@faicad/faijs 0.32.3 → 0.33.1

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.
Files changed (195) hide show
  1. package/dist/api/api-namespace.js +3 -3
  2. package/dist/api/api-namespace.js.map +1 -1
  3. package/dist/api/assembly/index.d.ts +1 -0
  4. package/dist/api/assembly/index.d.ts.map +1 -1
  5. package/dist/api/assembly/index.js +1 -0
  6. package/dist/api/assembly/index.js.map +1 -1
  7. package/dist/api/assembly/lower.d.ts.map +1 -1
  8. package/dist/api/assembly/lower.js +7 -0
  9. package/dist/api/assembly/lower.js.map +1 -1
  10. package/dist/api/assembly/normalize.d.ts.map +1 -1
  11. package/dist/api/assembly/normalize.js +2 -1
  12. package/dist/api/assembly/normalize.js.map +1 -1
  13. package/dist/api/assembly/solve-tree.d.ts +46 -0
  14. package/dist/api/assembly/solve-tree.d.ts.map +1 -0
  15. package/dist/api/assembly/solve-tree.js +135 -0
  16. package/dist/api/assembly/solve-tree.js.map +1 -0
  17. package/dist/api/assembly/solve.d.ts +7 -0
  18. package/dist/api/assembly/solve.d.ts.map +1 -1
  19. package/dist/api/assembly/solve.js.map +1 -1
  20. package/dist/api/assembly/solvers/assembly-tree.d.ts +4 -0
  21. package/dist/api/assembly/solvers/assembly-tree.d.ts.map +1 -1
  22. package/dist/api/assembly/solvers/assembly-tree.js +1 -0
  23. package/dist/api/assembly/solvers/assembly-tree.js.map +1 -1
  24. package/dist/api/assembly/solvers/global-solver.d.ts.map +1 -1
  25. package/dist/api/assembly/solvers/global-solver.js +210 -3
  26. package/dist/api/assembly/solvers/global-solver.js.map +1 -1
  27. package/dist/api/assembly/solvers/types.d.ts +8 -0
  28. package/dist/api/assembly/solvers/types.d.ts.map +1 -1
  29. package/dist/api/assembly/solvers/types.js.map +1 -1
  30. package/dist/api/assembly/types.d.ts +32 -1
  31. package/dist/api/assembly/types.d.ts.map +1 -1
  32. package/dist/api/assembly/types.js.map +1 -1
  33. package/dist/api/assembly/validate.d.ts +2 -2
  34. package/dist/api/assembly/validate.d.ts.map +1 -1
  35. package/dist/api/assembly/validate.js +24 -2
  36. package/dist/api/assembly/validate.js.map +1 -1
  37. package/dist/api/cadquery-selectors/edge.js +1 -1
  38. package/dist/api/cadquery-selectors/edge.js.map +1 -1
  39. package/dist/api/cadquery-selectors/entity.d.ts +29 -20
  40. package/dist/api/cadquery-selectors/entity.d.ts.map +1 -1
  41. package/dist/api/cadquery-selectors/entity.js +26 -20
  42. package/dist/api/cadquery-selectors/entity.js.map +1 -1
  43. package/dist/api/cadquery-selectors/face.d.ts +4 -2
  44. package/dist/api/cadquery-selectors/face.d.ts.map +1 -1
  45. package/dist/api/cadquery-selectors/face.js +8 -7
  46. package/dist/api/cadquery-selectors/face.js.map +1 -1
  47. package/dist/api/cadquery-selectors/resolve.d.ts +7 -6
  48. package/dist/api/cadquery-selectors/resolve.d.ts.map +1 -1
  49. package/dist/api/cadquery-selectors/resolve.js +13 -11
  50. package/dist/api/cadquery-selectors/resolve.js.map +1 -1
  51. package/dist/api/chamfer.js +1 -1
  52. package/dist/api/chamfer.js.map +1 -1
  53. package/dist/api/draft.js +1 -1
  54. package/dist/api/draft.js.map +1 -1
  55. package/dist/api/edge-ref.js +2 -2
  56. package/dist/api/edge-ref.js.map +1 -1
  57. package/dist/api/engrave.js +1 -1
  58. package/dist/api/engrave.js.map +1 -1
  59. package/dist/api/export-3mf.js +1 -1
  60. package/dist/api/export-3mf.js.map +1 -1
  61. package/dist/api/export-brep.js +1 -1
  62. package/dist/api/export-brep.js.map +1 -1
  63. package/dist/api/export-step.d.ts +12 -13
  64. package/dist/api/export-step.d.ts.map +1 -1
  65. package/dist/api/export-step.js +19 -17
  66. package/dist/api/export-step.js.map +1 -1
  67. package/dist/api/extrude.js +3 -3
  68. package/dist/api/extrude.js.map +1 -1
  69. package/dist/api/face-ref.js +2 -2
  70. package/dist/api/face-ref.js.map +1 -1
  71. package/dist/api/feature-repair.js +2 -2
  72. package/dist/api/feature-repair.js.map +1 -1
  73. package/dist/api/fillet-variable.js +1 -1
  74. package/dist/api/fillet-variable.js.map +1 -1
  75. package/dist/api/fillet.js +1 -1
  76. package/dist/api/fillet.js.map +1 -1
  77. package/dist/api/geom.js +1 -1
  78. package/dist/api/geom.js.map +1 -1
  79. package/dist/api/import-step.d.ts.map +1 -1
  80. package/dist/api/import-step.js +4 -2
  81. package/dist/api/import-step.js.map +1 -1
  82. package/dist/api/pattern.js +1 -1
  83. package/dist/api/pattern.js.map +1 -1
  84. package/dist/api/place.js +1 -1
  85. package/dist/api/place.js.map +1 -1
  86. package/dist/api/punch-hole.js +1 -1
  87. package/dist/api/punch-hole.js.map +1 -1
  88. package/dist/api/replicate.js +1 -1
  89. package/dist/api/replicate.js.map +1 -1
  90. package/dist/api/revolve.js +1 -1
  91. package/dist/api/revolve.js.map +1 -1
  92. package/dist/api/section-by-plane.js +1 -1
  93. package/dist/api/section-by-plane.js.map +1 -1
  94. package/dist/api/shell.js +1 -1
  95. package/dist/api/shell.js.map +1 -1
  96. package/dist/api/sketch-on-face.js +1 -1
  97. package/dist/api/sketch-on-face.js.map +1 -1
  98. package/dist/api/split-by-plane.js +1 -1
  99. package/dist/api/split-by-plane.js.map +1 -1
  100. package/dist/api/split.js +1 -1
  101. package/dist/api/split.js.map +1 -1
  102. package/dist/api/thicken.js +1 -1
  103. package/dist/api/thicken.js.map +1 -1
  104. package/dist/api/topo-resolve.js +4 -4
  105. package/dist/api/topo-resolve.js.map +1 -1
  106. package/dist/api/transform.js +1 -1
  107. package/dist/api/transform.js.map +1 -1
  108. package/dist/api/view/view-projection.d.ts +8 -0
  109. package/dist/api/view/view-projection.d.ts.map +1 -1
  110. package/dist/api/view/view-projection.js +73 -2
  111. package/dist/api/view/view-projection.js.map +1 -1
  112. package/dist/boolean/cross-section.d.ts.map +1 -1
  113. package/dist/boolean/cross-section.js +3 -1
  114. package/dist/boolean/cross-section.js.map +1 -1
  115. package/dist/brep/brep-ops.d.ts +26 -0
  116. package/dist/brep/brep-ops.d.ts.map +1 -1
  117. package/dist/brep/brep-ops.js +45 -0
  118. package/dist/brep/brep-ops.js.map +1 -1
  119. package/dist/brep/brep-topology.js +1 -1
  120. package/dist/brep/brep-topology.js.map +1 -1
  121. package/dist/brep/engine/adapters/brep-mock.d.ts.map +1 -1
  122. package/dist/brep/engine/adapters/brep-mock.js +2 -0
  123. package/dist/brep/engine/adapters/brep-mock.js.map +1 -1
  124. package/dist/brep/engine/primitives.d.ts +17 -0
  125. package/dist/brep/engine/primitives.d.ts.map +1 -1
  126. package/dist/brep/engine/primitives.js.map +1 -1
  127. package/dist/brep/export/export-model.d.ts.map +1 -1
  128. package/dist/brep/export/export-model.js +36 -11
  129. package/dist/brep/export/export-model.js.map +1 -1
  130. package/dist/brep/export/step-flat.d.ts +35 -0
  131. package/dist/brep/export/step-flat.d.ts.map +1 -0
  132. package/dist/brep/export/step-flat.js +94 -0
  133. package/dist/brep/export/step-flat.js.map +1 -0
  134. package/dist/brep/export/step.d.ts.map +1 -1
  135. package/dist/brep/export/step.js +42 -21
  136. package/dist/brep/export/step.js.map +1 -1
  137. package/dist/brep/handle-bridge.d.ts +4 -4
  138. package/dist/brep/handle-bridge.js +4 -4
  139. package/dist/brep/handle-bridge.js.map +1 -1
  140. package/dist/brep/svg/svg-to-solid.d.ts +3 -17
  141. package/dist/brep/svg/svg-to-solid.d.ts.map +1 -1
  142. package/dist/brep/svg/svg-to-solid.js +16 -317
  143. package/dist/brep/svg/svg-to-solid.js.map +1 -1
  144. package/dist/brepkit-kernel/brepkitKernel.d.ts.map +1 -1
  145. package/dist/brepkit-kernel/brepkitKernel.js +10 -0
  146. package/dist/brepkit-kernel/brepkitKernel.js.map +1 -1
  147. package/dist/brepkit-kernel/brepkitWasm.d.ts +1 -1
  148. package/dist/brepkit-kernel/brepkitWasm.d.ts.map +1 -1
  149. package/dist/brepkit-kernel/brepkitWasm.js +7 -6
  150. package/dist/brepkit-kernel/brepkitWasm.js.map +1 -1
  151. package/dist/brepkit-kernel/multi-version-test.d.ts +7 -7
  152. package/dist/brepkit-kernel/multi-version-test.d.ts.map +1 -1
  153. package/dist/brepkit-kernel/multi-version-test.js +10 -10
  154. package/dist/brepkit-kernel/multi-version-test.js.map +1 -1
  155. package/dist/cad-runtime/direct-executor.js +2 -2
  156. package/dist/cad-runtime/direct-executor.js.map +1 -1
  157. package/dist/cad-runtime/runtime.js +5 -5
  158. package/dist/cad-runtime/runtime.js.map +1 -1
  159. package/dist/geometry2d/curve2d.js +42 -1
  160. package/dist/geometry2d/curve2d.js.map +1 -1
  161. package/dist/math3d/Box3.js.map +1 -1
  162. package/dist/math3d/Euler.js.map +1 -1
  163. package/dist/math3d/Mat4.js.map +1 -1
  164. package/dist/math3d/Plane.js.map +1 -1
  165. package/dist/math3d/Quat.js.map +1 -1
  166. package/dist/math3d/Vec2.js.map +1 -1
  167. package/dist/math3d/Vec3.js.map +1 -1
  168. package/dist/math3d/index.js.map +1 -1
  169. package/dist/mesh/meshdata/contour.d.ts +34 -0
  170. package/dist/mesh/meshdata/contour.d.ts.map +1 -0
  171. package/dist/mesh/meshdata/contour.js +39 -0
  172. package/dist/mesh/meshdata/contour.js.map +1 -0
  173. package/dist/mesh/meshdata/extrude.d.ts +25 -0
  174. package/dist/mesh/meshdata/extrude.d.ts.map +1 -0
  175. package/dist/mesh/meshdata/extrude.js +198 -0
  176. package/dist/mesh/meshdata/extrude.js.map +1 -0
  177. package/dist/mesh/meshdata/index.js.map +1 -1
  178. package/dist/mesh/meshdata/ops.js.map +1 -1
  179. package/dist/mesh/meshdata/parametric.js.map +1 -1
  180. package/dist/mesh/meshdata/weld.js.map +1 -1
  181. package/dist/node-host/cli.d.ts.map +1 -1
  182. package/dist/node-host/cli.js +3 -2
  183. package/dist/node-host/cli.js.map +1 -1
  184. package/dist/occt-kernel/occt-primitives.d.ts.map +1 -1
  185. package/dist/occt-kernel/occt-primitives.js +2 -0
  186. package/dist/occt-kernel/occt-primitives.js.map +1 -1
  187. package/dist/primitives/svg/svg-path.d.ts +192 -0
  188. package/dist/primitives/svg/svg-path.d.ts.map +1 -0
  189. package/dist/primitives/svg/svg-path.js +776 -0
  190. package/dist/primitives/svg/svg-path.js.map +1 -0
  191. package/dist/third-party/earcut.d.ts +19 -0
  192. package/dist/third-party/earcut.d.ts.map +1 -0
  193. package/dist/third-party/earcut.js +575 -0
  194. package/dist/third-party/earcut.js.map +1 -0
  195. package/package.json +10 -3
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/api/assembly/solvers/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG","sourcesContent":["/**\n * api/assembly/solvers/types — 纯 TS global 求解器的类型与契约(P1)\n *\n * 本模块是 pure-type / 轻量数据层,不依赖任何 brepjs 或运行时单例,\n * 供 solve.ts、global-solver.ts、compound.ts 共享。\n */\n\nimport type { AssemblyTransform } from '../../../runtime-state'\n\n/** 求解风格:'chain'(链式拓扑解析,默认)/ 'global'(CadQuery 兼容全局最小二乘)。 */\nexport type SolverStyle = 'chain' | 'global'\n\n/**\n * 求解选项(P1):透传自 `cad.assembly({ solver })` / `AssemblyBehavior.solver`。\n * `name` 用于 B4 锚定(assembly.py:465 `name == self.name` 锁定)→ 从 behavior.name 注入。\n */\nexport interface SolveOptions {\n /** 默认 'chain',向后零兼容。 */\n solver?: SolverStyle\n /** 装配名(B4 锚定用;cq-compat 的 buildAssembly 注入)。 */\n name?: string\n}\n\n/**\n * global 求解器内部的本地系标记(local-frame marker)。\n *\n * 与 CQ solver.py 的 marker 同义:\n * - point:装配实体的局部坐标点;\n * - axis:轴上一点 + 单位方向(边/圆柱面法线);\n * - plane:面中心 + 单位法向(face_mate / align / angle 用)。\n *\n * 所有坐标取自成员 Shape 的本地系(faijs Shape 不携带 placement → 本地系 == 建模系)。\n */\nexport type GlobalMarker =\n | { type: 'point'; p: [number, number, number] }\n | { type: 'axis'; origin: [number, number, number]; dir: [number, number, number] }\n | { type: 'plane'; center: [number, number, number]; normal: [number, number, number] }\n\n/** global 求解结果(与 `AssemblySolveResult` 对齐的字段集,但新增 residuals)。 */\nexport interface GlobalSolveResult {\n /** 每个被定位成员一条终态变换(pivot 恒 [0,0,0];恒等位姿不输出)。 */\n transforms: AssemblyTransform[]\n /** 恒 0(数值求解不做 DOF 分析,保留字段避免 undefined)。 */\n dof: number\n /** LM 终止即 true(无论残差大小;裁定 4.6)。 */\n converged: boolean\n /** 仅约束类型无法映射为代价时填充。 */\n unsupported: string[]\n /** 逐约束最终残差(诊断,满足「绝不静默」)。 */\n residuals: number[]\n /** 残差超阈值(>1e-6·scale)的约束逐条写入(折中可见)。 */\n warnings?: string[]\n}\n\n\n// ── §5.6.1:chain 求解器类型迁入(原 brepjs kernel/solverAdapter.ts,已内化为第一方代码) ──\n\n/** 3D vector(chain 求解器本地别名,与 quat.ts 同构)。 */\nexport type SolverVec3 = readonly [number, number, number]\n\n/** A geometric entity (plane, axis, or point) referenced by a chain-solver constraint. */\nexport interface SolverEntity {\n type: 'plane' | 'axis' | 'point'\n origin: SolverVec3\n normal?: SolverVec3\n direction?: SolverVec3\n}\n\n/** A chain-solver constraint between two entities, with an optional scalar value. */\nexport interface SolverConstraint {\n type: 'coincident' | 'concentric' | 'distance' | 'angle' | 'fixed'\n entityA?: { node: string; entity: SolverEntity }\n entityB?: { node: string; entity: SolverEntity }\n value?: number\n}\n\n/** Result of the chain solver: per-node transforms, DOF count, and convergence. */\nexport interface SolverResult {\n transforms: Map<string, { position: SolverVec3; rotation: [number, number, number, number] }>\n dof: number\n converged: boolean\n /** Constraint types that were passed in but not solved (not yet implemented). */\n unsupported: string[]\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/api/assembly/solvers/types.ts"],"names":[],"mappings":"AAAA;;;;;GAKG","sourcesContent":["/**\n * api/assembly/solvers/types — 纯 TS global 求解器的类型与契约(P1)\n *\n * 本模块是 pure-type / 轻量数据层,不依赖任何 brepjs 或运行时单例,\n * 供 solve.ts、global-solver.ts、compound.ts 共享。\n */\n\nimport type { AssemblyTransform } from '../../../runtime-state'\n\n/** 求解风格:'chain'(链式拓扑解析,默认)/ 'global'(CadQuery 兼容全局最小二乘)。 */\nexport type SolverStyle = 'chain' | 'global'\n\n/**\n * 求解选项(P1):透传自 `cad.assembly({ solver })` / `AssemblyBehavior.solver`。\n * `name` 用于 B4 锚定(assembly.py:465 `name == self.name` 锁定)→ 从 behavior.name 注入。\n */\nexport interface SolveOptions {\n /** 默认 'chain',向后零兼容。 */\n solver?: SolverStyle\n /** 装配名(B4 锚定用;cq-compat 的 buildAssembly 注入)。 */\n name?: string\n}\n\n/**\n * global 求解器内部的本地系标记(local-frame marker)。\n *\n * 与 CQ solver.py 的 marker 同义:\n * - point:装配实体的局部坐标点;\n * - axis:轴上一点 + 单位方向(边/圆柱面法线);\n * - plane:面中心 + 单位法向(face_mate / align / angle 用)。\n *\n * 所有坐标取自成员 Shape 的本地系(faijs Shape 不携带 placement → 本地系 == 建模系)。\n */\nexport type GlobalMarker =\n | { type: 'point'; p: [number, number, number] }\n | { type: 'axis'; origin: [number, number, number]; dir: [number, number, number] }\n | { type: 'plane'; center: [number, number, number]; normal: [number, number, number] }\n\n/** global 求解结果(与 `AssemblySolveResult` 对齐的字段集,但新增 residuals)。 */\nexport interface GlobalSolveResult {\n /** 每个被定位成员一条终态变换(pivot 恒 [0,0,0];恒等位姿不输出)。 */\n transforms: AssemblyTransform[]\n /** 恒 0(数值求解不做 DOF 分析,保留字段避免 undefined)。 */\n dof: number\n /**\n * P7/D1-3:欠定自由度诊断(仅 global 路径)。dof > 0 = 约束集欠定,终态位姿\n * 依赖优化器轨迹、无唯一「正确解」——判等方应走规范判等通道而非逐位比对。\n * dof === 0 时字段缺省(undefined)。\n */\n underdetermined?: { dof: number }\n /** LM 终止即 true(无论残差大小;裁定 4.6)。 */\n converged: boolean\n /** 仅约束类型无法映射为代价时填充。 */\n unsupported: string[]\n /** 逐约束最终残差(诊断,满足「绝不静默」)。 */\n residuals: number[]\n /** 残差超阈值(>1e-6·scale)的约束逐条写入(折中可见)。 */\n warnings?: string[]\n}\n\n\n// ── §5.6.1:chain 求解器类型迁入(原 brepjs kernel/solverAdapter.ts,已内化为第一方代码) ──\n\n/** 3D vector(chain 求解器本地别名,与 quat.ts 同构)。 */\nexport type SolverVec3 = readonly [number, number, number]\n\n/** A geometric entity (plane, axis, or point) referenced by a chain-solver constraint. */\nexport interface SolverEntity {\n type: 'plane' | 'axis' | 'point'\n origin: SolverVec3\n normal?: SolverVec3\n direction?: SolverVec3\n}\n\n/** A chain-solver constraint between two entities, with an optional scalar value. */\nexport interface SolverConstraint {\n type: 'coincident' | 'concentric' | 'distance' | 'angle' | 'fixed'\n entityA?: { node: string; entity: SolverEntity }\n entityB?: { node: string; entity: SolverEntity }\n value?: number\n}\n\n/** Result of the chain solver: per-node transforms, DOF count, and convergence. */\nexport interface SolverResult {\n transforms: Map<string, { position: SolverVec3; rotation: [number, number, number, number] }>\n dof: number\n converged: boolean\n /** Constraint types that were passed in but not solved (not yet implemented). */\n unsupported: string[]\n}\n"]}
@@ -110,8 +110,39 @@ export interface FixedConstraint {
110
110
  type: 'fixed';
111
111
  part: PartName;
112
112
  }
113
+ /**
114
+ * 世界锚定 unary:把该部件的某个子实体(顶点/面中心/原点)钉到**世界字面坐标**
115
+ * `world`。只约束该点,成员其余自由度(尤其朝向)保持自由——**不等于**整件 `fixed`。
116
+ */
117
+ export interface FixedPointConstraint {
118
+ type: 'fixedPoint';
119
+ /** 待钉定的成员子实体(`{part, point}` / `{part, face}` / `{part, edge}`)。 */
120
+ a: EntityRef;
121
+ /** 世界字面坐标(mm)。 */
122
+ world: AssemblyVec3;
123
+ }
124
+ /**
125
+ * 世界锚定 unary:把该部件的某个轴(边方向 / 面法向)钉到**世界字面方向**
126
+ * `worldDir`。无需单位化,求解器内 `vnormalize`。
127
+ */
128
+ export interface FixedAxisConstraint {
129
+ type: 'fixedAxis';
130
+ /** 待钉定的成员轴(`{part, edge}` / `{part, face}`)。 */
131
+ a: EntityRef;
132
+ /** 世界字面方向(不需要单位化)。 */
133
+ worldDir: AssemblyVec3;
134
+ }
135
+ /**
136
+ * 世界锚定 unary:锁定该部件的**朝向**(本地 X/Y/Z 轴对齐世界 X/Y/Z,即恒等朝向),
137
+ * 平移自由度保持自由。
138
+ */
139
+ export interface FixedRotationConstraint {
140
+ type: 'fixedRotation';
141
+ /** 仅锁朝向的成员名。 */
142
+ part: PartName;
143
+ }
113
144
  /** 新形态约束的并集。 */
114
- export type StructuralConstraint = MateConstraint | AlignConstraint | CoincidentConstraint | ConcentricConstraint | DistanceConstraint | AngleConstraint | ParallelConstraint | PerpendicularConstraint | FixedConstraint;
145
+ export type StructuralConstraint = MateConstraint | AlignConstraint | CoincidentConstraint | ConcentricConstraint | DistanceConstraint | AngleConstraint | ParallelConstraint | PerpendicularConstraint | FixedConstraint | FixedPointConstraint | FixedAxisConstraint | FixedRotationConstraint;
115
146
  /**
116
147
  * 装配约束的一个面:`{ topoRef: FaceTopoRef }`(§6.2 新形态,执行期解析几何)或
117
148
  * 旧快照 `{ surfaceType, center, normal }`(兼容已持久化的历史脚本)。
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/api/assembly/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/api/assembly/types.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/api/assembly/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG","sourcesContent":["/**\n * api/assembly/types — 装配约束的 faijs 侧类型(P1,方案 §5.2/§5.3)\n *\n * 设计约束(方案 §5.1):\n * - C1 可序列化:约束参数全部 JSON 安全,写进 .fai.js 文本、跨重放指认同一实体。\n * - C4 a 是参考(reference)、b 是从动(dependent):移动 b 去贴合 a。\n * - C6 派生值不入库:约束对象不存 transform。\n *\n * 本模块是纯类型层:只依赖 naming 的 TopoRef 类型,不依赖 compound(避免循环)。\n * FaceMateConstraint(遗留形态)也在此定义,compound.ts re-export 保持既有导出面。\n */\n\nimport type { PartName } from '../../identity'\nimport type { FaceTopoRef, EdgeTopoRef } from '../../topology/naming'\n\n/** 3D 向量(mm)。 */\nexport type AssemblyVec3 = [number, number, number]\n\n// ── 实体引用 EntityRef(§5.2)──\n\n/**\n * 面引用:`{ topoRef }`(首选,宿主拾取生成,跨重放稳定)或\n * 旧快照 `{ surfaceType?, center, normal }`(兼容已持久化的历史脚本 / 手写调试)。\n */\nexport type FaceRef =\n | { topoRef: FaceTopoRef }\n | { surfaceType?: string; center: AssemblyVec3; normal: AssemblyVec3 }\n\n/**\n * 边引用:`{ topoRef }`(直边 → 轴;圆边 → 轴线)或轴快照 `{ axis }`。\n */\nexport type EdgeRef =\n | { topoRef: EdgeTopoRef }\n | { axis: { origin: AssemblyVec3; direction: AssemblyVec3 } }\n\n/**\n * 装配实体引用(§5.2):\n * - 面:平面 → plane 实体;圆柱/回转面 → axis 实体(需 hint.axis);\n * - 边:直边/圆边 → axis 实体;\n * - 点:局部坐标 → point 实体;\n * - faceIndex:面序号简写(1 起,手写友好但跨拓扑变更不稳定,仅调试)。\n */\nexport type EntityRef =\n | { part: PartName; face: FaceRef }\n | { part: PartName; edge: EdgeRef }\n | { part: PartName; point: AssemblyVec3 }\n | { part: PartName; faceIndex: number }\n\n// ── 约束类型(§5.3 总表)──\n\n/** 面对面贴合:法向反向 + 面中心重合(遗留 face_mate 的新名;求解降级为 concentric + 轴编码)。 */\nexport interface MateConstraint {\n type: 'mate'\n a: EntityRef\n b: EntityRef\n}\n\n/** 同向对齐:法向同向 + 面中心重合(mate 的不翻转变体)。 */\nexport interface AlignConstraint {\n type: 'align'\n a: EntityRef\n b: EntityRef\n}\n\n/** 共面/共点/共线(brepjs 原生 coincident;保留面内 2 个平移 DOF)。 */\nexport interface CoincidentConstraint {\n type: 'coincident'\n a: EntityRef\n b: EntityRef\n}\n\n/** 轴重合(孔轴配合 / 插入;要求两侧都是轴实体)。 */\nexport interface ConcentricConstraint {\n type: 'concentric'\n a: EntityRef\n b: EntityRef\n}\n\n/** 定距(mm)。 */\nexport interface DistanceConstraint {\n type: 'distance'\n value: number\n a: EntityRef\n b: EntityRef\n}\n\n/** 夹角(deg,plane-plane)。 */\nexport interface AngleConstraint {\n type: 'angle'\n value: number\n a: EntityRef\n b: EntityRef\n}\n\n/** 平行(angle 0° 的语法糖)。 */\nexport interface ParallelConstraint {\n type: 'parallel'\n a: EntityRef\n b: EntityRef\n}\n\n/** 垂直(angle 90° 的语法糖)。 */\nexport interface PerpendicularConstraint {\n type: 'perpendicular'\n a: EntityRef\n b: EntityRef\n}\n\n/** 锚定该部件(地基)。 */\nexport interface FixedConstraint {\n type: 'fixed'\n part: PartName\n}\n\n/** 新形态约束的并集。 */\nexport type StructuralConstraint =\n | MateConstraint\n | AlignConstraint\n | CoincidentConstraint\n | ConcentricConstraint\n | DistanceConstraint\n | AngleConstraint\n | ParallelConstraint\n | PerpendicularConstraint\n | FixedConstraint\n\n// ── 遗留形态(§2.1,规范化时改写为 mate)──\n\n/**\n * 装配约束的一个面:`{ topoRef: FaceTopoRef }`(§6.2 新形态,执行期解析几何)或\n * 旧快照 `{ surfaceType, center, normal }`(兼容已持久化的历史脚本)。\n */\nexport type FaceMateFace = { topoRef: FaceTopoRef } | {\n surfaceType?: string\n center: AssemblyVec3\n normal: AssemblyVec3\n}\n\n/** A face-mate constraint aligning two faces so the moving face mates against the fixed face. */\nexport interface FaceMateConstraint {\n type: 'face_mate'\n fixedPartName: PartName\n movingPartName: PartName\n fixedFace: FaceMateFace\n movingFace: FaceMateFace\n}\n\n/** `cad.assembly({ constraints })` 接受的全部约束形态(遗留 + 新增)。 */\nexport type AssemblyConstraint = FaceMateConstraint | StructuralConstraint\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/api/assembly/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG","sourcesContent":["/**\n * api/assembly/types — 装配约束的 faijs 侧类型(P1,方案 §5.2/§5.3)\n *\n * 设计约束(方案 §5.1):\n * - C1 可序列化:约束参数全部 JSON 安全,写进 .fai.js 文本、跨重放指认同一实体。\n * - C4 a 是参考(reference)、b 是从动(dependent):移动 b 去贴合 a。\n * - C6 派生值不入库:约束对象不存 transform。\n *\n * 本模块是纯类型层:只依赖 naming 的 TopoRef 类型,不依赖 compound(避免循环)。\n * FaceMateConstraint(遗留形态)也在此定义,compound.ts re-export 保持既有导出面。\n */\n\nimport type { PartName } from '../../identity'\nimport type { FaceTopoRef, EdgeTopoRef } from '../../topology/naming'\n\n/** 3D 向量(mm)。 */\nexport type AssemblyVec3 = [number, number, number]\n\n// ── 实体引用 EntityRef(§5.2)──\n\n/**\n * 面引用:`{ topoRef }`(首选,宿主拾取生成,跨重放稳定)或\n * 旧快照 `{ surfaceType?, center, normal }`(兼容已持久化的历史脚本 / 手写调试)。\n */\nexport type FaceRef =\n | { topoRef: FaceTopoRef }\n | { surfaceType?: string; center: AssemblyVec3; normal: AssemblyVec3 }\n\n/**\n * 边引用:`{ topoRef }`(直边 → 轴;圆边 → 轴线)或轴快照 `{ axis }`。\n */\nexport type EdgeRef =\n | { topoRef: EdgeTopoRef }\n | { axis: { origin: AssemblyVec3; direction: AssemblyVec3 } }\n\n/**\n * 装配实体引用(§5.2):\n * - 面:平面 → plane 实体;圆柱/回转面 → axis 实体(需 hint.axis);\n * - 边:直边/圆边 → axis 实体;\n * - 点:局部坐标 → point 实体;\n * - faceIndex:面序号简写(1 起,手写友好但跨拓扑变更不稳定,仅调试)。\n */\nexport type EntityRef =\n | { part: PartName; face: FaceRef }\n | { part: PartName; edge: EdgeRef }\n | { part: PartName; point: AssemblyVec3 }\n | { part: PartName; faceIndex: number }\n\n// ── 约束类型(§5.3 总表)──\n\n/** 面对面贴合:法向反向 + 面中心重合(遗留 face_mate 的新名;求解降级为 concentric + 轴编码)。 */\nexport interface MateConstraint {\n type: 'mate'\n a: EntityRef\n b: EntityRef\n}\n\n/** 同向对齐:法向同向 + 面中心重合(mate 的不翻转变体)。 */\nexport interface AlignConstraint {\n type: 'align'\n a: EntityRef\n b: EntityRef\n}\n\n/** 共面/共点/共线(brepjs 原生 coincident;保留面内 2 个平移 DOF)。 */\nexport interface CoincidentConstraint {\n type: 'coincident'\n a: EntityRef\n b: EntityRef\n}\n\n/** 轴重合(孔轴配合 / 插入;要求两侧都是轴实体)。 */\nexport interface ConcentricConstraint {\n type: 'concentric'\n a: EntityRef\n b: EntityRef\n}\n\n/** 定距(mm)。 */\nexport interface DistanceConstraint {\n type: 'distance'\n value: number\n a: EntityRef\n b: EntityRef\n}\n\n/** 夹角(deg,plane-plane)。 */\nexport interface AngleConstraint {\n type: 'angle'\n value: number\n a: EntityRef\n b: EntityRef\n}\n\n/** 平行(angle 0° 的语法糖)。 */\nexport interface ParallelConstraint {\n type: 'parallel'\n a: EntityRef\n b: EntityRef\n}\n\n/** 垂直(angle 90° 的语法糖)。 */\nexport interface PerpendicularConstraint {\n type: 'perpendicular'\n a: EntityRef\n b: EntityRef\n}\n\n/** 锚定该部件(地基)。 */\nexport interface FixedConstraint {\n type: 'fixed'\n part: PartName\n}\n\n/**\n * 世界锚定 unary:把该部件的某个子实体(顶点/面中心/原点)钉到**世界字面坐标**\n * `world`。只约束该点,成员其余自由度(尤其朝向)保持自由——**不等于**整件 `fixed`。\n */\nexport interface FixedPointConstraint {\n type: 'fixedPoint'\n /** 待钉定的成员子实体(`{part, point}` / `{part, face}` / `{part, edge}`)。 */\n a: EntityRef\n /** 世界字面坐标(mm)。 */\n world: AssemblyVec3\n}\n\n/**\n * 世界锚定 unary:把该部件的某个轴(边方向 / 面法向)钉到**世界字面方向**\n * `worldDir`。无需单位化,求解器内 `vnormalize`。\n */\nexport interface FixedAxisConstraint {\n type: 'fixedAxis'\n /** 待钉定的成员轴(`{part, edge}` / `{part, face}`)。 */\n a: EntityRef\n /** 世界字面方向(不需要单位化)。 */\n worldDir: AssemblyVec3\n}\n\n/**\n * 世界锚定 unary:锁定该部件的**朝向**(本地 X/Y/Z 轴对齐世界 X/Y/Z,即恒等朝向),\n * 平移自由度保持自由。\n */\nexport interface FixedRotationConstraint {\n type: 'fixedRotation'\n /** 仅锁朝向的成员名。 */\n part: PartName\n}\n\n/** 新形态约束的并集。 */\nexport type StructuralConstraint =\n | MateConstraint\n | AlignConstraint\n | CoincidentConstraint\n | ConcentricConstraint\n | DistanceConstraint\n | AngleConstraint\n | ParallelConstraint\n | PerpendicularConstraint\n | FixedConstraint\n | FixedPointConstraint\n | FixedAxisConstraint\n | FixedRotationConstraint\n\n// ── 遗留形态(§2.1,规范化时改写为 mate)──\n\n/**\n * 装配约束的一个面:`{ topoRef: FaceTopoRef }`(§6.2 新形态,执行期解析几何)或\n * 旧快照 `{ surfaceType, center, normal }`(兼容已持久化的历史脚本)。\n */\nexport type FaceMateFace = { topoRef: FaceTopoRef } | {\n surfaceType?: string\n center: AssemblyVec3\n normal: AssemblyVec3\n}\n\n/** A face-mate constraint aligning two faces so the moving face mates against the fixed face. */\nexport interface FaceMateConstraint {\n type: 'face_mate'\n fixedPartName: PartName\n movingPartName: PartName\n fixedFace: FaceMateFace\n movingFace: FaceMateFace\n}\n\n/** `cad.assembly({ constraints })` 接受的全部约束形态(遗留 + 新增)。 */\nexport type AssemblyConstraint = FaceMateConstraint | StructuralConstraint\n"]}
@@ -8,7 +8,7 @@
8
8
  *
9
9
  * 校验规则(逐条可判,报错文案必含:字段路径 + 期望形态 + 实际收到值):
10
10
  * - V1 `type` ∈ {mate, align, coincident, concentric, distance, angle, parallel,
11
- * perpendicular, fixed, face_mate}(文案列出合法类型全集);
11
+ * perpendicular, fixed, fixedPoint, fixedAxis, fixedRotation, face_mate}(文案列出合法类型全集);
12
12
  * - V2 mate/align/coincident/concentric/distance/angle/parallel/perpendicular
13
13
  * 必须有 `a`、`b` 两个 EntityRef(face_mate 等价为 fixedFace/movingFace);
14
14
  * - V3 distance/angle 必须有**有限数** `value`;不设区间(angle 允许 ±360 以外)
@@ -25,7 +25,7 @@
25
25
  */
26
26
  import type { AssemblyConstraint } from './types.js';
27
27
  /** 合法约束类型全集(V1;与 types.ts 的 AssemblyConstraint 并集约等)。 */
28
- export declare const ASSEMBLY_CONSTRAINT_TYPES: readonly ["mate", "align", "coincident", "concentric", "distance", "angle", "parallel", "perpendicular", "fixed", "face_mate"];
28
+ export declare const ASSEMBLY_CONSTRAINT_TYPES: readonly ["mate", "align", "coincident", "concentric", "distance", "angle", "parallel", "perpendicular", "fixed", "fixedPoint", "fixedAxis", "fixedRotation", "face_mate"];
29
29
  /**
30
30
  * 校验 `cad.assembly({ constraints })` 的 constraints 参数(V1–V6)。
31
31
  * @param constraints - 未校验的 constraints 输入(脚本/宿主直传,可为任意值)。
@@ -1 +1 @@
1
- {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/api/assembly/validate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAEjD,yDAAyD;AACzD,eAAO,MAAM,yBAAyB,gIAG5B,CAAA;AA0GV;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,OAAO,EACpB,WAAW,EAAE,MAAM,EAAE,GACpB,OAAO,CAAC,WAAW,IAAI,kBAAkB,EAAE,CAO7C"}
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/api/assembly/validate.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAEjD,yDAAyD;AACzD,eAAO,MAAM,yBAAyB,4KAG5B,CAAA;AAsIV;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CACjC,WAAW,EAAE,OAAO,EACpB,WAAW,EAAE,MAAM,EAAE,GACpB,OAAO,CAAC,WAAW,IAAI,kBAAkB,EAAE,CAO7C"}
@@ -8,7 +8,7 @@
8
8
  *
9
9
  * 校验规则(逐条可判,报错文案必含:字段路径 + 期望形态 + 实际收到值):
10
10
  * - V1 `type` ∈ {mate, align, coincident, concentric, distance, angle, parallel,
11
- * perpendicular, fixed, face_mate}(文案列出合法类型全集);
11
+ * perpendicular, fixed, fixedPoint, fixedAxis, fixedRotation, face_mate}(文案列出合法类型全集);
12
12
  * - V2 mate/align/coincident/concentric/distance/angle/parallel/perpendicular
13
13
  * 必须有 `a`、`b` 两个 EntityRef(face_mate 等价为 fixedFace/movingFace);
14
14
  * - V3 distance/angle 必须有**有限数** `value`;不设区间(angle 允许 ±360 以外)
@@ -26,7 +26,7 @@
26
26
  /** 合法约束类型全集(V1;与 types.ts 的 AssemblyConstraint 并集约等)。 */
27
27
  export const ASSEMBLY_CONSTRAINT_TYPES = [
28
28
  'mate', 'align', 'coincident', 'concentric', 'distance', 'angle',
29
- 'parallel', 'perpendicular', 'fixed', 'face_mate',
29
+ 'parallel', 'perpendicular', 'fixed', 'fixedPoint', 'fixedAxis', 'fixedRotation', 'face_mate',
30
30
  ];
31
31
  /** 需要 `a`/`b` 两个 EntityRef 的新形态类型(V2;distance/angle 在 types 契约里也有 a/b)。 */
32
32
  const PAIRED_TYPES = new Set([
@@ -36,6 +36,13 @@ const PAIRED_TYPES = new Set([
36
36
  function fail(path, expected, got) {
37
37
  throw new Error(`[assembly] ${path}: expected ${expected}, got ${JSON.stringify(got)}`);
38
38
  }
39
+ /** V3 类比:有限数 vec3(world/worldDir 用)。 */
40
+ function checkVec3(v, path) {
41
+ if (!Array.isArray(v) || v.length !== 3 ||
42
+ v.some((n) => typeof n !== 'number' || !Number.isFinite(n))) {
43
+ fail(path, 'a vec3 [x, y, z] of finite numbers', v);
44
+ }
45
+ }
39
46
  /** V4:EntityRef 四形态互斥且恰占其一;faceIndex 正整数;part 必须 ∈ members(V5)。 */
40
47
  function checkEntityRef(ref, path, memberNames) {
41
48
  if (ref === null || typeof ref !== 'object') {
@@ -100,6 +107,21 @@ function checkOne(raw, i, memberNames) {
100
107
  }
101
108
  return;
102
109
  }
110
+ // 世界锚定 unary(fixedPoint/fixedAxis/fixedRotation):a 是 EntityRef,part 是成员
111
+ if (type === 'fixedPoint' || type === 'fixedAxis') {
112
+ checkEntityRef(c.a, `${path}.a`, memberNames);
113
+ checkVec3(type === 'fixedPoint' ? c.world : c.worldDir, type === 'fixedPoint' ? `${path}.world` : `${path}.worldDir`);
114
+ return;
115
+ }
116
+ if (type === 'fixedRotation') {
117
+ if (typeof c.part !== 'string' || c.part.length === 0) {
118
+ fail(`${path}.part`, 'a non-empty member name string', c.part);
119
+ }
120
+ if (!memberNames.includes(c.part)) {
121
+ throw new Error(`[assembly] ${path}.part: "${c.part}" is not a member; members: [${memberNames.join(', ')}]`);
122
+ }
123
+ return;
124
+ }
103
125
  // V2 + V4(a/b 每个都是 EntityRef)
104
126
  if (PAIRED_TYPES.has(type)) {
105
127
  checkEntityRef(c.a, `${path}.a`, memberNames);
@@ -1 +1 @@
1
- {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../src/api/assembly/validate.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * api/assembly/validate — `cad.assembly({ constraints })` 约束参数运行期校验(P2-f1)\n *\n * 前置事实(09-07 方案 §2.1):`assembly` 是 `api/compound.ts` 里的普通导出函数\n * (经 api-namespace 注册进 cad 命名空间),**不是 defineOp/compatOp 声明的 op**,\n * 没有 \"params 校验惯例\" 可复用;`api/assert.ts` 的 7 个助手都是标量/向量级,\n * **没有对象/数组结构校验助手**——本模块内的结构校验逻辑是新增的,不污染通用 assert。\n *\n * 校验规则(逐条可判,报错文案必含:字段路径 + 期望形态 + 实际收到值):\n * - V1 `type` ∈ {mate, align, coincident, concentric, distance, angle, parallel,\n * perpendicular, fixed, face_mate}(文案列出合法类型全集);\n * - V2 mate/align/coincident/concentric/distance/angle/parallel/perpendicular\n * 必须有 `a`、`b` 两个 EntityRef(face_mate 等价为 fixedFace/movingFace);\n * - V3 distance/angle 必须有**有限数** `value`;不设区间(angle 允许 ±360 以外)\n * 与 brepjs solveAngle 行为对齐;\n * - V4 EntityRef 四形态 `face`/`edge`/`point`/`faceIndex` 互斥且恰占其一;\n * `faceIndex` 必须为正整数;\n * - V5 `fixed` 只需要 `part`;`part` 必须出现在 members 里(**所有约束类型统一检查**,\n * 文案含成员名全集);\n * - V6 face_mate 按 normalize 语义重排(fixedPartName/fixedFace → a,\n * movingPartName/movingFace → b)后同样过 V2/V5。\n *\n * 调用点:`compound.ts` 的 `assembly(params)` 函数体开头、`keep()` 之前(fail-fast,\n * 与 normalize.ts 的未知类型抛错互补——执行期错误不静默)。\n */\n\nimport type { AssemblyConstraint } from './types'\n\n/** 合法约束类型全集(V1;与 types.ts 的 AssemblyConstraint 并集约等)。 */\nexport const ASSEMBLY_CONSTRAINT_TYPES = [\n 'mate', 'align', 'coincident', 'concentric', 'distance', 'angle',\n 'parallel', 'perpendicular', 'fixed', 'face_mate',\n] as const\n\n/** 需要 `a`/`b` 两个 EntityRef 的新形态类型(V2;distance/angle 在 types 契约里也有 a/b)。 */\nconst PAIRED_TYPES = new Set([\n 'mate', 'align', 'coincident', 'concentric', 'distance', 'angle',\n 'parallel', 'perpendicular',\n])\n\nfunction fail(path: string, expected: string, got: unknown): never {\n throw new Error(`[assembly] ${path}: expected ${expected}, got ${JSON.stringify(got)}`)\n}\n\n/** V4:EntityRef 四形态互斥且恰占其一;faceIndex 正整数;part 必须 ∈ members(V5)。 */\nfunction checkEntityRef(ref: unknown, path: string, memberNames: string[]): void {\n if (ref === null || typeof ref !== 'object') {\n fail(path, 'an EntityRef object { part, face | edge | point | faceIndex }', ref)\n }\n const r = ref as Record<string, unknown>\n if (typeof r.part !== 'string' || r.part.length === 0) {\n fail(`${path}.part`, 'a non-empty member name string', r.part)\n }\n if (!memberNames.includes(r.part)) {\n throw new Error(\n `[assembly] ${path}.part: \"${r.part}\" is not a member; members: [${memberNames.join(', ')}]`,\n )\n }\n const present = (['face', 'edge', 'point', 'faceIndex'] as const).filter(\n (k) => k in r && r[k] !== undefined,\n )\n if (present.length !== 1) {\n fail(path, `exactly one of face/edge/point/faceIndex (mutually exclusive), got keys [${present.join(', ')}]`, r)\n }\n if ('faceIndex' in r) {\n const idx = r.faceIndex\n if (typeof idx !== 'number' || !Number.isInteger(idx) || idx < 1) {\n fail(`${path}.faceIndex`, 'a positive integer (1-based face ordinal)', idx)\n }\n }\n if ('point' in r) {\n const p = r.point\n if (\n !Array.isArray(p) || p.length !== 3 ||\n p.some((n) => typeof n !== 'number' || !Number.isFinite(n))\n ) {\n fail(`${path}.point`, 'a vec3 [x, y, z] of finite numbers', p)\n }\n }\n}\n\n/** V6:face_mate 按 normalize 语义重排后过 V2/V5(face 省略四形态检查——结构上必为面)。 */\nfunction checkFaceMate(c: Record<string, unknown>, path: string, memberNames: string[]): void {\n const a = { part: c.fixedPartName, face: c.fixedFace }\n const b = { part: c.movingPartName, face: c.movingFace }\n checkEntityRef(a, `${path} (a → fixedPartName/fixedFace)`, memberNames)\n checkEntityRef(b, `${path} (b → movingPartName/movingFace)`, memberNames)\n}\n\n/** 校验单条约束(下标 i 用于报错路径)。 */\nfunction checkOne(raw: unknown, i: number, memberNames: string[]): void {\n const path = `constraints[${i}]`\n if (raw === null || typeof raw !== 'object') {\n fail(path, 'an object with a \"type\" field', raw)\n }\n const c = raw as Record<string, unknown>\n // V1\n const type = c.type\n if (typeof type !== 'string' || !(ASSEMBLY_CONSTRAINT_TYPES as readonly string[]).includes(type)) {\n throw new Error(\n `[assembly] ${path}.type: unknown constraint type ${JSON.stringify(type)}, expected one of ${ASSEMBLY_CONSTRAINT_TYPES.join(' | ')}`,\n )\n }\n\n // V6:face_mate 先归一化再走通用校验\n if (type === 'face_mate') {\n checkFaceMate(c, path, memberNames)\n return\n }\n\n // V5:fixed 只需要顶层 part(字符串)且 ∈ members\n if (type === 'fixed') {\n if (typeof c.part !== 'string' || c.part.length === 0) {\n fail(`${path}.part`, 'a non-empty member name string', c.part)\n }\n if (!memberNames.includes(c.part)) {\n throw new Error(\n `[assembly] ${path}.part: \"${c.part}\" is not a member; members: [${memberNames.join(', ')}]`,\n )\n }\n return\n }\n\n // V2 + V4(a/b 每个都是 EntityRef)\n if (PAIRED_TYPES.has(type)) {\n checkEntityRef(c.a, `${path}.a`, memberNames)\n checkEntityRef(c.b, `${path}.b`, memberNames)\n }\n\n // V3:distance/angle 必须有有限数 value(不设区间,与 brepjs solveAngle 对齐)\n if (type === 'distance' || type === 'angle') {\n const v = c.value\n if (typeof v !== 'number' || !Number.isFinite(v)) {\n fail(`${path}.value`, 'a finite number', v)\n }\n }\n}\n\n/**\n * 校验 `cad.assembly({ constraints })` 的 constraints 参数(V1–V6)。\n * @param constraints - 未校验的 constraints 输入(脚本/宿主直传,可为任意值)。\n * @param memberNames - 成员名列表(来自成员的 nameOf 反查/显式 memberNames),V5 用。\n * @throws Error 首条违规即抛(fail-fast),文案含字段路径。\n * @returns 断言函数,通过后收窄 constraints 为 AssemblyConstraint[]。\n */\nexport function validateConstraints(\n constraints: unknown,\n memberNames: string[],\n): asserts constraints is AssemblyConstraint[] {\n if (!Array.isArray(constraints)) {\n fail('constraints', 'an array of constraint objects', constraints)\n }\n for (let i = 0; i < constraints.length; i++) {\n checkOne(constraints[i], i, memberNames)\n }\n}"]}
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../src/api/assembly/validate.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * api/assembly/validate — `cad.assembly({ constraints })` 约束参数运行期校验(P2-f1)\n *\n * 前置事实(09-07 方案 §2.1):`assembly` 是 `api/compound.ts` 里的普通导出函数\n * (经 api-namespace 注册进 cad 命名空间),**不是 defineOp/compatOp 声明的 op**,\n * 没有 \"params 校验惯例\" 可复用;`api/assert.ts` 的 7 个助手都是标量/向量级,\n * **没有对象/数组结构校验助手**——本模块内的结构校验逻辑是新增的,不污染通用 assert。\n *\n * 校验规则(逐条可判,报错文案必含:字段路径 + 期望形态 + 实际收到值):\n * - V1 `type` ∈ {mate, align, coincident, concentric, distance, angle, parallel,\n * perpendicular, fixed, fixedPoint, fixedAxis, fixedRotation, face_mate}(文案列出合法类型全集);\n * - V2 mate/align/coincident/concentric/distance/angle/parallel/perpendicular\n * 必须有 `a`、`b` 两个 EntityRef(face_mate 等价为 fixedFace/movingFace);\n * - V3 distance/angle 必须有**有限数** `value`;不设区间(angle 允许 ±360 以外)\n * 与 brepjs solveAngle 行为对齐;\n * - V4 EntityRef 四形态 `face`/`edge`/`point`/`faceIndex` 互斥且恰占其一;\n * `faceIndex` 必须为正整数;\n * - V5 `fixed` 只需要 `part`;`part` 必须出现在 members 里(**所有约束类型统一检查**,\n * 文案含成员名全集);\n * - V6 face_mate 按 normalize 语义重排(fixedPartName/fixedFace → a,\n * movingPartName/movingFace → b)后同样过 V2/V5。\n *\n * 调用点:`compound.ts` 的 `assembly(params)` 函数体开头、`keep()` 之前(fail-fast,\n * 与 normalize.ts 的未知类型抛错互补——执行期错误不静默)。\n */\n\nimport type { AssemblyConstraint } from './types'\n\n/** 合法约束类型全集(V1;与 types.ts 的 AssemblyConstraint 并集约等)。 */\nexport const ASSEMBLY_CONSTRAINT_TYPES = [\n 'mate', 'align', 'coincident', 'concentric', 'distance', 'angle',\n 'parallel', 'perpendicular', 'fixed', 'fixedPoint', 'fixedAxis', 'fixedRotation', 'face_mate',\n] as const\n\n/** 需要 `a`/`b` 两个 EntityRef 的新形态类型(V2;distance/angle 在 types 契约里也有 a/b)。 */\nconst PAIRED_TYPES = new Set([\n 'mate', 'align', 'coincident', 'concentric', 'distance', 'angle',\n 'parallel', 'perpendicular',\n])\n\nfunction fail(path: string, expected: string, got: unknown): never {\n throw new Error(`[assembly] ${path}: expected ${expected}, got ${JSON.stringify(got)}`)\n}\n\n/** V3 类比:有限数 vec3(world/worldDir 用)。 */\nfunction checkVec3(v: unknown, path: string): void {\n if (\n !Array.isArray(v) || v.length !== 3 ||\n v.some((n) => typeof n !== 'number' || !Number.isFinite(n))\n ) {\n fail(path, 'a vec3 [x, y, z] of finite numbers', v)\n }\n}\n\n/** V4:EntityRef 四形态互斥且恰占其一;faceIndex 正整数;part 必须 ∈ members(V5)。 */\nfunction checkEntityRef(ref: unknown, path: string, memberNames: string[]): void {\n if (ref === null || typeof ref !== 'object') {\n fail(path, 'an EntityRef object { part, face | edge | point | faceIndex }', ref)\n }\n const r = ref as Record<string, unknown>\n if (typeof r.part !== 'string' || r.part.length === 0) {\n fail(`${path}.part`, 'a non-empty member name string', r.part)\n }\n if (!memberNames.includes(r.part)) {\n throw new Error(\n `[assembly] ${path}.part: \"${r.part}\" is not a member; members: [${memberNames.join(', ')}]`,\n )\n }\n const present = (['face', 'edge', 'point', 'faceIndex'] as const).filter(\n (k) => k in r && r[k] !== undefined,\n )\n if (present.length !== 1) {\n fail(path, `exactly one of face/edge/point/faceIndex (mutually exclusive), got keys [${present.join(', ')}]`, r)\n }\n if ('faceIndex' in r) {\n const idx = r.faceIndex\n if (typeof idx !== 'number' || !Number.isInteger(idx) || idx < 1) {\n fail(`${path}.faceIndex`, 'a positive integer (1-based face ordinal)', idx)\n }\n }\n if ('point' in r) {\n const p = r.point\n if (\n !Array.isArray(p) || p.length !== 3 ||\n p.some((n) => typeof n !== 'number' || !Number.isFinite(n))\n ) {\n fail(`${path}.point`, 'a vec3 [x, y, z] of finite numbers', p)\n }\n }\n}\n\n/** V6:face_mate 按 normalize 语义重排后过 V2/V5(face 省略四形态检查——结构上必为面)。 */\nfunction checkFaceMate(c: Record<string, unknown>, path: string, memberNames: string[]): void {\n const a = { part: c.fixedPartName, face: c.fixedFace }\n const b = { part: c.movingPartName, face: c.movingFace }\n checkEntityRef(a, `${path} (a → fixedPartName/fixedFace)`, memberNames)\n checkEntityRef(b, `${path} (b → movingPartName/movingFace)`, memberNames)\n}\n\n/** 校验单条约束(下标 i 用于报错路径)。 */\nfunction checkOne(raw: unknown, i: number, memberNames: string[]): void {\n const path = `constraints[${i}]`\n if (raw === null || typeof raw !== 'object') {\n fail(path, 'an object with a \"type\" field', raw)\n }\n const c = raw as Record<string, unknown>\n // V1\n const type = c.type\n if (typeof type !== 'string' || !(ASSEMBLY_CONSTRAINT_TYPES as readonly string[]).includes(type)) {\n throw new Error(\n `[assembly] ${path}.type: unknown constraint type ${JSON.stringify(type)}, expected one of ${ASSEMBLY_CONSTRAINT_TYPES.join(' | ')}`,\n )\n }\n\n // V6:face_mate 先归一化再走通用校验\n if (type === 'face_mate') {\n checkFaceMate(c, path, memberNames)\n return\n }\n\n // V5:fixed 只需要顶层 part(字符串)且 ∈ members\n if (type === 'fixed') {\n if (typeof c.part !== 'string' || c.part.length === 0) {\n fail(`${path}.part`, 'a non-empty member name string', c.part)\n }\n if (!memberNames.includes(c.part)) {\n throw new Error(\n `[assembly] ${path}.part: \"${c.part}\" is not a member; members: [${memberNames.join(', ')}]`,\n )\n }\n return\n }\n\n // 世界锚定 unary(fixedPoint/fixedAxis/fixedRotation):a 是 EntityRef,part 是成员\n if (type === 'fixedPoint' || type === 'fixedAxis') {\n checkEntityRef(c.a, `${path}.a`, memberNames)\n checkVec3(type === 'fixedPoint' ? c.world : c.worldDir, type === 'fixedPoint' ? `${path}.world` : `${path}.worldDir`)\n return\n }\n if (type === 'fixedRotation') {\n if (typeof c.part !== 'string' || c.part.length === 0) {\n fail(`${path}.part`, 'a non-empty member name string', c.part)\n }\n if (!memberNames.includes(c.part)) {\n throw new Error(\n `[assembly] ${path}.part: \"${c.part}\" is not a member; members: [${memberNames.join(', ')}]`,\n )\n }\n return\n }\n\n // V2 + V4(a/b 每个都是 EntityRef)\n if (PAIRED_TYPES.has(type)) {\n checkEntityRef(c.a, `${path}.a`, memberNames)\n checkEntityRef(c.b, `${path}.b`, memberNames)\n }\n\n // V3:distance/angle 必须有有限数 value(不设区间,与 brepjs solveAngle 对齐)\n if (type === 'distance' || type === 'angle') {\n const v = c.value\n if (typeof v !== 'number' || !Number.isFinite(v)) {\n fail(`${path}.value`, 'a finite number', v)\n }\n }\n}\n\n/**\n * 校验 `cad.assembly({ constraints })` 的 constraints 参数(V1–V6)。\n * @param constraints - 未校验的 constraints 输入(脚本/宿主直传,可为任意值)。\n * @param memberNames - 成员名列表(来自成员的 nameOf 反查/显式 memberNames),V5 用。\n * @throws Error 首条违规即抛(fail-fast),文案含字段路径。\n * @returns 断言函数,通过后收窄 constraints 为 AssemblyConstraint[]。\n */\nexport function validateConstraints(\n constraints: unknown,\n memberNames: string[],\n): asserts constraints is AssemblyConstraint[] {\n if (!Array.isArray(constraints)) {\n fail('constraints', 'an array of constraint objects', constraints)\n }\n for (let i = 0; i < constraints.length; i++) {\n checkOne(constraints[i], i, memberNames)\n }\n}"]}
@@ -14,7 +14,7 @@
14
14
  */
15
15
  import { resolveSelection, resolveStepHandles } from './resolve.js';
16
16
  import { brepOf } from '../../shape.js';
17
- /** faijs BREP handle for a shape (numeric id space shared with occt-wasm). */
17
+ /** faijs BREP handle for a shape (engine-neutral handle id space). */
18
18
  function ownerHandle(shape) {
19
19
  return brepOf(shape);
20
20
  }
@@ -1 +1 @@
1
- {"version":3,"file":"edge.js","sourceRoot":"","sources":["../../../src/api/cadquery-selectors/edge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAA;AAChE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAGpC,8EAA8E;AAC9E,SAAS,WAAW,CAAC,KAAY;IAC/B,OAAO,MAAM,CAAC,KAAK,CAAY,CAAA;AACjC,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAY,EAAE,GAA8B;IAC/E,MAAM,MAAM,GAAG,GAAG,IAAI,EAAE,CAAA;IACxB,OAAO,kBAAkB,CAAC,WAAW,CAAC,KAAK,CAAU,EAAE,MAAM,EAAE,MAAM,CAAc,CAAA;AACrF,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,wBAAwB,CAAC,KAAY,EAAE,GAAW;IAChE,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAU,CAAA;IACzC,OAAO,gBAAgB,CAAC,KAAK,EAAE;QAC7B,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE;QACrB,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE;KAC1B,CAAC,CAAC,OAAoB,CAAA;AACzB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,sBAAsB,CAAC,KAAY,EAAE,GAA8B;IACjF,OAAO,kBAAkB,CAAC,WAAW,CAAC,KAAK,CAAU,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,CAAc,CAAA;AAC1F,CAAC","sourcesContent":["/**\n * cadquery-selectors/edge — CadQuery edge/vertex 选择器(hoild core 引擎 adapter)\n *\n * These are thin projections over the selector engine (plan §4.6). The heavy\n * lifting (direction rules, Nth clustering, set algebra, type filtering) lives\n * in `resolve.ts`; this file only bridges a faijs `Shape` into the engine's\n * kernel-handle space and adapts the result back to the cq-compat-consumed\n * `unknown[]` handle form.\n *\n * The legacy bbox-heuristic implementations (edn.g. `#Z` interpreted as \"max\n * along axis\", `|Z` from relative extents) were removed in favour of the\n * upstream `cadquery/selectors.py` semantics validated by\n * `selectors.test.ts`.\n */\nimport { resolveSelection, resolveStepHandles } from './resolve'\nimport { brepOf } from '../../shape'\nimport type { Shape } from '../../mesh/types'\n\n/** faijs BREP handle for a shape (numeric id space shared with occt-wasm). */\nfunction ownerHandle(shape: Shape): unknown {\n return brepOf(shape) as unknown\n}\n\n/**\n * Resolve a CadQuery EDGE selector string to concrete edge handles, using ONLY\n * the new selector engine (upstream `selectors.py` semantics):\n *\n * · `|Z` — ParallelDirSelector (edges whose tangent is parallel to the axis)\n * · `#Z` — PerpendicularDirSelector (edges whose tangent is perpendicular)\n * · `X` / `+X` / `-X` — DirectionSelector (signed tangent angle≈0)\n * · `>Z` / `<Z` — DirectionMinMaxSelector (extremal edge center along axis)\n * · `%LINE` / `%CIRCLE` — TypeSelector\n * · `and` / `or` / `except` / `not` — set algebra\n * · empty / missing — all edges (CadQuery `.edges()`)\n *\n * @param shape - Shape whose BREP edges are enumerated for selection.\n * @param sel - CadQuery edge selector, or empty/null/undefined for all edges.\n * @returns the matched edge handles (kernel identity space; cast to unknown).\n */\nexport function resolveEdgeSelection(shape: Shape, sel: string | null | undefined): unknown[] {\n const selStr = sel ?? ''\n return resolveStepHandles(ownerHandle(shape) as never, 'edge', selStr) as unknown[]\n}\n\n/**\n * Resolve the edges belonging to the face picked by `sel` — upstream\n * `.faces(\">Z\").edges()` semantics. The face selector runs first over the\n * face candidate set, then the survivors' edges are collected (chain widening\n * to edges, no filter): the selected face's own edges.\n *\n * @param shape - the shape whose BREP faces/edges are enumerated.\n * @param sel - a face direction / type selector (\">Z\", \"+Y\", \"%PLANE\", etc.).\n * @returns the handles of the edges belonging to the selected face(s).\n */\nexport function resolveFaceEdgeSelection(shape: Shape, sel: string): unknown[] {\n const owner = ownerHandle(shape) as never\n return resolveSelection(owner, [\n { kind: 'face', sel },\n { kind: 'edge', sel: '' },\n ]).handles as unknown[]\n}\n\n/**\n * Resolve a CadQuery vertex selector string to vertex handles (upstream `.vertices()`).\n * Mirrors the narrowing semantics of the engine: direction-less selectors drop,\n * cluster-based (`>`, `<`, `>>`, `<<`, `(x,y,z)`) apply.\n *\n * @param shape - the shape whose BREP vertices are enumerated.\n * @param sel - the vertex selector string, or empty/undefined for all vertices.\n * @returns the matched vertex handles.\n */\nexport function resolveVertexSelection(shape: Shape, sel: string | null | undefined): unknown[] {\n return resolveStepHandles(ownerHandle(shape) as never, 'vertex', sel ?? '') as unknown[]\n}"]}
1
+ {"version":3,"file":"edge.js","sourceRoot":"","sources":["../../../src/api/cadquery-selectors/edge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAA;AAChE,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAGpC,sEAAsE;AACtE,SAAS,WAAW,CAAC,KAAY;IAC/B,OAAO,MAAM,CAAC,KAAK,CAAY,CAAA;AACjC,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,oBAAoB,CAAC,KAAY,EAAE,GAA8B;IAC/E,MAAM,MAAM,GAAG,GAAG,IAAI,EAAE,CAAA;IACxB,OAAO,kBAAkB,CAAC,WAAW,CAAC,KAAK,CAAU,EAAE,MAAM,EAAE,MAAM,CAAc,CAAA;AACrF,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,wBAAwB,CAAC,KAAY,EAAE,GAAW;IAChE,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAU,CAAA;IACzC,OAAO,gBAAgB,CAAC,KAAK,EAAE;QAC7B,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE;QACrB,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,EAAE;KAC1B,CAAC,CAAC,OAAoB,CAAA;AACzB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,sBAAsB,CAAC,KAAY,EAAE,GAA8B;IACjF,OAAO,kBAAkB,CAAC,WAAW,CAAC,KAAK,CAAU,EAAE,QAAQ,EAAE,GAAG,IAAI,EAAE,CAAc,CAAA;AAC1F,CAAC","sourcesContent":["/**\n * cadquery-selectors/edge — CadQuery edge/vertex 选择器(hoild core 引擎 adapter)\n *\n * These are thin projections over the selector engine (plan §4.6). The heavy\n * lifting (direction rules, Nth clustering, set algebra, type filtering) lives\n * in `resolve.ts`; this file only bridges a faijs `Shape` into the engine's\n * kernel-handle space and adapts the result back to the cq-compat-consumed\n * `unknown[]` handle form.\n *\n * The legacy bbox-heuristic implementations (edn.g. `#Z` interpreted as \"max\n * along axis\", `|Z` from relative extents) were removed in favour of the\n * upstream `cadquery/selectors.py` semantics validated by\n * `selectors.test.ts`.\n */\nimport { resolveSelection, resolveStepHandles } from './resolve'\nimport { brepOf } from '../../shape'\nimport type { Shape } from '../../mesh/types'\n\n/** faijs BREP handle for a shape (engine-neutral handle id space). */\nfunction ownerHandle(shape: Shape): unknown {\n return brepOf(shape) as unknown\n}\n\n/**\n * Resolve a CadQuery EDGE selector string to concrete edge handles, using ONLY\n * the new selector engine (upstream `selectors.py` semantics):\n *\n * · `|Z` — ParallelDirSelector (edges whose tangent is parallel to the axis)\n * · `#Z` — PerpendicularDirSelector (edges whose tangent is perpendicular)\n * · `X` / `+X` / `-X` — DirectionSelector (signed tangent angle≈0)\n * · `>Z` / `<Z` — DirectionMinMaxSelector (extremal edge center along axis)\n * · `%LINE` / `%CIRCLE` — TypeSelector\n * · `and` / `or` / `except` / `not` — set algebra\n * · empty / missing — all edges (CadQuery `.edges()`)\n *\n * @param shape - Shape whose BREP edges are enumerated for selection.\n * @param sel - CadQuery edge selector, or empty/null/undefined for all edges.\n * @returns the matched edge handles (kernel identity space; cast to unknown).\n */\nexport function resolveEdgeSelection(shape: Shape, sel: string | null | undefined): unknown[] {\n const selStr = sel ?? ''\n return resolveStepHandles(ownerHandle(shape) as never, 'edge', selStr) as unknown[]\n}\n\n/**\n * Resolve the edges belonging to the face picked by `sel` — upstream\n * `.faces(\">Z\").edges()` semantics. The face selector runs first over the\n * face candidate set, then the survivors' edges are collected (chain widening\n * to edges, no filter): the selected face's own edges.\n *\n * @param shape - the shape whose BREP faces/edges are enumerated.\n * @param sel - a face direction / type selector (\">Z\", \"+Y\", \"%PLANE\", etc.).\n * @returns the handles of the edges belonging to the selected face(s).\n */\nexport function resolveFaceEdgeSelection(shape: Shape, sel: string): unknown[] {\n const owner = ownerHandle(shape) as never\n return resolveSelection(owner, [\n { kind: 'face', sel },\n { kind: 'edge', sel: '' },\n ]).handles as unknown[]\n}\n\n/**\n * Resolve a CadQuery vertex selector string to vertex handles (upstream `.vertices()`).\n * Mirrors the narrowing semantics of the engine: direction-less selectors drop,\n * cluster-based (`>`, `<`, `>>`, `<<`, `(x,y,z)`) apply.\n *\n * @param shape - the shape whose BREP vertices are enumerated.\n * @param sel - the vertex selector string, or empty/undefined for all vertices.\n * @returns the matched vertex handles.\n */\nexport function resolveVertexSelection(shape: Shape, sel: string | null | undefined): unknown[] {\n return resolveStepHandles(ownerHandle(shape) as never, 'vertex', sel ?? '') as unknown[]\n}"]}
@@ -18,11 +18,13 @@
18
18
  * type-agnostic. All quantities are computed lazily by the caller via the
19
19
  * projection object below.
20
20
  *
21
- * @platform occt — the projection resolves occt-wasm `ShapeHandle`s via the
22
- * native kernel (`getKernel()`: getSubShapes / hashCode / isSame / bounds /
23
- * surface & curve queries), so this module is occt-coupled by nature.
21
+ * @platform neutral — 2026-10-12 内核无关化:投影经 `getBrepApi()`(BrepEngineApi,
22
+ * 引擎中立)访问当前装配的 BREP 引擎,occt / brepkit 均可求值(双内核等价测试
23
+ * `test/api/cadquery-selectors/selectors-brepkit.test.ts` 钉住)。此前直连
24
+ * occt-wasm `getKernel()` 的 occt 耦合已移除。
24
25
  */
25
- import type { OcctKernel, ShapeHandle } from 'occt-wasm';
26
+ import type { BrepEngineApi } from '../../brep/engine/primitives.js';
27
+ import type { BrepHandle } from '../../brep/engine/types.js';
26
28
  /** Resolve the kernel geometry-kind → CadQuery LUT upcased name. */
27
29
  export interface GeomKindMap {
28
30
  surface: Record<string, string>;
@@ -31,6 +33,11 @@ export interface GeomKindMap {
31
33
  /**
32
34
  * Map a kernel surface-kind string to the CadQuery `geomType()` name.
33
35
  *
36
+ * 2026-10-12 大小写归一(双内核等价的前提):occt `surfaceType` 返回小写
37
+ * `'plane'`,brepkit 同为小写 `'plane'`;但 brepkit `curveType` 实测返回大写
38
+ * `'LINE'`(occt 为小写 `'line'`)——统一 `toLowerCase()` 后再查表,两内核
39
+ * 的 PLANE/LINE 谓词语义才一致(`selectors-brepkit.test.ts` 钉住)。
40
+ *
34
41
  * @param kind - The kernel surface kind (e.g. `plane`, `cylinder`, `torus`).
35
42
  * @returns The uppercased CadQuery geometry name, or `OTHER` when unmapped.
36
43
  */
@@ -38,6 +45,8 @@ export declare function faceGeomType(kind: string): string;
38
45
  /**
39
46
  * Map a kernel curve-kind string to the CadQuery `geomType()` name.
40
47
  *
48
+ * 大小写归一理由同 {@link faceGeomType}(brepkit 实测 `curveType` 返回大写)。
49
+ *
41
50
  * @param kind - The kernel curve kind (e.g. `line`, `circle`, `bspline`).
42
51
  * @returns The uppercased CadQuery geometry name, or `OTHER` when unmapped.
43
52
  */
@@ -54,7 +63,7 @@ export type P3 = {
54
63
  y: number;
55
64
  z: number;
56
65
  };
57
- export type { ShapeHandle };
66
+ export type { BrepHandle as ShapeHandle };
58
67
  /**
59
68
  * The lazily-evaluable geometry of one candidate entity. Predicates only access
60
69
  * the fields they need so the heavy computation (surface normal, etc.) is only
@@ -62,8 +71,8 @@ export type { ShapeHandle };
62
71
  */
63
72
  export interface EntityGeom {
64
73
  kind: 'face' | 'edge' | 'vertex';
65
- /** Internal kernel handle for identity comparison (not part of the public surface). */
66
- _handle: ShapeHandle;
74
+ /** Engine-neutral kernel handle for identity comparison (not part of the public surface). */
75
+ _handle: BrepHandle;
67
76
  /** Kernel handle box-identity hash (stable key across narrowing). */
68
77
  hash(): number;
69
78
  /** Kernel handle `isSame(...)` equality predicate. */
@@ -76,46 +85,46 @@ export interface EntityGeom {
76
85
  * tangent for an edge. Null for vertices (no usable direction, upstream
77
86
  * `BaseSelector` drops them).
78
87
  */
79
- direction(owner: ShapeHandle): P3 | null;
88
+ direction(owner: BrepHandle): P3 | null;
80
89
  /** Face/Edge geometry type (upcased LUT name), or undefined for vertices. */
81
90
  geomType(): string | undefined;
82
91
  }
83
92
  /**
84
93
  * Project a face handle into its `EntityGeom`.
85
94
  *
86
- * @param face - The kernel face handle to project.
95
+ * @param face - The engine face handle to project.
87
96
  * @returns The lazily-evaluable face geometry (normal oriented on demand).
88
97
  */
89
- export declare function faceGeom(face: ShapeHandle): EntityGeom;
98
+ export declare function faceGeom(face: BrepHandle): EntityGeom;
90
99
  /**
91
100
  * Orient a parametric face normal outward: offset probe → inside ⇒ flip.
92
101
  *
93
- * @param k - The active kernel instance used for surface/containment queries.
94
- * @param face - The kernel face handle whose normal is oriented.
102
+ * @param k - The active engine instance used for surface/containment queries.
103
+ * @param face - The engine face handle whose normal is oriented.
95
104
  * @param owner - The owning shape handle used for the containment probe.
96
105
  * @returns The outward-facing unit normal of `face`.
97
106
  */
98
- export declare function orientedFaceNormal(k: OcctKernel, face: ShapeHandle, owner: ShapeHandle): P3;
107
+ export declare function orientedFaceNormal(k: BrepEngineApi, face: BrepHandle, owner: BrepHandle): P3;
99
108
  /**
100
109
  * Project an edge handle into its `EntityGeom`.
101
110
  *
102
- * @param edge - The kernel edge handle to project.
111
+ * @param edge - The engine edge handle to project.
103
112
  * @returns The lazily-evaluable edge geometry (mid-parameter tangent).
104
113
  */
105
- export declare function edgeGeom(edge: ShapeHandle): EntityGeom;
114
+ export declare function edgeGeom(edge: BrepHandle): EntityGeom;
106
115
  /**
107
116
  * Project a vertex handle into its `EntityGeom`.
108
117
  *
109
- * @param vertex - The kernel vertex handle to project.
118
+ * @param vertex - The engine vertex handle to project.
110
119
  * @returns The lazily-evaluable vertex geometry (no direction / type).
111
120
  */
112
- export declare function vertexGeom(vertex: ShapeHandle): EntityGeom;
121
+ export declare function vertexGeom(vertex: BrepHandle): EntityGeom;
113
122
  /**
114
123
  * Get the sub-entity handles of the given topological type from a shape.
115
124
  *
116
- * @param shape - The kernel handle to query.
125
+ * @param shape - The engine handle to query.
117
126
  * @param type - The topological type to enumerate.
118
- * @returns The ordered kernel sub-shape handles of that type.
127
+ * @returns The ordered engine sub-shape handles of that type.
119
128
  */
120
- export declare function subShapeHandles(shape: ShapeHandle, type: 'face' | 'edge' | 'vertex'): ShapeHandle[];
129
+ export declare function subShapeHandles(shape: BrepHandle, type: 'face' | 'edge' | 'vertex'): BrepHandle[];
121
130
  //# sourceMappingURL=entity.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"entity.d.ts","sourceRoot":"","sources":["../../../src/api/cadquery-selectors/entity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAQ,MAAM,WAAW,CAAA;AAE9D,oEAAoE;AACpE,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC9B;AA2BD;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,mEAAmE;AACnE,MAAM,WAAW,YAAY;IAC3B,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;CACV;AAED,sDAAsD;AACtD,MAAM,MAAM,EAAE,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAEpD,YAAY,EAAE,WAAW,EAAE,CAAA;AAM3B;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAA;IAChC,uFAAuF;IACvF,OAAO,EAAE,WAAW,CAAA;IACpB,qEAAqE;IACrE,IAAI,IAAI,MAAM,CAAA;IACd,sDAAsD;IACtD,IAAI,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAA;IAChC,sDAAsD;IACtD,MAAM,IAAI,EAAE,CAAA;IACZ;;;;;OAKG;IACH,SAAS,CAAC,KAAK,EAAE,WAAW,GAAG,EAAE,GAAG,IAAI,CAAA;IACxC,6EAA6E;IAC7E,QAAQ,IAAI,MAAM,GAAG,SAAS,CAAA;CAC/B;AAID;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,WAAW,GAAG,UAAU,CAWtD;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,CAAC,EAAE,UAAU,EACb,IAAI,EAAE,WAAW,EACjB,KAAK,EAAE,WAAW,GACjB,EAAE,CAgBJ;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,WAAW,GAAG,UAAU,CAetD;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,UAAU,CAY1D;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,WAAW,EAAE,CAGnG"}
1
+ {"version":3,"file":"entity.d.ts","sourceRoot":"","sources":["../../../src/api/cadquery-selectors/entity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAA;AACjE,OAAO,KAAK,EAAE,UAAU,EAAY,MAAM,yBAAyB,CAAA;AAEnE,oEAAoE;AACpE,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAC9B;AA2BD;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEjD;AAED,mEAAmE;AACnE,MAAM,WAAW,YAAY;IAC3B,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;CACV;AAED,sDAAsD;AACtD,MAAM,MAAM,EAAE,GAAG;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAA;AAEpD,YAAY,EAAE,UAAU,IAAI,WAAW,EAAE,CAAA;AAMzC;;;;GAIG;AACH,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,QAAQ,CAAA;IAChC,6FAA6F;IAC7F,OAAO,EAAE,UAAU,CAAA;IACnB,qEAAqE;IACrE,IAAI,IAAI,MAAM,CAAA;IACd,sDAAsD;IACtD,IAAI,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAA;IAChC,sDAAsD;IACtD,MAAM,IAAI,EAAE,CAAA;IACZ;;;;;OAKG;IACH,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,EAAE,GAAG,IAAI,CAAA;IACvC,6EAA6E;IAC7E,QAAQ,IAAI,MAAM,GAAG,SAAS,CAAA;CAC/B;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAWrD;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,CAAC,EAAE,aAAa,EAChB,IAAI,EAAE,UAAU,EAChB,KAAK,EAAE,UAAU,GAChB,EAAE,CAgBJ;AAED;;;;;GAKG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,UAAU,GAAG,UAAU,CAerD;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,UAAU,CAYzD;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,QAAQ,GAAG,UAAU,EAAE,CAEjG"}
@@ -18,11 +18,12 @@
18
18
  * type-agnostic. All quantities are computed lazily by the caller via the
19
19
  * projection object below.
20
20
  *
21
- * @platform occt — the projection resolves occt-wasm `ShapeHandle`s via the
22
- * native kernel (`getKernel()`: getSubShapes / hashCode / isSame / bounds /
23
- * surface & curve queries), so this module is occt-coupled by nature.
21
+ * @platform neutral — 2026-10-12 内核无关化:投影经 `getBrepApi()`(BrepEngineApi,
22
+ * 引擎中立)访问当前装配的 BREP 引擎,occt / brepkit 均可求值(双内核等价测试
23
+ * `test/api/cadquery-selectors/selectors-brepkit.test.ts` 钉住)。此前直连
24
+ * occt-wasm `getKernel()` 的 occt 耦合已移除。
24
25
  */
25
- import { getKernel } from '../../occt-kernel/occtKernel.js';
26
+ import { getBrepApi } from '../../brep/handle-bridge.js';
26
27
  const NAMED_GEOM = {
27
28
  surface: {
28
29
  plane: 'PLANE',
@@ -50,39 +51,45 @@ const NAMED_GEOM = {
50
51
  /**
51
52
  * Map a kernel surface-kind string to the CadQuery `geomType()` name.
52
53
  *
54
+ * 2026-10-12 大小写归一(双内核等价的前提):occt `surfaceType` 返回小写
55
+ * `'plane'`,brepkit 同为小写 `'plane'`;但 brepkit `curveType` 实测返回大写
56
+ * `'LINE'`(occt 为小写 `'line'`)——统一 `toLowerCase()` 后再查表,两内核
57
+ * 的 PLANE/LINE 谓词语义才一致(`selectors-brepkit.test.ts` 钉住)。
58
+ *
53
59
  * @param kind - The kernel surface kind (e.g. `plane`, `cylinder`, `torus`).
54
60
  * @returns The uppercased CadQuery geometry name, or `OTHER` when unmapped.
55
61
  */
56
62
  export function faceGeomType(kind) {
57
- return NAMED_GEOM.surface[kind] ?? 'OTHER';
63
+ return NAMED_GEOM.surface[String(kind).toLowerCase()] ?? 'OTHER';
58
64
  }
59
65
  /**
60
66
  * Map a kernel curve-kind string to the CadQuery `geomType()` name.
61
67
  *
68
+ * 大小写归一理由同 {@link faceGeomType}(brepkit 实测 `curveType` 返回大写)。
69
+ *
62
70
  * @param kind - The kernel curve kind (e.g. `line`, `circle`, `bspline`).
63
71
  * @returns The uppercased CadQuery geometry name, or `OTHER` when unmapped.
64
72
  */
65
73
  export function edgeGeomType(kind) {
66
- return NAMED_GEOM.curve[kind] ?? 'OTHER';
74
+ return NAMED_GEOM.curve[String(kind).toLowerCase()] ?? 'OTHER';
67
75
  }
68
76
  function v(v) {
69
77
  return { x: v.x, y: v.y, z: v.z };
70
78
  }
71
- const kern = () => getKernel();
72
79
  /**
73
80
  * Project a face handle into its `EntityGeom`.
74
81
  *
75
- * @param face - The kernel face handle to project.
82
+ * @param face - The engine face handle to project.
76
83
  * @returns The lazily-evaluable face geometry (normal oriented on demand).
77
84
  */
78
85
  export function faceGeom(face) {
79
- const k = kern();
86
+ const k = getBrepApi();
80
87
  return {
81
88
  kind: 'face',
82
89
  _handle: face,
83
90
  hash: () => k.hashCode(face, 1e9),
84
91
  same: (other) => k.isSame(face, other._handle),
85
- center: () => v(k.getSurfaceCenterOfMass(face)),
92
+ center: () => v(k.surfaceCenterOfMass(face)),
86
93
  direction: (owner) => orientedFaceNormal(k, face, owner),
87
94
  geomType: () => faceGeomType(k.surfaceType(face)),
88
95
  };
@@ -90,8 +97,8 @@ export function faceGeom(face) {
90
97
  /**
91
98
  * Orient a parametric face normal outward: offset probe → inside ⇒ flip.
92
99
  *
93
- * @param k - The active kernel instance used for surface/containment queries.
94
- * @param face - The kernel face handle whose normal is oriented.
100
+ * @param k - The active engine instance used for surface/containment queries.
101
+ * @param face - The engine face handle whose normal is oriented.
95
102
  * @param owner - The owning shape handle used for the containment probe.
96
103
  * @returns The outward-facing unit normal of `face`.
97
104
  */
@@ -115,11 +122,11 @@ export function orientedFaceNormal(k, face, owner) {
115
122
  /**
116
123
  * Project an edge handle into its `EntityGeom`.
117
124
  *
118
- * @param edge - The kernel edge handle to project.
125
+ * @param edge - The engine edge handle to project.
119
126
  * @returns The lazily-evaluable edge geometry (mid-parameter tangent).
120
127
  */
121
128
  export function edgeGeom(edge) {
122
- const k = kern();
129
+ const k = getBrepApi();
123
130
  const midParams = () => {
124
131
  const cp = k.curveParameters(edge);
125
132
  return (cp.first + cp.last) / 2;
@@ -137,11 +144,11 @@ export function edgeGeom(edge) {
137
144
  /**
138
145
  * Project a vertex handle into its `EntityGeom`.
139
146
  *
140
- * @param vertex - The kernel vertex handle to project.
147
+ * @param vertex - The engine vertex handle to project.
141
148
  * @returns The lazily-evaluable vertex geometry (no direction / type).
142
149
  */
143
150
  export function vertexGeom(vertex) {
144
- const k = kern();
151
+ const k = getBrepApi();
145
152
  const p = k.vertexPosition(vertex);
146
153
  return {
147
154
  kind: 'vertex',
@@ -156,12 +163,11 @@ export function vertexGeom(vertex) {
156
163
  /**
157
164
  * Get the sub-entity handles of the given topological type from a shape.
158
165
  *
159
- * @param shape - The kernel handle to query.
166
+ * @param shape - The engine handle to query.
160
167
  * @param type - The topological type to enumerate.
161
- * @returns The ordered kernel sub-shape handles of that type.
168
+ * @returns The ordered engine sub-shape handles of that type.
162
169
  */
163
170
  export function subShapeHandles(shape, type) {
164
- const k = kern();
165
- return k.getSubShapes(shape, type);
171
+ return getBrepApi().getSubShapes(shape, type);
166
172
  }
167
173
  //# sourceMappingURL=entity.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"entity.js","sourceRoot":"","sources":["../../../src/api/cadquery-selectors/entity.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * cadquery-selectors/entity — projection of kernel handles into the geometric\n * quantities the selector predicates need.\n *\n * Each helper mirrors the CadQuery shape method it stands in for (plan §4.3):\n * · `Vertex.Center()` → vertex position\n * · `Edge.Center()` → linear centre of mass (LinearProperties centroid)\n * · `Face.Center()` → surface centre of mass (SurfaceProperties centroid)\n * · `Face.normalAt(None)` → parametric surface normal at the uv midpoint,\n * oriented outward via `containsPoint` on the owner\n * · `Edge.tangentAt()` → curve tangent at the parameter midpoint,\n * oriented along the edge parameter direction\n * · `Face/Edge.geomType()` → kernel surface/curve kind mapped to the CadQuery\n * geom_LUT uppercased names\n *\n * These are deliberately decoupled from any single entity type so the\n * predicates (predicates.ts) and the narrowing engine (resolve.ts) stay\n * type-agnostic. All quantities are computed lazily by the caller via the\n * projection object below.\n *\n * @platform occt — the projection resolves occt-wasm `ShapeHandle`s via the\n * native kernel (`getKernel()`: getSubShapes / hashCode / isSame / bounds /\n * surface & curve queries), so this module is occt-coupled by nature.\n */\n\nimport { getKernel } from '../../occt-kernel/occtKernel'\nimport type { OcctKernel, ShapeHandle, Vec3 } from 'occt-wasm'\n\n/** Resolve the kernel geometry-kind → CadQuery LUT upcased name. */\nexport interface GeomKindMap {\n surface: Record<string, string>\n curve: Record<string, string>\n}\n\nconst NAMED_GEOM: { surface: Record<string, string>; curve: Record<string, string> } = {\n surface: {\n plane: 'PLANE',\n cylinder: 'CYLINDER',\n cone: 'CONE',\n sphere: 'SPHERE',\n torus: 'TORUS',\n bspline: 'BSPLINE',\n bezier: 'BEZIER',\n offset: 'OFFSET',\n revolution: 'REVOLUTION',\n extrusion: 'EXTRUSION',\n },\n curve: {\n line: 'LINE',\n circle: 'CIRCLE',\n ellipse: 'ELLIPSE',\n hyperbola: 'HYPERBOLA',\n parabola: 'PARABOLA',\n bspline: 'BSPLINE',\n bezier: 'BEZIER',\n offset: 'OFFSET',\n },\n}\n\n/**\n * Map a kernel surface-kind string to the CadQuery `geomType()` name.\n *\n * @param kind - The kernel surface kind (e.g. `plane`, `cylinder`, `torus`).\n * @returns The uppercased CadQuery geometry name, or `OTHER` when unmapped.\n */\nexport function faceGeomType(kind: string): string {\n return NAMED_GEOM.surface[kind] ?? 'OTHER'\n}\n\n/**\n * Map a kernel curve-kind string to the CadQuery `geomType()` name.\n *\n * @param kind - The kernel curve kind (e.g. `line`, `circle`, `bspline`).\n * @returns The uppercased CadQuery geometry name, or `OTHER` when unmapped.\n */\nexport function edgeGeomType(kind: string): string {\n return NAMED_GEOM.curve[kind] ?? 'OTHER'\n}\n\n/** World-space cartesian coordinates of an entity center point. */\nexport interface EntityCenter {\n x: number\n y: number\n z: number\n}\n\n/** Plain 3-D vector in faijs' internal convention. */\nexport type P3 = { x: number; y: number; z: number }\n\nexport type { ShapeHandle }\n\nfunction v(v: Vec3 | P3): P3 {\n return { x: v.x, y: v.y, z: v.z }\n}\n\n/**\n * The lazily-evaluable geometry of one candidate entity. Predicates only access\n * the fields they need so the heavy computation (surface normal, etc.) is only\n * paid for when a direction/parallel filter is actually applied.\n */\nexport interface EntityGeom {\n kind: 'face' | 'edge' | 'vertex'\n /** Internal kernel handle for identity comparison (not part of the public surface). */\n _handle: ShapeHandle\n /** Kernel handle box-identity hash (stable key across narrowing). */\n hash(): number\n /** Kernel handle `isSame(...)` equality predicate. */\n same(other: EntityGeom): boolean\n /** CadQuery `Shape.Center()` for this entity kind. */\n center(): P3\n /**\n * The direction used by direction-motivated selectors: the outward normal for\n * a face (requires the owning shape for orientation) or the mid-parameter\n * tangent for an edge. Null for vertices (no usable direction, upstream\n * `BaseSelector` drops them).\n */\n direction(owner: ShapeHandle): P3 | null\n /** Face/Edge geometry type (upcased LUT name), or undefined for vertices. */\n geomType(): string | undefined\n}\n\nconst kern = (): OcctKernel => getKernel() as unknown as OcctKernel\n\n/**\n * Project a face handle into its `EntityGeom`.\n *\n * @param face - The kernel face handle to project.\n * @returns The lazily-evaluable face geometry (normal oriented on demand).\n */\nexport function faceGeom(face: ShapeHandle): EntityGeom {\n const k = kern()\n return {\n kind: 'face',\n _handle: face,\n hash: () => k.hashCode(face, 1e9),\n same: (other: EntityGeom) => k.isSame(face, other._handle),\n center: () => v(k.getSurfaceCenterOfMass(face)),\n direction: (owner: ShapeHandle) => orientedFaceNormal(k, face, owner),\n geomType: () => faceGeomType(k.surfaceType(face)),\n }\n}\n\n/**\n * Orient a parametric face normal outward: offset probe → inside ⇒ flip.\n *\n * @param k - The active kernel instance used for surface/containment queries.\n * @param face - The kernel face handle whose normal is oriented.\n * @param owner - The owning shape handle used for the containment probe.\n * @returns The outward-facing unit normal of `face`.\n */\nexport function orientedFaceNormal(\n k: OcctKernel,\n face: ShapeHandle,\n owner: ShapeHandle,\n): P3 {\n const uv = k.uvBounds(face)\n const u = (uv.uMin + uv.uMax) / 2\n const vv = (uv.vMin + uv.vMax) / 2\n const n = k.surfaceNormal(face, u, vv)\n const db = k.getBoundingBox(face)\n const ext = [db.xmax - db.xmin, db.ymax - db.ymin, db.zmax - db.zmin]\n const minExt = Math.min(...ext, 1)\n const eps = minExt * 1e-3 + 1e-6\n const center = k.pointOnSurface(face, u, vv)\n const probe = { x: center.x + n.x * eps, y: center.y + n.y * eps, z: center.z + n.z * eps }\n // inside owner ⇒ the candidate normal points inward, so flip it.\n if (k.containsPoint(owner, probe, 1e-9)) {\n return { x: -n.x, y: -n.y, z: -n.z }\n }\n return v(n)\n}\n\n/**\n * Project an edge handle into its `EntityGeom`.\n *\n * @param edge - The kernel edge handle to project.\n * @returns The lazily-evaluable edge geometry (mid-parameter tangent).\n */\nexport function edgeGeom(edge: ShapeHandle): EntityGeom {\n const k = kern()\n const midParams = () => {\n const cp = k.curveParameters(edge)\n return (cp.first + cp.last) / 2\n }\n return {\n kind: 'edge',\n _handle: edge,\n hash: () => k.hashCode(edge, 1e9),\n same: (other: EntityGeom) => k.isSame(edge, other._handle),\n center: () => v(k.curvePointAtParam(edge, midParams())),\n direction: () => v(k.curveTangent(edge, midParams())),\n geomType: () => edgeGeomType(k.curveType(edge)),\n }\n}\n\n/**\n * Project a vertex handle into its `EntityGeom`.\n *\n * @param vertex - The kernel vertex handle to project.\n * @returns The lazily-evaluable vertex geometry (no direction / type).\n */\nexport function vertexGeom(vertex: ShapeHandle): EntityGeom {\n const k = kern()\n const p = k.vertexPosition(vertex)\n return {\n kind: 'vertex',\n _handle: vertex,\n hash: () => k.hashCode(vertex, 1e9),\n same: (other: EntityGeom) => k.isSame(vertex, other._handle),\n center: () => v(p),\n direction: () => null,\n geomType: () => undefined,\n }\n}\n\n/**\n * Get the sub-entity handles of the given topological type from a shape.\n *\n * @param shape - The kernel handle to query.\n * @param type - The topological type to enumerate.\n * @returns The ordered kernel sub-shape handles of that type.\n */\nexport function subShapeHandles(shape: ShapeHandle, type: 'face' | 'edge' | 'vertex'): ShapeHandle[] {\n const k = kern()\n return k.getSubShapes(shape, type) as ShapeHandle[]\n}"]}
1
+ {"version":3,"file":"entity.js","sourceRoot":"","sources":["../../../src/api/cadquery-selectors/entity.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * cadquery-selectors/entity — projection of kernel handles into the geometric\n * quantities the selector predicates need.\n *\n * Each helper mirrors the CadQuery shape method it stands in for (plan §4.3):\n * · `Vertex.Center()` → vertex position\n * · `Edge.Center()` → linear centre of mass (LinearProperties centroid)\n * · `Face.Center()` → surface centre of mass (SurfaceProperties centroid)\n * · `Face.normalAt(None)` → parametric surface normal at the uv midpoint,\n * oriented outward via `containsPoint` on the owner\n * · `Edge.tangentAt()` → curve tangent at the parameter midpoint,\n * oriented along the edge parameter direction\n * · `Face/Edge.geomType()` → kernel surface/curve kind mapped to the CadQuery\n * geom_LUT uppercased names\n *\n * These are deliberately decoupled from any single entity type so the\n * predicates (predicates.ts) and the narrowing engine (resolve.ts) stay\n * type-agnostic. All quantities are computed lazily by the caller via the\n * projection object below.\n *\n * @platform neutral — 2026-10-12 内核无关化:投影经 `getBrepApi()`(BrepEngineApi,\n * 引擎中立)访问当前装配的 BREP 引擎,occt / brepkit 均可求值(双内核等价测试\n * `test/api/cadquery-selectors/selectors-brepkit.test.ts` 钉住)。此前直连\n * occt-wasm `getKernel()` 的 occt 耦合已移除。\n */\n\nimport { getBrepApi } from '../../brep/handle-bridge'\nimport type { BrepEngineApi } from '../../brep/engine/primitives'\nimport type { BrepHandle, BrepVec3 } from '../../brep/engine/types'\n\n/** Resolve the kernel geometry-kind → CadQuery LUT upcased name. */\nexport interface GeomKindMap {\n surface: Record<string, string>\n curve: Record<string, string>\n}\n\nconst NAMED_GEOM: { surface: Record<string, string>; curve: Record<string, string> } = {\n surface: {\n plane: 'PLANE',\n cylinder: 'CYLINDER',\n cone: 'CONE',\n sphere: 'SPHERE',\n torus: 'TORUS',\n bspline: 'BSPLINE',\n bezier: 'BEZIER',\n offset: 'OFFSET',\n revolution: 'REVOLUTION',\n extrusion: 'EXTRUSION',\n },\n curve: {\n line: 'LINE',\n circle: 'CIRCLE',\n ellipse: 'ELLIPSE',\n hyperbola: 'HYPERBOLA',\n parabola: 'PARABOLA',\n bspline: 'BSPLINE',\n bezier: 'BEZIER',\n offset: 'OFFSET',\n },\n}\n\n/**\n * Map a kernel surface-kind string to the CadQuery `geomType()` name.\n *\n * 2026-10-12 大小写归一(双内核等价的前提):occt `surfaceType` 返回小写\n * `'plane'`,brepkit 同为小写 `'plane'`;但 brepkit `curveType` 实测返回大写\n * `'LINE'`(occt 为小写 `'line'`)——统一 `toLowerCase()` 后再查表,两内核\n * 的 PLANE/LINE 谓词语义才一致(`selectors-brepkit.test.ts` 钉住)。\n *\n * @param kind - The kernel surface kind (e.g. `plane`, `cylinder`, `torus`).\n * @returns The uppercased CadQuery geometry name, or `OTHER` when unmapped.\n */\nexport function faceGeomType(kind: string): string {\n return NAMED_GEOM.surface[String(kind).toLowerCase()] ?? 'OTHER'\n}\n\n/**\n * Map a kernel curve-kind string to the CadQuery `geomType()` name.\n *\n * 大小写归一理由同 {@link faceGeomType}(brepkit 实测 `curveType` 返回大写)。\n *\n * @param kind - The kernel curve kind (e.g. `line`, `circle`, `bspline`).\n * @returns The uppercased CadQuery geometry name, or `OTHER` when unmapped.\n */\nexport function edgeGeomType(kind: string): string {\n return NAMED_GEOM.curve[String(kind).toLowerCase()] ?? 'OTHER'\n}\n\n/** World-space cartesian coordinates of an entity center point. */\nexport interface EntityCenter {\n x: number\n y: number\n z: number\n}\n\n/** Plain 3-D vector in faijs' internal convention. */\nexport type P3 = { x: number; y: number; z: number }\n\nexport type { BrepHandle as ShapeHandle }\n\nfunction v(v: BrepVec3 | P3): P3 {\n return { x: v.x, y: v.y, z: v.z }\n}\n\n/**\n * The lazily-evaluable geometry of one candidate entity. Predicates only access\n * the fields they need so the heavy computation (surface normal, etc.) is only\n * paid for when a direction/parallel filter is actually applied.\n */\nexport interface EntityGeom {\n kind: 'face' | 'edge' | 'vertex'\n /** Engine-neutral kernel handle for identity comparison (not part of the public surface). */\n _handle: BrepHandle\n /** Kernel handle box-identity hash (stable key across narrowing). */\n hash(): number\n /** Kernel handle `isSame(...)` equality predicate. */\n same(other: EntityGeom): boolean\n /** CadQuery `Shape.Center()` for this entity kind. */\n center(): P3\n /**\n * The direction used by direction-motivated selectors: the outward normal for\n * a face (requires the owning shape for orientation) or the mid-parameter\n * tangent for an edge. Null for vertices (no usable direction, upstream\n * `BaseSelector` drops them).\n */\n direction(owner: BrepHandle): P3 | null\n /** Face/Edge geometry type (upcased LUT name), or undefined for vertices. */\n geomType(): string | undefined\n}\n\n/**\n * Project a face handle into its `EntityGeom`.\n *\n * @param face - The engine face handle to project.\n * @returns The lazily-evaluable face geometry (normal oriented on demand).\n */\nexport function faceGeom(face: BrepHandle): EntityGeom {\n const k = getBrepApi()\n return {\n kind: 'face',\n _handle: face,\n hash: () => k.hashCode(face, 1e9),\n same: (other: EntityGeom) => k.isSame(face, other._handle),\n center: () => v(k.surfaceCenterOfMass(face)),\n direction: (owner: BrepHandle) => orientedFaceNormal(k, face, owner),\n geomType: () => faceGeomType(k.surfaceType(face)),\n }\n}\n\n/**\n * Orient a parametric face normal outward: offset probe → inside ⇒ flip.\n *\n * @param k - The active engine instance used for surface/containment queries.\n * @param face - The engine face handle whose normal is oriented.\n * @param owner - The owning shape handle used for the containment probe.\n * @returns The outward-facing unit normal of `face`.\n */\nexport function orientedFaceNormal(\n k: BrepEngineApi,\n face: BrepHandle,\n owner: BrepHandle,\n): P3 {\n const uv = k.uvBounds(face)\n const u = (uv.uMin + uv.uMax) / 2\n const vv = (uv.vMin + uv.vMax) / 2\n const n = k.surfaceNormal(face, u, vv)\n const db = k.getBoundingBox(face)\n const ext = [db.xmax - db.xmin, db.ymax - db.ymin, db.zmax - db.zmin]\n const minExt = Math.min(...ext, 1)\n const eps = minExt * 1e-3 + 1e-6\n const center = k.pointOnSurface(face, u, vv)\n const probe = { x: center.x + n.x * eps, y: center.y + n.y * eps, z: center.z + n.z * eps }\n // inside owner ⇒ the candidate normal points inward, so flip it.\n if (k.containsPoint(owner, probe, 1e-9)) {\n return { x: -n.x, y: -n.y, z: -n.z }\n }\n return v(n)\n}\n\n/**\n * Project an edge handle into its `EntityGeom`.\n *\n * @param edge - The engine edge handle to project.\n * @returns The lazily-evaluable edge geometry (mid-parameter tangent).\n */\nexport function edgeGeom(edge: BrepHandle): EntityGeom {\n const k = getBrepApi()\n const midParams = () => {\n const cp = k.curveParameters(edge)\n return (cp.first + cp.last) / 2\n }\n return {\n kind: 'edge',\n _handle: edge,\n hash: () => k.hashCode(edge, 1e9),\n same: (other: EntityGeom) => k.isSame(edge, other._handle),\n center: () => v(k.curvePointAtParam(edge, midParams())),\n direction: () => v(k.curveTangent(edge, midParams())),\n geomType: () => edgeGeomType(k.curveType(edge)),\n }\n}\n\n/**\n * Project a vertex handle into its `EntityGeom`.\n *\n * @param vertex - The engine vertex handle to project.\n * @returns The lazily-evaluable vertex geometry (no direction / type).\n */\nexport function vertexGeom(vertex: BrepHandle): EntityGeom {\n const k = getBrepApi()\n const p = k.vertexPosition(vertex)\n return {\n kind: 'vertex',\n _handle: vertex,\n hash: () => k.hashCode(vertex, 1e9),\n same: (other: EntityGeom) => k.isSame(vertex, other._handle),\n center: () => v(p),\n direction: () => null,\n geomType: () => undefined,\n }\n}\n\n/**\n * Get the sub-entity handles of the given topological type from a shape.\n *\n * @param shape - The engine handle to query.\n * @param type - The topological type to enumerate.\n * @returns The ordered engine sub-shape handles of that type.\n */\nexport function subShapeHandles(shape: BrepHandle, type: 'face' | 'edge' | 'vertex'): BrepHandle[] {\n return getBrepApi().getSubShapes(shape, type)\n}"]}