@faicad/faijs 0.22.2 → 0.29.5
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/LICENSE +202 -28
- package/dist/api/api-namespace.d.ts +5 -5
- package/dist/api/api-namespace.d.ts.map +1 -1
- package/dist/api/api-namespace.js +4 -4
- package/dist/api/api-namespace.js.map +1 -1
- package/dist/api/appearance.d.ts +138 -0
- package/dist/api/appearance.d.ts.map +1 -0
- package/dist/api/appearance.js +230 -0
- package/dist/api/appearance.js.map +1 -0
- package/dist/api/assert.d.ts +2 -2
- package/dist/api/assert.js +8 -8
- package/dist/api/assert.js.map +1 -1
- package/dist/api/asset.d.ts +1 -1
- package/dist/api/asset.js +2 -2
- package/dist/api/asset.js.map +1 -1
- package/dist/api/boolean.d.ts +1 -1
- package/dist/api/boolean.d.ts.map +1 -1
- package/dist/api/boolean.js +128 -16
- package/dist/api/boolean.js.map +1 -1
- package/dist/api/cadquery-selectors/borrow-bridge.d.ts +14 -0
- package/dist/api/cadquery-selectors/borrow-bridge.d.ts.map +1 -0
- package/dist/api/cadquery-selectors/borrow-bridge.js +52 -0
- package/dist/api/cadquery-selectors/borrow-bridge.js.map +1 -0
- package/dist/api/cadquery-selectors/edge.d.ts +40 -0
- package/dist/api/cadquery-selectors/edge.d.ts.map +1 -0
- package/dist/api/cadquery-selectors/edge.js +70 -0
- package/dist/api/cadquery-selectors/edge.js.map +1 -0
- package/dist/api/cadquery-selectors/entity.d.ts +121 -0
- package/dist/api/cadquery-selectors/entity.d.ts.map +1 -0
- package/dist/api/cadquery-selectors/entity.js +167 -0
- package/dist/api/cadquery-selectors/entity.js.map +1 -0
- package/dist/api/cadquery-selectors/face.d.ts +33 -0
- package/dist/api/cadquery-selectors/face.d.ts.map +1 -0
- package/dist/api/cadquery-selectors/face.js +353 -0
- package/dist/api/cadquery-selectors/face.js.map +1 -0
- package/dist/api/cadquery-selectors/grammar.d.ts +50 -0
- package/dist/api/cadquery-selectors/grammar.d.ts.map +1 -0
- package/dist/api/cadquery-selectors/grammar.js +345 -0
- package/dist/api/cadquery-selectors/grammar.js.map +1 -0
- package/dist/api/cadquery-selectors/index.d.ts +18 -0
- package/dist/api/cadquery-selectors/index.d.ts.map +1 -0
- package/dist/api/cadquery-selectors/index.js +17 -0
- package/dist/api/cadquery-selectors/index.js.map +1 -0
- package/dist/api/cadquery-selectors/predicates.d.ts +76 -0
- package/dist/api/cadquery-selectors/predicates.d.ts.map +1 -0
- package/dist/api/cadquery-selectors/predicates.js +85 -0
- package/dist/api/cadquery-selectors/predicates.js.map +1 -0
- package/dist/api/cadquery-selectors/resolve.d.ts +41 -0
- package/dist/api/cadquery-selectors/resolve.d.ts.map +1 -0
- package/dist/api/cadquery-selectors/resolve.js +243 -0
- package/dist/api/cadquery-selectors/resolve.js.map +1 -0
- package/dist/api/cadquery-selectors/types.d.ts +96 -0
- package/dist/api/cadquery-selectors/types.d.ts.map +1 -0
- package/dist/api/cadquery-selectors/types.js +11 -0
- package/dist/api/cadquery-selectors/types.js.map +1 -0
- package/dist/api/chamfer.d.ts +13 -5
- package/dist/api/chamfer.d.ts.map +1 -1
- package/dist/api/chamfer.js +63 -7
- package/dist/api/chamfer.js.map +1 -1
- package/dist/api/compound-geom.d.ts +1 -1
- package/dist/api/compound-geom.js +1 -1
- package/dist/api/compound-geom.js.map +1 -1
- package/dist/api/draft.d.ts +1 -1
- package/dist/api/draft.js +1 -1
- package/dist/api/draft.js.map +1 -1
- package/dist/api/edge-ref.d.ts +1 -1
- package/dist/api/edge-ref.d.ts.map +1 -1
- package/dist/api/edge-ref.js +11 -3
- package/dist/api/edge-ref.js.map +1 -1
- package/dist/api/engrave.d.ts +1 -1
- package/dist/api/engrave.js +7 -7
- package/dist/api/engrave.js.map +1 -1
- package/dist/api/extrude.d.ts +6 -1
- package/dist/api/extrude.d.ts.map +1 -1
- package/dist/api/extrude.js +59 -5
- package/dist/api/extrude.js.map +1 -1
- package/dist/api/face-ref.d.ts +1 -1
- package/dist/api/face-ref.js +1 -1
- package/dist/api/face-ref.js.map +1 -1
- package/dist/api/feature-repair.d.ts +1 -1
- package/dist/api/feature-repair.js +1 -1
- package/dist/api/feature-repair.js.map +1 -1
- package/dist/api/fillet-variable.d.ts +1 -1
- package/dist/api/fillet-variable.js +1 -1
- package/dist/api/fillet-variable.js.map +1 -1
- package/dist/api/fillet.d.ts +28 -8
- package/dist/api/fillet.d.ts.map +1 -1
- package/dist/api/fillet.js +64 -9
- package/dist/api/fillet.js.map +1 -1
- package/dist/api/geom.d.ts +1 -1
- package/dist/api/geom.js +1 -1
- package/dist/api/geom.js.map +1 -1
- package/dist/api/helix.d.ts +1 -1
- package/dist/api/helix.js +1 -1
- package/dist/api/helix.js.map +1 -1
- package/dist/api/import-brep.d.ts +20 -2
- package/dist/api/import-brep.d.ts.map +1 -1
- package/dist/api/import-brep.js +28 -3
- package/dist/api/import-brep.js.map +1 -1
- package/dist/api/import-step.d.ts +17 -2
- package/dist/api/import-step.d.ts.map +1 -1
- package/dist/api/import-step.js +51 -3
- package/dist/api/import-step.js.map +1 -1
- package/dist/api/index.d.ts +6 -1
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/index.js +7 -2
- package/dist/api/index.js.map +1 -1
- package/dist/api/internal/compat-op.js +1 -1
- package/dist/api/internal/compat-op.js.map +1 -1
- package/dist/api/internal/mesh-solid-op.d.ts +236 -0
- package/dist/api/internal/mesh-solid-op.d.ts.map +1 -0
- package/dist/api/internal/mesh-solid-op.js +352 -0
- package/dist/api/internal/mesh-solid-op.js.map +1 -0
- package/dist/api/internal/svg-asset-resolver.d.ts +1 -1
- package/dist/api/internal/svg-asset-resolver.js +1 -1
- package/dist/api/internal/svg-asset-resolver.js.map +1 -1
- package/dist/api/knurl.d.ts +1 -1
- package/dist/api/knurl.js +2 -2
- package/dist/api/knurl.js.map +1 -1
- package/dist/api/loft.d.ts +1 -1
- package/dist/api/loft.js +1 -1
- package/dist/api/loft.js.map +1 -1
- package/dist/api/measurement/index.d.ts +9 -5
- package/dist/api/measurement/index.d.ts.map +1 -1
- package/dist/api/measurement/index.js +47 -20
- package/dist/api/measurement/index.js.map +1 -1
- package/dist/api/meta.d.ts +93 -0
- package/dist/api/meta.d.ts.map +1 -0
- package/dist/api/meta.js +99 -0
- package/dist/api/meta.js.map +1 -0
- package/dist/api/pattern.d.ts +5 -3
- package/dist/api/pattern.d.ts.map +1 -1
- package/dist/api/pattern.js +32 -4
- package/dist/api/pattern.js.map +1 -1
- package/dist/api/place.d.ts +1 -1
- package/dist/api/place.js +1 -1
- package/dist/api/place.js.map +1 -1
- package/dist/api/primitives.d.ts +1 -1
- package/dist/api/primitives.d.ts.map +1 -1
- package/dist/api/primitives.js +119 -4
- package/dist/api/primitives.js.map +1 -1
- package/dist/api/profile.d.ts +39 -12
- package/dist/api/profile.d.ts.map +1 -1
- package/dist/api/profile.js +4 -4
- package/dist/api/profile.js.map +1 -1
- package/dist/api/reconcile.d.ts +1 -1
- package/dist/api/reconcile.js +1 -1
- package/dist/api/reconcile.js.map +1 -1
- package/dist/api/replicate.d.ts.map +1 -1
- package/dist/api/replicate.js +122 -1
- package/dist/api/replicate.js.map +1 -1
- package/dist/api/screw.d.ts +1 -1
- package/dist/api/screw.js +3 -3
- package/dist/api/screw.js.map +1 -1
- package/dist/api/sdf.d.ts +1 -1
- package/dist/api/sdf.js +2 -2
- package/dist/api/sdf.js.map +1 -1
- package/dist/api/section-by-plane.d.ts +1 -1
- package/dist/api/section-by-plane.d.ts.map +1 -1
- package/dist/api/section-by-plane.js +2 -1
- package/dist/api/section-by-plane.js.map +1 -1
- package/dist/api/shell.d.ts +11 -4
- package/dist/api/shell.d.ts.map +1 -1
- package/dist/api/shell.js +53 -7
- package/dist/api/shell.js.map +1 -1
- package/dist/api/sketch-on-face.d.ts +41 -0
- package/dist/api/sketch-on-face.d.ts.map +1 -1
- package/dist/api/sketch-on-face.js +100 -1
- package/dist/api/sketch-on-face.js.map +1 -1
- package/dist/api/sketch-on-plane.d.ts +7 -5
- package/dist/api/sketch-on-plane.d.ts.map +1 -1
- package/dist/api/sketch-on-plane.js +6 -7
- package/dist/api/sketch-on-plane.js.map +1 -1
- package/dist/api/split-by-plane.d.ts +1 -1
- package/dist/api/split-by-plane.d.ts.map +1 -1
- package/dist/api/split-by-plane.js +2 -1
- package/dist/api/split-by-plane.js.map +1 -1
- package/dist/api/split.d.ts +1 -1
- package/dist/api/split.js +2 -2
- package/dist/api/split.js.map +1 -1
- package/dist/api/sweep.d.ts +1 -1
- package/dist/api/sweep.js +1 -1
- package/dist/api/sweep.js.map +1 -1
- package/dist/api/thicken.d.ts +1 -1
- package/dist/api/thicken.js +1 -1
- package/dist/api/thicken.js.map +1 -1
- package/dist/api/topo-resolve.d.ts +74 -1
- package/dist/api/topo-resolve.d.ts.map +1 -1
- package/dist/api/topo-resolve.js +180 -2
- package/dist/api/topo-resolve.js.map +1 -1
- package/dist/api/transform.d.ts +5 -1
- package/dist/api/transform.d.ts.map +1 -1
- package/dist/api/transform.js +62 -11
- package/dist/api/transform.js.map +1 -1
- package/dist/api/wire.d.ts +1 -1
- package/dist/api/wire.js +1 -1
- package/dist/api/wire.js.map +1 -1
- package/dist/brep/brep-ops.d.ts +9 -7
- package/dist/brep/brep-ops.d.ts.map +1 -1
- package/dist/brep/brep-ops.js +50 -26
- package/dist/brep/brep-ops.js.map +1 -1
- package/dist/brep/brep-topology.d.ts +5 -4
- package/dist/brep/brep-topology.d.ts.map +1 -1
- package/dist/brep/brep-topology.js +6 -5
- package/dist/brep/brep-topology.js.map +1 -1
- package/dist/brep/effective-deflection.d.ts +35 -0
- package/dist/brep/effective-deflection.d.ts.map +1 -0
- package/dist/brep/effective-deflection.js +49 -0
- package/dist/brep/effective-deflection.js.map +1 -0
- package/dist/brep/engine/adapters/brep-mock.d.ts.map +1 -1
- package/dist/brep/engine/adapters/brep-mock.js +27 -0
- package/dist/brep/engine/adapters/brep-mock.js.map +1 -1
- package/dist/brep/engine/adapters/brepkit.d.ts +18 -0
- package/dist/brep/engine/adapters/brepkit.d.ts.map +1 -1
- package/dist/brep/engine/adapters/brepkit.js +46 -1
- package/dist/brep/engine/adapters/brepkit.js.map +1 -1
- package/dist/brep/engine/adapters/occt.d.ts +1 -1
- package/dist/brep/engine/adapters/occt.d.ts.map +1 -1
- package/dist/brep/engine/adapters/occt.js +4 -2
- package/dist/brep/engine/adapters/occt.js.map +1 -1
- package/dist/brep/engine/primitives.d.ts +29 -7
- package/dist/brep/engine/primitives.d.ts.map +1 -1
- package/dist/brep/engine/primitives.js.map +1 -1
- package/dist/brep/engine/registry.d.ts +24 -1
- package/dist/brep/engine/registry.d.ts.map +1 -1
- package/dist/brep/engine/registry.js +24 -0
- package/dist/brep/engine/registry.js.map +1 -1
- package/dist/brep/engine/types.d.ts +54 -3
- package/dist/brep/engine/types.d.ts.map +1 -1
- package/dist/brep/engine/types.js +10 -0
- package/dist/brep/engine/types.js.map +1 -1
- package/dist/brep/export/export-model.d.ts +40 -0
- package/dist/brep/export/export-model.d.ts.map +1 -1
- package/dist/brep/export/export-model.js +274 -30
- package/dist/brep/export/export-model.js.map +1 -1
- package/dist/brep/export/step-meta-header.d.ts +102 -0
- package/dist/brep/export/step-meta-header.d.ts.map +1 -0
- package/dist/brep/export/step-meta-header.js +225 -0
- package/dist/brep/export/step-meta-header.js.map +1 -0
- package/dist/brep/export/step.d.ts +5 -1
- package/dist/brep/export/step.d.ts.map +1 -1
- package/dist/brep/export/step.js +11 -2
- package/dist/brep/export/step.js.map +1 -1
- package/dist/brep/face-evolution.d.ts +1 -1
- package/dist/brep/face-evolution.d.ts.map +1 -1
- package/dist/brep/face-evolution.js +20 -1
- package/dist/brep/face-evolution.js.map +1 -1
- package/dist/brep/handle-bridge.d.ts +1 -1
- package/dist/brep/handle-bridge.js +1 -1
- package/dist/brep/handle-bridge.js.map +1 -1
- package/dist/brep/mesh-solid.d.ts +218 -0
- package/dist/brep/mesh-solid.d.ts.map +1 -0
- package/dist/brep/mesh-solid.js +229 -0
- package/dist/brep/mesh-solid.js.map +1 -0
- package/dist/brep/text/fontRegistry.d.ts +32 -1
- package/dist/brep/text/fontRegistry.d.ts.map +1 -1
- package/dist/brep/text/fontRegistry.js +51 -1
- package/dist/brep/text/fontRegistry.js.map +1 -1
- package/dist/brep/text/text-to-solid.d.ts.map +1 -1
- package/dist/brep/text/text-to-solid.js +8 -3
- package/dist/brep/text/text-to-solid.js.map +1 -1
- package/dist/brepkit-kernel/brepkitKernel.d.ts +18 -2
- package/dist/brepkit-kernel/brepkitKernel.d.ts.map +1 -1
- package/dist/brepkit-kernel/brepkitKernel.js +449 -123
- package/dist/brepkit-kernel/brepkitKernel.js.map +1 -1
- package/dist/brepkit-kernel/brepkitWasm.d.ts +8 -0
- package/dist/brepkit-kernel/brepkitWasm.d.ts.map +1 -1
- package/dist/brepkit-kernel/brepkitWasm.js +10 -0
- package/dist/brepkit-kernel/brepkitWasm.js.map +1 -1
- package/dist/browser-host/browser-font-provider.d.ts +12 -0
- package/dist/browser-host/browser-font-provider.d.ts.map +1 -1
- package/dist/browser-host/browser-font-provider.js +25 -0
- package/dist/browser-host/browser-font-provider.js.map +1 -1
- package/dist/browser.d.ts +6 -3
- package/dist/browser.d.ts.map +1 -1
- package/dist/browser.js +10 -3
- package/dist/browser.js.map +1 -1
- package/dist/cad-runtime/backend-dispatch.d.ts +28 -3
- package/dist/cad-runtime/backend-dispatch.d.ts.map +1 -1
- package/dist/cad-runtime/backend-dispatch.js +119 -4
- package/dist/cad-runtime/backend-dispatch.js.map +1 -1
- package/dist/cad-runtime/browser-lib-loader.js.map +1 -1
- package/dist/cad-runtime/direct-executor.d.ts +15 -3
- package/dist/cad-runtime/direct-executor.d.ts.map +1 -1
- package/dist/cad-runtime/direct-executor.js +33 -1
- package/dist/cad-runtime/direct-executor.js.map +1 -1
- package/dist/cad-runtime/ports.d.ts +3 -3
- package/dist/cad-runtime/ports.d.ts.map +1 -1
- package/dist/cad-runtime/ports.js.map +1 -1
- package/dist/cad-runtime/preview-exec.d.ts +4 -4
- package/dist/cad-runtime/preview-exec.js +2 -2
- package/dist/cad-runtime/preview-exec.js.map +1 -1
- package/dist/cad-runtime/runtime.d.ts +42 -7
- package/dist/cad-runtime/runtime.d.ts.map +1 -1
- package/dist/cad-runtime/runtime.js +68 -5
- package/dist/cad-runtime/runtime.js.map +1 -1
- package/dist/define-op.d.ts +15 -1
- package/dist/define-op.d.ts.map +1 -1
- package/dist/define-op.js +73 -2
- package/dist/define-op.js.map +1 -1
- package/dist/env-agnostic.d.ts +2 -2
- package/dist/env-agnostic.d.ts.map +1 -1
- package/dist/env-agnostic.js +1 -1
- package/dist/env-agnostic.js.map +1 -1
- package/dist/geometry2d/adapt.d.ts +39 -4
- package/dist/geometry2d/adapt.d.ts.map +1 -1
- package/dist/geometry2d/adapt.js +14 -3
- package/dist/geometry2d/adapt.js.map +1 -1
- package/dist/geometry2d/blueprint.d.ts +2 -2
- package/dist/geometry2d/blueprint.js +2 -2
- package/dist/geometry2d/blueprint.js.map +1 -1
- package/dist/geometry2d/bridge/lift-on-plane.d.ts +18 -8
- package/dist/geometry2d/bridge/lift-on-plane.d.ts.map +1 -1
- package/dist/geometry2d/bridge/lift-on-plane.js +65 -12
- package/dist/geometry2d/bridge/lift-on-plane.js.map +1 -1
- package/dist/geometry2d/bridge/plane.d.ts +17 -0
- package/dist/geometry2d/bridge/plane.d.ts.map +1 -1
- package/dist/geometry2d/bridge/plane.js +22 -0
- package/dist/geometry2d/bridge/plane.js.map +1 -1
- package/dist/geometry2d/curve2d.d.ts +25 -0
- package/dist/geometry2d/curve2d.d.ts.map +1 -1
- package/dist/geometry2d/curve2d.js +41 -5
- package/dist/geometry2d/curve2d.js.map +1 -1
- package/dist/index.d.ts +6 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +10 -3
- package/dist/index.js.map +1 -1
- package/dist/io/bytes-node.d.ts +11 -0
- package/dist/io/bytes-node.d.ts.map +1 -0
- package/dist/io/bytes-node.js +28 -0
- package/dist/io/bytes-node.js.map +1 -0
- package/dist/io/bytes.d.ts +33 -0
- package/dist/io/bytes.d.ts.map +1 -0
- package/dist/io/bytes.js +41 -0
- package/dist/io/bytes.js.map +1 -0
- package/dist/io/fai-zip/container-read.d.ts +102 -0
- package/dist/io/fai-zip/container-read.d.ts.map +1 -0
- package/dist/io/fai-zip/container-read.js +305 -0
- package/dist/io/fai-zip/container-read.js.map +1 -0
- package/dist/io/fai-zip/container-write.d.ts +70 -0
- package/dist/io/fai-zip/container-write.d.ts.map +1 -0
- package/dist/io/fai-zip/container-write.js +186 -0
- package/dist/io/fai-zip/container-write.js.map +1 -0
- package/dist/io/fai-zip/container.d.ts +107 -0
- package/dist/io/fai-zip/container.d.ts.map +1 -0
- package/dist/io/fai-zip/container.js +89 -0
- package/dist/io/fai-zip/container.js.map +1 -0
- package/dist/io/fai-zip/index.d.ts +18 -0
- package/dist/io/fai-zip/index.d.ts.map +1 -0
- package/dist/io/fai-zip/index.js +4 -0
- package/dist/io/fai-zip/index.js.map +1 -0
- package/dist/io/index.d.ts +10 -0
- package/dist/io/index.d.ts.map +1 -0
- package/dist/io/index.js +13 -0
- package/dist/io/index.js.map +1 -0
- package/dist/io/zip.d.ts +68 -0
- package/dist/io/zip.d.ts.map +1 -0
- package/dist/io/zip.js +147 -0
- package/dist/io/zip.js.map +1 -0
- package/dist/lang/code-to-args.d.ts +1 -1
- package/dist/lang/code-to-args.js +1 -1
- package/dist/lang/code-to-args.js.map +1 -1
- package/dist/lang/metadata-extractor.d.ts.map +1 -1
- package/dist/lang/metadata-extractor.js +2 -21
- package/dist/lang/metadata-extractor.js.map +1 -1
- package/dist/lang/statement-summary.d.ts +1 -1
- package/dist/lang/statement-summary.js +1 -1
- package/dist/lang/statement-summary.js.map +1 -1
- package/dist/lang/types.d.ts +6 -7
- package/dist/lang/types.d.ts.map +1 -1
- package/dist/lang/types.js +1 -1
- package/dist/lang/types.js.map +1 -1
- package/dist/mesh/index.d.ts +2 -1
- package/dist/mesh/index.d.ts.map +1 -1
- package/dist/mesh/index.js +2 -1
- package/dist/mesh/index.js.map +1 -1
- package/dist/mesh/io.d.ts +13 -0
- package/dist/mesh/io.d.ts.map +1 -1
- package/dist/mesh/io.js +38 -17
- package/dist/mesh/io.js.map +1 -1
- package/dist/mesh/primitives.d.ts.map +1 -1
- package/dist/mesh/primitives.js +41 -6
- package/dist/mesh/primitives.js.map +1 -1
- package/dist/mesh/reconcile.d.ts +1 -1
- package/dist/mesh/reconcile.js +1 -1
- package/dist/mesh/reconcile.js.map +1 -1
- package/dist/mesh/rigid-transform.d.ts +3 -3
- package/dist/mesh/rigid-transform.js +3 -3
- package/dist/mesh/rigid-transform.js.map +1 -1
- package/dist/mesh/stl-unit.d.ts +24 -0
- package/dist/mesh/stl-unit.d.ts.map +1 -0
- package/dist/mesh/stl-unit.js +17 -0
- package/dist/mesh/stl-unit.js.map +1 -0
- package/dist/mesh/threemf-bambu.d.ts +142 -0
- package/dist/mesh/threemf-bambu.d.ts.map +1 -0
- package/dist/mesh/threemf-bambu.js +334 -0
- package/dist/mesh/threemf-bambu.js.map +1 -0
- package/dist/mesh/threemf-loader.d.ts +65 -7
- package/dist/mesh/threemf-loader.d.ts.map +1 -1
- package/dist/mesh/threemf-loader.js +738 -99
- package/dist/mesh/threemf-loader.js.map +1 -1
- package/dist/mesh/threemf-view.d.ts +71 -0
- package/dist/mesh/threemf-view.d.ts.map +1 -0
- package/dist/mesh/threemf-view.js +100 -0
- package/dist/mesh/threemf-view.js.map +1 -0
- package/dist/mesh/types.d.ts +38 -0
- package/dist/mesh/types.d.ts.map +1 -1
- package/dist/mesh/types.js.map +1 -1
- package/dist/node-host/cli.d.ts +44 -6
- package/dist/node-host/cli.d.ts.map +1 -1
- package/dist/node-host/cli.js +76 -26
- package/dist/node-host/cli.js.map +1 -1
- package/dist/node-host/font-family-index.d.ts +93 -0
- package/dist/node-host/font-family-index.d.ts.map +1 -0
- package/dist/node-host/font-family-index.js +273 -0
- package/dist/node-host/font-family-index.js.map +1 -0
- package/dist/node-host/fs-asset-resolver.d.ts +8 -3
- package/dist/node-host/fs-asset-resolver.d.ts.map +1 -1
- package/dist/node-host/fs-asset-resolver.js +13 -5
- package/dist/node-host/fs-asset-resolver.js.map +1 -1
- package/dist/node-host/index.d.ts +8 -0
- package/dist/node-host/index.d.ts.map +1 -1
- package/dist/node-host/index.js +1 -0
- package/dist/node-host/index.js.map +1 -1
- package/dist/node-host/node-font-provider.d.ts +28 -0
- package/dist/node-host/node-font-provider.d.ts.map +1 -1
- package/dist/node-host/node-font-provider.js +49 -0
- package/dist/node-host/node-font-provider.js.map +1 -1
- package/dist/node.d.ts +1 -0
- package/dist/node.d.ts.map +1 -1
- package/dist/node.js +1 -0
- package/dist/node.js.map +1 -1
- package/dist/occt-kernel/highLevelApi.d.ts +4 -1
- package/dist/occt-kernel/highLevelApi.d.ts.map +1 -1
- package/dist/occt-kernel/highLevelApi.js +4 -2
- package/dist/occt-kernel/highLevelApi.js.map +1 -1
- package/dist/occt-kernel/occt-primitives.d.ts.map +1 -1
- package/dist/occt-kernel/occt-primitives.js +36 -3
- package/dist/occt-kernel/occt-primitives.js.map +1 -1
- package/dist/occt-kernel/occtKernel.d.ts +19 -14
- package/dist/occt-kernel/occtKernel.d.ts.map +1 -1
- package/dist/occt-kernel/occtKernel.js +19 -32
- package/dist/occt-kernel/occtKernel.js.map +1 -1
- package/dist/occt-kernel/stepColorParser.d.ts +18 -0
- package/dist/occt-kernel/stepColorParser.d.ts.map +1 -1
- package/dist/occt-kernel/stepColorParser.js +38 -0
- package/dist/occt-kernel/stepColorParser.js.map +1 -1
- package/dist/occt-kernel/stepMetaParser.d.ts +44 -0
- package/dist/occt-kernel/stepMetaParser.d.ts.map +1 -0
- package/dist/occt-kernel/stepMetaParser.js +166 -0
- package/dist/occt-kernel/stepMetaParser.js.map +1 -0
- package/dist/occt-kernel/topologyExt.d.ts +1 -1
- package/dist/occt-kernel/topologyExt.d.ts.map +1 -1
- package/dist/occt-kernel/topologyExt.js +4 -5
- package/dist/occt-kernel/topologyExt.js.map +1 -1
- package/dist/primitives/text/cjk-font.d.ts +2 -15
- package/dist/primitives/text/cjk-font.d.ts.map +1 -1
- package/dist/primitives/text/cjk-font.js +13 -1
- package/dist/primitives/text/cjk-font.js.map +1 -1
- package/dist/runtime-state.d.ts +85 -9
- package/dist/runtime-state.d.ts.map +1 -1
- package/dist/runtime-state.js +72 -2
- package/dist/runtime-state.js.map +1 -1
- package/dist/sdk.d.ts +3 -3
- package/dist/sdk.d.ts.map +1 -1
- package/dist/sdk.js +5 -5
- package/dist/sdk.js.map +1 -1
- package/dist/shape.d.ts +108 -5
- package/dist/shape.d.ts.map +1 -1
- package/dist/shape.js +130 -3
- package/dist/shape.js.map +1 -1
- package/dist/step/stepMetaParser.d.ts +55 -0
- package/dist/step/stepMetaParser.d.ts.map +1 -0
- package/dist/step/stepMetaParser.js +177 -0
- package/dist/step/stepMetaParser.js.map +1 -0
- package/dist/topology/naming/lineage.d.ts +6 -0
- package/dist/topology/naming/lineage.d.ts.map +1 -1
- package/dist/topology/naming/lineage.js +8 -0
- package/dist/topology/naming/lineage.js.map +1 -1
- package/dist/topology/naming/resolve-edge.d.ts +20 -1
- package/dist/topology/naming/resolve-edge.d.ts.map +1 -1
- package/dist/topology/naming/resolve-edge.js +54 -20
- package/dist/topology/naming/resolve-edge.js.map +1 -1
- package/dist/weapp.d.ts +6 -2
- package/dist/weapp.d.ts.map +1 -1
- package/dist/weapp.js +7 -1
- package/dist/weapp.js.map +1 -1
- package/package.json +19 -3
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* api/appearance — faijs PBR 外观规格(颜色/材质/透明度)权威类型与 Shape 方法
|
|
3
|
+
*
|
|
4
|
+
* 设计文档:docs/plans/2026-10-05-faijs-pbr-appearance-api-design.md(v2)
|
|
5
|
+
*
|
|
6
|
+
* 定位:
|
|
7
|
+
* - 外观设置**不是 op**(不进 defineOp/api-namespace/args-schema),是 Shape
|
|
8
|
+
* 实例方法(`box1.setColor(...)`,复用 `asm1.solve()` 的成员调用语句形态)。
|
|
9
|
+
* - `PbrAppearance` 引擎无关、JSON 可序列化,随 Shape 走 mesh/brep 双链路
|
|
10
|
+
* (`Shape.appearance`),编辑器/查看器只读字段,不依赖方法。
|
|
11
|
+
* - 本文件零依赖(不 import THREE / occt / store);唯一 import 是 mesh/types
|
|
12
|
+
* 的 `Shape` 类型(type-only),mesh/types 亦只 type-import 本文件的类型,
|
|
13
|
+
* 两者为类型环、无运行时环(值依赖单向:shape.ts → api/appearance.ts)。
|
|
14
|
+
*
|
|
15
|
+
* 颜色约定:
|
|
16
|
+
* - 内部归一形态:`color: [r, g, b]`(sRGB,0–1);`opacity` 是透明度的唯一
|
|
17
|
+
* 权威字段(0–1)。
|
|
18
|
+
* - 输入接受 hex(#rgb / #rrggbb / #rrggbbaa)与数组([r,g,b] / [r,g,b,a]);
|
|
19
|
+
* `#rrggbbaa` / 数组第 4 分量的 alpha 等价于 `opacity`(显式 setOpacity 后
|
|
20
|
+
* 写入的 opacity 优先于后续无 alpha 的 setColor 推导,见 setColor 注释)。
|
|
21
|
+
* - CSS 颜色名:P1 不支持(抛错),由宿主或后续版本扩展。
|
|
22
|
+
*/
|
|
23
|
+
// ── 归一化 ──
|
|
24
|
+
/** hex #rgb/#rrggbb/#rrggbbaa → sRGB 0–1(+可选 alpha)。 */
|
|
25
|
+
function parseHexColor(hex) {
|
|
26
|
+
let h = hex.startsWith('#') ? hex.slice(1) : hex;
|
|
27
|
+
if (h.length === 3) {
|
|
28
|
+
h = h.split('').map((c) => c + c).join('');
|
|
29
|
+
}
|
|
30
|
+
if (h.length !== 6 && h.length !== 8) {
|
|
31
|
+
throw new Error(`[faijs/appearance] invalid hex color "${hex}" (expected #rgb/#rrggbb/#rrggbbaa)`);
|
|
32
|
+
}
|
|
33
|
+
if (!/^[0-9a-fA-F]+$/.test(h)) {
|
|
34
|
+
throw new Error(`[faijs/appearance] invalid hex color "${hex}" (non-hex digit)`);
|
|
35
|
+
}
|
|
36
|
+
const r = parseInt(h.slice(0, 2), 16) / 255;
|
|
37
|
+
const g = parseInt(h.slice(2, 4), 16) / 255;
|
|
38
|
+
const b = parseInt(h.slice(4, 6), 16) / 255;
|
|
39
|
+
const rgb = [r, g, b];
|
|
40
|
+
if (h.length === 8)
|
|
41
|
+
return { rgb, alpha: parseInt(h.slice(6, 8), 16) / 255 };
|
|
42
|
+
return { rgb };
|
|
43
|
+
}
|
|
44
|
+
function assertComponent01(v, label) {
|
|
45
|
+
if (v < 0 || v > 1 || !Number.isFinite(v)) {
|
|
46
|
+
throw new Error(`[faijs/appearance] ${label} must be in 0..1, got ${v}`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* 归一颜色输入 → { rgb, alpha? }。
|
|
51
|
+
* hex 与 [r,g,b] / [r,g,b,a](sRGB 0–1);CSS 颜色名 P1 不支持。
|
|
52
|
+
* @param color 颜色输入:`#rgb` / `#rrggbb` / `#rrggbbaa`,或 `[r,g,b]` / `[r,g,b,a]`(sRGB 0–1)
|
|
53
|
+
* @returns 归一后的 sRGB 颜色(0–1)与可选 alpha;带 alpha 的输入在 alpha 通道返回
|
|
54
|
+
*/
|
|
55
|
+
export function normalizeColor(color) {
|
|
56
|
+
if (typeof color === 'string') {
|
|
57
|
+
if (color.startsWith('#'))
|
|
58
|
+
return parseHexColor(color);
|
|
59
|
+
throw new Error(`[faijs/appearance] unsupported color "${color}" (P1: hex #rgb/#rrggbb/#rrggbbaa or [r,g,b] expected; CSS names not supported)`);
|
|
60
|
+
}
|
|
61
|
+
const [r, g, b, a] = color;
|
|
62
|
+
assertComponent01(r, 'color.r');
|
|
63
|
+
assertComponent01(g, 'color.g');
|
|
64
|
+
assertComponent01(b, 'color.b');
|
|
65
|
+
if (a !== undefined) {
|
|
66
|
+
assertComponent01(a, 'color.a');
|
|
67
|
+
return { rgb: [r, g, b], alpha: a };
|
|
68
|
+
}
|
|
69
|
+
return { rgb: [r, g, b] };
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* 合并外观:spec 中 undefined 字段不覆盖旧值。
|
|
73
|
+
* @param cur 当前外观(可为 undefined)
|
|
74
|
+
* @param spec 待合并字段(undefined 字段被跳过)
|
|
75
|
+
* @returns 合并后的外观(新对象;cur 为 undefined 时仅含 spec 非空字段)
|
|
76
|
+
*/
|
|
77
|
+
export function mergeAppearance(cur, spec) {
|
|
78
|
+
const clean = {};
|
|
79
|
+
for (const [k, v] of Object.entries(spec)) {
|
|
80
|
+
if (v !== undefined)
|
|
81
|
+
clean[k] = v;
|
|
82
|
+
}
|
|
83
|
+
return { ...(cur ?? {}), ...clean };
|
|
84
|
+
}
|
|
85
|
+
/** 两外观等价判定(字段级深比较;undefined 视同空对象)。 */
|
|
86
|
+
function sameAppearance(a, b) {
|
|
87
|
+
const ka = Object.keys(a ?? {}).filter((k) => a[k] !== undefined).sort();
|
|
88
|
+
const kb = Object.keys(b ?? {}).filter((k) => b[k] !== undefined).sort();
|
|
89
|
+
if (ka.length !== kb.length)
|
|
90
|
+
return false;
|
|
91
|
+
for (const k of ka) {
|
|
92
|
+
const va = a[k];
|
|
93
|
+
const vb = b[k];
|
|
94
|
+
if (Array.isArray(va) || Array.isArray(vb)) {
|
|
95
|
+
if (!Array.isArray(va) || !Array.isArray(vb) || va.length !== vb.length)
|
|
96
|
+
return false;
|
|
97
|
+
for (let i = 0; i < va.length; i++)
|
|
98
|
+
if (va[i] !== vb[i])
|
|
99
|
+
return false;
|
|
100
|
+
}
|
|
101
|
+
else if (va !== vb) {
|
|
102
|
+
return false;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
return true;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* 把 faceIds 指定的面(面序号 → `Shape.faceRanges` 三角形区间)合并进
|
|
109
|
+
* `shape.materialGroups`。多次设置同一面 → 外观合并(spec 未设置字段保留旧值);
|
|
110
|
+
* 不同面同外观 → 相邻区间合并为一个分组。输出按三角形起始排序。
|
|
111
|
+
*
|
|
112
|
+
* 无面结构(`faceRanges` 缺失——布尔/组合/导入产物)抛 `E_FACE_UNAVAILABLE`;
|
|
113
|
+
* 面序号越界/非整数抛 `E_FACE_INDEX`。
|
|
114
|
+
* @param shape 目标 Shape(必须携带 faceRanges)
|
|
115
|
+
* @param faceIds 面序号列表(PbrAppearance 面序契约见 mesh/primitives.ts 各构造点注释)
|
|
116
|
+
* @param spec 待合并到目标面的外观字段
|
|
117
|
+
*/
|
|
118
|
+
export function mergeFaceAppearance(shape, faceIds, spec) {
|
|
119
|
+
const ranges = shape.faceRanges;
|
|
120
|
+
if (!ranges || ranges.length === 0) {
|
|
121
|
+
throw new Error('[faijs/appearance] E_FACE_UNAVAILABLE: shape has no face structure — ' +
|
|
122
|
+
'face-level methods only apply to parameterized primitives (box/cylinder/cone); ' +
|
|
123
|
+
'boolean/combined/imported shapes have no CAD faces');
|
|
124
|
+
}
|
|
125
|
+
const targets = [];
|
|
126
|
+
for (const id of faceIds) {
|
|
127
|
+
if (!Number.isInteger(id) || id < 0 || id >= ranges.length) {
|
|
128
|
+
throw new Error(`[faijs/appearance] E_FACE_INDEX: face index ${id} out of range 0..${ranges.length - 1}`);
|
|
129
|
+
}
|
|
130
|
+
targets.push(ranges[id]);
|
|
131
|
+
}
|
|
132
|
+
const spans = [];
|
|
133
|
+
for (const g of shape.materialGroups ?? []) {
|
|
134
|
+
spans.push({ start: g.start, end: g.start + g.count, appearance: g.appearance });
|
|
135
|
+
}
|
|
136
|
+
// 每个目标区间与现有 spans 求并:重叠部分 mergeAppearance,保留两侧未覆盖段。
|
|
137
|
+
for (const t of targets) {
|
|
138
|
+
const ts = t.start;
|
|
139
|
+
const te = t.start + t.count;
|
|
140
|
+
let applied = false;
|
|
141
|
+
for (const h of spans) {
|
|
142
|
+
const is = Math.max(ts, h.start);
|
|
143
|
+
const ie = Math.min(te, h.end);
|
|
144
|
+
if (is >= ie)
|
|
145
|
+
continue;
|
|
146
|
+
applied = true;
|
|
147
|
+
const left = h.start < is ? { start: h.start, end: is, appearance: h.appearance } : null;
|
|
148
|
+
const right = ie < h.end ? { start: ie, end: h.end, appearance: h.appearance } : null;
|
|
149
|
+
const merged = { start: is, end: ie, appearance: mergeAppearance(h.appearance, spec) };
|
|
150
|
+
const idx = spans.indexOf(h);
|
|
151
|
+
spans.splice(idx, 1, ...(left ? [left] : []), merged, ...(right ? [right] : []));
|
|
152
|
+
}
|
|
153
|
+
if (!applied)
|
|
154
|
+
spans.push({ start: ts, end: te, appearance: spec });
|
|
155
|
+
}
|
|
156
|
+
// 归一化:按 start 排序 + 相邻同外观合并。
|
|
157
|
+
spans.sort((a, b) => a.start - b.start);
|
|
158
|
+
const out = [];
|
|
159
|
+
for (const s of spans) {
|
|
160
|
+
const last = out[out.length - 1];
|
|
161
|
+
if (last && last.end === s.start && sameAppearance(last.appearance, s.appearance)) {
|
|
162
|
+
last.end = s.end;
|
|
163
|
+
}
|
|
164
|
+
else {
|
|
165
|
+
out.push({ ...s });
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
shape.materialGroups = out.map((s) => ({
|
|
169
|
+
start: s.start,
|
|
170
|
+
count: s.end - s.start,
|
|
171
|
+
appearance: s.appearance ?? {},
|
|
172
|
+
}));
|
|
173
|
+
}
|
|
174
|
+
// ── Shape 方法挂载 ──
|
|
175
|
+
/**
|
|
176
|
+
* 给 Shape 实例挂载外观方法(幂等:已有 setAppearance 则跳过)。
|
|
177
|
+
*
|
|
178
|
+
* 所有产物构造点(solid/curve → fromBrep/fromMeshSolid/fromBrepCurve)统一
|
|
179
|
+
* 调用本函数,保证 mesh/brep 双链路产物都可用 `box1.setColor(...)`。
|
|
180
|
+
* 方法**不序列化**(JSON 丢弃函数);`appearance` 字段随产物跨 worker 传递,
|
|
181
|
+
* 编辑器/查看器只读字段即可,不依赖方法。
|
|
182
|
+
* @param shape 产物 Shape 实例(solid/curve 产物)
|
|
183
|
+
* @returns 挂载后的 shape(类型提升为 `Shape & ShapeAppearanceMethods`;同一实例原地挂载)
|
|
184
|
+
*/
|
|
185
|
+
export function attachAppearanceMethods(shape) {
|
|
186
|
+
const s = shape;
|
|
187
|
+
if (typeof s.setAppearance === 'function')
|
|
188
|
+
return s;
|
|
189
|
+
s.setAppearance = function setAppearance(spec) {
|
|
190
|
+
this.appearance = mergeAppearance(this.appearance, spec);
|
|
191
|
+
return this;
|
|
192
|
+
};
|
|
193
|
+
s.setColor = function setColor(color) {
|
|
194
|
+
const { rgb, alpha } = normalizeColor(color);
|
|
195
|
+
const spec = { color: rgb };
|
|
196
|
+
// #rrggbbaa / [r,g,b,a] 的 alpha 归一为 opacity(权威字段)。已显式
|
|
197
|
+
// setOpacity 的旧值:仅当本次 color 自带 alpha 时覆盖;无 alpha 的
|
|
198
|
+
// setColor 不动 opacity。
|
|
199
|
+
if (alpha !== undefined)
|
|
200
|
+
spec.opacity = alpha;
|
|
201
|
+
this.appearance = mergeAppearance(this.appearance, spec);
|
|
202
|
+
return this;
|
|
203
|
+
};
|
|
204
|
+
s.setMaterial = function setMaterial(spec) {
|
|
205
|
+
this.appearance = mergeAppearance(this.appearance, spec);
|
|
206
|
+
return this;
|
|
207
|
+
};
|
|
208
|
+
s.setOpacity = function setOpacity(opacity) {
|
|
209
|
+
assertComponent01(opacity, 'opacity');
|
|
210
|
+
this.appearance = mergeAppearance(this.appearance, { opacity });
|
|
211
|
+
return this;
|
|
212
|
+
};
|
|
213
|
+
s.getAppearance = function getAppearance() {
|
|
214
|
+
return this.appearance;
|
|
215
|
+
};
|
|
216
|
+
s.setFaceColor = function setFaceColor(faces, color) {
|
|
217
|
+
const { rgb, alpha } = normalizeColor(color);
|
|
218
|
+
const spec = { color: rgb };
|
|
219
|
+
if (alpha !== undefined)
|
|
220
|
+
spec.opacity = alpha;
|
|
221
|
+
mergeFaceAppearance(this, faces, spec);
|
|
222
|
+
return this;
|
|
223
|
+
};
|
|
224
|
+
s.setFaceMaterial = function setFaceMaterial(faces, spec) {
|
|
225
|
+
mergeFaceAppearance(this, faces, spec);
|
|
226
|
+
return this;
|
|
227
|
+
};
|
|
228
|
+
return s;
|
|
229
|
+
}
|
|
230
|
+
//# sourceMappingURL=appearance.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"appearance.js","sourceRoot":"","sources":["../../src/api/appearance.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * api/appearance — faijs PBR 外观规格(颜色/材质/透明度)权威类型与 Shape 方法\n *\n * 设计文档:docs/plans/2026-10-05-faijs-pbr-appearance-api-design.md(v2)\n *\n * 定位:\n * - 外观设置**不是 op**(不进 defineOp/api-namespace/args-schema),是 Shape\n * 实例方法(`box1.setColor(...)`,复用 `asm1.solve()` 的成员调用语句形态)。\n * - `PbrAppearance` 引擎无关、JSON 可序列化,随 Shape 走 mesh/brep 双链路\n * (`Shape.appearance`),编辑器/查看器只读字段,不依赖方法。\n * - 本文件零依赖(不 import THREE / occt / store);唯一 import 是 mesh/types\n * 的 `Shape` 类型(type-only),mesh/types 亦只 type-import 本文件的类型,\n * 两者为类型环、无运行时环(值依赖单向:shape.ts → api/appearance.ts)。\n *\n * 颜色约定:\n * - 内部归一形态:`color: [r, g, b]`(sRGB,0–1);`opacity` 是透明度的唯一\n * 权威字段(0–1)。\n * - 输入接受 hex(#rgb / #rrggbb / #rrggbbaa)与数组([r,g,b] / [r,g,b,a]);\n * `#rrggbbaa` / 数组第 4 分量的 alpha 等价于 `opacity`(显式 setOpacity 后\n * 写入的 opacity 优先于后续无 alpha 的 setColor 推导,见 setColor 注释)。\n * - CSS 颜色名:P1 不支持(抛错),由宿主或后续版本扩展。\n */\n\nimport type { Shape } from '../mesh/types'\n\n// ── 类型 ──\n\n/** 颜色输入:hex(#rgb/#rrggbb/#rrggbbaa)或 sRGB 0–1 数组([r,g,b] / [r,g,b,a])。 */\nexport type PbrColor = string | [number, number, number] | [number, number, number, number]\n\n/** glTF 透明度约定(与 3d_editor MaterialAppearance.alphaMode 对齐)。 */\nexport type PbrAlphaMode = 'OPAQUE' | 'MASK' | 'BLEND'\n\n/**\n * faijs PBR 外观规格 —— 引擎无关、JSON 可序列化、随 Shape 走双链路。\n *\n * 全字段可选:未设置字段 = 继承上游 / 宿主默认,不隐式清零。\n * 归一形态约定:`color` 为 [r,g,b](sRGB 0–1)数组;`opacity`(0–1)为\n * 透明度唯一权威字段(color 的 aa 分量在 set 时归一为 opacity)。\n */\nexport interface PbrAppearance {\n /** 基色(sRGB 0–1)。 */\n color?: [number, number, number]\n /** 透明度 0–1。 */\n opacity?: number\n /** 金属度 0–1;粗糙度 0–1。 */\n metalness?: number\n roughness?: number\n\n /** 自发光:颜色 + 强度(>0 时启用,默认 1)。 */\n emissive?: [number, number, number]\n emissiveIntensity?: number\n\n /** 透射/玻璃。 */\n transmission?: number\n thickness?: number\n ior?: number\n attenuationColor?: [number, number, number]\n attenuationDistance?: number\n\n /** 清漆。 */\n clearcoat?: number\n clearcoatRoughness?: number\n\n /** 织物/丝绒。 */\n sheen?: number\n sheenColor?: [number, number, number]\n sheenRoughness?: number\n\n /** 拉丝金属。 */\n anisotropy?: number\n anisotropyRotation?: number\n\n /** 高光工作流(替代 metalness 工作流)。 */\n specularIntensity?: number\n specularColor?: [number, number, number]\n\n /** 环境光强度(IBL 贡献)。 */\n envMapIntensity?: number\n\n /** 透明度模式:默认 OPAQUE;opacity<1 未显式指定时宿主按 BLEND 处理。 */\n alphaMode?: PbrAlphaMode\n alphaCutoff?: number\n /** 双面渲染。 */\n doubleSided?: boolean\n /** 无光照。 */\n unlit?: boolean\n}\n\n/** 材质参数(不含颜色/透明度,`cad` 便捷方法 setMaterial 的入参)。 */\nexport type MaterialSpec = Omit<PbrAppearance, 'color' | 'opacity'>\n\n/** Shape 外观方法签名(运行时由 attachAppearanceMethods 挂载;纯数据判定不受影响)。 */\nexport interface ShapeAppearanceMethods {\n /** 合并外观:`{...cur, ...spec}`,spec 中 undefined 字段保留旧值。 */\n setAppearance(spec: PbrAppearance): this\n /** 便捷:等价 setAppearance({ color });#rrggbbaa / [r,g,b,a] 的 alpha 归一为 opacity。 */\n setColor(color: PbrColor): this\n /** 便捷:等价 setAppearance(spec)。 */\n setMaterial(spec: MaterialSpec): this\n /** 便捷:透明度权威字段(0–1)。 */\n setOpacity(opacity: number): this\n /** 读取当前外观(可能 undefined)。 */\n getAppearance(): Readonly<PbrAppearance> | undefined\n /**\n * 面级设色:把 faceIds 指定的面(面序号契约见 `Shape.faceRanges`,参数化\n * primitives 才有)写入 `materialGroups`。无面结构(布尔/组合/导入产物)抛\n * `E_FACE_UNAVAILABLE`;面序号越界抛 `E_FACE_INDEX`。\n */\n setFaceColor(faces: number[], color: PbrColor): this\n /** 面级材质:等价 setFaceColor 的 material 版本。 */\n setFaceMaterial(faces: number[], spec: MaterialSpec): this\n}\n\n// ── 归一化 ──\n\n/** hex #rgb/#rrggbb/#rrggbbaa → sRGB 0–1(+可选 alpha)。 */\nfunction parseHexColor(hex: string): { rgb: [number, number, number]; alpha?: number } {\n let h = hex.startsWith('#') ? hex.slice(1) : hex\n if (h.length === 3) {\n h = h.split('').map((c) => c + c).join('')\n }\n if (h.length !== 6 && h.length !== 8) {\n throw new Error(`[faijs/appearance] invalid hex color \"${hex}\" (expected #rgb/#rrggbb/#rrggbbaa)`)\n }\n if (!/^[0-9a-fA-F]+$/.test(h)) {\n throw new Error(`[faijs/appearance] invalid hex color \"${hex}\" (non-hex digit)`)\n }\n const r = parseInt(h.slice(0, 2), 16) / 255\n const g = parseInt(h.slice(2, 4), 16) / 255\n const b = parseInt(h.slice(4, 6), 16) / 255\n const rgb: [number, number, number] = [r, g, b]\n if (h.length === 8) return { rgb, alpha: parseInt(h.slice(6, 8), 16) / 255 }\n return { rgb }\n}\n\nfunction assertComponent01(v: number, label: string): void {\n if (v < 0 || v > 1 || !Number.isFinite(v)) {\n throw new Error(`[faijs/appearance] ${label} must be in 0..1, got ${v}`)\n }\n}\n\n/**\n * 归一颜色输入 → { rgb, alpha? }。\n * hex 与 [r,g,b] / [r,g,b,a](sRGB 0–1);CSS 颜色名 P1 不支持。\n * @param color 颜色输入:`#rgb` / `#rrggbb` / `#rrggbbaa`,或 `[r,g,b]` / `[r,g,b,a]`(sRGB 0–1)\n * @returns 归一后的 sRGB 颜色(0–1)与可选 alpha;带 alpha 的输入在 alpha 通道返回\n */\nexport function normalizeColor(color: PbrColor): { rgb: [number, number, number]; alpha?: number } {\n if (typeof color === 'string') {\n if (color.startsWith('#')) return parseHexColor(color)\n throw new Error(\n `[faijs/appearance] unsupported color \"${color}\" (P1: hex #rgb/#rrggbb/#rrggbbaa or [r,g,b] expected; CSS names not supported)`,\n )\n }\n const [r, g, b, a] = color\n assertComponent01(r, 'color.r')\n assertComponent01(g, 'color.g')\n assertComponent01(b, 'color.b')\n if (a !== undefined) {\n assertComponent01(a, 'color.a')\n return { rgb: [r, g, b], alpha: a }\n }\n return { rgb: [r, g, b] }\n}\n\n/**\n * 合并外观:spec 中 undefined 字段不覆盖旧值。\n * @param cur 当前外观(可为 undefined)\n * @param spec 待合并字段(undefined 字段被跳过)\n * @returns 合并后的外观(新对象;cur 为 undefined 时仅含 spec 非空字段)\n */\nexport function mergeAppearance(cur: PbrAppearance | undefined, spec: PbrAppearance): PbrAppearance {\n const clean: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(spec)) {\n if (v !== undefined) clean[k] = v\n }\n return { ...(cur ?? {}), ...clean } as PbrAppearance\n}\n\n/** 两外观等价判定(字段级深比较;undefined 视同空对象)。 */\nfunction sameAppearance(a: PbrAppearance | undefined, b: PbrAppearance | undefined): boolean {\n const ka = Object.keys(a ?? {}).filter((k) => (a as Record<string, unknown>)[k] !== undefined).sort()\n const kb = Object.keys(b ?? {}).filter((k) => (b as Record<string, unknown>)[k] !== undefined).sort()\n if (ka.length !== kb.length) return false\n for (const k of ka) {\n const va = (a as Record<string, unknown>)[k]\n const vb = (b as Record<string, unknown>)[k]\n if (Array.isArray(va) || Array.isArray(vb)) {\n if (!Array.isArray(va) || !Array.isArray(vb) || va.length !== vb.length) return false\n for (let i = 0; i < va.length; i++) if (va[i] !== vb[i]) return false\n } else if (va !== vb) {\n return false\n }\n }\n return true\n}\n\n// ── 面级外观 ──\n\n/** 面区间跨度(内部表示,end 为开区间上界)。 */\ninterface FaceSpan {\n start: number\n end: number\n appearance: PbrAppearance | undefined\n}\n\n/**\n * 把 faceIds 指定的面(面序号 → `Shape.faceRanges` 三角形区间)合并进\n * `shape.materialGroups`。多次设置同一面 → 外观合并(spec 未设置字段保留旧值);\n * 不同面同外观 → 相邻区间合并为一个分组。输出按三角形起始排序。\n *\n * 无面结构(`faceRanges` 缺失——布尔/组合/导入产物)抛 `E_FACE_UNAVAILABLE`;\n * 面序号越界/非整数抛 `E_FACE_INDEX`。\n * @param shape 目标 Shape(必须携带 faceRanges)\n * @param faceIds 面序号列表(PbrAppearance 面序契约见 mesh/primitives.ts 各构造点注释)\n * @param spec 待合并到目标面的外观字段\n */\nexport function mergeFaceAppearance(shape: Shape, faceIds: number[], spec: PbrAppearance): void {\n const ranges = shape.faceRanges\n if (!ranges || ranges.length === 0) {\n throw new Error(\n '[faijs/appearance] E_FACE_UNAVAILABLE: shape has no face structure — ' +\n 'face-level methods only apply to parameterized primitives (box/cylinder/cone); ' +\n 'boolean/combined/imported shapes have no CAD faces',\n )\n }\n const targets: Array<{ start: number; count: number }> = []\n for (const id of faceIds) {\n if (!Number.isInteger(id) || id < 0 || id >= ranges.length) {\n throw new Error(\n `[faijs/appearance] E_FACE_INDEX: face index ${id} out of range 0..${ranges.length - 1}`,\n )\n }\n targets.push(ranges[id])\n }\n\n const spans: FaceSpan[] = []\n for (const g of shape.materialGroups ?? []) {\n spans.push({ start: g.start, end: g.start + g.count, appearance: g.appearance })\n }\n // 每个目标区间与现有 spans 求并:重叠部分 mergeAppearance,保留两侧未覆盖段。\n for (const t of targets) {\n const ts = t.start\n const te = t.start + t.count\n let applied = false\n for (const h of spans) {\n const is = Math.max(ts, h.start)\n const ie = Math.min(te, h.end)\n if (is >= ie) continue\n applied = true\n const left = h.start < is ? { start: h.start, end: is, appearance: h.appearance } : null\n const right = ie < h.end ? { start: ie, end: h.end, appearance: h.appearance } : null\n const merged: FaceSpan = { start: is, end: ie, appearance: mergeAppearance(h.appearance, spec) }\n const idx = spans.indexOf(h)\n spans.splice(idx, 1, ...(left ? [left] : []), merged, ...(right ? [right] : []))\n }\n if (!applied) spans.push({ start: ts, end: te, appearance: spec })\n }\n // 归一化:按 start 排序 + 相邻同外观合并。\n spans.sort((a, b) => a.start - b.start)\n const out: FaceSpan[] = []\n for (const s of spans) {\n const last = out[out.length - 1]\n if (last && last.end === s.start && sameAppearance(last.appearance, s.appearance)) {\n last.end = s.end\n } else {\n out.push({ ...s })\n }\n }\n shape.materialGroups = out.map((s) => ({\n start: s.start,\n count: s.end - s.start,\n appearance: s.appearance ?? {},\n }))\n}\n\n// ── Shape 方法挂载 ──\n\n/**\n * 给 Shape 实例挂载外观方法(幂等:已有 setAppearance 则跳过)。\n *\n * 所有产物构造点(solid/curve → fromBrep/fromMeshSolid/fromBrepCurve)统一\n * 调用本函数,保证 mesh/brep 双链路产物都可用 `box1.setColor(...)`。\n * 方法**不序列化**(JSON 丢弃函数);`appearance` 字段随产物跨 worker 传递,\n * 编辑器/查看器只读字段即可,不依赖方法。\n * @param shape 产物 Shape 实例(solid/curve 产物)\n * @returns 挂载后的 shape(类型提升为 `Shape & ShapeAppearanceMethods`;同一实例原地挂载)\n */\nexport function attachAppearanceMethods(shape: Shape): Shape & ShapeAppearanceMethods {\n const s = shape as Shape & ShapeAppearanceMethods\n if (typeof s.setAppearance === 'function') return s\n s.setAppearance = function setAppearance(this: Shape & ShapeAppearanceMethods, spec: PbrAppearance) {\n this.appearance = mergeAppearance(this.appearance, spec)\n return this\n }\n s.setColor = function setColor(this: Shape & ShapeAppearanceMethods, color: PbrColor) {\n const { rgb, alpha } = normalizeColor(color)\n const spec: PbrAppearance = { color: rgb }\n // #rrggbbaa / [r,g,b,a] 的 alpha 归一为 opacity(权威字段)。已显式\n // setOpacity 的旧值:仅当本次 color 自带 alpha 时覆盖;无 alpha 的\n // setColor 不动 opacity。\n if (alpha !== undefined) spec.opacity = alpha\n this.appearance = mergeAppearance(this.appearance, spec)\n return this\n }\n s.setMaterial = function setMaterial(this: Shape & ShapeAppearanceMethods, spec: MaterialSpec) {\n this.appearance = mergeAppearance(this.appearance, spec as PbrAppearance)\n return this\n }\n s.setOpacity = function setOpacity(this: Shape & ShapeAppearanceMethods, opacity: number) {\n assertComponent01(opacity, 'opacity')\n this.appearance = mergeAppearance(this.appearance, { opacity })\n return this\n }\n s.getAppearance = function getAppearance(this: Shape) {\n return this.appearance\n }\n s.setFaceColor = function setFaceColor(this: Shape & ShapeAppearanceMethods, faces: number[], color: PbrColor) {\n const { rgb, alpha } = normalizeColor(color)\n const spec: PbrAppearance = { color: rgb }\n if (alpha !== undefined) spec.opacity = alpha\n mergeFaceAppearance(this, faces, spec)\n return this\n }\n s.setFaceMaterial = function setFaceMaterial(this: Shape & ShapeAppearanceMethods, faces: number[], spec: MaterialSpec) {\n mergeFaceAppearance(this, faces, spec as PbrAppearance)\n return this\n }\n return s\n}\n"]}
|
package/dist/api/assert.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* api assert — per-op 参数自校验助手(Phase 2.2)
|
|
3
3
|
*
|
|
4
4
|
*
|
|
5
5
|
* 阶段 4 起(args-schema/SCHEMAS 已删除),参数校验全部由本模块的 assert 助手
|
|
6
|
-
* 承担(各
|
|
6
|
+
* 承担(各 api 函数在 dispatchPath 之前调用);非法即抛 Error(不静默)。
|
|
7
7
|
*/
|
|
8
8
|
/**
|
|
9
9
|
* Assert that a parameter is a finite number, narrowing the type to `number`.
|
package/dist/api/assert.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* api assert — per-op 参数自校验助手(Phase 2.2)
|
|
3
3
|
*
|
|
4
4
|
*
|
|
5
5
|
* 阶段 4 起(args-schema/SCHEMAS 已删除),参数校验全部由本模块的 assert 助手
|
|
6
|
-
* 承担(各
|
|
6
|
+
* 承担(各 api 函数在 dispatchPath 之前调用);非法即抛 Error(不静默)。
|
|
7
7
|
*/
|
|
8
8
|
/**
|
|
9
9
|
* Assert that a parameter is a finite number, narrowing the type to `number`.
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
*/
|
|
14
14
|
export function assertNumber(value, name) {
|
|
15
15
|
if (typeof value !== 'number' || !Number.isFinite(value)) {
|
|
16
|
-
throw new Error(`[
|
|
16
|
+
throw new Error(`[api] ${name} must be a finite number, got ${JSON.stringify(value)}`);
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
19
|
/**
|
|
@@ -24,7 +24,7 @@ export function assertNumber(value, name) {
|
|
|
24
24
|
export function assertPositiveNumber(value, name) {
|
|
25
25
|
assertNumber(value, name);
|
|
26
26
|
if (value <= 0) {
|
|
27
|
-
throw new Error(`[
|
|
27
|
+
throw new Error(`[api] ${name} must be > 0, got ${value}`);
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
/**
|
|
@@ -35,7 +35,7 @@ export function assertPositiveNumber(value, name) {
|
|
|
35
35
|
export function assertNonNegativeNumber(value, name) {
|
|
36
36
|
assertNumber(value, name);
|
|
37
37
|
if (value < 0) {
|
|
38
|
-
throw new Error(`[
|
|
38
|
+
throw new Error(`[api] ${name} must be >= 0, got ${value}`);
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
/**
|
|
@@ -47,7 +47,7 @@ export function assertVec3(value, name) {
|
|
|
47
47
|
if (!Array.isArray(value) ||
|
|
48
48
|
value.length !== 3 ||
|
|
49
49
|
value.some((n) => typeof n !== 'number' || !Number.isFinite(n))) {
|
|
50
|
-
throw new Error(`[
|
|
50
|
+
throw new Error(`[api] ${name} must be a vec3 [x, y, z], got ${JSON.stringify(value)}`);
|
|
51
51
|
}
|
|
52
52
|
}
|
|
53
53
|
/**
|
|
@@ -60,7 +60,7 @@ export function assertNonZeroVec3(value, name) {
|
|
|
60
60
|
assertVec3(value, name);
|
|
61
61
|
const v = value;
|
|
62
62
|
if (v[0] === 0 && v[1] === 0 && v[2] === 0) {
|
|
63
|
-
throw new Error(`[
|
|
63
|
+
throw new Error(`[api] ${name} must be a non-zero vec3, got ${JSON.stringify(value)}`);
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
/**
|
|
@@ -84,7 +84,7 @@ export function assertNumberOrVec3(value, name) {
|
|
|
84
84
|
*/
|
|
85
85
|
export function assertOneOf(value, name, allowed) {
|
|
86
86
|
if (value !== undefined && value !== null && !allowed.includes(value)) {
|
|
87
|
-
throw new Error(`[
|
|
87
|
+
throw new Error(`[api] ${name} must be one of ${allowed.join(' | ')}, got ${JSON.stringify(value)}`);
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
90
|
//# sourceMappingURL=assert.js.map
|
package/dist/api/assert.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assert.js","sourceRoot":"","sources":["../../src/api/assert.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,KAAc,EAAE,IAAY;IACvD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACzD,MAAM,IAAI,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"assert.js","sourceRoot":"","sources":["../../src/api/assert.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAAC,KAAc,EAAE,IAAY;IACvD,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACzD,MAAM,IAAI,KAAK,CAAC,SAAS,IAAI,iCAAiC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;IACxF,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAc,EAAE,IAAY;IAC/D,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;IACzB,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;QACf,MAAM,IAAI,KAAK,CAAC,SAAS,IAAI,qBAAqB,KAAK,EAAE,CAAC,CAAA;IAC5D,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,uBAAuB,CAAC,KAAc,EAAE,IAAY;IAClE,YAAY,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;IACzB,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QACd,MAAM,IAAI,KAAK,CAAC,SAAS,IAAI,sBAAsB,KAAK,EAAE,CAAC,CAAA;IAC7D,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,UAAU,CAAC,KAAc,EAAE,IAAY;IACrD,IACE,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC;QACrB,KAAK,CAAC,MAAM,KAAK,CAAC;QAClB,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAC/D,CAAC;QACD,MAAM,IAAI,KAAK,CAAC,SAAS,IAAI,kCAAkC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;IACzF,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAc,EAAE,IAAY;IAC5D,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;IACvB,MAAM,CAAC,GAAG,KAAiC,CAAA;IAC3C,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3C,MAAM,IAAI,KAAK,CAAC,SAAS,IAAI,iCAAiC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;IACxF,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAc,EAAE,IAAY;IAC7D,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,oBAAoB,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;QACjC,OAAM;IACR,CAAC;IACD,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;AACzB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,WAAW,CAAC,KAAc,EAAE,IAAY,EAAE,OAA0B;IAClF,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAe,CAAC,EAAE,CAAC;QAChF,MAAM,IAAI,KAAK,CAAC,SAAS,IAAI,mBAAmB,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAA;IACtG,CAAC;AACH,CAAC","sourcesContent":["/**\n * api assert — per-op 参数自校验助手(Phase 2.2)\n *\n *\n * 阶段 4 起(args-schema/SCHEMAS 已删除),参数校验全部由本模块的 assert 助手\n * 承担(各 api 函数在 dispatchPath 之前调用);非法即抛 Error(不静默)。\n */\n\n/**\n * Assert that a parameter is a finite number, narrowing the type to `number`.\n * @param value - the value to check.\n * @param name - the parameter name used in the thrown error message.\n * @returns asserts that `value` is a number.\n */\nexport function assertNumber(value: unknown, name: string): asserts value is number {\n if (typeof value !== 'number' || !Number.isFinite(value)) {\n throw new Error(`[api] ${name} must be a finite number, got ${JSON.stringify(value)}`)\n }\n}\n\n/**\n * Assert that a parameter is a number greater than zero.\n * @param value - the value to check.\n * @param name - the parameter name used in the thrown error message.\n */\nexport function assertPositiveNumber(value: unknown, name: string): void {\n assertNumber(value, name)\n if (value <= 0) {\n throw new Error(`[api] ${name} must be > 0, got ${value}`)\n }\n}\n\n/**\n * Assert that a parameter is a number greater than or equal to zero.\n * @param value - the value to check.\n * @param name - the parameter name used in the thrown error message.\n */\nexport function assertNonNegativeNumber(value: unknown, name: string): void {\n assertNumber(value, name)\n if (value < 0) {\n throw new Error(`[api] ${name} must be >= 0, got ${value}`)\n }\n}\n\n/**\n * Assert that a parameter is a vec3 `[x, y, z]` of finite numbers.\n * @param value - the value to check.\n * @param name - the parameter name used in the thrown error message.\n */\nexport function assertVec3(value: unknown, name: string): void {\n if (\n !Array.isArray(value) ||\n value.length !== 3 ||\n value.some((n) => typeof n !== 'number' || !Number.isFinite(n))\n ) {\n throw new Error(`[api] ${name} must be a vec3 [x, y, z], got ${JSON.stringify(value)}`)\n }\n}\n\n/**\n * Assert that a parameter is a non-zero vec3 (a zero vector would degenerate\n * operations such as split/faceNormal, so it is rejected).\n * @param value - the value to check.\n * @param name - the parameter name used in the thrown error message.\n */\nexport function assertNonZeroVec3(value: unknown, name: string): void {\n assertVec3(value, name)\n const v = value as [number, number, number]\n if (v[0] === 0 && v[1] === 0 && v[2] === 0) {\n throw new Error(`[api] ${name} must be a non-zero vec3, got ${JSON.stringify(value)}`)\n }\n}\n\n/**\n * Assert that a parameter is either a positive number or a vec3.\n * @param value - the value to check.\n * @param name - the parameter name used in the thrown error message.\n */\nexport function assertNumberOrVec3(value: unknown, name: string): void {\n if (typeof value === 'number') {\n assertPositiveNumber(value, name)\n return\n }\n assertVec3(value, name)\n}\n\n/**\n * Assert that a parameter is one of the given allowed values (skipped when\n * `value` is absent).\n * @param value - the value to check.\n * @param name - the parameter name used in the thrown error message.\n * @param allowed - the list of permitted string values.\n */\nexport function assertOneOf(value: unknown, name: string, allowed: readonly string[]): void {\n if (value !== undefined && value !== null && !allowed.includes(value as string)) {\n throw new Error(`[api] ${name} must be one of ${allowed.join(' | ')}, got ${JSON.stringify(value)}`)\n }\n}\n"]}
|
package/dist/api/asset.d.ts
CHANGED
package/dist/api/asset.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* api asset — `cad.asset(key)` 库函数(A7 消灭后 asset 走 CallRefIR)
|
|
3
3
|
*
|
|
4
4
|
*
|
|
5
5
|
* 嵌套调用 `cad.asset('cfg')` 返回 UTF-8 字符串(SVG 等文本资产)。
|
|
@@ -20,7 +20,7 @@ import { getBackends } from '../runtime-state.js';
|
|
|
20
20
|
export async function asset(key) {
|
|
21
21
|
const assets = getBackends().assets;
|
|
22
22
|
if (!assets) {
|
|
23
|
-
throw new Error(`[
|
|
23
|
+
throw new Error(`[api/asset] asset "${key}" cannot be resolved: assets not available`);
|
|
24
24
|
}
|
|
25
25
|
const result = await assets.resolveByKey(key);
|
|
26
26
|
return new TextDecoder('utf-8').decode(new Uint8Array(result.bytes));
|
package/dist/api/asset.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"asset.js","sourceRoot":"","sources":["../../src/api/asset.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAE9C;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,GAAW;IACrC,MAAM,MAAM,GAAG,WAAW,EAAE,CAAC,MAAoF,CAAA;IACjH,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,
|
|
1
|
+
{"version":3,"file":"asset.js","sourceRoot":"","sources":["../../src/api/asset.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAE9C;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,GAAW;IACrC,MAAM,MAAM,GAAG,WAAW,EAAE,CAAC,MAAoF,CAAA;IACjH,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,sBAAsB,GAAG,4CAA4C,CAAC,CAAA;IACxF,CAAC;IACD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,YAAY,CAAC,GAAG,CAAC,CAAA;IAC7C,OAAO,IAAI,WAAW,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,IAAI,UAAU,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAA;AACtE,CAAC","sourcesContent":["/**\n * api asset — `cad.asset(key)` 库函数(A7 消灭后 asset 走 CallRefIR)\n *\n *\n * 嵌套调用 `cad.asset('cfg')` 返回 UTF-8 字符串(SVG 等文本资产)。\n */\n\nimport { getBackends } from '../runtime-state'\n\n/**\n * 查询资产 key 内容为 UTF-8 字符串(SVG 等文本资产)。嵌套调用,供 text/svg 类 op 作资产引用。\n * @group 查询\n * @inputs 0\n * @async true\n * @qual ok\n * @name asset\n * @returns Promise<string> 资产内容字符串(UTF-8 解码)。`cad.asset('cfg')` 返回 SVG 等文本资产,可作 svgExtrude/engrave 的 svg 参数。\n * @param key - 资产 key。type:string required:true\n * @example\n * const svg = await cad.asset('logo_cfg')\n */\nexport async function asset(key: string): Promise<string> {\n const assets = getBackends().assets as { resolveByKey(key: string): Promise<{ bytes: ArrayBuffer }> } | undefined\n if (!assets) {\n throw new Error(`[api/asset] asset \"${key}\" cannot be resolved: assets not available`)\n }\n const result = await assets.resolveByKey(key)\n return new TextDecoder('utf-8').decode(new Uint8Array(result.bytes))\n}\n"]}
|
package/dist/api/boolean.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"boolean.d.ts","sourceRoot":"","sources":["../../src/api/boolean.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;
|
|
1
|
+
{"version":3,"file":"boolean.d.ts","sourceRoot":"","sources":["../../src/api/boolean.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AA6Q1C;;;;;;;;;;;IAWI;AACJ,eAAO,MAAM,KAAK;;CAgBhB,CAAA;AAEF;;;;;;;;;;;;;;;IAeI;AACJ,eAAO,MAAM,GAAG;;CAYd,CAAA;AAEF;;;;;;;;;;;IAWI;AACJ,eAAO,MAAM,QAAQ;;CAanB,CAAA;AAEF;;;;;;;;;;;IAWI;AACJ,eAAO,MAAM,SAAS;;CAiBpB,CAAA"}
|