C3D-0422 · Linework: TBC curb string (800-5000 group) -> new layer V-TBC [C3D-LWTBC] done
Draws a curve-fit polyline through all TBC points in the 800-5000 group, connected nearest-neighbor from an endpoint (walked like the drawing, not by point number), on a new layer V-TBC. Linework only.
C# payload
// TBC linework from the 800-5000 group. Points whose desc starts TBC. Connect nearest-neighbor
// from an endpoint (walk the string like the drawing, not by point number), curve-fit the result
// so it reads curvy. New layer V-TBC.
const string LAYER="V-TBC"; const short COLOR=3;
var civ=Autodesk.Civil.ApplicationServices.CivilApplication.ActiveDocument;
Log("drawing: " + Db.Filename);
// collect TBC points
var pts=new List<Point2d>();
foreach (ObjectId id in civ.CogoPoints){
var p=(Autodesk.Civil.DatabaseServices.CogoPoint)Tx.GetObject(id,OpenMode.ForRead);
if((p.RawDescription??"").Trim().ToUpper().StartsWith("TBC")) pts.Add(new Point2d(p.Easting,p.Northing));
}
Log("TBC points: " + pts.Count);
if(pts.Count<2){ Log("not enough"); return; }
// nearest-neighbour chain starting from the point that is furthest from the centroid (an end)
double cx=0,cy=0; foreach(var p in pts){cx+=p.X;cy+=p.Y;} cx/=pts.Count; cy/=pts.Count;
int start=0; double best=-1; for(int i=0;i<pts.Count;i++){ double d=(pts[i].X-cx)*(pts[i].X-cx)+(pts[i].Y-cy)*(pts[i].Y-cy); if(d>best){best=d;start=i;} }
var used=new bool[pts.Count]; var order=new List<int>{start}; used[start]=true;
for(int k=1;k<pts.Count;k++){ int cur=order[order.Count-1]; int nn=-1; double nb=double.MaxValue;
for(int j=0;j<pts.Count;j++){ if(used[j])continue; double d=(pts[cur].X-pts[j].X)*(pts[cur].X-pts[j].X)+(pts[cur].Y-pts[j].Y)*(pts[cur].Y-pts[j].Y); if(d<nb){nb=d;nn=j;} }
order.Add(nn); used[nn]=true; }
// layer
var lt=(LayerTable)Tx.GetObject(Db.LayerTableId,OpenMode.ForWrite);
ObjectId layId;
if(lt.Has(LAYER)) layId=lt[LAYER];
else{ var l=new LayerTableRecord(); l.Name=LAYER; l.Color=Autodesk.AutoCAD.Colors.Color.FromColorIndex(Autodesk.AutoCAD.Colors.ColorMethod.ByAci,COLOR); layId=lt.Add(l); Tx.AddNewlyCreatedDBObject(l,true); Log("created layer "+LAYER); }
// polyline through the ordered points
var pl=new Polyline();
for(int i=0;i<order.Count;i++) pl.AddVertexAt(i,pts[order[i]],0,0,0);
pl.LayerId=layId;
// curve-fit: convert to a spline-like read by setting bulges from a 3-point circle at each interior vertex
for(int i=1;i<pl.NumberOfVertices-1;i++){
var a=pl.GetPoint2dAt(i-1); var b=pl.GetPoint2dAt(i); var c=pl.GetPoint2dAt(i+1);
// bulge from the angle subtended - approximate smooth arc through a,b,c
double dx1=b.X-a.X,dy1=b.Y-a.Y,dx2=c.X-b.X,dy2=c.Y-b.Y;
double cross=dx1*dy2-dy1*dx2; double dot=dx1*dx2+dy1*dy2;
double ang=System.Math.Atan2(cross,dot);
double bulge=System.Math.Tan(ang/4.0);
if(System.Math.Abs(bulge)>0.001) pl.SetBulgeAt(i-1,bulge);
}
var ms=(BlockTableRecord)Tx.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(Db),OpenMode.ForWrite);
ms.AppendEntity(pl); Tx.AddNewlyCreatedDBObject(pl,true);
var back=(Polyline)Tx.GetObject(pl.ObjectId,OpenMode.ForRead);
Log(string.Format("drew TBC polyline [{0}] on {1}: {2} verts, len {3:F1}", back.Handle, LAYER, back.NumberOfVertices, back.Length));
Ed.Regen();
Result
Log
drawing: C:\Users\sanja\OneDrive\_SurveyDisco\260711 - 281 Maranatha Trail, Lawrenceville, GA 30045, USA\281 MARANTHA 2607.dwg TBC points: 16 created layer V-TBC drew TBC polyline [11B4D] on V-TBC: 16 verts, len 239.1
Notes
What worked, what didn't, job-specific gotchas — flagged notes feed the recipes.
No notes yet.