Recipes
Parameterised, proven operations. A recipe is never “done” — it's proven on N cooks so far. Check decision points and known gaps before applying one.
Build lot hero sheet draft
Clone a lot sheet layout, set its parcel id, frame the viewport on the lot, draw the cyan hero boundary, add missing iron pins, and label boundary bearings.
- 260603 Clarks Ln: lots 1, 7, 8, 11, 12, 13 (with known gaps below)
- Parcel id for the new lot — confirm (not always sequential).
- Boundary trace — VERIFY against the survey: a 'lot' may be two parcels split by an internal line. Check Polyline.Area against the record area before accepting.
- Shared interior edge — its one bearing label can live on only one lot's hero layer; decide which.
- POB monument — should it be moved/bolded onto the hero?
- RESOLVED — LINEWEIGHT: hero layers set to 0.35mm (bold) so they read on B/W (C3D-FIX-RENDER).
- RESOLVED — IPP SYMBOL: new pins had an explicit style override blocking the marker; fix = set StyleId/LabelStyleId to Null + CogoPoint.ApplyDescriptionKeys() so 'IPP' maps to the iron-pin style (C3D-FIX-IPP).
- RESOLVED — ISOLATION OVER-FREEZE: the 'CLARKS LN' road label lived on hero layer SS-BOUNDARY CYAN, so isolation hid it on other sheets; moved to C-ANNO. RULE: keep shared annotations OFF hero layers (C3D-FIX-ROAD).
- OPEN — PARCELS must be created in the UI: bearings must CLOSE (survey QA) and lots 1 & 13 are two parcels each; the proper fix is Civil 3D Parcels (auto-split, area, closing bearings, POB). CONFIRMED there is NO programmatic creation — assembly-wide .NET reflection shows no creator, AND the COM AeccParcels collection has no Add/Create (DISP_E_UNKNOWNNAME). Only the interactive Create-Parcels-from-Objects command makes them. DIVISION OF LABOR: user creates the parcel per lot (~1 min, as done for Lot 1 = parcel #6, 4705 sf); then Claude does ALL downstream via the managed API — ParcelSegmentLabel.Create (closing bearings), ParcelAreaLabel.Create (area + POB), hero layer/lineweight/isolation. COM door for other ops: AeccXUiLand.AeccApplication.13.7. (C3D-FIX-PARCELS, C3D-FIX-BOUNDARY)
- BEARING STYLE: do not GeneralSegmentLabel.Create (default 'Grade Only' = % grade). For hero-only display, MOVE the survey's real 'Bearing and Distance' labels by FeatureId; for the real source/closure use parcel segment labels.
- 260603 (lots 12,13): established per-lot cyan hero layer + boundary + moved real bearings + framing + east pins; added per-viewport isolation. Extended heroes to lots 1,7,11 and isolated all six.
- 260623 review fixes: hero lineweight 0.35; IPP iron-pin symbol (clear override + ApplyDescriptionKeys); road label moved off hero layer to C-ANNO; durable GitHub store enabled so tickets persist. Confirmed via reflection there is no managed parcel-creation API — parcels (closure/POB/two-parcel split) need the Create-Parcels-from-Objects command or COM, then managed labeling.
Draw boundary from deed calls draft v0.1.0
Draw a boundary traverse (bearing + distance calls) anchored at a point/monument, closed or open, with area + closure check against the plat.
- 260619 Tract A — closed, area 43,295 sf vs plat 43,299 (4 sf)
- Which monument/corner to anchor the traverse at (no fixed basis otherwise).
- Closed parcel or open line string.
- Target layer (e.g. C-PROP-LINE).
- CONFIRM every bearing + distance — reads from a photo/plat image are error-prone.
- A misread call won't close; ALWAYS area/closure-check vs the plat before accepting.
- Anchor-corner choice is a guess unless a monument is confirmed. User re-fits by TRANSLATE only (grid bearings => no rotation).
- Curves (arcs) not yet supported — straight calls only.
- 260619 Tract A: N11-28-27E 210 / S89-10-36E 210 / S13-41-11W 220 / N86-51-24W 200; closed; area 43,295 vs 43,299. Anchored NW at IPF #479.
Field-to-finish linework draft v0.1.0
Connect a survey point group into polyline linework, breaking into a new run at each break code (e.g. END). For curb, CL, fence, etc.
- 260619 TBC curb (4 runs, break on END); CL centerline
- Point ORDER — number order vs figure/spatial (number order is not always spatial).
- The break code (END, etc.) and whether runs are closed.
- Target layer.
- Point-number order zigzagged for CL — may need spatial sorting.
- One group can hold MULTIPLE features (e.g. CL held Stonewall Tell + Newborn Dr SW + the road above) that must be SEPARATED into distinct polylines, not joined.
- Road labels are a separate step: text INLINE on the CL, rotated to it, always with the R/W note ('<NAME>\P(R/W VARIES)' or '(XX' R/W)'). NOT a flat note placed in the lot's frame — RE-BROKEN on 260702 (label landed 162' off the CL and the user moved it). Derive the label point + rotation FROM the centerline geometry itself.
- NEAREST-NEIGHBOR CHAINING IS WRONG — it strings points across unrelated features and produces crossings. Linework must NOT cross other features: edge-of-pavement must never cross a CL; a driveway must not have things crossing it. Chaining needs feature/figure order, not proximity.
- AREA features (driveway, concrete, walks) are NOT a chained path — they need a proper CLOSED OUTLINE traced in the correct order, and should be HATCHED (concrete pattern), not just outlined. CONFIRMED by the 260702 diff: the user deleted the 22-vertex open chain and drew a CLOSED 13-vertex polyline in its place.
- EP (edge of pavement) runs PER SIDE of the road — one chain over all EP points jumps between sides and the connector cuts across the CL. CONFIRMED by the 260702 diff: the user deleted the 5-vertex chained polyline and drew 3 SEPARATE lines.
- BUILDING FOOTPRINT: angular sort about the centroid FAILS on non-convex (L-shaped/notched) houses — it cuts corners. 260702: my 7-vertex HC ring was deleted and rebuilt as 9 vertices. HC corners need wall-following order (right-angle edges), not angular sort; the point count is usually MORE than the raw HC count because walls jog. Use the plat/photo footprint shape to order the corners.
- BUILDINGS ARE ORTHOGONAL — walls meet at ~90 deg. Use point count + edge angles as a DIAGNOSTIC for a MISSING corner (GPS often can't shoot a tight corner): (a) if the corner count is off for the expected shape (e.g. 5 where a rectangle needs 4, or an odd count), a corner is probably missing; (b) if two consecutive HC edges are NOT parallel or perpendicular — one runs off at a weird/skew angle — that skew is the tell that the true corner between them wasn't shot. FIX: extend the two adjacent wall lines to their intersection and put a SHARP vertex there (NO arc/fillet — 'fillets to that spot' means snap to the intersection point, not a radius). This is a per-building judgment call ('it all depends'), not a blind formula — read the corners, spot the skew or wrong count, reconstruct the square corner where the walls say it is.
- LAYERS: existing structures traced from field points go on SS-X-* (X=existing) or SS-V-ROAD-CURB, NOT SS-V-BLDG. 260702: user moved house+steps to SS-V-ROAD-CURB and the fence to SS-X-FENCE. Confirm the existing-vs-proposed layer convention before drawing.
- STEPS / CONCRETE PADS are hatched like any concrete area: closed outline + hatch + individual TREAD lines across it, not a bare outline. 260702: user replaced the 10-vertex step ring with outline+2 hatches+7 tread lines.
- FENCE: 'FLAGED FC' and 'OLD FLAGED FC' are DIFFERENT fences — do NOT join them. 260702: user split my single 4-corner run and connected only 137-173-167, LEAVING 169 (OLD FLAGED FC) unconnected. When FC codes distinguish old/new, draw separate runs and drop the old one unless told otherwise.
- 260619: TBC -> 4 curb runs (SS-V-ROAD-CURB, break END). CL -> single centerline (SS-V-ROAD-CNTR) — but it likely conflates Stonewall Tell + Newborn Dr + the road above; needs per-road separation. Road label placed inline + (R/W VARIES).
- 260702: connected CL/EP/driveway by nearest-neighbor — user feedback: EP crossed the CL, and the driveway came out as a chained mess instead of a driveway. Driveways must be a closed outline hatched to concrete, with nothing crossing them. Nearest-neighbor chaining retired as an approach.
- 260702 structures: traced existing HOUSE/DECK/STEPS/FENCE from point geometry (angular sort). Diff of the user's fixes: (1) house ring rebuilt 7->9 verts on SS-V-ROAD-CURB — angular sort cut corners on the non-convex footprint; (2) steps rebuilt as outline+hatch+tread lines (hatched concrete, not outline); (3) deck 5->6 verts (missed a corner); (4) fence split — only 137-173-167 connected on SS-X-FENCE, 169 'OLD FLAGED FC' left out as a separate old fence. ALSO: the user relabeled the whole sheet from PROPOSED to EXISTING — it is a 1-STORY FRAME HOUSE as-built, not the proposed 2-storey. The proposed site plan (house/porch/driveway/silt fence/erosion) was all deleted.
Import PNEZD points draft v1.1.0
Import a PNEZD (P,N,E,Z,D comma) point file from the drawing's folder as COGO points, preserving point numbers + descriptions, applying description keys.
- 260702 — 76 points (100-175) imported with numbers + descriptions, BUT no point types (see knownGaps)
- File name (in the drawing's folder).
- Format is PNEZD (Point, Northing, Easting, Elev, Desc) — confirm if the file is PENZD or other order.
- Non-point lines (base station, headers) are skipped by the numeric point-number check.
- NEEDS WORK — point TYPES not assigned: API Add + ApplyDescriptionKeys() creates valid cogo points with the right numbers + descriptions, but they do NOT receive point styles/types (the desc-key symbol). Civil 3D's native Import Points DOES apply them. Root cause likely: ApplyDescriptionKeys isn't matching, or the point-style-from-desc-key path differs from the native importer. UNTIL SOLVED, have the user run native Import Points for points.
- Point styles/symbols come from the drawing's Description Key Set — confirm one is configured.
- 260702: 76 points from 358 HOUSE.txt — numbers 100-175 + descriptions correct, but points got NO point type/style (user confirmed). Native Import Points applies types; API path does not yet. Recipe = draft, needs work.
Plat text / notes placement draft v0.1.0
Place plat annotation (dimensions, bearings, setbacks, feature labels, road names, area tables, adjoiners) on C-ANNO. Governs rotation, duplication and placement rules learned per cook.
- 260702 St Johns Ave (~25 notes; user kept most, moved 8, deleted the duplicates)
- Which notes are actually wanted — the user often does NOT need all the text, but says removing is easier than adding, so err toward MORE notes rather than fewer.
- Text heights per note class (dims/bearings ~4-5, feature labels ~3-4, minor callouts ~2.5, road name ~6).
- Whether the lot is skewed enough that lot-frame rotation reads badly.
- ROTATION IS PER NOTE CLASS, NOT GLOBAL. Do not rotate everything to the boundary frame. AREA / TABLE notes (lot area, F.A.R, unheated area, any tabular block) are 0 DEGREES HORIZONTAL — always, regardless of lot orientation. Dimensions/bearings align to the line they annotate. Road names align to the CL (see [field-to-finish]).
- ROAD NAME text must be INLINE ON THE CENTERLINE with the R/W note if noted — derive its point + rotation from the CL geometry, NOT from the lot frame. Broken on 260702: placed at lot-frame (f=30,d=-20), user moved it 162'.
- DUPLICATE STAMPING BUG: the 260702 cook wrote the bearings and BOTH 60.07'/170.00' dimension sets TWICE at identical coordinates — the user deleted 24 text entities, most of them duplicates. Guard against re-placing the same string at the same point (idempotency / no double-apply on re-run).
- Placement is draft-grade: the user moved the road name, sidewalk, amenity space, area tables and gravel exit out of the lot interior toward the road/margins. Interior of the lot should stay clear for the building.
- 260702: ~25 notes placed on C-ANNO in the boundary's f/d frame. User feedback + snapshot diff: KEPT most text ('not all the notes are normally needed, but removing is easier than adding — that part is fine'). DELETED 24 text entities (duplicated bearings + both dimension sets). MOVED 8 (road name inline to CL, sidewalk/amenity, area tables, gravel exit). RULES OUT: street text inline w/ CL + show R/W; area notes 0d horizontal.
Title block + sheet notes fill draft v0.1.0
Fill the SS_BLOCK_11X17 title block attributes and sheet notes (flood/FEMA, vicinity map) from the SurveyDisco job record.
- 260702 St Johns Ave — title block (8 attrs + date/subdivision) and FEMA note CONFIRMED GOOD by the user
- DATE = the date of the point DATA FILE (e.g. '358 HOUSE.txt' mtime), not today's date.
- SUBDIVISION_NAME_LOT = the neighborhood from the job record; lot number often unknown and most of the time no subdivision name exists at all — leave off rather than invent.
- Which layout is the deliverable sheet (this drawing has 11X17 AND HOUSEDIM, both carrying a VICINITY MAP label).
- STALE TEMPLATE DATA IS THE #1 HAZARD — new drawings are copied from a previous job and silently carry that job's data. On 260702 this bit TWICE: the title block still read job 251103 / Riderwood Dr / DeKalb / LL 147, and the flood note carried panel 13135C0016G which is a GWINNETT panel on a FULTON job. ALWAYS read every title-block attribute and every sheet note FIRST and diff against the job record before filling. Never assume a field is blank — assume it is wrong.
- FLOOD NOTES LIVE IN PAPER SPACE, NOT MODEL. Scan ALL layouts (and block defs) for existing flood/zone/FIRM/panel text and UPDATE the real one; do not add a new note. On 260702 a model-space note was added as a duplicate and had to be erased. Note there is also an unused block def 'A$C3840e5d8' (BLOCK_TB2) carrying yet another stale panel (13121C0087 F).
- Area on the job record is the HEATED FLOOR AREA (1st + 2nd floor), NOT the lot area — 260702 record said 2929 Sq.ft (1199+1730) while the lot is 10,212 SF from the 60.07' x 170' deed dims. Do not put the job-record area in a lot-area note.
- FEMA panel/zone/date are NOT in the job record's main text — they are under 'Surveying Details' (Flood Zone / FIRM Panel / Panel Date). Never guess a flood zone.
- 260702: title block filled from the job record — JOB_NO 260702, SITE_ADDRESS, REF DB 27530 Pg 262, LAND_LOT 90, DISTRICT 14th, COUNTY Fulton, PREP_FOR HOUSTON RESIDENTIAL RENTALS LLC, DATE 07/16/26 (from 358 HOUSE.txt), SUBDIVISION Lakewood Heights. Flood note on 11X17 corrected from the stale Gwinnett panel 13135C0016G to Fulton 13121C0359F eff 09/18/2013, and a duplicate model-space note erased. USER CONFIRMED: 'the flood note and date are good'.
- 260702: vicinity map — Google Static Maps (GOOGLE_MAPS_API_KEY lives in C:\dev\.env.dev.local, NOT this repo), zoom 14, scale 2, 640x640, red marker on the site address. Attached on 11X17 layer BLOCK_CLOSURE at the label's x with a 0.075" gap above it, 2.30" square. Verified exactly 1 raster on the sheet. Ran cleanly through dashboard approval.