C3D-0156 · As-built labels to layer 0 + before snapshot [ASB-TO-0] done
Moves the four as-built labels to layer 0 and records each one exact location, rotation, attachment and height, plus its perpendicular offset and side relative to the feature polyline it names, as the baseline for diffing after the user nudges them by hand.
C# payload
// Move the four as-built labels to layer 0, then snapshot their exact placement as the BEFORE
// baseline - the user is about to nudge them by hand so the convention can be measured from the
// diff (same method that produced the arc rule).
//
// Captures for each label: location, rotation, attachment, height, and its offset from the
// feature polyline it names - distance and which SIDE - since that offset is the thing being taught.
var ms = (BlockTableRecord)Tx.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(Db), OpenMode.ForWrite);
Log("drawing: " + Db.Filename);
var names = new Dictionary<string,string>();
names["SIDEWALK"] = "SS-V-ROAD-EPVM";
names["WALL"] = "V-STRC-WALL";
names["CONC"] = "X-DRIV-CONC";
names["FENCE"] = "SS-X-FENCE";
int moved = 0;
foreach (ObjectId id in ms) {
var mt0 = Tx.GetObject(id, OpenMode.ForRead) as MText;
if (mt0 == null || mt0.IsErased) continue;
if (!names.ContainsKey(mt0.Contents.Trim().ToUpper())) continue;
if (mt0.Layer == "0") continue;
var mt = (MText)Tx.GetObject(id, OpenMode.ForWrite);
string was = mt.Layer;
mt.Layer = "0";
moved++;
Log(" \"" + mt.Contents + "\" " + was + " -> 0");
}
Log("moved to layer 0: " + moved);
Log("");
Log("=== BEFORE SNAPSHOT ===");
foreach (ObjectId id in ms) {
var mt = Tx.GetObject(id, OpenMode.ForRead) as MText;
if (mt == null || mt.IsErased) continue;
string c = mt.Contents.Trim().ToUpper();
if (!names.ContainsKey(c)) continue;
// nearest point on the feature polyline this label names
double best = 1e18; double side = 0; Point3d foot = mt.Location;
foreach (ObjectId pid in ms) {
var pl = Tx.GetObject(pid, OpenMode.ForRead) as Polyline;
if (pl == null || pl.IsErased || pl.Layer != names[c]) continue;
for (int i = 0; i < pl.NumberOfVertices - 1; i++) {
var A = pl.GetPoint2dAt(i); var B = pl.GetPoint2dAt(i+1);
double vx = B.X-A.X, vy = B.Y-A.Y, L2 = vx*vx+vy*vy;
double t = L2 > 0 ? ((mt.Location.X-A.X)*vx + (mt.Location.Y-A.Y)*vy)/L2 : 0;
if (t < 0) t = 0; if (t > 1) t = 1;
double qx = A.X+t*vx, qy = A.Y+t*vy;
double d = Math.Sqrt(Math.Pow(mt.Location.X-qx,2)+Math.Pow(mt.Location.Y-qy,2));
if (d < best) {
best = d; foot = new Point3d(qx,qy,0);
side = vx*(mt.Location.Y-A.Y) - vy*(mt.Location.X-A.X);
}
}
}
Log(String.Format("SNAP [{0}] \"{1}\" layer={2} h={3}", mt.Handle, mt.Contents, mt.Layer, mt.TextHeight));
Log(String.Format(" location {0:F4},{1:F4} rotation {2:F4} deg attach {3}",
mt.Location.X, mt.Location.Y, mt.Rotation*180.0/Math.PI, mt.Attachment));
Log(String.Format(" offset from {0}: {1:F4} ft, side {2} (foot {3:F4},{4:F4})",
names[c], best, side > 0 ? "LEFT" : "RIGHT", foot.X, foot.Y));
}
Ed.Regen();
Result
Log
drawing: C:\Users\sanja\OneDrive\_SurveyDisco\260802 - 4082 Sweetbriar Ln, Forest Park, GA 30297, USA\260802 - 4082 Sweetbriar Ln.dwg
"WALL" V-STRC-WALL -> 0
"CONC" X-DRIV-CONC -> 0
"SIDEWALK" SS-V-ROAD-EPVM -> 0
"FENCE" SS-X-FENCE -> 0
moved to layer 0: 4
=== BEFORE SNAPSHOT ===
SNAP [20C89] "WALL" layer=0 h=0.8
location 2238240.0770,1325109.9995 rotation 339.0145 deg attach BottomCenter
offset from V-STRC-WALL: 0.0000 ft, side LEFT (foot 2238240.0770,1325109.9995)
SNAP [20C8A] "CONC" layer=0 h=0.8
location 2238210.2195,1325139.0679 rotation 336.6671 deg attach BottomCenter
offset from X-DRIV-CONC: 0.0000 ft, side LEFT (foot 2238210.2195,1325139.0679)
SNAP [20C8F] "SIDEWALK" layer=0 h=0.8
location 2238232.6465,1325138.6031 rotation 336.5170 deg attach BottomCenter
offset from SS-V-ROAD-EPVM: 0.0000 ft, side LEFT (foot 2238232.6465,1325138.6031)
SNAP [20C91] "FENCE" layer=0 h=0.8
location 2238320.8512,1325110.2963 rotation 30.0905 deg attach BottomCenter
offset from SS-X-FENCE: 0.0000 ft, side RIGHT (foot 2238320.8512,1325110.2963)Notes
What worked, what didn't, job-specific gotchas — flagged notes feed the recipes.
No notes yet.