mirror of
https://github.com/xibyte/jsketcher
synced 2025-12-08 01:13:27 +01:00
141 lines
3.7 KiB
JavaScript
141 lines
3.7 KiB
JavaScript
import Vector from '../../math/vector'
|
|
import {Triangulate} from '../../3d/triangulation'
|
|
|
|
export class SceneSolid {
|
|
|
|
constructor(shell) {
|
|
this.shell = shell;
|
|
|
|
this.cadGroup = new THREE.Object3D();
|
|
this.cadGroup.__tcad_solid = this;
|
|
this.wireframeGroup = new THREE.Object3D();
|
|
this.cadGroup.add(this.wireframeGroup);
|
|
|
|
const geometry = new THREE.Geometry();
|
|
geometry.dynamic = true;
|
|
this.mesh = new THREE.Mesh(geometry, createSolidMaterial());
|
|
this.cadGroup.add(this.mesh);
|
|
|
|
this.polyFaces = [];
|
|
this.createFaces();
|
|
this.createEdges();
|
|
this.createVertices();
|
|
}
|
|
|
|
createFaces() {
|
|
let off = 0;
|
|
let gIdx = 0;
|
|
const geom = this.mesh.geometry;
|
|
for (let brepFace of this.shell.faces) {
|
|
const polyFace = new SceneFace(brepFace);
|
|
this.polyFaces.push(polyFace);
|
|
const polygons = triangulate(brepFace);
|
|
for (let p = 0; p < polygons.length; ++p) {
|
|
const poly = polygons[p];
|
|
const vLength = poly.length;
|
|
if (vLength < 3) continue;
|
|
const firstVertex = poly[0];
|
|
geom.vertices.push(threeV(firstVertex));
|
|
geom.vertices.push(threeV(poly[1]));
|
|
const normal = threeV(brepFace.surface.normal);
|
|
for (let i = 2; i < vLength; i++) {
|
|
geom.vertices.push(threeV(poly[i]));
|
|
|
|
const a = off;
|
|
const b = i - 1 + off;
|
|
const c = i + off;
|
|
const face = new THREE.Face3(a, b, c);
|
|
polyFace.faces.push(face);
|
|
face.__TCAD_polyFace = polyFace;
|
|
face.normal = normal;
|
|
face.materialIndex = gIdx ++;
|
|
geom.faces.push(face);
|
|
if (brepFace.debugName == 'base') {
|
|
face.color.set(new THREE.Color().setHex( 0x000077 ));
|
|
}
|
|
if (brepFace.debugName == 'wall_3') {
|
|
face.color.set(new THREE.Color().setHex( 0x007700 ));
|
|
}
|
|
|
|
}
|
|
//view.setFaceColor(polyFace, utils.isSmoothPiece(group.shared) ? 0xFF0000 : null);
|
|
off = geom.vertices.length;
|
|
}
|
|
}
|
|
geom.mergeVertices();
|
|
}
|
|
|
|
createEdges() {
|
|
const visited = new Set();
|
|
for (let face of this.shell.faces) {
|
|
for (let halfEdge of face.outerLoop.halfEdges) {
|
|
if (!visited.has(halfEdge.edge)) {
|
|
visited.add(halfEdge.edge);
|
|
this.addLineToScene(halfEdge.vertexA.point, halfEdge.vertexB.point, halfEdge.edge);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
createVertices() {
|
|
|
|
}
|
|
|
|
addLineToScene(a, b, edge) {
|
|
const lg = new THREE.Geometry();
|
|
lg.vertices.push(a);
|
|
lg.vertices.push(b);
|
|
const line = new THREE.Line(lg, WIREFRAME_MATERIAL);
|
|
line.__TCAD_edge = edge;
|
|
this.wireframeGroup.add(line);
|
|
};
|
|
|
|
}
|
|
|
|
const WIREFRAME_MATERIAL = new THREE.LineBasicMaterial({color: 0xff0000, linewidth: 10});
|
|
|
|
|
|
class SceneFace {
|
|
constructor(brepFace) {
|
|
this.brepFace = brepFace;
|
|
this.faces = [];
|
|
}
|
|
}
|
|
|
|
function triangulate(face) {
|
|
function csgVert(data) {
|
|
return new Vector(data[0], data[1], data[2]);
|
|
}
|
|
function data(v) {
|
|
return [v.x, v.y, v.z];
|
|
}
|
|
|
|
var triangled = [];
|
|
const polygons = [face.outerLoop.asPolygon()];
|
|
for (let poly of polygons) {
|
|
let vertices = Triangulate([poly.map(v => data(v))], data(face.surface.normal));
|
|
for (let i = 0; i < vertices.length; i += 3 ) {
|
|
var a = csgVert(vertices[i]);
|
|
var b = csgVert(vertices[i + 1]);
|
|
var c = csgVert(vertices[i + 2]);
|
|
triangled.push([a, b, c]);
|
|
}
|
|
}
|
|
return triangled;
|
|
|
|
}
|
|
|
|
|
|
function createSolidMaterial() {
|
|
return new THREE.MeshPhongMaterial({
|
|
vertexColors: THREE.FaceColors,
|
|
color: 0xB0C4DE,
|
|
shininess: 0,
|
|
polygonOffset : true,
|
|
polygonOffsetFactor : 1,
|
|
polygonOffsetUnits : 2,
|
|
side : THREE.DoubleSide
|
|
});
|
|
}
|
|
|
|
function threeV(v) {return new THREE.Vector3( v.x, v.y, v.z )}
|