Skip to main content
Build a panelling script that distributes geometry across the surface of a complex mesh, with curvature-aware flow and consistent overlap. This is a demanding task with multiple interacting constraints, and a good showcase for what flagship coding models can do. Time: 15 minutes (advanced) You’ll need: Complete Generate Rhino scripts with AI first. A target mesh in Rhino plus a small mesh box (the unit panel) on a separate layer.
For the deeper physics-based refinement pattern that follows, see this 12 minute walkthrough.

What you’re building

Given:
  • A target mesh to clad
  • A small mesh box (the shingle unit)
  • An overlap percentage
The script should:
  1. Generate streamlines across the target mesh that respond to curvature
  2. Space streamlines so shingles in adjacent rows don’t overlap too much or leave gaps
  3. Place shingle geometry along each streamline with consistent overlap

Why this is hard

Two constraints fight each other:
  • Flow logic wants lines to follow curvature, lines bunch and spread naturally
  • Panel logic wants uniform distribution, evenly spaced, consistent overlap
Fix one and you break the other. The solution flagship models tend to land on is to grow streamlines incrementally, place one, check it, offset the next from it, rather than generating them all in parallel.

1. Set up

Have the target mesh on the canvas plus a small mesh box separately. The script will read the box’s dimensions rather than hard-coding panel sizes. Drop a Code node, set output to Rhino Python, select it, and switch the chat model to Claude Opus.

2. Prompt with the “ask questions first” pattern

Use streamlines as the centre lines for shingle geometry that should
be evenly distributed across the surface. Streamlines are important
because shingles need to gradually shift in direction in response to
mesh curvature. Shingles should always overlap by a fixed amount.

Let's use a mesh box of given dimensions for the shingle, then generate
streamlines that are valid centre lines for rows of shingles.

Ask questions if you need things clarified before writing the code.
The “ask questions if you need clarification” line is one of the most useful tricks in this workflow. Opus will come back with things like “rectangular shingle with length, width, thickness?” and “overlap along streamline direction, lateral overlap between streamlines, or both?”, exactly the ambiguities you need to pin down before it writes 700 lines of code.
For this kind of constraint-heavy generative work, expect the script to land at around 1,000 lines. A complete rewrite costs around 500-900 credits (~50 cents). Cheaper models will struggle.

3. Run with conservative parameters first

Don’t expect the first run to be perfect. The natural loop:
  1. Run with conservative parameters (small overlap %, small streamline count)
  2. Screenshot the result and paste it back into chat
  3. Describe what’s wrong, e.g. “overlap along the curves is good, but between the curves we aren’t computing properly”
  4. Let Opus diagnose and rewrite

4. Split complex scripts into explicit steps

Once the script grows, ask Opus to split it:
Let's do this as a two-step process. First, create the curves and show
a preview. Then generate the mesh geometry.
Huge quality-of-life improvement. You can validate the streamline layout before committing to generating thousands of shingle meshes.

5. Add real-world placement constraints

The base script gets you decent distribution. To push it toward how you’d actually shingle a roof, layer in:

Bottom-up placement

Don't worry about streamlines for now. Place panels one at a time,
starting at the bottom of the mesh and working up so panels overlap
the one below.

Model the orientation of each panel and keep it negotiating between
flow along mesh curvature and the direction of neighbouring panels.
Opus will rewrite ~800 lines. You should see more consistent direction between shingles than the base script, though the top of the mesh will still be problematic.

Multiple panel types and post-placement relaxation

Screenshot the result and describe what’s wrong:
We have a lot more than 10% overlap on many panels. Can we iteratively
move shingles after placement to ensure desired overlap? Also let's
allow three panel types of different dimensions so we can minimise
gaps by picking the right one during placement.
Model two extra mesh boxes (one longer, one shorter) so you have three panel types. Opus will rewrite (~1,400 lines) with post-placement relaxation and per-panel-type selection.
Opus’s own description of the approach it picks (post-placement relaxation, curvature-based panel selection) is often more sophisticated than what you’d prompt for directly. Read what the model says it’s doing before running. It’s how you learn what’s actually feasible.

Smoothing and curvature-matched panel types

We need more smoothing between shingles. There are extreme changes in
direction in some places. We also need to be more careful about
preserving the overlap, because shingle positions are being pushed too
far apart. And panel type should be based on mesh curvature, we
shouldn't have nearby shingles with dramatically different types.
At this point Opus is doing selective edits rather than full rewrites, which keeps cost down.

6. Use logs as feedback

When relaxation isn’t converging, the script’s own console output becomes useful feedback. Pass Opus:
  • A screenshot showing “good” and “bad” regions
  • The console logs with the overlap error metrics
  • A clear description of the target aesthetic
The max overlap error is decreasing but the average isn't. Here's a
region that looks great and a region that doesn't. Resolve the
convergence.
This is the same debugging loop you’d use writing this by hand, except Opus reads the logs.

An honest take on directionality

Halfway through, you may notice your shingles have a visual directionality (a leading edge) that’s making placements look worse than they are. Try the same script with non-directional panels (symmetric meshes), often the orientation problem disappears entirely and the result is noticeably cleaner. This is a design decision, not a code problem. Worth trying before pushing more constraints into the model.

What this is and isn’t

What this is: placement logic that respects real physical behaviour, shingles lap over each other, orientations smooth out, panel sizes vary with curvature. What this isn’t (yet): true fabrication awareness. For that you’d need:
  • Unrolling panels to flat sheets for cutting
  • Nesting unrolled panels onto stock material
  • Bending / curvature limits per panel material
  • Fastener / joint geometry
  • Cut files (DXF, SVG) exported per panel
  • Labelling panels for on-site assembly
All solvable with the same pattern (Opus + Rhino Python + iterate with screenshots and logs), but they’re a separate project.

Takeaways

  • Use Opus for constraint-heavy generative scripts. Cheaper models will struggle.
  • “Ask questions if you need clarification” up front saves rewrites later.
  • Split complex scripts into explicit steps (preview → commit).
  • Pass screenshots, logs, and target aesthetic together for the best iterations.
  • Test with non-directional panels before assuming orientation is a code problem.

Next steps