@bitbybit-dev/jscad
Version:
Bit By Bit Developers JSCAD based CAD Library to Program Geometry
140 lines (139 loc) • 5.78 kB
JavaScript
import { GeometryHelper } from "@bitbybit-dev/base";
import { MathBitByBit } from "@bitbybit-dev/base";
import { JSCADExpansions } from "./services/jscad-expansions";
import { JSCADBooleans } from "./services/jscad-booleans";
import { JSCADExtrusions } from "./services/jscad-extrusions";
import { JSCADPath } from "./services/jscad-path";
import { JSCADPolygon } from "./services/jscad-polygon";
import { JSCADShapes } from "./services/jscad-shapes";
import { JSCADText } from "./services/jscad-text";
import { JSCADHulls } from "./services/jscad-hulls";
import { JSCADColors } from "./services/jscad-colors";
// Worker make an instance of this class itself
export class Jscad {
constructor(jscad) {
this.getArrayDepth = (value) => {
return Array.isArray(value) ?
1 + Math.max(...value.map(this.getArrayDepth)) :
0;
};
const geometryHelper = new GeometryHelper();
const math = new MathBitByBit();
this.booleans = new JSCADBooleans(jscad);
this.expansions = new JSCADExpansions(jscad);
this.extrusions = new JSCADExtrusions(jscad, geometryHelper, math);
this.hulls = new JSCADHulls(jscad);
this.path = new JSCADPath(jscad, geometryHelper, math);
this.polygon = new JSCADPolygon(jscad, geometryHelper, math);
this.shapes = new JSCADShapes(jscad, math);
this.text = new JSCADText(jscad);
this.colors = new JSCADColors(jscad);
this.jscad = jscad;
}
shapesToMeshes(inputs) {
return inputs.meshes.map(mesh => {
return this.shapeToMesh(Object.assign(Object.assign({}, inputs), { mesh }));
});
}
shapeToMesh(inputs) {
let polygons = [];
if (inputs.mesh.toPolygons) {
polygons = inputs.mesh.toPolygons();
}
else if (inputs.mesh.polygons) {
polygons = inputs.mesh.polygons;
}
else if (inputs.mesh.sides || inputs.mesh.vertices) {
const extrusion = this.extrusions.extrudeLinear({ height: 0.001, twistAngle: 0, twistSteps: 1, geometry: inputs.mesh });
if (extrusion.toPolygons) {
polygons = extrusion.toPolygons();
}
else if (extrusion.polygons) {
polygons = extrusion.polygons;
}
}
const positions = [];
const normals = [];
const indices = [];
let countIndices = 0;
for (const polygon of polygons) {
if (polygon.vertices.length === 3) {
polygon.vertices.forEach(vert => {
positions.push(vert[0], vert[1], vert[2]);
indices.push(countIndices);
countIndices++;
});
}
else {
const triangles = [];
const reversedVertices = polygon.vertices;
const firstVertex = reversedVertices[0];
for (let i = reversedVertices.length - 3; i >= 0; i--) {
triangles.push([
firstVertex,
reversedVertices[i + 1],
reversedVertices[i + 2],
]);
}
triangles.forEach((triangle, index) => {
triangle.forEach(vert => {
positions.push(vert[0], vert[1], vert[2]);
indices.push(countIndices);
countIndices++;
});
});
}
}
return {
positions, normals, indices, transforms: inputs.mesh.transforms,
};
}
transformSolids(inputs) {
const solidsToTransform = inputs.meshes;
return solidsToTransform.map(mesh => {
return this.transformSolid({ mesh, transformation: inputs.transformation });
});
}
transformSolid(inputs) {
const transformation = inputs.transformation;
let transformedMesh = this.jscad.geometries.geom3.clone(inputs.mesh);
if (this.getArrayDepth(transformation) === 2) {
transformation.forEach(transform => {
transformedMesh = this.jscad.transforms.transform(transform, transformedMesh);
});
}
else if (this.getArrayDepth(transformation) === 3) {
transformation.forEach(transforms => {
transforms.forEach(mat => {
transformedMesh = this.jscad.transforms.transform(mat, transformedMesh);
});
});
}
else {
transformedMesh = this.jscad.transforms.transform(transformation, transformedMesh);
}
return transformedMesh;
}
downloadSolidSTL(inputs) {
const rawData = this.jscad.STLSERIALIZER.serialize({ binary: true }, inputs.mesh);
const madeBlob = new Blob(rawData, { type: "application/sla" });
return { blob: madeBlob };
}
downloadGeometryDxf(inputs) {
const options = inputs.options ? inputs.options : {};
const rawData = this.jscad.DXFSERIALIZER.serialize(options, inputs.geometry);
const madeBlob = new Blob(rawData);
return { blob: madeBlob };
}
downloadGeometry3MF(inputs) {
const options = inputs.options ? inputs.options : {};
const rawData = this.jscad.THREEMFSERIALIZER.serialize(options, inputs.geometry);
const madeBlob = new Blob(rawData);
return { blob: madeBlob };
}
downloadSolidsSTL(inputs) {
const rawData = this.jscad.STLSERIALIZER.serialize({ binary: true }, ...inputs.meshes);
const madeBlob = new Blob(rawData, { type: "application/sla" });
return { blob: madeBlob };
}
}