L1 · DS-110

Driven Dimensions & Relationships

Express a part's dimensions as formulas of a single driver parameter so derived dimensions stay consistent when the driver changes - verified by the bench measuring the real OpenCascade bounding box against an exact target.

01
Challenge

Try this first — before any explanation.

The Bench loads a real build123d block whose length, width and height were each TYPED as separate constants. The target envelope is 60 x 30 x 15 mm: the width must always be half the length and the height a quarter of the length. Right now only the length is 60 - the width and height are hand-typed numbers that don't know what the length is. Change ONLY the driver L and watch: the box stays the wrong shape because width and height are frozen constants. You'll discover there is no set of three typed numbers you can defend - the moment the driver moves, two of them are wrong. The dimensions have to do the math themselves. Make result's real bounding box read exactly 60 x 30 x 15 by driving every dimension from L.

The Bench

This is real build123d on the OpenCascade kernel (Pyodide + OCP.wasm), rendered in the 3D viewer. Define result as a build123d solid. The autograder reads the part's ACTUAL bounding box - result.bounding_box().size - so you can't fake the shape with a printed number. Drive width and height from the single driver L, Run, and the measured envelope must hit 60 x 30 x 15 mm exactly.

PARAMETRIC CAD

Driven Dimensions & Relationships

This is real build123d on the OpenCascade kernel (Pyodide + OCP.wasm), rendered in the 3D viewer. Define result as a build123d solid. The autograder reads the part's ACTUAL bounding box - result.bounding_box().size - so you can't fake the shape with a printed number. Drive width and height from the single driver L, Run, and the measured envelope must hit 60 x 30 x 15 mm exactly.

02
Model

The idea, built visually.

Here is a block that's exactly right at one size. The question isn't how to box it once - you can, three numbers, done. The question is what happens when it has to grow. I type length 60, width 30, height 15, and it looks perfect. But those three numbers don't know about each other. Bump the length to 80 and the width stays 30, the height stays 15 - because 30 and 15 are numbers I typed, and a typed number can only ever be right for one size. The part drifts out of proportion and nothing warns me. So stop typing the result. The width isn't 30 - it's 'half the length'. The height isn't 15 - it's 'a quarter of the length'. Replace each constant with a relationship: width = L/2, height = L/4. Now there is exactly ONE number you set, the driver L, and the rest fall out of it as math. Grow L and the whole block scales in proportion, every time, automatically. You don't store the answer - you store the intent. And build123d hands this straight to a real kernel: Box(L, L/2, L/4) carves an actual solid in OpenCascade, and its bounding box is measured, not promised. Encode the rule once and the part can't drift out of spec.

▣ Stage animation: Dark navy canvas, IBM Plex Mono numbers. A blue manim block at 60 x 30 x 15, its three edge lengths labelled in crisp mono. A driver slider drags L: 60 -> 80. The length edge stretches to 80 while the width (frozen 30) and height (frozen 15) stay put - the block turns into a wrong, stretched slab, the now-incorrect width and height edges flashing warm --accent-warm (#FF9E4C). Split screen: on the left the typed constants width=30, height=15 crumble; on the right width = L/2 and height = L/4 type themselves and blue brackets snap each edge to its driven value. Re-drag L 60 -> 80 -> 120: the block now scales in perfect proportion at every size, all edges staying blue. A small Box(L, L/2, L/4) glows and a ghost OpenCascade bounding-box wireframe measures it live: 60 x 30 x 15. Kinetic type: 'one driver, every dimension - design intent, not three lucky numbers.'

03
Guided practice

Build it up, step by step.

Work in build123d algebra mode. Step A (worked): set a single driver L = 60 at the top, then build result = Box(L, width, height) - notice the length is already driven by L. Step B (fill the blanks): replace the two typed constants - the width should be L/2 and the height should be L/4, so write width = L / 2 and height = L / 4 ABOVE the Box call. You never type 30 or 15, only the rule once. Step C (check): the autograder reads result.bounding_box().size and needs exactly 60 x 30 x 15 mm (tol 0.1). Confirm that if you change L to any value the three edges stay in 4 : 2 : 1 proportion - that's the proof the dimensions are driven, not typed.

04
Feedback

How the Bench grades your run.

PASS WHEN PASS - measured bounding box is 60.0 x 30.0 x 15.0 mm. Every dimension is driven from the single parameter L (width = L/2, height = L/4), so the part holds its 4:2:1 proportion at any driver value. Ladder logs 'Driven dimensions: one parameter, exact envelope, 0 hand-typed derived values.'

  • Bounding box Y is wrong: the kernel measured your width but the target width is 30 mm. Don't type 30 - drive it: width = L / 2. With L = 60 that is exactly 30.
  • Bounding box Z is wrong: the target height is 15 mm. Don't type 15 - drive it: height = L / 4. With L = 60 that is exactly 15.
  • Bounding box X is wrong: the length must equal the driver L (60 mm). Pass L straight into Box as the first (length) argument - don't overwrite it with a constant.
  • The envelope is right at L = 60 but breaks if L changes - that means a dimension is still a typed constant, not driven. Express width and height as formulas of L (L/2 and L/4) so the proportion can't drift.
  • result must be a build123d solid (e.g. Box(...)). The autograder calls result.bounding_box().size on the real kernel, so result has to be the part itself.
05
Retrieve & space

Bring back what you've already mastered.

  • build123d recall: write the one line that makes a solid block 40 mm long, 20 mm wide and 10 mm tall. (Box(40, 20, 10) - length, width, height.)
  • Driver/derived recall: a plate's width must always be one third of its length L. Without typing a number, give the expression for width. (width = L / 3.)
  • Bench-contract recall: the autograder grades the part's envelope by reading which property of result? (result.bounding_box().size, the X/Y/Z extents in mm.)
06
Mastery gate

What you must demonstrate to advance.

Submit a build123d program with exactly ONE driver L and result = Box(L, L/2, L/4) whose measured bounding box is 60 x 30 x 15 mm (tol 0.1), with zero hand-typed derived dimensions - change L and the 4:2:1 proportion must hold. Pass unlocks Lesson 2.2 (Constraints & Valid Ranges).

07
Project

How this feeds your build.

Not a capstone lesson. This driven block is the seed of every parametric part later in the course: in M2.2 you fence the driver with valid-range guards; in M3 you mate driven parts whose mating faces stay aligned because their dimensions scale together; in the M5 capstone, 'one driver, every dimension' is what lets the optimizer resize a device without you re-typing a single number. Store intent, not three lucky numbers.