C3D-0324 · 260714 Huckaby R2: draw the power squiggle as real geometry done
No SHX, no linetype. For each SS-V-POWER-CL line, traces a polyline alternating a 6 ft straight run with an 8 ft zigzag group (4 teeth, +-2 ft amplitude) built in the lines own along/across frame so it follows any bearing. Squiggles go on a new layer SS-V-POWER-SQUIGGLE in the same colour so they can be frozen or deleted independently; the centreline layer goes back to Continuous. Idempotent - erases squiggles from a previous run first. Verifies each polyline on read-back.
C# payload
// Draw the power-line squiggle as REAL GEOMETRY - no SHX, no linetype, nothing to break.
//
// For each line on SS-V-POWER-CL, walk its length and emit a polyline that alternates
// straight run / zigzag / straight run, matching the recorded plat's ---/\/\---/\/\--- look.
// The zigzag is built in the line's own local frame (along = unit vector, across = perpendicular)
// so it follows whatever bearing the line has.
//
// The centreline itself is set to a plain Continuous NO-DRAW state by moving it to a new
// SS-V-POWER-CL-HIDE? No - the user needs the centreline geometry to stay. Instead the squiggle
// polylines go on their own layer SS-V-POWER-SQUIGGLE so they can be frozen or deleted freely,
// and the centreline layer is put back on Continuous.
//
// Geometry per repeat (feet on the ground):
// RUN straight along the line
// ZIG 4 alternating diagonal segments, AMP either side
const string SRC = "SS-V-POWER-CL";
const string DEST = "SS-V-POWER-SQUIGGLE";
const double RUN = 6.0; // straight length between squiggles
const double ZIG = 8.0; // length consumed by one squiggle group
const double AMP = 2.0; // half-height of the squiggle
const int TEETH = 4; // diagonal segments per group
Log("drawing: " + Db.Filename);
var lt = (LayerTable)Tx.GetObject(Db.LayerTableId, OpenMode.ForWrite);
if (!lt.Has(SRC)) { Log("layer " + SRC + " missing"); return; }
// squiggle layer, same colour as the source
short colour = 1;
{
var s = (LayerTableRecord)Tx.GetObject(lt[SRC], OpenMode.ForRead);
colour = s.Color.ColorIndex;
}
ObjectId destId;
if (lt.Has(DEST)) { destId = lt[DEST]; Log("layer " + DEST + " exists - reusing"); }
else {
var nl = new LayerTableRecord();
nl.Name = DEST;
nl.Color = Autodesk.AutoCAD.Colors.Color.FromColorIndex(Autodesk.AutoCAD.Colors.ColorMethod.ByAci, colour);
destId = lt.Add(nl);
Tx.AddNewlyCreatedDBObject(nl, true);
Log("created layer " + DEST + " (colour " + colour + ")");
}
// put the centreline layer back on Continuous - the squiggle is geometry now
var ltt = (LinetypeTable)Tx.GetObject(Db.LinetypeTableId, OpenMode.ForRead);
{
var srcLayer = (LayerTableRecord)Tx.GetObject(lt[SRC], OpenMode.ForWrite);
srcLayer.LinetypeObjectId = ltt["Continuous"];
Log(SRC + " linetype -> Continuous");
}
var ms = (BlockTableRecord)Tx.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(Db), OpenMode.ForWrite);
// wipe any squiggles from a previous run so this is idempotent
int wiped = 0;
foreach (ObjectId id in ms) {
var e = Tx.GetObject(id, OpenMode.ForRead) as Autodesk.AutoCAD.DatabaseServices.Entity;
if (e == null || e.IsErased) continue;
if (!e.Layer.Equals(DEST, StringComparison.OrdinalIgnoreCase)) continue;
var w = (Autodesk.AutoCAD.DatabaseServices.Entity)Tx.GetObject(id, OpenMode.ForWrite);
w.Erase(); wiped++;
}
if (wiped > 0) Log("erased " + wiped + " squiggles from a previous run");
// collect the source lines first
var src = new List<ObjectId>();
foreach (ObjectId id in ms) {
var e = Tx.GetObject(id, OpenMode.ForRead) as Autodesk.AutoCAD.DatabaseServices.Entity;
if (e == null || e.IsErased) continue;
if (e.Layer.Equals(SRC, StringComparison.OrdinalIgnoreCase) && e is Line) src.Add(id);
}
Log("power centrelines: " + src.Count);
int made = 0; double totalTeeth = 0;
foreach (var id in src) {
var ln = (Line)Tx.GetObject(id, OpenMode.ForRead);
var a = ln.StartPoint; var b = ln.EndPoint;
double L = ln.Length;
if (L < 1.0) continue;
double ux = (b.X - a.X) / L, uy = (b.Y - a.Y) / L; // along
double px = -uy, py = ux; // across
var pl = new Polyline();
int v = 0;
double t = 0.0;
pl.AddVertexAt(v++, new Point2d(a.X, a.Y), 0, 0, 0);
while (t < L - 0.01) {
// straight run
double runEnd = Math.Min(t + RUN, L);
pl.AddVertexAt(v++, new Point2d(a.X + ux * runEnd, a.Y + uy * runEnd), 0, 0, 0);
t = runEnd;
if (t >= L - 0.01) break;
// squiggle group: TEETH diagonals alternating across the line
double zigEnd = Math.Min(t + ZIG, L);
double step = (zigEnd - t) / TEETH;
for (int k = 1; k <= TEETH; k++) {
double tt = t + step * k;
double off = (k % 2 == 1) ? AMP : -AMP;
if (k == TEETH) off = 0; // land back on the line
pl.AddVertexAt(v++, new Point2d(a.X + ux * tt + px * off,
a.Y + uy * tt + py * off), 0, 0, 0);
totalTeeth++;
}
t = zigEnd;
}
pl.Layer = DEST;
ms.AppendEntity(pl);
Tx.AddNewlyCreatedDBObject(pl, true);
made++;
var back = (Polyline)Tx.GetObject(pl.ObjectId, OpenMode.ForRead);
Log(string.Format(" [{0}] from line [{1}] len={2:F1} -> {3} verts, {4:F0} squiggle groups (verified)",
back.Handle, ln.Handle, L, back.NumberOfVertices, L / (RUN + ZIG)));
}
Log("");
Log(string.Format("drew {0} squiggle polylines on {1}: run {2:F1} ft, squiggle {3:F1} ft, amplitude +-{4:F1} ft",
made, DEST, RUN, ZIG, AMP));
Ed.Regen();
Result
Log
drawing: C:\Users\sanja\OneDrive\_SurveyDisco\260714 - 285 Huckaby Rd, Brooks, GA 30205, USA\260714 - 285 Huckaby Rd R2.dwg created layer SS-V-POWER-SQUIGGLE (colour 1) SS-V-POWER-CL linetype -> Continuous power centrelines: 4 [21C51] from line [20C9D] len=893.0 -> 321 verts, 64 squiggle groups (verified) [21C52] from line [20C9E] len=364.6 -> 132 verts, 26 squiggle groups (verified) [21C53] from line [20CA9] len=1514.6 -> 542 verts, 108 squiggle groups (verified) [21C54] from line [20CB1] len=1569.6 -> 562 verts, 112 squiggle groups (verified) drew 4 squiggle polylines on SS-V-POWER-SQUIGGLE: run 6.0 ft, squiggle 8.0 ft, amplitude +-2.0 ft
Notes
What worked, what didn't, job-specific gotchas — flagged notes feed the recipes.
No notes yet.