← Inbox

C3D-0078 · READ-ONLY: verify the main run lengths, slopes and inverts [VERIFY-MAIN-RUN] done

For each pair along A16-A14-A12-A10-A9-A6-A5-A4-A3-A2-A1-384, reads the joining line true length, its length and slope labels, and the invert out/in from the manhole notes drawn at each end, then recomputes the slope from drop over true length so the labelled value can be checked independently. No changes.

Script file
C3D-0078.cs
Target
260612 · model space
Author
claude
Approved
yes · reviewer
Timeout
240s

C# payload

// READ-ONLY. Full verification pass on the MAIN RUN:
//   A16 - A14 - A12 - A10 - A9 - A6 - A5 - A4 - A3 - A2 - A1 - MH384
//
// For each consecutive pair: find the SEWER_LINE line joining them, read its TRUE length, read
// the length label and the slope label sitting on it, and read the manhole notes at both ends so
// INVERT OUT (upstream) and INVERT IN (downstream) can be pulled from what is actually drawn.
//
// Everything comes from the drawing. Nothing is computed from a remembered table, so the slope
// arithmetic can be checked independently against what is labelled. Nothing is modified.
var ms = (BlockTableRecord)Tx.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(Db), OpenMode.ForRead);
Func<Func<string>, string> safe = f => { try { return f(); } catch (System.Exception ex) { return "<" + ex.GetType().Name + ">"; } };

// --- points by manhole name ---
var mh = new Dictionary<string, double[]>();   // "A16" -> {x,y}
foreach (ObjectId id in ms) {
    var cp = Tx.GetObject(id, OpenMode.ForRead) as CogoPoint;
    if (cp == null) continue;
    string d = (safe(() => cp.RawDescription ?? "")).Trim().ToUpper();
    if (d.StartsWith("SSMH ")) {
        string nm = d.Substring(5).Trim();
        if (nm == "MAIN") nm = "384";
        if (!mh.ContainsKey(nm)) mh[nm] = new double[] { cp.Easting, cp.Northing };
    }
}

// --- lines ---
var lines = new List<object[]>();
foreach (ObjectId id in ms) {
    var o = Tx.GetObject(id, OpenMode.ForRead);
    var ent = o as Autodesk.AutoCAD.DatabaseServices.Entity;
    if (ent == null || safe(() => ent.Layer) != "SEWER_LINE") continue;
    var ln = o as Line;
    if (ln == null) continue;
    lines.Add(new object[] { o.Handle.ToString(), ln.StartPoint.X, ln.StartPoint.Y,
                             ln.EndPoint.X, ln.EndPoint.Y, ln.Length });
}

// --- labels, assigned to nearest line ---
var lenLbl = new Dictionary<string,string>();
var pctLbl = new Dictionary<string,string>();
foreach (ObjectId id in ms) {
    var mt = Tx.GetObject(id, OpenMode.ForRead) as MText;
    if (mt == null || safe(() => mt.Layer) != "SEWER_LINE_TEXT") continue;
    double lx = mt.Location.X, ly = mt.Location.Y;
    string best = null; double bd = 1e18;
    foreach (var L in lines) {
        double x1=(double)L[1], y1=(double)L[2], x2=(double)L[3], y2=(double)L[4];
        double vx=x2-x1, vy=y2-y1, len2=vx*vx+vy*vy;
        double t = len2>0 ? ((lx-x1)*vx+(ly-y1)*vy)/len2 : 0.0;
        if (t<0) t=0; if (t>1) t=1;
        double px=x1+t*vx, py=y1+t*vy;
        double dd=Math.Sqrt((lx-px)*(lx-px)+(ly-py)*(ly-py));
        if (dd<bd) { bd=dd; best=(string)L[0]; }
    }
    if (best == null || bd > 40.0) continue;
    string c = mt.Contents.Trim();
    if (c.IndexOf('%') >= 0) pctLbl[best] = c;
    else lenLbl[best] = c;
}

// --- manhole notes: parse RIM / IN / OUT out of the SEWER_MANHOLE_TEXT MText ---
var note = new Dictionary<string,string[]>();   // "A16" -> {rim,in,out}
foreach (ObjectId id in ms) {
    var mt = Tx.GetObject(id, OpenMode.ForRead) as MText;
    if (mt == null || safe(() => mt.Layer) != "SEWER_MANHOLE_TEXT") continue;
    string raw = mt.Contents.Replace(@"\P", "\n");
    var ls = raw.Split('\n');
    if (ls.Length < 4) continue;
    string head = ls[0].Trim().ToUpper();          // "MH  A16" or "TEST MH"
    string nm = head.StartsWith("MH") ? head.Substring(2).Trim() : head;
    string rim = "", inv = "", outv = "";
    foreach (var l in ls) {
        string s = l.Trim().ToUpper();
        if (s.StartsWith("RIM")) rim = s.Substring(3).Trim();
        else if (s.StartsWith("OUT")) outv = s.Substring(3).Trim();
        else if (s.StartsWith("IN")) inv = s.Substring(2).Trim();
    }
    if (nm.Length > 0 && !note.ContainsKey(nm)) note[nm] = new string[] { rim, inv, outv };
}

string[] RUN = new string[] { "A16","A14","A12","A10","A9","A6","A5","A4","A3","A2","A1","384" };

Log("UP    DOWN   HANDLE   TRUE_LEN  LEN_LABEL   SLOPE_LBL  INV_OUT(up)  INV_IN(dn)   DROP    CALC_SLOPE");
for (int i = 0; i + 1 < RUN.Length; i++) {
    string a = RUN[i], b = RUN[i+1];
    if (!mh.ContainsKey(a) || !mh.ContainsKey(b)) { Log(String.Format("{0,-5} {1,-6} -- point missing --", a, b)); continue; }
    double[] pa = mh[a], pb = mh[b];

    string h = "(none)"; double trueLen = 0;
    foreach (var L in lines) {
        double x1=(double)L[1], y1=(double)L[2], x2=(double)L[3], y2=(double)L[4];
        bool fwd = Math.Abs(x1-pa[0])<1.0 && Math.Abs(y1-pa[1])<1.0 && Math.Abs(x2-pb[0])<1.0 && Math.Abs(y2-pb[1])<1.0;
        bool rev = Math.Abs(x1-pb[0])<1.0 && Math.Abs(y1-pb[1])<1.0 && Math.Abs(x2-pa[0])<1.0 && Math.Abs(y2-pa[1])<1.0;
        if (fwd || rev) { h = (string)L[0]; trueLen = (double)L[5]; break; }
    }

    string ll = lenLbl.ContainsKey(h) ? lenLbl[h] : "-";
    string sl = pctLbl.ContainsKey(h) ? pctLbl[h] : "-";
    string io = note.ContainsKey(a) ? note[a][2] : "?";
    string ii = note.ContainsKey(b) ? note[b][1] : "?";

    string drop = "-", calc = "-";
    double dOut, dIn;
    if (Double.TryParse(io, out dOut) && Double.TryParse(ii, out dIn) && trueLen > 0) {
        double dr = dOut - dIn;
        drop = dr.ToString("F2");
        calc = (dr / trueLen * 100.0).ToString("F2") + "%";
    }

    Log(String.Format("{0,-5} {1,-6} {2,-8} {3,8:F2}  {4,-10} {5,-10} {6,-12} {7,-12} {8,-7} {9}",
        a, b, h, trueLen, ll, sl, io, ii, drop, calc));
}

Result

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

Log

UP    DOWN   HANDLE   TRUE_LEN  LEN_LABEL   SLOPE_LBL  INV_OUT(up)  INV_IN(dn)   DROP    CALC_SLOPE
A16   A14    2EC86      132.52  132.52'    15.79%     ?            722.02       -       -
A14   A12    2EC87      133.21  133.21'    2.81%      721.82       718.08       3.74    2.81%
A12   A10    2EC89       86.31  86.31'     2.25%      717.88       717.37       0.51    0.59%
A10   A9     2EC8A       30.97  30.97'     8.89%      717.17       714.42       2.75    8.88%
A9    A6     2EC8B      133.46  133.46'    1.29%      714.22       712.49       1.73    1.30%
A6    A5     2EC8C       80.46  80.46'     15.60%     712.49       699.94       12.55   15.60%
A5    A4     2EC8D      161.58  161.58'    12.37%     699.56       679.57       19.99   12.37%
A4    A3     2EC8E      359.02  359.02'    1.16%      677.97       673.80       4.17    1.16%
A3    A2     2EC8F       80.02  80.02'     0.50%      673.74       673.34       0.40    0.50%
A2    A1     2EC90      155.37  155.37'    0.60%      673.34       672.41       0.93    0.60%
A1    384    2EC91       19.54  19.54'     2.41%      672.31       671.84       0.47    2.41%

Notes

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

No notes yet.