jscad-electronics 0.0.238 → 0.0.239
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/index.d.ts +36 -6
- package/dist/index.js +1044 -537
- package/dist/index.js.map +1 -1
- package/dist/vanilla.d.ts +51 -7
- package/dist/vanilla.js +1029 -407
- package/dist/vanilla.js.map +1 -1
- package/package.json +9 -11
package/dist/vanilla.js
CHANGED
|
@@ -12179,7 +12179,7 @@ function getNemaMotorReferencePoints(input) {
|
|
|
12179
12179
|
(p.bodyWidth - p.faceCornerChamfer) / (Math.abs(x) + Math.abs(y))
|
|
12180
12180
|
);
|
|
12181
12181
|
if (p.nemaSize !== 34 || p.stepped) {
|
|
12182
|
-
const
|
|
12182
|
+
const profile5 = p.nemaSize === 34 ? {
|
|
12183
12183
|
width: p.bodyWidth,
|
|
12184
12184
|
chamfer: p.bodyCornerChamfer,
|
|
12185
12185
|
stepped: p.stepped,
|
|
@@ -12195,7 +12195,7 @@ function getNemaMotorReferencePoints(input) {
|
|
|
12195
12195
|
let low = 0, high = p.bodyWidth;
|
|
12196
12196
|
for (let i = 0; i < 50; i++) {
|
|
12197
12197
|
const mid = (low + high) / 2;
|
|
12198
|
-
if (isInsideNemaFace(mid * x, mid * y,
|
|
12198
|
+
if (isInsideNemaFace(mid * x, mid * y, profile5)) low = mid;
|
|
12199
12199
|
else high = mid;
|
|
12200
12200
|
}
|
|
12201
12201
|
radius = low;
|
|
@@ -12383,6 +12383,746 @@ var componentMaterials = {
|
|
|
12383
12383
|
steel: { metalness: 1, roughness: 0.25 }
|
|
12384
12384
|
};
|
|
12385
12385
|
|
|
12386
|
+
// node_modules/@tscircuit/jscad/lib/cleanup-subtraction.ts
|
|
12387
|
+
import insertTjunctions from "@jscad/modeling/src/operations/modifiers/insertTjunctions.js";
|
|
12388
|
+
function cleanupSubtraction(kernel, geometry) {
|
|
12389
|
+
const { geom3 } = kernel.geometries;
|
|
12390
|
+
if (!geometry.polygons.length) return geometry;
|
|
12391
|
+
const source = structuredClone(geometry);
|
|
12392
|
+
const polygons = geom3.toPolygons(source);
|
|
12393
|
+
const extent = Math.max(...kernel.measurements.measureDimensions(source));
|
|
12394
|
+
if (!Number.isFinite(extent) || extent <= 0)
|
|
12395
|
+
throw new Error("Subtraction requires finite nonempty geometry");
|
|
12396
|
+
const epsilon = Math.max(extent * 1e-10, 1e-12);
|
|
12397
|
+
source.polygons = polygons.map((polygon4) => ({
|
|
12398
|
+
...polygon4,
|
|
12399
|
+
vertices: polygon4.vertices.map((point) => {
|
|
12400
|
+
if (!point.every(Number.isFinite))
|
|
12401
|
+
throw new Error("Subtraction requires finite coordinates");
|
|
12402
|
+
return point.map((value) => Math.round(value / epsilon) * epsilon);
|
|
12403
|
+
})
|
|
12404
|
+
}));
|
|
12405
|
+
const triangles = insertTjunctions(source.polygons).flatMap((polygon4) => {
|
|
12406
|
+
if (polygon4.vertices.length === 3) return [polygon4];
|
|
12407
|
+
const center = [0, 0, 0];
|
|
12408
|
+
for (const point of polygon4.vertices)
|
|
12409
|
+
for (let axis = 0; axis < 3; axis++)
|
|
12410
|
+
center[axis] += point[axis] / polygon4.vertices.length;
|
|
12411
|
+
return polygon4.vertices.map((point, index) => {
|
|
12412
|
+
const triangle = kernel.geometries.poly3.create([
|
|
12413
|
+
center,
|
|
12414
|
+
point,
|
|
12415
|
+
polygon4.vertices[(index + 1) % polygon4.vertices.length]
|
|
12416
|
+
]);
|
|
12417
|
+
if (polygon4.color) triangle.color = polygon4.color;
|
|
12418
|
+
return triangle;
|
|
12419
|
+
});
|
|
12420
|
+
});
|
|
12421
|
+
const cleaned = geom3.create(triangles);
|
|
12422
|
+
return {
|
|
12423
|
+
...geometry,
|
|
12424
|
+
polygons: cleaned.polygons,
|
|
12425
|
+
transforms: cleaned.transforms
|
|
12426
|
+
};
|
|
12427
|
+
}
|
|
12428
|
+
|
|
12429
|
+
// node_modules/@tscircuit/jscad/lib/with-references.ts
|
|
12430
|
+
import modeling from "@jscad/modeling";
|
|
12431
|
+
var metadata = /* @__PURE__ */ Symbol.for("@tscircuit/jscad/references/v1");
|
|
12432
|
+
var cache = /* @__PURE__ */ new WeakMap();
|
|
12433
|
+
var snapshot = (value) => structuredClone(value);
|
|
12434
|
+
var assertName = (name) => {
|
|
12435
|
+
if (typeof name !== "string" || !name.trim())
|
|
12436
|
+
throw new Error("Reference name must be nonempty");
|
|
12437
|
+
};
|
|
12438
|
+
function withReferences(kernel = modeling) {
|
|
12439
|
+
if (cache.has(kernel)) return cache.get(kernel);
|
|
12440
|
+
const k = kernel;
|
|
12441
|
+
const { mat4 } = k.maths;
|
|
12442
|
+
const identity = () => Array.from(mat4.create());
|
|
12443
|
+
const multiply = (a, b) => Array.from(mat4.multiply(mat4.create(), a, b));
|
|
12444
|
+
const isGeometry = (g) => g && (k.geometries.geom2.isA(g) || k.geometries.path2.isA(g) || k.geometries.geom3.isA(g));
|
|
12445
|
+
const inputs = (args) => args.flat(Infinity).filter(isGeometry);
|
|
12446
|
+
const read = (g) => g?.[metadata] ?? /* @__PURE__ */ Object.create(null);
|
|
12447
|
+
const merge = (geometries9) => {
|
|
12448
|
+
const refs = /* @__PURE__ */ Object.create(null);
|
|
12449
|
+
for (const g of geometries9)
|
|
12450
|
+
for (const [name, ref] of Object.entries(read(g))) {
|
|
12451
|
+
if (Object.hasOwn(refs, name) && refs[name] !== ref)
|
|
12452
|
+
throw new Error(`Duplicate reference: ${name}`);
|
|
12453
|
+
refs[name] = ref;
|
|
12454
|
+
}
|
|
12455
|
+
return refs;
|
|
12456
|
+
};
|
|
12457
|
+
const attach = (g, refs) => {
|
|
12458
|
+
if (!Object.keys(refs).length) return g;
|
|
12459
|
+
if (Array.isArray(g)) return g.map((item) => attach(item, refs));
|
|
12460
|
+
return isGeometry(g) ? Object.assign({}, g, { [metadata]: refs }) : g;
|
|
12461
|
+
};
|
|
12462
|
+
const moved = (refs, matrix) => Object.fromEntries(
|
|
12463
|
+
Object.entries(refs).map(([name, ref]) => [
|
|
12464
|
+
name,
|
|
12465
|
+
{ geometry: ref.geometry, matrix: multiply(matrix, ref.matrix) }
|
|
12466
|
+
])
|
|
12467
|
+
);
|
|
12468
|
+
const add = (refs, name, ref) => {
|
|
12469
|
+
assertName(name);
|
|
12470
|
+
if (Object.hasOwn(refs, name))
|
|
12471
|
+
throw new Error(`Duplicate reference: ${name}`);
|
|
12472
|
+
refs[name] = ref;
|
|
12473
|
+
};
|
|
12474
|
+
const planar = (g) => {
|
|
12475
|
+
if (!k.geometries.geom2.isA(g) && !k.geometries.path2.isA(g))
|
|
12476
|
+
throw new Error("References require native planar geometry");
|
|
12477
|
+
};
|
|
12478
|
+
const references2 = {
|
|
12479
|
+
name(name, geometry) {
|
|
12480
|
+
planar(geometry);
|
|
12481
|
+
const refs = merge([geometry]);
|
|
12482
|
+
add(refs, name, { geometry: snapshot(geometry), matrix: identity() });
|
|
12483
|
+
return attach(geometry, refs);
|
|
12484
|
+
},
|
|
12485
|
+
nameOutlines(geometry, names) {
|
|
12486
|
+
if (!k.geometries.geom2.isA(geometry))
|
|
12487
|
+
throw new Error("nameOutlines requires a native Geom2");
|
|
12488
|
+
const refs = merge([geometry]);
|
|
12489
|
+
const outlines = k.geometries.geom2.toOutlines(
|
|
12490
|
+
snapshot(geometry)
|
|
12491
|
+
);
|
|
12492
|
+
const area = (points) => points.reduce((sum, p, i) => {
|
|
12493
|
+
const q = points[(i + 1) % points.length];
|
|
12494
|
+
return sum + p[0] * q[1] - p[1] * q[0];
|
|
12495
|
+
}, 0);
|
|
12496
|
+
for (const [role, name] of Object.entries(names)) {
|
|
12497
|
+
if (name === void 0) continue;
|
|
12498
|
+
if (role !== "outer" && role !== "hole")
|
|
12499
|
+
throw new Error(`Unknown outline role: ${role}`);
|
|
12500
|
+
const matches = outlines.filter(
|
|
12501
|
+
(points) => role === "outer" ? area(points) > 0 : area(points) < 0
|
|
12502
|
+
);
|
|
12503
|
+
if (matches.length !== 1)
|
|
12504
|
+
throw new Error(
|
|
12505
|
+
`Expected exactly one ${role} outline, found ${matches.length}`
|
|
12506
|
+
);
|
|
12507
|
+
add(refs, name, {
|
|
12508
|
+
geometry: k.geometries.path2.fromPoints({ closed: true }, matches[0]),
|
|
12509
|
+
matrix: identity()
|
|
12510
|
+
});
|
|
12511
|
+
}
|
|
12512
|
+
return attach(geometry, refs);
|
|
12513
|
+
},
|
|
12514
|
+
reference(name, geometry) {
|
|
12515
|
+
return attach(
|
|
12516
|
+
k.geometries.geom3.create(),
|
|
12517
|
+
read(references2.name(name, geometry))
|
|
12518
|
+
);
|
|
12519
|
+
},
|
|
12520
|
+
get(geometry, name) {
|
|
12521
|
+
const ref = read(geometry)[name];
|
|
12522
|
+
if (!Object.hasOwn(read(geometry), name))
|
|
12523
|
+
throw new Error(`Unknown reference: ${name}`);
|
|
12524
|
+
return snapshot(ref);
|
|
12525
|
+
},
|
|
12526
|
+
list(geometry) {
|
|
12527
|
+
return Object.keys(read(geometry));
|
|
12528
|
+
},
|
|
12529
|
+
collect(geometries9) {
|
|
12530
|
+
return snapshot(merge(inputs([geometries9])));
|
|
12531
|
+
}
|
|
12532
|
+
};
|
|
12533
|
+
const wrapped = { ...k, references: references2 };
|
|
12534
|
+
for (const namespace of [
|
|
12535
|
+
"booleans",
|
|
12536
|
+
"hulls",
|
|
12537
|
+
"expansions",
|
|
12538
|
+
"modifiers",
|
|
12539
|
+
"extrusions",
|
|
12540
|
+
"colors"
|
|
12541
|
+
]) {
|
|
12542
|
+
wrapped[namespace] = { ...k[namespace] };
|
|
12543
|
+
for (const [name, fn] of Object.entries(k[namespace]))
|
|
12544
|
+
if (typeof fn === "function") {
|
|
12545
|
+
wrapped[namespace][name] = (...args) => {
|
|
12546
|
+
const refs = merge(inputs(args));
|
|
12547
|
+
let result = fn(...args);
|
|
12548
|
+
if (namespace === "booleans" && name === "subtract" && k.geometries.geom3.isA(result)) {
|
|
12549
|
+
result = cleanupSubtraction(kernel, result);
|
|
12550
|
+
}
|
|
12551
|
+
return attach(result, refs);
|
|
12552
|
+
};
|
|
12553
|
+
}
|
|
12554
|
+
}
|
|
12555
|
+
const transformResult = (fn, args, offset, boundsBased = false) => {
|
|
12556
|
+
const gs = inputs(args.slice(offset));
|
|
12557
|
+
if (!gs.some((g) => Object.keys(read(g)).length)) return fn(...args);
|
|
12558
|
+
const maps = gs.map((g) => read(g));
|
|
12559
|
+
const before = boundsBased ? gs.map((g) => k.measurements.measureBoundingBox(snapshot(g))[0]) : [];
|
|
12560
|
+
const matrix = boundsBased ? null : fn(...args.slice(0, offset), k.geometries.geom3.create()).transforms;
|
|
12561
|
+
const result = fn(...args);
|
|
12562
|
+
const results = Array.isArray(result) ? result : [result];
|
|
12563
|
+
const output = results.map((g, i) => {
|
|
12564
|
+
let m = matrix;
|
|
12565
|
+
if (boundsBased) {
|
|
12566
|
+
const after = k.measurements.measureBoundingBox(snapshot(g))[0];
|
|
12567
|
+
m = mat4.fromTranslation(
|
|
12568
|
+
mat4.create(),
|
|
12569
|
+
after.map((n, axis) => n - before[i][axis])
|
|
12570
|
+
);
|
|
12571
|
+
}
|
|
12572
|
+
return attach(g, moved(maps[i], Array.from(m)));
|
|
12573
|
+
});
|
|
12574
|
+
return Array.isArray(result) ? output : output[0];
|
|
12575
|
+
};
|
|
12576
|
+
wrapped.transforms = { ...k.transforms };
|
|
12577
|
+
for (const [name, fn] of Object.entries(k.transforms)) {
|
|
12578
|
+
const boundsBased = /^(center|align)/.test(name);
|
|
12579
|
+
const offset = /^center[XYZ]$|^mirror[XYZ]$/.test(name) ? 0 : 1;
|
|
12580
|
+
wrapped.transforms[name] = (...args) => transformResult(fn, args, offset, boundsBased);
|
|
12581
|
+
}
|
|
12582
|
+
wrapped.geometries = { ...k.geometries };
|
|
12583
|
+
for (const ns of ["geom2", "geom3", "path2"]) {
|
|
12584
|
+
wrapped.geometries[ns] = {
|
|
12585
|
+
...k.geometries[ns],
|
|
12586
|
+
transform: (matrix, g) => attach(k.geometries[ns].transform(matrix, g), moved(read(g), matrix))
|
|
12587
|
+
};
|
|
12588
|
+
}
|
|
12589
|
+
wrapped.extrusions.extrudeLinear = (options, ...objects) => {
|
|
12590
|
+
const gs = inputs(objects);
|
|
12591
|
+
const { topOutlineName, bottomOutlineName } = options ?? {};
|
|
12592
|
+
if (topOutlineName === void 0 && bottomOutlineName === void 0) {
|
|
12593
|
+
const refs2 = gs.map(read);
|
|
12594
|
+
const result = k.extrusions.extrudeLinear(options, ...objects);
|
|
12595
|
+
return Array.isArray(result) ? result.map((g, i) => attach(g, refs2[i])) : attach(result, refs2[0] ?? {});
|
|
12596
|
+
}
|
|
12597
|
+
if (gs.length !== 1)
|
|
12598
|
+
throw new Error("Named extrusion outlines require exactly one profile");
|
|
12599
|
+
const profile5 = gs[0];
|
|
12600
|
+
planar(profile5);
|
|
12601
|
+
if (k.geometries.path2.isA(profile5) && !profile5.isClosed)
|
|
12602
|
+
throw new Error("Named extrusion outlines require a closed path");
|
|
12603
|
+
const { height: height10 = 1, twistAngle = 0, twistSteps = 1 } = options;
|
|
12604
|
+
if (!Number.isFinite(height10) || !Number.isFinite(twistAngle) || !Number.isInteger(twistSteps) || twistSteps < 1)
|
|
12605
|
+
throw new Error(
|
|
12606
|
+
"Invalid named extrusion height, twistAngle or twistSteps"
|
|
12607
|
+
);
|
|
12608
|
+
const refs = merge(gs);
|
|
12609
|
+
const source = snapshot(profile5);
|
|
12610
|
+
const top = multiply(
|
|
12611
|
+
Array.from(mat4.fromTranslation(mat4.create(), [0, 0, height10])),
|
|
12612
|
+
Array.from(mat4.fromZRotation(mat4.create(), twistAngle))
|
|
12613
|
+
);
|
|
12614
|
+
for (const [prefix, matrix] of [
|
|
12615
|
+
[bottomOutlineName, identity()],
|
|
12616
|
+
[topOutlineName, top]
|
|
12617
|
+
]) {
|
|
12618
|
+
if (prefix === void 0) continue;
|
|
12619
|
+
add(refs, prefix, { geometry: source, matrix });
|
|
12620
|
+
for (const [name, ref] of Object.entries(read(profile5)))
|
|
12621
|
+
add(refs, `${prefix}.${name}`, {
|
|
12622
|
+
geometry: ref.geometry,
|
|
12623
|
+
matrix: multiply(matrix, ref.matrix)
|
|
12624
|
+
});
|
|
12625
|
+
}
|
|
12626
|
+
return attach(k.extrusions.extrudeLinear(options, ...objects), refs);
|
|
12627
|
+
};
|
|
12628
|
+
cache.set(kernel, wrapped);
|
|
12629
|
+
cache.set(wrapped, wrapped);
|
|
12630
|
+
return wrapped;
|
|
12631
|
+
}
|
|
12632
|
+
|
|
12633
|
+
// node_modules/@tscircuit/jscad/lib/geom3-to-indexed-mesh.ts
|
|
12634
|
+
import jscad from "@jscad/modeling";
|
|
12635
|
+
var edgeKey = (a, b) => a < b ? `${a},${b}` : `${b},${a}`;
|
|
12636
|
+
function geom3ToIndexedMesh(input) {
|
|
12637
|
+
const generalize8 = jscad.modifiers.generalize;
|
|
12638
|
+
input = structuredClone(input);
|
|
12639
|
+
const inputExtent = Math.max(...jscad.measurements.measureDimensions(input));
|
|
12640
|
+
if (!Number.isFinite(inputExtent) || inputExtent <= 0)
|
|
12641
|
+
throw new Error("Expected finite nonempty geometry");
|
|
12642
|
+
const weldTolerance = Math.max(inputExtent * 1e-10, 1e-12);
|
|
12643
|
+
const cells = /* @__PURE__ */ new Map();
|
|
12644
|
+
const weld = (v) => {
|
|
12645
|
+
if (v.length !== 3 || v.some((value) => !Number.isFinite(value)))
|
|
12646
|
+
throw new Error("Expected finite mesh coordinates");
|
|
12647
|
+
const cell = v.map((value) => Math.floor(value / weldTolerance));
|
|
12648
|
+
for (let x = -1; x <= 1; x++)
|
|
12649
|
+
for (let y = -1; y <= 1; y++)
|
|
12650
|
+
for (let z = -1; z <= 1; z++) {
|
|
12651
|
+
const entries2 = cells.get(
|
|
12652
|
+
`${cell[0] + x},${cell[1] + y},${cell[2] + z}`
|
|
12653
|
+
);
|
|
12654
|
+
const existing = entries2?.find(
|
|
12655
|
+
(point3) => Math.hypot(...v.map((value, axis) => value - point3[axis])) <= weldTolerance
|
|
12656
|
+
);
|
|
12657
|
+
if (existing) return existing;
|
|
12658
|
+
}
|
|
12659
|
+
const point2 = [v[0], v[1], v[2]], key = cell.join(","), entries = cells.get(key);
|
|
12660
|
+
if (entries) entries.push(point2);
|
|
12661
|
+
else cells.set(key, [point2]);
|
|
12662
|
+
return point2;
|
|
12663
|
+
};
|
|
12664
|
+
const welded = jscad.geometries.geom3.fromPoints(
|
|
12665
|
+
jscad.geometries.geom3.toPolygons(input).map((poly) => poly.vertices.map(weld))
|
|
12666
|
+
);
|
|
12667
|
+
const geom = generalize8({ snap: true, triangulate: true }, welded);
|
|
12668
|
+
const extent = Math.max(...jscad.measurements.measureDimensions(geom));
|
|
12669
|
+
if (!Number.isFinite(extent) || extent <= 0)
|
|
12670
|
+
throw new Error("Expected finite nonempty geometry");
|
|
12671
|
+
const epsilon = Math.max(extent * 1e-10, 1e-12);
|
|
12672
|
+
const snapTolerance = Math.max(
|
|
12673
|
+
2 * jscad.measurements.measureEpsilon(geom),
|
|
12674
|
+
epsilon
|
|
12675
|
+
);
|
|
12676
|
+
const positions = [], indices = [];
|
|
12677
|
+
const lookup = /* @__PURE__ */ new Map();
|
|
12678
|
+
const point = (index) => [
|
|
12679
|
+
positions[index * 3],
|
|
12680
|
+
positions[index * 3 + 1],
|
|
12681
|
+
positions[index * 3 + 2]
|
|
12682
|
+
];
|
|
12683
|
+
const vertex = (v) => {
|
|
12684
|
+
if (v.length !== 3 || v.some((value) => !Number.isFinite(value)))
|
|
12685
|
+
throw new Error("Expected finite mesh coordinates");
|
|
12686
|
+
const key = v.map((x) => Math.round(x / epsilon)).join(",");
|
|
12687
|
+
let index = lookup.get(key);
|
|
12688
|
+
if (index === void 0) {
|
|
12689
|
+
index = positions.length / 3;
|
|
12690
|
+
positions.push(...v);
|
|
12691
|
+
lookup.set(key, index);
|
|
12692
|
+
}
|
|
12693
|
+
return index;
|
|
12694
|
+
};
|
|
12695
|
+
const area = ([a, b, c]) => {
|
|
12696
|
+
const pa = point(a), pb = point(b), pc = point(c);
|
|
12697
|
+
const u = pb.map((x, i) => x - pa[i]), v = pc.map((x, i) => x - pa[i]);
|
|
12698
|
+
return Math.hypot(
|
|
12699
|
+
u[1] * v[2] - u[2] * v[1],
|
|
12700
|
+
u[2] * v[0] - u[0] * v[2],
|
|
12701
|
+
u[0] * v[1] - u[1] * v[0]
|
|
12702
|
+
);
|
|
12703
|
+
};
|
|
12704
|
+
const triangles = [];
|
|
12705
|
+
const edges = /* @__PURE__ */ new Map();
|
|
12706
|
+
for (const poly of jscad.geometries.geom3.toPolygons(geom)) {
|
|
12707
|
+
for (let i = 1; i < poly.vertices.length - 1; i++) {
|
|
12708
|
+
const triangle = [
|
|
12709
|
+
vertex(poly.vertices[0]),
|
|
12710
|
+
vertex(poly.vertices[i]),
|
|
12711
|
+
vertex(poly.vertices[i + 1])
|
|
12712
|
+
];
|
|
12713
|
+
if (area(triangle) <= epsilon * epsilon) continue;
|
|
12714
|
+
triangles.push(triangle);
|
|
12715
|
+
triangle.forEach((a, i2) => {
|
|
12716
|
+
const b = triangle[(i2 + 1) % 3], key = edgeKey(a, b), entry = edges.get(key);
|
|
12717
|
+
if (entry) entry.count++;
|
|
12718
|
+
else edges.set(key, { a, b, count: 1 });
|
|
12719
|
+
});
|
|
12720
|
+
}
|
|
12721
|
+
}
|
|
12722
|
+
const unmatched = [...edges.values()].filter(({ count }) => count === 1);
|
|
12723
|
+
const candidates = [...new Set(unmatched.flatMap(({ a, b }) => [a, b]))];
|
|
12724
|
+
const sorted = [0, 1, 2].map(
|
|
12725
|
+
(axis) => [...candidates].sort(
|
|
12726
|
+
(a, b) => positions[a * 3 + axis] - positions[b * 3 + axis]
|
|
12727
|
+
)
|
|
12728
|
+
);
|
|
12729
|
+
const subdivisions = /* @__PURE__ */ new Map();
|
|
12730
|
+
for (const { a, b } of unmatched) {
|
|
12731
|
+
const pa = point(a), pb = point(b), direction = pb.map((x, i) => x - pa[i]), length32 = Math.hypot(...direction);
|
|
12732
|
+
if (length32 <= epsilon) continue;
|
|
12733
|
+
const axis = direction.reduce(
|
|
12734
|
+
(best, x, i) => Math.abs(x) > Math.abs(direction[best]) ? i : best,
|
|
12735
|
+
0
|
|
12736
|
+
);
|
|
12737
|
+
const unit = direction.map((x) => x / length32), low = Math.min(pa[axis], pb[axis]), high = Math.max(pa[axis], pb[axis]);
|
|
12738
|
+
const byAxis = sorted[axis];
|
|
12739
|
+
let left = 0, right = byAxis.length;
|
|
12740
|
+
while (left < right) {
|
|
12741
|
+
const mid = left + right >>> 1;
|
|
12742
|
+
if (positions[byAxis[mid] * 3 + axis] < low) left = mid + 1;
|
|
12743
|
+
else right = mid;
|
|
12744
|
+
}
|
|
12745
|
+
const splits = [];
|
|
12746
|
+
for (let i = left; i < byAxis.length; i++) {
|
|
12747
|
+
const index = byAxis[i], p = point(index);
|
|
12748
|
+
if (p[axis] > high) break;
|
|
12749
|
+
if (index === a || index === b) continue;
|
|
12750
|
+
const delta = p.map((x, j) => x - pa[j]), along = delta.reduce((sum, x, j) => sum + x * unit[j], 0);
|
|
12751
|
+
if (along <= epsilon || along >= length32 - epsilon) continue;
|
|
12752
|
+
const distance2 = Math.hypot(...delta.map((x, j) => x - along * unit[j]));
|
|
12753
|
+
if (distance2 <= snapTolerance) splits.push({ index, t: along / length32 });
|
|
12754
|
+
}
|
|
12755
|
+
if (splits.length)
|
|
12756
|
+
subdivisions.set(
|
|
12757
|
+
edgeKey(a, b),
|
|
12758
|
+
splits.sort((x, y) => x.t - y.t).map(({ index }) => index)
|
|
12759
|
+
);
|
|
12760
|
+
}
|
|
12761
|
+
for (const triangle of triangles) {
|
|
12762
|
+
const boundary = triangle.flatMap((a, i) => {
|
|
12763
|
+
const b = triangle[(i + 1) % 3], splits = subdivisions.get(edgeKey(a, b));
|
|
12764
|
+
if (!splits) return [a];
|
|
12765
|
+
const edge = edges.get(edgeKey(a, b));
|
|
12766
|
+
return [a, ...edge.a === a ? splits : [...splits].reverse()];
|
|
12767
|
+
});
|
|
12768
|
+
if (boundary.length === 3) {
|
|
12769
|
+
indices.push(...triangle);
|
|
12770
|
+
continue;
|
|
12771
|
+
}
|
|
12772
|
+
const origin = point(boundary[0]);
|
|
12773
|
+
const center = origin.map(
|
|
12774
|
+
(value, axis) => value + boundary.reduce(
|
|
12775
|
+
(sum, index) => sum + (point(index)[axis] - value) / boundary.length,
|
|
12776
|
+
0
|
|
12777
|
+
)
|
|
12778
|
+
);
|
|
12779
|
+
const middle = vertex(center);
|
|
12780
|
+
for (let i = 0; i < boundary.length; i++) {
|
|
12781
|
+
const part = [
|
|
12782
|
+
middle,
|
|
12783
|
+
boundary[i],
|
|
12784
|
+
boundary[(i + 1) % boundary.length]
|
|
12785
|
+
];
|
|
12786
|
+
if (area(part) <= epsilon * epsilon)
|
|
12787
|
+
throw new Error("Unable to preserve a degenerate mesh boundary");
|
|
12788
|
+
indices.push(...part);
|
|
12789
|
+
}
|
|
12790
|
+
}
|
|
12791
|
+
const compactPositions = [], compactIndices = [], remap = /* @__PURE__ */ new Map();
|
|
12792
|
+
for (const original of indices) {
|
|
12793
|
+
let index = remap.get(original);
|
|
12794
|
+
if (index === void 0) {
|
|
12795
|
+
index = compactPositions.length / 3;
|
|
12796
|
+
compactPositions.push(...point(original));
|
|
12797
|
+
remap.set(original, index);
|
|
12798
|
+
}
|
|
12799
|
+
compactIndices.push(index);
|
|
12800
|
+
}
|
|
12801
|
+
if (!compactIndices.length)
|
|
12802
|
+
throw new Error("Expected finite nonempty geometry");
|
|
12803
|
+
return { positions: compactPositions, indices: compactIndices };
|
|
12804
|
+
}
|
|
12805
|
+
|
|
12806
|
+
// node_modules/@tscircuit/jscad/lib/index.ts
|
|
12807
|
+
var jscad2 = withReferences();
|
|
12808
|
+
var {
|
|
12809
|
+
booleans,
|
|
12810
|
+
colors,
|
|
12811
|
+
curves,
|
|
12812
|
+
expansions,
|
|
12813
|
+
extrusions,
|
|
12814
|
+
geometries,
|
|
12815
|
+
hulls,
|
|
12816
|
+
maths,
|
|
12817
|
+
measurements,
|
|
12818
|
+
modifiers,
|
|
12819
|
+
primitives,
|
|
12820
|
+
text,
|
|
12821
|
+
transforms,
|
|
12822
|
+
utils,
|
|
12823
|
+
references
|
|
12824
|
+
} = jscad2;
|
|
12825
|
+
|
|
12826
|
+
// lib/vanilla/render.ts
|
|
12827
|
+
var isVNode = (n) => n && typeof n === "object" && "type" in n;
|
|
12828
|
+
var degToRad = (v) => {
|
|
12829
|
+
if (typeof v === "number") return v;
|
|
12830
|
+
if (typeof v === "string") {
|
|
12831
|
+
const m = /^(-?\d+(?:\.\d+)?)\s*deg$/i.exec(v);
|
|
12832
|
+
if (m) return parseFloat(m[1]) * Math.PI / 180;
|
|
12833
|
+
const n = Number(v);
|
|
12834
|
+
if (!Number.isNaN(n)) return n;
|
|
12835
|
+
}
|
|
12836
|
+
return 0;
|
|
12837
|
+
};
|
|
12838
|
+
var toVec3 = (v) => {
|
|
12839
|
+
if (Array.isArray(v))
|
|
12840
|
+
return [Number(v[0]) || 0, Number(v[1]) || 0, Number(v[2]) || 0];
|
|
12841
|
+
if (typeof v === "object" && v)
|
|
12842
|
+
return [Number(v.x) || 0, Number(v.y) || 0, Number(v.z) || 0];
|
|
12843
|
+
return [0, 0, 0];
|
|
12844
|
+
};
|
|
12845
|
+
var assertFiniteFeatureTransform = (values) => {
|
|
12846
|
+
if (!values.every(Number.isFinite))
|
|
12847
|
+
throw new Error("JSCAD reference feature transforms must be finite");
|
|
12848
|
+
};
|
|
12849
|
+
var transformFeatureContext = (context, local) => {
|
|
12850
|
+
if (!context.referenceFeatures) return context;
|
|
12851
|
+
const { mat4 } = context.jscad.maths;
|
|
12852
|
+
const matrix = mat4.multiply(mat4.create(), context.matrix, local);
|
|
12853
|
+
assertFiniteFeatureTransform(matrix);
|
|
12854
|
+
return { ...context, matrix };
|
|
12855
|
+
};
|
|
12856
|
+
var validateFeatureName = (name) => {
|
|
12857
|
+
if (name !== void 0 && (typeof name !== "string" || !name.trim()))
|
|
12858
|
+
throw new Error("Named JSCAD features require a nonblank name");
|
|
12859
|
+
};
|
|
12860
|
+
var recordFeature = (context, name, geometry) => {
|
|
12861
|
+
if (!context.referenceFeatures || name === void 0) return;
|
|
12862
|
+
if (Object.hasOwn(context.referenceFeatures, name))
|
|
12863
|
+
throw new Error(`Duplicate JSCAD feature name "${name}"`);
|
|
12864
|
+
const { geometries: geometries9 } = context.jscad;
|
|
12865
|
+
if (!geometries9.geom2.isA(geometry) && !geometries9.path2.isA(geometry) && !geometries9.geom3.isA(geometry))
|
|
12866
|
+
throw new Error(`Named JSCAD feature "${name}" requires native geometry`);
|
|
12867
|
+
assertFiniteFeatureTransform(context.matrix);
|
|
12868
|
+
context.referenceFeatures[name] = {
|
|
12869
|
+
geometry,
|
|
12870
|
+
matrix: [...context.matrix]
|
|
12871
|
+
};
|
|
12872
|
+
};
|
|
12873
|
+
function renderNode(node, colorCtx, renderCtx) {
|
|
12874
|
+
const {
|
|
12875
|
+
jscad: { primitives: primitives9, booleans: booleans5, hulls: hulls2, geometries: geometries9, extrusions: extrusions9, transforms: transforms3 }
|
|
12876
|
+
} = renderCtx;
|
|
12877
|
+
if (node == null || node === false) return [];
|
|
12878
|
+
if (Array.isArray(node))
|
|
12879
|
+
return node.flatMap((n) => renderNode(n, colorCtx, renderCtx));
|
|
12880
|
+
if (!isVNode(node)) return [];
|
|
12881
|
+
const { type, props, children } = node;
|
|
12882
|
+
if (props?.material) {
|
|
12883
|
+
const { material, ...rest } = props;
|
|
12884
|
+
return renderNode({ ...node, props: rest }, colorCtx, renderCtx).map(
|
|
12885
|
+
(entry) => ({
|
|
12886
|
+
...entry,
|
|
12887
|
+
material: { ...material },
|
|
12888
|
+
geom: { ...entry.geom, material: { ...material } }
|
|
12889
|
+
})
|
|
12890
|
+
);
|
|
12891
|
+
}
|
|
12892
|
+
if (type === Fragment) {
|
|
12893
|
+
return (children ?? []).flatMap((c) => renderNode(c, colorCtx, renderCtx));
|
|
12894
|
+
}
|
|
12895
|
+
if (type === Colorize) {
|
|
12896
|
+
const newColor = props?.color;
|
|
12897
|
+
return (children ?? []).flatMap(
|
|
12898
|
+
(c) => renderNode(c, newColor ?? colorCtx, renderCtx)
|
|
12899
|
+
);
|
|
12900
|
+
}
|
|
12901
|
+
if (type === Translate) {
|
|
12902
|
+
const offset = props?.offset ?? props?.center ?? { x: props?.x, y: props?.y, z: props?.z };
|
|
12903
|
+
if (renderCtx.referenceFeatures)
|
|
12904
|
+
assertFiniteFeatureTransform(
|
|
12905
|
+
(Array.isArray(offset) ? offset.slice(0, 3) : [offset?.x, offset?.y, offset?.z]).map((value) => Number(value ?? 0))
|
|
12906
|
+
);
|
|
12907
|
+
const off = toVec3(offset);
|
|
12908
|
+
const { mat4 } = renderCtx.jscad.maths;
|
|
12909
|
+
const childContext = transformFeatureContext(
|
|
12910
|
+
renderCtx,
|
|
12911
|
+
mat4.fromTranslation(mat4.create(), off)
|
|
12912
|
+
);
|
|
12913
|
+
const geoms = (children ?? []).flatMap(
|
|
12914
|
+
(c) => renderNode(c, colorCtx, childContext)
|
|
12915
|
+
);
|
|
12916
|
+
return geoms.map(({ geom, color, material }) => ({
|
|
12917
|
+
material,
|
|
12918
|
+
geom: transforms3.translate(off, geom),
|
|
12919
|
+
color: color ?? colorCtx
|
|
12920
|
+
}));
|
|
12921
|
+
}
|
|
12922
|
+
if (type === Rotate) {
|
|
12923
|
+
const angles = props?.angles ?? props?.rotation;
|
|
12924
|
+
if (renderCtx.referenceFeatures)
|
|
12925
|
+
assertFiniteFeatureTransform(
|
|
12926
|
+
(Array.isArray(angles) ? angles.slice(0, 3) : [props?.x, props?.y, props?.z]).map(
|
|
12927
|
+
(value) => Number(
|
|
12928
|
+
typeof value === "string" ? value.replace(/\s*deg$/i, "") : value ?? 0
|
|
12929
|
+
)
|
|
12930
|
+
)
|
|
12931
|
+
);
|
|
12932
|
+
const rot = Array.isArray(angles) ? [degToRad(angles[0]), degToRad(angles[1]), degToRad(angles[2])] : [
|
|
12933
|
+
degToRad(props?.x ?? 0),
|
|
12934
|
+
degToRad(props?.y ?? 0),
|
|
12935
|
+
degToRad(props?.z ?? 0)
|
|
12936
|
+
];
|
|
12937
|
+
const { mat4 } = renderCtx.jscad.maths;
|
|
12938
|
+
const childContext = transformFeatureContext(
|
|
12939
|
+
renderCtx,
|
|
12940
|
+
mat4.fromTaitBryanRotation(mat4.create(), rot[2], rot[1], rot[0])
|
|
12941
|
+
);
|
|
12942
|
+
const geoms = (children ?? []).flatMap(
|
|
12943
|
+
(c) => renderNode(c, colorCtx, childContext)
|
|
12944
|
+
);
|
|
12945
|
+
return geoms.map(({ geom, color, material }) => ({
|
|
12946
|
+
material,
|
|
12947
|
+
geom: transforms3.rotateZ(
|
|
12948
|
+
rot[2],
|
|
12949
|
+
transforms3.rotateY(rot[1], transforms3.rotateX(rot[0], geom))
|
|
12950
|
+
),
|
|
12951
|
+
color
|
|
12952
|
+
}));
|
|
12953
|
+
}
|
|
12954
|
+
if (type === Union || type === Subtract || type === Hull) {
|
|
12955
|
+
const entries = (children ?? []).flatMap(
|
|
12956
|
+
(c) => renderNode(c, colorCtx, renderCtx)
|
|
12957
|
+
);
|
|
12958
|
+
const geoms = entries.map((g) => g.geom);
|
|
12959
|
+
if (geoms.length === 0) return [];
|
|
12960
|
+
let geom;
|
|
12961
|
+
if (type === Union) geom = booleans5.union(geoms);
|
|
12962
|
+
else if (type === Subtract)
|
|
12963
|
+
geom = booleans5.subtract(geoms[0], geoms.slice(1));
|
|
12964
|
+
else geom = hulls2.hull(geoms);
|
|
12965
|
+
return [
|
|
12966
|
+
{
|
|
12967
|
+
geom,
|
|
12968
|
+
color: colorCtx,
|
|
12969
|
+
material: type === Subtract ? entries[0]?.material : void 0
|
|
12970
|
+
}
|
|
12971
|
+
];
|
|
12972
|
+
}
|
|
12973
|
+
if (type === Custom) {
|
|
12974
|
+
const { name, reference, geometry } = props;
|
|
12975
|
+
validateFeatureName(name);
|
|
12976
|
+
if (reference && name === void 0)
|
|
12977
|
+
throw new Error("Named JSCAD features require a nonblank name");
|
|
12978
|
+
recordFeature(renderCtx, name, geometry);
|
|
12979
|
+
if (reference) return [];
|
|
12980
|
+
return [{ geom: props.geometry, color: colorCtx }];
|
|
12981
|
+
}
|
|
12982
|
+
if (type === Polygon) {
|
|
12983
|
+
const points = props?.points ?? [];
|
|
12984
|
+
const origin = points[0] ?? [0, 0];
|
|
12985
|
+
const area = points.reduce((sum, point, index) => {
|
|
12986
|
+
const next = points[(index + 1) % points.length];
|
|
12987
|
+
return sum + (point[0] - origin[0]) * (next[1] - origin[1]) - (next[0] - origin[0]) * (point[1] - origin[1]);
|
|
12988
|
+
}, 0);
|
|
12989
|
+
const oriented = area < 0 ? [...points].reverse() : points;
|
|
12990
|
+
const g2 = geometries9.geom2.fromPoints(oriented);
|
|
12991
|
+
return [{ geom: g2, color: colorCtx ?? props?.color }];
|
|
12992
|
+
}
|
|
12993
|
+
if (type === ExtrudeLinear) {
|
|
12994
|
+
const { topOutlineName, bottomOutlineName, twistAngle, twistSteps } = props;
|
|
12995
|
+
const namedOutline = topOutlineName !== void 0 || bottomOutlineName !== void 0;
|
|
12996
|
+
const height10 = props?.height ?? props?.h ?? 1;
|
|
12997
|
+
validateFeatureName(topOutlineName);
|
|
12998
|
+
validateFeatureName(bottomOutlineName);
|
|
12999
|
+
if (namedOutline) {
|
|
13000
|
+
if (!Number.isFinite(height10) || !Number.isFinite(twistAngle ?? 0))
|
|
13001
|
+
throw new Error(
|
|
13002
|
+
"Named extrusion outlines require finite height and twistAngle"
|
|
13003
|
+
);
|
|
13004
|
+
if (twistSteps !== void 0 && (!Number.isInteger(twistSteps) || twistSteps < 1))
|
|
13005
|
+
throw new Error(
|
|
13006
|
+
"Named extrusion outlines require positive integer twistSteps"
|
|
13007
|
+
);
|
|
13008
|
+
}
|
|
13009
|
+
const entries = (children ?? []).flatMap(
|
|
13010
|
+
(c) => renderNode(c, colorCtx, renderCtx)
|
|
13011
|
+
);
|
|
13012
|
+
const geoms2 = entries.map((g) => g.geom);
|
|
13013
|
+
if (geoms2.length === 0) return [];
|
|
13014
|
+
if (namedOutline && geoms2.length !== 1)
|
|
13015
|
+
throw new Error("Named extrusion outlines require exactly one profile");
|
|
13016
|
+
const base2 = geoms2.length > 1 ? booleans5.union(geoms2) : geoms2[0];
|
|
13017
|
+
if (namedOutline && !geometries9.geom2.isA(base2) && !(geometries9.path2.isA(base2) && base2.isClosed))
|
|
13018
|
+
throw new Error(
|
|
13019
|
+
"Named extrusion outlines require a geom2 or closed path2 profile"
|
|
13020
|
+
);
|
|
13021
|
+
if (namedOutline && renderCtx.referenceFeatures) {
|
|
13022
|
+
const { mat4 } = renderCtx.jscad.maths;
|
|
13023
|
+
const topContext = transformFeatureContext(
|
|
13024
|
+
renderCtx,
|
|
13025
|
+
mat4.multiply(
|
|
13026
|
+
mat4.create(),
|
|
13027
|
+
mat4.fromTranslation(mat4.create(), [0, 0, height10]),
|
|
13028
|
+
mat4.fromZRotation(mat4.create(), twistAngle ?? 0)
|
|
13029
|
+
)
|
|
13030
|
+
);
|
|
13031
|
+
recordFeature(topContext, topOutlineName, base2);
|
|
13032
|
+
recordFeature(renderCtx, bottomOutlineName, base2);
|
|
13033
|
+
}
|
|
13034
|
+
const g3 = extrusions9.extrudeLinear(
|
|
13035
|
+
{
|
|
13036
|
+
height: height10,
|
|
13037
|
+
...twistAngle !== void 0 ? { twistAngle } : {},
|
|
13038
|
+
...twistSteps !== void 0 ? { twistSteps } : {}
|
|
13039
|
+
},
|
|
13040
|
+
base2
|
|
13041
|
+
);
|
|
13042
|
+
return [
|
|
13043
|
+
{
|
|
13044
|
+
geom: g3,
|
|
13045
|
+
color: colorCtx ?? props?.color,
|
|
13046
|
+
material: entries.length === 1 ? entries[0]?.material : void 0
|
|
13047
|
+
}
|
|
13048
|
+
];
|
|
13049
|
+
}
|
|
13050
|
+
if (type === Cuboid || type === Cube || type === Cylinder || type === Sphere || type === RoundedCuboid || type === RoundedCylinder) {
|
|
13051
|
+
let g;
|
|
13052
|
+
if (type === Cuboid) {
|
|
13053
|
+
const size = props?.size ?? [1, 1, 1];
|
|
13054
|
+
const offset = props?.offset;
|
|
13055
|
+
const center = props?.center ?? (offset ? [offset[0], offset[1], offset[2]] : [0, 0, 0]);
|
|
13056
|
+
g = primitives9.cuboid({ size, center });
|
|
13057
|
+
} else if (type === Cube) {
|
|
13058
|
+
const size = props?.size ?? 1;
|
|
13059
|
+
const offset = props?.offset;
|
|
13060
|
+
const center = props?.center ?? (offset ? [offset[0], offset[1], offset[2]] : [0, 0, 0]);
|
|
13061
|
+
g = primitives9.cube({ size, center });
|
|
13062
|
+
} else if (type === Cylinder) {
|
|
13063
|
+
const height10 = props?.height ?? 1;
|
|
13064
|
+
const radius = props?.radius ?? 1;
|
|
13065
|
+
const center = props?.center ?? [0, 0, 0];
|
|
13066
|
+
g = primitives9.cylinder({ height: height10, radius, center });
|
|
13067
|
+
} else if (type === Sphere) {
|
|
13068
|
+
const radius = props?.radius ?? 1;
|
|
13069
|
+
const center = props?.center ?? [0, 0, 0];
|
|
13070
|
+
g = primitives9.sphere({ radius, center });
|
|
13071
|
+
} else if (type === RoundedCylinder) {
|
|
13072
|
+
const height10 = props?.height ?? 1;
|
|
13073
|
+
const radius = props?.radius ?? 1;
|
|
13074
|
+
const roundRadius = props?.roundRadius ?? 0.1;
|
|
13075
|
+
const center = props?.center ?? [0, 0, 0];
|
|
13076
|
+
g = primitives9.roundedCylinder({ height: height10, radius, roundRadius, center });
|
|
13077
|
+
} else {
|
|
13078
|
+
const size = props?.size ?? [1, 1, 1];
|
|
13079
|
+
const roundRadius = props?.roundRadius ?? 0.1;
|
|
13080
|
+
const center = props?.center ?? [0, 0, 0];
|
|
13081
|
+
g = primitives9.roundedCuboid({ size, roundRadius, center });
|
|
13082
|
+
}
|
|
13083
|
+
return [{ geom: g, color: colorCtx ?? props?.color }];
|
|
13084
|
+
}
|
|
13085
|
+
if (typeof type === "function") {
|
|
13086
|
+
const out = type(props ?? {});
|
|
13087
|
+
return renderNode(out, colorCtx, renderCtx);
|
|
13088
|
+
}
|
|
13089
|
+
return (children ?? []).flatMap((c) => renderNode(c, colorCtx, renderCtx));
|
|
13090
|
+
}
|
|
13091
|
+
function render(root, jscad22) {
|
|
13092
|
+
jscad22 = withReferences(
|
|
13093
|
+
jscad22
|
|
13094
|
+
);
|
|
13095
|
+
const geometries9 = renderNode(root, void 0, { jscad: jscad22 });
|
|
13096
|
+
return {
|
|
13097
|
+
geometries: geometries9.map(
|
|
13098
|
+
(entry) => entry.material ? { ...entry, geom: { ...entry.geom, material: entry.material } } : entry
|
|
13099
|
+
)
|
|
13100
|
+
};
|
|
13101
|
+
}
|
|
13102
|
+
function renderToJscadModel(root, jscad22) {
|
|
13103
|
+
jscad22 = withReferences(
|
|
13104
|
+
jscad22
|
|
13105
|
+
);
|
|
13106
|
+
const referenceFeatures = /* @__PURE__ */ Object.create(null);
|
|
13107
|
+
const geometries9 = renderNode(root, void 0, {
|
|
13108
|
+
jscad: jscad22,
|
|
13109
|
+
referenceFeatures,
|
|
13110
|
+
matrix: jscad22.maths.mat4.create()
|
|
13111
|
+
});
|
|
13112
|
+
return {
|
|
13113
|
+
geometries: geometries9.map(({ geom, color }) => {
|
|
13114
|
+
if (color === void 0) return geom;
|
|
13115
|
+
const { colors: colors2 } = jscad22;
|
|
13116
|
+
const rgb = typeof color === "string" ? color.startsWith("#") ? colors2.hexToRgb(
|
|
13117
|
+
/^#[\da-f]{3,4}$/i.test(color) ? `#${[...color.slice(1)].map((c) => c + c).join("")}` : color
|
|
13118
|
+
) : colors2.colorNameToRgb(color) : color;
|
|
13119
|
+
if (!rgb) throw new Error(`Unknown JSCAD color "${color}"`);
|
|
13120
|
+
return colors2.colorize(rgb, geom);
|
|
13121
|
+
}),
|
|
13122
|
+
referenceFeatures
|
|
13123
|
+
};
|
|
13124
|
+
}
|
|
13125
|
+
|
|
12386
13126
|
// lib/vanilla/primitives.ts
|
|
12387
13127
|
var Cuboid = /* @__PURE__ */ Symbol("Cuboid");
|
|
12388
13128
|
var Cube = /* @__PURE__ */ Symbol("Cube");
|
|
@@ -12573,11 +13313,11 @@ var ModelRendererRegistry = class {
|
|
|
12573
13313
|
};
|
|
12574
13314
|
|
|
12575
13315
|
// lib/models/anglebar/geometry.ts
|
|
12576
|
-
import
|
|
12577
|
-
var { primitives, extrusions, geometries, modifiers, measurements } =
|
|
12578
|
-
var generalize =
|
|
12579
|
-
var { rectangle, roundedRectangle, polygon } =
|
|
12580
|
-
var profile = (shape49, height10) =>
|
|
13316
|
+
import jscad3 from "@jscad/modeling";
|
|
13317
|
+
var { primitives: primitives2, extrusions: extrusions2, geometries: geometries2, modifiers: modifiers2, measurements: measurements2 } = jscad3;
|
|
13318
|
+
var generalize = modifiers2.generalize;
|
|
13319
|
+
var { rectangle, roundedRectangle, polygon } = primitives2;
|
|
13320
|
+
var profile = (shape49, height10) => extrusions2.extrudeLinear({ height: height10 }, shape49);
|
|
12581
13321
|
function filletProfile(points, radii, width10, height10) {
|
|
12582
13322
|
const outline = [];
|
|
12583
13323
|
for (let i = 0; i < points.length; i++) {
|
|
@@ -12636,7 +13376,7 @@ function createAngleBarMesh(input) {
|
|
|
12636
13376
|
{ snap: true, triangulate: true },
|
|
12637
13377
|
createAngleBarGeom(input)
|
|
12638
13378
|
);
|
|
12639
|
-
const epsilon = Math.max(...
|
|
13379
|
+
const epsilon = Math.max(...measurements2.measureDimensions(geom)) * 1e-10;
|
|
12640
13380
|
const positions = [];
|
|
12641
13381
|
const indices = [];
|
|
12642
13382
|
const lookup = /* @__PURE__ */ new Map();
|
|
@@ -12650,7 +13390,7 @@ function createAngleBarMesh(input) {
|
|
|
12650
13390
|
}
|
|
12651
13391
|
return index;
|
|
12652
13392
|
};
|
|
12653
|
-
for (const poly of
|
|
13393
|
+
for (const poly of geometries2.geom3.toPolygons(geom)) {
|
|
12654
13394
|
for (let i = 1; i < poly.vertices.length - 1; i++) {
|
|
12655
13395
|
const a = poly.vertices[0], b = poly.vertices[i], c = poly.vertices[i + 1];
|
|
12656
13396
|
const u = b.map((x, j) => x - a[j]), v = c.map((x, j) => x - a[j]);
|
|
@@ -12683,7 +13423,7 @@ function register55(registry2) {
|
|
|
12683
13423
|
}
|
|
12684
13424
|
|
|
12685
13425
|
// lib/mechanical/indexedMeshToGeom3.ts
|
|
12686
|
-
import
|
|
13426
|
+
import jscad4 from "@jscad/modeling";
|
|
12687
13427
|
function indexedMeshToGeom3(mesh) {
|
|
12688
13428
|
const polygons = [];
|
|
12689
13429
|
for (let i = 0; i < mesh.indices.length; i += 3)
|
|
@@ -12694,7 +13434,7 @@ function indexedMeshToGeom3(mesh) {
|
|
|
12694
13434
|
mesh.positions[index * 3 + 2]
|
|
12695
13435
|
])
|
|
12696
13436
|
);
|
|
12697
|
-
return
|
|
13437
|
+
return jscad4.geometries.geom3.fromPoints(polygons);
|
|
12698
13438
|
}
|
|
12699
13439
|
|
|
12700
13440
|
// lib/models/ballbearing/mesh.ts
|
|
@@ -12823,11 +13563,11 @@ function createBallBearingMesh(input = {}, options = {}) {
|
|
|
12823
13563
|
[ri + 0.15 * (ro - ri), 0.5 * t],
|
|
12824
13564
|
[ro - 0.15 * (ro - ri), 0.5 * t]
|
|
12825
13565
|
];
|
|
12826
|
-
const
|
|
13566
|
+
const profile5 = sign === -1 ? shape49 : shape49.map(([r, z]) => [r, d.width - z]).reverse();
|
|
12827
13567
|
parts.push({
|
|
12828
13568
|
name: `${face2} ${sign < 0 ? "lower" : "upper"}`,
|
|
12829
13569
|
color: face2 === "sealed" ? "#252a30" : "#b5bbc3",
|
|
12830
|
-
mesh: revolve(
|
|
13570
|
+
mesh: revolve(profile5, segments)
|
|
12831
13571
|
});
|
|
12832
13572
|
}
|
|
12833
13573
|
return { ...combine(parts), parts };
|
|
@@ -12844,21 +13584,21 @@ function checkPrecision(lengths25) {
|
|
|
12844
13584
|
"Bearing dimensions exceed the renderer's numerical resolution"
|
|
12845
13585
|
);
|
|
12846
13586
|
}
|
|
12847
|
-
function revolve(
|
|
13587
|
+
function revolve(profile5, segments) {
|
|
12848
13588
|
const positions = [];
|
|
12849
13589
|
const indices = [];
|
|
12850
|
-
for (const [radius, z] of
|
|
13590
|
+
for (const [radius, z] of profile5)
|
|
12851
13591
|
for (let i = 0; i < segments; i++) {
|
|
12852
13592
|
const angle = i * Math.PI * 2 / segments;
|
|
12853
13593
|
const r = typeof radius === "number" ? radius : radius(angle);
|
|
12854
13594
|
positions.push(r * Math.cos(angle), r * Math.sin(angle), z);
|
|
12855
13595
|
}
|
|
12856
|
-
for (let j = 0; j <
|
|
13596
|
+
for (let j = 0; j < profile5.length; j++)
|
|
12857
13597
|
for (let i = 0; i < segments; i++) {
|
|
12858
13598
|
const a = j * segments + i;
|
|
12859
13599
|
const b = j * segments + (i + 1) % segments;
|
|
12860
|
-
const c = (j + 1) %
|
|
12861
|
-
const e = (j + 1) %
|
|
13600
|
+
const c = (j + 1) % profile5.length * segments + (i + 1) % segments;
|
|
13601
|
+
const e = (j + 1) % profile5.length * segments + i;
|
|
12862
13602
|
indices.push(a, b, c, a, c, e);
|
|
12863
13603
|
}
|
|
12864
13604
|
return { positions, indices };
|
|
@@ -12869,7 +13609,7 @@ function annularSector(inner, outer, z0, z1, start, end, segments) {
|
|
|
12869
13609
|
Math.ceil((end - start) / (2 * Math.PI) * segments)
|
|
12870
13610
|
);
|
|
12871
13611
|
const count = steps + 1;
|
|
12872
|
-
const
|
|
13612
|
+
const profile5 = [
|
|
12873
13613
|
[outer, z0],
|
|
12874
13614
|
[outer, z1],
|
|
12875
13615
|
[inner, z1],
|
|
@@ -12877,7 +13617,7 @@ function annularSector(inner, outer, z0, z1, start, end, segments) {
|
|
|
12877
13617
|
];
|
|
12878
13618
|
const positions = [];
|
|
12879
13619
|
const indices = [];
|
|
12880
|
-
for (const [r, z] of
|
|
13620
|
+
for (const [r, z] of profile5)
|
|
12881
13621
|
for (let i = 0; i <= steps; i++) {
|
|
12882
13622
|
const angle = start + (end - start) * i / steps;
|
|
12883
13623
|
positions.push(r * Math.cos(angle), r * Math.sin(angle), z);
|
|
@@ -13068,7 +13808,7 @@ function createBallTransferUnitMesh(input = {}) {
|
|
|
13068
13808
|
);
|
|
13069
13809
|
const segments = 96;
|
|
13070
13810
|
const latitude = 48;
|
|
13071
|
-
const
|
|
13811
|
+
const profile5 = [
|
|
13072
13812
|
[d.bodyRadius, 0],
|
|
13073
13813
|
[d.bodyRadius, d.flangeBottomZ],
|
|
13074
13814
|
[d.flangeRadius, d.flangeBottomZ],
|
|
@@ -13081,12 +13821,12 @@ function createBallTransferUnitMesh(input = {}) {
|
|
|
13081
13821
|
for (let j = 1; j < latitude; j++) {
|
|
13082
13822
|
const angle = j * Math.PI / latitude;
|
|
13083
13823
|
if ((angle - openingAngle) * d.socketRadius > resolution7)
|
|
13084
|
-
|
|
13824
|
+
profile5.push([
|
|
13085
13825
|
d.socketRadius * Math.sin(angle),
|
|
13086
13826
|
d.ballCenterZ + d.socketRadius * Math.cos(angle)
|
|
13087
13827
|
]);
|
|
13088
13828
|
}
|
|
13089
|
-
|
|
13829
|
+
profile5.push([0, d.socketBottomZ], [0, 0]);
|
|
13090
13830
|
const holes = d.mountingHoles.map(
|
|
13091
13831
|
({ x, y, diameter }) => circularProfile(x, y, diameter / 2, segments)
|
|
13092
13832
|
);
|
|
@@ -13094,7 +13834,7 @@ function createBallTransferUnitMesh(input = {}) {
|
|
|
13094
13834
|
const housing = joinProfileMeshes([
|
|
13095
13835
|
// Cap faces are triangulated with all openings, rather than covered by
|
|
13096
13836
|
// annular triangles and repaired afterward with Boolean subtraction.
|
|
13097
|
-
revolve2(
|
|
13837
|
+
revolve2(profile5, segments, /* @__PURE__ */ new Set([1, 3])),
|
|
13098
13838
|
cap(
|
|
13099
13839
|
flangeOutline,
|
|
13100
13840
|
[circularProfile(0, 0, d.bodyRadius, segments), ...holes],
|
|
@@ -13131,10 +13871,10 @@ function createBallTransferUnitMesh(input = {}) {
|
|
|
13131
13871
|
];
|
|
13132
13872
|
return { positions, indices, parts };
|
|
13133
13873
|
}
|
|
13134
|
-
function revolve2(
|
|
13874
|
+
function revolve2(profile5, segments, omittedEdges = /* @__PURE__ */ new Set()) {
|
|
13135
13875
|
const positions = [];
|
|
13136
13876
|
const indices = [];
|
|
13137
|
-
const rings =
|
|
13877
|
+
const rings = profile5.map(([radius, z]) => {
|
|
13138
13878
|
const start = positions.length / 3;
|
|
13139
13879
|
const count = radius === 0 ? 1 : segments;
|
|
13140
13880
|
for (let i = 0; i < count; i++) {
|
|
@@ -13416,11 +14156,11 @@ function register59(registry2) {
|
|
|
13416
14156
|
}
|
|
13417
14157
|
|
|
13418
14158
|
// lib/models/channelbar/geometry.ts
|
|
13419
|
-
import
|
|
13420
|
-
var { primitives:
|
|
13421
|
-
var generalize2 =
|
|
13422
|
-
var { rectangle: rectangle2, roundedRectangle: roundedRectangle2, polygon: polygon2 } =
|
|
13423
|
-
var profile2 = (shape49, height10) =>
|
|
14159
|
+
import jscad5 from "@jscad/modeling";
|
|
14160
|
+
var { primitives: primitives3, extrusions: extrusions3, geometries: geometries3, modifiers: modifiers3, measurements: measurements3 } = jscad5;
|
|
14161
|
+
var generalize2 = modifiers3.generalize;
|
|
14162
|
+
var { rectangle: rectangle2, roundedRectangle: roundedRectangle2, polygon: polygon2 } = primitives3;
|
|
14163
|
+
var profile2 = (shape49, height10) => extrusions3.extrudeLinear({ height: height10 }, shape49);
|
|
13424
14164
|
function filletProfile2(points, radii, width10, height10) {
|
|
13425
14165
|
const outline = [];
|
|
13426
14166
|
for (let i = 0; i < points.length; i++) {
|
|
@@ -13490,7 +14230,7 @@ function createChannelBarMesh(input) {
|
|
|
13490
14230
|
{ snap: true, triangulate: true },
|
|
13491
14231
|
createChannelBarGeom(input)
|
|
13492
14232
|
);
|
|
13493
|
-
const epsilon = Math.max(...
|
|
14233
|
+
const epsilon = Math.max(...measurements3.measureDimensions(geom)) * 1e-10;
|
|
13494
14234
|
const positions = [];
|
|
13495
14235
|
const indices = [];
|
|
13496
14236
|
const lookup = /* @__PURE__ */ new Map();
|
|
@@ -13504,7 +14244,7 @@ function createChannelBarMesh(input) {
|
|
|
13504
14244
|
}
|
|
13505
14245
|
return index;
|
|
13506
14246
|
};
|
|
13507
|
-
for (const poly of
|
|
14247
|
+
for (const poly of geometries3.geom3.toPolygons(geom)) {
|
|
13508
14248
|
for (let i = 1; i < poly.vertices.length - 1; i++) {
|
|
13509
14249
|
const a = poly.vertices[0], b = poly.vertices[i], c = poly.vertices[i + 1];
|
|
13510
14250
|
const u = b.map((x, j) => x - a[j]), v = c.map((x, j) => x - a[j]);
|
|
@@ -13537,10 +14277,10 @@ function register60(registry2) {
|
|
|
13537
14277
|
}
|
|
13538
14278
|
|
|
13539
14279
|
// lib/models/clampingshaftcollar/mesh.ts
|
|
13540
|
-
import
|
|
14280
|
+
import jscad7 from "@jscad/modeling";
|
|
13541
14281
|
|
|
13542
14282
|
// lib/mechanical/shaft-mount-geometry.ts
|
|
13543
|
-
import
|
|
14283
|
+
import jscad6 from "@jscad/modeling";
|
|
13544
14284
|
var bodySegments = 64;
|
|
13545
14285
|
var threadSegments = 24;
|
|
13546
14286
|
var samplesPerTurn = 12;
|
|
@@ -13583,22 +14323,22 @@ function createAnnularSleeve({
|
|
|
13583
14323
|
[chamfer, boreARadius, true],
|
|
13584
14324
|
[0, boreARadius + chamfer, true]
|
|
13585
14325
|
];
|
|
13586
|
-
const
|
|
14326
|
+
const profile5 = raw.filter(
|
|
13587
14327
|
([z, r], i) => i === 0 || z !== raw[i - 1][0] || r !== raw[i - 1][1]
|
|
13588
14328
|
);
|
|
13589
14329
|
const positions = [];
|
|
13590
14330
|
const indices = [];
|
|
13591
|
-
for (const [z, r, isBore] of
|
|
14331
|
+
for (const [z, r, isBore] of profile5)
|
|
13592
14332
|
for (let i = 0; i < bodySegments; i++) {
|
|
13593
14333
|
const angle = (i + (isBore ? 0.5 : 0)) * Math.PI * 2 / bodySegments;
|
|
13594
14334
|
const radius = isBore ? r / cosine : r;
|
|
13595
14335
|
positions.push(radius * Math.cos(angle), radius * Math.sin(angle), z);
|
|
13596
14336
|
}
|
|
13597
|
-
for (let row = 0; row <
|
|
14337
|
+
for (let row = 0; row < profile5.length; row++)
|
|
13598
14338
|
for (let i = 0; i < bodySegments; i++) {
|
|
13599
14339
|
const next = (i + 1) % bodySegments;
|
|
13600
14340
|
const a = row * bodySegments + i, b = row * bodySegments + next;
|
|
13601
|
-
const c = (row + 1) %
|
|
14341
|
+
const c = (row + 1) % profile5.length * bodySegments + next, d = (row + 1) % profile5.length * bodySegments + i;
|
|
13602
14342
|
indices.push(a, b, c, a, c, d);
|
|
13603
14343
|
}
|
|
13604
14344
|
return indexedMeshToGeom3({ positions, indices });
|
|
@@ -13656,10 +14396,10 @@ function createMountingHoleCutter(hole) {
|
|
|
13656
14396
|
function subtractShaftMountParts(body, ...cutters) {
|
|
13657
14397
|
const factor = 100;
|
|
13658
14398
|
const scaled = [body, ...cutters].map(
|
|
13659
|
-
(geometry) =>
|
|
14399
|
+
(geometry) => jscad6.transforms.scale([factor, factor, factor], geometry)
|
|
13660
14400
|
);
|
|
13661
|
-
const result =
|
|
13662
|
-
return
|
|
14401
|
+
const result = jscad6.booleans.subtract(scaled[0], ...scaled.slice(1));
|
|
14402
|
+
return jscad6.transforms.scale([1 / factor, 1 / factor, 1 / factor], result);
|
|
13663
14403
|
}
|
|
13664
14404
|
function finishShaftMountMesh(geometry) {
|
|
13665
14405
|
const positions = [];
|
|
@@ -13685,7 +14425,7 @@ function finishShaftMountMesh(geometry) {
|
|
|
13685
14425
|
vertices.set(key, [...vertices.get(key) ?? [], index]);
|
|
13686
14426
|
return index;
|
|
13687
14427
|
};
|
|
13688
|
-
const polygons =
|
|
14428
|
+
const polygons = jscad6.geometries.geom3.toPolygons(geometry).map(
|
|
13689
14429
|
(polygon4) => polygon4.vertices.map(weld).filter((id, i, ids) => id !== ids[(i + ids.length - 1) % ids.length])
|
|
13690
14430
|
).map((ids) => [...new Set(ids)]).filter((ids) => ids.length >= 3).filter((ids) => {
|
|
13691
14431
|
let longest = 0;
|
|
@@ -13708,11 +14448,11 @@ function finishShaftMountMesh(geometry) {
|
|
|
13708
14448
|
return Math.hypot(...delta.map((v, axis) => v - t * direction[axis])) >= tolerance;
|
|
13709
14449
|
});
|
|
13710
14450
|
});
|
|
13711
|
-
const
|
|
14451
|
+
const edgeKey2 = (a, b) => `${Math.min(a, b)},${Math.max(a, b)}`;
|
|
13712
14452
|
const edges = /* @__PURE__ */ new Map();
|
|
13713
14453
|
for (const polygon4 of polygons)
|
|
13714
14454
|
for (let i = 0; i < polygon4.length; i++) {
|
|
13715
|
-
const a = polygon4[i], b = polygon4[(i + 1) % polygon4.length], key =
|
|
14455
|
+
const a = polygon4[i], b = polygon4[(i + 1) % polygon4.length], key = edgeKey2(a, b);
|
|
13716
14456
|
const edge = edges.get(key) ?? { a, b, count: 0 };
|
|
13717
14457
|
edge.count++;
|
|
13718
14458
|
edges.set(key, edge);
|
|
@@ -13797,7 +14537,7 @@ function createClampingShaftCollarMesh(input) {
|
|
|
13797
14537
|
});
|
|
13798
14538
|
const s = dimensions5.split;
|
|
13799
14539
|
const epsilon = 1e-4;
|
|
13800
|
-
const slit =
|
|
14540
|
+
const slit = jscad7.primitives.cuboid({
|
|
13801
14541
|
size: [
|
|
13802
14542
|
s.xMax - s.xMin + epsilon,
|
|
13803
14543
|
s.yMax - s.yMin,
|
|
@@ -14372,7 +15112,7 @@ function createFlangedBushingMesh(input) {
|
|
|
14372
15112
|
const ri = d.innerDiameter / 2;
|
|
14373
15113
|
const ro = d.outerDiameter / 2;
|
|
14374
15114
|
const rf = d.flangeDiameter / 2;
|
|
14375
|
-
const
|
|
15115
|
+
const profile5 = [
|
|
14376
15116
|
[rf, 0],
|
|
14377
15117
|
[rf, d.shoulderZ],
|
|
14378
15118
|
[ro, d.shoulderZ],
|
|
@@ -14383,14 +15123,14 @@ function createFlangedBushingMesh(input) {
|
|
|
14383
15123
|
const segments = 96;
|
|
14384
15124
|
const positions = [];
|
|
14385
15125
|
const indices = [];
|
|
14386
|
-
for (const [radius, z] of
|
|
15126
|
+
for (const [radius, z] of profile5)
|
|
14387
15127
|
for (let i = 0; i < segments; i++) {
|
|
14388
15128
|
const angle = i * Math.PI * 2 / segments;
|
|
14389
15129
|
positions.push(radius * Math.cos(angle), radius * Math.sin(angle), z);
|
|
14390
15130
|
}
|
|
14391
|
-
for (let ring = 0; ring <
|
|
15131
|
+
for (let ring = 0; ring < profile5.length; ring++) {
|
|
14392
15132
|
const a = ring * segments;
|
|
14393
|
-
const b = (ring + 1) %
|
|
15133
|
+
const b = (ring + 1) % profile5.length * segments;
|
|
14394
15134
|
for (let i = 0; i < segments; i++) {
|
|
14395
15135
|
const next = (i + 1) % segments;
|
|
14396
15136
|
indices.push(a + i, a + next, b + next, a + i, b + next, b + i);
|
|
@@ -14535,15 +15275,15 @@ function register67(registry2) {
|
|
|
14535
15275
|
}
|
|
14536
15276
|
|
|
14537
15277
|
// lib/models/flatcableclip/geometry.ts
|
|
14538
|
-
import
|
|
15278
|
+
import jscad8 from "@jscad/modeling";
|
|
14539
15279
|
var {
|
|
14540
|
-
primitives:
|
|
14541
|
-
extrusions:
|
|
14542
|
-
transforms,
|
|
14543
|
-
booleans,
|
|
14544
|
-
geometries:
|
|
14545
|
-
measurements:
|
|
14546
|
-
} =
|
|
15280
|
+
primitives: primitives4,
|
|
15281
|
+
extrusions: extrusions4,
|
|
15282
|
+
transforms: transforms2,
|
|
15283
|
+
booleans: booleans2,
|
|
15284
|
+
geometries: geometries4,
|
|
15285
|
+
measurements: measurements4
|
|
15286
|
+
} = jscad8;
|
|
14547
15287
|
function createFlatCableClipSolid(input) {
|
|
14548
15288
|
const p = flatCableClipModelPropsSchema.parse(input);
|
|
14549
15289
|
const legOuter = p.innerWidth / 2 + p.thickness, half = legOuter + p.footLength;
|
|
@@ -14561,25 +15301,25 @@ function createFlatCableClipSolid(input) {
|
|
|
14561
15301
|
[-legOuter, p.thickness],
|
|
14562
15302
|
[-half, p.thickness]
|
|
14563
15303
|
];
|
|
14564
|
-
const bridge =
|
|
15304
|
+
const bridge = transforms2.translate(
|
|
14565
15305
|
[0, p.depth / 2, 0],
|
|
14566
|
-
|
|
15306
|
+
transforms2.rotateX(
|
|
14567
15307
|
Math.PI / 2,
|
|
14568
|
-
|
|
15308
|
+
extrusions4.extrudeLinear(
|
|
14569
15309
|
{ height: p.depth },
|
|
14570
|
-
|
|
15310
|
+
primitives4.polygon({ points })
|
|
14571
15311
|
)
|
|
14572
15312
|
)
|
|
14573
15313
|
);
|
|
14574
15314
|
const bores = [-1, 1].map(
|
|
14575
|
-
(sign) =>
|
|
15315
|
+
(sign) => primitives4.cylinder({
|
|
14576
15316
|
radius: p.holeDiameter / 2,
|
|
14577
15317
|
height: p.thickness + 2,
|
|
14578
15318
|
center: [sign * p.holePitch / 2, 0, p.thickness / 2],
|
|
14579
15319
|
segments: 96
|
|
14580
15320
|
})
|
|
14581
15321
|
);
|
|
14582
|
-
return
|
|
15322
|
+
return booleans2.subtract(bridge, ...bores);
|
|
14583
15323
|
}
|
|
14584
15324
|
function createFlatCableClipMesh(input) {
|
|
14585
15325
|
const p = flatCableClipModelPropsSchema.parse(input);
|
|
@@ -14590,8 +15330,8 @@ function createFlatCableClipMesh(input) {
|
|
|
14590
15330
|
[0, p.thickness, p.innerHeight, p.innerHeight + p.thickness]
|
|
14591
15331
|
];
|
|
14592
15332
|
const geom = createFlatCableClipSolid(p);
|
|
14593
|
-
const tolerance = Math.max(...
|
|
14594
|
-
const polygons =
|
|
15333
|
+
const tolerance = Math.max(...measurements4.measureDimensions(geom)) * 1e-5;
|
|
15334
|
+
const polygons = geometries4.geom3.toPolygons(geom).map(
|
|
14595
15335
|
(poly) => poly.vertices.map(
|
|
14596
15336
|
(point) => point.map((value, axis) => {
|
|
14597
15337
|
const nearest = planes[axis].reduce(
|
|
@@ -14601,7 +15341,7 @@ function createFlatCableClipMesh(input) {
|
|
|
14601
15341
|
})
|
|
14602
15342
|
)
|
|
14603
15343
|
);
|
|
14604
|
-
return finishShaftMountMesh(
|
|
15344
|
+
return finishShaftMountMesh(geometries4.geom3.fromPoints(polygons));
|
|
14605
15345
|
}
|
|
14606
15346
|
function createFlatCableClipGeom(input) {
|
|
14607
15347
|
return indexedMeshToGeom3(createFlatCableClipMesh(input));
|
|
@@ -16504,7 +17244,7 @@ function register79(registry2) {
|
|
|
16504
17244
|
}
|
|
16505
17245
|
|
|
16506
17246
|
// lib/utils/nemaMotorAssemblyGeometry.ts
|
|
16507
|
-
import
|
|
17247
|
+
import jscad9 from "@jscad/modeling";
|
|
16508
17248
|
function nema34AssemblyCenters(p) {
|
|
16509
17249
|
const edge = p.bodyWidth / 2;
|
|
16510
17250
|
return [-1, 1].flatMap(
|
|
@@ -16514,16 +17254,16 @@ function nema34AssemblyCenters(p) {
|
|
|
16514
17254
|
);
|
|
16515
17255
|
}
|
|
16516
17256
|
function cutNema34FrontRecesses(geometry, p) {
|
|
16517
|
-
return
|
|
17257
|
+
return jscad9.booleans.subtract(
|
|
16518
17258
|
geometry,
|
|
16519
17259
|
...nema34AssemblyCenters(p).flatMap(([x, y]) => [
|
|
16520
|
-
|
|
17260
|
+
jscad9.primitives.cylinder({
|
|
16521
17261
|
radius: 1.6,
|
|
16522
17262
|
height: p.frontCapLength + 0.2,
|
|
16523
17263
|
center: [x, y, -p.frontCapLength / 2],
|
|
16524
17264
|
segments: 32
|
|
16525
17265
|
}),
|
|
16526
|
-
|
|
17266
|
+
jscad9.primitives.cylinder({
|
|
16527
17267
|
radius: 5,
|
|
16528
17268
|
height: Math.min(4, p.frontCapLength / 2) + 0.1,
|
|
16529
17269
|
center: [
|
|
@@ -16537,8 +17277,8 @@ function cutNema34FrontRecesses(geometry, p) {
|
|
|
16537
17277
|
);
|
|
16538
17278
|
}
|
|
16539
17279
|
function createNema34FrontScrews(p) {
|
|
16540
|
-
const head =
|
|
16541
|
-
|
|
17280
|
+
const head = jscad9.booleans.subtract(
|
|
17281
|
+
jscad9.primitives.ellipsoid({
|
|
16542
17282
|
radius: [3.2, 3.2, 1.5],
|
|
16543
17283
|
center: [0, 0, -1.8],
|
|
16544
17284
|
segments: 32
|
|
@@ -16547,22 +17287,22 @@ function createNema34FrontScrews(p) {
|
|
|
16547
17287
|
[3.7, 0.8, 1.1],
|
|
16548
17288
|
[0.8, 3.7, 1.1]
|
|
16549
17289
|
].map(
|
|
16550
|
-
(size) =>
|
|
17290
|
+
(size) => jscad9.primitives.cuboid({
|
|
16551
17291
|
size,
|
|
16552
17292
|
center: [0, 0, -0.8]
|
|
16553
17293
|
})
|
|
16554
17294
|
)
|
|
16555
17295
|
);
|
|
16556
17296
|
return nema34AssemblyCenters(p).map(
|
|
16557
|
-
([x, y]) =>
|
|
17297
|
+
([x, y]) => jscad9.transforms.translate([x, y, 0], head)
|
|
16558
17298
|
);
|
|
16559
17299
|
}
|
|
16560
17300
|
|
|
16561
17301
|
// lib/NemaMotor.tsx
|
|
16562
|
-
import
|
|
17302
|
+
import jscad11 from "@jscad/modeling";
|
|
16563
17303
|
|
|
16564
17304
|
// lib/utils/nemaMotorWireGeometry.ts
|
|
16565
|
-
import
|
|
17305
|
+
import jscad10 from "@jscad/modeling";
|
|
16566
17306
|
|
|
16567
17307
|
// lib/utils/nemaMotorParameters.ts
|
|
16568
17308
|
var resolveNemaMotorProps = nemaMotorModelPropsSchema.parse.bind(nemaMotorModelPropsSchema);
|
|
@@ -16573,12 +17313,12 @@ function createNemaMotorWireGeometry(input) {
|
|
|
16573
17313
|
if (p.noWires) return [];
|
|
16574
17314
|
const { position } = getNemaMotorReferencePoints(p).wireside;
|
|
16575
17315
|
const angle = p.wireSideAngle * Math.PI / 180;
|
|
16576
|
-
const place = (geometry) =>
|
|
17316
|
+
const place = (geometry) => jscad10.transforms.translate(
|
|
16577
17317
|
[position.x, position.y, position.z],
|
|
16578
|
-
|
|
17318
|
+
jscad10.transforms.rotateZ(angle, geometry)
|
|
16579
17319
|
);
|
|
16580
17320
|
if (p.wireStubs) {
|
|
16581
|
-
const
|
|
17321
|
+
const colors2 = [
|
|
16582
17322
|
"#d53f3f",
|
|
16583
17323
|
"#2463af",
|
|
16584
17324
|
"#3b934b",
|
|
@@ -16589,17 +17329,17 @@ function createNemaMotorWireGeometry(input) {
|
|
|
16589
17329
|
"#803e91"
|
|
16590
17330
|
];
|
|
16591
17331
|
const wires = Array.from({ length: p.wireCount }, (_, i) => ({
|
|
16592
|
-
color:
|
|
17332
|
+
color: colors2[i],
|
|
16593
17333
|
geometry: place(
|
|
16594
|
-
|
|
17334
|
+
jscad10.transforms.translate(
|
|
16595
17335
|
[
|
|
16596
17336
|
(p.wireLength - 0.15) / 2,
|
|
16597
17337
|
(i - (p.wireCount - 1) / 2) * p.wireDiameter * 1.5,
|
|
16598
17338
|
0
|
|
16599
17339
|
],
|
|
16600
|
-
|
|
17340
|
+
jscad10.transforms.rotateY(
|
|
16601
17341
|
Math.PI / 2,
|
|
16602
|
-
|
|
17342
|
+
jscad10.primitives.cylinder({
|
|
16603
17343
|
height: p.wireLength + 0.15,
|
|
16604
17344
|
radius: p.wireDiameter / 2,
|
|
16605
17345
|
segments: 24
|
|
@@ -16612,7 +17352,7 @@ function createNemaMotorWireGeometry(input) {
|
|
|
16612
17352
|
wires.unshift({
|
|
16613
17353
|
color: "#252830",
|
|
16614
17354
|
geometry: place(
|
|
16615
|
-
|
|
17355
|
+
jscad10.primitives.roundedCuboid({
|
|
16616
17356
|
size: [3, p.wireCount * p.wireDiameter * 1.5 + 3, 6],
|
|
16617
17357
|
center: [0.8, 0, 0],
|
|
16618
17358
|
roundRadius: 1,
|
|
@@ -16627,12 +17367,12 @@ function createNemaMotorWireGeometry(input) {
|
|
|
16627
17367
|
const wall = pitch === 2 ? 0.6 : 0.3;
|
|
16628
17368
|
const contactLength = pitch === 2 ? 3.4 : 2.4;
|
|
16629
17369
|
const contactSize = pitch === 2 ? 0.5 : 0.3;
|
|
16630
|
-
const shell =
|
|
16631
|
-
|
|
17370
|
+
const shell = jscad10.booleans.subtract(
|
|
17371
|
+
jscad10.primitives.cuboid({
|
|
16632
17372
|
size: [matingDepth + 0.1, bodyWidth, bodyHeight],
|
|
16633
17373
|
center: [(matingDepth - 0.1) / 2, 0, 0]
|
|
16634
17374
|
}),
|
|
16635
|
-
|
|
17375
|
+
jscad10.primitives.cuboid({
|
|
16636
17376
|
size: [matingDepth - 0.5, bodyWidth - 2 * wall, bodyHeight - 2 * wall],
|
|
16637
17377
|
center: [matingDepth / 2 + 0.55, 0, 0]
|
|
16638
17378
|
})
|
|
@@ -16642,7 +17382,7 @@ function createNemaMotorWireGeometry(input) {
|
|
|
16642
17382
|
...Array.from({ length: pinCount }, (_, i) => ({
|
|
16643
17383
|
color: "#b8bec6",
|
|
16644
17384
|
geometry: place(
|
|
16645
|
-
|
|
17385
|
+
jscad10.primitives.cuboid({
|
|
16646
17386
|
size: [contactLength, contactSize, contactSize],
|
|
16647
17387
|
center: [contactLength / 2, (i - (pinCount - 1) / 2) * pitch, 0]
|
|
16648
17388
|
})
|
|
@@ -16786,12 +17526,12 @@ function createNemaMotorSections(input) {
|
|
|
16786
17526
|
else {
|
|
16787
17527
|
const cut = r - p.shaftFlatDepth;
|
|
16788
17528
|
const angle = Math.acos(cut / r);
|
|
16789
|
-
const
|
|
17529
|
+
const profile5 = Array.from({ length: 97 }, (_, i) => {
|
|
16790
17530
|
const a = angle + (2 * Math.PI - 2 * angle) * i / 96;
|
|
16791
17531
|
return [r * Math.cos(a), r * Math.sin(a)];
|
|
16792
17532
|
});
|
|
16793
17533
|
const rotation = p.shaftFlatAngle * Math.PI / 180;
|
|
16794
|
-
const d =
|
|
17534
|
+
const d = profile5.map(([x, y]) => [
|
|
16795
17535
|
x * Math.cos(rotation) - y * Math.sin(rotation),
|
|
16796
17536
|
x * Math.sin(rotation) + y * Math.cos(rotation)
|
|
16797
17537
|
]);
|
|
@@ -16802,7 +17542,7 @@ function createNemaMotorSections(input) {
|
|
|
16802
17542
|
}
|
|
16803
17543
|
|
|
16804
17544
|
// lib/NemaMotor.tsx
|
|
16805
|
-
var generalize3 =
|
|
17545
|
+
var generalize3 = jscad11.modifiers.generalize;
|
|
16806
17546
|
function NemaMotor({
|
|
16807
17547
|
bodyColor = "#242830",
|
|
16808
17548
|
capColor = "#aeb5bd",
|
|
@@ -16811,7 +17551,7 @@ function NemaMotor({
|
|
|
16811
17551
|
...props
|
|
16812
17552
|
}) {
|
|
16813
17553
|
const p = resolveNemaMotorProps(props);
|
|
16814
|
-
const screw = p.backFaceScrews ?
|
|
17554
|
+
const screw = p.backFaceScrews ? jscad11.transforms.rotateX(
|
|
16815
17555
|
Math.PI,
|
|
16816
17556
|
createHexSocketBoltGeom({
|
|
16817
17557
|
metricSize: p.backFaceScrewSize,
|
|
@@ -16823,16 +17563,16 @@ function NemaMotor({
|
|
|
16823
17563
|
const halfPitchY = p.backFaceHoleSpacingY / 2;
|
|
16824
17564
|
return /* @__PURE__ */ jsxs(Fragment2, { children: [
|
|
16825
17565
|
createNemaMotorSections(p).map((section, index) => {
|
|
16826
|
-
const outline =
|
|
16827
|
-
const
|
|
17566
|
+
const outline = jscad11.geometries.geom2.fromPoints(section.outline);
|
|
17567
|
+
const profile5 = section.holes.length ? jscad11.booleans.subtract(
|
|
16828
17568
|
outline,
|
|
16829
|
-
...section.holes.map((h2) =>
|
|
17569
|
+
...section.holes.map((h2) => jscad11.geometries.geom2.fromPoints(h2))
|
|
16830
17570
|
) : outline;
|
|
16831
|
-
let geometry =
|
|
17571
|
+
let geometry = jscad11.transforms.translate(
|
|
16832
17572
|
[0, 0, section.zMin],
|
|
16833
|
-
|
|
17573
|
+
jscad11.extrusions.extrudeLinear(
|
|
16834
17574
|
{ height: section.zMax - section.zMin },
|
|
16835
|
-
|
|
17575
|
+
profile5
|
|
16836
17576
|
)
|
|
16837
17577
|
);
|
|
16838
17578
|
if (p.nemaSize === 34 && section.name === "frontCap")
|
|
@@ -16874,7 +17614,7 @@ function NemaMotor({
|
|
|
16874
17614
|
children: /* @__PURE__ */ jsx(
|
|
16875
17615
|
Custom,
|
|
16876
17616
|
{
|
|
16877
|
-
geometry:
|
|
17617
|
+
geometry: jscad11.transforms.translate(
|
|
16878
17618
|
[x, y, -p.bodyLength],
|
|
16879
17619
|
generalize3({ simplify: true }, screw)
|
|
16880
17620
|
)
|
|
@@ -17364,19 +18104,19 @@ function register83(registry2) {
|
|
|
17364
18104
|
}
|
|
17365
18105
|
|
|
17366
18106
|
// lib/models/perforatedsheet/geometry.ts
|
|
17367
|
-
import
|
|
18107
|
+
import jscad12 from "@jscad/modeling";
|
|
17368
18108
|
var {
|
|
17369
|
-
booleans:
|
|
17370
|
-
primitives:
|
|
17371
|
-
extrusions:
|
|
17372
|
-
geometries:
|
|
17373
|
-
modifiers:
|
|
17374
|
-
measurements:
|
|
17375
|
-
} =
|
|
17376
|
-
var generalize4 =
|
|
17377
|
-
var { subtract } =
|
|
17378
|
-
var { rectangle: rectangle3, roundedRectangle: roundedRectangle3, circle: circle2 } =
|
|
17379
|
-
var profile3 = (shape49, height10) =>
|
|
18109
|
+
booleans: booleans3,
|
|
18110
|
+
primitives: primitives5,
|
|
18111
|
+
extrusions: extrusions5,
|
|
18112
|
+
geometries: geometries5,
|
|
18113
|
+
modifiers: modifiers4,
|
|
18114
|
+
measurements: measurements5
|
|
18115
|
+
} = jscad12;
|
|
18116
|
+
var generalize4 = modifiers4.generalize;
|
|
18117
|
+
var { subtract } = booleans3;
|
|
18118
|
+
var { rectangle: rectangle3, roundedRectangle: roundedRectangle3, circle: circle2 } = primitives5;
|
|
18119
|
+
var profile3 = (shape49, height10) => extrusions5.extrudeLinear({ height: height10 }, shape49);
|
|
17380
18120
|
function perforated(p) {
|
|
17381
18121
|
const holes = [];
|
|
17382
18122
|
const rows = Math.floor((p.width - 2 * p.edgeY) / p.pitchY + 1 + 1e-10);
|
|
@@ -17407,7 +18147,7 @@ function createPerforatedSheetMesh(input) {
|
|
|
17407
18147
|
{ snap: true, triangulate: true },
|
|
17408
18148
|
createPerforatedSheetGeom(input)
|
|
17409
18149
|
);
|
|
17410
|
-
const epsilon = Math.max(...
|
|
18150
|
+
const epsilon = Math.max(...measurements5.measureDimensions(geom)) * 1e-10;
|
|
17411
18151
|
const positions = [];
|
|
17412
18152
|
const indices = [];
|
|
17413
18153
|
const lookup = /* @__PURE__ */ new Map();
|
|
@@ -17421,7 +18161,7 @@ function createPerforatedSheetMesh(input) {
|
|
|
17421
18161
|
}
|
|
17422
18162
|
return index;
|
|
17423
18163
|
};
|
|
17424
|
-
for (const poly of
|
|
18164
|
+
for (const poly of geometries5.geom3.toPolygons(geom)) {
|
|
17425
18165
|
for (let i = 1; i < poly.vertices.length - 1; i++) {
|
|
17426
18166
|
const a = poly.vertices[0], b = poly.vertices[i], c = poly.vertices[i + 1];
|
|
17427
18167
|
const u = b.map((x, j) => x - a[j]), v = c.map((x, j) => x - a[j]);
|
|
@@ -17463,7 +18203,7 @@ function createPlainBushingMesh(input) {
|
|
|
17463
18203
|
const ri = d.innerDiameter / 2;
|
|
17464
18204
|
const ro = d.outerDiameter / 2;
|
|
17465
18205
|
const c = props.edgeChamfer;
|
|
17466
|
-
const
|
|
18206
|
+
const profile5 = c > 0 ? [
|
|
17467
18207
|
[d.endOuterDiameter / 2, 0],
|
|
17468
18208
|
[ro, c],
|
|
17469
18209
|
[ro, d.length - c],
|
|
@@ -17481,14 +18221,14 @@ function createPlainBushingMesh(input) {
|
|
|
17481
18221
|
const segments = 96;
|
|
17482
18222
|
const positions = [];
|
|
17483
18223
|
const indices = [];
|
|
17484
|
-
for (const [radius, z] of
|
|
18224
|
+
for (const [radius, z] of profile5)
|
|
17485
18225
|
for (let i = 0; i < segments; i++) {
|
|
17486
18226
|
const angle = i * Math.PI * 2 / segments;
|
|
17487
18227
|
positions.push(radius * Math.cos(angle), radius * Math.sin(angle), z);
|
|
17488
18228
|
}
|
|
17489
|
-
for (let ring = 0; ring <
|
|
18229
|
+
for (let ring = 0; ring < profile5.length; ring++) {
|
|
17490
18230
|
const a = ring * segments;
|
|
17491
|
-
const b = (ring + 1) %
|
|
18231
|
+
const b = (ring + 1) % profile5.length * segments;
|
|
17492
18232
|
for (let i = 0; i < segments; i++) {
|
|
17493
18233
|
const next = (i + 1) % segments;
|
|
17494
18234
|
indices.push(a + i, a + next, b + next, a + i, b + next, b + i);
|
|
@@ -17520,13 +18260,13 @@ function register85(registry2) {
|
|
|
17520
18260
|
}
|
|
17521
18261
|
|
|
17522
18262
|
// lib/models/pushfitplug/geometry.ts
|
|
17523
|
-
import
|
|
17524
|
-
var { primitives:
|
|
17525
|
-
var generalize5 =
|
|
17526
|
-
var { rectangle: rectangle4, roundedRectangle: roundedRectangle4, polygon: polygon3 } =
|
|
18263
|
+
import jscad13 from "@jscad/modeling";
|
|
18264
|
+
var { primitives: primitives6, extrusions: extrusions6, geometries: geometries6, modifiers: modifiers5, measurements: measurements6 } = jscad13;
|
|
18265
|
+
var generalize5 = modifiers5.generalize;
|
|
18266
|
+
var { rectangle: rectangle4, roundedRectangle: roundedRectangle4, polygon: polygon3 } = primitives6;
|
|
17527
18267
|
function createPushFitPlugGeom(input) {
|
|
17528
18268
|
const p = pushFitPlugModelPropsSchema.parse(input);
|
|
17529
|
-
return
|
|
18269
|
+
return extrusions6.extrudeRotate(
|
|
17530
18270
|
{ segments: 64 },
|
|
17531
18271
|
polygon3({
|
|
17532
18272
|
points: [
|
|
@@ -17545,7 +18285,7 @@ function createPushFitPlugMesh(input) {
|
|
|
17545
18285
|
{ snap: true, triangulate: true },
|
|
17546
18286
|
createPushFitPlugGeom(input)
|
|
17547
18287
|
);
|
|
17548
|
-
const epsilon = Math.max(...
|
|
18288
|
+
const epsilon = Math.max(...measurements6.measureDimensions(geom)) * 1e-10;
|
|
17549
18289
|
const positions = [];
|
|
17550
18290
|
const indices = [];
|
|
17551
18291
|
const lookup = /* @__PURE__ */ new Map();
|
|
@@ -17559,7 +18299,7 @@ function createPushFitPlugMesh(input) {
|
|
|
17559
18299
|
}
|
|
17560
18300
|
return index;
|
|
17561
18301
|
};
|
|
17562
|
-
for (const poly of
|
|
18302
|
+
for (const poly of geometries6.geom3.toPolygons(geom)) {
|
|
17563
18303
|
for (let i = 1; i < poly.vertices.length - 1; i++) {
|
|
17564
18304
|
const a = poly.vertices[0], b = poly.vertices[i], c = poly.vertices[i + 1];
|
|
17565
18305
|
const u = b.map((x, j) => x - a[j]), v = c.map((x, j) => x - a[j]);
|
|
@@ -17592,11 +18332,11 @@ function register86(registry2) {
|
|
|
17592
18332
|
}
|
|
17593
18333
|
|
|
17594
18334
|
// lib/models/rectangularbar/geometry.ts
|
|
17595
|
-
import
|
|
17596
|
-
var { primitives:
|
|
17597
|
-
var generalize6 =
|
|
17598
|
-
var { rectangle: rectangle5, roundedRectangle: roundedRectangle5 } =
|
|
17599
|
-
var profile4 = (shape49, height10) =>
|
|
18335
|
+
import jscad14 from "@jscad/modeling";
|
|
18336
|
+
var { primitives: primitives7, extrusions: extrusions7, geometries: geometries7, modifiers: modifiers6, measurements: measurements7 } = jscad14;
|
|
18337
|
+
var generalize6 = modifiers6.generalize;
|
|
18338
|
+
var { rectangle: rectangle5, roundedRectangle: roundedRectangle5 } = primitives7;
|
|
18339
|
+
var profile4 = (shape49, height10) => extrusions7.extrudeLinear({ height: height10 }, shape49);
|
|
17600
18340
|
var roundedRect = (width10, height10, radius) => radius ? roundedRectangle5({
|
|
17601
18341
|
size: [width10, height10],
|
|
17602
18342
|
roundRadius: radius,
|
|
@@ -17611,7 +18351,7 @@ function createRectangularBarMesh(input) {
|
|
|
17611
18351
|
{ snap: true, triangulate: true },
|
|
17612
18352
|
createRectangularBarGeom(input)
|
|
17613
18353
|
);
|
|
17614
|
-
const epsilon = Math.max(...
|
|
18354
|
+
const epsilon = Math.max(...measurements7.measureDimensions(geom)) * 1e-10;
|
|
17615
18355
|
const positions = [];
|
|
17616
18356
|
const indices = [];
|
|
17617
18357
|
const lookup = /* @__PURE__ */ new Map();
|
|
@@ -17625,7 +18365,7 @@ function createRectangularBarMesh(input) {
|
|
|
17625
18365
|
}
|
|
17626
18366
|
return index;
|
|
17627
18367
|
};
|
|
17628
|
-
for (const poly of
|
|
18368
|
+
for (const poly of geometries7.geom3.toPolygons(geom)) {
|
|
17629
18369
|
for (let i = 1; i < poly.vertices.length - 1; i++) {
|
|
17630
18370
|
const a = poly.vertices[0], b = poly.vertices[i], c = poly.vertices[i + 1];
|
|
17631
18371
|
const u = b.map((x, j) => x - a[j]), v = c.map((x, j) => x - a[j]);
|
|
@@ -17769,72 +18509,27 @@ function register88(registry2) {
|
|
|
17769
18509
|
registry2.register(model88);
|
|
17770
18510
|
}
|
|
17771
18511
|
|
|
17772
|
-
// lib/models/rectangulartube/
|
|
17773
|
-
import
|
|
17774
|
-
var {
|
|
17775
|
-
booleans: booleans3,
|
|
17776
|
-
primitives: primitives7,
|
|
17777
|
-
extrusions: extrusions7,
|
|
17778
|
-
geometries: geometries7,
|
|
17779
|
-
modifiers: modifiers6,
|
|
17780
|
-
measurements: measurements7
|
|
17781
|
-
} = jscad13;
|
|
17782
|
-
var generalize7 = modifiers6.generalize;
|
|
17783
|
-
var { subtract: subtract2 } = booleans3;
|
|
17784
|
-
var { rectangle: rectangle6, roundedRectangle: roundedRectangle6 } = primitives7;
|
|
17785
|
-
var profile5 = (shape49, height10) => extrusions7.extrudeLinear({ height: height10 }, shape49);
|
|
17786
|
-
var roundedRect2 = (width10, height10, radius) => radius ? roundedRectangle6({
|
|
18512
|
+
// lib/models/rectangulartube/profiles.ts
|
|
18513
|
+
import jscad15 from "@jscad/modeling";
|
|
18514
|
+
var roundedRectangle6 = (width10, height10, radius) => radius ? jscad15.primitives.roundedRectangle({
|
|
17787
18515
|
size: [width10, height10],
|
|
17788
18516
|
roundRadius: radius,
|
|
17789
18517
|
segments: 64
|
|
17790
|
-
}) :
|
|
17791
|
-
function
|
|
18518
|
+
}) : jscad15.primitives.rectangle({ size: [width10, height10] });
|
|
18519
|
+
function getRectangularTubeProfiles(input) {
|
|
17792
18520
|
const p = rectangularTubeModelPropsSchema.parse(input);
|
|
17793
|
-
|
|
17794
|
-
|
|
17795
|
-
|
|
17796
|
-
|
|
18521
|
+
const points = (geometry) => jscad15.geometries.geom2.toPoints(geometry);
|
|
18522
|
+
return {
|
|
18523
|
+
length: p.length,
|
|
18524
|
+
outerPoints: points(roundedRectangle6(p.width, p.height, p.outerRadius)),
|
|
18525
|
+
innerPoints: points(
|
|
18526
|
+
roundedRectangle6(
|
|
17797
18527
|
p.width - 2 * p.wallThickness,
|
|
17798
18528
|
p.height - 2 * p.wallThickness,
|
|
17799
18529
|
p.innerRadius
|
|
17800
18530
|
)
|
|
17801
|
-
)
|
|
17802
|
-
p.length
|
|
17803
|
-
);
|
|
17804
|
-
}
|
|
17805
|
-
function createRectangularTubeMesh(input) {
|
|
17806
|
-
const geom = generalize7(
|
|
17807
|
-
{ snap: true, triangulate: true },
|
|
17808
|
-
createRectangularTubeGeom(input)
|
|
17809
|
-
);
|
|
17810
|
-
const epsilon = Math.max(...measurements7.measureDimensions(geom)) * 1e-10;
|
|
17811
|
-
const positions = [];
|
|
17812
|
-
const indices = [];
|
|
17813
|
-
const lookup = /* @__PURE__ */ new Map();
|
|
17814
|
-
const vertex = (v) => {
|
|
17815
|
-
const key = v.map((x) => Math.round(x / epsilon)).join(",");
|
|
17816
|
-
let index = lookup.get(key);
|
|
17817
|
-
if (index === void 0) {
|
|
17818
|
-
index = positions.length / 3;
|
|
17819
|
-
positions.push(...v);
|
|
17820
|
-
lookup.set(key, index);
|
|
17821
|
-
}
|
|
17822
|
-
return index;
|
|
18531
|
+
)
|
|
17823
18532
|
};
|
|
17824
|
-
for (const poly of geometries7.geom3.toPolygons(geom)) {
|
|
17825
|
-
for (let i = 1; i < poly.vertices.length - 1; i++) {
|
|
17826
|
-
const a = poly.vertices[0], b = poly.vertices[i], c = poly.vertices[i + 1];
|
|
17827
|
-
const u = b.map((x, j) => x - a[j]), v = c.map((x, j) => x - a[j]);
|
|
17828
|
-
const area = Math.hypot(
|
|
17829
|
-
u[1] * v[2] - u[2] * v[1],
|
|
17830
|
-
u[2] * v[0] - u[0] * v[2],
|
|
17831
|
-
u[0] * v[1] - u[1] * v[0]
|
|
17832
|
-
);
|
|
17833
|
-
if (area > epsilon * epsilon)
|
|
17834
|
-
indices.push(vertex(a), vertex(b), vertex(c));
|
|
17835
|
-
}
|
|
17836
|
-
}
|
|
17837
|
-
return { positions, indices };
|
|
17838
18533
|
}
|
|
17839
18534
|
|
|
17840
18535
|
// lib/models/rectangulartube/RectangularTube.tsx
|
|
@@ -17842,7 +18537,27 @@ function RectangularTube({
|
|
|
17842
18537
|
color = "#929da9",
|
|
17843
18538
|
...props
|
|
17844
18539
|
}) {
|
|
17845
|
-
|
|
18540
|
+
const { length: length32, outerPoints, innerPoints } = getRectangularTubeProfiles(props);
|
|
18541
|
+
return /* @__PURE__ */ jsx(Colorize, { color, children: /* @__PURE__ */ jsxs(Subtract, { children: [
|
|
18542
|
+
/* @__PURE__ */ jsx(
|
|
18543
|
+
ExtrudeLinear,
|
|
18544
|
+
{
|
|
18545
|
+
height: length32,
|
|
18546
|
+
topOutlineName: "outer_top",
|
|
18547
|
+
bottomOutlineName: "outer_bottom",
|
|
18548
|
+
children: /* @__PURE__ */ jsx(Polygon, { points: outerPoints })
|
|
18549
|
+
}
|
|
18550
|
+
),
|
|
18551
|
+
/* @__PURE__ */ jsx(
|
|
18552
|
+
ExtrudeLinear,
|
|
18553
|
+
{
|
|
18554
|
+
height: length32,
|
|
18555
|
+
topOutlineName: "inner_top",
|
|
18556
|
+
bottomOutlineName: "inner_bottom",
|
|
18557
|
+
children: /* @__PURE__ */ jsx(Polygon, { points: innerPoints })
|
|
18558
|
+
}
|
|
18559
|
+
)
|
|
18560
|
+
] }) });
|
|
17846
18561
|
}
|
|
17847
18562
|
|
|
17848
18563
|
// lib/models/rectangulartube/register.tsx
|
|
@@ -18087,7 +18802,7 @@ function holeOutline(hole) {
|
|
|
18087
18802
|
function createSheetMetalMesh(input) {
|
|
18088
18803
|
const props = sheetMetalModelPropsSchema.parse(input);
|
|
18089
18804
|
const { width: width10, baseLength, flangeHeight, thickness } = props;
|
|
18090
|
-
const
|
|
18805
|
+
const profile5 = props.channel ? "channel" : props.angle ? "angle" : "plate";
|
|
18091
18806
|
const radius = props.insideBendRadius + thickness / 2;
|
|
18092
18807
|
const positions = [];
|
|
18093
18808
|
const indices = [];
|
|
@@ -18100,10 +18815,10 @@ function createSheetMetalMesh(input) {
|
|
|
18100
18815
|
addTriangle([vertices[0], vertices[1], vertices[2]], reverse);
|
|
18101
18816
|
addTriangle([vertices[0], vertices[2], vertices[3]], reverse);
|
|
18102
18817
|
};
|
|
18103
|
-
const panels =
|
|
18818
|
+
const panels = profile5 === "plate" ? ["base"] : profile5 === "angle" ? ["base", "right"] : ["base", "left", "right"];
|
|
18104
18819
|
for (const hole of props.holes) {
|
|
18105
18820
|
if (!panels.includes(hole.panel))
|
|
18106
|
-
throw new Error(`No ${hole.panel} panel on ${
|
|
18821
|
+
throw new Error(`No ${hole.panel} panel on ${profile5}`);
|
|
18107
18822
|
}
|
|
18108
18823
|
for (const panel of panels) {
|
|
18109
18824
|
const length32 = panel === "base" ? baseLength : flangeHeight;
|
|
@@ -18154,7 +18869,7 @@ function createSheetMetalMesh(input) {
|
|
|
18154
18869
|
for (const [loopIndex, loop] of loops.entries())
|
|
18155
18870
|
for (let i = 0; i < loop.length; i++) {
|
|
18156
18871
|
const a = loop[i], b = loop[(i + 1) % loop.length];
|
|
18157
|
-
if (loopIndex === 0 && a.u === b.u && (panel === "base" && (a.u > 0 &&
|
|
18872
|
+
if (loopIndex === 0 && a.u === b.u && (panel === "base" && (a.u > 0 && profile5 !== "plate" || a.u < 0 && profile5 === "channel") || panel !== "base" && a.u < 0))
|
|
18158
18873
|
continue;
|
|
18159
18874
|
addQuad(
|
|
18160
18875
|
[
|
|
@@ -18167,7 +18882,7 @@ function createSheetMetalMesh(input) {
|
|
|
18167
18882
|
);
|
|
18168
18883
|
}
|
|
18169
18884
|
}
|
|
18170
|
-
const sides =
|
|
18885
|
+
const sides = profile5 === "plate" ? [] : profile5 === "angle" ? [1] : [-1, 1];
|
|
18171
18886
|
for (const side of sides) {
|
|
18172
18887
|
const project = (angle, crossSection) => {
|
|
18173
18888
|
const r = radius - crossSection.offset;
|
|
@@ -18766,7 +19481,7 @@ function register100(registry2) {
|
|
|
18766
19481
|
}
|
|
18767
19482
|
|
|
18768
19483
|
// lib/models/tslotcoverstrip/geometry.ts
|
|
18769
|
-
import
|
|
19484
|
+
import jscad18 from "@jscad/modeling";
|
|
18770
19485
|
var {
|
|
18771
19486
|
primitives: primitives8,
|
|
18772
19487
|
extrusions: extrusions8,
|
|
@@ -18774,8 +19489,8 @@ var {
|
|
|
18774
19489
|
geometries: geometries8,
|
|
18775
19490
|
modifiers: modifiers7,
|
|
18776
19491
|
measurements: measurements8
|
|
18777
|
-
} =
|
|
18778
|
-
var
|
|
19492
|
+
} = jscad18;
|
|
19493
|
+
var generalize7 = modifiers7.generalize;
|
|
18779
19494
|
function createTSlotCoverStripGeom(input) {
|
|
18780
19495
|
const p = tSlotCoverStripModelPropsSchema.parse(input);
|
|
18781
19496
|
const w = p.width / 2;
|
|
@@ -18802,7 +19517,7 @@ function createTSlotCoverStripGeom(input) {
|
|
|
18802
19517
|
return extrusions8.extrudeLinear({ height: p.length }, outline);
|
|
18803
19518
|
}
|
|
18804
19519
|
function createTSlotCoverStripMesh(input) {
|
|
18805
|
-
const geom =
|
|
19520
|
+
const geom = generalize7(
|
|
18806
19521
|
{ snap: false, triangulate: true },
|
|
18807
19522
|
createTSlotCoverStripGeom(input)
|
|
18808
19523
|
);
|
|
@@ -19056,10 +19771,10 @@ function register104(registry2) {
|
|
|
19056
19771
|
}
|
|
19057
19772
|
|
|
19058
19773
|
// lib/models/ufl/geometry.ts
|
|
19059
|
-
import
|
|
19774
|
+
import jscad19 from "@jscad/modeling";
|
|
19060
19775
|
function createUflGeometries(input = {}) {
|
|
19061
19776
|
const d = getUflDimensions(input);
|
|
19062
|
-
const { booleans: booleans5, primitives: primitives9 } =
|
|
19777
|
+
const { booleans: booleans5, primitives: primitives9 } = jscad19;
|
|
19063
19778
|
const silver = "#bcbfc3";
|
|
19064
19779
|
const dielectric = "#eee9d5";
|
|
19065
19780
|
const gold = "#d9b45b";
|
|
@@ -19216,17 +19931,17 @@ var createWormGearMesh = (input) => {
|
|
|
19216
19931
|
fractions.push(fraction);
|
|
19217
19932
|
}
|
|
19218
19933
|
}
|
|
19219
|
-
const
|
|
19934
|
+
const profile5 = [];
|
|
19220
19935
|
for (let start = 0; start < props.starts; start++) {
|
|
19221
19936
|
for (const fraction of fractions) {
|
|
19222
19937
|
const distance2 = Math.min(fraction, 1 - fraction) * axialPitch;
|
|
19223
|
-
|
|
19938
|
+
profile5.push({
|
|
19224
19939
|
angle: (start + fraction) * Math.PI * 2 / props.starts,
|
|
19225
19940
|
radius: distance2 <= tipHalfWidth ? outsideRadius : distance2 >= rootHalfWidth ? rootRadius : pitchRadius + (toothThickness / 2 - distance2) / pressureTangent
|
|
19226
19941
|
});
|
|
19227
19942
|
}
|
|
19228
19943
|
}
|
|
19229
|
-
const count =
|
|
19944
|
+
const count = profile5.length;
|
|
19230
19945
|
const positions = [];
|
|
19231
19946
|
const indices = [];
|
|
19232
19947
|
const phase = props.phase % 360 * Math.PI / 180;
|
|
@@ -19234,7 +19949,7 @@ var createWormGearMesh = (input) => {
|
|
|
19234
19949
|
const ring = (z) => {
|
|
19235
19950
|
const first = positions.length / 3;
|
|
19236
19951
|
const rotation = phase + direction * (z / lead) * Math.PI * 2;
|
|
19237
|
-
for (const sample of
|
|
19952
|
+
for (const sample of profile5) {
|
|
19238
19953
|
const angle = sample.angle + rotation;
|
|
19239
19954
|
positions.push(
|
|
19240
19955
|
sample.radius * Math.cos(angle),
|
|
@@ -27737,185 +28452,6 @@ var Footprinter3d = ({ footprint }) => {
|
|
|
27737
28452
|
return null;
|
|
27738
28453
|
};
|
|
27739
28454
|
|
|
27740
|
-
// lib/vanilla/render.ts
|
|
27741
|
-
var isVNode = (n) => n && typeof n === "object" && "type" in n;
|
|
27742
|
-
var degToRad = (v) => {
|
|
27743
|
-
if (typeof v === "number") return v;
|
|
27744
|
-
if (typeof v === "string") {
|
|
27745
|
-
const m = /^(-?\d+(?:\.\d+)?)\s*deg$/i.exec(v);
|
|
27746
|
-
if (m) return parseFloat(m[1]) * Math.PI / 180;
|
|
27747
|
-
const n = Number(v);
|
|
27748
|
-
if (!Number.isNaN(n)) return n;
|
|
27749
|
-
}
|
|
27750
|
-
return 0;
|
|
27751
|
-
};
|
|
27752
|
-
var toVec3 = (v) => {
|
|
27753
|
-
if (Array.isArray(v))
|
|
27754
|
-
return [Number(v[0]) || 0, Number(v[1]) || 0, Number(v[2]) || 0];
|
|
27755
|
-
if (typeof v === "object" && v)
|
|
27756
|
-
return [Number(v.x) || 0, Number(v.y) || 0, Number(v.z) || 0];
|
|
27757
|
-
return [0, 0, 0];
|
|
27758
|
-
};
|
|
27759
|
-
function renderNode(node, colorCtx, renderCtx) {
|
|
27760
|
-
const {
|
|
27761
|
-
jscad: { primitives: primitives9, booleans: booleans5, hulls, geometries: geometries9, extrusions: extrusions9, transforms: transforms2 }
|
|
27762
|
-
} = renderCtx;
|
|
27763
|
-
if (node == null || node === false) return [];
|
|
27764
|
-
if (Array.isArray(node))
|
|
27765
|
-
return node.flatMap((n) => renderNode(n, colorCtx, renderCtx));
|
|
27766
|
-
if (!isVNode(node)) return [];
|
|
27767
|
-
const { type, props, children } = node;
|
|
27768
|
-
if (props?.material) {
|
|
27769
|
-
const { material, ...rest } = props;
|
|
27770
|
-
return renderNode({ ...node, props: rest }, colorCtx, renderCtx).map(
|
|
27771
|
-
(entry) => ({
|
|
27772
|
-
...entry,
|
|
27773
|
-
material: { ...material },
|
|
27774
|
-
geom: { ...entry.geom, material: { ...material } }
|
|
27775
|
-
})
|
|
27776
|
-
);
|
|
27777
|
-
}
|
|
27778
|
-
if (type === Fragment) {
|
|
27779
|
-
return (children ?? []).flatMap((c) => renderNode(c, colorCtx, renderCtx));
|
|
27780
|
-
}
|
|
27781
|
-
if (type === Colorize) {
|
|
27782
|
-
const newColor = props?.color;
|
|
27783
|
-
return (children ?? []).flatMap(
|
|
27784
|
-
(c) => renderNode(c, newColor ?? colorCtx, renderCtx)
|
|
27785
|
-
);
|
|
27786
|
-
}
|
|
27787
|
-
if (type === Translate) {
|
|
27788
|
-
const off = toVec3(
|
|
27789
|
-
props?.offset ?? props?.center ?? { x: props?.x, y: props?.y, z: props?.z }
|
|
27790
|
-
);
|
|
27791
|
-
const geoms = (children ?? []).flatMap(
|
|
27792
|
-
(c) => renderNode(c, colorCtx, renderCtx)
|
|
27793
|
-
);
|
|
27794
|
-
return geoms.map(({ geom, color, material }) => ({
|
|
27795
|
-
material,
|
|
27796
|
-
geom: transforms2.translate(off, geom),
|
|
27797
|
-
color: color ?? colorCtx
|
|
27798
|
-
}));
|
|
27799
|
-
}
|
|
27800
|
-
if (type === Rotate) {
|
|
27801
|
-
const angles = props?.angles ?? props?.rotation;
|
|
27802
|
-
const rot = Array.isArray(angles) ? [degToRad(angles[0]), degToRad(angles[1]), degToRad(angles[2])] : [
|
|
27803
|
-
degToRad(props?.x ?? 0),
|
|
27804
|
-
degToRad(props?.y ?? 0),
|
|
27805
|
-
degToRad(props?.z ?? 0)
|
|
27806
|
-
];
|
|
27807
|
-
const geoms = (children ?? []).flatMap(
|
|
27808
|
-
(c) => renderNode(c, colorCtx, renderCtx)
|
|
27809
|
-
);
|
|
27810
|
-
return geoms.map(({ geom, color, material }) => ({
|
|
27811
|
-
material,
|
|
27812
|
-
geom: transforms2.rotateZ(
|
|
27813
|
-
rot[2],
|
|
27814
|
-
transforms2.rotateY(rot[1], transforms2.rotateX(rot[0], geom))
|
|
27815
|
-
),
|
|
27816
|
-
color
|
|
27817
|
-
}));
|
|
27818
|
-
}
|
|
27819
|
-
if (type === Union || type === Subtract || type === Hull) {
|
|
27820
|
-
const entries = (children ?? []).flatMap(
|
|
27821
|
-
(c) => renderNode(c, colorCtx, renderCtx)
|
|
27822
|
-
);
|
|
27823
|
-
const geoms = entries.map((g) => g.geom);
|
|
27824
|
-
if (geoms.length === 0) return [];
|
|
27825
|
-
let geom;
|
|
27826
|
-
if (type === Union) geom = booleans5.union(geoms);
|
|
27827
|
-
else if (type === Subtract)
|
|
27828
|
-
geom = booleans5.subtract(geoms[0], geoms.slice(1));
|
|
27829
|
-
else geom = hulls.hull(geoms);
|
|
27830
|
-
return [
|
|
27831
|
-
{
|
|
27832
|
-
geom,
|
|
27833
|
-
color: colorCtx,
|
|
27834
|
-
material: type === Subtract ? entries[0]?.material : void 0
|
|
27835
|
-
}
|
|
27836
|
-
];
|
|
27837
|
-
}
|
|
27838
|
-
if (type === Custom) {
|
|
27839
|
-
return [{ geom: props.geometry, color: colorCtx }];
|
|
27840
|
-
}
|
|
27841
|
-
if (type === Polygon) {
|
|
27842
|
-
const points = props?.points ?? [];
|
|
27843
|
-
const g2 = geometries9.geom2.fromPoints(points);
|
|
27844
|
-
return [{ geom: g2, color: colorCtx ?? props?.color }];
|
|
27845
|
-
}
|
|
27846
|
-
if (type === ExtrudeLinear) {
|
|
27847
|
-
const entries = (children ?? []).flatMap(
|
|
27848
|
-
(c) => renderNode(c, colorCtx, renderCtx)
|
|
27849
|
-
);
|
|
27850
|
-
const geoms2 = entries.map((g) => g.geom);
|
|
27851
|
-
if (geoms2.length === 0) return [];
|
|
27852
|
-
const base2 = geoms2.length > 1 ? booleans5.union(geoms2) : geoms2[0];
|
|
27853
|
-
const height10 = props?.height ?? props?.h ?? 1;
|
|
27854
|
-
let g3 = extrusions9.extrudeLinear({ height: height10 }, base2);
|
|
27855
|
-
if (g3.polygons) {
|
|
27856
|
-
for (const poly of g3.polygons) {
|
|
27857
|
-
if (!poly.plane || !poly.vertices || poly.vertices.length < 3) continue;
|
|
27858
|
-
poly.vertices.reverse();
|
|
27859
|
-
}
|
|
27860
|
-
}
|
|
27861
|
-
return [
|
|
27862
|
-
{
|
|
27863
|
-
geom: g3,
|
|
27864
|
-
color: colorCtx ?? props?.color,
|
|
27865
|
-
material: entries.length === 1 ? entries[0]?.material : void 0
|
|
27866
|
-
}
|
|
27867
|
-
];
|
|
27868
|
-
}
|
|
27869
|
-
if (type === Cuboid || type === Cube || type === Cylinder || type === Sphere || type === RoundedCuboid || type === RoundedCylinder) {
|
|
27870
|
-
let g;
|
|
27871
|
-
if (type === Cuboid) {
|
|
27872
|
-
const size = props?.size ?? [1, 1, 1];
|
|
27873
|
-
const offset = props?.offset;
|
|
27874
|
-
const center = props?.center ?? (offset ? [offset[0], offset[1], offset[2]] : [0, 0, 0]);
|
|
27875
|
-
g = primitives9.cuboid({ size, center });
|
|
27876
|
-
} else if (type === Cube) {
|
|
27877
|
-
const size = props?.size ?? 1;
|
|
27878
|
-
const offset = props?.offset;
|
|
27879
|
-
const center = props?.center ?? (offset ? [offset[0], offset[1], offset[2]] : [0, 0, 0]);
|
|
27880
|
-
g = primitives9.cube({ size, center });
|
|
27881
|
-
} else if (type === Cylinder) {
|
|
27882
|
-
const height10 = props?.height ?? 1;
|
|
27883
|
-
const radius = props?.radius ?? 1;
|
|
27884
|
-
const center = props?.center ?? [0, 0, 0];
|
|
27885
|
-
g = primitives9.cylinder({ height: height10, radius, center });
|
|
27886
|
-
} else if (type === Sphere) {
|
|
27887
|
-
const radius = props?.radius ?? 1;
|
|
27888
|
-
const center = props?.center ?? [0, 0, 0];
|
|
27889
|
-
g = primitives9.sphere({ radius, center });
|
|
27890
|
-
} else if (type === RoundedCylinder) {
|
|
27891
|
-
const height10 = props?.height ?? 1;
|
|
27892
|
-
const radius = props?.radius ?? 1;
|
|
27893
|
-
const roundRadius = props?.roundRadius ?? 0.1;
|
|
27894
|
-
const center = props?.center ?? [0, 0, 0];
|
|
27895
|
-
g = primitives9.roundedCylinder({ height: height10, radius, roundRadius, center });
|
|
27896
|
-
} else {
|
|
27897
|
-
const size = props?.size ?? [1, 1, 1];
|
|
27898
|
-
const roundRadius = props?.roundRadius ?? 0.1;
|
|
27899
|
-
const center = props?.center ?? [0, 0, 0];
|
|
27900
|
-
g = primitives9.roundedCuboid({ size, roundRadius, center });
|
|
27901
|
-
}
|
|
27902
|
-
return [{ geom: g, color: colorCtx ?? props?.color }];
|
|
27903
|
-
}
|
|
27904
|
-
if (typeof type === "function") {
|
|
27905
|
-
const out = type(props ?? {});
|
|
27906
|
-
return renderNode(out, colorCtx, renderCtx);
|
|
27907
|
-
}
|
|
27908
|
-
return (children ?? []).flatMap((c) => renderNode(c, colorCtx, renderCtx));
|
|
27909
|
-
}
|
|
27910
|
-
function render(root, jscad18) {
|
|
27911
|
-
const geometries9 = renderNode(root, void 0, { jscad: jscad18 });
|
|
27912
|
-
return {
|
|
27913
|
-
geometries: geometries9.map(
|
|
27914
|
-
(entry) => entry.material ? { ...entry, geom: { ...entry.geom, material: entry.material } } : entry
|
|
27915
|
-
)
|
|
27916
|
-
};
|
|
27917
|
-
}
|
|
27918
|
-
|
|
27919
28455
|
// lib/vanilla/convertCSGToThreeGeom.ts
|
|
27920
28456
|
import {
|
|
27921
28457
|
BufferAttribute,
|
|
@@ -27926,16 +28462,16 @@ function convertCSGToThreeGeom(csg) {
|
|
|
27926
28462
|
if (csg.polygons) {
|
|
27927
28463
|
const vertices = [];
|
|
27928
28464
|
const indices = [];
|
|
27929
|
-
const
|
|
28465
|
+
const colors2 = [];
|
|
27930
28466
|
let idx = 0;
|
|
27931
28467
|
for (const polygon4 of csg.polygons) {
|
|
27932
28468
|
for (const vertex of polygon4.vertices) {
|
|
27933
28469
|
vertex.index = idx;
|
|
27934
28470
|
vertices.push(vertex[0], vertex[1], vertex[2]);
|
|
27935
28471
|
if (csg.color && csg.color.length >= 3) {
|
|
27936
|
-
|
|
28472
|
+
colors2.push(csg.color[0], csg.color[1], csg.color[2]);
|
|
27937
28473
|
} else {
|
|
27938
|
-
|
|
28474
|
+
colors2.push(1, 1, 1);
|
|
27939
28475
|
}
|
|
27940
28476
|
idx++;
|
|
27941
28477
|
}
|
|
@@ -27952,29 +28488,29 @@ function convertCSGToThreeGeom(csg) {
|
|
|
27952
28488
|
new BufferAttribute(new Float32Array(vertices), 3)
|
|
27953
28489
|
);
|
|
27954
28490
|
geo.setIndex(indices);
|
|
27955
|
-
if (
|
|
28491
|
+
if (colors2.length > 0) {
|
|
27956
28492
|
geo.setAttribute(
|
|
27957
28493
|
"color",
|
|
27958
|
-
new BufferAttribute(new Float32Array(
|
|
28494
|
+
new BufferAttribute(new Float32Array(colors2), 3)
|
|
27959
28495
|
);
|
|
27960
28496
|
}
|
|
27961
28497
|
if (csg.transforms) {
|
|
27962
|
-
const
|
|
27963
|
-
|
|
27964
|
-
geo.applyMatrix4(
|
|
28498
|
+
const transforms3 = new Matrix4();
|
|
28499
|
+
transforms3.fromArray(csg.transforms);
|
|
28500
|
+
geo.applyMatrix4(transforms3);
|
|
27965
28501
|
}
|
|
27966
28502
|
geo.computeVertexNormals();
|
|
27967
28503
|
return geo;
|
|
27968
28504
|
}
|
|
27969
28505
|
if (csg.sides) {
|
|
27970
28506
|
const vertices = [];
|
|
27971
|
-
const
|
|
28507
|
+
const colors2 = [];
|
|
27972
28508
|
for (const side of csg.sides) {
|
|
27973
28509
|
vertices.push(side[0][0], side[0][1], 0);
|
|
27974
28510
|
if (csg.color && csg.color.length >= 3) {
|
|
27975
|
-
|
|
28511
|
+
colors2.push(csg.color[0], csg.color[1], csg.color[2]);
|
|
27976
28512
|
} else {
|
|
27977
|
-
|
|
28513
|
+
colors2.push(1, 1, 1);
|
|
27978
28514
|
}
|
|
27979
28515
|
}
|
|
27980
28516
|
const geo = new BufferGeometry();
|
|
@@ -27982,16 +28518,16 @@ function convertCSGToThreeGeom(csg) {
|
|
|
27982
28518
|
"position",
|
|
27983
28519
|
new BufferAttribute(new Float32Array(vertices), 3)
|
|
27984
28520
|
);
|
|
27985
|
-
if (
|
|
28521
|
+
if (colors2.length > 0) {
|
|
27986
28522
|
geo.setAttribute(
|
|
27987
28523
|
"color",
|
|
27988
|
-
new BufferAttribute(new Float32Array(
|
|
28524
|
+
new BufferAttribute(new Float32Array(colors2), 3)
|
|
27989
28525
|
);
|
|
27990
28526
|
}
|
|
27991
28527
|
if (csg.transforms) {
|
|
27992
|
-
const
|
|
27993
|
-
|
|
27994
|
-
geo.applyMatrix4(
|
|
28528
|
+
const transforms3 = new Matrix4();
|
|
28529
|
+
transforms3.fromArray(csg.transforms);
|
|
28530
|
+
geo.applyMatrix4(transforms3);
|
|
27995
28531
|
}
|
|
27996
28532
|
return geo;
|
|
27997
28533
|
}
|
|
@@ -27999,25 +28535,104 @@ function convertCSGToThreeGeom(csg) {
|
|
|
27999
28535
|
return new BufferGeometry();
|
|
28000
28536
|
}
|
|
28001
28537
|
|
|
28538
|
+
// lib/named-edges.ts
|
|
28539
|
+
import jscad20 from "@jscad/modeling";
|
|
28540
|
+
function listJscadNamedEdges(model108) {
|
|
28541
|
+
return listJscadReferenceFeatures(model108).filter((name) => {
|
|
28542
|
+
const { geometry } = model108.referenceFeatures[name];
|
|
28543
|
+
return jscad20.geometries.geom2.isA(geometry) || jscad20.geometries.path2.isA(geometry);
|
|
28544
|
+
});
|
|
28545
|
+
}
|
|
28546
|
+
function listJscadReferenceFeatures(model108) {
|
|
28547
|
+
return Object.keys(model108.referenceFeatures);
|
|
28548
|
+
}
|
|
28549
|
+
function readJscadReferenceFeature(model108, name) {
|
|
28550
|
+
if (!Object.hasOwn(model108.referenceFeatures, name))
|
|
28551
|
+
throw new Error(`JSCAD model does not define named feature "${name}"`);
|
|
28552
|
+
return model108.referenceFeatures[name];
|
|
28553
|
+
}
|
|
28554
|
+
function readJscadNamedEdge(model108, name) {
|
|
28555
|
+
const { geometry: feature, matrix } = readJscadReferenceFeature(model108, name);
|
|
28556
|
+
if (matrix.length !== 16 || !matrix.every(Number.isFinite))
|
|
28557
|
+
throw new Error(
|
|
28558
|
+
`Named JSCAD feature "${name}" requires a finite 4x4 matrix`
|
|
28559
|
+
);
|
|
28560
|
+
let points;
|
|
28561
|
+
let closed;
|
|
28562
|
+
if (jscad20.geometries.path2.isA(feature)) {
|
|
28563
|
+
const path = jscad20.geometries.path2.clone(feature);
|
|
28564
|
+
points = jscad20.geometries.path2.toPoints(path);
|
|
28565
|
+
closed = path.isClosed;
|
|
28566
|
+
} else if (jscad20.geometries.geom2.isA(feature)) {
|
|
28567
|
+
const outlines = jscad20.geometries.geom2.toOutlines(
|
|
28568
|
+
jscad20.geometries.geom2.clone(feature)
|
|
28569
|
+
);
|
|
28570
|
+
if (outlines.length !== 1)
|
|
28571
|
+
throw new Error(
|
|
28572
|
+
`Named JSCAD edge "${name}" must identify one contour; name its boundaries separately`
|
|
28573
|
+
);
|
|
28574
|
+
points = outlines[0];
|
|
28575
|
+
closed = true;
|
|
28576
|
+
} else {
|
|
28577
|
+
throw new Error(
|
|
28578
|
+
`Named JSCAD edge "${name}" is not a geom2 or path2 feature`
|
|
28579
|
+
);
|
|
28580
|
+
}
|
|
28581
|
+
if (points.length < 2)
|
|
28582
|
+
throw new Error(`Named JSCAD edge "${name}" has no measurable path`);
|
|
28583
|
+
return {
|
|
28584
|
+
points: points.map(([x, y]) => {
|
|
28585
|
+
const point = jscad20.maths.vec3.transform(
|
|
28586
|
+
jscad20.maths.vec3.create(),
|
|
28587
|
+
[x, y, 0],
|
|
28588
|
+
matrix
|
|
28589
|
+
);
|
|
28590
|
+
return { x: point[0], y: point[1], z: point[2] };
|
|
28591
|
+
}),
|
|
28592
|
+
closed
|
|
28593
|
+
};
|
|
28594
|
+
}
|
|
28595
|
+
|
|
28596
|
+
// lib/models/rectangulartube/model.tsx
|
|
28597
|
+
import jscad21 from "@jscad/modeling";
|
|
28598
|
+
function createRectangularTubeModel(input) {
|
|
28599
|
+
const model108 = renderToJscadModel(
|
|
28600
|
+
/* @__PURE__ */ jsx(RectangularTube, { ...input }),
|
|
28601
|
+
jscad21
|
|
28602
|
+
);
|
|
28603
|
+
if (model108.geometries.length !== 1 || !jscad21.geometries.geom3.isA(model108.geometries[0]))
|
|
28604
|
+
throw new Error("RectangularTube must render exactly one native solid");
|
|
28605
|
+
return model108;
|
|
28606
|
+
}
|
|
28607
|
+
|
|
28608
|
+
// lib/models/rectangulartube/geometry.ts
|
|
28609
|
+
function createRectangularTubeGeom(input) {
|
|
28610
|
+
const model108 = createRectangularTubeModel(input);
|
|
28611
|
+
return model108.geometries[0];
|
|
28612
|
+
}
|
|
28613
|
+
function createRectangularTubeMesh(input) {
|
|
28614
|
+
return geom3ToIndexedMesh(createRectangularTubeGeom(input));
|
|
28615
|
+
}
|
|
28616
|
+
|
|
28002
28617
|
// lib/vanilla/index.ts
|
|
28003
|
-
function getJscadModelForFootprint(footprint,
|
|
28618
|
+
function getJscadModelForFootprint(footprint, jscad22) {
|
|
28004
28619
|
const vnode = h(Footprinter3d, { footprint });
|
|
28005
|
-
return render(vnode,
|
|
28620
|
+
return render(vnode, jscad22);
|
|
28006
28621
|
}
|
|
28007
|
-
function getJscadModelForFootprintWithPads(footprint,
|
|
28622
|
+
function getJscadModelForFootprintWithPads(footprint, jscad22) {
|
|
28008
28623
|
const vnode = h(
|
|
28009
28624
|
Fragment,
|
|
28010
28625
|
{},
|
|
28011
28626
|
h(Footprinter3d, { footprint }),
|
|
28012
28627
|
h(ExtrudedPads, { footprint })
|
|
28013
28628
|
);
|
|
28014
|
-
return render(vnode,
|
|
28629
|
+
return render(vnode, jscad22);
|
|
28015
28630
|
}
|
|
28016
|
-
function createJSCADRenderer(
|
|
28631
|
+
function createJSCADRenderer(jscad22) {
|
|
28017
28632
|
function createJSCADRoot(container) {
|
|
28018
28633
|
return {
|
|
28019
28634
|
render(element) {
|
|
28020
|
-
const { geometries: geometries9 } = render(element,
|
|
28635
|
+
const { geometries: geometries9 } = render(element, jscad22);
|
|
28021
28636
|
container.splice(0, container.length, ...geometries9);
|
|
28022
28637
|
}
|
|
28023
28638
|
};
|
|
@@ -28152,6 +28767,7 @@ export {
|
|
|
28152
28767
|
createRectangularGasketMesh,
|
|
28153
28768
|
createRectangularTubeGeom,
|
|
28154
28769
|
createRectangularTubeMesh,
|
|
28770
|
+
createRectangularTubeModel,
|
|
28155
28771
|
createRigidCouplerGeom,
|
|
28156
28772
|
createRigidCouplerMesh,
|
|
28157
28773
|
createSetScrewGeom,
|
|
@@ -28187,8 +28803,14 @@ export {
|
|
|
28187
28803
|
createWormGearMesh,
|
|
28188
28804
|
createZeeBarGeom,
|
|
28189
28805
|
createZeeBarMesh,
|
|
28806
|
+
geom3ToIndexedMesh,
|
|
28190
28807
|
getJscadModelForFootprint,
|
|
28191
28808
|
getJscadModelForFootprintWithPads,
|
|
28192
|
-
h
|
|
28809
|
+
h,
|
|
28810
|
+
listJscadNamedEdges,
|
|
28811
|
+
listJscadReferenceFeatures,
|
|
28812
|
+
readJscadNamedEdge,
|
|
28813
|
+
readJscadReferenceFeature,
|
|
28814
|
+
renderToJscadModel
|
|
28193
28815
|
};
|
|
28194
28816
|
//# sourceMappingURL=vanilla.js.map
|