@hatiolab/figure-model 0.1.92 → 0.1.94
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 +12 -12
- package/README.md +25 -25
- package/dist/{v3-asset-types.d.ts → asset-types.d.ts} +73 -67
- package/dist/asset-types.d.ts.map +1 -0
- package/dist/asset-types.js +2 -0
- package/dist/asset-types.js.map +1 -0
- package/dist/asset.d.ts +20 -0
- package/dist/asset.d.ts.map +1 -0
- package/dist/{v3-asset.js → asset.js} +49 -28
- package/dist/asset.js.map +1 -0
- package/dist/{v3-authoring-actions.d.ts → authoring-actions.d.ts} +77 -66
- package/dist/authoring-actions.d.ts.map +1 -0
- package/dist/{v3-authoring-actions.js → authoring-actions.js} +129 -104
- package/dist/authoring-actions.js.map +1 -0
- package/dist/{v3-authoring-session.d.ts → authoring-session.d.ts} +23 -21
- package/dist/authoring-session.d.ts.map +1 -0
- package/dist/{v3-authoring-session.js → authoring-session.js} +4 -4
- package/dist/authoring-session.js.map +1 -0
- package/dist/capabilities.d.ts +3 -0
- package/dist/capabilities.d.ts.map +1 -0
- package/dist/{v3-capabilities.js → capabilities.js} +8 -8
- package/dist/capabilities.js.map +1 -0
- package/dist/clip-keeping.d.ts +30 -0
- package/dist/clip-keeping.d.ts.map +1 -0
- package/dist/clip-keeping.js +77 -0
- package/dist/clip-keeping.js.map +1 -0
- package/dist/command-preview.d.ts +125 -0
- package/dist/command-preview.d.ts.map +1 -0
- package/dist/command-preview.js +246 -0
- package/dist/command-preview.js.map +1 -0
- package/dist/contract.d.ts +7 -0
- package/dist/contract.d.ts.map +1 -0
- package/dist/contract.js +12 -0
- package/dist/contract.js.map +1 -0
- package/dist/{v3-cost.d.ts → cost.d.ts} +5 -5
- package/dist/cost.d.ts.map +1 -0
- package/dist/{v3-cost.js → cost.js} +11 -11
- package/dist/cost.js.map +1 -0
- package/dist/{v3-create.d.ts → create.d.ts} +8 -8
- package/dist/{v3-create.d.ts.map → create.d.ts.map} +1 -1
- package/dist/{v3-create.js → create.js} +26 -26
- package/dist/create.js.map +1 -0
- package/dist/document.d.ts +5 -0
- package/dist/document.d.ts.map +1 -0
- package/dist/document.js +31 -0
- package/dist/document.js.map +1 -0
- package/dist/{v3-driver.d.ts → driver.d.ts} +10 -10
- package/dist/driver.d.ts.map +1 -0
- package/dist/{v3-driver.js → driver.js} +10 -10
- package/dist/driver.js.map +1 -0
- package/dist/{v3-editor-workspace.d.ts → editor-workspace.d.ts} +99 -73
- package/dist/editor-workspace.d.ts.map +1 -0
- package/dist/{v3-editor-workspace.js → editor-workspace.js} +48 -32
- package/dist/editor-workspace.js.map +1 -0
- package/dist/{v3-examples.d.ts → examples.d.ts} +5 -5
- package/dist/examples.d.ts.map +1 -0
- package/dist/{v3-examples.js → examples.js} +11 -11
- package/dist/examples.js.map +1 -0
- package/dist/{v3-follow.d.ts → follow.d.ts} +5 -5
- package/dist/follow.d.ts.map +1 -0
- package/dist/{v3-follow.js → follow.js} +2 -2
- package/dist/follow.js.map +1 -0
- package/dist/{v3-gate.d.ts → gate.d.ts} +36 -28
- package/dist/gate.d.ts.map +1 -0
- package/dist/{v3-gate.js → gate.js} +54 -48
- package/dist/gate.js.map +1 -0
- package/dist/{v3-graph-types.d.ts → graph-types.d.ts} +33 -33
- package/dist/graph-types.d.ts.map +1 -0
- package/dist/graph-types.js +2 -0
- package/dist/graph-types.js.map +1 -0
- package/dist/{v3-graph.d.ts → graph.d.ts} +14 -14
- package/dist/graph.d.ts.map +1 -0
- package/dist/{v3-graph.js → graph.js} +16 -16
- package/dist/graph.js.map +1 -0
- package/dist/index.d.ts +39 -33
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +39 -33
- package/dist/index.js.map +1 -1
- package/dist/{v3-instance-size.d.ts → instance-size.d.ts} +14 -14
- package/dist/instance-size.d.ts.map +1 -0
- package/dist/{v3-instance-size.js → instance-size.js} +13 -13
- package/dist/instance-size.js.map +1 -0
- package/dist/json.d.ts +12 -0
- package/dist/json.d.ts.map +1 -0
- package/dist/{v3-json.js → json.js} +13 -13
- package/dist/json.js.map +1 -0
- package/dist/kernel-version.d.ts +8 -0
- package/dist/kernel-version.d.ts.map +1 -0
- package/dist/{v3-kernel-version.js → kernel-version.js} +4 -4
- package/dist/kernel-version.js.map +1 -0
- package/dist/{v3-part-edit.d.ts → part-edit.d.ts} +12 -11
- package/dist/part-edit.d.ts.map +1 -0
- package/dist/{v3-part-edit.js → part-edit.js} +84 -68
- package/dist/part-edit.js.map +1 -0
- package/dist/proposal.d.ts +55 -0
- package/dist/proposal.d.ts.map +1 -0
- package/dist/{v3-proposal.js → proposal.js} +29 -21
- package/dist/proposal.js.map +1 -0
- package/dist/{v3-public-inputs.d.ts → public-inputs.d.ts} +4 -4
- package/dist/public-inputs.d.ts.map +1 -0
- package/dist/{v3-public-inputs.js → public-inputs.js} +3 -3
- package/dist/public-inputs.js.map +1 -0
- package/dist/recipe-build.d.ts +27 -0
- package/dist/recipe-build.d.ts.map +1 -0
- package/dist/{v3-recipe-build.js → recipe-build.js} +9 -9
- package/dist/recipe-build.js.map +1 -0
- package/dist/recipe-from-parts.d.ts +8 -0
- package/dist/recipe-from-parts.d.ts.map +1 -0
- package/dist/{v3-recipe-from-parts.js → recipe-from-parts.js} +9 -9
- package/dist/recipe-from-parts.js.map +1 -0
- package/dist/{v3-recipe.d.ts → recipe.d.ts} +25 -25
- package/dist/recipe.d.ts.map +1 -0
- package/dist/{v3-recipe.js → recipe.js} +30 -30
- package/dist/recipe.js.map +1 -0
- package/dist/release-contract.d.ts +19 -0
- package/dist/release-contract.d.ts.map +1 -0
- package/dist/{v3-release-contract.js → release-contract.js} +8 -7
- package/dist/release-contract.js.map +1 -0
- package/dist/{v3-render-batches.d.ts → render-batches.d.ts} +8 -8
- package/dist/render-batches.d.ts.map +1 -0
- package/dist/{v3-render-batches.js → render-batches.js} +4 -4
- package/dist/render-batches.js.map +1 -0
- package/dist/resize-plan.d.ts +61 -0
- package/dist/resize-plan.d.ts.map +1 -0
- package/dist/resize-plan.js +189 -0
- package/dist/resize-plan.js.map +1 -0
- package/dist/room.d.ts +53 -0
- package/dist/room.d.ts.map +1 -0
- package/dist/room.js +90 -0
- package/dist/room.js.map +1 -0
- package/dist/{v3-score.d.ts → score.d.ts} +19 -19
- package/dist/score.d.ts.map +1 -0
- package/dist/{v3-score.js → score.js} +32 -32
- package/dist/score.js.map +1 -0
- package/dist/shape-provider.d.ts +37 -0
- package/dist/shape-provider.d.ts.map +1 -0
- package/dist/shape-provider.js +69 -0
- package/dist/shape-provider.js.map +1 -0
- package/dist/{v3-shape-sampling.d.ts → shape-sampling.d.ts} +4 -4
- package/dist/shape-sampling.d.ts.map +1 -0
- package/dist/{v3-shape-sampling.js → shape-sampling.js} +3 -3
- package/dist/shape-sampling.js.map +1 -0
- package/dist/size-edit.d.ts +38 -0
- package/dist/size-edit.d.ts.map +1 -0
- package/dist/size-edit.js +178 -0
- package/dist/size-edit.js.map +1 -0
- package/dist/{v3-surface.d.ts → surface.d.ts} +5 -5
- package/dist/surface.d.ts.map +1 -0
- package/dist/{v3-surface.js → surface.js} +7 -7
- package/dist/surface.js.map +1 -0
- package/dist/{v3-words.d.ts → words.d.ts} +3 -3
- package/dist/words.d.ts.map +1 -0
- package/dist/{v3-words.js → words.js} +3 -3
- package/dist/words.js.map +1 -0
- package/docs/{assembly-constraints-v3.md → assembly-constraints.md} +1 -1
- package/docs/{v3-asset-persistence.md → asset-persistence.md} +8 -8
- package/docs/{v3-authoring-transactions.md → authoring-transactions.md} +2 -2
- package/docs/{v3-capability-bindings.md → capability-bindings.md} +8 -8
- package/docs/{v3-common-kernel-experiment.md → common-kernel-experiment.md} +4 -4
- package/docs/{v3-core-semantics.md → core-semantics.md} +5 -5
- package/docs/{v3-cutover.md → cutover.md} +4 -4
- package/docs/{v3-design.md → design.md} +11 -11
- package/docs/{v3-document-contract.md → document-contract.md} +9 -9
- package/docs/{v3-dryroom-profile-validation.md → dryroom-profile-validation.md} +4 -4
- package/docs/{v3-editor-integration.md → editor-integration.md} +6 -6
- package/docs/{v3-full-conveyor-validation.md → full-conveyor-validation.md} +4 -4
- package/docs/{v3-full-dryroom-validation.md → full-dryroom-validation.md} +4 -4
- package/docs/{v3-full-forklift-validation.md → full-forklift-validation.md} +5 -5
- package/docs/{v3-full-robot-validation.md → full-robot-validation.md} +4 -4
- package/docs/{v3-layout-system.md → layout-system.md} +4 -4
- package/docs/{v3-legacy-risk-audit-2026-09-23.md → legacy-risk-audit-2026-09-23.md} +5 -5
- package/docs/{v3-minimal-model.md → minimal-model.md} +6 -6
- package/docs/{v3-motion-contract.md → motion-contract.md} +3 -3
- package/docs/{v3-openusd-review.md → openusd-review.md} +8 -8
- package/docs/{v3-operator-contracts.md → operator-contracts.md} +6 -6
- package/docs/{v3-payload-collision-validation.md → payload-collision-validation.md} +4 -4
- package/docs/{v3-payload-contact-validation.md → payload-contact-validation.md} +5 -5
- package/docs/prototypes/README.md +10 -10
- package/docs/prototypes/{v3-asset-samples.mjs → asset-samples.mjs} +6 -6
- package/docs/prototypes/{v3-asset-store.mjs → asset-store.mjs} +3 -3
- package/docs/prototypes/{v3-asset-store.test.mjs → asset-store.test.mjs} +6 -6
- package/docs/prototypes/asset.mjs +1 -0
- package/docs/prototypes/{v3-asset.schema.json → asset.schema.json} +2 -2
- package/docs/prototypes/{v3-asset.test.mjs → asset.test.mjs} +10 -10
- package/docs/prototypes/authoring-session.mjs +1 -0
- package/docs/prototypes/{v3-authoring-session.test.mjs → authoring-session.test.mjs} +6 -6
- package/docs/prototypes/capability-plan.mjs +1 -0
- package/docs/prototypes/{v3-capability-plan.test.mjs → capability-plan.test.mjs} +5 -5
- package/docs/prototypes/{v3-capability-samples.mjs → capability-samples.mjs} +2 -2
- package/docs/prototypes/document.mjs +2 -0
- package/docs/prototypes/{v3-document.schema.json → document.schema.json} +1 -1
- package/docs/prototypes/{v3-document.test.mjs → document.test.mjs} +7 -7
- package/docs/prototypes/{v3-dryroom-mesh.mjs → dryroom-mesh.mjs} +1 -1
- package/docs/prototypes/{v3-dryroom-mesh.test.mjs → dryroom-mesh.test.mjs} +1 -1
- package/docs/prototypes/{v3-editor-browser.mjs → editor-browser.mjs} +13 -13
- package/docs/prototypes/editor-workspace.mjs +1 -0
- package/docs/prototypes/{v3-editor-workspace.test.mjs → editor-workspace.test.mjs} +3 -3
- package/docs/prototypes/{v3-feature-pattern.test.mjs → feature-pattern.test.mjs} +1 -1
- package/docs/prototypes/{v3-full-conveyor.mjs → full-conveyor.mjs} +2 -2
- package/docs/prototypes/{v3-full-conveyor.test.mjs → full-conveyor.test.mjs} +3 -3
- package/docs/prototypes/{v3-full-dryroom.mjs → full-dryroom.mjs} +2 -2
- package/docs/prototypes/{v3-full-dryroom.test.mjs → full-dryroom.test.mjs} +3 -3
- package/docs/prototypes/{v3-full-forklift.mjs → full-forklift.mjs} +2 -2
- package/docs/prototypes/{v3-full-forklift.test.mjs → full-forklift.test.mjs} +3 -3
- package/docs/prototypes/{v3-full-robot.mjs → full-robot.mjs} +2 -2
- package/docs/prototypes/{v3-full-robot.test.mjs → full-robot.test.mjs} +4 -4
- package/docs/prototypes/{v3-kernel.test.mjs → kernel.test.mjs} +1 -1
- package/docs/prototypes/{v3-layout.test.mjs → layout.test.mjs} +1 -1
- package/docs/prototypes/{v3-more-samples.test.mjs → more-samples.test.mjs} +2 -2
- package/docs/prototypes/{v3-payload-collision.mjs → payload-collision.mjs} +2 -2
- package/docs/prototypes/{v3-payload-collision.test.mjs → payload-collision.test.mjs} +3 -3
- package/docs/prototypes/{v3-payload-fit.mjs → payload-fit.mjs} +2 -2
- package/docs/prototypes/{v3-payload-fit.test.mjs → payload-fit.test.mjs} +4 -4
- package/docs/prototypes/render-full-dryroom.mjs +12 -12
- package/docs/prototypes/{v3-repeated-binding.mjs → repeated-binding.mjs} +1 -1
- package/docs/prototypes/{v3-repeated-binding.test.mjs → repeated-binding.test.mjs} +6 -6
- package/docs/prototypes/{v3-runtime-browser.mjs → runtime-browser.mjs} +26 -26
- package/docs/prototypes/{v3-samples.test.mjs → samples.test.mjs} +1 -1
- package/docs/prototypes/{v3-spatial-plan.test.mjs → spatial-plan.test.mjs} +1 -1
- package/docs/prototypes/typed-plan.mjs +3 -0
- package/docs/prototypes/{v3-typed-plan.test.mjs → typed-plan.test.mjs} +1 -1
- package/docs/prototypes/{v3-typed-repeat.test.mjs → typed-repeat.test.mjs} +2 -2
- package/docs/{v3-repeated-binding-validation.md → repeated-binding-validation.md} +4 -4
- package/docs/{v3-research-review.md → research-review.md} +2 -2
- package/docs/{v3-review-2026-09-22.md → review-2026-09-22.md} +10 -10
- package/docs/{v3-runtime-extraction.md → runtime-extraction.md} +16 -16
- package/docs/{v3-sample-validation-expanded.md → sample-validation-expanded.md} +5 -5
- package/docs/{v3-sample-validation.md → sample-validation.md} +3 -3
- package/docs/{v3-shape-dimension-contract.md → shape-dimension-contract.md} +12 -12
- package/docs/{v3-shapeassembly-reproduction.md → shapeassembly-reproduction.md} +4 -4
- package/docs/{v3-spatial-contracts.md → spatial-contracts.md} +5 -5
- package/docs/status.md +12 -0
- package/docs/{v3-storage-integration.md → storage-integration.md} +5 -5
- package/docs/{v3-typed-repeat-contracts.md → typed-repeat-contracts.md} +3 -3
- package/package.json +3 -3
- package/dist/v3-asset-types.d.ts.map +0 -1
- package/dist/v3-asset-types.js +0 -2
- package/dist/v3-asset-types.js.map +0 -1
- package/dist/v3-asset.d.ts +0 -8
- package/dist/v3-asset.d.ts.map +0 -1
- package/dist/v3-asset.js.map +0 -1
- package/dist/v3-authoring-actions.d.ts.map +0 -1
- package/dist/v3-authoring-actions.js.map +0 -1
- package/dist/v3-authoring-session.d.ts.map +0 -1
- package/dist/v3-authoring-session.js.map +0 -1
- package/dist/v3-capabilities.d.ts +0 -3
- package/dist/v3-capabilities.d.ts.map +0 -1
- package/dist/v3-capabilities.js.map +0 -1
- package/dist/v3-contract.d.ts +0 -7
- package/dist/v3-contract.d.ts.map +0 -1
- package/dist/v3-contract.js +0 -12
- package/dist/v3-contract.js.map +0 -1
- package/dist/v3-cost.d.ts.map +0 -1
- package/dist/v3-cost.js.map +0 -1
- package/dist/v3-create.js.map +0 -1
- package/dist/v3-document.d.ts +0 -5
- package/dist/v3-document.d.ts.map +0 -1
- package/dist/v3-document.js +0 -31
- package/dist/v3-document.js.map +0 -1
- package/dist/v3-driver.d.ts.map +0 -1
- package/dist/v3-driver.js.map +0 -1
- package/dist/v3-editor-workspace.d.ts.map +0 -1
- package/dist/v3-editor-workspace.js.map +0 -1
- package/dist/v3-examples.d.ts.map +0 -1
- package/dist/v3-examples.js.map +0 -1
- package/dist/v3-follow.d.ts.map +0 -1
- package/dist/v3-follow.js.map +0 -1
- package/dist/v3-gate.d.ts.map +0 -1
- package/dist/v3-gate.js.map +0 -1
- package/dist/v3-graph-types.d.ts.map +0 -1
- package/dist/v3-graph-types.js +0 -2
- package/dist/v3-graph-types.js.map +0 -1
- package/dist/v3-graph.d.ts.map +0 -1
- package/dist/v3-graph.js.map +0 -1
- package/dist/v3-instance-size.d.ts.map +0 -1
- package/dist/v3-instance-size.js.map +0 -1
- package/dist/v3-json.d.ts +0 -12
- package/dist/v3-json.d.ts.map +0 -1
- package/dist/v3-json.js.map +0 -1
- package/dist/v3-kernel-version.d.ts +0 -8
- package/dist/v3-kernel-version.d.ts.map +0 -1
- package/dist/v3-kernel-version.js.map +0 -1
- package/dist/v3-part-edit.d.ts.map +0 -1
- package/dist/v3-part-edit.js.map +0 -1
- package/dist/v3-proposal.d.ts +0 -42
- package/dist/v3-proposal.d.ts.map +0 -1
- package/dist/v3-proposal.js.map +0 -1
- package/dist/v3-public-inputs.d.ts.map +0 -1
- package/dist/v3-public-inputs.js.map +0 -1
- package/dist/v3-recipe-build.d.ts +0 -27
- package/dist/v3-recipe-build.d.ts.map +0 -1
- package/dist/v3-recipe-build.js.map +0 -1
- package/dist/v3-recipe-from-parts.d.ts +0 -8
- package/dist/v3-recipe-from-parts.d.ts.map +0 -1
- package/dist/v3-recipe-from-parts.js.map +0 -1
- package/dist/v3-recipe.d.ts.map +0 -1
- package/dist/v3-recipe.js.map +0 -1
- package/dist/v3-release-contract.d.ts +0 -19
- package/dist/v3-release-contract.d.ts.map +0 -1
- package/dist/v3-release-contract.js.map +0 -1
- package/dist/v3-render-batches.d.ts.map +0 -1
- package/dist/v3-render-batches.js.map +0 -1
- package/dist/v3-score.d.ts.map +0 -1
- package/dist/v3-score.js.map +0 -1
- package/dist/v3-shape-sampling.d.ts.map +0 -1
- package/dist/v3-shape-sampling.js.map +0 -1
- package/dist/v3-surface.d.ts.map +0 -1
- package/dist/v3-surface.js.map +0 -1
- package/dist/v3-words.d.ts.map +0 -1
- package/dist/v3-words.js.map +0 -1
- package/docs/prototypes/v3-asset.mjs +0 -1
- package/docs/prototypes/v3-authoring-session.mjs +0 -1
- package/docs/prototypes/v3-capability-plan.mjs +0 -1
- package/docs/prototypes/v3-document.mjs +0 -2
- package/docs/prototypes/v3-editor-workspace.mjs +0 -1
- package/docs/prototypes/v3-typed-plan.mjs +0 -3
- package/docs/v3-status.md +0 -50
- /package/docs/prototypes/{v3-kernel.mjs → kernel.mjs} +0 -0
- /package/docs/prototypes/{v3-linear-comparison.py → linear-comparison.py} +0 -0
- /package/docs/prototypes/{v3-semantics.test.mjs → semantics.test.mjs} +0 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { FigureAsset } from './asset-types.ts';
|
|
2
|
+
import type { FigureInputChange } from './authoring-session.ts';
|
|
3
|
+
export declare function figureSizeEditChanges(asset: FigureAsset, part: string, changes: readonly FigureInputChange[]): FigureInputChange[];
|
|
4
|
+
/**
|
|
5
|
+
* Per axis of the part's own frame, the face a size change keeps: 1 the low face (the part grows toward +), -1 the high
|
|
6
|
+
* face, 0 its centre -- what `figureSizeEditChanges` writes for a part placed by its own numbers, and what a fastening
|
|
7
|
+
* keeps for a fastened one (its face along the normal, its edges where it is aligned min or max). A gizmo drag shows
|
|
8
|
+
* this while it is dragged, so what the author sees is what is written (designer 2026-09-27: 「드래그 중 미리보기와
|
|
9
|
+
* 확정에 같은 기준면·간격 규칙」). Undefined where it cannot be said in the part's own axes -- a fastening turned or
|
|
10
|
+
* twisted -- and the caller must not guess one.
|
|
11
|
+
*/
|
|
12
|
+
export declare function figureScaleAnchorOf(asset: FigureAsset, part: string): Record<'x' | 'y' | 'z', -1 | 0 | 1> | undefined;
|
|
13
|
+
export type FigurePlaneAlignRefusal = 'HELD' | 'POSITION_RULE' | 'NO_FACE';
|
|
14
|
+
/**
|
|
15
|
+
* How the part meets the plane once aligned: `face` -- its named face lies on it; `tilted` -- it has that face but stands
|
|
16
|
+
* turned off the plane, so only its lowest (highest, backmost) point or edge touches, and the turn is left as it is;
|
|
17
|
+
* `extreme` -- no face of its own is known there (a ball), and its lowest (highest, backmost) extent touches; `centre` --
|
|
18
|
+
* a centred figure's part, its centre brought to the origin's height. The screen says which (designer 2026-09-27: a
|
|
19
|
+
* point touching is not a face attached; a ball is not said to be tilted).
|
|
20
|
+
*/
|
|
21
|
+
export type FigurePlaneContact = 'face' | 'tilted' | 'extreme' | 'centre';
|
|
22
|
+
/**
|
|
23
|
+
* "Put it on the plane, this once" -- the modeller's one-off align tool, by the figure's placement (designer 2026-09-27):
|
|
24
|
+
* a floor figure's part brings its bottom to Y 0, a ceiling one's its top, a wall one's its back to Z 0, and a centred
|
|
25
|
+
* figure's part its centre to the origin's height. Only the part's own position number moves; nothing is fastened, so a
|
|
26
|
+
* later change of size keeps the face by the size rule, not by a fastening (ADR-0097 §5.2: aligning once is not
|
|
27
|
+
* attaching). A part standing turned is aligned by the extent it covers turned, its lowest (highest, backmost) point,
|
|
28
|
+
* since its named face no longer lies along the plane.
|
|
29
|
+
*
|
|
30
|
+
* Refused, with the reason: a fastened part (its fastening places it), and a part whose position is worked out. The
|
|
31
|
+
* part's turn is never changed: only the one position number is written.
|
|
32
|
+
*/
|
|
33
|
+
export declare function figurePlaneAlignChanges(asset: FigureAsset, part: string): {
|
|
34
|
+
changes: FigureInputChange[];
|
|
35
|
+
contact?: FigurePlaneContact;
|
|
36
|
+
refusal?: FigurePlaneAlignRefusal;
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=size-edit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"size-edit.d.ts","sourceRoot":"","sources":["../src/size-edit.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,WAAW,EAAmB,MAAM,kBAAkB,CAAA;AACpE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AA0B/D,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,iBAAiB,EAAE,GAAG,iBAAiB,EAAE,CA0ClI;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,SAAS,CAiCrH;AAED,MAAM,MAAM,uBAAuB,GAAG,MAAM,GAAG,eAAe,GAAG,SAAS,CAAA;AAC1E;;;;;;GAMG;AACH,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAA;AAEzE;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,WAAW,EAClB,IAAI,EAAE,MAAM,GACX;IAAE,OAAO,EAAE,iBAAiB,EAAE,CAAC;IAAC,OAAO,CAAC,EAAE,kBAAkB,CAAC;IAAC,OAAO,CAAC,EAAE,uBAAuB,CAAA;CAAE,CAsCnG"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
import { compileFigureGraph } from "./graph.js";
|
|
2
|
+
import { figureShapeProviderOf } from "./shape-provider.js";
|
|
3
|
+
import { KEPT_FACE } from "./resize-plan.js";
|
|
4
|
+
import { compileFigureAsset, figurePlacementOf, upgradeFigurePlacement } from "./asset.js";
|
|
5
|
+
import { figureOccupiedBoxesOf, figureWritersOf } from "./gate.js";
|
|
6
|
+
import { AXES } from "./words.js";
|
|
7
|
+
const round6 = (v) => Math.round(v * 1e6) / 1e6;
|
|
8
|
+
/** The changes as given, and the part's own position along the plane's normal moved so the kept face stays where it is. */
|
|
9
|
+
/**
|
|
10
|
+
* How a part stands turned, for the face a size change keeps: `none`, `about-normal` (turned only about the plane's
|
|
11
|
+
* normal, so its named face along the normal still lies along the plane), `other`, or `unknown` when a turn is not a
|
|
12
|
+
* number here (worked out, or state).
|
|
13
|
+
*/
|
|
14
|
+
function turnKindOf(asset, pose, normal) {
|
|
15
|
+
const m = asset.document.model;
|
|
16
|
+
const turn = pose.args.slice(3, 6).map(ref => m.constants.find((c) => c.id === ref)?.value ?? asset.designInputs[ref]);
|
|
17
|
+
if (turn.some(t => typeof t !== 'number' || !Number.isFinite(t)))
|
|
18
|
+
return 'unknown';
|
|
19
|
+
if (turn.every(t => t === 0))
|
|
20
|
+
return 'none';
|
|
21
|
+
return AXES.every((axis, i) => axis === normal || turn[i] === 0) ? 'about-normal' : 'other';
|
|
22
|
+
}
|
|
23
|
+
export function figureSizeEditChanges(asset, part, changes) {
|
|
24
|
+
asset = upgradeFigurePlacement(asset);
|
|
25
|
+
const given = [...changes];
|
|
26
|
+
const kept = KEPT_FACE[figurePlacementOf(asset)];
|
|
27
|
+
if (!kept)
|
|
28
|
+
return given;
|
|
29
|
+
const m = asset.document.model;
|
|
30
|
+
const node = (id) => m.nodes.find((n) => n.id === id);
|
|
31
|
+
const place = node(part);
|
|
32
|
+
const pose = node(`${part}.pose`);
|
|
33
|
+
if (place?.op !== 'place@1' || pose?.op !== 'rigid@1')
|
|
34
|
+
return given;
|
|
35
|
+
if ((asset.joints ?? []).some((j) => j.body1?.part === part) || node(`${part}.chain`) || node(`${part}.seat.rigid`))
|
|
36
|
+
return given;
|
|
37
|
+
const shape = m.nodes.find((n) => Object.values(n.outputs ?? {}).includes(place.args[0]));
|
|
38
|
+
const face = shape && figureShapeProviderOf(shape.op)?.faces[kept.face];
|
|
39
|
+
if (!face || face.axis !== kept.normal)
|
|
40
|
+
return given;
|
|
41
|
+
const position = pose.args[AXES.indexOf(kept.normal)];
|
|
42
|
+
const own = position === `${part}.position.${kept.normal}` && m.inputs.some((i) => i.id === position && i.role === 'design');
|
|
43
|
+
if (!own || given.some(c => c.input === position))
|
|
44
|
+
return given;
|
|
45
|
+
const turn = turnKindOf(asset, pose, kept.normal);
|
|
46
|
+
if (turn === 'unknown')
|
|
47
|
+
return given;
|
|
48
|
+
const graph = compileFigureGraph(m);
|
|
49
|
+
const before = { ...asset.designInputs, ...asset.stateDefaults };
|
|
50
|
+
const after = { ...before };
|
|
51
|
+
for (const c of given)
|
|
52
|
+
after[c.input] = c.value;
|
|
53
|
+
/*
|
|
54
|
+
Unturned, or turned only about the plane's normal, the named face still lies along the plane: it is kept. Turned any
|
|
55
|
+
other way, it does not; the point kept is the extreme the part covers along the normal -- its lowest on a floor, its
|
|
56
|
+
highest on a ceiling, its backmost on a wall -- as the one-off align measures it (designer 2026-09-27: a turned
|
|
57
|
+
part typed into its fields must still land as meant).
|
|
58
|
+
*/
|
|
59
|
+
const planeAt = (inputs) => {
|
|
60
|
+
if (turn !== 'other') {
|
|
61
|
+
const values = graph.evaluate(inputs).values;
|
|
62
|
+
return face.plane.reduce((sum, p) => sum + p.k * values[shape.args[p.arg]], 0);
|
|
63
|
+
}
|
|
64
|
+
const geometry = compileFigureAsset({ ...asset, designInputs: { ...asset.designInputs, ...inputs } }).evaluate().geometry;
|
|
65
|
+
const box = figureOccupiedBoxesOf(geometry, figureWritersOf(asset)).find(b => b.part === part);
|
|
66
|
+
return box.centre[kept.normal] + (kept.outward > 0 ? -1 : 1) * (box.extent[kept.normal] / 2) - (inputs[position] ?? 0);
|
|
67
|
+
};
|
|
68
|
+
const shift = planeAt(before) - planeAt(after);
|
|
69
|
+
if (!Number.isFinite(shift) || Math.abs(shift) < 1e-9)
|
|
70
|
+
return given;
|
|
71
|
+
return [...given, { kind: 'set-design', input: position, unit: 'mm', value: round6(before[position] + shift) }];
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Per axis of the part's own frame, the face a size change keeps: 1 the low face (the part grows toward +), -1 the high
|
|
75
|
+
* face, 0 its centre -- what `figureSizeEditChanges` writes for a part placed by its own numbers, and what a fastening
|
|
76
|
+
* keeps for a fastened one (its face along the normal, its edges where it is aligned min or max). A gizmo drag shows
|
|
77
|
+
* this while it is dragged, so what the author sees is what is written (designer 2026-09-27: 「드래그 중 미리보기와
|
|
78
|
+
* 확정에 같은 기준면·간격 규칙」). Undefined where it cannot be said in the part's own axes -- a fastening turned or
|
|
79
|
+
* twisted -- and the caller must not guess one.
|
|
80
|
+
*/
|
|
81
|
+
export function figureScaleAnchorOf(asset, part) {
|
|
82
|
+
asset = upgradeFigurePlacement(asset);
|
|
83
|
+
const m = asset.document.model;
|
|
84
|
+
const node = (id) => m.nodes.find((n) => n.id === id);
|
|
85
|
+
const pose = node(`${part}.pose`);
|
|
86
|
+
if (!node(part) || pose?.op !== 'rigid@1')
|
|
87
|
+
return undefined;
|
|
88
|
+
const centre = { x: 0, y: 0, z: 0 };
|
|
89
|
+
const joint = (asset.joints ?? []).find((j) => j.body1?.part === part);
|
|
90
|
+
if (joint) {
|
|
91
|
+
const o = joint.origin ?? {};
|
|
92
|
+
if (o.twist || Object.values(o.turn ?? {}).some(t => t))
|
|
93
|
+
return undefined;
|
|
94
|
+
const anchor = { ...centre };
|
|
95
|
+
const face = joint.body1.face;
|
|
96
|
+
const FACE = { left: ['x', 1], right: ['x', -1], bottom: ['y', 1], top: ['y', -1], back: ['z', 1], front: ['z', -1] };
|
|
97
|
+
if (FACE[face])
|
|
98
|
+
anchor[FACE[face][0]] = FACE[face][1];
|
|
99
|
+
for (const [axis, how] of Object.entries(o.align ?? {}))
|
|
100
|
+
if (how === 'min')
|
|
101
|
+
anchor[axis] = 1;
|
|
102
|
+
else if (how === 'max')
|
|
103
|
+
anchor[axis] = -1;
|
|
104
|
+
return anchor;
|
|
105
|
+
}
|
|
106
|
+
if (node(`${part}.chain`) || node(`${part}.seat.rigid`))
|
|
107
|
+
return undefined;
|
|
108
|
+
const kept = KEPT_FACE[figurePlacementOf(asset)];
|
|
109
|
+
/* Placed at the centre, a size edit leaves the position as it is: the part grows about its centre. */
|
|
110
|
+
if (!kept)
|
|
111
|
+
return centre;
|
|
112
|
+
/*
|
|
113
|
+
Turned only about the plane's normal, its own axis along the normal is the plane's: the face is kept as unturned.
|
|
114
|
+
Turned any other way, the point kept is an extreme of what it covers, which no face of its own frame is: a drag
|
|
115
|
+
cannot show it, and the caller must not guess one (the fields keep it).
|
|
116
|
+
*/
|
|
117
|
+
const turn = turnKindOf(asset, pose, kept.normal);
|
|
118
|
+
if (turn === 'other' || turn === 'unknown')
|
|
119
|
+
return undefined;
|
|
120
|
+
const position = pose.args[AXES.indexOf(kept.normal)];
|
|
121
|
+
if (position !== `${part}.position.${kept.normal}`)
|
|
122
|
+
return centre;
|
|
123
|
+
return { ...centre, [kept.normal]: kept.outward };
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* "Put it on the plane, this once" -- the modeller's one-off align tool, by the figure's placement (designer 2026-09-27):
|
|
127
|
+
* a floor figure's part brings its bottom to Y 0, a ceiling one's its top, a wall one's its back to Z 0, and a centred
|
|
128
|
+
* figure's part its centre to the origin's height. Only the part's own position number moves; nothing is fastened, so a
|
|
129
|
+
* later change of size keeps the face by the size rule, not by a fastening (ADR-0097 §5.2: aligning once is not
|
|
130
|
+
* attaching). A part standing turned is aligned by the extent it covers turned, its lowest (highest, backmost) point,
|
|
131
|
+
* since its named face no longer lies along the plane.
|
|
132
|
+
*
|
|
133
|
+
* Refused, with the reason: a fastened part (its fastening places it), and a part whose position is worked out. The
|
|
134
|
+
* part's turn is never changed: only the one position number is written.
|
|
135
|
+
*/
|
|
136
|
+
export function figurePlaneAlignChanges(asset, part) {
|
|
137
|
+
asset = upgradeFigurePlacement(asset);
|
|
138
|
+
const placement = figurePlacementOf(asset);
|
|
139
|
+
const kept = KEPT_FACE[placement];
|
|
140
|
+
const m = asset.document.model;
|
|
141
|
+
const node = (id) => m.nodes.find((n) => n.id === id);
|
|
142
|
+
const pose = node(`${part}.pose`);
|
|
143
|
+
if ((asset.joints ?? []).some((j) => j.body1?.part === part) || node(`${part}.chain`) || node(`${part}.seat.rigid`))
|
|
144
|
+
return { changes: [], refusal: 'HELD' };
|
|
145
|
+
const axis = kept?.normal ?? 'y';
|
|
146
|
+
const position = pose?.args?.[AXES.indexOf(axis)];
|
|
147
|
+
if (pose?.op !== 'rigid@1' || position !== `${part}.position.${axis}` || !m.inputs.some((i) => i.id === position && i.role === 'design'))
|
|
148
|
+
return { changes: [], refusal: 'POSITION_RULE' };
|
|
149
|
+
const geometry = compileFigureAsset(asset).evaluate().geometry;
|
|
150
|
+
const box = figureOccupiedBoxesOf(geometry, figureWritersOf(asset)).find(b => b.part === part);
|
|
151
|
+
if (!box)
|
|
152
|
+
return { changes: [], refusal: 'NO_FACE' };
|
|
153
|
+
const values = compileFigureGraph(m).evaluate({ ...asset.designInputs, ...asset.stateDefaults }).values;
|
|
154
|
+
/* Where the kept point is now along the plane's normal: the named face for an unturned part, its covered extent turned. */
|
|
155
|
+
let at;
|
|
156
|
+
let contact;
|
|
157
|
+
if (!kept)
|
|
158
|
+
(at = box.centre[axis]), (contact = 'centre');
|
|
159
|
+
else {
|
|
160
|
+
const shape = m.nodes.find((n) => Object.values(n.outputs ?? {}).includes(node(part)?.args?.[0]));
|
|
161
|
+
const turn = turnKindOf(asset, pose, axis);
|
|
162
|
+
const named = shape ? figureShapeProviderOf(shape.op)?.faces[kept.face] : undefined;
|
|
163
|
+
const square = turn === 'none' || turn === 'about-normal';
|
|
164
|
+
/* A face lies on the plane only for a part standing square to it; otherwise what touches is the extreme it covers. */
|
|
165
|
+
if (named && square && named.axis === axis)
|
|
166
|
+
(at = values[position] + named.plane.reduce((sum, p) => sum + p.k * values[shape.args[p.arg]], 0)),
|
|
167
|
+
(contact = 'face');
|
|
168
|
+
else
|
|
169
|
+
(at = box.centre[axis] + (kept.outward > 0 ? -1 : 1) * (box.extent[axis] / 2)),
|
|
170
|
+
/* A shape with a face there, turned off the plane, is tilted; one with no face there (a ball) is not said to be. */
|
|
171
|
+
(contact = named && !square ? 'tilted' : 'extreme');
|
|
172
|
+
}
|
|
173
|
+
const next = Math.round((values[position] - at) * 1e6) / 1e6;
|
|
174
|
+
if (Math.abs(next - values[position]) < 1e-9)
|
|
175
|
+
return { changes: [], contact };
|
|
176
|
+
return { changes: [{ kind: 'set-design', input: position, unit: 'mm', value: next }], contact };
|
|
177
|
+
}
|
|
178
|
+
//# sourceMappingURL=size-edit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"size-edit.js","sourceRoot":"","sources":["../src/size-edit.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,8 +3,8 @@ type Dynamic = any;
|
|
|
3
3
|
* Outward normals in the shape's own frame, by feature name. A surface's pose keeps the part's rotation, so this is
|
|
4
4
|
* also the normal in the frame of a place (a seat or a grip) set on that face -- a scene reads it from here.
|
|
5
5
|
*/
|
|
6
|
-
export declare const
|
|
7
|
-
export interface
|
|
6
|
+
export declare const FIGURE_FACE_NORMALS: Readonly<Record<string, readonly [number, number, number]>>;
|
|
7
|
+
export interface FigureSurfaceContext {
|
|
8
8
|
/** Every node output's type, from the compiled graph. */
|
|
9
9
|
types: Dynamic;
|
|
10
10
|
/** Which node writes each output. */
|
|
@@ -13,8 +13,8 @@ export interface V3SurfaceContext {
|
|
|
13
13
|
assetFrame: string;
|
|
14
14
|
}
|
|
15
15
|
/** Check that a `{ placement, feature }` pair names a supported planar face, and say which one. */
|
|
16
|
-
export declare function
|
|
16
|
+
export declare function resolveFigureSurface(ctx: FigureSurfaceContext, contact: Dynamic, path: string): Dynamic;
|
|
17
17
|
/** Where a resolved surface sits, and which way it faces, for one evaluation of the graph. */
|
|
18
|
-
export declare function
|
|
18
|
+
export declare function evaluateFigureSurface(values: Dynamic, s: Dynamic): Dynamic;
|
|
19
19
|
export {};
|
|
20
|
-
//# sourceMappingURL=
|
|
20
|
+
//# sourceMappingURL=surface.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"surface.d.ts","sourceRoot":"","sources":["../src/surface.ts"],"names":[],"mappings":"AASA,KAAK,OAAO,GAAG,GAAG,CAAA;AAKlB;;;GAGG;AACH,eAAO,MAAM,mBAAmB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAS3F,CAAA;AAED,MAAM,WAAW,oBAAoB;IACnC,yDAAyD;IACzD,KAAK,EAAE,OAAO,CAAA;IACd,qCAAqC;IACrC,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;IAC7B,KAAK,EAAE,OAAO,CAAA;IACd,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,mGAAmG;AACnG,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,oBAAoB,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAgDvG;AAED,8FAA8F;AAC9F,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,GAAG,OAAO,CAuB1E"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* One reader for "this face of this part, in the asset frame". The capability bindings named their contacts this
|
|
3
|
-
* way first; the declared occupancy names the face it is mounted on the same way (
|
|
3
|
+
* way first; the declared occupancy names the face it is mounted on the same way (designer's ruling
|
|
4
4
|
* 2026-09-23), and neither writes the rule twice.
|
|
5
5
|
*
|
|
6
6
|
* A surface is a pair of graph outputs: an actual placement and a `feature@1` on the same shape. That pairing is
|
|
7
7
|
* what makes it a real face of a real drawn body, rather than any transform an author points at.
|
|
8
8
|
*/
|
|
9
|
-
import {
|
|
9
|
+
import { FigureContractError as ContractError } from "./contract.js";
|
|
10
10
|
const fail = (code, path, message) => {
|
|
11
11
|
throw new ContractError(code, path, message);
|
|
12
12
|
};
|
|
@@ -14,7 +14,7 @@ const fail = (code, path, message) => {
|
|
|
14
14
|
* Outward normals in the shape's own frame, by feature name. A surface's pose keeps the part's rotation, so this is
|
|
15
15
|
* also the normal in the frame of a place (a seat or a grip) set on that face -- a scene reads it from here.
|
|
16
16
|
*/
|
|
17
|
-
export const
|
|
17
|
+
export const FIGURE_FACE_NORMALS = {
|
|
18
18
|
left: [-1, 0, 0],
|
|
19
19
|
right: [1, 0, 0],
|
|
20
20
|
bottom: [0, -1, 0],
|
|
@@ -25,7 +25,7 @@ export const V3_FACE_NORMALS = {
|
|
|
25
25
|
end: [0, 1, 0]
|
|
26
26
|
};
|
|
27
27
|
/** Check that a `{ placement, feature }` pair names a supported planar face, and say which one. */
|
|
28
|
-
export function
|
|
28
|
+
export function resolveFigureSurface(ctx, contact, path) {
|
|
29
29
|
const { types, writers, model, assetFrame } = ctx;
|
|
30
30
|
if (!contact || typeof contact !== 'object' || Array.isArray(contact))
|
|
31
31
|
fail('SCHEMA', path, 'object required');
|
|
@@ -79,10 +79,10 @@ export function resolveV3Surface(ctx, contact, path) {
|
|
|
79
79
|
: [];
|
|
80
80
|
if (!allowed.includes(face))
|
|
81
81
|
fail('SURFACE_UNSUPPORTED', path, 'feature is not a supported planar surface');
|
|
82
|
-
return { ...contact, geometryId: selection ? null : place.id, selection, provider, face, frame: featureType.from, normal:
|
|
82
|
+
return { ...contact, geometryId: selection ? null : place.id, selection, provider, face, frame: featureType.from, normal: FIGURE_FACE_NORMALS[face] };
|
|
83
83
|
}
|
|
84
84
|
/** Where a resolved surface sits, and which way it faces, for one evaluation of the graph. */
|
|
85
|
-
export function
|
|
85
|
+
export function evaluateFigureSurface(values, s) {
|
|
86
86
|
const placed = values[s.placement], local = values[s.feature], r = placed.pose.r;
|
|
87
87
|
const normal = r.map((row) => row.reduce((v, x, i) => v + x * s.normal[i], 0));
|
|
88
88
|
const t = r.map((row, j) => placed.pose.t[j] + row.reduce((v, x, i) => v + x * local.t[i], 0));
|
|
@@ -104,4 +104,4 @@ export function evaluateV3Surface(values, s) {
|
|
|
104
104
|
provenance: 'verified-planar-surface'
|
|
105
105
|
};
|
|
106
106
|
}
|
|
107
|
-
//# sourceMappingURL=
|
|
107
|
+
//# sourceMappingURL=surface.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"surface.js","sourceRoot":"","sources":["../src/surface.ts"],"names":[],"mappings":"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"}
|
|
@@ -62,7 +62,7 @@ export declare const LIMITS: {
|
|
|
62
62
|
/** Triangles on one screen. **Not measured yet** -- the design target. */
|
|
63
63
|
readonly trianglesOnScreen: 500000;
|
|
64
64
|
/**
|
|
65
|
-
* How many of the same figure one screen must hold -- the
|
|
65
|
+
* How many of the same figure one screen must hold -- the grade's target (chief architect, 2026-09-24). A figure of
|
|
66
66
|
* 12 moving parts and 12 bodies (24 groups) runs 166 on one screen at 60 fps; one that fits that many is within the
|
|
67
67
|
* limit (C), twice as many is A.
|
|
68
68
|
*/
|
|
@@ -92,7 +92,7 @@ export declare const LIMITS: {
|
|
|
92
92
|
*/
|
|
93
93
|
export declare const SEGMENT_PRESETS: readonly number[];
|
|
94
94
|
/** The design inputs that stand for the figure's size, in mm. */
|
|
95
|
-
export declare const
|
|
95
|
+
export declare const FIGURE_SIZE_INPUTS: Readonly<Record<Axis, string>>;
|
|
96
96
|
/**
|
|
97
97
|
* The shape of a figure's `type` -- the name boards call it by: `SCREAMING_SNAKE_CASE` starting with a capital, 3 to 32
|
|
98
98
|
* characters. Capitals are the figure namespace; built-in scene components use lower-case kebab names, so a figure that
|
|
@@ -111,4 +111,4 @@ export declare const TYPE_LENGTH: {
|
|
|
111
111
|
export declare function placeholderType(now?: number): string;
|
|
112
112
|
/** Whether a type is the temporary name given before anyone names the figure. */
|
|
113
113
|
export declare function isPlaceholderType(type: string): boolean;
|
|
114
|
-
//# sourceMappingURL=
|
|
114
|
+
//# sourceMappingURL=words.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"words.d.ts","sourceRoot":"","sources":["../src/words.ts"],"names":[],"mappings":"AAUA,eAAO,MAAM,IAAI,0BAA2B,CAAA;AAC5C,MAAM,MAAM,IAAI,GAAG,CAAC,OAAO,IAAI,CAAC,CAAC,MAAM,CAAC,CAAA;AAExC,MAAM,WAAW,IAAI;IACnB,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;CACV;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,mBAAmB,+DAAgE,CAAA;AAChG,MAAM,MAAM,gBAAgB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAA;AAEnE;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,SAAS,gBAAgB,EAAE,CAAC,CAEjF,CAAA;AAEF,gFAAgF;AAChF,eAAO,MAAM,gBAAgB,gFAAiF,CAAA;AAC9G,MAAM,MAAM,cAAc,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAA;AAE9D;;;GAGG;AACH,eAAO,MAAM,YAAY,MAAM,CAAA;AAE/B;;;;;;;;GAQG;AACH,eAAO,MAAM,aAAa,0BAA2B,CAAA;AACrD,MAAM,MAAM,WAAW,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAA;AAExD,2CAA2C;AAC3C,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CAAyB,CAAA;AAE5E;;;GAGG;AACH,eAAO,MAAM,IAAI,MAAM,CAAA;AAEvB,MAAM,MAAM,WAAW,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAA;AAE/C;;;GAGG;AACH,eAAO,MAAM,MAAM;IACjB,2GAA2G;;IAE3G,qEAAqE;;IAErE,0EAA0E;;IAE1E;;;;OAIG;;IAEH;;;OAGG;;IAEH;;;;OAIG;;IAEH,mDAAmD;;IAEnD,mGAAmG;;IAEnG,iDAAiD;;CAEzC,CAAA;AAEV;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,SAAS,MAAM,EAA4B,CAAA;AAEzE,iEAAiE;AACjE,eAAO,MAAM,kBAAkB,EAAE,QAAQ,CAAC,MAAM,CAAC,IAAI,EAAE,MAAM,CAAC,CAA4D,CAAA;AAE1H;;;;GAIG;AACH,eAAO,MAAM,YAAY,QAAkC,CAAA;AAC3D,eAAO,MAAM,WAAW;;;CAA+B,CAAA;AAEvD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,GAAG,GAAE,MAAmB,GAAG,MAAM,CAEhE;AAID,iFAAiF;AACjF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEvD"}
|
|
@@ -62,7 +62,7 @@ export const LIMITS = {
|
|
|
62
62
|
/** Triangles on one screen. **Not measured yet** -- the design target. */
|
|
63
63
|
trianglesOnScreen: 500_000,
|
|
64
64
|
/**
|
|
65
|
-
* How many of the same figure one screen must hold -- the
|
|
65
|
+
* How many of the same figure one screen must hold -- the grade's target (chief architect, 2026-09-24). A figure of
|
|
66
66
|
* 12 moving parts and 12 bodies (24 groups) runs 166 on one screen at 60 fps; one that fits that many is within the
|
|
67
67
|
* limit (C), twice as many is A.
|
|
68
68
|
*/
|
|
@@ -92,7 +92,7 @@ export const LIMITS = {
|
|
|
92
92
|
*/
|
|
93
93
|
export const SEGMENT_PRESETS = [8, 12, 16, 24, 32, 48];
|
|
94
94
|
/** The design inputs that stand for the figure's size, in mm. */
|
|
95
|
-
export const
|
|
95
|
+
export const FIGURE_SIZE_INPUTS = Object.freeze({ x: 'size.x', y: 'size.y', z: 'size.z' });
|
|
96
96
|
/**
|
|
97
97
|
* The shape of a figure's `type` -- the name boards call it by: `SCREAMING_SNAKE_CASE` starting with a capital, 3 to 32
|
|
98
98
|
* characters. Capitals are the figure namespace; built-in scene components use lower-case kebab names, so a figure that
|
|
@@ -113,4 +113,4 @@ const PLACEHOLDER_TYPE = /^FIGURE_[0-9A-Z]{8}$/;
|
|
|
113
113
|
export function isPlaceholderType(type) {
|
|
114
114
|
return PLACEHOLDER_TYPE.test(type);
|
|
115
115
|
}
|
|
116
|
-
//# sourceMappingURL=
|
|
116
|
+
//# sourceMappingURL=words.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"words.js","sourceRoot":"","sources":["../src/words.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;;;GAIG;AAEH,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAU,CAAA;AAS5C;;;;;;;;;;GAUG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,UAAU,CAAU,CAAA;AAGhG;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAA0D,MAAM,CAAC,MAAM,CAAC;IACnG,YAAY,EAAE,CAAC,UAAU,EAAE,UAAU,CAAC;CACvC,CAAC,CAAA;AAEF,gFAAgF;AAChF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,QAAQ,CAAU,CAAA;AAG9G;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,GAAG,CAAA;AAE/B;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAU,CAAA;AAGrD,2CAA2C;AAC3C,MAAM,CAAC,MAAM,UAAU,GAAgC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,CAAA;AAE5E;;;GAGG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,GAAG,CAAA;AAIvB;;;GAGG;AACH,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,2GAA2G;IAC3G,iBAAiB,EAAE,CAAC;IACpB,qEAAqE;IACrE,cAAc,EAAE,IAAI;IACpB,0EAA0E;IAC1E,iBAAiB,EAAE,OAAO;IAC1B;;;;OAIG;IACH,eAAe,EAAE,GAAG;IACpB;;;OAGG;IACH,gBAAgB,EAAE,EAAE;IACpB;;;;OAIG;IACH,oBAAoB,EAAE,MAAM;IAC5B,mDAAmD;IACnD,oBAAoB,EAAE,CAAC;IACvB,mGAAmG;IACnG,eAAe,EAAE,CAAC;IAClB,iDAAiD;IACjD,WAAW,EAAE,CAAC;CACN,CAAA;AAEV;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAAsB,CAAC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAA;AAEzE,iEAAiE;AACjE,MAAM,CAAC,MAAM,kBAAkB,GAAmC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAA;AAE1H;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,+BAA+B,CAAA;AAC3D,MAAM,CAAC,MAAM,WAAW,GAAG,EAAE,GAAG,EAAE,CAAC,EAAE,GAAG,EAAE,EAAE,EAAW,CAAA;AAEvD;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,MAAc,IAAI,CAAC,GAAG,EAAE;IACtD,OAAO,UAAU,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,EAAE,CAAA;AACnD,CAAC;AAED,MAAM,gBAAgB,GAAG,sBAAsB,CAAA;AAE/C,iFAAiF;AACjF,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,OAAO,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACpC,CAAC"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Figure v3 — 조립 관계와 반응형 제약
|
|
2
2
|
|
|
3
3
|
> 상태: 아래 내용은 **폐기된 초기 초안**이다. 구현 계약으로 사용하지 않는다.
|
|
4
|
-
> [재설계 상세안](
|
|
4
|
+
> [재설계 상세안](design.md)이 이 문서를 대체한다. 특히 병렬 `fit/relative/face` 제약,
|
|
5
5
|
> 관계 없는 초안의 저장 금지, 2배 검사 통과를 안전성으로 간주하는 조건은 철회한다.
|
|
6
6
|
|
|
7
7
|
## 결정 요약
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
# V3 자산 저장·복원 계약 — 실험판
|
|
2
2
|
|
|
3
|
-
> 현재 구현·검증·제품 연결 상태는 [
|
|
3
|
+
> 현재 구현·검증·제품 연결 상태는 [구현·검증 현황](status.md)을 따른다. 본문의 단계별 연구/검증 기록은 제품 전체 완료 선언이 아니다.
|
|
4
4
|
|
|
5
5
|
## 구현 범위
|
|
6
6
|
|
|
7
7
|
그래프/기능 선언에 **설계 입력·동작 기본값·재질·팔레트·형상 품질**을 함께 담는 자산 envelope를 구현했다. 저장된 JSON만으로 이 범위의 평가 결과를 복원한다. 제품 서버·DB·실제 자산을 변경하지 않았다.
|
|
8
8
|
|
|
9
|
-
- [컴파일·직렬화·읽기 코드](../src/
|
|
10
|
-
- [JSON Schema](prototypes/
|
|
11
|
-
- [네 대표 모델 자산 생성 예제](prototypes/
|
|
12
|
-
- [검증 테스트](prototypes/
|
|
9
|
+
- [컴파일·직렬화·읽기 코드](../src/asset.ts) — 파일/DB 쓰기와 구분
|
|
10
|
+
- [JSON Schema](prototypes/asset.schema.json)
|
|
11
|
+
- [네 대표 모델 자산 생성 예제](prototypes/asset-samples.mjs)
|
|
12
|
+
- [검증 테스트](prototypes/asset.test.mjs)
|
|
13
13
|
|
|
14
|
-
버전은 `figure-
|
|
14
|
+
버전은 `figure-asset-1`이다. **정식 Figure V3 전체 포맷 완료를 뜻하지 않는다.**
|
|
15
15
|
|
|
16
16
|
## 저장 항목
|
|
17
17
|
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
| palette | 사용한 토큰의 색상 snapshot. 미정의 토큰은 거부 |
|
|
24
24
|
| appearance | source placement/member별 재질과 품질 설정 |
|
|
25
25
|
| name | 자산 이름 |
|
|
26
|
-
| occupancy | 선언한 점유 부피(`extent`: 그래프의 길이 값 셋)와 놓이는 면(`placement`). ADR-0044·0045 를 V3 로 다시 세운 것(ADR-0087 결정 3). 없으면 `
|
|
26
|
+
| occupancy | 선언한 점유 부피(`extent`: 그래프의 길이 값 셋)와 놓이는 면(`placement`). ADR-0044·0045 를 V3 로 다시 세운 것(ADR-0087 결정 3). 없으면 `inspectFigureAsset` 이 `OCCUPANCY_UNDECLARED` 를 낸다 |
|
|
27
27
|
| document.capabilities.names | 도형 수준 능력 이름. `FIGURE_CAPABILITIES` 목록 그대로 검사한다(ADR-0051 ④) |
|
|
28
28
|
|
|
29
29
|
메시·계산된 pose·과거 성공 판정은 저장하지 않는다. 다시 로드하면 선언에서 재계산한다. 이 프로토타입은 팔레트 색상을 고정 snapshot으로 저장한다. 제품 공통 테마를 따라갈지 자산 색상을 유지할지는 별도 정책이 필요하다. 조명·환경맵·카메라는 이 계약에 포함되지 않아 모든 화면의 픽셀 동일성을 보장하지 않는다.
|
|
@@ -65,4 +65,4 @@ appearance는 모든 `place@1`/`member@1`에 정확히 하나씩 필요하다.
|
|
|
65
65
|
- 파일 시스템 원자적 교체·권한·DB revision 충돌·업로드/다운로드 API는 없다. 함수는 문자열을 반환하며 제품 저장소에 직접 쓰지 않는다.
|
|
66
66
|
- 실제 속성창·AI-dock·새 모델/다른 모델 전환·재접속은 통합 테스트가 남아 있다.
|
|
67
67
|
|
|
68
|
-
저장된 자산을 공통 편집 세션으로 여는 연결과 격리 UI 검증은 [편집 화면 연결 검증](
|
|
68
|
+
저장된 자산을 공통 편집 세션으로 여는 연결과 격리 UI 검증은 [편집 화면 연결 검증](editor-integration.md)에 기록했다. 다음 게이트는 실제 제품의 V3 전용 편집 경로와 저장 API 연결이다. 프로토타입 테스트 수를 제품 배포 완료 여부로 사용하지 않는다.
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# UI·AI 공통 편집 트랜잭션 — 실행 프로토타입
|
|
2
2
|
|
|
3
|
-
> 현재 구현·검증·제품 연결 상태는 [
|
|
3
|
+
> 현재 구현·검증·제품 연결 상태는 [구현·검증 현황](status.md)을 따른다. 본문의 단계별 연구/검증 기록은 제품 전체 완료 선언이 아니다.
|
|
4
4
|
|
|
5
5
|
## 이번 구현 범위
|
|
6
6
|
|
|
7
|
-
[입력 세션](../src/
|
|
7
|
+
[입력 세션](../src/authoring-session.ts)은 design/state 값 편집을 담당한다. [workspace](../src/editor-workspace.ts)는 상자 추가와 입력 편집을 같은 50단계 undo/redo 이력으로 관리한다. [검증 테스트](prototypes/authoring-session.test.mjs)는 정식 소스 구현을 호출한다. 격리 UI에는 새 Figure·상자 추가·undo/redo 버튼이 연결되어 있다. 제품 AI-dock·일반 그래프 재저작·삭제·재질 편집은 아직 미완료다.
|
|
8
8
|
|
|
9
9
|
세션은 V3 문서와 초기 입력을 받아 동일 compiler로 검증한다. UI/AI 모두 아래 같은 요청을 사용한다.
|
|
10
10
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
#
|
|
1
|
+
# capability binding 설계 기준안
|
|
2
2
|
|
|
3
|
-
> 현재 구현·검증·제품 연결 상태는 [
|
|
3
|
+
> 현재 구현·검증·제품 연결 상태는 [구현·검증 현황](status.md)을 따른다. 본문의 단계별 연구/검증 기록은 제품 전체 완료 선언이 아니다.
|
|
4
4
|
|
|
5
5
|
상태: **실행 프로토타입 추가**, 제품 런타임·정식 직렬화 스키마 구현 완료 아님. 로봇암 전체 검증에서 발견한 tool-seat 간섭을 근거로 핵심 feature/frame 계약을 확장하는 부가 계약이다.
|
|
6
6
|
|
|
@@ -72,9 +72,9 @@ region은 의미상 허용/검사 영역이다. 표시용 가이드가 될 수
|
|
|
72
72
|
|
|
73
73
|
## 실행 프로토타입 결과 — 2026-09-21
|
|
74
74
|
|
|
75
|
-
- [컴파일·평가 코드](prototypes/
|
|
76
|
-
- [로봇암·포크리프트 binding 예제](prototypes/
|
|
77
|
-
- [회귀 테스트](prototypes/
|
|
75
|
+
- [컴파일·평가 코드](prototypes/capability-plan.mjs)
|
|
76
|
+
- [로봇암·포크리프트 binding 예제](prototypes/capability-samples.mjs)
|
|
77
|
+
- [회귀 테스트](prototypes/capability-plan.test.mjs)
|
|
78
78
|
|
|
79
79
|
`compileCapabilities(model, declaration)`은 typed graph를 내부에서 컴파일하고 선언을 snapshot으로 보관한다. 호출자가 제공한 임의의 pose 결과를 받아 검증한 것으로 표시하지 않는다. 현재 실험 계약은 `r3-capability-3`다. V1/V2는 자동 변환하지 않고 거부한다.
|
|
80
80
|
|
|
@@ -89,8 +89,8 @@ region은 의미상 허용/검사 영역이다. 표시용 가이드가 될 수
|
|
|
89
89
|
### 아직 구현하지 않은 계약
|
|
90
90
|
|
|
91
91
|
- `contacts`의 실제 표면 출처와 법선 검사는 아래 단계에서 추가했다. 물체와의 실제 접촉 여부 검사는 여전히 없다.
|
|
92
|
-
- 일반 capability 평가기는 공간·충돌을 미검증으로 둔다. 이후 별도 [상자 적재물·평면 접촉 검사](
|
|
93
|
-
- 단일 repeat의 선택 항목은 후속 [반복 참조 검증](
|
|
92
|
+
- 일반 capability 평가기는 공간·충돌을 미검증으로 둔다. 이후 별도 [상자 적재물·평면 접촉 검사](payload-contact-validation.md)를 추가했으며, 명시적으로 그 검사기를 호출한 경우에만 제한된 포함/접촉 결과를 얻는다. 전역 충돌 solver는 없다.
|
|
93
|
+
- 단일 repeat의 선택 항목은 후속 [반복 참조 검증](repeated-binding-validation.md)에서 연결했다. 개수 축소로 대상이 사라지면 실패하며 중첩 반복/외부 점유 복구는 미지원이다.
|
|
94
94
|
- JSON Schema, 마이그레이션, 제품 런타임, UI/AI 편집과 영속화는 별도 작업이다.
|
|
95
95
|
- 실제 tool-seat의 의미를 결정하거나 해당 solid를 자동 삭제하지 않았다.
|
|
96
96
|
|
|
@@ -106,4 +106,4 @@ region은 의미상 허용/검사 영역이다. 표시용 가이드가 될 수
|
|
|
106
106
|
|
|
107
107
|
반환된 `verified-planar-surface`는 **출처가 검증된 평면이라는 뜻**이지 payload와 접촉했다는 뜻이 아니다. 정점/면 영역 전체, 허용 오차, 하중 지지, 충돌 여부는 별도 검사다. curved feature, portal 등의 아직 정의되지 않은 경우를 가짜 평면으로 추정하지 않고 거부한다. 단일 repeat의 선택된 평면은 V3 계약에서 지원한다.
|
|
108
108
|
|
|
109
|
-
[직렬화 계약 및 테스트 결과](
|
|
109
|
+
[직렬화 계약 및 테스트 결과](document-contract.md)를 함께 참조한다.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# 공통 v3 실행 커널 실험
|
|
2
2
|
|
|
3
|
-
> 현재 구현·검증·제품 연결 상태는 [
|
|
3
|
+
> 현재 구현·검증·제품 연결 상태는 [구현·검증 현황](status.md)을 따른다. 본문의 단계별 연구/검증 기록은 제품 전체 완료 선언이 아니다.
|
|
4
4
|
|
|
5
5
|
2026-09-20. 제품 구현·출하 명세가 아닌 독립 실험이다.
|
|
6
6
|
원본 seed, package.json, 서버와 제품 코드를 수정하지 않는다.
|
|
@@ -11,11 +11,11 @@
|
|
|
11
11
|
이번에는 **모델 이름을 전혀 모르는 하나의 resolve 함수**에 선언 데이터를 입력한다.
|
|
12
12
|
실제 seed/fixture를 읽는 어댑터는 테스트에만 있고 엔진에는 없다.
|
|
13
13
|
|
|
14
|
-
- `docs/prototypes/
|
|
15
|
-
- `docs/prototypes/
|
|
14
|
+
- `docs/prototypes/kernel.mjs`: 공통 scalar/frame/geometry/repeat 평가.
|
|
15
|
+
- `docs/prototypes/kernel.test.mjs`: 실제 자료에서 유도한 선언과 독립 기대값 검사.
|
|
16
16
|
|
|
17
17
|
```sh
|
|
18
|
-
node --test docs/prototypes/
|
|
18
|
+
node --test docs/prototypes/kernel.test.mjs
|
|
19
19
|
```
|
|
20
20
|
|
|
21
21
|
Node 25.6.0에서 6개 검사 통과. 정상 크기·상태 조합 213개와 별도 반례/거절 검사를 실행했다.
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
# Figure Model V3 핵심 의미론 기준안 — r3
|
|
2
2
|
|
|
3
|
-
> 현재 구현·검증·제품 연결 상태는 [
|
|
3
|
+
> 현재 구현·검증·제품 연결 상태는 [구현·검증 현황](status.md)을 따른다. 본문의 단계별 연구/검증 기록은 제품 전체 완료 선언이 아니다.
|
|
4
4
|
|
|
5
|
-
실행 가능한 첫 subset: [연산·형상 타입 계약](
|
|
5
|
+
실행 가능한 첫 subset: [연산·형상 타입 계약](operator-contracts.md).
|
|
6
6
|
scalar 타입/참조 검증 단계이며 전체 의미론 구현과 구분한다.
|
|
7
|
-
후속으로 [공간 타입·부착 관계 통합](
|
|
8
|
-
반복의 현재 구현 범위는 [typed 반복 계약](
|
|
7
|
+
후속으로 [공간 타입·부착 관계 통합](spatial-contracts.md)을 추가했다.
|
|
8
|
+
반복의 현재 구현 범위는 [typed 반복 계약](typed-repeat-contracts.md)을 따른다.
|
|
9
9
|
|
|
10
10
|
상태: **설계 검토 기준안. 출하 명세·구현 완료 아님.**
|
|
11
11
|
이 문서가 r1/r2의 설계 방향을 대체한다. 과거 실험은 근거와 반례로 보존한다.
|
|
@@ -293,7 +293,7 @@ Y축 cylinder, feature의 방향 없는 point, 단순 floor(span/pitch)는 이
|
|
|
293
293
|
|
|
294
294
|
## 14. 기준안의 독립 수치 검사
|
|
295
295
|
|
|
296
|
-
`node --test docs/prototypes/
|
|
296
|
+
`node --test docs/prototypes/semantics.test.mjs`
|
|
297
297
|
|
|
298
298
|
- 부착식: 자기 feature 크기·회전·상태 45조합에서 `W*B=A*O*J` 확인.
|
|
299
299
|
- 반복식: 정수 길이/경계와 3개 정렬을 조합한 3,000건을 순차 배치 oracle과 비교.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# V3 단일 체계 전환 — 작업 기준
|
|
2
2
|
|
|
3
|
-
> 현재 구현·검증·제품 연결 상태는 [
|
|
3
|
+
> 현재 구현·검증·제품 연결 상태는 [구현·검증 현황](status.md)을 따른다. 본문의 단계별 연구/검증 기록은 제품 전체 완료 선언이 아니다.
|
|
4
4
|
|
|
5
5
|
사용자 결정: 제품은 V3 하나를 쓴다. V3의 단순성·일관성·저작성·품질을 우선하며, 버전별 편집 경로는 두지 않는다.
|
|
6
6
|
|
|
@@ -12,13 +12,13 @@ V2와 V1은 2026-09-26 코드와 명세에서 제거했다. ADR-0087의 전환
|
|
|
12
12
|
|
|
13
13
|
- figure-ui와 figure-service에 직전에 추가했던 형식 버전 차단 전용 코드와 테스트를 제거했다.
|
|
14
14
|
- 형식 해석 실패 시 다른 자산 ID로 기존 모델을 저장하지 않도록 하는 일반적인 로드 오류 처리는 유지했다. 이는 호환 기능이 아니라 데이터 손실 방지다.
|
|
15
|
-
- `
|
|
16
|
-
- `
|
|
15
|
+
- `createFigureAsset(name)`은 부품 없는 빈 자산을 만든다. 기본 상자는 자동 생성하지 않는다.
|
|
16
|
+
- `addFigureBox(asset, request)`는 명시적 부품 추가 요청을 표준 shape/rigid/place 노드와 9개 설계 입력(크기·위치·회전)으로 만든다. 별도의 레거시 parts 원본을 만들지 않는다.
|
|
17
17
|
- 중복 식별자, 잘못된 치수·재질은 거부한다. 입력 자산은 수정하지 않고 검증된 새 자산을 반환한다.
|
|
18
18
|
|
|
19
19
|
## 검증과 범위
|
|
20
20
|
|
|
21
|
-
상자 생성 함수 구현 당시 소스 테스트454개가 통과했다. 이후 트랜잭션 검증을 추가한 최신 수치는 [통합 현황](
|
|
21
|
+
상자 생성 함수 구현 당시 소스 테스트454개가 통과했다. 이후 트랜잭션 검증을 추가한 최신 수치는 [통합 현황](status.md)을 따른다. Chrome에서 빈 자산0개 → 상자1개 → 높이2000→1500mm 편집 → 저장 JSON 복원 경로를 검증했다. 기존 네 대표 자산과 편집 workspace의 브라우저 비교도 통과했다.
|
|
22
22
|
|
|
23
23
|
상자 추가 순수 함수를 workspace의 `addBox` 트랜잭션으로 연결했다. 부품 추가와 입력 수정은 같은 50단계 undo/redo 이력을 사용한다. 구조 변경도 미저장 상태에 반영되며, 잘못된 추가는 이력·revision·원본을 바꾸지 않는다. 저장 이후 undo하면 저장본과 달라졌음을 다시 표시한다.
|
|
24
24
|
|