okgeometry-api 0.5.0 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/Ray.ts ADDED
@@ -0,0 +1,90 @@
1
+ import { ensureInit } from "./engine.js";
2
+ import { Point } from "./Point.js";
3
+ import { Vec3 } from "./Vec3.js";
4
+ import * as wasm from "../wasm/okgeometrycore_bg.js";
5
+
6
+ /**
7
+ * 3D ray defined by origin and direction.
8
+ * Parametric form: point(t) = origin + t * direction
9
+ */
10
+ export class Ray {
11
+ constructor(
12
+ public readonly origin: Point,
13
+ public readonly direction: Vec3
14
+ ) {}
15
+
16
+ /**
17
+ * Create a ray from origin and direction, normalizing the direction.
18
+ * Returns null if direction is zero-length.
19
+ */
20
+ static fromOriginDirection(origin: Point, direction: Vec3): Ray | null {
21
+ const normalized = direction.normalize();
22
+ if (normalized.length() < 1e-10) return null;
23
+ return new Ray(origin, normalized);
24
+ }
25
+
26
+ /**
27
+ * Get point along the ray at parameter t.
28
+ * Returns origin + t * direction
29
+ */
30
+ pointAt(t: number): Point {
31
+ ensureInit();
32
+ const r = wasm.ray_point_at(
33
+ this.origin.x, this.origin.y, this.origin.z,
34
+ this.direction.x, this.direction.y, this.direction.z,
35
+ t
36
+ );
37
+ return new Point(r[0], r[1], r[2]);
38
+ }
39
+
40
+ /**
41
+ * Find the parameter t for the closest point on the ray to a given point.
42
+ * The closest point is at: origin + t * direction
43
+ * Note: t can be negative if the closest point is "behind" the ray origin,
44
+ * but closestPoint() clamps t >= 0.
45
+ */
46
+ closestPointParameter(point: Point): number {
47
+ ensureInit();
48
+ return wasm.ray_closest_point_parameter(
49
+ this.origin.x, this.origin.y, this.origin.z,
50
+ this.direction.x, this.direction.y, this.direction.z,
51
+ point.x, point.y, point.z
52
+ );
53
+ }
54
+
55
+ /**
56
+ * Find the closest point on the ray to a given point.
57
+ * The result is clamped to the ray (t >= 0), so if the closest
58
+ * point would be "behind" the origin, returns the origin.
59
+ */
60
+ closestPoint(point: Point): Point {
61
+ ensureInit();
62
+ const r = wasm.ray_closest_point(
63
+ this.origin.x, this.origin.y, this.origin.z,
64
+ this.direction.x, this.direction.y, this.direction.z,
65
+ point.x, point.y, point.z
66
+ );
67
+ return new Point(r[0], r[1], r[2]);
68
+ }
69
+
70
+ /**
71
+ * Compute the distance from this ray to a point.
72
+ * This is the perpendicular distance from the ray to the point,
73
+ * clamped so that the closest point is on the ray (t >= 0).
74
+ */
75
+ distanceToPoint(point: Point): number {
76
+ ensureInit();
77
+ return wasm.ray_distance_to_point(
78
+ this.origin.x, this.origin.y, this.origin.z,
79
+ this.direction.x, this.direction.y, this.direction.z,
80
+ point.x, point.y, point.z
81
+ );
82
+ }
83
+
84
+ /**
85
+ * Translate the ray by an offset vector.
86
+ */
87
+ translate(offset: Vec3): Ray {
88
+ return new Ray(this.origin.add(offset), this.direction);
89
+ }
90
+ }
package/src/Vec3.ts ADDED
@@ -0,0 +1,159 @@
1
+ /**
2
+ * Immutable 3D vector for representing directions and offsets.
3
+ * All operations return new Vec3 instances.
4
+ */
5
+ export class Vec3 {
6
+ constructor(
7
+ public readonly x: number,
8
+ public readonly y: number,
9
+ public readonly z: number
10
+ ) {}
11
+
12
+ /**
13
+ * Add another vector to this one.
14
+ * @param v - Vector to add
15
+ * @returns New vector representing the sum
16
+ */
17
+ add(v: Vec3): Vec3 {
18
+ return new Vec3(this.x + v.x, this.y + v.y, this.z + v.z);
19
+ }
20
+
21
+ /**
22
+ * Subtract another vector from this one.
23
+ * @param v - Vector to subtract
24
+ * @returns New vector representing the difference
25
+ */
26
+ sub(v: Vec3): Vec3 {
27
+ return new Vec3(this.x - v.x, this.y - v.y, this.z - v.z);
28
+ }
29
+
30
+ /**
31
+ * Scale this vector by a scalar value.
32
+ * @param s - Scalar multiplier
33
+ * @returns New scaled vector
34
+ */
35
+ scale(s: number): Vec3 {
36
+ return new Vec3(this.x * s, this.y * s, this.z * s);
37
+ }
38
+
39
+ /**
40
+ * Compute the dot product with another vector.
41
+ * @param v - Vector to dot with
42
+ * @returns Scalar dot product value
43
+ */
44
+ dot(v: Vec3): number {
45
+ return this.x * v.x + this.y * v.y + this.z * v.z;
46
+ }
47
+
48
+ /**
49
+ * Compute the cross product with another vector.
50
+ * @param v - Vector to cross with
51
+ * @returns New vector perpendicular to both inputs
52
+ */
53
+ cross(v: Vec3): Vec3 {
54
+ return new Vec3(
55
+ this.y * v.z - this.z * v.y,
56
+ this.z * v.x - this.x * v.z,
57
+ this.x * v.y - this.y * v.x
58
+ );
59
+ }
60
+
61
+ /**
62
+ * Get the magnitude (length) of this vector.
63
+ * @returns Euclidean length
64
+ */
65
+ length(): number {
66
+ return Math.sqrt(this.x * this.x + this.y * this.y + this.z * this.z);
67
+ }
68
+
69
+ /**
70
+ * Get a unit vector in the same direction.
71
+ * Returns zero vector if length is zero.
72
+ * @returns Normalized unit vector
73
+ */
74
+ normalize(): Vec3 {
75
+ const len = this.length();
76
+ if (len === 0) return new Vec3(0, 0, 0);
77
+ return this.scale(1 / len);
78
+ }
79
+
80
+ /**
81
+ * Compute the distance to another vector.
82
+ * @param v - Target vector
83
+ * @returns Euclidean distance between vectors
84
+ */
85
+ distance(v: Vec3): number {
86
+ return this.sub(v).length();
87
+ }
88
+
89
+ /**
90
+ * Linear interpolation between this vector and another.
91
+ * @param v - Target vector
92
+ * @param t - Parameter in [0, 1] (0 = this, 1 = v)
93
+ * @returns Interpolated vector
94
+ */
95
+ lerp(v: Vec3, t: number): Vec3 {
96
+ return new Vec3(
97
+ this.x + (v.x - this.x) * t,
98
+ this.y + (v.y - this.y) * t,
99
+ this.z + (v.z - this.z) * t
100
+ );
101
+ }
102
+
103
+ /**
104
+ * Get the negation of this vector.
105
+ * @returns Vector pointing in opposite direction
106
+ */
107
+ negate(): Vec3 {
108
+ return new Vec3(-this.x, -this.y, -this.z);
109
+ }
110
+
111
+ /**
112
+ * Create a copy of this vector.
113
+ * @returns New vector with same components
114
+ */
115
+ clone(): Vec3 {
116
+ return new Vec3(this.x, this.y, this.z);
117
+ }
118
+
119
+ /**
120
+ * Check equality with another vector within tolerance.
121
+ * @param v - Vector to compare
122
+ * @param eps - Tolerance (default 1e-10)
123
+ * @returns True if vectors are approximately equal
124
+ */
125
+ equals(v: Vec3, eps = 1e-10): boolean {
126
+ return (
127
+ Math.abs(this.x - v.x) < eps &&
128
+ Math.abs(this.y - v.y) < eps &&
129
+ Math.abs(this.z - v.z) < eps
130
+ );
131
+ }
132
+
133
+ /**
134
+ * Convert to array format.
135
+ * @returns Tuple [x, y, z]
136
+ */
137
+ toArray(): [number, number, number] {
138
+ return [this.x, this.y, this.z];
139
+ }
140
+
141
+ /**
142
+ * Create a Vec3 from a plain object or JSON.
143
+ * @param json - Object with x, y, z properties
144
+ * @returns New Vec3 instance
145
+ */
146
+ static fromJSON(json: any): Vec3 {
147
+ if (json instanceof Vec3) return json;
148
+ return new Vec3(json.x ?? 0, json.y ?? 0, json.z ?? 0);
149
+ }
150
+
151
+ /** Zero vector (0, 0, 0) */
152
+ static readonly ZERO = new Vec3(0, 0, 0);
153
+ /** Unit X axis (1, 0, 0) */
154
+ static readonly X = new Vec3(1, 0, 0);
155
+ /** Unit Y axis (0, 1, 0) */
156
+ static readonly Y = new Vec3(0, 1, 0);
157
+ /** Unit Z axis (0, 0, 1) */
158
+ static readonly Z = new Vec3(0, 0, 1);
159
+ }
package/src/engine.ts ADDED
@@ -0,0 +1,92 @@
1
+ import { WASM_B64 } from "./wasm-base64.js";
2
+ import * as bg from "../wasm/okgeometrycore_bg.js";
3
+
4
+ let initialized = false;
5
+ let wasmExports: Record<string, unknown> | null = null;
6
+
7
+ const engineGlobal = globalThis as typeof globalThis & {
8
+ __okgeometry_boolean_should_cancel?: () => boolean;
9
+ };
10
+
11
+ if (typeof engineGlobal.__okgeometry_boolean_should_cancel !== "function") {
12
+ engineGlobal.__okgeometry_boolean_should_cancel = () => false;
13
+ }
14
+
15
+ function buildWasmImports(requiredNames: string[] = []): Record<string, unknown> {
16
+ const bgAny = bg as Record<string, unknown>;
17
+ const importModule: Record<string, unknown> = { ...bgAny };
18
+ const cancelKey = Object.keys(importModule).find(k => k.startsWith("__wbg___okgeometry_boolean_should_cancel_"));
19
+ const cancelFn = () => {
20
+ try {
21
+ return !!engineGlobal.__okgeometry_boolean_should_cancel?.();
22
+ } catch {
23
+ return false;
24
+ }
25
+ };
26
+ if (cancelKey) {
27
+ importModule[cancelKey] = cancelFn;
28
+ } else {
29
+ // Fallback to current known symbol in generated bindings.
30
+ importModule.__wbg___okgeometry_boolean_should_cancel_3e76652b5286d323 = cancelFn;
31
+ }
32
+
33
+ // Fill hash-suffixed imports that may not be exported by generated glue in this runtime.
34
+ for (const name of requiredNames) {
35
+ const existing = importModule[name];
36
+ if (typeof existing === "function") {
37
+ continue;
38
+ }
39
+ if (name.startsWith("__wbg___okgeometry_boolean_should_cancel_")) {
40
+ importModule[name] = cancelFn;
41
+ continue;
42
+ }
43
+ if (name.startsWith("__wbg_now_")) {
44
+ importModule[name] = () => Date.now();
45
+ continue;
46
+ }
47
+ if (name.startsWith("__wbg___wbindgen_throw_")) {
48
+ importModule[name] = () => {
49
+ throw new Error("WASM trap: __wbindgen_throw");
50
+ };
51
+ continue;
52
+ }
53
+ if (name === "__wbindgen_init_externref_table") {
54
+ importModule[name] = () => {};
55
+ continue;
56
+ }
57
+ }
58
+
59
+ return importModule;
60
+ }
61
+
62
+ export async function init(): Promise<void> {
63
+ if (initialized) return;
64
+ const raw = atob(WASM_B64);
65
+ const bytes = new Uint8Array(raw.length);
66
+ for (let i = 0; i < raw.length; i++) bytes[i] = raw.charCodeAt(i);
67
+
68
+ const wasmModule = await WebAssembly.compile(bytes.buffer);
69
+ const requiredNames = WebAssembly.Module.imports(wasmModule)
70
+ .filter((imp) => imp.module === "./okgeometrycore_bg.js")
71
+ .map((imp) => imp.name);
72
+ const importModule = buildWasmImports(requiredNames);
73
+ const instance = await WebAssembly.instantiate(wasmModule, {
74
+ "./okgeometrycore_bg.js": importModule as any,
75
+ });
76
+ wasmExports = instance.exports as Record<string, unknown>;
77
+
78
+ (bg as any).__wbg_set_wasm(instance.exports);
79
+ (instance.exports as any).__wbindgen_start();
80
+
81
+ initialized = true;
82
+ }
83
+
84
+ export function ensureInit(): void {
85
+ if (!initialized) {
86
+ throw new Error("OkGeometry WASM not initialized. Call `await init()` before using geometry operations.");
87
+ }
88
+ }
89
+
90
+ export function isInitialized(): boolean {
91
+ return initialized;
92
+ }
package/src/index.ts ADDED
@@ -0,0 +1,45 @@
1
+ // Core initialization
2
+ export { init, isInitialized } from "./engine.js";
3
+
4
+ // Shared types and utilities
5
+ export type {
6
+ SweepableCurve,
7
+ LoftableCurve,
8
+ RotationAxis,
9
+ CurveSegment,
10
+ } from "./types.js";
11
+ export { CurveTypeCode, SegmentTypeCode } from "./types.js";
12
+ export {
13
+ pointsToCoords,
14
+ coordsToPoints,
15
+ parsePolylineBuffer,
16
+ parseIntersectionPoints,
17
+ } from "./BufferCodec.js";
18
+
19
+ // Primitive types
20
+ export { Vec3 } from "./Vec3.js";
21
+ export { Point } from "./Point.js";
22
+ export { Plane } from "./Plane.js";
23
+ export { Ray } from "./Ray.js";
24
+
25
+ // Curve types
26
+ export { Line } from "./Line.js";
27
+ export { Circle } from "./Circle.js";
28
+ export { Arc } from "./Arc.js";
29
+ export { Polyline } from "./Polyline.js";
30
+ export { Polygon } from "./Polygon.js";
31
+ export { PolyCurve } from "./PolyCurve.js";
32
+ export { NurbsCurve } from "./NurbsCurve.js";
33
+ export { NurbsSurface } from "./NurbsSurface.js";
34
+
35
+ // Mesh and operations
36
+ export { Mesh, MeshBooleanExecutionError } from "./Mesh.js";
37
+ export type {
38
+ MeshBooleanLimits,
39
+ MeshBooleanOptions,
40
+ MeshBooleanAsyncOptions,
41
+ MeshBooleanErrorCode,
42
+ MeshBooleanErrorPayload,
43
+ MeshBooleanProgressEvent,
44
+ } from "./Mesh.js";
45
+ export { intersect } from "./Geometry.js";