107 lines
4.2 KiB
JavaScript
107 lines
4.2 KiB
JavaScript
import { ocRef } from './oc.js';
|
|
|
|
export function build3DBusbar(geometry, positions, padRadius, zBase, thickness) {
|
|
const oc = ocRef.instance;
|
|
if (!oc || geometry.padIndices.length === 0) return null;
|
|
|
|
const shapes = [];
|
|
const extraPads = Array.isArray(geometry.extraPads) ? geometry.extraPads : [];
|
|
const extraSegments = Array.isArray(geometry.extraSegments) ? geometry.extraSegments : [];
|
|
const cutouts = Array.isArray(geometry.cutouts) ? geometry.cutouts : [];
|
|
|
|
for (const i of geometry.padIndices) {
|
|
if (!positions[i]) continue;
|
|
const [x, y] = positions[i];
|
|
const ax = new oc.gp_Ax2(new oc.gp_Pnt(x, y, zBase), oc.gp.prototype.DZ());
|
|
shapes.push(new oc.BRepPrimAPI_MakeCylinder(ax, padRadius, thickness).Shape());
|
|
}
|
|
|
|
for (const pad of extraPads) {
|
|
const [x, y] = pad.pos;
|
|
const radius = pad.radius ?? padRadius;
|
|
const ax = new oc.gp_Ax2(new oc.gp_Pnt(x, y, zBase), oc.gp.prototype.DZ());
|
|
shapes.push(new oc.BRepPrimAPI_MakeCylinder(ax, radius, thickness).Shape());
|
|
}
|
|
|
|
for (const edge of geometry.edges) {
|
|
const pts = [positions[edge.from], ...edge.waypoints, positions[edge.to]];
|
|
|
|
for (let k = 1; k < pts.length - 1; k++) {
|
|
const [wx, wy] = pts[k];
|
|
const ax = new oc.gp_Ax2(new oc.gp_Pnt(wx, wy, zBase), oc.gp.prototype.DZ());
|
|
shapes.push(new oc.BRepPrimAPI_MakeCylinder(ax, padRadius, thickness).Shape());
|
|
}
|
|
|
|
for (let k = 0; k < pts.length - 1; k++) {
|
|
const [x1, y1] = pts[k];
|
|
const [x2, y2] = pts[k + 1];
|
|
const dx = x2 - x1, dy = y2 - y1;
|
|
const len = Math.hypot(dx, dy);
|
|
if (len < 1e-6) continue;
|
|
const angle = Math.atan2(dy, dx);
|
|
|
|
const box = new oc.BRepPrimAPI_MakeBox(len, 2 * padRadius, thickness).Shape();
|
|
|
|
const trans1 = new oc.gp_Trsf();
|
|
trans1.SetTranslation(new oc.gp_Vec(0, -padRadius, 0));
|
|
let shape = new oc.BRepBuilderAPI_Transform(box, trans1, false).Shape();
|
|
|
|
const rot = new oc.gp_Trsf();
|
|
rot.SetRotation(new oc.gp_Ax1(new oc.gp_Pnt(0, 0, 0), oc.gp.prototype.DZ()), angle);
|
|
shape = new oc.BRepBuilderAPI_Transform(shape, rot, false).Shape();
|
|
|
|
const trans2 = new oc.gp_Trsf();
|
|
trans2.SetTranslation(new oc.gp_Vec(x1, y1, zBase));
|
|
shape = new oc.BRepBuilderAPI_Transform(shape, trans2, false).Shape();
|
|
|
|
shapes.push(shape);
|
|
}
|
|
}
|
|
|
|
for (const segment of extraSegments) {
|
|
const [x1, y1] = segment.from;
|
|
const [x2, y2] = segment.to;
|
|
const segmentRadius = segment.radius ?? padRadius;
|
|
const dx = x2 - x1, dy = y2 - y1;
|
|
const len = Math.hypot(dx, dy);
|
|
if (len < 1e-6) continue;
|
|
const angle = Math.atan2(dy, dx);
|
|
|
|
const box = new oc.BRepPrimAPI_MakeBox(len, 2 * segmentRadius, thickness).Shape();
|
|
|
|
const trans1 = new oc.gp_Trsf();
|
|
trans1.SetTranslation(new oc.gp_Vec(0, -segmentRadius, 0));
|
|
let shape = new oc.BRepBuilderAPI_Transform(box, trans1, false).Shape();
|
|
|
|
const rot = new oc.gp_Trsf();
|
|
rot.SetRotation(new oc.gp_Ax1(new oc.gp_Pnt(0, 0, 0), oc.gp.prototype.DZ()), angle);
|
|
shape = new oc.BRepBuilderAPI_Transform(shape, rot, false).Shape();
|
|
|
|
const trans2 = new oc.gp_Trsf();
|
|
trans2.SetTranslation(new oc.gp_Vec(x1, y1, zBase));
|
|
shape = new oc.BRepBuilderAPI_Transform(shape, trans2, false).Shape();
|
|
|
|
shapes.push(shape);
|
|
}
|
|
|
|
if (shapes.length === 0) return null;
|
|
let combined = shapes[0];
|
|
for (let i = 1; i < shapes.length; i++) {
|
|
combined = new oc.BRepAlgoAPI_Fuse(combined, shapes[i]).Shape();
|
|
}
|
|
|
|
for (const cutout of cutouts) {
|
|
const [cx, cy] = cutout.center;
|
|
const width = cutout.width;
|
|
const height = cutout.height;
|
|
const cutter = new oc.BRepPrimAPI_MakeBox(width, height, thickness).Shape();
|
|
|
|
const trans = new oc.gp_Trsf();
|
|
trans.SetTranslation(new oc.gp_Vec(cx - width / 2, cy - height / 2, zBase));
|
|
const placedCutter = new oc.BRepBuilderAPI_Transform(cutter, trans, false).Shape();
|
|
combined = new oc.BRepAlgoAPI_Cut(combined, placedCutter).Shape();
|
|
}
|
|
|
|
return combined;
|
|
}
|