FCC Platform Integration — HiStruct Parametric Components, PVC, and Project Spaces
This document covers the full stack from authoring an FCC component in FCS to its lifecycle in the HiStruct web platform: component manifests, parameter-item UI declarations, PVC storage, revision management, and project-space types.
1. FCC Project Folder Structure
An FCC (FemCAD Component) project is a folder whose name ends in .fcc:
MyBuilding.fcc/
├── fcscdm.json ← component manifest (ComponentDefinition)
├── Main.fcs ← root computation entry-point
├── Inputs.fcs ← Fcs.Parameter.Item* declarations
├── *_updated.fcs ← test snapshot: pre-set parameter values
├── *_viewAll.fcs ← view-all entry-point (imports Main.fcs)
└── …sub-folders…
The *_updated.fcs / *_viewAll.fcs naming follows the pattern <ComponentName>_updated.fcs.
2. fcscdm.json — Component Manifest (ComponentDefinition)
The manifest tells HiStruct how to render, parameterise and evaluate the component.
Key fields (from FCS.HiStruct/API/ComponentDefinition.cs):
| Field | Type | Description |
|---|---|---|
FccRef |
string | Path to the .fcc folder |
ParameterDescriptions |
object | Points to the FCS variable that exports Fcs.Parameter.Item* declarations |
Views |
array | List of view configurations (camera presets) |
Reports |
array | Optional report page definitions |
EvaluationEntryPoint |
string | The *_updated.fcs file to execute |
3. Fcs.Parameter.Item* — Parameter UI Type System
Parameter items declare the user-facing input form. They are pure FCS objects — no special keyword, just object constructors.
3.1 Fcs.Parameter.ItemDouble — Numeric input
SpanDef := Fcs.Parameter.ItemDouble{
HumanName := "Building span",
Identifier := NameSpace + "B", # path in the PVC property tree
DefaultUnit := "m",
Min := 6.0,
Max := 60.0,
Step := 1.0,
EditabilityCondition := "" # "" = always editable
}
Read-only (output) field:
FloorAreaDef := Fcs.Parameter.ItemDouble{
HumanName := "Floor area",
Identifier := NameSpace + "area_floor",
DefaultUnit := "m2",
EditabilityCondition := "False" # "False" = always read-only
}
Conditionally visible:
HeightTaxDef := Fcs.Parameter.ItemDouble{
HumanName := "Height tax",
Identifier := NameSpace + "HeightTax",
VisibilityCondition := NameSpace + "HeightTaxVisibility",
DefaultUnit := "%"
}
3.2 Fcs.Parameter.ItemInteger — Integer input
BayCountDef := Fcs.Parameter.ItemInteger{
HumanName := "Number of bays",
Identifier := NameSpace + "N",
Min := 1,
Max := 20
}
3.3 Fcs.Parameter.ItemList — Dropdown / radio list
PaintDef := Fcs.Parameter.ItemList{
HumanName := "Paint color",
Identifier := NameSpace + "paintLayerKey",
List := ListType_PanelColor # array of {Key, Label} objects
}
3.4 Fcs.Parameter.ItemArray — Repeating sub-class table
TreeTableDef := Fcs.Parameter.ItemArray{
HumanName := "Table of trees",
Identifier := NameSpace + "inTreeArray",
ElementPrototype := TreeClassType, # ItemClass defining one row
EditableCount := True # user can add/remove rows
}
For the older res.fit.InputItemArray pattern, including count assumptions and PVC row paths, see 27-FCC-INPUT-ITEM-ARRAY.md.
3.5 Fcs.Parameter.ItemClass — Group / nested page
DimensionsPage := Fcs.Parameter.ItemClass{
HumanName := "Dimensions",
ClassTypeName := "DimensionsType", # unique type name for serialisation
Items := [
SpanDef,
EavesDef,
RidgeDef,
BayCountDef,
FloorAreaDef # read-only summary
]
}
AllItems := [ DimensionsPage ]
The top-level export convention used by HiStruct: name the root array AllItems or expose a *_ParameterItemClasses variable:
# from new-ParkTrip.fcc/main.fcs
input := InputClass{ NameSpace:="input." }
InputPageTrees_ParameterItemClasses := input.InputPageTrees
3.6 Fcs.Parameter.ItemAction — Button / trigger
RecalcAction := Fcs.Parameter.ItemAction{
HumanName := "Recalculate",
ActionName := "recalc",
HmtlContent := "",
CssStyleClass := "btn-primary"
}
3.7 Fcs.Parameter.ItemComment — Static text block
InfoText := Fcs.Parameter.ItemComment{
HumanName := "",
HumanDescription := "Set the span before the eaves height."
}
4. NameSpace — Parameter Path Prefix
In multi-level component hierarchies, NameSpace prefixes all Identifier values so they are unique in the flat PVC property map:
NameSpace := "" # top-level component (no prefix)
# or:
NameSpace := "site." # nested under "site"
NameSpace := "site.definitionBuildingsBase[0]." # nested + indexed
This convention ensures that Identifier := NameSpace + "B" resolves to "site.definitionBuildingsBase[0].B" in the PVC store.
5. _updated.fcs — Parameter Snapshot / Test File
The _updated.fcs file is the test-harness entry point. It imports the main component and then overrides individual parameters using deep property-path syntax:
# from benchmark-HBC-2/Buildings.fcc/BuildingsComponentMain_updated.fcs
import "../HiStruct_BuildingConfigurator2/Geometry/BuildingsComponentMain_updated.fcs"
site.definitionBuildingsBase[0].inWidth_m := 24
site.definitionBuildingsBase[0].inLength_m := 48
site.definitionBuildingsBase[0].inEaveHeight_m := 6
site.definitionBuildingsBase[0].inRoofPlaneSlope_per := 10
# inline array/class construction
site.definitionBuildingsBase[0].inRoofPlaneProperties_CtArray := [
RoofSectionSegmentInput{
inRoofPlaneSlope_deg=10,
roofSlopeMultiplierId="upwards",
inRoofSlopeInputMethod="percent",
inRoofPlaneWidth_m=6
}
]
# color / string properties
site.wallSheetingInput.pur.inColorSchemeVertical := "singleColor"
site.wallSheetingInput.pur.inColorSchemeOutsideColorRal := 7035
Property naming conventions
| Prefix | Meaning |
|---|---|
in* |
Input parameter (user-editable) |
out* |
Output / computed value (read-only) |
is* |
Boolean flag |
definition* |
Sub-object that collects related inputs |
*Setting* |
Optional configuration sub-object |
_m |
Value in metres |
_mm |
Value in millimetres |
_deg |
Value in degrees |
_per |
Value in percent |
_fra |
Value as fraction (0–1) |
6. PVC — Parameter Value Change Lifecycle
PVC (Parameter Value Changes) is the delta-encoding store that records every parameter change made by the user or by automation.
Delta-encoding mechanism
The platform stores only the delta (changed values) against the component's default state. When a component is evaluated:
- The default parameter values are loaded from the
.fcsfiles. - The saved PVC delta is applied on top.
- The resulting complete parameter set drives the FLI evaluation.
This means the _updated.fcs snapshot is the server-side equivalent of "apply this PVC delta to the defaults".
PvcTransaction
Each user interaction results in a PvcTransaction:
| Field | Type | Description |
|---|---|---|
ComponentId |
GUID | Target component |
PropertyPath |
string | Dotted path, e.g. "site.definitionBuildingsBase[0].inWidth_m" |
OldValue |
JSON token | Previous value |
NewValue |
JSON token | New value |
Timestamp |
DateTime | When the change occurred |
Undo / Redo via ComponentValuesRevision
Revisions checkpoint the full PVC state. The UI undo/redo stack replays or reverses transactions between revision points.
ComponentValuesRevision
├── RevisionId
├── PvcSnapshot (JSON)
├── PublishedAt
└── IsPublished
7. ProjectSpace Types
A ProjectSpace is the tenant/project container that owns components. The Type field controls which features and templates are available:
| Type value | Description |
|---|---|
Default |
Standard FemCAD project |
Astron |
Astron Building Solutions integration |
Demo |
Public demo / showcase space |
GsiSilos |
GSI silo configurator |
Unihal |
Unihal industrial building configurator |
BuildingConfigurator |
Generic HiStruct building configurator (HBC-2) |
The ProjectSpace entity fields (from FCS.HiStruct/FCS.HiStruct.ModelsEF6/Models/Spaces/):
| Field | Description |
|---|---|
Id |
GUID primary key |
Name |
Human-readable name |
Type |
Enum (see table above) |
OwnerId |
User/organisation GUID |
Components |
Navigation: list of Component objects |
8. AppComponent REST API
Components are evaluated server-side via the AppComponent API:
POST /api/spaces/{spaceId}/components/{componentId}/app-component-expression
Body: { "expression": "...", "pvc": { ... } }
The expression is plain FCS code that can reference the component's parameter tree. The server evaluates it and returns the result as JSON.
Used for:
- Computing derived properties on demand.
- Running analysis without full page reload.
- Returning HiScene JSON for 3-D preview updates.
9. Complete Inputs.fcs Pattern (PortalFrame Example)
# from LabComponents/PortalFrame.fcc/Inputs.fcs
NameSpace := "" # set by caller when nesting
SpanDef := Fcs.Parameter.ItemDouble{
HumanName := "Building span",
Identifier := NameSpace + "B",
DefaultUnit := "m",
Min := 6.0, Max := 60.0, Step := 1.0
}
EavesDef := Fcs.Parameter.ItemDouble{
HumanName := "Eaves height",
Identifier := NameSpace + "He",
DefaultUnit := "m",
Min := 2.5, Max := 15.0, Step := 0.25
}
# Read-only computed output
FloorAreaDef := Fcs.Parameter.ItemDouble{
HumanName := "Floor area",
Identifier := NameSpace + "area_floor",
DefaultUnit := "m2",
EditabilityCondition := "False"
}
DimensionsPage := Fcs.Parameter.ItemClass{
HumanName := "Portal Frame — Dimensions",
Items := [ SpanDef, EavesDef, FloorAreaDef ]
}
AllItems := [ DimensionsPage ]
10. Complete InputClass with ItemArray (ParkTrip Example)
# from new-ParkTrip.fcc/InputClass.fcs
NameSpace := ""
TreeClassType := Fcs.Parameter.ItemClass{
ClassTypeName := "TreeClassType",
HumanName := "Tree properties",
Items := [
Fcs.Parameter.ItemInteger{ HumanName:="Tree color", Identifier:="inColor" },
Fcs.Parameter.ItemInteger{ HumanName:="Tree height", Identifier:="inHeight" }
]
}
InputPageTrees := Fcs.Parameter.ItemClass{
HumanName := "Trees",
Items := [
Fcs.Parameter.ItemInteger{
HumanName := "Number of trees",
Identifier := NameSpace + "inNumberOfTrees"
},
Fcs.Parameter.ItemArray{
HumanName := "Table of trees",
Identifier := NameSpace + "inTreeArray",
ElementPrototype := TreeClassType,
EditableCount := True
},
Fcs.Parameter.ItemDouble{
HumanName := "Harvest potential",
Identifier := NameSpace + "outHarvestPotential",
EditabilityCondition := "False" # read-only output
}
]
}
# main.fcs wires it up:
# input := InputClass{ NameSpace:="input." }
# InputPageTrees_ParameterItemClasses := input.InputPageTrees
11. Quick Reference
# --- ItemDouble (editable) ---
Fcs.Parameter.ItemDouble{
HumanName:="Span", Identifier:=NameSpace+"B",
DefaultUnit:="m", Min:=6, Max:=60, Step:=1 }
# --- ItemDouble (read-only) ---
Fcs.Parameter.ItemDouble{
HumanName:="Floor area", Identifier:=NameSpace+"outArea",
DefaultUnit:="m2", EditabilityCondition:="False" }
# --- ItemList (dropdown) ---
Fcs.Parameter.ItemList{
HumanName:="Color", Identifier:=NameSpace+"colorKey", List:=colorOptions }
# --- ItemArray ---
Fcs.Parameter.ItemArray{
HumanName:="Rows", Identifier:=NameSpace+"rows",
ElementPrototype:=RowClassType, EditableCount:=True }
# --- ItemClass (group) ---
Fcs.Parameter.ItemClass{
HumanName:="Dimensions", ClassTypeName:="DimsType",
Items:=[item1, item2, item3] }
# --- _updated.fcs deep path ---
site.sub[0].inWidth_m := 24
site.sub[0].inArray := [ClassType{field=val}]
12. Relevant Source Locations
| Source | Path |
|---|---|
ComponentDefinition API model |
FCS.HiStruct/API/ComponentDefinition.cs |
ParameterDescriptions |
FCS.HiStruct/API/ParameterDescriptions.cs |
ParameterValues / PVC store |
FCS.HiStruct/API/ParameterValues.cs |
PvcBatchUpdateRequest |
FCS.HiStruct/API/PvcBatchUpdateRequest.cs |
Component EF model |
FCS.HiStruct.ModelsEF6/Models/Projects/Component.cs |
PvcTransaction |
FCS.HiStruct.ModelsEF6/Models/Projects/PvcTransaction.cs |
ProjectSpace EF models |
FCS.HiStruct.ModelsEF6/Models/Spaces/ProjectSpace*.cs |
ComponentUpdateService |
FCS.HiStruct.Services.Library/Services/ComponentUpdateService.cs |
AppComponentEvaluationService |
FCS.HiStruct.Services.Library/Services/AppComponentEvaluationService.cs |
ComponentsApiController |
FCS.HiStruct/WebApp/Controllers/Api/ComponentsApiController.cs |
PvcStoreController |
FCS.HiStruct/WebApp/Controllers/Api/PvcStoreController.cs |
13. Relevant Test Folders
| Folder | Feature |
|---|---|
new-ParkTrip.fcc/ |
ItemArray, nested ItemClass, NameSpace prefixing |
LabComponents/PortalFrame.fcc/ |
Full Inputs.fcs with all item types |
LabComponents/SimplePageTest2.fcc/ |
ItemList, VisibilityCondition |
benchmark-HBC-2/ |
Deep _updated.fcs property paths, BuildingConfigurator |
new-HiDumbbell.fcc/ |
Constraint triggers, _viewAll.fcs pattern |
new-Speed2/ |
Multi-level configurator, distribution with ithparameters |
new-GsiSilo/ |
GsiSilos project-space component |
bug-AgriBuildingFlashing/ |
Full InputItem.fcs helper pattern with all 7 item types |