okgeometry-api 1.23.0 → 1.24.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.
@@ -1 +1 @@
1
- {"version":3,"file":"wasm-base64.js","sourceRoot":"","sources":["../src/wasm-base64.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,MAAM,CAAC,MAAM,QAAQ,GAAG,8kolGAA8kolG,CAAC"}
1
+ {"version":3,"file":"wasm-base64.js","sourceRoot":"","sources":["../src/wasm-base64.ts"],"names":[],"mappings":"AAAA,+BAA+B;AAC/B,MAAM,CAAC,MAAM,QAAQ,GAAG,04qlGAA04qlG,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "okgeometry-api",
3
- "version": "1.23.0",
3
+ "version": "1.24.0",
4
4
  "description": "Geometry engine API for AEC applications - NURBS, meshes, booleans, intersections. Powered by Rust/WASM.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
package/src/Line.ts CHANGED
@@ -1,12 +1,12 @@
1
- import { ensureInit } from "./engine.js";
2
- import { Point } from "./Point.js";
3
- import { Vec3 } from "./Vec3.js";
4
- import { Mesh } from "./Mesh.js";
5
- import { PolyCurve } from "./PolyCurve.js";
6
- import { Polyline } from "./Polyline.js";
7
- import type { Plane } from "./Plane.js";
8
- import type { CurveOffsetOptions, RotationAxis } from "./types.js";
9
- import * as wasm from "./wasm-bindings.js";
1
+ import { ensureInit } from "./engine.js";
2
+ import { Point } from "./Point.js";
3
+ import { Vec3 } from "./Vec3.js";
4
+ import { Mesh } from "./Mesh.js";
5
+ import { PolyCurve } from "./PolyCurve.js";
6
+ import { Polyline } from "./Polyline.js";
7
+ import type { Plane } from "./Plane.js";
8
+ import type { CurveOffsetOptions, RotationAxis } from "./types.js";
9
+ import * as wasm from "./wasm-bindings.js";
10
10
 
11
11
  /**
12
12
  * Immutable line segment defined by start and end points.
@@ -86,6 +86,15 @@ export class Line {
86
86
  return new Line(this.start.add(offset), this.end.add(offset));
87
87
  }
88
88
 
89
+ /**
90
+ * Apply a row-major 4x4 matrix to both endpoints.
91
+ * @param matrix - Row-major 4x4 matrix (16 entries)
92
+ * @returns New transformed line
93
+ */
94
+ applyMatrix(matrix: number[] | Float64Array): Line {
95
+ return new Line(this.start.applyMatrix(matrix), this.end.applyMatrix(matrix));
96
+ }
97
+
89
98
  /**
90
99
  * Rotate this line around an axis.
91
100
  * @param axis - Rotation axis (Vec3 through origin, or Line for arbitrary axis)
@@ -102,40 +111,40 @@ export class Line {
102
111
  * @param normal - Reference normal for determining offset direction (default Z axis)
103
112
  * @returns New offset line
104
113
  */
105
- offset(distance: number, normal: Vec3 = Vec3.Z): Line {
106
- ensureInit();
107
- const r = wasm.line_offset(
108
- this.start.x, this.start.y, this.start.z,
109
- this.end.x, this.end.y, this.end.z,
114
+ offset(distance: number, normal: Vec3 = Vec3.Z): Line {
115
+ ensureInit();
116
+ const r = wasm.line_offset(
117
+ this.start.x, this.start.y, this.start.z,
118
+ this.end.x, this.end.y, this.end.z,
110
119
  distance,
111
120
  normal.x, normal.y, normal.z,
112
121
  );
113
122
  return new Line(
114
123
  new Point(r[0], r[1], r[2]),
115
- new Point(r[3], r[4], r[5]),
116
- );
117
- }
118
-
119
- /**
120
- * Thicken this line into a closed PolyCurve suitable for extrusion.
121
- * When `bothSides` is false, the source line forms one side of the result.
122
- * When true, the thickness is added on each side of the line.
123
- *
124
- * If `normal` is omitted, the kernel will infer a stable fallback plane.
125
- */
126
- thicken(
127
- distance: number,
128
- bothSides = false,
129
- normal?: Vec3,
130
- options: CurveOffsetOptions = {},
131
- ): PolyCurve {
132
- return new Polyline([this.start, this.end]).thicken(distance, bothSides, normal, options);
133
- }
134
-
135
- /**
136
- * Project this line onto a plane.
137
- * @param plane - Target plane
138
- * @param direction - Optional projection direction (default: perpendicular to plane)
124
+ new Point(r[3], r[4], r[5]),
125
+ );
126
+ }
127
+
128
+ /**
129
+ * Thicken this line into a closed PolyCurve suitable for extrusion.
130
+ * When `bothSides` is false, the source line forms one side of the result.
131
+ * When true, the thickness is added on each side of the line.
132
+ *
133
+ * If `normal` is omitted, the kernel will infer a stable fallback plane.
134
+ */
135
+ thicken(
136
+ distance: number,
137
+ bothSides = false,
138
+ normal?: Vec3,
139
+ options: CurveOffsetOptions = {},
140
+ ): PolyCurve {
141
+ return new Polyline([this.start, this.end]).thicken(distance, bothSides, normal, options);
142
+ }
143
+
144
+ /**
145
+ * Project this line onto a plane.
146
+ * @param plane - Target plane
147
+ * @param direction - Optional projection direction (default: perpendicular to plane)
139
148
  * @returns New projected line
140
149
  */
141
150
  projectOntoPlane(plane: Plane, direction?: Vec3): Line {
package/src/NurbsCurve.ts CHANGED
@@ -363,6 +363,22 @@ export class NurbsCurve {
363
363
  );
364
364
  }
365
365
 
366
+ /**
367
+ * Apply a row-major 4x4 AFFINE matrix to this curve. NURBS are invariant
368
+ * under affine maps of their control points, so rigid transforms, scaling
369
+ * (uniform or not) and shear are EXACT — weights and knots are unchanged.
370
+ * @param matrix - Row-major 4x4 matrix (16 entries)
371
+ * @returns New transformed curve
372
+ */
373
+ applyMatrix(matrix: number[] | Float64Array): NurbsCurve {
374
+ return new NurbsCurve(
375
+ this.degree,
376
+ this.controlPoints.map(p => p.applyMatrix(matrix)),
377
+ this.weights,
378
+ this.knots
379
+ );
380
+ }
381
+
366
382
  /**
367
383
  * Rotate this curve around an axis.
368
384
  * @param axis - Rotation axis (Vec3 through origin, or Line for arbitrary axis)
@@ -81,6 +81,25 @@ export class NurbsSurface implements Surface {
81
81
  );
82
82
  }
83
83
 
84
+ /**
85
+ * Apply a row-major 4x4 AFFINE matrix to this surface. NURBS are invariant
86
+ * under affine maps of their control net, so rigid transforms, scaling
87
+ * (uniform or not) and shear are EXACT — weights and knots are unchanged.
88
+ * @param matrix - Row-major 4x4 matrix (16 entries)
89
+ * @returns New transformed surface
90
+ */
91
+ applyMatrix(matrix: number[] | Float64Array): NurbsSurface {
92
+ const newCps = this.controlPoints.map(row => row.map(p => p.applyMatrix(matrix)));
93
+ return new NurbsSurface(
94
+ this.degreeU,
95
+ this.degreeV,
96
+ newCps,
97
+ this.weights,
98
+ this.knotsU,
99
+ this.knotsV
100
+ );
101
+ }
102
+
84
103
  /**
85
104
  * Evaluate a point on the surface at parameters (u, v).
86
105
  * @param u - Parameter in U direction [0, 1]
package/src/Point.ts CHANGED
@@ -1,145 +1,161 @@
1
- import { Vec3 } from "./Vec3.js";
2
- import type { Plane } from "./Plane.js";
3
- import type { RotationAxis } from "./types.js";
4
-
5
- /**
6
- * Immutable 3D point for representing positions in space.
7
- * All operations return new Point instances.
8
- */
9
- export class Point {
10
- constructor(
11
- public readonly x: number,
12
- public readonly y: number,
13
- public readonly z: number
14
- ) {}
15
-
16
- /**
17
- * Compute the distance to another point.
18
- * @param other - Target point
19
- * @returns Euclidean distance between points
20
- */
21
- distanceTo(other: Point): number {
22
- const dx = this.x - other.x;
23
- const dy = this.y - other.y;
24
- const dz = this.z - other.z;
25
- return Math.sqrt(dx * dx + dy * dy + dz * dz);
26
- }
27
-
28
- /**
29
- * Convert this point to a vector (from origin).
30
- * @returns Vec3 with same coordinates
31
- */
32
- toVec3(): Vec3 {
33
- return new Vec3(this.x, this.y, this.z);
34
- }
35
-
36
- /**
37
- * Add a vector to this point.
38
- * @param v - Vector to add
39
- * @returns New point offset by vector
40
- */
41
- add(v: Vec3): Point {
42
- return new Point(this.x + v.x, this.y + v.y, this.z + v.z);
43
- }
44
-
45
- /**
46
- * Translate this point by an offset vector.
47
- * Alias for add().
48
- * @param offset - Translation vector
49
- * @returns New translated point
50
- */
51
- translate(offset: Vec3): Point {
52
- return this.add(offset);
53
- }
54
-
55
- /**
56
- * Rotate around an axis by angle in radians using Rodrigues' formula.
57
- * @param axis - Vec3 (rotation around origin) or Line (rotation around arbitrary axis)
58
- * @param angle - Rotation angle in radians
59
- * @returns Rotated point
60
- */
61
- rotate(axis: RotationAxis, angle: number): Point {
62
- if ('start' in axis && 'end' in axis) {
63
- const dir = new Vec3(axis.end.x - axis.start.x, axis.end.y - axis.start.y, axis.end.z - axis.start.z);
64
- const shifted = new Point(this.x - axis.start.x, this.y - axis.start.y, this.z - axis.start.z);
65
- const rotated = shifted.rotate(dir, angle);
66
- return new Point(rotated.x + axis.start.x, rotated.y + axis.start.y, rotated.z + axis.start.z);
67
- }
68
- const len = Math.sqrt(axis.x * axis.x + axis.y * axis.y + axis.z * axis.z);
69
- if (len < 1e-15) return this.clone();
70
- const k = { x: axis.x / len, y: axis.y / len, z: axis.z / len };
71
- const cos = Math.cos(angle);
72
- const sin = Math.sin(angle);
73
- const dot = k.x * this.x + k.y * this.y + k.z * this.z;
74
- const cx = k.y * this.z - k.z * this.y;
75
- const cy = k.z * this.x - k.x * this.z;
76
- const cz = k.x * this.y - k.y * this.x;
77
- return new Point(
78
- this.x * cos + cx * sin + k.x * dot * (1 - cos),
79
- this.y * cos + cy * sin + k.y * dot * (1 - cos),
80
- this.z * cos + cz * sin + k.z * dot * (1 - cos),
81
- );
82
- }
83
-
84
- /**
85
- * Project this point onto a plane.
86
- * @param plane - Target plane
87
- * @param direction - Optional projection direction (default: perpendicular to plane)
88
- * @returns Projected point on plane
89
- */
90
- projectOntoPlane(plane: Plane, direction?: Vec3): Point {
91
- return direction ? plane.projectPointAlongDirection(this, direction) : plane.projectPoint(this);
92
- }
93
-
94
- /**
95
- * Get the vector from another point to this point.
96
- * @param other - Origin point
97
- * @returns Vector from other to this
98
- */
99
- sub(other: Point): Vec3 {
100
- return new Vec3(this.x - other.x, this.y - other.y, this.z - other.z);
101
- }
102
-
103
- /**
104
- * Create a copy of this point.
105
- * @returns New point with same coordinates
106
- */
107
- clone(): Point {
108
- return new Point(this.x, this.y, this.z);
109
- }
110
-
111
- /**
112
- * Check equality with another point within tolerance.
113
- * @param other - Point to compare
114
- * @param eps - Tolerance (default 1e-10)
115
- * @returns True if points are approximately equal
116
- */
117
- equals(other: Point, eps = 1e-10): boolean {
118
- return (
119
- Math.abs(this.x - other.x) < eps &&
120
- Math.abs(this.y - other.y) < eps &&
121
- Math.abs(this.z - other.z) < eps
122
- );
123
- }
124
-
125
- /**
126
- * Convert to array format.
127
- * @returns Tuple [x, y, z]
128
- */
129
- toArray(): [number, number, number] {
130
- return [this.x, this.y, this.z];
131
- }
132
-
133
- /**
134
- * Create a Point from a plain object or JSON.
135
- * @param json - Object with x, y, z properties
136
- * @returns New Point instance
137
- */
138
- static fromJSON(json: any): Point {
139
- if (json instanceof Point) return json;
140
- return new Point(json.x ?? 0, json.y ?? 0, json.z ?? 0);
141
- }
142
-
143
- /** Origin point (0, 0, 0) */
144
- static readonly ORIGIN = new Point(0, 0, 0);
145
- }
1
+ import { Vec3 } from "./Vec3.js";
2
+ import type { Plane } from "./Plane.js";
3
+ import type { RotationAxis } from "./types.js";
4
+
5
+ /**
6
+ * Immutable 3D point for representing positions in space.
7
+ * All operations return new Point instances.
8
+ */
9
+ export class Point {
10
+ constructor(
11
+ public readonly x: number,
12
+ public readonly y: number,
13
+ public readonly z: number
14
+ ) {}
15
+
16
+ /**
17
+ * Compute the distance to another point.
18
+ * @param other - Target point
19
+ * @returns Euclidean distance between points
20
+ */
21
+ distanceTo(other: Point): number {
22
+ const dx = this.x - other.x;
23
+ const dy = this.y - other.y;
24
+ const dz = this.z - other.z;
25
+ return Math.sqrt(dx * dx + dy * dy + dz * dz);
26
+ }
27
+
28
+ /**
29
+ * Convert this point to a vector (from origin).
30
+ * @returns Vec3 with same coordinates
31
+ */
32
+ toVec3(): Vec3 {
33
+ return new Vec3(this.x, this.y, this.z);
34
+ }
35
+
36
+ /**
37
+ * Add a vector to this point.
38
+ * @param v - Vector to add
39
+ * @returns New point offset by vector
40
+ */
41
+ add(v: Vec3): Point {
42
+ return new Point(this.x + v.x, this.y + v.y, this.z + v.z);
43
+ }
44
+
45
+ /**
46
+ * Translate this point by an offset vector.
47
+ * Alias for add().
48
+ * @param offset - Translation vector
49
+ * @returns New translated point
50
+ */
51
+ translate(offset: Vec3): Point {
52
+ return this.add(offset);
53
+ }
54
+
55
+ /**
56
+ * Apply a row-major 4x4 matrix to this point (same convention as
57
+ * Mesh.applyMatrix / Brep.applyMatrix).
58
+ * @param matrix - Row-major 4x4 matrix (16 entries)
59
+ * @returns New transformed point
60
+ */
61
+ applyMatrix(matrix: number[] | Float64Array): Point {
62
+ if (matrix.length < 16) throw new Error("Point.applyMatrix: need 16 entries");
63
+ const m = matrix;
64
+ return new Point(
65
+ m[0] * this.x + m[1] * this.y + m[2] * this.z + m[3],
66
+ m[4] * this.x + m[5] * this.y + m[6] * this.z + m[7],
67
+ m[8] * this.x + m[9] * this.y + m[10] * this.z + m[11]
68
+ );
69
+ }
70
+
71
+ /**
72
+ * Rotate around an axis by angle in radians using Rodrigues' formula.
73
+ * @param axis - Vec3 (rotation around origin) or Line (rotation around arbitrary axis)
74
+ * @param angle - Rotation angle in radians
75
+ * @returns Rotated point
76
+ */
77
+ rotate(axis: RotationAxis, angle: number): Point {
78
+ if ('start' in axis && 'end' in axis) {
79
+ const dir = new Vec3(axis.end.x - axis.start.x, axis.end.y - axis.start.y, axis.end.z - axis.start.z);
80
+ const shifted = new Point(this.x - axis.start.x, this.y - axis.start.y, this.z - axis.start.z);
81
+ const rotated = shifted.rotate(dir, angle);
82
+ return new Point(rotated.x + axis.start.x, rotated.y + axis.start.y, rotated.z + axis.start.z);
83
+ }
84
+ const len = Math.sqrt(axis.x * axis.x + axis.y * axis.y + axis.z * axis.z);
85
+ if (len < 1e-15) return this.clone();
86
+ const k = { x: axis.x / len, y: axis.y / len, z: axis.z / len };
87
+ const cos = Math.cos(angle);
88
+ const sin = Math.sin(angle);
89
+ const dot = k.x * this.x + k.y * this.y + k.z * this.z;
90
+ const cx = k.y * this.z - k.z * this.y;
91
+ const cy = k.z * this.x - k.x * this.z;
92
+ const cz = k.x * this.y - k.y * this.x;
93
+ return new Point(
94
+ this.x * cos + cx * sin + k.x * dot * (1 - cos),
95
+ this.y * cos + cy * sin + k.y * dot * (1 - cos),
96
+ this.z * cos + cz * sin + k.z * dot * (1 - cos),
97
+ );
98
+ }
99
+
100
+ /**
101
+ * Project this point onto a plane.
102
+ * @param plane - Target plane
103
+ * @param direction - Optional projection direction (default: perpendicular to plane)
104
+ * @returns Projected point on plane
105
+ */
106
+ projectOntoPlane(plane: Plane, direction?: Vec3): Point {
107
+ return direction ? plane.projectPointAlongDirection(this, direction) : plane.projectPoint(this);
108
+ }
109
+
110
+ /**
111
+ * Get the vector from another point to this point.
112
+ * @param other - Origin point
113
+ * @returns Vector from other to this
114
+ */
115
+ sub(other: Point): Vec3 {
116
+ return new Vec3(this.x - other.x, this.y - other.y, this.z - other.z);
117
+ }
118
+
119
+ /**
120
+ * Create a copy of this point.
121
+ * @returns New point with same coordinates
122
+ */
123
+ clone(): Point {
124
+ return new Point(this.x, this.y, this.z);
125
+ }
126
+
127
+ /**
128
+ * Check equality with another point within tolerance.
129
+ * @param other - Point to compare
130
+ * @param eps - Tolerance (default 1e-10)
131
+ * @returns True if points are approximately equal
132
+ */
133
+ equals(other: Point, eps = 1e-10): boolean {
134
+ return (
135
+ Math.abs(this.x - other.x) < eps &&
136
+ Math.abs(this.y - other.y) < eps &&
137
+ Math.abs(this.z - other.z) < eps
138
+ );
139
+ }
140
+
141
+ /**
142
+ * Convert to array format.
143
+ * @returns Tuple [x, y, z]
144
+ */
145
+ toArray(): [number, number, number] {
146
+ return [this.x, this.y, this.z];
147
+ }
148
+
149
+ /**
150
+ * Create a Point from a plain object or JSON.
151
+ * @param json - Object with x, y, z properties
152
+ * @returns New Point instance
153
+ */
154
+ static fromJSON(json: any): Point {
155
+ if (json instanceof Point) return json;
156
+ return new Point(json.x ?? 0, json.y ?? 0, json.z ?? 0);
157
+ }
158
+
159
+ /** Origin point (0, 0, 0) */
160
+ static readonly ORIGIN = new Point(0, 0, 0);
161
+ }
package/src/Polyline.ts CHANGED
@@ -135,6 +135,15 @@ export class Polyline {
135
135
  return new Polyline(this.points.map(p => p.add(offset)));
136
136
  }
137
137
 
138
+ /**
139
+ * Apply a row-major 4x4 matrix to every vertex.
140
+ * @param matrix - Row-major 4x4 matrix (16 entries)
141
+ * @returns New transformed polyline
142
+ */
143
+ applyMatrix(matrix: number[] | Float64Array): Polyline {
144
+ return new Polyline(this.points.map(p => p.applyMatrix(matrix)));
145
+ }
146
+
138
147
  /**
139
148
  * Rotate this polyline around an axis.
140
149
  * @param axis - Rotation axis (Vec3 through origin, or Line for arbitrary axis)