brepjs 18.69.2 → 18.69.3
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 +95 -60
- package/dist/brepjs.js +95 -60
- package/dist/kernel/solverAdapter.d.ts +7 -2
- package/package.json +1 -1
package/dist/brepjs.cjs
CHANGED
|
@@ -2146,11 +2146,64 @@ var UNSUPPORTED_DOF = {
|
|
|
2146
2146
|
distance: 1,
|
|
2147
2147
|
angle: 1
|
|
2148
2148
|
};
|
|
2149
|
+
var IDENTITY_ROTATION = [
|
|
2150
|
+
1,
|
|
2151
|
+
0,
|
|
2152
|
+
0,
|
|
2153
|
+
0
|
|
2154
|
+
];
|
|
2155
|
+
function add$1(a, b) {
|
|
2156
|
+
return [
|
|
2157
|
+
a[0] + b[0],
|
|
2158
|
+
a[1] + b[1],
|
|
2159
|
+
a[2] + b[2]
|
|
2160
|
+
];
|
|
2161
|
+
}
|
|
2162
|
+
function dot(a, b) {
|
|
2163
|
+
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
|
|
2164
|
+
}
|
|
2165
|
+
/**
|
|
2166
|
+
* Position a dependent plane against an already-placed reference plane.
|
|
2167
|
+
*
|
|
2168
|
+
* The reference's solved translation is applied to its (local) entity origin
|
|
2169
|
+
* before measuring, so a chain composes down already-solved poses instead of
|
|
2170
|
+
* reading original geometry. The dependent is at the origin (a node is only
|
|
2171
|
+
* solved once, while unplaced), so the returned position is its absolute
|
|
2172
|
+
* translation. `extra` is the gap for a distance mate (0 for coincident).
|
|
2173
|
+
* Rotation stays identity — coincident/distance produce pure translations;
|
|
2174
|
+
* Phase 1 rotational constraints will extend this.
|
|
2175
|
+
*/
|
|
2176
|
+
function solvePlanePair(ref, refPos, dep, extra) {
|
|
2177
|
+
const n = ref.normal ?? [
|
|
2178
|
+
0,
|
|
2179
|
+
0,
|
|
2180
|
+
1
|
|
2181
|
+
];
|
|
2182
|
+
const refOrigin = add$1(ref.origin, refPos);
|
|
2183
|
+
const offset = dot(n, [
|
|
2184
|
+
refOrigin[0] - dep.origin[0],
|
|
2185
|
+
refOrigin[1] - dep.origin[1],
|
|
2186
|
+
refOrigin[2] - dep.origin[2]
|
|
2187
|
+
]) + extra;
|
|
2188
|
+
return {
|
|
2189
|
+
position: [
|
|
2190
|
+
offset * n[0],
|
|
2191
|
+
offset * n[1],
|
|
2192
|
+
offset * n[2]
|
|
2193
|
+
],
|
|
2194
|
+
rotation: IDENTITY_ROTATION
|
|
2195
|
+
};
|
|
2196
|
+
}
|
|
2149
2197
|
/**
|
|
2150
2198
|
* Solve assembly constraints analytically.
|
|
2151
2199
|
*
|
|
2152
|
-
*
|
|
2153
|
-
*
|
|
2200
|
+
* Handles: fixed, coincident (plane-plane), distance (plane-plane). For a
|
|
2201
|
+
* positioning mate, entityA is the reference and entityB the dependent. Chain
|
|
2202
|
+
* roots (nodes never positioned by a mate) and explicit `fixed` nodes anchor at
|
|
2203
|
+
* the origin; constraints then resolve in topological order — each places its
|
|
2204
|
+
* dependent against the reference's solved pose, so multi-body chains compose.
|
|
2205
|
+
* Returns `converged: false` with unsupported details for concentric, angle,
|
|
2206
|
+
* non-plane pairs, and any constraint whose reference never resolves.
|
|
2154
2207
|
*/
|
|
2155
2208
|
function solveConstraints(nodes, constraints) {
|
|
2156
2209
|
const transforms = /* @__PURE__ */ new Map();
|
|
@@ -2160,69 +2213,51 @@ function solveConstraints(nodes, constraints) {
|
|
|
2160
2213
|
0,
|
|
2161
2214
|
0
|
|
2162
2215
|
],
|
|
2163
|
-
rotation:
|
|
2164
|
-
1,
|
|
2165
|
-
0,
|
|
2166
|
-
0,
|
|
2167
|
-
0
|
|
2168
|
-
]
|
|
2216
|
+
rotation: IDENTITY_ROTATION
|
|
2169
2217
|
});
|
|
2170
2218
|
const unsupported = [];
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
|
|
2181
|
-
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
if (a.entity.type === "plane" && b.entity.type === "plane") {
|
|
2202
|
-
const aNormal = a.entity.normal ?? [
|
|
2203
|
-
0,
|
|
2204
|
-
0,
|
|
2205
|
-
1
|
|
2206
|
-
];
|
|
2207
|
-
const aOrigin = a.entity.origin;
|
|
2208
|
-
const bOrigin = b.entity.origin;
|
|
2209
|
-
const offset = aNormal[0] * (aOrigin[0] - bOrigin[0]) + aNormal[1] * (aOrigin[1] - bOrigin[1]) + aNormal[2] * (aOrigin[2] - bOrigin[2]) + c.value;
|
|
2210
|
-
const pos = [
|
|
2211
|
-
offset * aNormal[0],
|
|
2212
|
-
offset * aNormal[1],
|
|
2213
|
-
offset * aNormal[2]
|
|
2214
|
-
];
|
|
2215
|
-
transforms.set(b.node, {
|
|
2216
|
-
position: pos,
|
|
2217
|
-
rotation: [
|
|
2218
|
-
1,
|
|
2219
|
+
const positioning = constraints.filter((c) => (c.type === "coincident" || c.type === "distance") && c.entityA && c.entityB);
|
|
2220
|
+
const dependents = /* @__PURE__ */ new Set();
|
|
2221
|
+
for (const c of positioning) if (c.entityB) dependents.add(c.entityB.node);
|
|
2222
|
+
const placed = /* @__PURE__ */ new Set();
|
|
2223
|
+
for (const node of nodes) if (!dependents.has(node)) placed.add(node);
|
|
2224
|
+
for (const c of constraints) if (c.type === "fixed" && c.entityA) placed.add(c.entityA.node);
|
|
2225
|
+
for (const c of constraints) if (c.type === "concentric" || c.type === "angle") unsupported.push(c.type);
|
|
2226
|
+
const pending = [];
|
|
2227
|
+
for (const c of positioning) {
|
|
2228
|
+
if (!c.entityA || !c.entityB) continue;
|
|
2229
|
+
if (c.entityA.entity.type !== "plane" || c.entityB.entity.type !== "plane") {
|
|
2230
|
+
unsupported.push(`${c.type}(${c.entityA.entity.type}-${c.entityB.entity.type})`);
|
|
2231
|
+
continue;
|
|
2232
|
+
}
|
|
2233
|
+
pending.push(c);
|
|
2234
|
+
}
|
|
2235
|
+
let progress = true;
|
|
2236
|
+
while (progress && pending.length > 0) {
|
|
2237
|
+
progress = false;
|
|
2238
|
+
for (let i = pending.length - 1; i >= 0; i--) {
|
|
2239
|
+
const c = pending[i];
|
|
2240
|
+
if (!c?.entityA || !c.entityB) continue;
|
|
2241
|
+
const ref = c.entityA;
|
|
2242
|
+
const dep = c.entityB;
|
|
2243
|
+
if (!placed.has(ref.node)) continue;
|
|
2244
|
+
pending.splice(i, 1);
|
|
2245
|
+
progress = true;
|
|
2246
|
+
if (placed.has(dep.node)) continue;
|
|
2247
|
+
const refPose = transforms.get(ref.node) ?? {
|
|
2248
|
+
position: [
|
|
2219
2249
|
0,
|
|
2220
2250
|
0,
|
|
2221
2251
|
0
|
|
2222
|
-
]
|
|
2223
|
-
|
|
2224
|
-
|
|
2225
|
-
|
|
2252
|
+
],
|
|
2253
|
+
rotation: IDENTITY_ROTATION
|
|
2254
|
+
};
|
|
2255
|
+
const extra = c.type === "distance" ? c.value ?? 0 : 0;
|
|
2256
|
+
transforms.set(dep.node, solvePlanePair(ref.entity, refPose.position, dep.entity, extra));
|
|
2257
|
+
placed.add(dep.node);
|
|
2258
|
+
}
|
|
2259
|
+
}
|
|
2260
|
+
for (const c of pending) unsupported.push(`${c.type}(unanchored)`);
|
|
2226
2261
|
return {
|
|
2227
2262
|
transforms,
|
|
2228
2263
|
dof: unsupported.reduce((sum, type) => {
|
package/dist/brepjs.js
CHANGED
|
@@ -2157,11 +2157,64 @@ var UNSUPPORTED_DOF = {
|
|
|
2157
2157
|
distance: 1,
|
|
2158
2158
|
angle: 1
|
|
2159
2159
|
};
|
|
2160
|
+
var IDENTITY_ROTATION = [
|
|
2161
|
+
1,
|
|
2162
|
+
0,
|
|
2163
|
+
0,
|
|
2164
|
+
0
|
|
2165
|
+
];
|
|
2166
|
+
function add$1(a, b) {
|
|
2167
|
+
return [
|
|
2168
|
+
a[0] + b[0],
|
|
2169
|
+
a[1] + b[1],
|
|
2170
|
+
a[2] + b[2]
|
|
2171
|
+
];
|
|
2172
|
+
}
|
|
2173
|
+
function dot(a, b) {
|
|
2174
|
+
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
|
|
2175
|
+
}
|
|
2176
|
+
/**
|
|
2177
|
+
* Position a dependent plane against an already-placed reference plane.
|
|
2178
|
+
*
|
|
2179
|
+
* The reference's solved translation is applied to its (local) entity origin
|
|
2180
|
+
* before measuring, so a chain composes down already-solved poses instead of
|
|
2181
|
+
* reading original geometry. The dependent is at the origin (a node is only
|
|
2182
|
+
* solved once, while unplaced), so the returned position is its absolute
|
|
2183
|
+
* translation. `extra` is the gap for a distance mate (0 for coincident).
|
|
2184
|
+
* Rotation stays identity — coincident/distance produce pure translations;
|
|
2185
|
+
* Phase 1 rotational constraints will extend this.
|
|
2186
|
+
*/
|
|
2187
|
+
function solvePlanePair(ref, refPos, dep, extra) {
|
|
2188
|
+
const n = ref.normal ?? [
|
|
2189
|
+
0,
|
|
2190
|
+
0,
|
|
2191
|
+
1
|
|
2192
|
+
];
|
|
2193
|
+
const refOrigin = add$1(ref.origin, refPos);
|
|
2194
|
+
const offset = dot(n, [
|
|
2195
|
+
refOrigin[0] - dep.origin[0],
|
|
2196
|
+
refOrigin[1] - dep.origin[1],
|
|
2197
|
+
refOrigin[2] - dep.origin[2]
|
|
2198
|
+
]) + extra;
|
|
2199
|
+
return {
|
|
2200
|
+
position: [
|
|
2201
|
+
offset * n[0],
|
|
2202
|
+
offset * n[1],
|
|
2203
|
+
offset * n[2]
|
|
2204
|
+
],
|
|
2205
|
+
rotation: IDENTITY_ROTATION
|
|
2206
|
+
};
|
|
2207
|
+
}
|
|
2160
2208
|
/**
|
|
2161
2209
|
* Solve assembly constraints analytically.
|
|
2162
2210
|
*
|
|
2163
|
-
*
|
|
2164
|
-
*
|
|
2211
|
+
* Handles: fixed, coincident (plane-plane), distance (plane-plane). For a
|
|
2212
|
+
* positioning mate, entityA is the reference and entityB the dependent. Chain
|
|
2213
|
+
* roots (nodes never positioned by a mate) and explicit `fixed` nodes anchor at
|
|
2214
|
+
* the origin; constraints then resolve in topological order — each places its
|
|
2215
|
+
* dependent against the reference's solved pose, so multi-body chains compose.
|
|
2216
|
+
* Returns `converged: false` with unsupported details for concentric, angle,
|
|
2217
|
+
* non-plane pairs, and any constraint whose reference never resolves.
|
|
2165
2218
|
*/
|
|
2166
2219
|
function solveConstraints(nodes, constraints) {
|
|
2167
2220
|
const transforms = /* @__PURE__ */ new Map();
|
|
@@ -2171,69 +2224,51 @@ function solveConstraints(nodes, constraints) {
|
|
|
2171
2224
|
0,
|
|
2172
2225
|
0
|
|
2173
2226
|
],
|
|
2174
|
-
rotation:
|
|
2175
|
-
1,
|
|
2176
|
-
0,
|
|
2177
|
-
0,
|
|
2178
|
-
0
|
|
2179
|
-
]
|
|
2227
|
+
rotation: IDENTITY_ROTATION
|
|
2180
2228
|
});
|
|
2181
2229
|
const unsupported = [];
|
|
2182
|
-
|
|
2183
|
-
|
|
2184
|
-
|
|
2185
|
-
|
|
2186
|
-
|
|
2187
|
-
|
|
2188
|
-
|
|
2189
|
-
|
|
2190
|
-
|
|
2191
|
-
|
|
2192
|
-
|
|
2193
|
-
|
|
2194
|
-
|
|
2195
|
-
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
|
|
2199
|
-
|
|
2200
|
-
|
|
2201
|
-
|
|
2202
|
-
|
|
2203
|
-
|
|
2204
|
-
|
|
2205
|
-
|
|
2206
|
-
|
|
2207
|
-
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
|
|
2211
|
-
|
|
2212
|
-
if (a.entity.type === "plane" && b.entity.type === "plane") {
|
|
2213
|
-
const aNormal = a.entity.normal ?? [
|
|
2214
|
-
0,
|
|
2215
|
-
0,
|
|
2216
|
-
1
|
|
2217
|
-
];
|
|
2218
|
-
const aOrigin = a.entity.origin;
|
|
2219
|
-
const bOrigin = b.entity.origin;
|
|
2220
|
-
const offset = aNormal[0] * (aOrigin[0] - bOrigin[0]) + aNormal[1] * (aOrigin[1] - bOrigin[1]) + aNormal[2] * (aOrigin[2] - bOrigin[2]) + c.value;
|
|
2221
|
-
const pos = [
|
|
2222
|
-
offset * aNormal[0],
|
|
2223
|
-
offset * aNormal[1],
|
|
2224
|
-
offset * aNormal[2]
|
|
2225
|
-
];
|
|
2226
|
-
transforms.set(b.node, {
|
|
2227
|
-
position: pos,
|
|
2228
|
-
rotation: [
|
|
2229
|
-
1,
|
|
2230
|
+
const positioning = constraints.filter((c) => (c.type === "coincident" || c.type === "distance") && c.entityA && c.entityB);
|
|
2231
|
+
const dependents = /* @__PURE__ */ new Set();
|
|
2232
|
+
for (const c of positioning) if (c.entityB) dependents.add(c.entityB.node);
|
|
2233
|
+
const placed = /* @__PURE__ */ new Set();
|
|
2234
|
+
for (const node of nodes) if (!dependents.has(node)) placed.add(node);
|
|
2235
|
+
for (const c of constraints) if (c.type === "fixed" && c.entityA) placed.add(c.entityA.node);
|
|
2236
|
+
for (const c of constraints) if (c.type === "concentric" || c.type === "angle") unsupported.push(c.type);
|
|
2237
|
+
const pending = [];
|
|
2238
|
+
for (const c of positioning) {
|
|
2239
|
+
if (!c.entityA || !c.entityB) continue;
|
|
2240
|
+
if (c.entityA.entity.type !== "plane" || c.entityB.entity.type !== "plane") {
|
|
2241
|
+
unsupported.push(`${c.type}(${c.entityA.entity.type}-${c.entityB.entity.type})`);
|
|
2242
|
+
continue;
|
|
2243
|
+
}
|
|
2244
|
+
pending.push(c);
|
|
2245
|
+
}
|
|
2246
|
+
let progress = true;
|
|
2247
|
+
while (progress && pending.length > 0) {
|
|
2248
|
+
progress = false;
|
|
2249
|
+
for (let i = pending.length - 1; i >= 0; i--) {
|
|
2250
|
+
const c = pending[i];
|
|
2251
|
+
if (!c?.entityA || !c.entityB) continue;
|
|
2252
|
+
const ref = c.entityA;
|
|
2253
|
+
const dep = c.entityB;
|
|
2254
|
+
if (!placed.has(ref.node)) continue;
|
|
2255
|
+
pending.splice(i, 1);
|
|
2256
|
+
progress = true;
|
|
2257
|
+
if (placed.has(dep.node)) continue;
|
|
2258
|
+
const refPose = transforms.get(ref.node) ?? {
|
|
2259
|
+
position: [
|
|
2230
2260
|
0,
|
|
2231
2261
|
0,
|
|
2232
2262
|
0
|
|
2233
|
-
]
|
|
2234
|
-
|
|
2235
|
-
|
|
2236
|
-
|
|
2263
|
+
],
|
|
2264
|
+
rotation: IDENTITY_ROTATION
|
|
2265
|
+
};
|
|
2266
|
+
const extra = c.type === "distance" ? c.value ?? 0 : 0;
|
|
2267
|
+
transforms.set(dep.node, solvePlanePair(ref.entity, refPose.position, dep.entity, extra));
|
|
2268
|
+
placed.add(dep.node);
|
|
2269
|
+
}
|
|
2270
|
+
}
|
|
2271
|
+
for (const c of pending) unsupported.push(`${c.type}(unanchored)`);
|
|
2237
2272
|
return {
|
|
2238
2273
|
transforms,
|
|
2239
2274
|
dof: unsupported.reduce((sum, type) => {
|
|
@@ -34,8 +34,13 @@ export interface SolverResult {
|
|
|
34
34
|
/**
|
|
35
35
|
* Solve assembly constraints analytically.
|
|
36
36
|
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
37
|
+
* Handles: fixed, coincident (plane-plane), distance (plane-plane). For a
|
|
38
|
+
* positioning mate, entityA is the reference and entityB the dependent. Chain
|
|
39
|
+
* roots (nodes never positioned by a mate) and explicit `fixed` nodes anchor at
|
|
40
|
+
* the origin; constraints then resolve in topological order — each places its
|
|
41
|
+
* dependent against the reference's solved pose, so multi-body chains compose.
|
|
42
|
+
* Returns `converged: false` with unsupported details for concentric, angle,
|
|
43
|
+
* non-plane pairs, and any constraint whose reference never resolves.
|
|
39
44
|
*/
|
|
40
45
|
export declare function solveConstraints(nodes: string[], constraints: SolverConstraint[]): SolverResult;
|
|
41
46
|
export {};
|