@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
|
@@ -18,12 +18,55 @@
|
|
|
18
18
|
* - 链纪律:kernel.meshFallbackCount 计数差 > 0 → getMeshFallbackCount 暴露给宿主,
|
|
19
19
|
* 由宿主标记 BREP 链中断(不在此层静默处理)。
|
|
20
20
|
*/
|
|
21
|
-
import { initBrepkitWasm } from './brepkitWasm.js';
|
|
21
|
+
import { initBrepkitWasm, resetBrepkitWasm } from './brepkitWasm.js';
|
|
22
22
|
import { DEFAULT_LINEAR_DEFLECTION } from '../tolerance.js';
|
|
23
23
|
import { mm } from '../units.js';
|
|
24
|
-
|
|
24
|
+
import { BREP_HASH_BOUND } from '../brep/engine/types.js';
|
|
25
|
+
// ── 句柄桥接:brepkit number 句柄 ↔ BrepHandle ──
|
|
26
|
+
//
|
|
27
|
+
// GOTCHA(2026-10-01 实测,本文件最容易踩的坑):brepkit 句柄是**按类型分命名空间的裸 u32**
|
|
28
|
+
// ——同一个 box 上 solid=0、face=0..5、edge=0..11 同时存在,且**内核没有任何可靠的类型判别式**:
|
|
29
|
+
// getEdgeCurveType(0) / edgeLength(0) → 命中 edge 0
|
|
30
|
+
// getFaceEdges(0) / getFaceNormal(0) → 命中 face 0
|
|
31
|
+
// getSolidFaces(0) → 命中 solid 0
|
|
32
|
+
// 三者对同一个数字 0 各自返回「自己命名空间里 0 号」的数据,谁都不抛错(`getSolidFaces(1)` 才抛)。
|
|
33
|
+
// 因此「拿句柄去问内核它是什么类型」在 brepkit 上**不可能实现**。
|
|
34
|
+
//
|
|
35
|
+
// 但 L1 契约里 `hashCode(handle)` 只收到一个数字,必须知道类型才能选面/边指纹函数。
|
|
36
|
+
// 解法:适配器在**出口**把类型编进句柄高位。类型随句柄流动,`asNum()` 剥掉标签后仍是内核
|
|
37
|
+
// 裸句柄号——内部集合(knownFaces/knownEdges/…)、hashRegistry、全部 `kernel.*` 调用语义不变。
|
|
38
|
+
// 高 3 位(bit 26..28)放类型;虚拟 compound 句柄从 bit 29(0x20000000)起分配,互不干扰。
|
|
39
|
+
// 注意 `asNum` 用**算术减法**而非 `& ~KIND_MASK`:后者把 ≥2^31 的虚拟句柄按 int32 截断成负数。
|
|
40
|
+
const KIND_SHIFT = 26;
|
|
41
|
+
const KIND_MASK = 7 << KIND_SHIFT;
|
|
42
|
+
const KIND_SOLID = 0 << KIND_SHIFT; // 也是 compound / 未登记句柄的默认类
|
|
43
|
+
const KIND_FACE = 1 << KIND_SHIFT;
|
|
44
|
+
const KIND_EDGE = 2 << KIND_SHIFT;
|
|
45
|
+
const KIND_WIRE = 3 << KIND_SHIFT;
|
|
46
|
+
const KIND_VERTEX = 4 << KIND_SHIFT;
|
|
47
|
+
/** 句柄类型标签(0 = SOLID/COMPOUND 默认类)。 */
|
|
48
|
+
const kindOf = (h) => h & KIND_MASK;
|
|
49
|
+
/** 剥掉类型标签,得到 brepkit 内核裸句柄号——所有 `kernel.*` 调用必须用这个。 */
|
|
50
|
+
const asNum = (h) => {
|
|
51
|
+
const n = h;
|
|
52
|
+
return n - (n & KIND_MASK);
|
|
53
|
+
};
|
|
54
|
+
/** 实体/compound 句柄(默认类,保持历史行为:无标签 ⇒ 内核按 solid 路径分发)。 */
|
|
25
55
|
const asHandle = (n) => n;
|
|
26
|
-
const
|
|
56
|
+
const asFace = (n) => (n | KIND_FACE);
|
|
57
|
+
const asEdge = (n) => (n | KIND_EDGE);
|
|
58
|
+
const asWire = (n) => (n | KIND_WIRE);
|
|
59
|
+
const asVertex = (n) => (n | KIND_VERTEX);
|
|
60
|
+
/** 按已有类型标签给裸句柄重新打标签(copy/transform 族保持入参类型)。 */
|
|
61
|
+
const withKind = (kind, n) => {
|
|
62
|
+
switch (kind) {
|
|
63
|
+
case KIND_FACE: return asFace(n);
|
|
64
|
+
case KIND_EDGE: return asEdge(n);
|
|
65
|
+
case KIND_WIRE: return asWire(n);
|
|
66
|
+
case KIND_VERTEX: return asVertex(n);
|
|
67
|
+
default: return asHandle(n);
|
|
68
|
+
}
|
|
69
|
+
};
|
|
27
70
|
const arr = (x) => Array.from(x);
|
|
28
71
|
/** 适配器内部的显式失败(替代旧 unsupported 桩:能力缺失一律在静态判定拦截,不在实现体里伪装)。 */
|
|
29
72
|
function fail(detail) {
|
|
@@ -79,6 +122,26 @@ function toNumArray(v) {
|
|
|
79
122
|
}
|
|
80
123
|
return [];
|
|
81
124
|
}
|
|
125
|
+
/**
|
|
126
|
+
* brepkit 无任何 hash API(228 个方法里没有 hashCode/subShapeHashes)——faijs 侧的
|
|
127
|
+
* 面/边 hash 全部由适配器**合成指纹**,因此「合成函数」与「消费函数的取模上界」
|
|
128
|
+
* 必须同源:
|
|
129
|
+
* - 消费端 `topologyExt.buildSelectorManifestCore` 用
|
|
130
|
+
* `kernel.hashCode(subShape, BREP_HASH_BOUND)` 回查 faceGroups/edgeGroups 里的 hash;
|
|
131
|
+
* - 生产端(本文件的 solidMesh / faceMesh / compoundMesh / wireframe)必须用**同一个**
|
|
132
|
+
* `BREP_HASH_BOUND` 生成,否则查表恒 miss。
|
|
133
|
+
*
|
|
134
|
+
* GOTCHA(2026-10-01 实测修复):本文件此前生产端用 1e9、消费端用 2147483647,
|
|
135
|
+
* 导致 brepkit 引擎下面行的 triStart/triCount 恒为 0(面积/法向随之丢失)。
|
|
136
|
+
*/
|
|
137
|
+
function fnv1a(basis, upperBound) {
|
|
138
|
+
let h = 0x811c9dc5;
|
|
139
|
+
for (let i = 0; i < basis.length; i++) {
|
|
140
|
+
h ^= basis.charCodeAt(i);
|
|
141
|
+
h = Math.imul(h, 0x01000193) >>> 0;
|
|
142
|
+
}
|
|
143
|
+
return upperBound > 0 ? h % upperBound : h;
|
|
144
|
+
}
|
|
82
145
|
/** 面稳定指纹:解析曲面参数 + 面积 → FNV-1a → 取模上界(跨操作可追溯,与句柄无关)。 */
|
|
83
146
|
function faceFingerprint(kernel, face, upperBound) {
|
|
84
147
|
let params = '';
|
|
@@ -91,13 +154,45 @@ function faceFingerprint(kernel, face, upperBound) {
|
|
|
91
154
|
area = Number(kernel.faceArea?.(face, 0.1) ?? 0);
|
|
92
155
|
}
|
|
93
156
|
catch { /* 查询失败用 0 */ }
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
157
|
+
return fnv1a(`${params}|${area.toFixed(6)}`, upperBound);
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* 边稳定指纹:曲线类型 + 参数区间 + 两端/中点采样 + 长度 → FNV-1a。
|
|
161
|
+
*
|
|
162
|
+
* 为什么不能用 `faceFingerprint`:它对边恒得同一个值(`getAnalyticSurfaceParams`
|
|
163
|
+
* 与 `faceArea` 对 edge 句柄都抛错)——旧实现在 box 上 12 条边 hash 全同,
|
|
164
|
+
* 使 `topologyExt` 的 edgeGroupByHash 只留最后一条折线(实测 2026-10-01)。
|
|
165
|
+
*
|
|
166
|
+
* 为什么不能只用端点:整圆(圆柱端盖)首末点重合,z 不同的两个圆会撞 —
|
|
167
|
+
* 故补 UV 中点采样。`getBoundingBox(edge)` 在 brepkit 上抛错,不可用。
|
|
168
|
+
*/
|
|
169
|
+
function edgeFingerprint(kernel, edge, upperBound) {
|
|
170
|
+
let curveType = '';
|
|
171
|
+
try {
|
|
172
|
+
curveType = String(kernel.getEdgeCurveType(edge) ?? '');
|
|
99
173
|
}
|
|
100
|
-
|
|
174
|
+
catch { /* 非边 */ }
|
|
175
|
+
let range = '';
|
|
176
|
+
let mid = '';
|
|
177
|
+
try {
|
|
178
|
+
// 方言:`getEdgeCurveParameters` 返回 **Float64Array**(如 [0, 10]),不是 JSON 字符串
|
|
179
|
+
// (见本文件头的返回值归一化说明)。曾误用 JSON.parse → 恒定抛错 → range/mid 恒空,
|
|
180
|
+
// 于是所有同类型同长度的边(box 的 12 条棱)挤成同一个指纹(2026-10-01 实测)。
|
|
181
|
+
const p = toNumArray(kernel.getEdgeCurveParameters(edge));
|
|
182
|
+
const first = p[0] ?? 0;
|
|
183
|
+
const last = p[1] ?? 0;
|
|
184
|
+
range = `${first.toFixed(9)},${last.toFixed(9)}`;
|
|
185
|
+
const midT = (first + last) / 2;
|
|
186
|
+
const sample = (t) => toNumArray(kernel.evaluateEdgeCurve(edge, t)).map((x) => x.toFixed(6)).join(',');
|
|
187
|
+
mid = `${sample(first)}|${sample(midT)}|${sample(last)}`;
|
|
188
|
+
}
|
|
189
|
+
catch { /* 采样失败 → 退化为类型 + 空几何 */ }
|
|
190
|
+
let length = 0;
|
|
191
|
+
try {
|
|
192
|
+
length = Number(kernel.edgeLength(edge) ?? 0);
|
|
193
|
+
}
|
|
194
|
+
catch { /* 长度不可用用 0 */ }
|
|
195
|
+
return fnv1a(`${curveType}|${range}|${mid}|${length.toFixed(6)}`, upperBound);
|
|
101
196
|
}
|
|
102
197
|
/** 面演化数据(BrepEvolutionData):brepkit evolution JSON → hash 编码三元组。 */
|
|
103
198
|
function mapEvolution(kernel, raw, resultHandle, inputFaceHashes, hashUpperBound) {
|
|
@@ -148,7 +243,18 @@ function mapEvolution(kernel, raw, resultHandle, inputFaceHashes, hashUpperBound
|
|
|
148
243
|
}
|
|
149
244
|
/** per-kernel 的 hash↔handle 登记表(fuseWithHistory 溯源对齐用)。 */
|
|
150
245
|
const hashRegistry = new WeakMap();
|
|
151
|
-
/**
|
|
246
|
+
/**
|
|
247
|
+
* 三点外接圆(makeArcEdge 方言消化:occt 吃 3 点,brepkit 吃圆心+轴)。
|
|
248
|
+
*
|
|
249
|
+
* 圆心偏移取标准式 `d = ( |ab|²·(ac×n) + |ac|²·(n×ab) ) / (2·|n|²)`,`n = ab×ac`。
|
|
250
|
+
* GOTCHA(弧缺陷,2026-09-30 实证):旧式 `( |ac|²·(ab×n) + |ab|²·(n×ac) ) / (2·|n|²)`
|
|
251
|
+
* 把两项的系数对调,等于整体取反——圆心落到弦的另一侧(实测 quarter arc 圆心 (20,0,0)
|
|
252
|
+
* 而非 (0,0,0),三点不等距),brepkit 据此生成 333° 的补弧(弧长 58.195 而非 πr/2)。
|
|
253
|
+
* 判据是等距不变量 `|center−a| = |center−b| = |center−c|`。
|
|
254
|
+
*
|
|
255
|
+
* axis = n/|n| 即三点逆时针扫掠方向的右手法向;brepkit `makeCircleArc3d` 语义为
|
|
256
|
+
* "沿法向看从 start 逆时针到 end",故该轴向同时正确表达 ccw 与 cw 弧。
|
|
257
|
+
*/
|
|
152
258
|
function circumcircle(a, b, c) {
|
|
153
259
|
const abx = b.x - a.x, aby = b.y - a.y, abz = b.z - a.z;
|
|
154
260
|
const acx = c.x - a.x, acy = c.y - a.y, acz = c.z - a.z;
|
|
@@ -160,16 +266,16 @@ function circumcircle(a, b, c) {
|
|
|
160
266
|
fail('makeArcEdge: 3 points are collinear (no circumscribed circle)');
|
|
161
267
|
const ab2 = abx * abx + aby * aby + abz * abz;
|
|
162
268
|
const ac2 = acx * acx + acy * acy + acz * acz;
|
|
163
|
-
// center = a + (
|
|
164
|
-
const
|
|
165
|
-
const
|
|
269
|
+
// center = a + ( ab2·(ac×n) + ac2·(n×ab) ) / (2·n²)
|
|
270
|
+
const acxnx = acy * nz - acz * ny, acxny = acz * nx - acx * nz, acxnz = acx * ny - acy * nx;
|
|
271
|
+
const nxabx = ny * abz - nz * aby, nxaby = nz * abx - nx * abz, nxabz = nx * aby - ny * abx;
|
|
166
272
|
const denom = 2 * n2;
|
|
167
273
|
const len = Math.sqrt(n2);
|
|
168
274
|
return {
|
|
169
275
|
center: {
|
|
170
|
-
x: a.x + (
|
|
171
|
-
y: a.y + (
|
|
172
|
-
z: a.z + (
|
|
276
|
+
x: a.x + (ab2 * acxnx + ac2 * nxabx) / denom,
|
|
277
|
+
y: a.y + (ab2 * acxny + ac2 * nxaby) / denom,
|
|
278
|
+
z: a.z + (ab2 * acxnz + ac2 * nxabz) / denom,
|
|
173
279
|
},
|
|
174
280
|
axis: { x: nx / len, y: ny / len, z: nz / len },
|
|
175
281
|
};
|
|
@@ -192,6 +298,13 @@ function flattenPoints(points) {
|
|
|
192
298
|
*/
|
|
193
299
|
export async function createBrepkitPrimitives() {
|
|
194
300
|
const kernel = await initBrepkitWasm();
|
|
301
|
+
// GOTCHA(2026-10-01):本函数此前每次调用都新建一套闭包(knownFaces/knownSolids/
|
|
302
|
+
// derivedFaces…)——即**新建一套句柄桥接层**。句柄号虽然对同一个 wasm 内核全局有效,
|
|
303
|
+
// 但桥接层侧的类型登记表不同:A 层枚举出的面句柄交给 B 层做 getSubShapes,会被当
|
|
304
|
+
// 实体走 tessellateSolidGrouped。BREP 引擎装配点与网格后端装配点都调本函数,必须
|
|
305
|
+
// 拿到**同一个**对象。故按内核实例 memo 化(disposeBrepkit 会清掉)。
|
|
306
|
+
if (memoizedPrimitives && memoizedKernel === kernel)
|
|
307
|
+
return memoizedPrimitives;
|
|
195
308
|
liveKernel = kernel;
|
|
196
309
|
let lastFallbackCount = 0;
|
|
197
310
|
// 已知面句柄集合:getSubShapes(shape,'face') / makeRectangle / makeFace / buildTriFace
|
|
@@ -225,14 +338,45 @@ export async function createBrepkitPrimitives() {
|
|
|
225
338
|
// (实测 box makeBox 返回 solid 2,撞 profile 早先的 face 2 → cloneShape 走 copyFace 崩溃)。
|
|
226
339
|
// 建 solid 时必须从 knownFaces/knownWires/knownEdges/derivedFaces 抹掉该编号,让默认 solid 路径生效。
|
|
227
340
|
// derivedFaces 也必须清:getSubShapes(solid,'edge') 会查 derivedFaces.has(s) 误走 getFaceEdges。
|
|
341
|
+
// GOTCHA(2026-10-01 实测):`derivedFaces` 是**全局**面句柄号集合,枚举 solid A 的面会把
|
|
342
|
+
// 面号 0..N 写进去;此后对**裸句柄号恰好相同的另一个 solid**做 getSubShapes(...,'edge')
|
|
343
|
+
// 时,`derivedFaces.has(s)` 为真 → isFaceLike 误判 → 走 getFaceEdges 只拿到一张面的 4 条边
|
|
344
|
+
// (实测 box:12 条边变 4 条)。故必须显式登记 solid 句柄:实体永远不是 face-like。
|
|
345
|
+
const knownSolids = new Set();
|
|
228
346
|
const markSolid = (h) => {
|
|
229
347
|
knownFaces.delete(h);
|
|
230
348
|
knownWires.delete(h);
|
|
231
349
|
knownEdges.delete(h);
|
|
232
350
|
knownCompounds.delete(h);
|
|
233
351
|
derivedFaces.delete(h);
|
|
352
|
+
knownSolids.add(h);
|
|
234
353
|
return h;
|
|
235
354
|
};
|
|
355
|
+
/** 实体数组批量登记(阵列族返回多个实体)。 */
|
|
356
|
+
const markSolids = (list) => list.map(markSolid);
|
|
357
|
+
/**
|
|
358
|
+
* 句柄类型解析:**标签优先**,无标签时退回已知集合(历史行为)。
|
|
359
|
+
*
|
|
360
|
+
* 标签是权威来源——集合的 key 是**裸句柄号**,face 3 与 edge 3 会共存于不同集合,
|
|
361
|
+
* 靠集合无法区分。故有标签(非 0)时直接用标签,集合里的同名条目一律忽略;
|
|
362
|
+
* 只有无标签句柄(实体/compound/构造 API 外传入)才走集合分发,行为与加标签前一致。
|
|
363
|
+
*/
|
|
364
|
+
const resolveKind = (shape, s) => {
|
|
365
|
+
const tagged = kindOf(shape);
|
|
366
|
+
if (tagged !== KIND_SOLID)
|
|
367
|
+
return tagged;
|
|
368
|
+
// 已登记的实体优先:knownFaces/knownEdges 的 key 是裸句柄号,历史登记(如
|
|
369
|
+
// getSubShapes(face,'edge') 写 knownEdges)与后来新建的 solid 号同号时会把实体判成边。
|
|
370
|
+
if (knownSolids.has(s))
|
|
371
|
+
return KIND_SOLID;
|
|
372
|
+
if (knownFaces.has(s))
|
|
373
|
+
return KIND_FACE;
|
|
374
|
+
if (knownWires.has(s))
|
|
375
|
+
return KIND_WIRE;
|
|
376
|
+
if (knownEdges.has(s))
|
|
377
|
+
return KIND_EDGE;
|
|
378
|
+
return KIND_SOLID;
|
|
379
|
+
};
|
|
236
380
|
const readFallback = () => {
|
|
237
381
|
try {
|
|
238
382
|
return typeof kernel.meshFallbackCount === 'function' ? Number(kernel.meshFallbackCount()) : 0;
|
|
@@ -264,7 +408,7 @@ export async function createBrepkitPrimitives() {
|
|
|
264
408
|
indices: new Uint32Array(indices),
|
|
265
409
|
vertexCount: positions.length / 3,
|
|
266
410
|
triangleCount: triCount,
|
|
267
|
-
faceGroups: new Int32Array([0,
|
|
411
|
+
faceGroups: new Int32Array([0, indices.length, faceFingerprint(kernel, f, BREP_HASH_BOUND)]),
|
|
268
412
|
faceCount: 1,
|
|
269
413
|
};
|
|
270
414
|
};
|
|
@@ -304,21 +448,24 @@ export async function createBrepkitPrimitives() {
|
|
|
304
448
|
const solidMesh = (solid, deflection, angular) => {
|
|
305
449
|
const raw = kernel.tessellateSolidGrouped(solid, deflection, angular);
|
|
306
450
|
const m = JSON.parse(raw);
|
|
307
|
-
// faceOffsets 形如 [start0, start1, ..., totalEnd]
|
|
308
|
-
//
|
|
451
|
+
// faceOffsets 形如 [start0, start1, ..., totalEnd]:以「索引数组单位」计的每面偏移
|
|
452
|
+
// (2026-09-19 实测)。**L1 契约的 faceGroups 就是索引单位**(与 OCCT 一致,
|
|
453
|
+
// 见 brep/engine/types.BrepMeshResult)——此处原样透传,不得再除以 3。
|
|
454
|
+
// GOTCHA(2026-10-01):旧实现除以 3 换成三角形单位,与 topologyExt 的 `/3`
|
|
455
|
+
// 叠加 → 面行区间缩小 3 倍。
|
|
309
456
|
const fo = m.faceOffsets;
|
|
310
457
|
const faceCount = Math.max(0, fo.length - 1);
|
|
311
458
|
const faceHashes = [];
|
|
312
459
|
try {
|
|
313
460
|
const faces = arr(kernel.getSolidFaces(solid));
|
|
314
461
|
for (let i = 0; i < faceCount && i < faces.length; i++)
|
|
315
|
-
faceHashes.push(faceFingerprint(kernel, faces[i],
|
|
462
|
+
faceHashes.push(faceFingerprint(kernel, faces[i], BREP_HASH_BOUND));
|
|
316
463
|
}
|
|
317
464
|
catch { /* 非实体:faceHash 置 0 */ }
|
|
318
465
|
const faceGroups = new Int32Array(faceCount * 3);
|
|
319
466
|
for (let i = 0; i < faceCount; i++) {
|
|
320
|
-
faceGroups[i * 3] = fo[i]
|
|
321
|
-
faceGroups[i * 3 + 1] =
|
|
467
|
+
faceGroups[i * 3] = fo[i];
|
|
468
|
+
faceGroups[i * 3 + 1] = fo[i + 1] - fo[i];
|
|
322
469
|
faceGroups[i * 3 + 2] = faceHashes[i] ?? 0;
|
|
323
470
|
}
|
|
324
471
|
return {
|
|
@@ -337,7 +484,7 @@ export async function createBrepkitPrimitives() {
|
|
|
337
484
|
const normals = [];
|
|
338
485
|
const indices = [];
|
|
339
486
|
const faceGroups = [];
|
|
340
|
-
let
|
|
487
|
+
let indexOffset = 0;
|
|
341
488
|
for (const c of children) {
|
|
342
489
|
let sub;
|
|
343
490
|
if (knownFaces.has(c)) {
|
|
@@ -362,10 +509,10 @@ export async function createBrepkitPrimitives() {
|
|
|
362
509
|
indices.push(sub.indices[i] + vOffset);
|
|
363
510
|
if (sub.faceGroups) {
|
|
364
511
|
for (let i = 0; i < sub.faceGroups.length; i += 3) {
|
|
365
|
-
faceGroups.push((sub.faceGroups[i] ?? 0) +
|
|
512
|
+
faceGroups.push((sub.faceGroups[i] ?? 0) + indexOffset, sub.faceGroups[i + 1] ?? 0, sub.faceGroups[i + 2] ?? 0);
|
|
366
513
|
}
|
|
367
514
|
}
|
|
368
|
-
|
|
515
|
+
indexOffset += sub.indices.length;
|
|
369
516
|
}
|
|
370
517
|
return {
|
|
371
518
|
positions: new Float32Array(positions),
|
|
@@ -382,13 +529,15 @@ export async function createBrepkitPrimitives() {
|
|
|
382
529
|
// 传错即崩溃;transformSolid/transformFace/transformWire 均为「原地修改」void。
|
|
383
530
|
// place/translate 等会作用在 profile 产出的 face 上(sew 用例 place 两张 face),
|
|
384
531
|
// 故必须按 knownFaces/knownWires 分发,不能一律 copySolid。
|
|
385
|
-
|
|
386
|
-
|
|
532
|
+
// kind 为调用方句柄的类型标签(0 = solid):句柄标签是**权威判定**,knownFaces/knownWires
|
|
533
|
+
// 只作无标签时的兜底(枚举出的面句柄只进 derivedFaces,不在 knownFaces 里)。
|
|
534
|
+
const cloneShape = (shape, kind = KIND_SOLID) => {
|
|
535
|
+
if (kind === KIND_FACE || knownFaces.has(shape)) {
|
|
387
536
|
const c = kernel.copyFace(shape);
|
|
388
537
|
knownFaces.add(c);
|
|
389
538
|
return c;
|
|
390
539
|
}
|
|
391
|
-
if (knownWires.has(shape)) {
|
|
540
|
+
if (kind === KIND_WIRE || knownWires.has(shape)) {
|
|
392
541
|
const c = kernel.copyWire(shape);
|
|
393
542
|
knownWires.add(c);
|
|
394
543
|
return c;
|
|
@@ -396,12 +545,12 @@ export async function createBrepkitPrimitives() {
|
|
|
396
545
|
return markSolid(kernel.copySolid(shape));
|
|
397
546
|
};
|
|
398
547
|
/** 深拷贝 + 原地仿射变换(matrix 已经 toKernelMatrix 归一为 16 元素 4×4)。 */
|
|
399
|
-
const cloneAndTransform = (shape, matrix16) => {
|
|
400
|
-
const c = cloneShape(shape);
|
|
548
|
+
const cloneAndTransform = (shape, matrix16, kind = KIND_SOLID) => {
|
|
549
|
+
const c = cloneShape(shape, kind);
|
|
401
550
|
const m = Float64Array.from(matrix16);
|
|
402
|
-
if (knownFaces.has(c))
|
|
551
|
+
if (kind === KIND_FACE || knownFaces.has(c))
|
|
403
552
|
kernel.transformFace(c, m);
|
|
404
|
-
else if (knownWires.has(c))
|
|
553
|
+
else if (kind === KIND_WIRE || knownWires.has(c))
|
|
405
554
|
kernel.transformWire(c, m);
|
|
406
555
|
else
|
|
407
556
|
kernel.transformSolid(c, m);
|
|
@@ -435,11 +584,11 @@ export async function createBrepkitPrimitives() {
|
|
|
435
584
|
makeRectangle(width, height) {
|
|
436
585
|
const f = kernel.makeRectangle(width, height);
|
|
437
586
|
knownFaces.add(f);
|
|
438
|
-
return
|
|
587
|
+
return asFace(f);
|
|
439
588
|
},
|
|
440
589
|
makeEllipsoid(rx, ry, rz) { return asHandle(markSolid(kernel.makeEllipsoid(rx, ry, rz))); },
|
|
441
590
|
makeTorus(majorRadius, minorRadius) { return asHandle(markSolid(kernel.makeTorus(majorRadius, minorRadius, 64))); },
|
|
442
|
-
makeVertex(x, y, z) { return
|
|
591
|
+
makeVertex(x, y, z) { return asVertex(kernel.makeVertex(x, y, z)); },
|
|
443
592
|
// ── 造型运算 ──
|
|
444
593
|
extrude(shape, dx, dy, dz) {
|
|
445
594
|
// 方言归一(§3.6-1):L1 口径是挤出向量;brepkit 原生吃 (face, dir, distance)。
|
|
@@ -461,7 +610,7 @@ export async function createBrepkitPrimitives() {
|
|
|
461
610
|
return asHandle(markSolid(kernel.revolve(s, center.x, center.y, center.z, direction.x, direction.y, direction.z, angleDeg)));
|
|
462
611
|
},
|
|
463
612
|
sew(shapesList, tolerance) {
|
|
464
|
-
return asHandle(kernel.sewFaces(Uint32Array.from(shapesList.map(asNum)), tolerance ?? 1e-6));
|
|
613
|
+
return asHandle(markSolid(kernel.sewFaces(Uint32Array.from(shapesList.map(asNum)), tolerance ?? 1e-6)));
|
|
465
614
|
},
|
|
466
615
|
sewAndSolidify(faces, _tolerance) {
|
|
467
616
|
// brepkit 的 makeSolid 即「缝合并固化成实体」(sewFaces + 建 solid)。
|
|
@@ -469,10 +618,10 @@ export async function createBrepkitPrimitives() {
|
|
|
469
618
|
},
|
|
470
619
|
shell(solid, facesToRemove, thickness, _tolerance) {
|
|
471
620
|
// brepkit 参数序 (solid, thickness, open_faces);tolerance 内核固定。
|
|
472
|
-
return asHandle(kernel.shell(asNum(solid), thickness, Uint32Array.from(facesToRemove.map(asNum))));
|
|
621
|
+
return asHandle(markSolid(kernel.shell(asNum(solid), thickness, Uint32Array.from(facesToRemove.map(asNum)))));
|
|
473
622
|
},
|
|
474
623
|
hullFromPoints(points, _tolerance) {
|
|
475
|
-
return asHandle(kernel.convexHull(flattenPoints(points)));
|
|
624
|
+
return asHandle(markSolid(kernel.convexHull(flattenPoints(points))));
|
|
476
625
|
},
|
|
477
626
|
// ── 布尔与分割 ──
|
|
478
627
|
fuse(a, b) { return asHandle(markSolid(trackFallback(kernel.fuse(asNum(a), asNum(b))))); },
|
|
@@ -481,7 +630,7 @@ export async function createBrepkitPrimitives() {
|
|
|
481
630
|
// brepkit 无 `common` 原生名;交集语义由 `intersect` 承担(method-map: dialect)。
|
|
482
631
|
return asHandle(markSolid(trackFallback(kernel.intersect(asNum(a), asNum(b)))));
|
|
483
632
|
},
|
|
484
|
-
intersect(a, b) { return asHandle(trackFallback(kernel.intersect(asNum(a), asNum(b)))); },
|
|
633
|
+
intersect(a, b) { return asHandle(markSolid(trackFallback(kernel.intersect(asNum(a), asNum(b))))); },
|
|
485
634
|
fuseAll(shapesList) {
|
|
486
635
|
return asHandle(markSolid(trackFallback(kernel.fuseAll(Int32Array.from(shapesList.map(asNum))))));
|
|
487
636
|
},
|
|
@@ -515,24 +664,24 @@ export async function createBrepkitPrimitives() {
|
|
|
515
664
|
},
|
|
516
665
|
// ── 倒角与圆角(Q7:只对齐等距 + 距角两种粒度)──
|
|
517
666
|
chamfer(solid, edges, distance) {
|
|
518
|
-
return asHandle(trackFallback(kernel.chamfer(asNum(solid), Uint32Array.from(edges.map(asNum)), distance)));
|
|
667
|
+
return asHandle(markSolid(trackFallback(kernel.chamfer(asNum(solid), Uint32Array.from(edges.map(asNum)), distance))));
|
|
519
668
|
},
|
|
520
669
|
chamferDistAngle(solid, edges, distance, angleDeg) {
|
|
521
670
|
// 方言映射:L1 chamferDistAngle ↔ brepkit chamferDistanceAngle。
|
|
522
671
|
// ⚠️ 单位方言:L1 口径是**度**(`AddDA(distance, angleDeg, E, F)`),brepkit 内核吃**弧度**
|
|
523
672
|
// (2026-09-25 实证:传 45 抛 "angle must be less than π/2";传 π/4 正常倒角)。
|
|
524
673
|
const angleRad = (angleDeg * Math.PI) / 180;
|
|
525
|
-
return asHandle(trackFallback(kernel.chamferDistanceAngle(asNum(solid), Uint32Array.from(edges.map(asNum)), distance, angleRad)));
|
|
674
|
+
return asHandle(markSolid(trackFallback(kernel.chamferDistanceAngle(asNum(solid), Uint32Array.from(edges.map(asNum)), distance, angleRad))));
|
|
526
675
|
},
|
|
527
676
|
fillet(solid, edges, radius) {
|
|
528
|
-
return asHandle(trackFallback(kernel.fillet(asNum(solid), Uint32Array.from(edges.map(asNum)), radius)));
|
|
677
|
+
return asHandle(markSolid(trackFallback(kernel.fillet(asNum(solid), Uint32Array.from(edges.map(asNum)), radius))));
|
|
529
678
|
},
|
|
530
679
|
filletVariable(solid, edge, startRadius, endRadius) {
|
|
531
680
|
// 方言映射:L1 filletVariable(solid, edge, startRadius, endRadius)(单边变半径)
|
|
532
681
|
// ↔ brepkit filletVariable(solid, json) 吃**序列** `[{edge, radius1, radius2}, ...]`。
|
|
533
682
|
// ⚠️ 直接传 4 个位置参数会触发 wasm memory out of bounds(2026-09-25 实证)。
|
|
534
683
|
const spec = JSON.stringify([{ edge: asNum(edge), radius1: startRadius, radius2: endRadius }]);
|
|
535
|
-
return asHandle(trackFallback(kernel.filletVariable(asNum(solid), spec)));
|
|
684
|
+
return asHandle(markSolid(trackFallback(kernel.filletVariable(asNum(solid), spec))));
|
|
536
685
|
},
|
|
537
686
|
filletWithHistory(solid, edges, radius, inputFaceHashes, hashUpperBound) {
|
|
538
687
|
const raw = kernel.filletWithEvolution(asNum(solid), Int32Array.from(edges.map(asNum)), radius);
|
|
@@ -545,61 +694,62 @@ export async function createBrepkitPrimitives() {
|
|
|
545
694
|
// brepkit transformSolid 吃 4×4 行主序 16 元素。所有 transformSolid 调用一律经
|
|
546
695
|
// toKernelMatrix 归一(下方唯一转换点),禁止直出 16 元素旁路。
|
|
547
696
|
translate(shape, dx, dy, dz) {
|
|
548
|
-
return
|
|
697
|
+
return withKind(kindOf(shape), cloneAndTransform(asNum(shape), toKernelMatrix(translationMatrix(dx, dy, dz)), kindOf(shape)));
|
|
549
698
|
},
|
|
550
699
|
scale(shape, center, factor) {
|
|
551
|
-
return
|
|
700
|
+
return withKind(kindOf(shape), cloneAndTransform(asNum(shape), toKernelMatrix(scaleMatrix(center, factor)), kindOf(shape)));
|
|
552
701
|
},
|
|
553
702
|
transform(shape, matrix) {
|
|
554
|
-
return
|
|
703
|
+
return withKind(kindOf(shape), cloneAndTransform(asNum(shape), toKernelMatrix(matrix), kindOf(shape)));
|
|
555
704
|
},
|
|
556
705
|
located(shape, matrix) {
|
|
557
|
-
return
|
|
706
|
+
return withKind(kindOf(shape), cloneAndTransform(asNum(shape), toKernelMatrix(matrix), kindOf(shape)));
|
|
558
707
|
},
|
|
559
708
|
locate(shape, matrix) {
|
|
560
|
-
return
|
|
709
|
+
return withKind(kindOf(shape), cloneAndTransform(asNum(shape), toKernelMatrix(matrix), kindOf(shape)));
|
|
561
710
|
},
|
|
562
711
|
generalTransform(shape, matrix) {
|
|
563
|
-
return
|
|
712
|
+
return withKind(kindOf(shape), cloneAndTransform(asNum(shape), toKernelMatrix(matrix), kindOf(shape)));
|
|
564
713
|
},
|
|
565
|
-
copy(shape) { return
|
|
566
|
-
copyShape(shape) { return
|
|
714
|
+
copy(shape) { return withKind(kindOf(shape), cloneShape(asNum(shape), kindOf(shape))); },
|
|
715
|
+
copyShape(shape) { return withKind(kindOf(shape), cloneShape(asNum(shape), kindOf(shape))); },
|
|
567
716
|
composeTransform(m1, m2) {
|
|
568
717
|
// 方言:L1 是 3×4 行主序 12 元素;brepkit composeTransforms 吃/回 4×4 16 元素。
|
|
569
718
|
const r = kernel.composeTransforms(Float64Array.from(toKernelMatrix(m1)), Float64Array.from(toKernelMatrix(m2)));
|
|
570
719
|
return Array.from(r).slice(0, 12);
|
|
571
720
|
},
|
|
572
721
|
mirror(shape, point, normal) {
|
|
573
|
-
return
|
|
722
|
+
return withKind(kindOf(shape), kernel.mirror(asNum(shape), point.x, point.y, point.z, normal.x, normal.y, normal.z));
|
|
574
723
|
},
|
|
575
724
|
// ── 阵列 ──
|
|
576
725
|
// brepkit wasm 的 pattern 内核函数都返回 compound(含全部副本)→ 经 getCompoundSolids 拆成数组。
|
|
577
726
|
linearPattern(shape, direction, spacing, count) {
|
|
578
727
|
const compound = kernel.linearPattern(asNum(shape), direction.x, direction.y, direction.z, spacing, count);
|
|
579
|
-
|
|
728
|
+
// 阵列内核返回 compound(原始句柄)→ 拆成实体数组并逐个登记(见 markSolid GOTCHA)。
|
|
729
|
+
return markSolids(arr(kernel.getCompoundSolids(compound))).map(asHandle);
|
|
580
730
|
},
|
|
581
731
|
circularPattern(shape, _center, axis, _angleStep, count) {
|
|
582
732
|
// ⚠️ brepkit wasm circularPattern(solid, ax, ay, az, count) 无 center/angle 参数:
|
|
583
733
|
// 固定整圆均分(每份 360°/count)。fullAngle=360 时与 vendored/occt 语义一致;
|
|
584
734
|
// 其它角度跨度无法表达(语义限制记录于此,parity 测试用整圆)。
|
|
585
735
|
const compound = kernel.circularPattern(asNum(shape), axis.x, axis.y, axis.z, count);
|
|
586
|
-
return arr(kernel.getCompoundSolids(compound)).map(asHandle);
|
|
736
|
+
return markSolids(arr(kernel.getCompoundSolids(compound))).map(asHandle);
|
|
587
737
|
},
|
|
588
738
|
gridPattern(shape, directionX, directionY, spacingX, spacingY, countX, countY) {
|
|
589
|
-
return asHandle(kernel.gridPattern(asNum(shape), directionX.x, directionX.y, directionX.z, directionY.x, directionY.y, directionY.z, spacingX, spacingY, countX, countY));
|
|
739
|
+
return asHandle(markSolid(kernel.gridPattern(asNum(shape), directionX.x, directionX.y, directionX.z, directionY.x, directionY.y, directionY.z, spacingX, spacingY, countX, countY)));
|
|
590
740
|
},
|
|
591
741
|
// ── 曲线构造 ──
|
|
592
742
|
makeLineEdge(start, end) {
|
|
593
743
|
const e = kernel.makeLineEdge(start.x, start.y, start.z, end.x, end.y, end.z);
|
|
594
744
|
knownEdges.add(e);
|
|
595
|
-
return
|
|
745
|
+
return asEdge(e);
|
|
596
746
|
},
|
|
597
747
|
makeArcEdge(start, mid, end) {
|
|
598
748
|
// 方言消化:occt 吃 3 点;brepkit makeCircleArc3d 吃 (start,end,center,axis)。
|
|
599
749
|
const { center, axis } = circumcircle(start, mid, end);
|
|
600
750
|
const e = kernel.makeCircleArc3d(start.x, start.y, start.z, end.x, end.y, end.z, center.x, center.y, center.z, axis.x, axis.y, axis.z);
|
|
601
751
|
knownEdges.add(e);
|
|
602
|
-
return
|
|
752
|
+
return asEdge(e);
|
|
603
753
|
},
|
|
604
754
|
makeBezierEdge(controlPoints) {
|
|
605
755
|
// 方言消化:L1 吃控制点(Bezier);brepkit 原生 makeNurbsEdge 吃
|
|
@@ -617,34 +767,59 @@ export async function createBrepkitPrimitives() {
|
|
|
617
767
|
const last = controlPoints[n - 1];
|
|
618
768
|
const e = kernel.makeNurbsEdge(first.x, first.y, first.z, last.x, last.y, last.z, degree, knots, flattenPoints(controlPoints), weights);
|
|
619
769
|
knownEdges.add(e);
|
|
620
|
-
return
|
|
770
|
+
return asEdge(e);
|
|
771
|
+
},
|
|
772
|
+
makeBSplineEdge(poles, weights, knots, multiplicities, degree, periodic = false) {
|
|
773
|
+
// 方言消化:L1 吃 occt 形态 (poles, weights, knots, multiplicities, degree),
|
|
774
|
+
// brepkit makeNurbsEdge 吃 (start,end,degree, **展开后** knots, control_points, weights)。
|
|
775
|
+
// 两侧 knots 的表示不同:occt 给「去重值 + 多重度」两个平行数组,brepkit 要
|
|
776
|
+
// 逐项重复后的整条节点向量(与 makeBezierEdge 里手工铺 [0]×n+[1]×n 同一口径)。
|
|
777
|
+
const controlPoints = [];
|
|
778
|
+
for (let i = 0; i + 2 < poles.length; i += 3) {
|
|
779
|
+
controlPoints.push({ x: poles[i], y: poles[i + 1], z: poles[i + 2] });
|
|
780
|
+
}
|
|
781
|
+
const n = controlPoints.length;
|
|
782
|
+
if (n < 2)
|
|
783
|
+
fail('makeBSplineEdge: need at least 2 poles');
|
|
784
|
+
const expanded = [];
|
|
785
|
+
for (let i = 0; i < knots.length; i++) {
|
|
786
|
+
const rep = multiplicities[i] ?? 1;
|
|
787
|
+
for (let j = 0; j < rep; j++)
|
|
788
|
+
expanded.push(knots[i]);
|
|
789
|
+
}
|
|
790
|
+
const first = controlPoints[0];
|
|
791
|
+
const last = controlPoints[n - 1];
|
|
792
|
+
const e = kernel.makeNurbsEdge(first.x, first.y, first.z, last.x, last.y, last.z, degree, Float64Array.from(expanded), flattenPoints(controlPoints), weights.length === n ? Float64Array.from(weights) : new Float64Array(n).fill(1));
|
|
793
|
+
void periodic;
|
|
794
|
+
knownEdges.add(e);
|
|
795
|
+
return asEdge(e);
|
|
621
796
|
},
|
|
622
797
|
makeCircleEdge(center, normal, radius) {
|
|
623
798
|
const e = kernel.makeCircleEdge(center.x, center.y, center.z, normal.x, normal.y, normal.z, radius);
|
|
624
799
|
knownEdges.add(e);
|
|
625
|
-
return
|
|
800
|
+
return asEdge(e);
|
|
626
801
|
},
|
|
627
802
|
// ── 拓扑构造 ──
|
|
628
803
|
makeWire(edges) {
|
|
629
804
|
const w = kernel.makeWire(Int32Array.from(edges.map(asNum)), false);
|
|
630
805
|
knownWires.add(w);
|
|
631
|
-
return
|
|
806
|
+
return asWire(w);
|
|
632
807
|
},
|
|
633
808
|
makeFace(wire) {
|
|
634
809
|
const f = kernel.makeFaceFromWire(asNum(wire));
|
|
635
810
|
knownFaces.add(f);
|
|
636
|
-
return
|
|
811
|
+
return asFace(f);
|
|
637
812
|
},
|
|
638
813
|
makeCompound(shapesList) {
|
|
639
814
|
const kids = arr(shapesList.map(asNum));
|
|
640
815
|
// GOTCHA(2026-09-26):brepkit makeCompound 只接受 **solid** 句柄——把 face/wire
|
|
641
816
|
// (sectionByPlane 截面面组)塞进去即抛 "invalid solid handle"。非实体子句柄时
|
|
642
|
-
// 不调内核,改用高段虚拟句柄(
|
|
817
|
+
// 不调内核,改用高段虚拟句柄(0x20000000+,避开类型标签 bit26..28),仅靠 knownCompounds 表分发
|
|
643
818
|
// meshShape/wireframe/getSubShapes/getBoundingBox,不触达内核。
|
|
644
819
|
const hasNonSolid = kids.some((k) => knownFaces.has(k) || knownWires.has(k) || knownEdges.has(k) || knownCompounds.has(k));
|
|
645
820
|
if (hasNonSolid) {
|
|
646
821
|
virtualCompoundCounter++;
|
|
647
|
-
const v =
|
|
822
|
+
const v = 0x20000000 + virtualCompoundCounter;
|
|
648
823
|
knownCompounds.set(v, kids);
|
|
649
824
|
return asHandle(v);
|
|
650
825
|
}
|
|
@@ -657,25 +832,26 @@ export async function createBrepkitPrimitives() {
|
|
|
657
832
|
// 否则 profile(op) 带孔面送 meshShape 会落到 solid 路径崩溃。
|
|
658
833
|
const f = kernel.addHolesToFace(asNum(face), Int32Array.from(holeWires.map(asNum)));
|
|
659
834
|
knownFaces.add(f);
|
|
660
|
-
return
|
|
835
|
+
return asFace(f);
|
|
661
836
|
},
|
|
662
837
|
buildTriFace(a, b, c) {
|
|
663
838
|
const f = kernel.makePolygon(flattenPoints([a, b, c]));
|
|
664
839
|
knownFaces.add(f);
|
|
665
|
-
return
|
|
840
|
+
return asFace(f);
|
|
666
841
|
},
|
|
667
842
|
// ── 三角化(BREP→mesh 唯一出口) ──
|
|
668
843
|
meshShape(shape, options) {
|
|
669
844
|
const deflection = options?.linearDeflection ?? DEFAULT_LINEAR_DEFLECTION.as(mm);
|
|
670
845
|
const angular = options?.angularDeflection ?? 0.5;
|
|
671
846
|
const s = asNum(shape);
|
|
672
|
-
//
|
|
847
|
+
// 非实体句柄按类型静态分发(标签优先,见文件头 GOTCHA:brepkit 无 shape-type 分类 API)。
|
|
673
848
|
// 顺序:face → wire → edge → compound → solid。实体创建不入任何集合,天然落 solid 路径。
|
|
674
|
-
|
|
849
|
+
const kind = resolveKind(shape, s);
|
|
850
|
+
if (kind === KIND_FACE)
|
|
675
851
|
return faceMesh(s, deflection, angular);
|
|
676
|
-
if (
|
|
852
|
+
if (kind === KIND_WIRE)
|
|
677
853
|
return wireMesh(s, deflection);
|
|
678
|
-
if (
|
|
854
|
+
if (kind === KIND_EDGE)
|
|
679
855
|
return edgesToLineMesh([s], deflection);
|
|
680
856
|
const compoundChildren = knownCompounds.get(s);
|
|
681
857
|
if (compoundChildren)
|
|
@@ -690,11 +866,12 @@ export async function createBrepkitPrimitives() {
|
|
|
690
866
|
// 产物调 wireframe(...),传入非实体句柄即抛 "invalid solid handle"。按已知集合分发:
|
|
691
867
|
// face -> getFaceEdges;wire -> getWireEdges;edge -> [self];否则 solid 走 meshEdgesAll。
|
|
692
868
|
let edgeHandles = null;
|
|
693
|
-
|
|
869
|
+
const kind = resolveKind(shape, s);
|
|
870
|
+
if (kind === KIND_FACE)
|
|
694
871
|
edgeHandles = arr(kernel.getFaceEdges(s));
|
|
695
|
-
else if (
|
|
872
|
+
else if (kind === KIND_WIRE)
|
|
696
873
|
edgeHandles = arr(kernel.getWireEdges(s));
|
|
697
|
-
else if (
|
|
874
|
+
else if (kind === KIND_EDGE)
|
|
698
875
|
edgeHandles = [s];
|
|
699
876
|
else if (knownCompounds.has(s)) {
|
|
700
877
|
// compound(sectionByPlane 面组):逐子面收集边。
|
|
@@ -711,20 +888,22 @@ export async function createBrepkitPrimitives() {
|
|
|
711
888
|
if (edgeHandles) {
|
|
712
889
|
const nPts = Math.max(12, Math.round(4 / Math.max(d, 0.01)));
|
|
713
890
|
const positions = [];
|
|
891
|
+
// offsets 为**浮点单位**(L1 契约:edgeGroups = [pointStart_float, pointCount_float, hash])
|
|
714
892
|
const offsets = [0];
|
|
715
893
|
for (const e of edgeHandles) {
|
|
716
894
|
const pts = arr(kernel.tessellateEdge(e, nPts));
|
|
717
895
|
for (const p of pts)
|
|
718
896
|
positions.push(p);
|
|
719
|
-
offsets.push(positions.length
|
|
897
|
+
offsets.push(positions.length);
|
|
720
898
|
}
|
|
721
899
|
const edgeGroups = new Int32Array(edgeHandles.length * 3);
|
|
722
900
|
for (let i = 0; i < edgeHandles.length; i++) {
|
|
723
901
|
edgeGroups[i * 3] = offsets[i] ?? 0;
|
|
724
|
-
edgeGroups[i * 3 + 1] = (offsets[i + 1] ?? positions.length
|
|
725
|
-
|
|
902
|
+
edgeGroups[i * 3 + 1] = (offsets[i + 1] ?? positions.length) - (offsets[i] ?? 0);
|
|
903
|
+
// hash 必须与 hashCode(edge, BREP_HASH_BOUND) 同源,否则 topologyExt 查不到折线。
|
|
904
|
+
edgeGroups[i * 3 + 2] = edgeFingerprint(kernel, edgeHandles[i], BREP_HASH_BOUND);
|
|
726
905
|
}
|
|
727
|
-
return { points: new Float32Array(positions), edgeGroups, pointCount: positions.length
|
|
906
|
+
return { points: new Float32Array(positions), edgeGroups, pointCount: positions.length, edgeCount: edgeHandles.length };
|
|
728
907
|
}
|
|
729
908
|
// solid(或未登记句柄):走原 meshEdgesAll 路径。
|
|
730
909
|
// JsEdgeLines:edgeCount/offsets/positions 均为属性(offsets/positions 为 TypedArray,2026-09-19 实测)
|
|
@@ -732,13 +911,25 @@ export async function createBrepkitPrimitives() {
|
|
|
732
911
|
const edgeCount = Number(me.edgeCount);
|
|
733
912
|
const offsets = arr(me.offsets);
|
|
734
913
|
const positions = arr(me.positions);
|
|
914
|
+
// hash:meshEdgesAll 与 getSolidEdges 同序(同一次遍历),据此回填真实边指纹;
|
|
915
|
+
// 取不到(数量不符)时退化为序号——此时 topologyExt 查不到折线,曲面边走
|
|
916
|
+
// 曲线采样兜底(功能可用,只是丢掉内核线框数据)。
|
|
917
|
+
let solidEdges = null;
|
|
918
|
+
try {
|
|
919
|
+
const es = arr(kernel.getSolidEdges(s));
|
|
920
|
+
if (es.length === edgeCount)
|
|
921
|
+
solidEdges = es;
|
|
922
|
+
}
|
|
923
|
+
catch { /* 非实体 */ }
|
|
735
924
|
const edgeGroups = new Int32Array(edgeCount * 3);
|
|
736
925
|
for (let i = 0; i < edgeCount; i++) {
|
|
737
926
|
const start = offsets[i] ?? 0;
|
|
738
|
-
const count = (offsets[i + 1] ?? positions.length
|
|
927
|
+
const count = (offsets[i + 1] ?? positions.length) - start;
|
|
739
928
|
edgeGroups[i * 3] = start;
|
|
740
929
|
edgeGroups[i * 3 + 1] = count;
|
|
741
|
-
edgeGroups[i * 3 + 2] =
|
|
930
|
+
edgeGroups[i * 3 + 2] = solidEdges
|
|
931
|
+
? edgeFingerprint(kernel, solidEdges[i], BREP_HASH_BOUND)
|
|
932
|
+
: i;
|
|
742
933
|
}
|
|
743
934
|
return { points: new Float32Array(positions), edgeGroups, pointCount: positions.length, edgeCount };
|
|
744
935
|
},
|
|
@@ -751,49 +942,104 @@ export async function createBrepkitPrimitives() {
|
|
|
751
942
|
// edge/vertex 查询时按句柄是否在 knownFaces 里分发到 face 级或 solid 级 API。
|
|
752
943
|
getSubShapes(shape, type) {
|
|
753
944
|
const s = asNum(shape);
|
|
945
|
+
// 出口一律按 **type 参数**打类型标签(`type` 就是调用方声明的子形类型,是权威来源;
|
|
946
|
+
// 不用内核反查——brepkit 无法反查类型,见文件头句柄桥接 GOTCHA)。
|
|
947
|
+
const tag = (list) => {
|
|
948
|
+
switch (type) {
|
|
949
|
+
case 'face': return list.map(asFace);
|
|
950
|
+
case 'edge': return list.map(asEdge);
|
|
951
|
+
case 'vertex': return list.map(asVertex);
|
|
952
|
+
case 'wire': return list.map(asWire);
|
|
953
|
+
default: return list.map(asHandle);
|
|
954
|
+
}
|
|
955
|
+
};
|
|
956
|
+
// ── A. 有类型标签:按标签分发,**不登记 knownEdges** ──
|
|
957
|
+
// GOTCHA(2026-10-01 实测回归):历史分支里 `es.forEach(e => knownEdges.add(e))` 会把
|
|
958
|
+
// 面/线的边号写进 knownEdges,而 knownEdges 的 key 是**裸句柄号**、会与后来新建的
|
|
959
|
+
// solid 号相撞 → resolveKind 把实体判成边 → getBoundingBox 返回边的退化 bbox
|
|
960
|
+
// (实测 8 个 op 的 AABB 全错)。标签句柄自带类型,登记已无必要,故这里一律不登记。
|
|
961
|
+
const tagged = kindOf(shape);
|
|
962
|
+
if (tagged === KIND_FACE) {
|
|
963
|
+
if (type === 'face')
|
|
964
|
+
return [asFace(s)];
|
|
965
|
+
if (type === 'edge')
|
|
966
|
+
return tag(arr(kernel.getFaceEdges(s)));
|
|
967
|
+
if (type === 'vertex')
|
|
968
|
+
return tag(arr(kernel.getFaceVertices(s)));
|
|
969
|
+
return [];
|
|
970
|
+
}
|
|
971
|
+
if (tagged === KIND_WIRE) {
|
|
972
|
+
if (type === 'edge')
|
|
973
|
+
return tag(arr(kernel.getWireEdges(s)));
|
|
974
|
+
return [];
|
|
975
|
+
}
|
|
976
|
+
if (tagged === KIND_EDGE) {
|
|
977
|
+
// input is itself an edge (wire.ts smooth path: interpolatePoints returns edge)
|
|
978
|
+
if (type === 'edge')
|
|
979
|
+
return [asEdge(s)];
|
|
980
|
+
return [];
|
|
981
|
+
}
|
|
982
|
+
// ── B. 无标签:逐字沿用历史集合分发(含 knownEdges 登记),行为与加标签前一致 ──
|
|
754
983
|
// GOTCHA(2026-09-26 非实体句柄修复):buildTopologyFromMesh 会对**面产物**
|
|
755
984
|
// 调 getSubShapes(face,'face')。brepkit 的 getSolidFaces/getShellFaces 是 solid-only,
|
|
756
985
|
// 对面句柄一个抛 "invalid solid handle"、catch 里再抛 "invalid shell handle"——
|
|
757
|
-
//
|
|
758
|
-
// 输入本身就是 knownFaces 里的一张面时,'face' 返回 [s],edge/vertex 走 face 级 API。
|
|
986
|
+
// 两跳都不被捕获即崩溃。无标签时靠已知集合先分发。
|
|
759
987
|
if (knownFaces.has(s)) {
|
|
760
988
|
if (type === 'face')
|
|
761
|
-
return [
|
|
989
|
+
return [asFace(s)];
|
|
762
990
|
if (type === 'edge') {
|
|
763
991
|
const es = arr(kernel.getFaceEdges(s));
|
|
764
992
|
es.forEach((e) => knownEdges.add(e));
|
|
765
|
-
return es
|
|
993
|
+
return tag(es);
|
|
766
994
|
}
|
|
767
995
|
if (type === 'vertex')
|
|
768
|
-
return arr(kernel.getFaceVertices(s))
|
|
996
|
+
return tag(arr(kernel.getFaceVertices(s)));
|
|
769
997
|
return [];
|
|
770
998
|
}
|
|
771
999
|
if (knownWires.has(s)) {
|
|
772
1000
|
if (type === 'edge') {
|
|
773
1001
|
const es = arr(kernel.getWireEdges(s));
|
|
774
1002
|
es.forEach((e) => knownEdges.add(e));
|
|
775
|
-
return es
|
|
1003
|
+
return tag(es);
|
|
776
1004
|
}
|
|
777
1005
|
return [];
|
|
778
1006
|
}
|
|
779
1007
|
if (knownEdges.has(s)) {
|
|
780
|
-
// input is itself an edge (wire.ts smooth path: interpolatePoints returns edge)
|
|
781
1008
|
if (type === 'edge')
|
|
782
|
-
return [
|
|
1009
|
+
return [asEdge(s)];
|
|
783
1010
|
return [];
|
|
784
1011
|
}
|
|
785
1012
|
const compKids = knownCompounds.get(s);
|
|
786
1013
|
if (compKids) {
|
|
787
1014
|
// compound(sectionByPlane 面组 / makeCompound 多实体 / importStep 多实体):
|
|
788
|
-
// 'face' 返回子面,'solid'
|
|
1015
|
+
// 'face' 返回子面,'solid' 返回子实体,'edge' 返回各子句柄的边,其余空。
|
|
789
1016
|
if (type === 'face')
|
|
790
|
-
return compKids.filter((k) => knownFaces.has(k))
|
|
1017
|
+
return tag(compKids.filter((k) => knownFaces.has(k)));
|
|
791
1018
|
if (type === 'solid')
|
|
792
|
-
return compKids.filter((k) => !knownFaces.has(k) && !knownWires.has(k) && !knownEdges.has(k))
|
|
1019
|
+
return tag(compKids.filter((k) => !knownFaces.has(k) && !knownWires.has(k) && !knownEdges.has(k)));
|
|
1020
|
+
if (type === 'edge') {
|
|
1021
|
+
// 2026-10-02 补:此前 compound 的边查询落到 `return []`,会让归一化后的
|
|
1022
|
+
// getLength(compound) 静默变 0。按子句柄的已知类型分发,与 occt 的
|
|
1023
|
+
// getSubShapes(compound,'edge')(返回全部子边)对齐。
|
|
1024
|
+
const out = [];
|
|
1025
|
+
for (const kid of compKids) {
|
|
1026
|
+
if (knownFaces.has(kid))
|
|
1027
|
+
out.push(...arr(kernel.getFaceEdges(kid)));
|
|
1028
|
+
else if (knownWires.has(kid))
|
|
1029
|
+
out.push(...arr(kernel.getWireEdges(kid)));
|
|
1030
|
+
else if (knownEdges.has(kid))
|
|
1031
|
+
out.push(kid);
|
|
1032
|
+
else
|
|
1033
|
+
out.push(...arr(kernel.getSolidEdges(kid)));
|
|
1034
|
+
}
|
|
1035
|
+
return tag(out);
|
|
1036
|
+
}
|
|
793
1037
|
return [];
|
|
794
1038
|
}
|
|
795
1039
|
let list;
|
|
796
|
-
|
|
1040
|
+
// 实体句柄(knownSolids)永远不是 face-like——`derivedFaces` 只装「枚举出来的面号」,
|
|
1041
|
+
// 与 solid 号共用一个裸数字空间,不排除会造成误判(见 knownSolids 注释)。
|
|
1042
|
+
const isFaceLike = knownFaces.has(s) || (derivedFaces.has(s) && !knownSolids.has(s));
|
|
797
1043
|
if (type === 'face') {
|
|
798
1044
|
// 输入可能是 solid 或 shell。枚举到的子面登记到 derivedFaces(不进 knownFaces,
|
|
799
1045
|
// 避免与 solid 句柄撞号——见 derivedFaces 注释)。
|
|
@@ -831,18 +1077,19 @@ export async function createBrepkitPrimitives() {
|
|
|
831
1077
|
else {
|
|
832
1078
|
fail(`getSubShapes(${type}): unsupported sub-shape type`);
|
|
833
1079
|
}
|
|
834
|
-
return list
|
|
1080
|
+
return tag(list);
|
|
835
1081
|
},
|
|
836
1082
|
subShapeHashes(shape, type, hashUpperBound) {
|
|
837
1083
|
if (type !== 'face')
|
|
838
1084
|
fail(`subShapeHashes(${type}): only 'face' is supported by brepkit`);
|
|
839
1085
|
const s = asNum(shape);
|
|
840
1086
|
// GOTCHA:buildTopologyFromMesh 会对面产物调 subShapeHashes(face,'face');
|
|
841
|
-
// getSolidFaces 是 solid-only
|
|
842
|
-
|
|
1087
|
+
// getSolidFaces 是 solid-only,对面句柄崩溃。输入本身是面时,哈希即其自身指纹。
|
|
1088
|
+
const kind = resolveKind(shape, s);
|
|
1089
|
+
if (kind === KIND_FACE)
|
|
843
1090
|
return [faceFingerprint(kernel, s, hashUpperBound)];
|
|
844
1091
|
// wire/edge 无面;compound(sectionByPlane 面组)的子句柄即面。
|
|
845
|
-
if (
|
|
1092
|
+
if (kind === KIND_WIRE || kind === KIND_EDGE)
|
|
846
1093
|
return [];
|
|
847
1094
|
const compKids = knownCompounds.get(s);
|
|
848
1095
|
if (compKids) {
|
|
@@ -858,9 +1105,25 @@ export async function createBrepkitPrimitives() {
|
|
|
858
1105
|
return hashes;
|
|
859
1106
|
},
|
|
860
1107
|
hashCode(shape, upperBound) {
|
|
861
|
-
|
|
1108
|
+
// 类型由句柄标签决定(见文件头句柄桥接 GOTCHA):brepkit 无法反查句柄类型,
|
|
1109
|
+
// 而面指纹与边指纹必须落在**互不相交**的取值域,否则 edgeGroups 的 hash 会
|
|
1110
|
+
// 命中面的指纹(实测:box 的 edge 0..5 句柄号与 face 0..5 相同)。
|
|
1111
|
+
// 生产端(faceMesh/solidMesh/compoundMesh → faceFingerprint;wireframe →
|
|
1112
|
+
// edgeFingerprint)与消费端(本函数)用同一组函数、同一个上界,查表才命中。
|
|
1113
|
+
const raw = asNum(shape);
|
|
1114
|
+
return kindOf(shape) === KIND_EDGE
|
|
1115
|
+
? edgeFingerprint(kernel, raw, upperBound)
|
|
1116
|
+
: faceFingerprint(kernel, raw, upperBound);
|
|
1117
|
+
},
|
|
1118
|
+
isSame(a, b) {
|
|
1119
|
+
// 裸句柄号相同还不够:brepkit 的 face 3 与 edge 3 是**两个不同的形**。
|
|
1120
|
+
// 两侧都带标签时必须同类型;任一侧无标签(历史调用方)时退回纯数字比较,
|
|
1121
|
+
// 保证加标签不改变既有行为。
|
|
1122
|
+
if (asNum(a) !== asNum(b))
|
|
1123
|
+
return false;
|
|
1124
|
+
const ka = kindOf(a), kb = kindOf(b);
|
|
1125
|
+
return ka === kb || ka === KIND_SOLID || kb === KIND_SOLID;
|
|
862
1126
|
},
|
|
863
|
-
isSame(a, b) { return asNum(a) === asNum(b); },
|
|
864
1127
|
isSolid(shape) {
|
|
865
1128
|
try {
|
|
866
1129
|
return arr(kernel.getSolidFaces(asNum(shape))).length > 0;
|
|
@@ -892,10 +1155,10 @@ export async function createBrepkitPrimitives() {
|
|
|
892
1155
|
return kernel.edgeToFaceMap(asNum(shape));
|
|
893
1156
|
},
|
|
894
1157
|
adjacentFaces(shape, face) {
|
|
895
|
-
return arr(kernel.adjacentFaces(asNum(shape), asNum(face))).map(
|
|
1158
|
+
return arr(kernel.adjacentFaces(asNum(shape), asNum(face))).map(asFace);
|
|
896
1159
|
},
|
|
897
1160
|
sharedEdges(a, b) {
|
|
898
|
-
return arr(kernel.sharedEdges(asNum(a), asNum(b))).map(
|
|
1161
|
+
return arr(kernel.sharedEdges(asNum(a), asNum(b))).map(asEdge);
|
|
899
1162
|
},
|
|
900
1163
|
// ── 几何求值 ──
|
|
901
1164
|
curveType(edge) { return String(kernel.getEdgeCurveType(asNum(edge))); },
|
|
@@ -968,21 +1231,42 @@ export async function createBrepkitPrimitives() {
|
|
|
968
1231
|
getNurbsCurveData(edge) {
|
|
969
1232
|
try {
|
|
970
1233
|
const p = JSON.parse(kernel.getNurbsCurveData(asNum(edge)));
|
|
971
|
-
if (p && typeof p.degree === 'number')
|
|
972
|
-
return {
|
|
1234
|
+
if (p && typeof p.degree === 'number') {
|
|
1235
|
+
return {
|
|
1236
|
+
degree: p.degree,
|
|
1237
|
+
periodic: !!p.periodic,
|
|
1238
|
+
rational: !!p.rational,
|
|
1239
|
+
knots: (p.knots ?? []).map(Number),
|
|
1240
|
+
multiplicities: (p.multiplicities ?? []).map(Number),
|
|
1241
|
+
poles: (p.poles ?? []).map(Number),
|
|
1242
|
+
weights: (p.weights ?? []).map(Number),
|
|
1243
|
+
};
|
|
1244
|
+
}
|
|
973
1245
|
}
|
|
974
1246
|
catch { /* 非 Nurbs 边 */ }
|
|
975
1247
|
return null;
|
|
976
1248
|
},
|
|
1249
|
+
curveSplit(edge, param) {
|
|
1250
|
+
// brepkit 原生返回 Uint32Array 两元素(occt 返回 [ShapeHandle, ShapeHandle])——
|
|
1251
|
+
// 适配器统一为二元组。两个碎片都必须登记进 knownEdges,否则下游 meshShape 分发不到。
|
|
1252
|
+
const parts = kernel.curveSplit(asNum(edge), param);
|
|
1253
|
+
if (parts.length !== 2)
|
|
1254
|
+
fail(`curveSplit: expected 2 edges, got ${parts.length}`);
|
|
1255
|
+
const a = parts[0];
|
|
1256
|
+
const b = parts[1];
|
|
1257
|
+
knownEdges.add(a);
|
|
1258
|
+
knownEdges.add(b);
|
|
1259
|
+
return [asEdge(a), asEdge(b)];
|
|
1260
|
+
},
|
|
977
1261
|
interpolatePoints(points, degree) {
|
|
978
1262
|
// GOTCHA:interpolatePoints 返回 **edge** 句柄(不是 wire)——wire.ts smooth 路径把它
|
|
979
1263
|
// 直接当 wire 送 solidToShape。登记进 knownEdges,meshShape 才能走 tessellateEdge 路径。
|
|
980
1264
|
const e = kernel.interpolatePoints(flattenPoints(points), degree);
|
|
981
1265
|
knownEdges.add(e);
|
|
982
|
-
return
|
|
1266
|
+
return asEdge(e);
|
|
983
1267
|
},
|
|
984
1268
|
defeature(shape, faces) {
|
|
985
|
-
return asHandle(kernel.defeature(asNum(shape), Uint32Array.from(faces.map(asNum))));
|
|
1269
|
+
return asHandle(markSolid(kernel.defeature(asNum(shape), Uint32Array.from(faces.map(asNum)))));
|
|
986
1270
|
},
|
|
987
1271
|
draft(shape, faces, pull, neutral, angleDeg) {
|
|
988
1272
|
return asHandle(kernel.draft(asNum(shape), Uint32Array.from(faces.map(asNum)), pull.x, pull.y, pull.z, neutral.x, neutral.y, neutral.z, angleDeg));
|
|
@@ -991,10 +1275,10 @@ export async function createBrepkitPrimitives() {
|
|
|
991
1275
|
// removeHolesFromFace 返回**新 face 句柄**(去掉内孔的同曲面 face),必须登记进 knownFaces。
|
|
992
1276
|
const f = kernel.removeHolesFromFace(asNum(face));
|
|
993
1277
|
knownFaces.add(f);
|
|
994
|
-
return
|
|
1278
|
+
return asFace(f);
|
|
995
1279
|
},
|
|
996
1280
|
reverseShape(shape) {
|
|
997
|
-
return
|
|
1281
|
+
return withKind(kindOf(shape), kernel.reverseShape(asNum(shape)));
|
|
998
1282
|
},
|
|
999
1283
|
projectEdges(shape, origin, direction, xAxis, hiddenLines, deflection) {
|
|
1000
1284
|
// brepkit 返回 JSON 字符串 {"visible":[[x,y,…]],"hidden":[[…]]};L1 契约是 unknown。
|
|
@@ -1054,11 +1338,12 @@ export async function createBrepkitPrimitives() {
|
|
|
1054
1338
|
}
|
|
1055
1339
|
// GOTCHA:kernel.boundingBox 是 solid-only。face/wire/edge 句柄必须走 tessellation 采样,
|
|
1056
1340
|
// 否则 measure() 对 wire/profile 调 getBoundingBox 即崩 "invalid solid handle"。
|
|
1057
|
-
|
|
1341
|
+
const kind = resolveKind(shape, s);
|
|
1342
|
+
if (kind === KIND_FACE)
|
|
1058
1343
|
return bboxFromPoints(arr(kernel.tessellateFace(s, 0.1, 1).positions));
|
|
1059
|
-
if (
|
|
1344
|
+
if (kind === KIND_WIRE)
|
|
1060
1345
|
return bboxFromPoints(arr(kernel.getWireEdges(s)).flatMap((e) => arr(kernel.tessellateEdge(e, 16))));
|
|
1061
|
-
if (
|
|
1346
|
+
if (kind === KIND_EDGE)
|
|
1062
1347
|
return bboxFromPoints(arr(kernel.tessellateEdge(s, 16)));
|
|
1063
1348
|
return solidBbox(s);
|
|
1064
1349
|
},
|
|
@@ -1072,17 +1357,15 @@ export async function createBrepkitPrimitives() {
|
|
|
1072
1357
|
return Number(kernel.surfaceArea(asNum(shape), 0.05));
|
|
1073
1358
|
},
|
|
1074
1359
|
getLength(shape) {
|
|
1075
|
-
//
|
|
1076
|
-
//
|
|
1077
|
-
// 对 wire
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
return Number(kernel.wireLength(s));
|
|
1085
|
-
}
|
|
1360
|
+
// 唯一 edge 弧长之和(与 occt 适配器同口径,D5)。
|
|
1361
|
+
// 旧实现用 `try { getEdgeCurveType } catch { wireLength }` 判别入参差异,但
|
|
1362
|
+
// getEdgeCurveType 对 solid / face / wire **也不抛错**,于是统一走 edgeLength,
|
|
1363
|
+
// 返回「首条边」长度——值随构建历史漂移(盒 20 vs 10;两边的 wire 真长 15 却给 20),
|
|
1364
|
+
// 且与 occt 的 Σ 面周长(280)不同口径。改为按 topo 去重枚举边后求和。
|
|
1365
|
+
let total = 0;
|
|
1366
|
+
for (const e of api.getSubShapes(shape, 'edge'))
|
|
1367
|
+
total += api.curveLength(e);
|
|
1368
|
+
return total;
|
|
1086
1369
|
},
|
|
1087
1370
|
// ── 校验与修复 ──
|
|
1088
1371
|
// ⚠️ brepkit 的修复类内核函数全部是「**原地修改入参实体 + 返回修复计数**」,不是返回新句柄:
|
|
@@ -1113,12 +1396,12 @@ export async function createBrepkitPrimitives() {
|
|
|
1113
1396
|
return asHandle(c);
|
|
1114
1397
|
},
|
|
1115
1398
|
fixFaceOrientations(shape) {
|
|
1116
|
-
const c = kernel.copySolid(asNum(shape));
|
|
1399
|
+
const c = markSolid(kernel.copySolid(asNum(shape)));
|
|
1117
1400
|
kernel.fixFaceOrientations(c);
|
|
1118
1401
|
return asHandle(c);
|
|
1119
1402
|
},
|
|
1120
1403
|
removeDegenerateEdges(shape, tolerance) {
|
|
1121
|
-
const c = kernel.copySolid(asNum(shape));
|
|
1404
|
+
const c = markSolid(kernel.copySolid(asNum(shape)));
|
|
1122
1405
|
kernel.removeDegenerateEdges(c, tolerance ?? 1e-6);
|
|
1123
1406
|
return asHandle(c);
|
|
1124
1407
|
},
|
|
@@ -1130,7 +1413,10 @@ export async function createBrepkitPrimitives() {
|
|
|
1130
1413
|
const solids = arr(kernel.importStep(bytes));
|
|
1131
1414
|
if (solids.length === 0)
|
|
1132
1415
|
fail('importStep: kernel returned no solid');
|
|
1133
|
-
|
|
1416
|
+
const c = solids.length === 1 ? solids[0] : kernel.makeCompound(Uint32Array.from(solids));
|
|
1417
|
+
if (solids.length > 1)
|
|
1418
|
+
knownCompounds.set(c, solids);
|
|
1419
|
+
return asHandle(markSolid(c));
|
|
1134
1420
|
},
|
|
1135
1421
|
exportStep(shape) {
|
|
1136
1422
|
// brepkit exportStep 返回 UTF-8 字节(Uint8Array),需解码为 STEP 文本(2026-09-19 实测)
|
|
@@ -1139,14 +1425,39 @@ export async function createBrepkitPrimitives() {
|
|
|
1139
1425
|
},
|
|
1140
1426
|
importStl(data) {
|
|
1141
1427
|
const bytes = typeof data === 'string' ? new TextEncoder().encode(data) : new Uint8Array(data);
|
|
1142
|
-
return asHandle(kernel.importStl(bytes));
|
|
1428
|
+
return asHandle(markSolid(kernel.importStl(bytes)));
|
|
1143
1429
|
},
|
|
1144
1430
|
fromBREP(data) {
|
|
1145
1431
|
// ⚠️ brepkit fromBREP 吃字符串(STEP 文本或 toBREP/toBrepJson 输出,内核自动判别),
|
|
1146
1432
|
// 与 serializeSolid/deserializeSolid 的**二进制 arena** 是两套机制。
|
|
1147
1433
|
// 旧实现误用 `deserializeSolid(atob(data))`:base64 解码破坏了 STEP 文本 → 往返必失败
|
|
1148
1434
|
// (2026-09-25 实证:fromBREP(STEP)、fromBREP(toBREP)、fromBREP(toBrepJson) 均成功)。
|
|
1149
|
-
return asHandle(kernel.fromBREP(data));
|
|
1435
|
+
return asHandle(markSolid(kernel.fromBREP(data)));
|
|
1436
|
+
},
|
|
1437
|
+
// ── 网格实体原语(方案 2026-10-01 §3.3;内核私有,不在 L1 契约面) ──
|
|
1438
|
+
// 规范构造顺序**不可交换**:importMesh → weld → unify。
|
|
1439
|
+
// 实测(brepkit-kernel/mesh-solid-topology.test.ts):先 unify 后 weld 会把实体做坏
|
|
1440
|
+
// (体积归零、validate 非 0)。本对象只暴露原语,顺序由 `normalizeMeshSolid` 驱动。
|
|
1441
|
+
meshSolid: {
|
|
1442
|
+
importMesh(positions, indices) {
|
|
1443
|
+
// 方言:importIndexedMesh 吃 **Float64Array**(坐标)+ **Uint32Array**(索引),
|
|
1444
|
+
// 返回裸 solid 号。逐三角形建面、顶点按坐标焊接、边不共享(不是真流形)。
|
|
1445
|
+
const coords = new Float64Array(positions.length);
|
|
1446
|
+
for (let i = 0; i < positions.length; i++)
|
|
1447
|
+
coords[i] = positions[i];
|
|
1448
|
+
return asHandle(markSolid(kernel.importIndexedMesh(coords, indices)));
|
|
1449
|
+
},
|
|
1450
|
+
weld(faces, tolerance) {
|
|
1451
|
+
// weldShellsAndFaces 吃**裸面号数组**(Uint32Array),返回新 solid 号;
|
|
1452
|
+
// 把重复边缝成共享边 → 真流形(实测 10mm 立方体 36 边 → 18 边、validate 0)。
|
|
1453
|
+
return asHandle(markSolid(kernel.weldShellsAndFaces(Uint32Array.from(faces.map((f) => asNum(f))), tolerance)));
|
|
1454
|
+
},
|
|
1455
|
+
unify(solid) {
|
|
1456
|
+
// GOTCHA:unifyFaces 是**原地修改**入参实体,返回值是**被合并掉的面数**
|
|
1457
|
+
// (不是新句柄)。写成 `const s = unify(...)` 会拿到一个落在合法句柄区间的
|
|
1458
|
+
// 数字,后续全部查询打在一个无关实体上且不报错。
|
|
1459
|
+
return Number(kernel.unifyFaces(asNum(solid)));
|
|
1460
|
+
},
|
|
1150
1461
|
},
|
|
1151
1462
|
// ── 面演化(L1 三员 + filletWithHistory,双方都有对齐实现) ──
|
|
1152
1463
|
cutWithHistory(a, b, inputFaceHashes, hashUpperBound) {
|
|
@@ -1162,6 +1473,8 @@ export async function createBrepkitPrimitives() {
|
|
|
1162
1473
|
return mapEvolution(kernel, raw, JSON.parse(raw).solid, inputFaceHashes, hashUpperBound);
|
|
1163
1474
|
},
|
|
1164
1475
|
};
|
|
1476
|
+
memoizedKernel = kernel;
|
|
1477
|
+
memoizedPrimitives = api;
|
|
1165
1478
|
return api;
|
|
1166
1479
|
}
|
|
1167
1480
|
// ── 工具 ──
|
|
@@ -1206,6 +1519,9 @@ function vec3Of(p) {
|
|
|
1206
1519
|
}
|
|
1207
1520
|
/** 已初始化的 brepkit 内核单例(createBrepkitPrimitives 时赋值)。 */
|
|
1208
1521
|
let liveKernel = null;
|
|
1522
|
+
/** 已构建的 L1 契约面对象(按内核实例 memo;见 createBrepkitPrimitives 的 GOTCHA)。 */
|
|
1523
|
+
let memoizedPrimitives = null;
|
|
1524
|
+
let memoizedKernel = null;
|
|
1209
1525
|
/**
|
|
1210
1526
|
* 原生 brepkit 内核面(D3):平台特定代码访问 brepkit 独有能力的唯一入口
|
|
1211
1527
|
* (chamfer2d/chamferV2/filletV2/sketch* 族、serializeSolid、meshBoolean 等)。
|
|
@@ -1221,7 +1537,14 @@ export function getBrepkitKernel() {
|
|
|
1221
1537
|
}
|
|
1222
1538
|
return liveKernel;
|
|
1223
1539
|
}
|
|
1224
|
-
/**
|
|
1540
|
+
/**
|
|
1541
|
+
* 释放内核单例(测试收尾用;宿主常驻不需调用)。
|
|
1542
|
+
*
|
|
1543
|
+
* GOTCHA(2026-10-01 修复):旧实现只 `free()` 内核、**不重置** brepkitWasm.ts 里
|
|
1544
|
+
* 缓存的 `initPromise`,也不丢 memo 化的原语对象 → 第二次 `createBrepkitPrimitives()`
|
|
1545
|
+
* 拿到**已释放**的内核,随后一切内核调用报 `null pointer passed to rust`
|
|
1546
|
+
* (实测:`BrepKernel.makeBox`)。现在三样一起清:内核、initPromise、memo 原语。
|
|
1547
|
+
*/
|
|
1225
1548
|
export function disposeBrepkit() {
|
|
1226
1549
|
try {
|
|
1227
1550
|
if (liveKernel?.free)
|
|
@@ -1229,5 +1552,8 @@ export function disposeBrepkit() {
|
|
|
1229
1552
|
}
|
|
1230
1553
|
catch { /* 已释放 */ }
|
|
1231
1554
|
liveKernel = null;
|
|
1555
|
+
memoizedPrimitives = null;
|
|
1556
|
+
memoizedKernel = null;
|
|
1557
|
+
resetBrepkitWasm();
|
|
1232
1558
|
}
|
|
1233
1559
|
//# sourceMappingURL=brepkitKernel.js.map
|