C3D-PDFFIT2 · Fit PDF block - translation corrected done
Both controls were off by an identical 1271.5ft vector (pure translation error in my insertion calc). Shifts insertion by that vector so MH A16 lands on SSMH 1106 and A14 on SSMH 1105.
C# payload
// Fit the PDF import block so its MH symbols land on the surveyed manhole points.
// Transform solved from 2 controls: block MH A16 -> SSMH 1106, block MH A14 -> SSMH 1105.
// Scale/rotation are whatever makes those fit (72.9458, 271.329 deg) — not a nominal plot scale.
var bt = (BlockTable)Tx.GetObject(Db.BlockTableId, OpenMode.ForRead);
var ms = (BlockTableRecord)Tx.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead);
const double SCALE = 72.9458;
const double ROTDEG = 271.329;
var INSERT = new Point3d(73913019.3568, 257513918.4130, 0);
ObjectId tid = ObjectId.Null;
foreach (ObjectId id in ms) {
var o = Tx.GetObject(id, OpenMode.ForRead);
if (o is BlockReference br) {
var d = (BlockTableRecord)Tx.GetObject(br.DynamicBlockTableRecord, OpenMode.ForRead);
if (d.Name.Contains("As Built") || d.Name.Contains("DEV3896")) { tid = id; break; }
}
}
if (tid.IsNull) { Log("PDF block not found."); return; }
var w = (BlockReference)Tx.GetObject(tid, OpenMode.ForWrite);
Log($"before: insert=({w.Position.X:F2},{w.Position.Y:F2}) scale={w.ScaleFactors.X:F4} rot={w.Rotation*180/System.Math.PI:F3}");
w.Position = INSERT;
w.ScaleFactors = new Scale3d(SCALE, SCALE, SCALE);
w.Rotation = ROTDEG * System.Math.PI / 180.0;
var chk = (BlockReference)Tx.GetObject(tid, OpenMode.ForRead);
Log($"after : insert=({chk.Position.X:F2},{chk.Position.Y:F2}) scale={chk.ScaleFactors.X:F4} rot={chk.Rotation*180/System.Math.PI:F3} (verified)");
// verify: transform the block-space MH symbol centers and measure against the surveyed points
var xform = chk.BlockTransform;
var checks = new (string name, Point3d blockPt, Point2d survey)[] {
("A16 -> SSMH 1106", new Point3d(3488946.6984,-1062985.0852,0), new Point2d(2296379.89,1279953.45)),
("A14 -> SSMH 1105", new Point3d(3488946.7660,-1062983.2881,0), new Point2d(2296511.06,1279951.56)),
("A12 (no survey)", new Point3d(3488946.2684,-1062981.2538,0), new Point2d(0,0)),
("A10 (no survey)", new Point3d(3488945.8131,-1062981.2964,0), new Point2d(0,0)),
};
foreach (var (name, bp, sv) in checks) {
var t = bp.TransformBy(xform);
if (sv.X == 0) Log($" {name}: lands at ({t.X:F2},{t.Y:F2})");
else {
double err = new Point2d(t.X, t.Y).GetDistanceTo(sv);
Log($" {name}: lands at ({t.X:F2},{t.Y:F2}) err={err:F3} ft");
}
}
try { var ex = chk.GeometricExtents;
Log($"extents ({ex.MinPoint.X:F0},{ex.MinPoint.Y:F0})-({ex.MaxPoint.X:F0},{ex.MaxPoint.Y:F0}) size {ex.MaxPoint.X-ex.MinPoint.X:F0} x {ex.MaxPoint.Y-ex.MinPoint.Y:F0} ft");
} catch { }
Result
Log
before: insert=(73914247.16,257513587.86) scale=72.9458 rot=271.329 after : insert=(73913019.36,257513918.41) scale=72.9458 rot=271.329 (verified) A16 -> SSMH 1106: lands at (2296379.89,1279953.45) err=0.002 ft A14 -> SSMH 1105: lands at (2296511.06,1279951.56) err=0.001 ft A12 (no survey): lands at (2296658.57,1279991.29) A10 (no survey): lands at (2296654.70,1280024.42) extents (2295707,1279330)-(2297497,1280557) size 1790 x 1227 ft
Notes
What worked, what didn't, job-specific gotchas — flagged notes feed the recipes.
No notes yet.