C3D-0390 · Box + 1500 GAL label around each grease-trap pair [C3D-GTBOX] error
Groups the 4 SEWER_GREASE_TRAPS points into 2 pairs by proximity, draws a padded rectangle around each pair and adds an MText 'PROP. 1500 GAL / GREASE TRAPS' (SIMPLEX, height 3.0) above each box, all on layer SEWER_GREASE_TRAPS. Only points already on SEWER_GREASE_TRAPS are used.
C# payload
// Draw a box around each grease-trap pair and label it "PROP. 1500 GAL / GREASE TRAPS".
// Pairs (from C3D-0389): A = pts 354,355 ; B = pts 359,1100. All on SEWER_GREASE_TRAPS.
// Box = tight bounding rect of the pair + PAD; MText above the box, SIMPLEX h=3.0.
const string LAYER = "SEWER_GREASE_TRAPS";
const double PAD = 4.0; // ft padding around the two points
const double TXTH = 3.0; // match the sheet's SIMPLEX 3.0
Log("drawing: " + Db.Filename);
// gather the SEWER_GREASE_TRAPS points
var civ = Autodesk.Civil.ApplicationServices.CivilApplication.ActiveDocument;
var pts = new List<Tuple<int,double,double>>();
foreach (ObjectId id in civ.CogoPoints){
var p=(Autodesk.Civil.DatabaseServices.CogoPoint)Tx.GetObject(id,OpenMode.ForRead);
if (!p.Layer.Equals(LAYER,StringComparison.OrdinalIgnoreCase)) continue;
if (((p.RawDescription??"")).ToUpper().IndexOf("GREASE")<0) continue;
pts.Add(Tuple.Create((int)p.PointNumber, p.Easting, p.Northing));
}
Log("grease-trap points on " + LAYER + ": " + pts.Count);
// group into pairs by proximity (nearest-neighbour, <=20 ft)
var used=new HashSet<int>();
var pairs=new List<List<Tuple<int,double,double>>>();
for (int i=0;i<pts.Count;i++){
if (used.Contains(pts[i].Item1)) continue;
var grp=new List<Tuple<int,double,double>>{ pts[i] }; used.Add(pts[i].Item1);
for (int j=0;j<pts.Count;j++){
if (i==j || used.Contains(pts[j].Item1)) continue;
double d=Math.Sqrt(Math.Pow(pts[i].Item2-pts[j].Item2,2)+Math.Pow(pts[i].Item3-pts[j].Item3,2));
if (d<=20.0){ grp.Add(pts[j]); used.Add(pts[j].Item1); }
}
pairs.Add(grp);
}
Log("pairs: " + pairs.Count);
// style
var tst=(TextStyleTable)Tx.GetObject(Db.TextStyleTableId,OpenMode.ForRead);
ObjectId styleId = tst.Has("SIMPLEX") ? tst["SIMPLEX"] : Db.Textstyle;
var ms=(BlockTableRecord)Tx.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(Db),OpenMode.ForWrite);
var lt=(LayerTable)Tx.GetObject(Db.LayerTableId,OpenMode.ForRead);
ObjectId layId = lt.Has(LAYER)? lt[LAYER] : ObjectId.Null;
int boxes=0, labels=0;
foreach (var grp in pairs){
double minX=1e30,minY=1e30,maxX=-1e30,maxY=-1e30;
foreach (var t in grp){ minX=Math.Min(minX,t.Item2); maxX=Math.Max(maxX,t.Item2); minY=Math.Min(minY,t.Item3); maxY=Math.Max(maxY,t.Item3); }
minX-=PAD; minY-=PAD; maxX+=PAD; maxY+=PAD;
// rectangle polyline
var pl=new Polyline();
pl.AddVertexAt(0,new Point2d(minX,minY),0,0,0);
pl.AddVertexAt(1,new Point2d(maxX,minY),0,0,0);
pl.AddVertexAt(2,new Point2d(maxX,maxY),0,0,0);
pl.AddVertexAt(3,new Point2d(minX,maxY),0,0,0);
pl.Closed=true;
if(!layId.IsNull) pl.LayerId=layId;
ms.AppendEntity(pl); Tx.AddNewlyCreatedDBObject(pl,true); boxes++;
// label just above the box, centred
var mt=new MText();
mt.SetDatabaseDefaults();
mt.TextStyleId=styleId;
mt.TextHeight=TXTH;
mt.Attachment=AttachmentPoint.BottomCenter;
mt.Location=new Point3d((minX+maxX)/2, maxY+PAD*0.5, 0);
mt.Contents="PROP. 1500 GAL\PGREASE TRAPS";
if(!layId.IsNull) mt.LayerId=layId;
ms.AppendEntity(mt); Tx.AddNewlyCreatedDBObject(mt,true); labels++;
var nums=new System.Text.StringBuilder(); foreach(var t in grp) nums.Append(t.Item1).Append(" ");
Log(string.Format(" box [{0}] label [{1}] pts {2} rect ({3:F1},{4:F1})-({5:F1},{6:F1})",
pl.Handle, mt.Handle, nums.ToString().Trim(), minX,minY,maxX,maxY));
}
Log("");
Log(string.Format("drew {0} boxes and {1} labels on {2}", boxes, labels, LAYER));
Ed.Regen();
Result
Notes
What worked, what didn't, job-specific gotchas — flagged notes feed the recipes.
No notes yet.