@metamesh/generator-sdk 0.11.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +28 -0
- package/README.md +67 -66
- package/dist/contracts.d.ts +5 -5
- package/dist/contracts.d.ts.map +1 -1
- package/dist/docs/guides/authoring.md +114 -0
- package/dist/docs/guides/package.md +120 -0
- package/dist/docs/guides/parameters.md +429 -0
- package/dist/docs/manifest.json +2361 -0
- package/dist/docs/reference/fonts/FontSelection.md +14 -0
- package/dist/docs/reference/fonts/isFontSelection.md +10 -0
- package/dist/docs/reference/index/ArrayParameterDefinition.md +12 -0
- package/dist/docs/reference/index/BaseParameterDefinition.md +16 -0
- package/dist/docs/reference/index/BooleanParameterDefinition.md +12 -0
- package/dist/docs/reference/index/ChoiceOption.md +13 -0
- package/dist/docs/reference/index/ChoiceParameterDefinition.md +14 -0
- package/dist/docs/reference/index/ChoiceSetParameterDefinition.md +15 -0
- package/dist/docs/reference/index/ColorParameterDefinition.md +12 -0
- package/dist/docs/reference/index/ConditionExpression.md +36 -0
- package/dist/docs/reference/index/ContourAnchor.md +12 -0
- package/dist/docs/reference/index/ContourParameterDefinition.md +13 -0
- package/dist/docs/reference/index/ContourParameterUi.md +12 -0
- package/dist/docs/reference/index/ContourPoint.md +13 -0
- package/dist/docs/reference/index/ContourSegment.md +17 -0
- package/dist/docs/reference/index/ContourValue.md +14 -0
- package/dist/docs/reference/index/FontParameterDefinition.md +12 -0
- package/dist/docs/reference/index/FontSelection.md +14 -0
- package/dist/docs/reference/index/GeneratorDefinition.md +14 -0
- package/dist/docs/reference/index/GeneratorIssue.md +12 -0
- package/dist/docs/reference/index/GeneratorModule.md +15 -0
- package/dist/docs/reference/index/GeneratorModuleOptions.md +12 -0
- package/dist/docs/reference/index/GeneratorParamId.md +10 -0
- package/dist/docs/reference/index/GeneratorParams.md +12 -0
- package/dist/docs/reference/index/GeneratorPreset.md +14 -0
- package/dist/docs/reference/index/GeneratorProgram.md +13 -0
- package/dist/docs/reference/index/GeneratorServices.md +15 -0
- package/dist/docs/reference/index/GeneratorTextArcBaseline.md +18 -0
- package/dist/docs/reference/index/GeneratorTextLayout.md +13 -0
- package/dist/docs/reference/index/GeneratorTextMetrics.md +21 -0
- package/dist/docs/reference/index/GeneratorTextOptions.md +19 -0
- package/dist/docs/reference/index/MAX_CONTOUR_SEGMENTS.md +9 -0
- package/dist/docs/reference/index/MAX_SIDE_PROFILE_SEGMENTS.md +9 -0
- package/dist/docs/reference/index/NumberArrayItemDefinition.md +19 -0
- package/dist/docs/reference/index/NumberArrayParameterDefinition.md +12 -0
- package/dist/docs/reference/index/NumberParameterDefinition.md +19 -0
- package/dist/docs/reference/index/NumberParameterUi.md +14 -0
- package/dist/docs/reference/index/ParameterDefinition.md +9 -0
- package/dist/docs/reference/index/ParameterDefinitionDocument.md +12 -0
- package/dist/docs/reference/index/ParameterGroup.md +15 -0
- package/dist/docs/reference/index/ParameterIssue.md +17 -0
- package/dist/docs/reference/index/ParameterIssueCode.md +10 -0
- package/dist/docs/reference/index/ParameterIssueSeverity.md +9 -0
- package/dist/docs/reference/index/ParameterScaleReference.md +13 -0
- package/dist/docs/reference/index/ParameterUi.md +15 -0
- package/dist/docs/reference/index/ParameterValidationResult.md +14 -0
- package/dist/docs/reference/index/ParameterValue.md +9 -0
- package/dist/docs/reference/index/ParameterValues.md +9 -0
- package/dist/docs/reference/index/RowParameterUi.md +12 -0
- package/dist/docs/reference/index/ScalarParameterValue.md +9 -0
- package/dist/docs/reference/index/SideProfileAnchor.md +12 -0
- package/dist/docs/reference/index/SideProfileParameterDefinition.md +13 -0
- package/dist/docs/reference/index/SideProfileParameterUi.md +12 -0
- package/dist/docs/reference/index/SideProfilePoint.md +13 -0
- package/dist/docs/reference/index/SideProfileSegment.md +17 -0
- package/dist/docs/reference/index/SideProfileValue.md +14 -0
- package/dist/docs/reference/index/SourceVisibility.md +15 -0
- package/dist/docs/reference/index/StringArrayItemDefinition.md +11 -0
- package/dist/docs/reference/index/StringArrayParameterDefinition.md +12 -0
- package/dist/docs/reference/index/SvgParameterDefinition.md +12 -0
- package/dist/docs/reference/index/TextParameterDefinition.md +13 -0
- package/dist/docs/reference/index/UNPREPARED_GENERATOR_SERVICES.md +9 -0
- package/dist/docs/reference/index/cloneContourValue.md +10 -0
- package/dist/docs/reference/index/cloneSideProfileValue.md +10 -0
- package/dist/docs/reference/index/contourValuesEqual.md +10 -0
- package/dist/docs/reference/index/defineGenerator.md +10 -0
- package/dist/docs/reference/index/defineGeneratorModule.md +10 -0
- package/dist/docs/reference/index/definePresets.md +10 -0
- package/dist/docs/reference/index/evaluateCondition.md +13 -0
- package/dist/docs/reference/index/isContourValue.md +10 -0
- package/dist/docs/reference/index/isFontSelection.md +10 -0
- package/dist/docs/reference/index/isSideProfileValue.md +10 -0
- package/dist/docs/reference/index/sideProfileValuesEqual.md +10 -0
- package/dist/docs/reference/packages/GENERATOR_PACKAGE_FORMAT_VERSION.md +9 -0
- package/dist/docs/reference/packages/GeneratorAccess.md +9 -0
- package/dist/docs/reference/packages/GeneratorDefinitionIssue.md +14 -0
- package/dist/docs/reference/packages/GeneratorDefinitionParseResult.md +15 -0
- package/dist/docs/reference/packages/GeneratorDescriptor.md +9 -0
- package/dist/docs/reference/packages/GeneratorPackageManifest.md +11 -0
- package/dist/docs/reference/packages/GeneratorPackageSource.md +9 -0
- package/dist/docs/reference/packages/GeneratorPackageValidationError.md +12 -0
- package/dist/docs/reference/packages/GeneratorPreset.md +14 -0
- package/dist/docs/reference/packages/GeneratorRuntimeReference.md +15 -0
- package/dist/docs/reference/packages/InstalledGenerator.md +15 -0
- package/dist/docs/reference/packages/MAX_ARRAY_ITEMS.md +9 -0
- package/dist/docs/reference/packages/MAX_CONDITION_BRANCHES.md +9 -0
- package/dist/docs/reference/packages/MAX_CONDITION_DEPTH.md +9 -0
- package/dist/docs/reference/packages/MAX_DESCRIPTOR_LIST_ITEMS.md +9 -0
- package/dist/docs/reference/packages/MAX_GENERATOR_ID_LENGTH.md +9 -0
- package/dist/docs/reference/packages/MAX_GENERATOR_PACKAGE_BYTES.md +9 -0
- package/dist/docs/reference/packages/MAX_GENERATOR_PRESETS.md +9 -0
- package/dist/docs/reference/packages/MAX_METADATA_TEXT_LENGTH.md +9 -0
- package/dist/docs/reference/packages/MAX_PARAMETERS.md +9 -0
- package/dist/docs/reference/packages/MAX_PARAMETER_GROUPS.md +9 -0
- package/dist/docs/reference/packages/MAX_PARAMETER_OPTIONS.md +9 -0
- package/dist/docs/reference/packages/MAX_TEXT_PARAMETER_LENGTH.md +9 -0
- package/dist/docs/reference/packages/METAMESH_RUNTIME_VERSION.md +9 -0
- package/dist/docs/reference/packages/compareSemanticVersions.md +9 -0
- package/dist/docs/reference/packages/definitionIssuesFromZod.md +10 -0
- package/dist/docs/reference/packages/isRuntimeCompatible.md +9 -0
- package/dist/docs/reference/packages/parseGeneratorDefinition.md +9 -0
- package/dist/docs/reference/packages/parseGeneratorDescriptor.md +9 -0
- package/dist/docs/reference/packages/parseGeneratorPackageManifest.md +9 -0
- package/dist/docs/reference/packages/parseParameterDefinitionDocument.md +9 -0
- package/dist/docs/reference/packages/safeParseGeneratorDefinition.md +10 -0
- package/dist/docs/reference/packages/safeParseParameterDefinitionDocument.md +10 -0
- package/dist/docs/reference/packages/validateGeneratorPresets.md +10 -0
- package/dist/docs/reference/packages/validationErrorFromIssues.md +9 -0
- package/dist/docs/reference/packages/validationErrorFromZod.md +9 -0
- package/dist/docs/reference/parameters/EMPTY_SVG_PARAMETER_DEFAULT.md +9 -0
- package/dist/docs/reference/parameters/MAX_PARAMETER_ISSUES.md +9 -0
- package/dist/docs/reference/parameters/MAX_PARAMETER_ISSUE_MESSAGE_LENGTH.md +9 -0
- package/dist/docs/reference/parameters/MAX_PROJECT_SVG_PARAMETER_BYTES.md +9 -0
- package/dist/docs/reference/parameters/MAX_SVG_PARAMETER_BYTES.md +9 -0
- package/dist/docs/reference/parameters/ParamCodec.md +14 -0
- package/dist/docs/reference/parameters/ParamDecodeCode.md +9 -0
- package/dist/docs/reference/parameters/ParamDecodeError.md +12 -0
- package/dist/docs/reference/parameters/ParamDecodeIssue.md +14 -0
- package/dist/docs/reference/parameters/ParamParseResult.md +15 -0
- package/dist/docs/reference/parameters/PreparedParameters.md +12 -0
- package/dist/docs/reference/parameters/aggregateParameterIssues.md +10 -0
- package/dist/docs/reference/parameters/canonicalizeParameters.md +10 -0
- package/dist/docs/reference/parameters/createParamCodec.md +13 -0
- package/dist/docs/reference/parameters/getDefaultParameters.md +9 -0
- package/dist/docs/reference/parameters/normalizeParameters.md +13 -0
- package/dist/docs/reference/parameters/parameterValueEquals.md +9 -0
- package/dist/docs/reference/parameters/parseParameterIssues.md +15 -0
- package/dist/docs/reference/parameters/prepareParameters.md +13 -0
- package/dist/docs/reference/parameters/svgParameterBytes.md +9 -0
- package/dist/docs/reference/parameters/validateParameters.md +10 -0
- package/dist/docs/reference/runtime/ExecuteGeneratorOptions.md +18 -0
- package/dist/docs/reference/runtime/Export3mfRequest.md +18 -0
- package/dist/docs/reference/runtime/ExportError.md +13 -0
- package/dist/docs/reference/runtime/ExportSuccess.md +13 -0
- package/dist/docs/reference/runtime/ExportedFile.md +13 -0
- package/dist/docs/reference/runtime/GenerateRequest.md +16 -0
- package/dist/docs/reference/runtime/GeneratedModel.md +17 -0
- package/dist/docs/reference/runtime/GeneratedModelDelivery.md +12 -0
- package/dist/docs/reference/runtime/GeneratedPart.md +20 -0
- package/dist/docs/reference/runtime/GeneratedPartDelivery.md +13 -0
- package/dist/docs/reference/runtime/GeneratedPartsDecoder.md +24 -0
- package/dist/docs/reference/runtime/GeneratedPartsLimits.md +15 -0
- package/dist/docs/reference/runtime/GenerationError.md +13 -0
- package/dist/docs/reference/runtime/GenerationInvalid.md +13 -0
- package/dist/docs/reference/runtime/GenerationSuccess.md +15 -0
- package/dist/docs/reference/runtime/GeneratorExecutionGenerated.md +14 -0
- package/dist/docs/reference/runtime/GeneratorExecutionInvalid.md +13 -0
- package/dist/docs/reference/runtime/GeneratorExecutionResult.md +9 -0
- package/dist/docs/reference/runtime/MeshTopologyMode.md +10 -0
- package/dist/docs/reference/runtime/ModelBounds.md +12 -0
- package/dist/docs/reference/runtime/ModelStats.md +15 -0
- package/dist/docs/reference/runtime/ModelTimings.md +27 -0
- package/dist/docs/reference/runtime/ParsedGeneratorModule.md +9 -0
- package/dist/docs/reference/runtime/RuntimeError.md +14 -0
- package/dist/docs/reference/runtime/ValidateRequest.md +15 -0
- package/dist/docs/reference/runtime/ValidationError.md +13 -0
- package/dist/docs/reference/runtime/ValidationSuccess.md +13 -0
- package/dist/docs/reference/runtime/WorkerRequest.md +9 -0
- package/dist/docs/reference/runtime/WorkerResponse.md +9 -0
- package/dist/docs/reference/runtime/executeGenerator.md +10 -0
- package/dist/docs/reference/runtime/generationIssues.md +10 -0
- package/dist/docs/reference/runtime/isGeneratorModule.md +9 -0
- package/dist/docs/reference/runtime/parseGeneratedParts.md +15 -0
- package/dist/docs/reference/runtime/parseGenerationSentAt.md +10 -0
- package/dist/docs/reference/runtime/parseGeneratorModule.md +10 -0
- package/dist/generator-package/constants.d.ts +1 -1
- package/dist/generator-package/constants.js +1 -1
- package/dist/generator-package/validate-manifest.js +2 -2
- package/dist/parameters/issues.d.ts +2 -2
- package/dist/parameters/issues.js +2 -2
- package/dist/parameters/strict.d.ts +4 -3
- package/dist/parameters/strict.d.ts.map +1 -1
- package/dist/parameters/strict.js +2 -3
- package/dist/parameters/strict.js.map +1 -1
- package/dist/{execute-generator.d.ts → runtime/execute-generator.d.ts} +4 -4
- package/dist/runtime/execute-generator.d.ts.map +1 -0
- package/dist/{execute-generator.js → runtime/execute-generator.js} +1 -1
- package/dist/runtime/execute-generator.js.map +1 -0
- package/dist/{generated-parts.d.ts → runtime/generated-parts.d.ts} +1 -1
- package/dist/runtime/generated-parts.d.ts.map +1 -0
- package/dist/runtime/generated-parts.js.map +1 -0
- package/dist/{parse-generator-module.d.ts → runtime/parse-generator-module.d.ts} +2 -2
- package/dist/runtime/parse-generator-module.d.ts.map +1 -0
- package/dist/{parse-generator-module.js → runtime/parse-generator-module.js} +1 -1
- package/dist/runtime/parse-generator-module.js.map +1 -0
- package/dist/{worker-contracts.d.ts → runtime/worker-contracts.d.ts} +2 -2
- package/dist/runtime/worker-contracts.d.ts.map +1 -0
- package/dist/runtime/worker-contracts.js.map +1 -0
- package/dist/runtime.d.ts +8 -8
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +4 -4
- package/dist/runtime.js.map +1 -1
- package/dist/source-visibility.d.ts +2 -3
- package/dist/source-visibility.d.ts.map +1 -1
- package/package.json +4 -3
- package/dist/execute-generator.d.ts.map +0 -1
- package/dist/execute-generator.js.map +0 -1
- package/dist/generated-parts.d.ts.map +0 -1
- package/dist/generated-parts.js.map +0 -1
- package/dist/parse-generator-module.d.ts.map +0 -1
- package/dist/parse-generator-module.js.map +0 -1
- package/dist/worker-contracts.d.ts.map +0 -1
- package/dist/worker-contracts.js.map +0 -1
- /package/dist/{generated-parts.js → runtime/generated-parts.js} +0 -0
- /package/dist/{worker-contracts.js → runtime/worker-contracts.js} +0 -0
|
@@ -0,0 +1,429 @@
|
|
|
1
|
+
# Define parameters and validation
|
|
2
|
+
|
|
3
|
+
Define model controls, side profiles, closed cross sections, fonts, conditional visibility, and cross-field validation for an authored Project.
|
|
4
|
+
|
|
5
|
+
A reusable code Project exposes meaningful design decisions through controls. Studio stores the
|
|
6
|
+
control definition as JSON-safe Project data, types `params` through the imported `generate`
|
|
7
|
+
helper, and runs executable cross-field validation from `model.ts`.
|
|
8
|
+
|
|
9
|
+
The JSON document contains required `groups` and `parameters` arrays. A parameter's `type`,
|
|
10
|
+
default, units, bounds, and choices describe its value. Its optional `ui` object describes
|
|
11
|
+
presentation: group, shared row, hint, visibility, editing increment, and physical editor bindings.
|
|
12
|
+
Number and Slider both use `type: "number"`; a Slider also declares `ui.control: "slider"`.
|
|
13
|
+
Options use `type: "choice"`, Side profile uses `type: "side-profile"`, and a closed outline uses
|
|
14
|
+
`type: "contour"`. Changing a numeric widget does not change its saved value or valid range.
|
|
15
|
+
|
|
16
|
+
JSON editing provides field completion, help, and inline validation. Reference completion suggests
|
|
17
|
+
declared groups, parameters, and choice values. Errors prevent applying the draft; returning to
|
|
18
|
+
Visual requires fixing or discarding invalid JSON.
|
|
19
|
+
For other editors, the SDK ships `@metamesh/generator-sdk/parameters.schema.json`; the SDK parser
|
|
20
|
+
also checks cross-field rules that JSON Schema cannot express.
|
|
21
|
+
|
|
22
|
+
## Open the control editor
|
|
23
|
+
|
|
24
|
+
In an authored Project, open the parameter panel's **Parameter actions** menu and choose
|
|
25
|
+
**Edit controls**. The same action is available in the **MetaMesh menu → Current project** group.
|
|
26
|
+
The Model controls editor's **Visual** and **JSON** views edit the same draft. Choose
|
|
27
|
+
**Apply & return** to commit it and return to the model.
|
|
28
|
+
|
|
29
|
+
1. Add a section for one coherent decision, such as **Size** or **Outputs**.
|
|
30
|
+
2. Add a control, give it a stable ID, a plain-language label, and a useful default.
|
|
31
|
+
3. Add units and field limits where they carry real meaning.
|
|
32
|
+
4. Try the selected control in its preview, then apply the draft and check the generated
|
|
33
|
+
`params` completion in `model.ts`.
|
|
34
|
+
|
|
35
|
+
Preview values are temporary; they do not change the default or the Project's current values.
|
|
36
|
+
|
|
37
|
+
Use labels to name the decision and descriptions for supplementary help. Defaults should produce a useful model immediately;
|
|
38
|
+
minimum and maximum values should describe the supported input range rather than compensate for a
|
|
39
|
+
missing cross-field rule.
|
|
40
|
+
|
|
41
|
+
## Separate help from essential instructions
|
|
42
|
+
|
|
43
|
+
Keep `description` for explanations, terminology, and examples. Studio shows it on demand when the
|
|
44
|
+
user hovers, focuses, or taps the question-mark help button. Clicking the label focuses the input;
|
|
45
|
+
hovering it does not open help.
|
|
46
|
+
Use one optional static `ui.hint` for a short, essential instruction shown inline whenever the
|
|
47
|
+
control is visible. Omit it when the label is enough. Put guidance covering multiple modes in
|
|
48
|
+
`description`; hints have no conditions. Errors, warnings, and explanations for unavailable
|
|
49
|
+
controls remain visible too.
|
|
50
|
+
|
|
51
|
+
In **Visual**, edit **Hint (optional)** as ordinary text. **Visual**, **JSON**, and the live preview
|
|
52
|
+
use the same string field. Clearing it omits the hint when applying the definition. For example,
|
|
53
|
+
a socket-only Diameter control can include:
|
|
54
|
+
|
|
55
|
+
```json
|
|
56
|
+
{
|
|
57
|
+
"description": "The dimension before fit allowance.",
|
|
58
|
+
"ui": { "hint": "Measure the mating part's outside diameter." }
|
|
59
|
+
}
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
For a control shared by socket and spigot modes, omit the hint and explain both measurements in
|
|
63
|
+
its description: measure the mating part's outside diameter for a socket or the opening's inside
|
|
64
|
+
diameter for a spigot. Add this metadata to the existing control object. Keep hints short and
|
|
65
|
+
avoid repeating labels, units, or descriptions. A declared hint must be non-empty and at most
|
|
66
|
+
4,096 characters. Generator packages use format `4` and runtime major `5`.
|
|
67
|
+
|
|
68
|
+
## Choose the right control
|
|
69
|
+
|
|
70
|
+
| Studio control | Use it for |
|
|
71
|
+
| ------------------------ | --------------------------------------------------------------- |
|
|
72
|
+
| Number or Slider | Dimensions, counts, and bounded continuous values |
|
|
73
|
+
| Toggle | A feature that is either enabled or disabled |
|
|
74
|
+
| Options | Exactly one value from a fixed supported set |
|
|
75
|
+
| Multiple choice | A supported subset of fixed options, such as named outputs |
|
|
76
|
+
| Color | An exact six-digit sRGB preview or part color |
|
|
77
|
+
| Text | Wording or another string consumed by the model |
|
|
78
|
+
| Font | An exact catalog face and weight for generated text |
|
|
79
|
+
| SVG | Editable vector artwork consumed as an SVG string |
|
|
80
|
+
| Side profile | An editable side outline for a handle, knob, or revolved shape |
|
|
81
|
+
| Cross section | One closed XY outline for extrusion or a swept section |
|
|
82
|
+
| Number List or Text List | An ordered sequence the user may add, remove, edit, and reorder |
|
|
83
|
+
|
|
84
|
+
A Slider requires `min`, `max`, and a positive `ui.step`. Multiple choice may require a minimum or maximum
|
|
85
|
+
selection count. List controls can bound their item count; number-list items can also have their own
|
|
86
|
+
unit, limits, and `items.ui.step`.
|
|
87
|
+
|
|
88
|
+
A Font value is a structured selection, not a family-name string. Pass the whole value in
|
|
89
|
+
`services.text.layout(text, { font, fontSize })` inside generation, then pass its layout to
|
|
90
|
+
`textSection(layout)`. Studio loads declared fonts before generation. See the
|
|
91
|
+
[text recipe](https://metamesh.studio/docs/develop/geometry-recipes#text-from-a-font-parameter) for the setup and offline
|
|
92
|
+
limits.
|
|
93
|
+
|
|
94
|
+
## Show controls side by side
|
|
95
|
+
|
|
96
|
+
Use shared rows for related dimensions, short choices, or text values. In **Visual**, select a
|
|
97
|
+
Number, Options, or Text control and set **Placement** to **Beside previous**. **Own row** is the
|
|
98
|
+
default. Two adjacent controls in the same section can share a row, including mixed types.
|
|
99
|
+
|
|
100
|
+
In **JSON**, give the controls the same `ui.row` identifier:
|
|
101
|
+
|
|
102
|
+
```json
|
|
103
|
+
[
|
|
104
|
+
{
|
|
105
|
+
"id": "width",
|
|
106
|
+
"label": "Width",
|
|
107
|
+
"type": "number",
|
|
108
|
+
"default": 100,
|
|
109
|
+
"unit": "mm",
|
|
110
|
+
"ui": {
|
|
111
|
+
"row": "size"
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
{
|
|
115
|
+
"id": "height",
|
|
116
|
+
"label": "Height",
|
|
117
|
+
"type": "number",
|
|
118
|
+
"default": 80,
|
|
119
|
+
"unit": "mm",
|
|
120
|
+
"ui": {
|
|
121
|
+
"row": "size"
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
]
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
These entries belong in the definition's `parameters` array. Row identifiers are local to each
|
|
128
|
+
section, and controls in a row must remain adjacent within that section. Omit `ui.row` for an ordinary
|
|
129
|
+
full-width control. Shared rows support number inputs, `choice`, and `text`; sliders and other control types use
|
|
130
|
+
their own rows. Prefer full width for long option names or text values.
|
|
131
|
+
|
|
132
|
+
Shared fields have equal widths and compact labels. They stack when the panel is too
|
|
133
|
+
narrow, and hidden fields leave space for the remaining row members. Each field keeps its own
|
|
134
|
+
value, units, validation, and history; `params.width` and `params.height` remain
|
|
135
|
+
separate numbers.
|
|
136
|
+
|
|
137
|
+
## Define an editable side profile
|
|
138
|
+
|
|
139
|
+
Add a **Side profile** control when the model needs an outer silhouette. Its **Edit side profile** action
|
|
140
|
+
opens guided points with automatic smoothing, Bézier handles, straight/curved segments,
|
|
141
|
+
and numeric editing. Select a segment directly; double-click it to insert a point at that location.
|
|
142
|
+
Choosing **Curve** reveals handles while retaining the existing shape until a handle moves.
|
|
143
|
+
The Model controls editor uses the same editor for the default outline.
|
|
144
|
+
**Apply profile** changes only the draft being edited; choose **Apply & return** to commit the
|
|
145
|
+
control definition.
|
|
146
|
+
|
|
147
|
+
The value on `params` is a readonly `SideProfileValue`, with a start anchor and line or cubic
|
|
148
|
+
segments. It contains normalized radius/height coordinates rather than SVG markup or sampled
|
|
149
|
+
vertices. Its parameter type is `side-profile`. This is a complete control you can add in **JSON**:
|
|
150
|
+
|
|
151
|
+
```json
|
|
152
|
+
{
|
|
153
|
+
"id": "sideProfile",
|
|
154
|
+
"type": "side-profile",
|
|
155
|
+
"label": "Side profile",
|
|
156
|
+
"default": {
|
|
157
|
+
"version": 1,
|
|
158
|
+
"start": {
|
|
159
|
+
"radius": 0.4,
|
|
160
|
+
"height": 0,
|
|
161
|
+
"mode": "auto"
|
|
162
|
+
},
|
|
163
|
+
"segments": [
|
|
164
|
+
{
|
|
165
|
+
"type": "cubic",
|
|
166
|
+
"control1": {
|
|
167
|
+
"radius": 0.4,
|
|
168
|
+
"height": 0.35
|
|
169
|
+
},
|
|
170
|
+
"control2": {
|
|
171
|
+
"radius": 1,
|
|
172
|
+
"height": 0.75
|
|
173
|
+
},
|
|
174
|
+
"end": {
|
|
175
|
+
"radius": 0.6,
|
|
176
|
+
"height": 1,
|
|
177
|
+
"mode": "auto"
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
]
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
Coordinates lie between `0` and `1`. The first height is `0`, the last is `1`, and points progress
|
|
186
|
+
upward. Cubic controls also progress upward between their endpoints. A profile supports up to 32
|
|
187
|
+
points. **Auto** computes tangents when points change; **Smooth** links their directions;
|
|
188
|
+
**Corner** lets handles move independently. Explicit control coordinates define the saved shape.
|
|
189
|
+
|
|
190
|
+
In **Physical dimensions (optional)**, link the radius and height to existing Number or Slider
|
|
191
|
+
controls with unit `mm`, a positive default, and a positive minimum. A radius factor of `0.5` uses
|
|
192
|
+
half a diameter control. The corresponding JSON fields are `ui.radiusScale` and `ui.heightScale`, each
|
|
193
|
+
with `parameterId` and a positive `factor`. These bindings set editor measurements; your source
|
|
194
|
+
still applies the same physical scales when modeling. The envelope describes the available size:
|
|
195
|
+
an outline reaching half the radius envelope produces half its diameter. The editor also shows
|
|
196
|
+
the actual maximum diameter.
|
|
197
|
+
|
|
198
|
+
Use [`sampleSideProfile()`](https://metamesh.studio/docs/reference/geometry/sampleSideProfile) to convert
|
|
199
|
+
`params.sideProfile` to an open `[radius, height]` polyline, supplying the physical radius
|
|
200
|
+
and height scales. Your model then closes the outline and uses
|
|
201
|
+
[`section.revolve()`](https://metamesh.studio/docs/reference/model/Section#revolve) on a filled Section to create the solid. Keep the mounting connection,
|
|
202
|
+
minimum walls, bore clearance, and other manufacturing rules in generation.
|
|
203
|
+
The side profile supports one upward open silhouette, with fixed bottom/top heights and strictly
|
|
204
|
+
increasing interior heights. Use a [Cross section](#define-an-editable-cross-section) for a closed
|
|
205
|
+
planar outline; holes and imported artwork remain separate modeling choices.
|
|
206
|
+
|
|
207
|
+
## Define an editable cross section
|
|
208
|
+
|
|
209
|
+
Add a **Cross section** control for one closed XY outline. **Edit cross section** lets the user
|
|
210
|
+
select points and segments, edit coordinates, and shape explicit Bézier handles. The default uses
|
|
211
|
+
the same editor. **Corner** leaves handles independent; **Smooth** links their directions.
|
|
212
|
+
|
|
213
|
+
`params` receives a readonly `ContourValue`. Every `x` and upward `y` coordinate,
|
|
214
|
+
including cubic controls, lies in `[0, 1]`. It has 2–32 line or cubic segments. The final endpoint
|
|
215
|
+
repeats the start's coordinates and mode, so the seam remains one editable point. This unscaled
|
|
216
|
+
square control can be added in **JSON**:
|
|
217
|
+
|
|
218
|
+
```json
|
|
219
|
+
{
|
|
220
|
+
"id": "crossSection",
|
|
221
|
+
"type": "contour",
|
|
222
|
+
"label": "Cross section",
|
|
223
|
+
"default": {
|
|
224
|
+
"version": 1,
|
|
225
|
+
"start": {
|
|
226
|
+
"x": 0,
|
|
227
|
+
"y": 0,
|
|
228
|
+
"mode": "corner"
|
|
229
|
+
},
|
|
230
|
+
"segments": [
|
|
231
|
+
{
|
|
232
|
+
"type": "line",
|
|
233
|
+
"end": {
|
|
234
|
+
"x": 1,
|
|
235
|
+
"y": 0,
|
|
236
|
+
"mode": "corner"
|
|
237
|
+
}
|
|
238
|
+
},
|
|
239
|
+
{
|
|
240
|
+
"type": "line",
|
|
241
|
+
"end": {
|
|
242
|
+
"x": 1,
|
|
243
|
+
"y": 1,
|
|
244
|
+
"mode": "corner"
|
|
245
|
+
}
|
|
246
|
+
},
|
|
247
|
+
{
|
|
248
|
+
"type": "line",
|
|
249
|
+
"end": {
|
|
250
|
+
"x": 0,
|
|
251
|
+
"y": 1,
|
|
252
|
+
"mode": "corner"
|
|
253
|
+
}
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
"type": "line",
|
|
257
|
+
"end": {
|
|
258
|
+
"x": 0,
|
|
259
|
+
"y": 0,
|
|
260
|
+
"mode": "corner"
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
]
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
Link **Width** and **Height** in **Physical dimensions (optional)** to positive `mm` Number or
|
|
269
|
+
Slider controls with explicit positive minima. JSON uses `ui.widthScale` and `ui.heightScale`, each
|
|
270
|
+
with a `parameterId` and positive `factor`, such as `{ "parameterId": "width", "factor": 1 }`.
|
|
271
|
+
Bindings describe the coordinate envelope; they never rescale the saved value. Without them,
|
|
272
|
+
the editor displays percentages.
|
|
273
|
+
|
|
274
|
+
Inside generation or a computed value, pass `params.crossSection` to
|
|
275
|
+
[`sampleContour()`](https://metamesh.studio/docs/reference/geometry/sampleContour) with physical `widthScale`,
|
|
276
|
+
`heightScale`, and a millimetre resolution policy. It returns an immutable counterclockwise
|
|
277
|
+
XY `Contour` without a duplicated seam, rejecting invalid sampled topology and exhausted budgets.
|
|
278
|
+
Reuse that contour in generation, create a filled Section with
|
|
279
|
+
[`polygon(contour)`](https://metamesh.studio/docs/reference/model/polygon), and use
|
|
280
|
+
[`section.extrude()`](https://metamesh.studio/docs/reference/model/Section#extrude) or [`section.sweep()`](https://metamesh.studio/docs/reference/model/Section#sweep) for the solid.
|
|
281
|
+
The Generator owns extrusion depth, the sweep path, fit, walls, and manufacturing rules.
|
|
282
|
+
Data validation checks the bounded structure and closure; it does not establish those geometric
|
|
283
|
+
requirements. This control contains one contour without holes or multiple loops.
|
|
284
|
+
|
|
285
|
+
Side-profile and cross-section edits stay local until **Apply**. Workspace editors check the
|
|
286
|
+
current draft with Generator declaration and reached assertions before applying it; errors block Apply and warnings
|
|
287
|
+
remain visible. Failed checks offer **Retry draft check**. Editing a control default changes its
|
|
288
|
+
definition draft, so check the current model after **Apply & return**.
|
|
289
|
+
|
|
290
|
+
<a id="expose-curve-resolution-in-the-viewport"></a>
|
|
291
|
+
|
|
292
|
+
## Expose Curve resolution in Parameters
|
|
293
|
+
|
|
294
|
+
In **JSON**, add `"role": "curve-resolution"` to a Number or Slider control to group it under
|
|
295
|
+
**Parameters → Curve resolution**. Use millimetres, a positive default, and an explicit positive minimum:
|
|
296
|
+
|
|
297
|
+
```json
|
|
298
|
+
{
|
|
299
|
+
"id": "curveResolution",
|
|
300
|
+
"type": "number",
|
|
301
|
+
"label": "Maximum curve deviation",
|
|
302
|
+
"role": "curve-resolution",
|
|
303
|
+
"unit": "mm",
|
|
304
|
+
"default": 0.05,
|
|
305
|
+
"min": 0.01,
|
|
306
|
+
"max": 0.1,
|
|
307
|
+
"ui": {
|
|
308
|
+
"step": 0.01
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
The control remains a saved parameter on `params`. Your source must apply it to geometry,
|
|
314
|
+
for example by passing `resolution: { maxChordError: params.curveResolution }` to each
|
|
315
|
+
affected primitive or Section operation. Share that ordinary options value where several curves
|
|
316
|
+
use the same policy. The declaration alone
|
|
317
|
+
does not change sampling. Keep supported limits and any feature-specific sampling in your model.
|
|
318
|
+
|
|
319
|
+
Studio groups these fields under **Curve resolution** in Parameters, including the mobile sheet
|
|
320
|
+
where draft validation errors can be corrected. The chosen value affects preview and export through
|
|
321
|
+
the same generation path. Visual editing
|
|
322
|
+
preserves the role; duplicating the control creates an ordinary numeric control. A Project may
|
|
323
|
+
declare multiple Curve resolution controls, shown together in definition order.
|
|
324
|
+
For example, declare separate **Coil path** and **Wire cross-section** values and pass each to the
|
|
325
|
+
appropriate sampler. Your Generator decides which curves or parts each value affects; Studio saves
|
|
326
|
+
the values without assigning them to parts automatically.
|
|
327
|
+
|
|
328
|
+
## Reveal a control only when it applies
|
|
329
|
+
|
|
330
|
+
Use **JSON** for advanced metadata such as `ui.visibleWhen`. The Visual view preserves supported
|
|
331
|
+
metadata it does not expose. Add the condition to the existing control object in the `parameters`
|
|
332
|
+
array; this example shows Hole diameter only while Add hole is enabled:
|
|
333
|
+
|
|
334
|
+
```json
|
|
335
|
+
{
|
|
336
|
+
"id": "holeDiameter",
|
|
337
|
+
"type": "number",
|
|
338
|
+
"label": "Hole diameter",
|
|
339
|
+
"default": 12,
|
|
340
|
+
"min": 1,
|
|
341
|
+
"max": 28,
|
|
342
|
+
"unit": "mm",
|
|
343
|
+
"ui": {
|
|
344
|
+
"visibleWhen": {
|
|
345
|
+
"param": "addHole",
|
|
346
|
+
"eq": true
|
|
347
|
+
},
|
|
348
|
+
"step": 0.5
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
Use `eq` or `ne` for scalar comparisons, `gt`, `gte`, `lt`, or `lte` for numbers, and `contains`
|
|
354
|
+
for Multiple choice membership. Combine conditions with `all`, `any`, or `not`. Font, Side profile, Cross section,
|
|
355
|
+
Number List, and Text List values cannot be the referenced value in a condition.
|
|
356
|
+
|
|
357
|
+
The JSON root accepts only `groups` and `parameters`. Project identity, title, and version are
|
|
358
|
+
managed separately by Studio.
|
|
359
|
+
|
|
360
|
+
Visibility is presentation, not data deletion. Source still receives the control's normalized value.
|
|
361
|
+
Generation decides whether it matters in the current mode; assertions and geometry follow that choice.
|
|
362
|
+
|
|
363
|
+
## Add cross-field validation in TypeScript
|
|
364
|
+
|
|
365
|
+
The generation callback receives normalized readonly parameters. Put a cheap assertion before
|
|
366
|
+
geometry when a combination cannot produce a supported model:
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
```ts
|
|
371
|
+
assert(
|
|
372
|
+
!params.addHole || params.holeDiameter < Math.min(params.width, params.depth),
|
|
373
|
+
"Hole diameter must be smaller than the body width and depth.",
|
|
374
|
+
{ parameterId: "holeDiameter" }
|
|
375
|
+
);
|
|
376
|
+
```
|
|
377
|
+
|
|
378
|
+
|
|
379
|
+
|
|
380
|
+
`assert(condition, message, { parameterId? })` stops on the first false condition. The parameter ID
|
|
381
|
+
is checked against your controls and tells the user where to make a correction. Successful assertions
|
|
382
|
+
return normally. For a valid result with a meaningful caution, use a warning in the outer callback:
|
|
383
|
+
|
|
384
|
+
```ts
|
|
385
|
+
assert(params.wall > 0, "Wall thickness must be positive.", { parameterId: "wall" });
|
|
386
|
+
if (params.wall < 1) warn("This wall may be difficult to print.", { parameterId: "wall" });
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
A zero wall stops generation; a 0.5 mm wall generates with a warning. A failed edit leaves the last
|
|
390
|
+
valid preview and its export available. Warnings allow a current model to generate and export.
|
|
391
|
+
|
|
392
|
+
Checks run in JavaScript order. Reading a computed value evaluates it when necessary, and a
|
|
393
|
+
geometry observation must realize its input first. This also applies to draft validation: it runs
|
|
394
|
+
declaration and reached assertions, without finalizing the returned parts. It does not prove full
|
|
395
|
+
geometric validity. Keep exact layouts and shared dimensions in optional `computed` values so
|
|
396
|
+
unrelated edits do not repeat expensive work. There is no separate preparation callback.
|
|
397
|
+
|
|
398
|
+
## Test the definition as a contract
|
|
399
|
+
|
|
400
|
+
Before relying on a Project, check:
|
|
401
|
+
|
|
402
|
+
- defaults generate a useful model with no error;
|
|
403
|
+
- each numeric minimum and maximum produces the intended boundary result;
|
|
404
|
+
- hidden controls become visible under the right condition;
|
|
405
|
+
- essential hints stay inline, while supplementary help is available by keyboard and tap;
|
|
406
|
+
- every fixed-choice and allowed multiple-choice combination behaves intentionally;
|
|
407
|
+
- empty, minimum, and maximum list lengths are handled;
|
|
408
|
+
- edited side profiles and cross sections affect the solid and keep required clearances and walls;
|
|
409
|
+
- cross-field errors identify the control the user should change;
|
|
410
|
+
- warnings still generate and export the expected current model; and
|
|
411
|
+
- resetting controls returns to the documented defaults.
|
|
412
|
+
|
|
413
|
+
The Model controls editor checks the definition when you apply it and keeps invalid drafts open
|
|
414
|
+
with errors to correct. After **Apply & return**, Studio uses the updated definition for controls,
|
|
415
|
+
normalization, persistence, and the typed generation context. It then validates the current values
|
|
416
|
+
with `model.ts`; check the workspace for source or cross-field errors before exporting.
|
|
417
|
+
|
|
418
|
+
|
|
419
|
+
|
|
420
|
+
**Keep executable rules in model.ts**
|
|
421
|
+
|
|
422
|
+
JSON mode defines serializable controls and visibility. Derived calculations, geometry checks, and
|
|
423
|
+
cross-field messages belong in `generate`; do not invent a second executable rules language inside
|
|
424
|
+
the Project definition.
|
|
425
|
+
|
|
426
|
+
|
|
427
|
+
|
|
428
|
+
- [Read the source contract](https://metamesh.studio/docs/develop/code-project-contract)
|
|
429
|
+
- [See the user experience](https://metamesh.studio/docs/use/parameters)
|