Configurator Patterns
This document covers the FCS patterns used to build reusable, parameter-driven configurators.
1. Single-file component (GClass / GBlock)
A simple reusable part can live in one .fcs file and be instantiated multiple times with different placements.
gclass {gcFence} filename "fence.fcs"
gblock {gbFence1} gclass {gcFence} lcs { Origin={0,0,0}, Axes=GCS.Axes }
gblock {gbFence2} gclass {gcFence} lcs { Origin={5,0,0}, Axes=GCS.Axes }
What this pattern gives you
- one source file for one logical component
- multiple placements without duplicating geometry code
- easy promotion from prototype to reusable building block
Typical use cases
- fence segments
- windows
- columns
- brackets, plates, stiffeners
Design advice
Keep the component file focused on geometry and internal calculations. Use the parent file to decide how many instances to place and where.
2. Parameter passing
gclass instances can receive parameters from the parent context.
gclass {gcWeight} filename "weight.fcs" parameters { H = T, B = T }
gblock {gbW1} gclass {gcWeight} lcs { Origin={0,0,0}, Axes=GCS.Axes }
This lets the parent drive child behavior without hard-coding dimensions inside the component file.
Good pattern
- define reusable child logic in
weight.fcs - pass only the values the child actually needs
- keep parameter names explicit and stable
GOTCHA: parameter typos fail silently
If you misspell a parameter name, FCS creates a new variable instead of overriding the intended one. That means the child file keeps using its default or internal value and nothing obviously crashes.
Example of the danger:
gclass {gcWeight} filename "weight.fcs" parameters { Heigth = T }
If the child expects Height, Heigth becomes a new variable and the override never happens.
Defensive practice
- copy parameter names directly from the child file
- keep naming conventions consistent
- test one instance before creating distributions of many instances
3. Conditional placement
A component can be placed only when a condition is true.
gblock {gbWindow} gclass {gcWindow} lcs { ... } if (buildingHasWindows)
Why this matters
Conditional placement is the backbone of configurators. It lets the same component definition support many variants without maintaining separate files.
Common conditions
- product options such as
buildingHasWindows - size thresholds such as
span > 8 m - feature toggles such as
showBracing - dependent logic such as
isEndBay && hasDoor
Pattern recommendation
Compute readable boolean variables first, then use them in if (...) clauses.
showWindowOnSideA = buildingHasWindows && facadeType == "Openings"
gblock {gbWindowSideA} gclass {gcWindow} lcs { ... } if (showWindowOnSideA)
That makes downstream debugging much easier.
4. Distribution — repeated elements
Use distribution when you need repeated placement of the same component along a rule.
distribution {dCols} gclass {gcColumn}
lcs { Origin={0,0,0}, Axes=GCS.Axes.Ry(-PI/2).Rx(PI/2) }
transformation translation direction {1,0,0}
repetitions spacings (columnSpacings)
specialization ithparameters {
ith 0 parameters { CssHead:= { h:=0.34 } },
ith 1 parameters { CssHead:= { h:=0.30 } }
}
What this pattern does
- places the same
gclassrepeatedly - moves each instance along a transformation rule
- supports per-index customization with
ithparameters
Best use cases
- column lines
- roof purlins
- facade rails
- bolts, anchors, repeated stiffeners
Key concepts
transformation translation direction {1,0,0}defines the placement axisrepetitions spacings (...)controls repetition count and spacing valuesspecialization ithparameterslets specific instances differ from the default
Why ithparameters is powerful
It allows one repeated system to still express local exceptions: first/last element conditions, edge cases, or architectural tweaks.
5. Multi-file architecture pattern
Real components usually outgrow a single file. A robust configurator often splits responsibilities across several files.
Recommended structure
Main.fcs— orchestration, imports, component assembly, top-level decisionsInputs.fcs— parameter definitions and UI itemsGeometry*.fcs— specific geometry generatorsMaterials.fcsorRules.fcs— shared calculations and design logic- feature files such as
Doors.fcs,Windows.fcs,Roof.fcs— isolated subsystems
Why split files?
- clearer ownership of logic
- easier reuse across multiple components
- lower risk when changing one subsystem
- simpler code review and debugging
Example layering
Main.fcs
- includes sub-files
- defines global dimensions and switches
- instantiates major
gclassorgblockstructures - combines geometry into the final output
Inputs.fcs
- defines
Fcs.Parameter.Item*entries - stores defaults, limits, units, visibility rules
- keeps UI logic separate from geometry logic
Geometry files
- build one subsystem each
- expose stable parameters to the parent
- avoid direct knowledge of unrelated subsystems
Practical rule
Keep files organized by responsibility, not by convenience. If a file mixes UI, geometry, API integration, and repeated calculations, it is usually a sign to split it.
6. Pattern selection guide
Start with a single file when:
- the component is still exploratory
- there is only one placement
- there are very few parameters
Move to gclass + gblock when:
- you need the same part more than once
- placement logic differs per instance
- parent and child should be separated cleanly
Move to distribution when:
- repetition follows a spacing rule
- the count may vary parametrically
- you need index-based customization
Split into multiple files when:
- the file is hard to navigate
- UI and geometry are interfering with each other
- multiple subsystems can evolve independently
7. Checklist for robust parametric components
- Model one reusable concept per file where practical.
- Pass parameters intentionally; do not rely on accidental globals.
- Watch for silent parameter-name typos.
- Use readable booleans for conditional placement.
- Prefer
distributionover manual repeated copy-paste. - Isolate UI, orchestration, and geometry into separate files as complexity grows.