brepjs 18.116.0 → 18.116.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.
package/dist/brepjs.cjs
CHANGED
|
@@ -17,7 +17,7 @@ const require_arrayAccess = require("./arrayAccess-e4H9cBfh.cjs");
|
|
|
17
17
|
const require_surfaceBuilders = require("./surfaceBuilders-UyyfZy8w.cjs");
|
|
18
18
|
const require_solidBuilders = require("./solidBuilders-DiUv_mD0.cjs");
|
|
19
19
|
const require_healingFns = require("./healingFns-xLJ6Cp_O.cjs");
|
|
20
|
-
const require_threadFns = require("./threadFns-
|
|
20
|
+
const require_threadFns = require("./threadFns-BqWHWpea.cjs");
|
|
21
21
|
const require_blueprintSketcher = require("./blueprintSketcher-RK-cH6ps.cjs");
|
|
22
22
|
const require_helpers = require("./helpers-BSLPCflF.cjs");
|
|
23
23
|
const require_drawFns = require("./drawFns-DNxs7PAT.cjs");
|
|
@@ -5837,48 +5837,144 @@ function cacheKey(node, env, kernelId, tolerance) {
|
|
|
5837
5837
|
const tolHash = tolerance === void 0 ? "d" : fnvMixNumber(fnvInit(), tolerance).toString(16);
|
|
5838
5838
|
return `${toHex(node.structuralHash)}:${kernelId}:${toHex(projHash)}:${tolHash}`;
|
|
5839
5839
|
}
|
|
5840
|
+
var IDENTITY_QUAT = [
|
|
5841
|
+
1,
|
|
5842
|
+
0,
|
|
5843
|
+
0,
|
|
5844
|
+
0
|
|
5845
|
+
];
|
|
5846
|
+
/** Resolve a Rotate node's angle/axis/center in `env`, applying the same
|
|
5847
|
+
* defaults as the evaluator (Z axis, origin pivot). Null if any free param
|
|
5848
|
+
* can't be evaluated, so the caller stops peeling there. */
|
|
5849
|
+
function evalRotateParams(node, env) {
|
|
5850
|
+
const a = evalScalar(node.angle, env, "evaluateMesh.peelRigid");
|
|
5851
|
+
if (!a.ok) return null;
|
|
5852
|
+
const axis = node.axis ? evalVec3(node.axis, env, "evaluateMesh.peelRigid") : require_errors.ok([
|
|
5853
|
+
0,
|
|
5854
|
+
0,
|
|
5855
|
+
1
|
|
5856
|
+
]);
|
|
5857
|
+
if (!axis.ok) return null;
|
|
5858
|
+
const center = node.at ? evalVec3(node.at, env, "evaluateMesh.peelRigid") : require_errors.ok([
|
|
5859
|
+
0,
|
|
5860
|
+
0,
|
|
5861
|
+
0
|
|
5862
|
+
]);
|
|
5863
|
+
if (!center.ok) return null;
|
|
5864
|
+
return {
|
|
5865
|
+
angle: a.value,
|
|
5866
|
+
axis: axis.value,
|
|
5867
|
+
center: center.value
|
|
5868
|
+
};
|
|
5869
|
+
}
|
|
5840
5870
|
/**
|
|
5841
|
-
* Peel outer
|
|
5842
|
-
*
|
|
5843
|
-
*
|
|
5844
|
-
*
|
|
5845
|
-
*
|
|
5871
|
+
* Peel outer rigid-motion nodes (Translate / Rotate) off `node`, composing them
|
|
5872
|
+
* into a single rotation + translation. A rigid motion shares its inner
|
|
5873
|
+
* geometry's tessellation — the shape path re-tags it via `locate` (#1633) — so
|
|
5874
|
+
* the inner meshes once and the cached mesh is moved per placement instead of
|
|
5875
|
+
* re-tessellating. Stops at the first non-rigid node (Scale/Mirror/boolean/…) or
|
|
5876
|
+
* one whose parameters can't be evaluated in `env`.
|
|
5877
|
+
*
|
|
5878
|
+
* Composition is outer∘inner: peeling outward, each node's local transform acts
|
|
5879
|
+
* on points the inner nodes already placed, so it post-multiplies the
|
|
5880
|
+
* accumulator. A pure-translation chain keeps the identity rotation, so the mesh
|
|
5881
|
+
* move below degenerates to the exact vertex-shift fast path (normals untouched).
|
|
5846
5882
|
*/
|
|
5847
|
-
function
|
|
5883
|
+
function peelRigid(node, env) {
|
|
5848
5884
|
let inner = node;
|
|
5849
|
-
let
|
|
5850
|
-
let
|
|
5851
|
-
|
|
5852
|
-
|
|
5853
|
-
|
|
5885
|
+
let rot = IDENTITY_QUAT;
|
|
5886
|
+
let trans = [
|
|
5887
|
+
0,
|
|
5888
|
+
0,
|
|
5889
|
+
0
|
|
5890
|
+
];
|
|
5891
|
+
for (;;) if (inner.kind === "Translate") {
|
|
5892
|
+
const v = evalVec3(inner.vector, env, "evaluateMesh.peelRigid");
|
|
5854
5893
|
if (!v.ok) break;
|
|
5855
|
-
|
|
5856
|
-
|
|
5857
|
-
|
|
5894
|
+
const rv = require_threadFns.quatRotate(rot, v.value);
|
|
5895
|
+
trans = [
|
|
5896
|
+
trans[0] + rv[0],
|
|
5897
|
+
trans[1] + rv[1],
|
|
5898
|
+
trans[2] + rv[2]
|
|
5899
|
+
];
|
|
5858
5900
|
inner = inner.target;
|
|
5859
|
-
}
|
|
5901
|
+
} else if (inner.kind === "Rotate") {
|
|
5902
|
+
const p = evalRotateParams(inner, env);
|
|
5903
|
+
if (!p) break;
|
|
5904
|
+
const r = require_threadFns.quatFromAxisAngle(p.axis, p.angle * Math.PI / 180);
|
|
5905
|
+
const newRot = require_threadFns.quatMultiply(rot, r);
|
|
5906
|
+
const rotC = require_threadFns.quatRotate(rot, p.center);
|
|
5907
|
+
const newRotC = require_threadFns.quatRotate(newRot, p.center);
|
|
5908
|
+
trans = [
|
|
5909
|
+
trans[0] + rotC[0] - newRotC[0],
|
|
5910
|
+
trans[1] + rotC[1] - newRotC[1],
|
|
5911
|
+
trans[2] + rotC[2] - newRotC[2]
|
|
5912
|
+
];
|
|
5913
|
+
rot = newRot;
|
|
5914
|
+
inner = inner.target;
|
|
5915
|
+
} else break;
|
|
5860
5916
|
return {
|
|
5861
5917
|
inner,
|
|
5862
|
-
|
|
5863
|
-
|
|
5864
|
-
oy,
|
|
5865
|
-
oz
|
|
5866
|
-
]
|
|
5918
|
+
rot,
|
|
5919
|
+
trans
|
|
5867
5920
|
};
|
|
5868
5921
|
}
|
|
5869
|
-
|
|
5870
|
-
|
|
5871
|
-
|
|
5872
|
-
|
|
5873
|
-
|
|
5874
|
-
|
|
5875
|
-
|
|
5876
|
-
|
|
5877
|
-
|
|
5922
|
+
function isIdentityQuat(q) {
|
|
5923
|
+
return q[0] === 1 && q[1] === 0 && q[2] === 0 && q[3] === 0;
|
|
5924
|
+
}
|
|
5925
|
+
/**
|
|
5926
|
+
* Write `src` (flat xyz) rigidly transformed by quaternion (qw,qx,qy,qz) then
|
|
5927
|
+
* translation (tx,ty,tz) into `dst`. The quaternion-rotate math is inlined with
|
|
5928
|
+
* scalar locals — no per-vertex array allocation — because this runs once per
|
|
5929
|
+
* mesh vertex/normal and helper-allocated vector math regressed the gridfinity
|
|
5930
|
+
* benchmark 17% (see `utils/vec3.ts`). Pass zero translation for normals.
|
|
5931
|
+
*/
|
|
5932
|
+
function rotateXyzBuffer(dst, src, qw, qx, qy, qz, tx, ty, tz) {
|
|
5933
|
+
for (let i = 0; i < src.length; i += 3) {
|
|
5934
|
+
const vx = src[i] ?? 0;
|
|
5935
|
+
const vy = src[i + 1] ?? 0;
|
|
5936
|
+
const vz = src[i + 2] ?? 0;
|
|
5937
|
+
const cx = 2 * (qy * vz - qz * vy);
|
|
5938
|
+
const cy = 2 * (qz * vx - qx * vz);
|
|
5939
|
+
const cz = 2 * (qx * vy - qy * vx);
|
|
5940
|
+
dst[i] = vx + qw * cx + (qy * cz - qz * cy) + tx;
|
|
5941
|
+
dst[i + 1] = vy + qw * cy + (qz * cx - qx * cz) + ty;
|
|
5942
|
+
dst[i + 2] = vz + qw * cz + (qx * cy - qy * cx) + tz;
|
|
5878
5943
|
}
|
|
5944
|
+
}
|
|
5945
|
+
/**
|
|
5946
|
+
* Apply a rigid motion to a mesh: vertices get the rotation then translation,
|
|
5947
|
+
* normals get the rotation only (a unit rotation preserves length, so no
|
|
5948
|
+
* renormalization). UVs and triangles are motion-invariant. A pure translation
|
|
5949
|
+
* (identity rotation) keeps the source normals array by reference and only
|
|
5950
|
+
* shifts vertices — the exact previous translation-only fast path.
|
|
5951
|
+
*/
|
|
5952
|
+
function transformMeshRigid(m, rot, trans) {
|
|
5953
|
+
const [tx, ty, tz] = trans;
|
|
5954
|
+
const pureTranslation = isIdentityQuat(rot);
|
|
5955
|
+
if (pureTranslation && tx === 0 && ty === 0 && tz === 0) return m;
|
|
5956
|
+
const src = m.vertices;
|
|
5957
|
+
const vertices = new Float32Array(src.length);
|
|
5958
|
+
if (pureTranslation) {
|
|
5959
|
+
for (let i = 0; i < src.length; i += 3) {
|
|
5960
|
+
vertices[i] = (src[i] ?? 0) + tx;
|
|
5961
|
+
vertices[i + 1] = (src[i + 1] ?? 0) + ty;
|
|
5962
|
+
vertices[i + 2] = (src[i + 2] ?? 0) + tz;
|
|
5963
|
+
}
|
|
5964
|
+
return {
|
|
5965
|
+
...m,
|
|
5966
|
+
vertices
|
|
5967
|
+
};
|
|
5968
|
+
}
|
|
5969
|
+
const [qw, qx, qy, qz] = rot;
|
|
5970
|
+
rotateXyzBuffer(vertices, src, qw, qx, qy, qz, tx, ty, tz);
|
|
5971
|
+
const sn = m.normals;
|
|
5972
|
+
const normals = new Float32Array(sn.length);
|
|
5973
|
+
rotateXyzBuffer(normals, sn, qw, qx, qy, qz, 0, 0, 0);
|
|
5879
5974
|
return {
|
|
5880
5975
|
...m,
|
|
5881
|
-
vertices
|
|
5976
|
+
vertices,
|
|
5977
|
+
normals
|
|
5882
5978
|
};
|
|
5883
5979
|
}
|
|
5884
5980
|
/**
|
|
@@ -5886,8 +5982,8 @@ function translateMesh(m, offset) {
|
|
|
5886
5982
|
* moved faces location-dependent hashes, so the inner mesh's `faceId`s describe
|
|
5887
5983
|
* the *unplaced* shape; remap them to the placed faces (1:1 by iteration order,
|
|
5888
5984
|
* since `locate` shares the source TShape) so face picking and metadata lookup
|
|
5889
|
-
* resolve against the placed mesh. Origins are
|
|
5890
|
-
* `faceId` changes.
|
|
5985
|
+
* resolve against the placed mesh. Origins are boolean-lineage tags, invariant
|
|
5986
|
+
* under any rigid motion, so only `faceId` changes.
|
|
5891
5987
|
*
|
|
5892
5988
|
* Takes pre-captured hash arrays (not shapes): a bounded shape cache can evict
|
|
5893
5989
|
* and dispose one shape while the other is being evaluated, so the caller reads
|
|
@@ -5983,7 +6079,7 @@ var Evaluator = class {
|
|
|
5983
6079
|
}
|
|
5984
6080
|
return require_errors.ok(cached);
|
|
5985
6081
|
}
|
|
5986
|
-
const { inner,
|
|
6082
|
+
const { inner, rot, trans } = peelRigid(node, env);
|
|
5987
6083
|
if (inner !== node) {
|
|
5988
6084
|
const innerMesh = this.evaluateMesh(inner, env, meshOpts);
|
|
5989
6085
|
if (!innerMesh.ok) return innerMesh;
|
|
@@ -5993,7 +6089,7 @@ var Evaluator = class {
|
|
|
5993
6089
|
const placedShape = this.evaluate(node, env);
|
|
5994
6090
|
if (!placedShape.ok) return placedShape;
|
|
5995
6091
|
const placedHashes = require_topologyQueryFns.getFaces(placedShape.value).map(require_shapeFns.getHashCode);
|
|
5996
|
-
const moved =
|
|
6092
|
+
const moved = transformMeshRigid(innerMesh.value, rot, trans);
|
|
5997
6093
|
const faceGroups = relocateFaceGroups(moved.faceGroups, innerHashes, placedHashes);
|
|
5998
6094
|
const placedSet = new Set(placedHashes);
|
|
5999
6095
|
if (faceGroups.every((g) => placedSet.has(g.faceId))) {
|
package/dist/brepjs.js
CHANGED
|
@@ -15,7 +15,7 @@ import { n as getAtOrThrow, r as lastOrThrow, t as firstOrThrow } from "./arrayA
|
|
|
15
15
|
import { _ as makeThreePointArc, d as makeCircle, h as makeLine, l as makeBSplineInterpolation, n as fill, r as makeFace, s as assembleWire } from "./surfaceBuilders-rkE-jE90.js";
|
|
16
16
|
import { _ as section$1, b as split$1, d as booleanPipeline, f as cut$2, g as intersect$2, h as fuseAll$2, m as fuse$2, p as cutAll$2, r as makeCylinder, t as makeCompound, v as sectionToFace$1, y as slice$1 } from "./solidBuilders-C32wXQWG.js";
|
|
17
17
|
import { A as toBufferGeometryData, C as shellWithEvolution, D as getNurbsCurveData, E as fuseAllBisect, M as toLODGeometryData, N as toLODGeometryLevels, O as getNurbsSurfaceData, P as toLineGeometryData, S as intersectWithEvolution, T as cutAllBisect, _ as positionOnCurve, a as healFace, b as filletWithEvolution, c as isValid$1, d as draft$1, f as fillet$1, g as variableFillet, h as thicken$1, i as heal$1, j as toGroupedBufferGeometryData, k as chamferDistAngle, l as solidFromShell, m as shell$1, n as fixSelfIntersection, o as healSolid, p as offset$1, r as fixShape, s as healWire, t as autoHeal, u as chamfer$1, v as chamferWithEvolution, w as checkBoolean, x as fuseWithEvolution, y as cutWithEvolution } from "./healingFns-2TJHHDg5.js";
|
|
18
|
-
import { A as setJointValue, B as
|
|
18
|
+
import { A as setJointValue, B as createAssemblyNode, C as cylindricalJoint, D as planarJoint, E as mechanismDOF, F as quatMultiply, G as circularPattern, H as removeChild, I as quatRotate, J as exportAssemblySTEP, K as gridPattern, L as addChild, M as sphericalJoint, N as quatFromAxisAngle, O as prismaticJoint, P as quatFromTo, R as collectShapes, S as addJoint, T as jointTransform, U as updateNode, V as findNode, W as walkAssembly, Y as createAssembly, _ as exportURDF, a as deserializeHistory, b as inverseKinematics, c as modifyStep, d as replayFrom, f as replayHistory, g as undoLast, h as stepsFrom, i as createRegistry, j as setJointValues, k as revoluteJoint, l as registerOperation, m as stepCount, n as addStep, o as findStep, p as serializeHistory, q as linearPattern, r as createHistory, s as getShape, t as thread, u as registerShape, v as importURDF, w as forwardKinematics, x as jointTrajectory, y as jointsFromDH, z as countNodes } from "./threadFns-KbYZu7Q9.js";
|
|
19
19
|
import { n as BaseSketcher2d, r as organiseBlueprints, t as BlueprintSketcher } from "./blueprintSketcher-7rtwqUHZ.js";
|
|
20
20
|
import { a as createTypedFinder, i as wireFinder, n as edgeFinder, r as faceFinder, t as getSingleFace } from "./helpers-DhJwFrkC.js";
|
|
21
21
|
import { A as sketchEllipse, D as makeBaseBox, E as deserializeDrawing, F as sketchRectangle, I as sketchRoundedRectangle, L as FaceSketcher, M as sketchHelix, N as sketchParametricFunction, O as polysideInnerRadius, P as sketchPolysides, R as Sketcher, S as drawText, _ as drawPolysides, a as drawingIntersect, b as drawSingleCircle, c as rotateDrawing, d as drawFaceOutline, f as drawProjection, g as drawPointsInterpolation, h as drawParametricFunction, i as drawingFuse, j as sketchFaceOffset, k as sketchCircle, l as scaleDrawing, m as drawEllipse, n as drawingCut, o as drawingToSketchOnPlane, p as drawCircle, r as drawingFillet, s as mirrorDrawing, t as drawingChamfer, u as translateDrawing, v as drawRectangle, w as draw, x as drawSingleEllipse, y as drawRoundedRectangle } from "./drawFns-SQIBls6p.js";
|
|
@@ -5840,48 +5840,144 @@ function cacheKey(node, env, kernelId, tolerance) {
|
|
|
5840
5840
|
const tolHash = tolerance === void 0 ? "d" : fnvMixNumber(fnvInit(), tolerance).toString(16);
|
|
5841
5841
|
return `${toHex(node.structuralHash)}:${kernelId}:${toHex(projHash)}:${tolHash}`;
|
|
5842
5842
|
}
|
|
5843
|
+
var IDENTITY_QUAT = [
|
|
5844
|
+
1,
|
|
5845
|
+
0,
|
|
5846
|
+
0,
|
|
5847
|
+
0
|
|
5848
|
+
];
|
|
5849
|
+
/** Resolve a Rotate node's angle/axis/center in `env`, applying the same
|
|
5850
|
+
* defaults as the evaluator (Z axis, origin pivot). Null if any free param
|
|
5851
|
+
* can't be evaluated, so the caller stops peeling there. */
|
|
5852
|
+
function evalRotateParams(node, env) {
|
|
5853
|
+
const a = evalScalar(node.angle, env, "evaluateMesh.peelRigid");
|
|
5854
|
+
if (!a.ok) return null;
|
|
5855
|
+
const axis = node.axis ? evalVec3(node.axis, env, "evaluateMesh.peelRigid") : ok([
|
|
5856
|
+
0,
|
|
5857
|
+
0,
|
|
5858
|
+
1
|
|
5859
|
+
]);
|
|
5860
|
+
if (!axis.ok) return null;
|
|
5861
|
+
const center = node.at ? evalVec3(node.at, env, "evaluateMesh.peelRigid") : ok([
|
|
5862
|
+
0,
|
|
5863
|
+
0,
|
|
5864
|
+
0
|
|
5865
|
+
]);
|
|
5866
|
+
if (!center.ok) return null;
|
|
5867
|
+
return {
|
|
5868
|
+
angle: a.value,
|
|
5869
|
+
axis: axis.value,
|
|
5870
|
+
center: center.value
|
|
5871
|
+
};
|
|
5872
|
+
}
|
|
5843
5873
|
/**
|
|
5844
|
-
* Peel outer
|
|
5845
|
-
*
|
|
5846
|
-
*
|
|
5847
|
-
*
|
|
5848
|
-
*
|
|
5874
|
+
* Peel outer rigid-motion nodes (Translate / Rotate) off `node`, composing them
|
|
5875
|
+
* into a single rotation + translation. A rigid motion shares its inner
|
|
5876
|
+
* geometry's tessellation — the shape path re-tags it via `locate` (#1633) — so
|
|
5877
|
+
* the inner meshes once and the cached mesh is moved per placement instead of
|
|
5878
|
+
* re-tessellating. Stops at the first non-rigid node (Scale/Mirror/boolean/…) or
|
|
5879
|
+
* one whose parameters can't be evaluated in `env`.
|
|
5880
|
+
*
|
|
5881
|
+
* Composition is outer∘inner: peeling outward, each node's local transform acts
|
|
5882
|
+
* on points the inner nodes already placed, so it post-multiplies the
|
|
5883
|
+
* accumulator. A pure-translation chain keeps the identity rotation, so the mesh
|
|
5884
|
+
* move below degenerates to the exact vertex-shift fast path (normals untouched).
|
|
5849
5885
|
*/
|
|
5850
|
-
function
|
|
5886
|
+
function peelRigid(node, env) {
|
|
5851
5887
|
let inner = node;
|
|
5852
|
-
let
|
|
5853
|
-
let
|
|
5854
|
-
|
|
5855
|
-
|
|
5856
|
-
|
|
5888
|
+
let rot = IDENTITY_QUAT;
|
|
5889
|
+
let trans = [
|
|
5890
|
+
0,
|
|
5891
|
+
0,
|
|
5892
|
+
0
|
|
5893
|
+
];
|
|
5894
|
+
for (;;) if (inner.kind === "Translate") {
|
|
5895
|
+
const v = evalVec3(inner.vector, env, "evaluateMesh.peelRigid");
|
|
5857
5896
|
if (!v.ok) break;
|
|
5858
|
-
|
|
5859
|
-
|
|
5860
|
-
|
|
5897
|
+
const rv = quatRotate(rot, v.value);
|
|
5898
|
+
trans = [
|
|
5899
|
+
trans[0] + rv[0],
|
|
5900
|
+
trans[1] + rv[1],
|
|
5901
|
+
trans[2] + rv[2]
|
|
5902
|
+
];
|
|
5861
5903
|
inner = inner.target;
|
|
5862
|
-
}
|
|
5904
|
+
} else if (inner.kind === "Rotate") {
|
|
5905
|
+
const p = evalRotateParams(inner, env);
|
|
5906
|
+
if (!p) break;
|
|
5907
|
+
const r = quatFromAxisAngle(p.axis, p.angle * Math.PI / 180);
|
|
5908
|
+
const newRot = quatMultiply(rot, r);
|
|
5909
|
+
const rotC = quatRotate(rot, p.center);
|
|
5910
|
+
const newRotC = quatRotate(newRot, p.center);
|
|
5911
|
+
trans = [
|
|
5912
|
+
trans[0] + rotC[0] - newRotC[0],
|
|
5913
|
+
trans[1] + rotC[1] - newRotC[1],
|
|
5914
|
+
trans[2] + rotC[2] - newRotC[2]
|
|
5915
|
+
];
|
|
5916
|
+
rot = newRot;
|
|
5917
|
+
inner = inner.target;
|
|
5918
|
+
} else break;
|
|
5863
5919
|
return {
|
|
5864
5920
|
inner,
|
|
5865
|
-
|
|
5866
|
-
|
|
5867
|
-
oy,
|
|
5868
|
-
oz
|
|
5869
|
-
]
|
|
5921
|
+
rot,
|
|
5922
|
+
trans
|
|
5870
5923
|
};
|
|
5871
5924
|
}
|
|
5872
|
-
|
|
5873
|
-
|
|
5874
|
-
|
|
5875
|
-
|
|
5876
|
-
|
|
5877
|
-
|
|
5878
|
-
|
|
5879
|
-
|
|
5880
|
-
|
|
5925
|
+
function isIdentityQuat(q) {
|
|
5926
|
+
return q[0] === 1 && q[1] === 0 && q[2] === 0 && q[3] === 0;
|
|
5927
|
+
}
|
|
5928
|
+
/**
|
|
5929
|
+
* Write `src` (flat xyz) rigidly transformed by quaternion (qw,qx,qy,qz) then
|
|
5930
|
+
* translation (tx,ty,tz) into `dst`. The quaternion-rotate math is inlined with
|
|
5931
|
+
* scalar locals — no per-vertex array allocation — because this runs once per
|
|
5932
|
+
* mesh vertex/normal and helper-allocated vector math regressed the gridfinity
|
|
5933
|
+
* benchmark 17% (see `utils/vec3.ts`). Pass zero translation for normals.
|
|
5934
|
+
*/
|
|
5935
|
+
function rotateXyzBuffer(dst, src, qw, qx, qy, qz, tx, ty, tz) {
|
|
5936
|
+
for (let i = 0; i < src.length; i += 3) {
|
|
5937
|
+
const vx = src[i] ?? 0;
|
|
5938
|
+
const vy = src[i + 1] ?? 0;
|
|
5939
|
+
const vz = src[i + 2] ?? 0;
|
|
5940
|
+
const cx = 2 * (qy * vz - qz * vy);
|
|
5941
|
+
const cy = 2 * (qz * vx - qx * vz);
|
|
5942
|
+
const cz = 2 * (qx * vy - qy * vx);
|
|
5943
|
+
dst[i] = vx + qw * cx + (qy * cz - qz * cy) + tx;
|
|
5944
|
+
dst[i + 1] = vy + qw * cy + (qz * cx - qx * cz) + ty;
|
|
5945
|
+
dst[i + 2] = vz + qw * cz + (qx * cy - qy * cx) + tz;
|
|
5881
5946
|
}
|
|
5947
|
+
}
|
|
5948
|
+
/**
|
|
5949
|
+
* Apply a rigid motion to a mesh: vertices get the rotation then translation,
|
|
5950
|
+
* normals get the rotation only (a unit rotation preserves length, so no
|
|
5951
|
+
* renormalization). UVs and triangles are motion-invariant. A pure translation
|
|
5952
|
+
* (identity rotation) keeps the source normals array by reference and only
|
|
5953
|
+
* shifts vertices — the exact previous translation-only fast path.
|
|
5954
|
+
*/
|
|
5955
|
+
function transformMeshRigid(m, rot, trans) {
|
|
5956
|
+
const [tx, ty, tz] = trans;
|
|
5957
|
+
const pureTranslation = isIdentityQuat(rot);
|
|
5958
|
+
if (pureTranslation && tx === 0 && ty === 0 && tz === 0) return m;
|
|
5959
|
+
const src = m.vertices;
|
|
5960
|
+
const vertices = new Float32Array(src.length);
|
|
5961
|
+
if (pureTranslation) {
|
|
5962
|
+
for (let i = 0; i < src.length; i += 3) {
|
|
5963
|
+
vertices[i] = (src[i] ?? 0) + tx;
|
|
5964
|
+
vertices[i + 1] = (src[i + 1] ?? 0) + ty;
|
|
5965
|
+
vertices[i + 2] = (src[i + 2] ?? 0) + tz;
|
|
5966
|
+
}
|
|
5967
|
+
return {
|
|
5968
|
+
...m,
|
|
5969
|
+
vertices
|
|
5970
|
+
};
|
|
5971
|
+
}
|
|
5972
|
+
const [qw, qx, qy, qz] = rot;
|
|
5973
|
+
rotateXyzBuffer(vertices, src, qw, qx, qy, qz, tx, ty, tz);
|
|
5974
|
+
const sn = m.normals;
|
|
5975
|
+
const normals = new Float32Array(sn.length);
|
|
5976
|
+
rotateXyzBuffer(normals, sn, qw, qx, qy, qz, 0, 0, 0);
|
|
5882
5977
|
return {
|
|
5883
5978
|
...m,
|
|
5884
|
-
vertices
|
|
5979
|
+
vertices,
|
|
5980
|
+
normals
|
|
5885
5981
|
};
|
|
5886
5982
|
}
|
|
5887
5983
|
/**
|
|
@@ -5889,8 +5985,8 @@ function translateMesh(m, offset) {
|
|
|
5889
5985
|
* moved faces location-dependent hashes, so the inner mesh's `faceId`s describe
|
|
5890
5986
|
* the *unplaced* shape; remap them to the placed faces (1:1 by iteration order,
|
|
5891
5987
|
* since `locate` shares the source TShape) so face picking and metadata lookup
|
|
5892
|
-
* resolve against the placed mesh. Origins are
|
|
5893
|
-
* `faceId` changes.
|
|
5988
|
+
* resolve against the placed mesh. Origins are boolean-lineage tags, invariant
|
|
5989
|
+
* under any rigid motion, so only `faceId` changes.
|
|
5894
5990
|
*
|
|
5895
5991
|
* Takes pre-captured hash arrays (not shapes): a bounded shape cache can evict
|
|
5896
5992
|
* and dispose one shape while the other is being evaluated, so the caller reads
|
|
@@ -5986,7 +6082,7 @@ var Evaluator = class {
|
|
|
5986
6082
|
}
|
|
5987
6083
|
return ok(cached);
|
|
5988
6084
|
}
|
|
5989
|
-
const { inner,
|
|
6085
|
+
const { inner, rot, trans } = peelRigid(node, env);
|
|
5990
6086
|
if (inner !== node) {
|
|
5991
6087
|
const innerMesh = this.evaluateMesh(inner, env, meshOpts);
|
|
5992
6088
|
if (!innerMesh.ok) return innerMesh;
|
|
@@ -5996,7 +6092,7 @@ var Evaluator = class {
|
|
|
5996
6092
|
const placedShape = this.evaluate(node, env);
|
|
5997
6093
|
if (!placedShape.ok) return placedShape;
|
|
5998
6094
|
const placedHashes = getFaces(placedShape.value).map(getHashCode);
|
|
5999
|
-
const moved =
|
|
6095
|
+
const moved = transformMeshRigid(innerMesh.value, rot, trans);
|
|
6000
6096
|
const faceGroups = relocateFaceGroups(moved.faceGroups, innerHashes, placedHashes);
|
|
6001
6097
|
const placedSet = new Set(placedHashes);
|
|
6002
6098
|
if (faceGroups.every((g) => placedSet.has(g.faceId))) {
|
package/dist/operations.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_threadFns = require("./threadFns-
|
|
2
|
+
const require_threadFns = require("./threadFns-BqWHWpea.cjs");
|
|
3
3
|
const require_loftFns = require("./loftFns-fpTmrIdd.cjs");
|
|
4
4
|
exports.addChild = require_threadFns.addChild;
|
|
5
5
|
exports.addJoint = require_threadFns.addJoint;
|
package/dist/operations.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { A as setJointValue, B as
|
|
1
|
+
import { A as setJointValue, B as createAssemblyNode, C as cylindricalJoint, D as planarJoint, E as mechanismDOF, G as circularPattern, H as removeChild, J as exportAssemblySTEP, K as gridPattern, L as addChild, M as sphericalJoint, O as prismaticJoint, R as collectShapes, S as addJoint, T as jointTransform, U as updateNode, V as findNode, W as walkAssembly, Y as createAssembly, _ as exportURDF, b as inverseKinematics, c as modifyStep, d as replayFrom, f as replayHistory, g as undoLast, h as stepsFrom, i as createRegistry, j as setJointValues, k as revoluteJoint, l as registerOperation, m as stepCount, n as addStep, o as findStep, q as linearPattern, r as createHistory, s as getShape, t as thread, u as registerShape, v as importURDF, w as forwardKinematics, x as jointTrajectory, y as jointsFromDH, z as countNodes } from "./threadFns-KbYZu7Q9.js";
|
|
2
2
|
import { d as twistExtrude, l as supportExtrude, o as complexExtrude, u as sweep } from "./loftFns-CmShFQlv.js";
|
|
3
3
|
export { addChild, addJoint, addStep, circularPattern, collectShapes, complexExtrude, countNodes, createAssembly, createAssemblyNode, createHistory, createRegistry, cylindricalJoint, exportAssemblySTEP, exportURDF, findNode, findStep, forwardKinematics, getShape as getHistoryShape, gridPattern, importURDF, inverseKinematics, jointTrajectory, jointTransform, jointsFromDH, linearPattern, mechanismDOF, modifyStep, planarJoint, prismaticJoint, registerOperation, registerShape, removeChild, replayFrom, replayHistory, revoluteJoint, setJointValue, setJointValues, sphericalJoint, stepCount, stepsFrom, supportExtrude, sweep, thread, twistExtrude, undoLast, updateNode, walkAssembly };
|
|
@@ -1699,6 +1699,12 @@ Object.defineProperty(exports, "quatFromTo", {
|
|
|
1699
1699
|
return quatFromTo;
|
|
1700
1700
|
}
|
|
1701
1701
|
});
|
|
1702
|
+
Object.defineProperty(exports, "quatMultiply", {
|
|
1703
|
+
enumerable: true,
|
|
1704
|
+
get: function() {
|
|
1705
|
+
return quatMultiply;
|
|
1706
|
+
}
|
|
1707
|
+
});
|
|
1702
1708
|
Object.defineProperty(exports, "quatRotate", {
|
|
1703
1709
|
enumerable: true,
|
|
1704
1710
|
get: function() {
|
|
@@ -1513,4 +1513,4 @@ function thread(options) {
|
|
|
1513
1513
|
}
|
|
1514
1514
|
}
|
|
1515
1515
|
//#endregion
|
|
1516
|
-
export { setJointValue as A,
|
|
1516
|
+
export { setJointValue as A, createAssemblyNode as B, cylindricalJoint as C, planarJoint as D, mechanismDOF as E, quatMultiply as F, circularPattern as G, removeChild as H, quatRotate as I, exportAssemblySTEP as J, gridPattern as K, addChild as L, sphericalJoint as M, quatFromAxisAngle as N, prismaticJoint as O, quatFromTo as P, collectShapes as R, addJoint as S, jointTransform as T, updateNode as U, findNode as V, walkAssembly as W, createAssembly as Y, exportURDF as _, deserializeHistory as a, inverseKinematics as b, modifyStep as c, replayFrom as d, replayHistory as f, undoLast as g, stepsFrom as h, createRegistry as i, setJointValues as j, revoluteJoint as k, registerOperation as l, stepCount as m, addStep as n, findStep as o, serializeHistory as p, linearPattern as q, createHistory as r, getShape as s, thread as t, registerShape as u, importURDF as v, forwardKinematics as w, jointTrajectory as x, jointsFromDH as y, countNodes as z };
|