okgeometry-api 1.14.0 → 1.15.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.
- package/dist/Brep.d.ts +72 -0
- package/dist/Brep.d.ts.map +1 -1
- package/dist/Brep.js +136 -0
- package/dist/Brep.js.map +1 -1
- package/dist/Mesh.d.ts +69 -0
- package/dist/Mesh.d.ts.map +1 -1
- package/dist/Mesh.js +145 -0
- package/dist/Mesh.js.map +1 -1
- package/dist/NurbsCurve.d.ts +78 -0
- package/dist/NurbsCurve.d.ts.map +1 -1
- package/dist/NurbsCurve.js +118 -0
- package/dist/NurbsCurve.js.map +1 -1
- package/dist/NurbsSurface.d.ts +23 -0
- package/dist/NurbsSurface.d.ts.map +1 -1
- package/dist/NurbsSurface.js +40 -0
- package/dist/NurbsSurface.js.map +1 -1
- package/dist/Polyline.d.ts +47 -0
- package/dist/Polyline.d.ts.map +1 -1
- package/dist/Polyline.js +45 -0
- package/dist/Polyline.js.map +1 -1
- package/dist/wasm-base64.d.ts +1 -1
- package/dist/wasm-base64.d.ts.map +1 -1
- package/dist/wasm-base64.js +1 -1
- package/dist/wasm-base64.js.map +1 -1
- package/dist/wasm-bindings.d.ts +208 -0
- package/dist/wasm-bindings.d.ts.map +1 -1
- package/dist/wasm-bindings.js +307 -0
- package/dist/wasm-bindings.js.map +1 -1
- package/package.json +54 -52
- package/src/Brep.ts +149 -0
- package/src/Mesh.ts +173 -0
- package/src/NurbsCurve.ts +129 -0
- package/src/NurbsSurface.ts +41 -0
- package/src/Polyline.ts +145 -95
- package/src/wasm-base64.ts +1 -1
- package/src/wasm-bindings.d.ts +186 -0
- package/src/wasm-bindings.js +318 -0
package/dist/Mesh.js
CHANGED
|
@@ -2159,6 +2159,151 @@ export class Mesh {
|
|
|
2159
2159
|
const outside = readGroup();
|
|
2160
2160
|
return { inside, outside };
|
|
2161
2161
|
}
|
|
2162
|
+
/**
|
|
2163
|
+
* Compute all transversal crossing points of a polyline with this mesh.
|
|
2164
|
+
* Works on OPEN meshes (sheets) — unlike `clipPolyline`, the mesh is NOT
|
|
2165
|
+
* required to be a closed volume.
|
|
2166
|
+
*
|
|
2167
|
+
* Hits are deduplicated (shared-edge / shared-vertex crossings merge into
|
|
2168
|
+
* one, keeping the smallest triangle index) and sorted by
|
|
2169
|
+
* (segmentIndex, segmentT). Coplanar sliding overlaps yield no hits.
|
|
2170
|
+
* Segment `i` runs from point `i` to point `(i + 1) % n`; open polylines
|
|
2171
|
+
* have n − 1 segments, closed ones n (the wrap segment).
|
|
2172
|
+
*
|
|
2173
|
+
* @param polyline - Polyline (closedness inferred) or raw point list
|
|
2174
|
+
* @param closed - Treat the points as a closed loop (defaults to the
|
|
2175
|
+
* polyline's own closedness; required when passing a raw point list)
|
|
2176
|
+
* @returns Crossings with the 3D point, segment index/parameter, and
|
|
2177
|
+
* triangle index
|
|
2178
|
+
*/
|
|
2179
|
+
intersectPolyline(polyline, closed) {
|
|
2180
|
+
ensureInit();
|
|
2181
|
+
const { flat, isClosed } = Mesh.flattenPolylineArg(polyline, closed, "Mesh.intersectPolyline");
|
|
2182
|
+
const buf = wasm.mesh_polyline_intersection_points(this._vertexCount, this._buffer, flat, isClosed);
|
|
2183
|
+
if (buf.length === 0) {
|
|
2184
|
+
throw new Error("Mesh.intersectPolyline failed — the mesh and polyline must be non-degenerate.");
|
|
2185
|
+
}
|
|
2186
|
+
const count = buf[0];
|
|
2187
|
+
const hits = [];
|
|
2188
|
+
for (let i = 0; i < count; i++) {
|
|
2189
|
+
const off = 1 + i * 6;
|
|
2190
|
+
hits.push({
|
|
2191
|
+
point: new Point(buf[off], buf[off + 1], buf[off + 2]),
|
|
2192
|
+
segmentIndex: buf[off + 3],
|
|
2193
|
+
segmentT: buf[off + 4],
|
|
2194
|
+
triangleIndex: buf[off + 5],
|
|
2195
|
+
});
|
|
2196
|
+
}
|
|
2197
|
+
return hits;
|
|
2198
|
+
}
|
|
2199
|
+
/**
|
|
2200
|
+
* Split a polyline into pieces at every crossing with this mesh (open
|
|
2201
|
+
* sheets allowed). Hit points become the shared endpoints of adjacent
|
|
2202
|
+
* pieces; a closed loop is opened at the first crossing (N crossings → N
|
|
2203
|
+
* pieces), an open polyline yields N + 1 pieces. With no crossings the
|
|
2204
|
+
* original polyline comes back as one piece. Pieces are NOT classified —
|
|
2205
|
+
* use `clipPolyline` (closed volume, containment) or
|
|
2206
|
+
* `clipPolylineBySheet` (oriented sheet, signed side) for classification.
|
|
2207
|
+
*
|
|
2208
|
+
* @param polyline - Polyline (closedness inferred) or raw point list
|
|
2209
|
+
* @param closed - Treat the points as a closed loop (defaults to the
|
|
2210
|
+
* polyline's own closedness; required when passing a raw point list)
|
|
2211
|
+
* @returns Polyline pieces in order along the input
|
|
2212
|
+
*/
|
|
2213
|
+
splitPolyline(polyline, closed) {
|
|
2214
|
+
ensureInit();
|
|
2215
|
+
const { flat, isClosed } = Mesh.flattenPolylineArg(polyline, closed, "Mesh.splitPolyline");
|
|
2216
|
+
const buf = wasm.mesh_split_polyline(this._vertexCount, this._buffer, flat, isClosed);
|
|
2217
|
+
if (buf.length === 0) {
|
|
2218
|
+
throw new Error("Mesh.splitPolyline failed — the mesh and polyline must be non-degenerate.");
|
|
2219
|
+
}
|
|
2220
|
+
return parsePolylineBuf(buf).map(pts => new Polyline(pts));
|
|
2221
|
+
}
|
|
2222
|
+
/**
|
|
2223
|
+
* Clip a polyline by this mesh treated as an OPEN oriented sheet: the
|
|
2224
|
+
* polyline is split at every crossing and each piece is classified by the
|
|
2225
|
+
* SIGNED SIDE of the sheet — `inside` = in FRONT of the sheet normal,
|
|
2226
|
+
* `outside` = behind it (the mesh's stored winding defines the normals).
|
|
2227
|
+
*
|
|
2228
|
+
* This is side classification, NOT containment — unlike `clipPolyline`,
|
|
2229
|
+
* which requires a CLOSED volume: the sheet may be open, and pieces far
|
|
2230
|
+
* from it still classify deterministically by the nearest facet's normal.
|
|
2231
|
+
* Pieces lying ON the sheet default to `inside`. Adjacent same-side pieces
|
|
2232
|
+
* (e.g. from a touch, not a crossing) merge back into one run; closed
|
|
2233
|
+
* loops merge the run spanning the seam.
|
|
2234
|
+
*
|
|
2235
|
+
* @param polyline - Polyline (closedness inferred) or raw point list
|
|
2236
|
+
* @param closed - Treat the points as a closed loop (defaults to the
|
|
2237
|
+
* polyline's own closedness; required when passing a raw point list)
|
|
2238
|
+
*/
|
|
2239
|
+
clipPolylineBySheet(polyline, closed) {
|
|
2240
|
+
ensureInit();
|
|
2241
|
+
const { flat, isClosed } = Mesh.flattenPolylineArg(polyline, closed, "Mesh.clipPolylineBySheet");
|
|
2242
|
+
const buf = wasm.mesh_clip_polyline_by_sheet(this._vertexCount, this._buffer, flat, isClosed);
|
|
2243
|
+
if (buf.length === 0) {
|
|
2244
|
+
throw new Error("Mesh.clipPolylineBySheet failed — the sheet and polyline must be non-degenerate.");
|
|
2245
|
+
}
|
|
2246
|
+
// Two concatenated polyline groups: inside first, then outside — same
|
|
2247
|
+
// packing as clipPolyline.
|
|
2248
|
+
let idx = 0;
|
|
2249
|
+
const readGroup = () => {
|
|
2250
|
+
const group = [];
|
|
2251
|
+
const count = buf[idx++];
|
|
2252
|
+
for (let i = 0; i < count; i++) {
|
|
2253
|
+
const n = buf[idx++];
|
|
2254
|
+
const points = [];
|
|
2255
|
+
for (let k = 0; k < n; k++) {
|
|
2256
|
+
points.push(new Point(buf[idx], buf[idx + 1], buf[idx + 2]));
|
|
2257
|
+
idx += 3;
|
|
2258
|
+
}
|
|
2259
|
+
if (points.length >= 2)
|
|
2260
|
+
group.push(new Polyline(points));
|
|
2261
|
+
}
|
|
2262
|
+
return group;
|
|
2263
|
+
};
|
|
2264
|
+
const inside = readGroup();
|
|
2265
|
+
const outside = readGroup();
|
|
2266
|
+
return { inside, outside };
|
|
2267
|
+
}
|
|
2268
|
+
/**
|
|
2269
|
+
* Flatten a Polyline-or-points argument into WASM coords + closed flag.
|
|
2270
|
+
*
|
|
2271
|
+
* Closed inputs following the duplicated-seam convention (terminal point
|
|
2272
|
+
* repeating the first) have the duplicate STRIPPED before crossing the
|
|
2273
|
+
* boundary — the kernel's closed-polyline encoding is seam-free (the wrap
|
|
2274
|
+
* segment is implicit), and a duplicated seam would add a zero-length wrap
|
|
2275
|
+
* segment / doubled seam vertex to split pieces.
|
|
2276
|
+
*/
|
|
2277
|
+
static flattenPolylineArg(polyline, closed, context) {
|
|
2278
|
+
let pts = Array.isArray(polyline) ? polyline : polyline.points;
|
|
2279
|
+
if (pts.length < 2) {
|
|
2280
|
+
throw new Error(`${context} needs at least 2 polyline points`);
|
|
2281
|
+
}
|
|
2282
|
+
const isClosed = closed ?? (!Array.isArray(polyline) && polyline.isClosed());
|
|
2283
|
+
if (isClosed && pts.length > 2) {
|
|
2284
|
+
// Scale-relative epsilon for the duplicate-seam test.
|
|
2285
|
+
let maxAbs = 0;
|
|
2286
|
+
for (const p of pts) {
|
|
2287
|
+
maxAbs = Math.max(maxAbs, Math.abs(p.x), Math.abs(p.y), Math.abs(p.z));
|
|
2288
|
+
}
|
|
2289
|
+
const eps = (1 + maxAbs) * 1e-12;
|
|
2290
|
+
const first = pts[0];
|
|
2291
|
+
const last = pts[pts.length - 1];
|
|
2292
|
+
const dx = first.x - last.x;
|
|
2293
|
+
const dy = first.y - last.y;
|
|
2294
|
+
const dz = first.z - last.z;
|
|
2295
|
+
if (Math.sqrt(dx * dx + dy * dy + dz * dz) <= eps) {
|
|
2296
|
+
pts = pts.slice(0, -1);
|
|
2297
|
+
}
|
|
2298
|
+
}
|
|
2299
|
+
const flat = new Float64Array(pts.length * 3);
|
|
2300
|
+
for (let i = 0; i < pts.length; i++) {
|
|
2301
|
+
flat[i * 3] = pts[i].x;
|
|
2302
|
+
flat[i * 3 + 1] = pts[i].y;
|
|
2303
|
+
flat[i * 3 + 2] = pts[i].z;
|
|
2304
|
+
}
|
|
2305
|
+
return { flat, isClosed };
|
|
2306
|
+
}
|
|
2162
2307
|
/**
|
|
2163
2308
|
* Apply a 4x4 transformation matrix.
|
|
2164
2309
|
* @param matrix - Row-major flat array of 16 numbers
|