@faicad/fai-cq-gears 0.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/dist/bevel_gear.d.ts +113 -0
  2. package/dist/bevel_gear.d.ts.map +1 -0
  3. package/dist/bevel_gear.js +327 -0
  4. package/dist/bevel_gear.js.map +1 -0
  5. package/dist/crossed_helical_gear.d.ts +24 -0
  6. package/dist/crossed_helical_gear.d.ts.map +1 -0
  7. package/dist/crossed_helical_gear.js +24 -0
  8. package/dist/crossed_helical_gear.js.map +1 -0
  9. package/dist/crossed_pair.d.ts +177 -0
  10. package/dist/crossed_pair.d.ts.map +1 -0
  11. package/dist/crossed_pair.js +237 -0
  12. package/dist/crossed_pair.js.map +1 -0
  13. package/dist/features.d.ts +184 -0
  14. package/dist/features.d.ts.map +1 -0
  15. package/dist/features.js +408 -0
  16. package/dist/features.js.map +1 -0
  17. package/dist/index.d.ts +178 -0
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/index.js +223 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/math.d.ts +200 -0
  22. package/dist/math.d.ts.map +1 -0
  23. package/dist/math.js +274 -0
  24. package/dist/math.js.map +1 -0
  25. package/dist/pairs.d.ts +161 -0
  26. package/dist/pairs.d.ts.map +1 -0
  27. package/dist/pairs.js +183 -0
  28. package/dist/pairs.js.map +1 -0
  29. package/dist/planetary.d.ts +96 -0
  30. package/dist/planetary.d.ts.map +1 -0
  31. package/dist/planetary.js +139 -0
  32. package/dist/planetary.js.map +1 -0
  33. package/dist/profile.d.ts +439 -0
  34. package/dist/profile.d.ts.map +1 -0
  35. package/dist/profile.js +592 -0
  36. package/dist/profile.js.map +1 -0
  37. package/dist/rack_gear.d.ts +125 -0
  38. package/dist/rack_gear.d.ts.map +1 -0
  39. package/dist/rack_gear.js +344 -0
  40. package/dist/rack_gear.js.map +1 -0
  41. package/dist/ring_gear.d.ts +54 -0
  42. package/dist/ring_gear.d.ts.map +1 -0
  43. package/dist/ring_gear.js +133 -0
  44. package/dist/ring_gear.js.map +1 -0
  45. package/dist/spline-face.d.ts +99 -0
  46. package/dist/spline-face.d.ts.map +1 -0
  47. package/dist/spline-face.js +94 -0
  48. package/dist/spline-face.js.map +1 -0
  49. package/dist/spur_gear.d.ts +112 -0
  50. package/dist/spur_gear.d.ts.map +1 -0
  51. package/dist/spur_gear.js +206 -0
  52. package/dist/spur_gear.js.map +1 -0
  53. package/dist/worm_gear.d.ts +78 -0
  54. package/dist/worm_gear.d.ts.map +1 -0
  55. package/dist/worm_gear.js +256 -0
  56. package/dist/worm_gear.js.map +1 -0
  57. package/package.json +47 -0
@@ -0,0 +1,133 @@
1
+ /**
2
+ * ring_gear — RingGear(内部齿)实体构造
3
+ *
4
+ * 对应 `RingGear._build_gear_faces()` + `_build_rim_face()` + `_build()`:
5
+ *
6
+ * ```
7
+ * ① 4z 个齿面(复用 SpurGear 的 `buildToothFaces`,因为点集布局一致)
8
+ * ② 外圈 rim:两圈圆环 wire(z=0 / z=width)经 `loft(ruled=true)` 蒙成圆柱面
9
+ * ③ 顶/底面:在 z=width / z=0 收齿面边界边 → 组线成内孔 wire,
10
+ * 再用 `Face.makeFromWires(rimWire, [toothWire])` 做成**环形**盖面(外圆 rim_r、内孔齿廓)
11
+ * ④ sew(齿面 + rim + 2 盖面) → makeSolid → fixFaceOrientations
12
+ * ```
13
+ *
14
+ * 与 SpurGear 的关键差异:端面是**环形**(外 rim 圆 + 内齿廓孔),不是实心圆盘;
15
+ * 多了外圈 rim 圆柱面。倒角(chamfer)/ 轴孔(bore)属于 `_make_chamfer` / `_make_bore`,
16
+ * 在 sew 之后以旋转体 cutter 布尔差实现(见 `features.ts`,A1 已验证几何),
17
+ * 由 `BuildRingGearOptions.chamfer` / `boreD` 驱动。
18
+ */
19
+ import { ringGearGeometry, GEAR_BASE_CONSTANTS } from './profile.js';
20
+ import { DEFAULT_SPLINE_FACE_STRATEGY, soleFace, } from './spline-face.js';
21
+ import { buildToothFaces, buildHerringboneToothFaces } from './spur_gear.js';
22
+ import { connectEdgesToWires, gearFaceFromWires as faceFromWires } from '@faicad/cq-compat';
23
+ import { applyChamfer, applyBore, } from './features.js';
24
+ /** 判定「边是否落在某个 z 平面上」的容差(远小于 wire_comb_tol)。 */
25
+ const PLANAR_PICK_TOL = 1e-6;
26
+ /**
27
+ * 一个半径 `radius`、圆心在 `(0,0,z)`、法向 +Z 的整圆 wire。
28
+ *
29
+ * @param kernel 原始 OCCT 内核
30
+ * @param radius 圆半径
31
+ * @param z 圆所在高度
32
+ * @returns 闭合圆 wire
33
+ */
34
+ function circleWire(kernel, radius, z) {
35
+ const arc = kernel.makeCircleArc({ x: 0, y: 0, z }, { x: 0, y: 0, z: 1 }, radius, 0, Math.PI * 2);
36
+ return kernel.makeWire([arc]);
37
+ }
38
+ /**
39
+ * 外圈 rim 圆柱面(cq `Face.makeRuledSurface(w1, w2)` 的等价物)。
40
+ *
41
+ * @param kernel 原始 OCCT 内核
42
+ * @param rimR 外圈半径(`rd + rim_width`)
43
+ * @param width 齿宽
44
+ * @returns 圆柱侧面(Face)
45
+ */
46
+ function buildRimFace(kernel, rimR, width) {
47
+ const w0 = circleWire(kernel, rimR, 0);
48
+ const w1 = circleWire(kernel, rimR, width);
49
+ // `loft(wires, isSolid=false, ruled=true)` 在两圈之间蒙出 ruled 圆柱面
50
+ return soleFace(kernel, kernel.loft([w0, w1], false, true));
51
+ }
52
+ /**
53
+ * 在高度 `z` 收齿面边界边 → 组线成内孔 wire,与外圈 rim 圆合成**环形**盖面。
54
+ *
55
+ * @param kernel 原始 OCCT 内核
56
+ * @param toothFaces 全部齿面(含 z 向厚度)
57
+ * @param rimR 外圈半径
58
+ * @param z 目标平面高度
59
+ * @param wireCombTol 组线容差(mm)
60
+ * @returns 环形盖面(外 rim 圆、内齿廓孔)
61
+ */
62
+ function ringCapAtZ(kernel, toothFaces, rimR, z, wireCombTol) {
63
+ const edges = [];
64
+ for (const f of toothFaces) {
65
+ for (const e of kernel.getSubShapes(f, 'edge')) {
66
+ const bb = kernel.getBoundingBox(e);
67
+ if (Math.abs(bb.zmin - z) <= PLANAR_PICK_TOL && Math.abs(bb.zmax - z) <= PLANAR_PICK_TOL) {
68
+ edges.push(e);
69
+ }
70
+ }
71
+ }
72
+ if (edges.length === 0) {
73
+ throw new Error(`ringCapAtZ: no tooth boundary edges found at z=${z}`);
74
+ }
75
+ const toothWires = connectEdgesToWires(kernel, edges, wireCombTol ?? GEAR_BASE_CONSTANTS.wire_comb_tol);
76
+ if (toothWires.length !== 1) {
77
+ throw new Error(`ringCapAtZ: expected one closed tooth-profile loop at z=${z}, got ${toothWires.length} wires from ${edges.length} edges`);
78
+ }
79
+ const rimWire = circleWire(kernel, rimR, z);
80
+ return faceFromWires(kernel, rimWire, [toothWires[0]]);
81
+ }
82
+ /** ①–④:完整 RingGear 实体(内部齿,非倒角)。
83
+ *
84
+ * @param kernel 原始 OCCT 内核
85
+ * @param params 齿轮参数
86
+ * @param build 构造选项(策略/容差覆盖)
87
+ * @returns 朝向归一化后的 solid
88
+ */
89
+ export function buildRingGearSolid(kernel, params, build = {}) {
90
+ const strategy = build.strategy ?? DEFAULT_SPLINE_FACE_STRATEGY;
91
+ const geom = ringGearGeometry(params);
92
+ const toothFaces = build.herringbone
93
+ ? buildHerringboneToothFaces(kernel, geom, strategy, build)
94
+ : buildToothFaces(kernel, geom, strategy, build);
95
+ const rimR = geom.rd + params.rim_width;
96
+ const rimFace = buildRimFace(kernel, rimR, geom.width);
97
+ const top = ringCapAtZ(kernel, toothFaces, rimR, geom.width, build.wireCombTol);
98
+ const bottom = ringCapAtZ(kernel, toothFaces, rimR, 0, build.wireCombTol);
99
+ const all = [...toothFaces, rimFace, top, bottom];
100
+ const shell = kernel.sew(all, build.shellSewingTol ?? GEAR_BASE_CONSTANTS.shell_sewing_tol);
101
+ const solid = kernel.makeSolid(shell);
102
+ const oriented = kernel.fixFaceOrientations(solid);
103
+ if (!kernel.isSolid(oriented)) {
104
+ throw new Error(`buildRingGearSolid: result is not a solid (got ${String(kernel.getShapeType(oriented))})`);
105
+ }
106
+ // 镀铬特征(倒角 / 轴孔):cq RingGear `_make_chamfer` 用内齿版 cutter 轮廓(isRing=true)。
107
+ let result = oriented;
108
+ if (build.chamfer !== undefined || build.chamferTop !== undefined || build.chamferBottom !== undefined) {
109
+ result = applyChamfer(kernel, result, geom.ra, geom.width, build, true);
110
+ }
111
+ if (build.boreD !== undefined) {
112
+ result = applyBore(kernel, result, build.boreD, geom.width);
113
+ }
114
+ if (!kernel.isSolid(result)) {
115
+ throw new Error(`buildRingGearSolid: result is not a solid after features (got ${String(kernel.getShapeType(result))})`);
116
+ }
117
+ return result;
118
+ }
119
+ /** ①–④:完整 HerringboneRingGear 实体(人字内齿,裸齿轮)。
120
+ *
121
+ * 齿廓数学与 RingGear 同构(`gearGeometryForClass` 已分派到 `ringGearGeometry`),
122
+ * 差异只在建面阶段:齿面拆成上下两半、反向螺旋形成 V 形(复用
123
+ * `buildHerringboneToothFaces`);rim 圆柱面与环形盖面与 RingGear 一致。
124
+ *
125
+ * @param kernel 原始 OCCT 内核
126
+ * @param params 内齿参数(逐字沿用 Python 构造参数名)
127
+ * @param build 构造选项(策略/容差覆盖)
128
+ * @returns 朝向归一化后的 solid
129
+ */
130
+ export function buildHerringboneRingGearSolid(kernel, params, build = {}) {
131
+ return buildRingGearSolid(kernel, params, { ...build, herringbone: true });
132
+ }
133
+ //# sourceMappingURL=ring_gear.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ring_gear.js","sourceRoot":"","sources":["../src/ring_gear.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,99 @@
1
+ /**
2
+ * spline-face — thin adapter over cq-compat's gear spline-face primitives.
3
+ *
4
+ * The three B-spline face strategies (probed in the v1 spike, 2026-09-08) moved
5
+ * INTO cq-compat per the port plan (§4/§5): raw kernel knowledge lives there,
6
+ * fai_cq_gears only consumes. This file preserves the v1 import names for
7
+ * existing call sites and keeps the measurement helpers (they are test/report
8
+ * tooling, not geometry ops — they stay in this package but consume the
9
+ * cq-compat kernel type).
10
+ *
11
+ * | strategy | how | semantic delta vs cq |
12
+ * |---|---|---|
13
+ * | `grid-approx` | `kernel.bsplineSurface(flat, rows, cols)` | OCCT default DegMin/DegMax/Tol3D; cq passes 3/8/1e-2 explicitly |
14
+ * | `row-approx-loft` | per-row `approximatePoints(row, tol)` → `loft(wires, false, false)` | curve-level tol same name/meaning; surface is skinned, not fitted at once |
15
+ * | `row-interp-loft` | per-row `interpolatePoints(row)` → `loft` | passes through every sample point (interpolation) |
16
+ */
17
+ import type { BrepHandle } from '@faicad/faijs';
18
+ import { soleGearFace as soleFace, type GearDeviationStats, type GearKernel, type GearSplineFaceOptions, type GearSplineFaceStrategy } from '@faicad/cq-compat';
19
+ import type { Vec3 } from './math.js';
20
+ import type { ToothGrid } from './profile.js';
21
+ export { soleFace };
22
+ /** 齿面样条生成策略(cq-compat `Workplane.splineFace` 的 `strategy` 取值)。 */
23
+ export type SplineFaceStrategy = GearSplineFaceStrategy;
24
+ /** `splineFace` 的构造选项(行/列策略与容差)。 */
25
+ export type SplineFaceOptions = GearSplineFaceOptions;
26
+ /** 与解析齿面的偏差统计(面积相对偏差 + 采样点最大距离)。 */
27
+ export type DeviationStats = GearDeviationStats;
28
+ /**
29
+ * P0 实测选定的默认策略(2026-09-08)。
30
+ *
31
+ * 依据 `spline-face.test.ts` 的实测表:S2 的面积相对偏差 5.6e-7 / 采样点最大距离
32
+ * 2.6e-6 mm,比 S1、S3 好约 3 个数量级。详见
33
+ * `docs/analysis/2026-09-08-fai-cq-gears-spike.md`。
34
+ */
35
+ export declare const DEFAULT_SPLINE_FACE_STRATEGY: GearSplineFaceStrategy;
36
+ /** 全部可选策略(测试按此顺序遍历出偏差表)。 */
37
+ export declare const SPLINE_FACE_STRATEGIES: readonly GearSplineFaceStrategy[];
38
+ /**
39
+ * 用给定策略把一个 row×col 点阵建成面。
40
+ *
41
+ * @throws 内核抛错时原样上抛(不吞错误——这是红线)
42
+ *
43
+ * @param kernel 原始 OCCT 内核(经 cq-compat 的 `GearKernel`)
44
+ * @param grid row×col 点阵
45
+ * @param strategy 建面策略
46
+ * @param options 容差/次数选项
47
+ * @returns 单个面句柄(Face)
48
+ */
49
+ export declare function buildSplineFace(kernel: GearKernel, grid: ToothGrid, strategy: SplineFaceStrategy, options?: SplineFaceOptions): BrepHandle;
50
+ /** 点到面的最近距离(`projectPointOnFace`)。
51
+ *
52
+ * @param kernel 原始 OCCT 内核
53
+ * @param face 目标面
54
+ * @param p 查询点
55
+ * @returns 欧氏距离(mm)
56
+ */
57
+ export declare function distanceToFace(kernel: GearKernel, face: BrepHandle, p: Vec3): number;
58
+ /** 距离统计(最大值 / RMS / 样本数)。 */
59
+ /**
60
+ * 参考采样点到本面的距离统计。
61
+ *
62
+ * 参数化无关:采样点取自 cq 侧的 (u,v) 网格,两侧曲面参数化不同也能比。
63
+ *
64
+ * @param kernel 原始 OCCT 内核
65
+ * @param face 本侧面
66
+ * @param samplePoints 参考采样点(3D)
67
+ * @returns 最大距离 / RMS / 样本数
68
+ */
69
+ export declare function faceDeviation(kernel: GearKernel, face: BrepHandle, samplePoints: Vec3[]): DeviationStats;
70
+ /** 单个齿面的实测结果(面积 + 偏差 + 拓扑计数),供测试与报告使用。 */
71
+ export interface SplineFaceMeasurement {
72
+ segment: string;
73
+ strategy: SplineFaceStrategy;
74
+ rows: number;
75
+ cols: number;
76
+ area: number;
77
+ isFace: boolean;
78
+ isValid: boolean;
79
+ deviation: DeviationStats;
80
+ /** Python 侧的参考面积(来自 manifest) */
81
+ refArea: number;
82
+ /** 面积相对偏差 |Δ|/ref */
83
+ areaRelDiff: number;
84
+ }
85
+ /**
86
+ * 建面并测量(参考面积与采样点由 Python 侧 manifest 提供)。
87
+ *
88
+ * @param kernel 原始 OCCT 内核
89
+ * @param grid row×col 点阵
90
+ * @param strategy 建面策略
91
+ * @param ref 参考面积与采样点
92
+ * @param options 容差/次数选项
93
+ * @returns 实测结果(面积、偏差、拓扑计数)
94
+ */
95
+ export declare function measureSplineFace(kernel: GearKernel, grid: ToothGrid, strategy: SplineFaceStrategy, ref: {
96
+ area: number;
97
+ sample_points: number[][];
98
+ }, options?: SplineFaceOptions): SplineFaceMeasurement;
99
+ //# sourceMappingURL=spline-face.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spline-face.d.ts","sourceRoot":"","sources":["../src/spline-face.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAC/C,OAAO,EAIL,YAAY,IAAI,QAAQ,EAGxB,KAAK,kBAAkB,EACvB,KAAK,UAAU,EACf,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,EAC5B,MAAM,mBAAmB,CAAA;AAC1B,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAClC,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAE1C,OAAO,EAAE,QAAQ,EAAE,CAAA;AAEnB,kEAAkE;AAClE,MAAM,MAAM,kBAAkB,GAAG,sBAAsB,CAAA;AACvD,oCAAoC;AACpC,MAAM,MAAM,iBAAiB,GAAG,qBAAqB,CAAA;AACrD,oCAAoC;AACpC,MAAM,MAAM,cAAc,GAAG,kBAAkB,CAAA;AAE/C;;;;;;GAMG;AACH,eAAO,MAAM,4BAA4B,wBAAoC,CAAA;AAE7E,4BAA4B;AAC5B,eAAO,MAAM,sBAAsB,mCAA8B,CAAA;AAEjE;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,SAAS,EACf,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,GAAE,iBAAsB,GAC9B,UAAU,CAEZ;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC,EAAE,IAAI,GAAG,MAAM,CAEpF;AAED,6BAA6B;AAE7B;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,UAAU,EAChB,YAAY,EAAE,IAAI,EAAE,GACnB,cAAc,CAEhB;AAED,0CAA0C;AAC1C,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,kBAAkB,CAAA;IAC5B,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,OAAO,CAAA;IACf,OAAO,EAAE,OAAO,CAAA;IAChB,SAAS,EAAE,cAAc,CAAA;IACzB,iCAAiC;IACjC,OAAO,EAAE,MAAM,CAAA;IACf,qBAAqB;IACrB,WAAW,EAAE,MAAM,CAAA;CACpB;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,SAAS,EACf,QAAQ,EAAE,kBAAkB,EAC5B,GAAG,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,EAAE,EAAE,CAAA;CAAE,EAChD,OAAO,GAAE,iBAAsB,GAC9B,qBAAqB,CAoBvB"}
@@ -0,0 +1,94 @@
1
+ /**
2
+ * spline-face — thin adapter over cq-compat's gear spline-face primitives.
3
+ *
4
+ * The three B-spline face strategies (probed in the v1 spike, 2026-09-08) moved
5
+ * INTO cq-compat per the port plan (§4/§5): raw kernel knowledge lives there,
6
+ * fai_cq_gears only consumes. This file preserves the v1 import names for
7
+ * existing call sites and keeps the measurement helpers (they are test/report
8
+ * tooling, not geometry ops — they stay in this package but consume the
9
+ * cq-compat kernel type).
10
+ *
11
+ * | strategy | how | semantic delta vs cq |
12
+ * |---|---|---|
13
+ * | `grid-approx` | `kernel.bsplineSurface(flat, rows, cols)` | OCCT default DegMin/DegMax/Tol3D; cq passes 3/8/1e-2 explicitly |
14
+ * | `row-approx-loft` | per-row `approximatePoints(row, tol)` → `loft(wires, false, false)` | curve-level tol same name/meaning; surface is skinned, not fitted at once |
15
+ * | `row-interp-loft` | per-row `interpolatePoints(row)` → `loft` | passes through every sample point (interpolation) |
16
+ */
17
+ import { buildGearSplineFace, gearDistanceToFace, gearFaceDeviation, soleGearFace as soleFace, DEFAULT_GEAR_SPLINE_FACE_STRATEGY, GEAR_SPLINE_FACE_STRATEGIES, } from '@faicad/cq-compat';
18
+ export { soleFace };
19
+ /**
20
+ * P0 实测选定的默认策略(2026-09-08)。
21
+ *
22
+ * 依据 `spline-face.test.ts` 的实测表:S2 的面积相对偏差 5.6e-7 / 采样点最大距离
23
+ * 2.6e-6 mm,比 S1、S3 好约 3 个数量级。详见
24
+ * `docs/analysis/2026-09-08-fai-cq-gears-spike.md`。
25
+ */
26
+ export const DEFAULT_SPLINE_FACE_STRATEGY = DEFAULT_GEAR_SPLINE_FACE_STRATEGY;
27
+ /** 全部可选策略(测试按此顺序遍历出偏差表)。 */
28
+ export const SPLINE_FACE_STRATEGIES = GEAR_SPLINE_FACE_STRATEGIES;
29
+ /**
30
+ * 用给定策略把一个 row×col 点阵建成面。
31
+ *
32
+ * @throws 内核抛错时原样上抛(不吞错误——这是红线)
33
+ *
34
+ * @param kernel 原始 OCCT 内核(经 cq-compat 的 `GearKernel`)
35
+ * @param grid row×col 点阵
36
+ * @param strategy 建面策略
37
+ * @param options 容差/次数选项
38
+ * @returns 单个面句柄(Face)
39
+ */
40
+ export function buildSplineFace(kernel, grid, strategy, options = {}) {
41
+ return buildGearSplineFace(kernel, grid, strategy, options);
42
+ }
43
+ /** 点到面的最近距离(`projectPointOnFace`)。
44
+ *
45
+ * @param kernel 原始 OCCT 内核
46
+ * @param face 目标面
47
+ * @param p 查询点
48
+ * @returns 欧氏距离(mm)
49
+ */
50
+ export function distanceToFace(kernel, face, p) {
51
+ return gearDistanceToFace(kernel, face, p);
52
+ }
53
+ /** 距离统计(最大值 / RMS / 样本数)。 */
54
+ /**
55
+ * 参考采样点到本面的距离统计。
56
+ *
57
+ * 参数化无关:采样点取自 cq 侧的 (u,v) 网格,两侧曲面参数化不同也能比。
58
+ *
59
+ * @param kernel 原始 OCCT 内核
60
+ * @param face 本侧面
61
+ * @param samplePoints 参考采样点(3D)
62
+ * @returns 最大距离 / RMS / 样本数
63
+ */
64
+ export function faceDeviation(kernel, face, samplePoints) {
65
+ return gearFaceDeviation(kernel, face, samplePoints);
66
+ }
67
+ /**
68
+ * 建面并测量(参考面积与采样点由 Python 侧 manifest 提供)。
69
+ *
70
+ * @param kernel 原始 OCCT 内核
71
+ * @param grid row×col 点阵
72
+ * @param strategy 建面策略
73
+ * @param ref 参考面积与采样点
74
+ * @param options 容差/次数选项
75
+ * @returns 实测结果(面积、偏差、拓扑计数)
76
+ */
77
+ export function measureSplineFace(kernel, grid, strategy, ref, options = {}) {
78
+ const face = buildSplineFace(kernel, grid, strategy, options);
79
+ const area = kernel.getSurfaceArea(face);
80
+ const deviation = faceDeviation(kernel, face, ref.sample_points.map((p) => ({ x: p[0], y: p[1], z: p[2] })));
81
+ return {
82
+ segment: grid.segment,
83
+ strategy,
84
+ rows: grid.rows,
85
+ cols: grid.cols,
86
+ area,
87
+ isFace: kernel.isFace(face),
88
+ isValid: kernel.isValid(face),
89
+ deviation,
90
+ refArea: ref.area,
91
+ areaRelDiff: Math.abs(area - ref.area) / ref.area,
92
+ };
93
+ }
94
+ //# sourceMappingURL=spline-face.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spline-face.js","sourceRoot":"","sources":["../src/spline-face.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,iBAAiB,EACjB,YAAY,IAAI,QAAQ,EACxB,iCAAiC,EACjC,2BAA2B,GAK5B,MAAM,mBAAmB,CAAA;AAI1B,OAAO,EAAE,QAAQ,EAAE,CAAA;AASnB;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,iCAAiC,CAAA;AAE7E,4BAA4B;AAC5B,MAAM,CAAC,MAAM,sBAAsB,GAAG,2BAA2B,CAAA;AAEjE;;;;;;;;;;GAUG;AACH,MAAM,UAAU,eAAe,CAC7B,MAAkB,EAClB,IAAe,EACf,QAA4B,EAC5B,UAA6B,EAAE;IAE/B,OAAO,mBAAmB,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAA;AAC7D,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,cAAc,CAAC,MAAkB,EAAE,IAAgB,EAAE,CAAO;IAC1E,OAAO,kBAAkB,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;AAC5C,CAAC;AAED,6BAA6B;AAE7B;;;;;;;;;GASG;AACH,MAAM,UAAU,aAAa,CAC3B,MAAkB,EAClB,IAAgB,EAChB,YAAoB;IAEpB,OAAO,iBAAiB,CAAC,MAAM,EAAE,IAAI,EAAE,YAAY,CAAC,CAAA;AACtD,CAAC;AAkBD;;;;;;;;;GASG;AACH,MAAM,UAAU,iBAAiB,CAC/B,MAAkB,EAClB,IAAe,EACf,QAA4B,EAC5B,GAAgD,EAChD,UAA6B,EAAE;IAE/B,MAAM,IAAI,GAAG,eAAe,CAAC,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAA;IAC7D,MAAM,IAAI,GAAG,MAAM,CAAC,cAAc,CAAC,IAAI,CAAC,CAAA;IACxC,MAAM,SAAS,GAAG,aAAa,CAC7B,MAAM,EACN,IAAI,EACJ,GAAG,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAC9D,CAAA;IACD,OAAO;QACL,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,QAAQ;QACR,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,IAAI,EAAE,IAAI,CAAC,IAAI;QACf,IAAI;QACJ,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC;QAC3B,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC;QAC7B,SAAS;QACT,OAAO,EAAE,GAAG,CAAC,IAAI;QACjB,WAAW,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,IAAI;KAClD,CAAA;AACH,CAAC"}
@@ -0,0 +1,112 @@
1
+ /**
2
+ * spur_gear — SpurGear 最小实体构造(P0/P1:裸齿轮,无 bore/hub/spokes/chamfer)
3
+ *
4
+ * 对应 `SpurGear._build_gear_faces()` + `make_shell` + `Solid.makeSolid`:
5
+ *
6
+ * ```
7
+ * ① 4 段齿廓 → 4 个齿面(spline-face 三方案可切换)
8
+ * ② 每个齿面绕 Z 旋转 tau*i,得到 z 个齿的 4z 个面
9
+ * ③ 顶/底面:取所有位于 z=0 / z=width 的边 → 组线 → 成面
10
+ * ④ sew(faces, shell_sewing_tol) → makeSolid(shell)
11
+ * ```
12
+ *
13
+ * cq 用 `Wire.combine(edges, tol)` 组线(带容差排序);faijs 侧用
14
+ * `makeWire(edges)` + `healWire(wire, tol)` 复现,容差取同一个 `wire_comb_tol`。
15
+ */
16
+ import type { BrepHandle } from '@faicad/faijs';
17
+ import type { GearKernel } from '@faicad/cq-compat';
18
+ import { type SpurGearGeometry, type SpurGearParams } from './profile.js';
19
+ import { type HyperbolicGearParams } from './profile.js';
20
+ import { type SplineFaceOptions, type SplineFaceStrategy } from './spline-face.js';
21
+ import { type GearFeatureOptions } from './features.js';
22
+ /** SpurGear 实体构造选项(在 `SplineFaceOptions` 上加容差、策略与镀铬特征覆盖)。 */
23
+ export interface BuildSpurGearOptions extends SplineFaceOptions, GearFeatureOptions {
24
+ strategy?: SplineFaceStrategy;
25
+ /** 缝合容差(cq `shell_sewing_tol`)。 */
26
+ shellSewingTol?: number;
27
+ /** 组线容差(cq `wire_comb_tol`)。 */
28
+ wireCombTol?: number;
29
+ /** 人字齿:齿面沿宽度方向拆成上下两半、各以相反螺旋扭转(V 形)。 */
30
+ herringbone?: boolean;
31
+ }
32
+ /**
33
+ * 把一批面中位于 `z` 平面上的边界边收集成一个平面盖面。
34
+ *
35
+ * @throws 内核抛错时原样上抛
36
+ *
37
+ * @param kernel 原始 OCCT 内核
38
+ * @param faces 齿面集合(已含 z 向厚度)
39
+ * @param z 目标平面高度
40
+ * @param wireCombTol 组线容差(mm)
41
+ * @returns 平面盖面(Face)
42
+ */
43
+ export declare function planarCapAtZ(kernel: GearKernel, faces: BrepHandle[], z: number, wireCombTol?: number): BrepHandle;
44
+ /** ①+②:4z 个齿面(不含顶/底面)。
45
+ *
46
+ * @param kernel 原始 OCCT 内核
47
+ * @param geom 齿轮几何量
48
+ * @param strategy 齿面建面策略
49
+ * @param options 容差/次数选项
50
+ * @returns 齿面列表(4z 个 Face)
51
+ */
52
+ export declare function buildToothFaces(kernel: GearKernel, geom: SpurGearGeometry, strategy: SplineFaceStrategy, options?: SplineFaceOptions): BrepHandle[];
53
+ /**
54
+ * ①+②:人字齿(Herringbone)的 8z 个齿面(上下两半 V 形)。
55
+ *
56
+ * 对应 cq_gears `HerringboneGear._build_tooth_faces`:调父类两次,
57
+ * 上半 `(0, +twist, 0, w/2)`、下半 `(+twist, 0, w/2, w/2)`,两半在 z=w/2 处
58
+ * 以相同扭转角衔接(点集重合,sew 自动并合)。
59
+ *
60
+ * @param kernel 原始 OCCT 内核
61
+ * @param geom 齿廓几何量
62
+ * @param strategy 齿面建面策略
63
+ * @param options 容差/次数选项
64
+ * @returns 齿面列表(8z 个 Face:4 段 × 2 半 × z 齿)
65
+ */
66
+ export declare function buildHerringboneToothFaces(kernel: GearKernel, geom: SpurGearGeometry, strategy: SplineFaceStrategy, options?: SplineFaceOptions): BrepHandle[];
67
+ /** ③–④:由**已算好**的齿廓几何量构造裸齿轮实体(SpurGear 全族共用)。
68
+ *
69
+ * 与类无关:只吃 `SpurGearGeometry`(Spur / Herringbone / CrossedHelical 的齿廓布局
70
+ * 同构),所以子类(如 CrossedHelical)只要先用自己的公式算出 `geom`,即可复用它。
71
+ *
72
+ * @param kernel 原始 OCCT 内核
73
+ * @param geom 齿廓几何量(`spurGearGeometry` / `crossedHelicalGearGeometry` 的产物)
74
+ * @param build 构造选项(策略/容差覆盖)
75
+ * @returns 朝向归一化后的 solid
76
+ */
77
+ export declare function buildGearSolid(kernel: GearKernel, geom: SpurGearGeometry, build?: BuildSpurGearOptions): BrepHandle;
78
+ /** ①–④:完整 SpurGear 实体(裸齿轮)。
79
+ *
80
+ * @param kernel 原始 OCCT 内核
81
+ * @param params 齿轮参数
82
+ * @param build 构造选项(策略/容差覆盖)
83
+ * @returns 朝向归一化后的 solid
84
+ */
85
+ export declare function buildSpurGearSolid(kernel: GearKernel, params: SpurGearParams, build?: BuildSpurGearOptions): BrepHandle;
86
+ /** ①–④:完整 HerringboneGear 实体(人字齿,裸齿轮)。
87
+ *
88
+ * 齿廓数学与 SpurGear 同构(`gearGeometryForClass` 已分派到 `spurGearGeometry`),
89
+ * 差异只在建面阶段:齿面沿宽度拆成上下两半、反向螺旋形成 V 形,由
90
+ * `buildHerringboneToothFaces` 实现;顶/底盖面与 SpurGear 一致(z=0 与 z=width 处
91
+ * 截面均为基准渐开线,净扭转回零)。
92
+ *
93
+ * @param kernel 原始 OCCT 内核
94
+ * @param params 齿轮参数(逐字沿用 Python 构造参数名)
95
+ * @param build 构造选项(策略/容差覆盖)
96
+ * @returns 朝向归一化后的 solid
97
+ */
98
+ export declare function buildHerringboneGearSolid(kernel: GearKernel, params: SpurGearParams, build?: BuildSpurGearOptions): BrepHandle;
99
+ /**
100
+ * ①–④:完整 HyperbolicGear 实体(双曲面齿轮,裸齿轮)。
101
+ *
102
+ * 齿廓数学与 SpurGear 同构,差异只在 `twist_angle` 来自显式构造参数(见
103
+ * `hyperbolicGearGeometry`)、`surfaceSplines=2`;实体构造完全复用通用的
104
+ * `buildGearSolid`。
105
+ *
106
+ * @param kernel 原始 OCCT 内核
107
+ * @param params 双曲面齿轮参数(逐字沿用 Python 构造参数名)
108
+ * @param build 构造选项(策略/容差覆盖)
109
+ * @returns 朝向归一化后的 solid
110
+ */
111
+ export declare function buildHyperbolicGearSolid(kernel: GearKernel, params: HyperbolicGearParams, build?: BuildSpurGearOptions): BrepHandle;
112
+ //# sourceMappingURL=spur_gear.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spur_gear.d.ts","sourceRoot":"","sources":["../src/spur_gear.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAC/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAEnD,OAAO,EAAkB,KAAK,gBAAgB,EAAE,KAAK,cAAc,EAAE,MAAM,WAAW,CAAA;AACtF,OAAO,EAA4C,KAAK,oBAAoB,EAAE,MAAM,WAAW,CAAA;AAC/F,OAAO,EAEL,KAAK,iBAAiB,EAAE,KAAK,kBAAkB,EAChD,MAAM,eAAe,CAAA;AAEtB,OAAO,EAEL,KAAK,kBAAkB,EACxB,MAAM,YAAY,CAAA;AAKnB,6DAA6D;AAC7D,MAAM,WAAW,oBAAqB,SAAQ,iBAAiB,EAAE,kBAAkB;IACjF,QAAQ,CAAC,EAAE,kBAAkB,CAAA;IAC7B,mCAAmC;IACnC,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,gCAAgC;IAChC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,uCAAuC;IACvC,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAC1B,MAAM,EAAE,UAAU,EAClB,KAAK,EAAE,UAAU,EAAE,EACnB,CAAC,EAAE,MAAM,EACT,WAAW,GAAE,MAA0C,GACtD,UAAU,CAoBZ;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,gBAAgB,EACtB,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,GAAE,iBAAsB,GAC9B,UAAU,EAAE,CAad;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,gBAAgB,EACtB,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,GAAE,iBAAsB,GAC9B,UAAU,EAAE,CAgBd;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,gBAAgB,EACtB,KAAK,GAAE,oBAAyB,GAC/B,UAAU,CAyDZ;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,cAAc,EACtB,KAAK,GAAE,oBAAyB,GAC/B,UAAU,CAEZ;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,cAAc,EACtB,KAAK,GAAE,oBAAyB,GAC/B,UAAU,CAEZ;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,UAAU,EAClB,MAAM,EAAE,oBAAoB,EAC5B,KAAK,GAAE,oBAAyB,GAC/B,UAAU,CAEZ"}