SlipcurveEstimating and takeoff

Estimating where every number can be opened and read back

Quantities taken off the drawing, then price book to assemblies to crews to burden to a markup ladder to tax — with the arithmetic behind any line openable on that line, and one trade-class classification shared by the whole platform so an estimate, a commitment and an actual cost can be joined.

The build-up, and the drawer under each line

A unit rate is not a number somebody typed. It is material plus labour plus equipment, where labour is a crew composition at wage rates with burden applied, then a markup ladder, then tax — and the reason estimates are argued about is almost never the total. It is that nobody downstream can see which of those steps produced the difference.

Every line here carries a drawer that shows how the number was built, step by step, in the order the steps were applied. The value of that is not transparency as a virtue: it is that a line whose labour looks wrong can be diagnosed in the estimate rather than in a post-mortem.

  • Price book of materials with unit, unit cost, spec section, lead time, and — the pair that makes escalation computable — the date priced on and the price source. Most item masters carry the cost and not those two, which means escalation becomes a guess about a number whose age nobody recorded.
  • Assemblies that compose priced items into a single measured unit.
  • Crews with composition and wage rates, and burden applied as its own step rather than folded invisibly into a rate.
  • A markup ladder — overhead, profit, bond, contingency, fee — applied in a stated order, because markup on markup is order-dependent and two estimators applying the same five percentages in different orders get different totals.
  • Tax as the last step, on the base the jurisdiction actually taxes.

One trade-class table, and one code parser

This is the part of the estimating story that is unusual, and it is worth explaining because the failure it fixes is invisible.

Classification by trade class is what lets an estimate, a commitment, an invoice, a submittal and an actual cost all be talked about as the same trade. Getting a trade class out of a cost code looks trivial, and the obvious implementation — take the first two digits you find — is wrong in ways that never announce themselves:

A-101
A drawing number. The naive parse files it under class 10, Specialties.
2018 mix design
A year. Filed under class 20, which does not exist.
3 30 00
A concrete code with the leading zero dropped. Filed under class 30, which is Reserved for future expansion.
19 00 00
Class 19 is reserved and unassigned. Reserved and unknown are different answers here, because a user who typed 19 needs different advice from one who typed 90.

None of those throws an error. None renders visibly odd. The symptom is a record filed under a trade it does not belong to, or a phantom class in a rollup whose grand total still ties — which is the hardest kind of wrong to notice.

There is no default trade class, ever. A code that cannot be read becomes a named unclassified row that sorts last — never a guess, and never dropped.

Dropping it would be worse than guessing: a rollup that quietly omits the work it could not place reads as a complete rollup. So the parse anchors on the published DD SS TT shape rather than scanning for digits, validates against the assigned classes, and refuses the reserved ones by name. Every module in the platform that needs a trade class calls that one parser, and a build gate asserts there is exactly one table and no second parser anywhere.

On licensing: The classification is a trade-class taxonomy keyed by two-digit class codes and named by plain trade names; it does not present or reproduce any third party's classification standard. What ships is the class-level structure plus a curated working subset of Level-2 groups — the minimum needed to organise a takeoff. The full Level-2 list and Levels 3 and 4 are deliberately not included, and a commercial deployment should hold a classification licence. That is stated here rather than left to be discovered.

Counts, lengths and areas: the takeoff measure model

A symbol library that a quantity sheet can also get a quantity from is a double-count waiting to happen. So the symbol catalogue here is a catalogue both ends read, and never a second place either of them can get a number from.

What it does carry is the measure class, and that is a model decision rather than metadata, because the class decides which arithmetic runs:

The measure class on a symbol decides how a quantity is derived from it. Volume is deliberately absent from this table.
ClassPlaced asUnitQuantity from
Pointa pointeacount
Linea polylinemrouted length, with rise and drop where the run leaves the plane
Areaa closed regionplan area net of deducts
Annotationanywherenone — structurally incapable, not conventionally empty

Volume is not a placement class. It is always derived from an area and a depth, through one door, and the result names which method produced it: mid-ordinate, prismoidal or average-end-area. On the battered excavation in the product's own known-answer test — 12.65 m by 7.50 m, 1.9 m deep, battered 1 in 3, with a working-space allowance — the taught mid-ordinate rule answers 241.717 m³ and the prismoidal formula answers 241.971 m³. A quantity whose method is not stated is a quantity two people can disagree about while both being right.

That difference is 0.254 m³, and the interesting part is that it is predictable: for a rectangle battered on all four sides it has the closed form D · run² / 3, and the engine checks its own computed difference against that closed form and reports whether the two agree. A silently wrong batter therefore shows up as a disagreement rather than as a plausible number. Average end area is the third method and it is not a third answer to the same shape: it measures along a chainage from cross-sections, which is how public agencies measure earthwork, and it is offered where that is the contract's measurement rule.

Section through a battered excavation, with the mid-depth plane drawn A cross-section through an excavation 1 900 millimetres deep with both faces battered at 3 vertical to 1 horizontal, so the horizontal run of each face is 633.33 millimetres. A strip footing sits at the bottom of the cut with 525 millimetres of working space outside its face. A dashed horizontal line is drawn at mid-depth, 950 millimetres down, and it meets the sloping face 841.67 millimetres out from the footing face — exactly half the run further out than the bottom of the cut, and half the run short of the top. The topsoil strip is measured at the top offset of 1 158.33; the bulk excavation is measured at the mid-depth offset of 841.67. 3 1 525 run 633.33 1 158.33 — topsoil strip offset 1 900 deep ground 841.67 — bulk offset mid-depth plane 841.67 mm at depth 950 mm STAGE PLAN OFFSET FROM THE FACE WHY topsoil strip 525 + 633.33 = 1 158.33 covers everything disturbed — the TOP of the cut bulk excavation 525 + 316.67 = 841.67 volume = mid-depth plan area × depth
The same cut as the volume above: 1.9 m deep, battered 1 in 3, with 525 mm of working space outside the face of the footing. The mid-depth line is drawn because it is the rule — a battered prism's volume is its mid-depth plan area times its depth, so the bulk excavation's plan offset carries half the run, while the topsoil strip, which covers everything that will be disturbed, carries all of it. Measuring the bulk at the full run over-measures its plan area by about 12.3 % on the source project, and the sheet still foots and still looks entirely normal.

Two further refusals carry the rest of the model. A class-level unit default is rejected — the unit belongs on the item, because class 03 alone is concrete in cubic metres, formwork in square metres of contact area and rebar in kilograms. And measurement produces nothing until the regime is named: builder's quantity surveying measures what must be bought and done, while unit-price contract measurement measures what the owner pays for, and under a unit-price regime a working-space allowance is refused by name rather than quietly added.

The perimeter identity every girth-derived item inherits

Trench, footing, formwork, foundation drain, drain rock, perimeter insulation, the longitudinal bars: on a low-rise building a large share of the take-off is something running around the outside of it, measured on a line set in or out from the outside face. Get that one line wrong and every item derived from it is wrong together, by a consistent percentage, with a grand total that still ties.

So the offset is one engine function with known-answer tests rather than a column on a sheet. Move the measuring line perpendicular to itself by d and the perimeter changes by exactly 8d — inward or outward, however many notches, returns and recesses the plan carries.

At every external corner the two lines each shorten by d; at every re-entrant corner they each lengthen by d. For any closed rectilinear figure the number of external corners exceeds the number of re-entrant ones by 4, so the adjustment is always 4 × 2d.

The engine refuses the ambiguous input rather than guessing at it. The course sheets this was recovered from write the same rule three ways depending on what HA means on that page — the wall thickness on one, the offset itself on another — so the API takes one unambiguous parameter, the signed perpendicular offset, and refuses a value passed as HA by name. A mid-side recess supplied with only its length and no depth is refused too: measuring it would put 45 110 where 39 630 belongs, a 13.8 % error inherited by every girth-derived item on the job.

A rectilinear footprint offset in and out, and the girth each offset produces A building footprint 11 280 by 7 925 millimetres with one recess 3 350 long and 610 deep in its south side, six convex corners and two re-entrant corners. Four further outlines are drawn parallel to it, two outside at 262.5 and 150 millimetres and two inside at 187.5 and 825 millimetres, and a detail of the south-west corner at four times plan scale separates them. The reference perimeter is 39 630 millimetres, and each parallel outline measures exactly 39 630 plus or minus eight times its offset: 41 730, 40 830, 38 130 and 33 030. The recess grows wider, not narrower, as the outlines step inward, and the corner difference stays at four throughout. 11 280 7 925 recess 3 350 × 610 DETAIL · SOUTH-WEST CORNER · 4 × PLAN SCALE 262.5 out 150 out 187.5 in 825 in P1 BAND OFFSET d GIRTH mm GIRTH ON THE MOVING LINE drain gravel 262.5 out 41 730 perimeter drain 150 out 40 830 P1 · outside face of ftg 0 39 630 trench centreline 187.5 in 38 130 native fill u/s ftg 825 in 33 030 33 030 mm 39 630 − 8 × 825 = 33 030 convex 6 − re-entrant 2 = 4 values from tools/cases/qs_geometry.js
The footprint, the four bands and every girth on them are ASSIGNMENT 4's numbers out of tools/cases/qs_geometry.js, where they are asserted to the millimetre. Watch the recess: it gets wider as the line steps inward, which is exactly why a girth cannot be got by shrinking the figure. It comes from the corner count instead — for any closed rectilinear outline, convex minus re-entrant is 4 — so moving the measuring line by d moves the perimeter by exactly 8d. One formula, an L-shaped plan with three corner deducts, no special case.

Quantity takeoff from a PDF drawing, and the scale that makes it mean anything

Quantities are measured on the sheet itself: pick a drawing that carries a PDF, set the page scale, then count symbols, trace a length, or close an area — with an opening deducted by drawing it as a hole inside the area above it. Orthogonal constraint holds a segment to the axis it is mostly moving along, and snapping lands a click on the nearest existing corner or on the perpendicular foot of the nearest edge.

A page with no scale yields no measurement. Not 1:1, not the previous page, not the last scale used.

That refusal is the reason this exists rather than a feature of it. An unscaled page read at 1:1 does not produce an error or a blank — it produces a number, in the right units, in the right column, on the right line, three orders of magnitude wrong, and every total below it still foots. A count is the one exception, because counting is scale-free, and every measurement says which of the two it is.

The scale is a record rather than a setting, and it carries how it was obtained. Stated is the scale printed on the sheet, picked from the architectural, civil or metric list — and all three lists reduce to one ratio, because PDF user space is 1/72 inch: a quarter-inch-to-the-foot sheet, 1/4 in = 1 ft, is a scale factor of 48; 1 in = 50 ft is 600; 1:100 is 100. Calibrated is two points clicked against a dimension you could read — and the two points and the distance are stored, so the calibration can be re-checked later rather than merely believed. Derived is a scale inherited by an apply-to-all, naming the page it came from, because a sheet that inherited a scale and a sheet that was scaled on its own evidence are not the same claim. A calibration is never quietly snapped to a nearby listed scale.

Objects hold their raw geometry, never a quantity. Correct a scale and every length and area on that page re-derives from the same points with nothing redrawn — and anything measured under the older scale is listed rather than silently changed. What is sent to the estimate is a takeoff line, not a number: a hole becomes a signed row that prints under its area, a line somebody has edited by hand is kept with what the drawing now says recorded beside it, and an object whose item has no unit is refused by name rather than inheriting the geometry's unit. A non-uniform sheet — a civil profile with an exaggerated vertical scale — has its areas and volumes refused by name, where the market leader's own documentation says such a drawing cannot be used at all.

Formwork, and why contact area is its own measurement

Formwork is the standing example of why a unit cannot be inherited from a trade class. Concrete is priced by volume; the forms that shape it are priced by the square feet of contact area — the surface of the concrete the form touches — and the two quantities scale completely differently. A thin tall wall is cheap in concrete and expensive in forms.

There is no formwork symbol you count. There is a wall whose contact area you measure: both faces of a wall, the two sides and the soffit of a beam, the underside of a slab plus its edge forms. Because contact area is what is measured, the estimator does not need the form design settled at takeoff — only which surfaces need forms. That is the reason the measure class sits on the item and not on the class, and the reason a counted default that is right 93 per cent of the time inside one electrical class is exactly wrong the moment it escapes it.

From estimate to bid to commitment

  • Bid packages with a side-by-side levelling matrix: base bid, alternates, adjustments, and the spread against the estimate — which is the number that tells you whether a low bid is competitive or has misread the scope.
  • The award creates the commitment. That is the correct direction of flow: the subcontract exists because a bid was accepted, rather than being typed a second time.
  • Prequalification gating the award, with an experience modification rate on an inverted score curve, certificate-of-insurance validity and expiry, bonding capacity, current backlog, single-project limit and a utilisation flag.
  • Cost benchmarks: estimate-versus-actual unit rates by trade class, fed back as next-bid rates. That database is one job deep, which is a structural consequence of holding one project at a time rather than a missing feature, and the page says so.
  • Every sheet leaves as a real .xlsx workbook — typed cells and live formulas, with the rows, columns, sort and filter exactly as they stand on screen, rather than a CSV given a spreadsheet extension.

Change events, priced with their basis stated

A change event carries requests for quotation and, on the resulting number, a pricing basis chip: accepted quote, low quote, or rough order of magnitude. A change order priced off a ROM and a change order priced off an accepted subcontractor quote are different claims about the same money, and a schedule of values that does not distinguish them invites an argument later that nobody has the evidence to settle.

What this does not do

  • Optical character recognition is English-only and on request. A scan with no text layer can be recognised through the vendored Tesseract engine from Settings, with the engine version and the confidence printed beside the result. It reads English only, runs only on the sheet you ask for, and recognised text is a search aid, never a measurement.
  • Sending a marked-up sheet as a PDF. A sheet can be marked up here — notes, callouts, clouds, arrows, stamps and freehand, each carrying its author and its accept or reject — and two issues of one drawing can be overlaid with the changes found and clouded. What does not exist is a flattened or annotated PDF export or a print, so a markup reaches someone who does not open this workspace only through the workbook, never as a PDF.
  • A commercial cost database. There is no RSMeans-style priced catalogue included. The price book is yours to populate, and the benchmark history is only as deep as the jobs you have run through it.
  • Any third party's classification standard. The classes are named by trade and keyed by a two-digit code.
  • Symbols beyond classes 25 to 28. The shipped catalogue covers integrated automation, electrical, communications and electronic safety and security. Other classes have no artwork, and forty-five of the shipped symbols carry our own outline designator rather than the conventional glyph — flagged as such on the page rather than passed off.
  • Digital plan rooms and outbound invitations to bid. A local bid board is not a bidder network, and outbound email with response tracking needs a server.

Related