← Inbox

C3D-HCWA-TANGENT · HCWA migration 4/5: one line per sewer tangent done

Explode multi-segment SEWER_LINE polylines into one Line per tangent (HCWA: 'lines must not continue for more than one tangent') and snap endpoints to exact manhole centers (no gaps).

Script file
C3D-HCWA-TANGENT.cs
Target
C:\Users\sanja\OneDrive\_SurveyDisco\260613 - 5030 E Lake Pkwy, Stockbridge, GA 30281, USA\CSTORE WATER ABS-260612_SHEET.dwg · model space
Author
claude
Approved
yes · sanjay (batch-approved: HCWA migration)
Timeout
60s

C# payload

// HCWA migration 4/5: SEWER TANGENTS. HCWA: "All tangents between sewer manholes need to be drawn
// with a single line. Lines must not continue for more than one tangent." + "All tangents must be
// snapped at endpoints intersecting at the exact center of the manhole."
// Explodes any multi-segment polyline on SEWER_LINE into one Line per tangent, then snaps every
// SEWER_LINE endpoint to the nearest manhole center within tolerance.
var bt = (BlockTable)Tx.GetObject(Db.BlockTableId, OpenMode.ForRead);
var ms = (BlockTableRecord)Tx.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);

// manhole centers (circles now on SEWER_MANHOLE)
var mh = new List<Point2d>();
foreach (ObjectId id in ms) {
    var o = Tx.GetObject(id, OpenMode.ForRead);
    if (o is Circle c && c.Layer == "SEWER_MANHOLE") mh.Add(new Point2d(c.Center.X, c.Center.Y));
}
Log($"manhole centers found: {mh.Count}");

// 1) explode multi-segment polylines into per-tangent lines
var kill = new List<ObjectId>(); int madeLines = 0;
foreach (ObjectId id in ms) {
    var o = Tx.GetObject(id, OpenMode.ForRead);
    if (!(o is Polyline pl) || pl.Layer != "SEWER_LINE") continue;
    if (pl.NumberOfVertices < 3) continue;                 // already a single tangent
    for (int i = 0; i < pl.NumberOfVertices - 1; i++) {
        var a = pl.GetPoint2dAt(i); var b = pl.GetPoint2dAt(i+1);
        var ln = new Line(new Point3d(a.X,a.Y,0), new Point3d(b.X,b.Y,0)) { Layer = "SEWER_LINE" };
        ms.AppendEntity(ln); Tx.AddNewlyCreatedDBObject(ln, true); madeLines++;
    }
    kill.Add(id);
    Log($"  exploded polyline v={pl.NumberOfVertices} -> {pl.NumberOfVertices-1} tangents");
}
foreach (var id in kill) { var e = (Autodesk.AutoCAD.DatabaseServices.Entity)Tx.GetObject(id, OpenMode.ForWrite); e.Erase(); }

// 2) snap endpoints to manhole centers (tolerance 6')
const double TOL = 6.0;
int snapped = 0;
Point3d Snap(Point3d p, ref bool did) {
    var q = new Point2d(p.X, p.Y); double bd = double.MaxValue; Point2d best = q;
    foreach (var m in mh) { double d = q.GetDistanceTo(m); if (d < bd) { bd = d; best = m; } }
    if (bd > 0.0001 && bd <= TOL) { did = true; return new Point3d(best.X, best.Y, p.Z); }
    return p;
}
foreach (ObjectId id in ms) {
    var o = Tx.GetObject(id, OpenMode.ForRead);
    if (!(o is Line l) || l.Layer != "SEWER_LINE") continue;
    bool a = false, b = false;
    var ns = Snap(l.StartPoint, ref a); var ne = Snap(l.EndPoint, ref b);
    if (!a && !b) continue;
    var w = (Line)Tx.GetObject(id, OpenMode.ForWrite);
    if (a) w.StartPoint = ns;
    if (b) w.EndPoint = ne;
    snapped++;
}
Log($"tangents created: {madeLines}, lines with endpoints snapped to MH centers: {snapped}");

// 3) report directionality (HCWA: uphill node -> downhill node). Report only; no auto-flip,
//    because inverts live in text, not on the geometry.
int n = 0;
foreach (ObjectId id in ms) {
    var o = Tx.GetObject(id, OpenMode.ForRead);
    if (o is Line l && l.Layer == "SEWER_LINE") n++;
}
Log($"SEWER_LINE tangents now: {n}. Directionality (uphill->downhill) must be verified against inverts — see SEWER_MANHOLE_TEXT.");

Result

Status
success
Drawing file
C:\Users\sanja\OneDrive\_SurveyDisco\260613 - 5030 E Lake Pkwy, Stockbridge, GA 30281, USA\CSTORE WATER ABS-260612_SHEET.dwg
Message
Executed C3D-HCWA-TANGENT (0 entities touched).
Entities
Duration
386 ms
Civil 3D
25.0.0.0

Log

manhole centers found: 8
  exploded polyline v=6 -> 5 tangents
tangents created: 5, lines with endpoints snapped to MH centers: 0
SEWER_LINE tangents now: 12. Directionality (uphill->downhill) must be verified against inverts — see SEWER_MANHOLE_TEXT.

Notes

What worked, what didn't, job-specific gotchas — flagged notes feed the recipes.

No notes yet.