mirror of
https://github.com/xibyte/jsketcher
synced 2025-12-08 01:13:27 +01:00
172 lines
4.6 KiB
JavaScript
172 lines
4.6 KiB
JavaScript
import {HashTable} from '../../utils/hashmap'
|
|
import Vector from '../../math/vector'
|
|
import Counters from '../counters'
|
|
import {Matrix3, BasisForPlane} from '../../math/l3space'
|
|
import {arrFlatten1L, isCurveClass} from '../cad-utils'
|
|
import DPR from '../../utils/dpr'
|
|
|
|
export class SceneSolid {
|
|
|
|
constructor(type, id, skin) {
|
|
this.tCadType = type || 'SOLID';
|
|
|
|
this.cadGroup = new THREE.Object3D();
|
|
this.cadGroup.__tcad_solid = this;
|
|
|
|
this.tCadId = Counters.solid ++;
|
|
this.id = id === undefined ? this.tCadId : id; // to keep identity through the history
|
|
this.faceCounter = 0;
|
|
|
|
this.wireframeGroup = new THREE.Object3D();
|
|
this.cadGroup.add(this.wireframeGroup);
|
|
this.mergeable = true;
|
|
this.sceneFaces = [];
|
|
|
|
this.material = createSolidMaterial(skin);
|
|
}
|
|
|
|
addLineToScene(a, b) {
|
|
var lg = new THREE.Geometry();
|
|
lg.vertices.push(a);
|
|
lg.vertices.push(b);
|
|
var line = new THREE.Line(lg, WIREFRAME_MATERIAL);
|
|
this.wireframeGroup.add(line);
|
|
}
|
|
|
|
createGeometry() {
|
|
throw 'not implemented';
|
|
}
|
|
|
|
dropGeometry() {
|
|
throw 'not implemented';
|
|
}
|
|
|
|
vanish() {
|
|
this.cadGroup.parent.remove( this.cadGroup );
|
|
this.material.dispose();
|
|
this.mesh.geometry.dispose();
|
|
}
|
|
}
|
|
|
|
export function createSolidMaterial(skin) {
|
|
return new THREE.MeshPhongMaterial(Object.assign({
|
|
vertexColors: THREE.FaceColors,
|
|
color: 0xB0C4DE,
|
|
shininess: 0,
|
|
polygonOffset : true,
|
|
polygonOffsetFactor : 1,
|
|
polygonOffsetUnits : 2,
|
|
//side : THREE.DoubleSide
|
|
}, skin));
|
|
}
|
|
|
|
export class SceneFace {
|
|
constructor(solid, propagatedId) {
|
|
if (propagatedId === undefined) {
|
|
this.id = solid.tCadId + ":" + (solid.faceCounter++);
|
|
} else {
|
|
this.id = propagatedId;
|
|
}
|
|
|
|
this.solid = solid;
|
|
this.meshFaces = [];
|
|
this.sketch3DGroup = null;
|
|
}
|
|
|
|
normal() {
|
|
throw 'not implemented';
|
|
}
|
|
|
|
depth() {
|
|
throw 'not implemented';
|
|
}
|
|
|
|
getBounds() {
|
|
throw 'not implemented';
|
|
}
|
|
|
|
calcBasis() {
|
|
return BasisForPlane(this.normal());
|
|
};
|
|
|
|
basis() {
|
|
if (!this._basis) {
|
|
this._basis = this.calcBasis();
|
|
}
|
|
return this._basis;
|
|
}
|
|
|
|
createMeshFace(a, b, c) {
|
|
const face = new THREE.Face3(a, b, c);
|
|
this.registerMeshFace(face);
|
|
return face;
|
|
}
|
|
|
|
registerMeshFace(threeFace) {
|
|
this.meshFaces.push(threeFace);
|
|
threeFace.__TCAD_SceneFace = this;
|
|
}
|
|
|
|
syncSketches(geom) {
|
|
const normal = this.normal();
|
|
const offVector = new Vector();//normal.multiply(0); // disable it. use polygon offset feature of material
|
|
|
|
if (this.sketch3DGroup != null) {
|
|
for (let i = this.sketch3DGroup.children.length - 1; i >= 0; --i) {
|
|
this.sketch3DGroup.remove(this.sketch3DGroup.children[i]);
|
|
}
|
|
} else {
|
|
this.sketch3DGroup = new THREE.Object3D();
|
|
this.solid.cadGroup.add(this.sketch3DGroup);
|
|
}
|
|
|
|
const basis = this.basis();
|
|
const _3dTransformation = new Matrix3().setBasis(basis);
|
|
//we lost depth or z off in 2d sketch, calculate it again
|
|
const depth = this.depth();
|
|
const polyLines = new Map();
|
|
function addSketchConnections(connections, material) {
|
|
for (let i = 0; i < connections.length; ++i) {
|
|
const l = connections[i];
|
|
|
|
let line = polyLines.get(l.sketchObject.id);
|
|
if (!line) {
|
|
line = new THREE.Line(undefined, material);
|
|
line.__TCAD_SketchObject = l.sketchObject;
|
|
polyLines.set(l.sketchObject.id, line);
|
|
}
|
|
const lg = line.geometry;
|
|
l.a.z = l.b.z = depth;
|
|
const a = _3dTransformation.apply(l.a);
|
|
const b = _3dTransformation.apply(l.b);
|
|
|
|
lg.vertices.push(a.plus(offVector).three());
|
|
lg.vertices.push(b.plus(offVector).three());
|
|
}
|
|
|
|
}
|
|
addSketchConnections(geom.constructionSegments, SKETCH_CONSTRUCTION_MATERIAL);
|
|
addSketchConnections(geom.connections, SKETCH_MATERIAL);
|
|
addSketchConnections(arrFlatten1L(geom.loops), SKETCH_MATERIAL);
|
|
|
|
for (let line of polyLines.values()) {
|
|
this.sketch3DGroup.add(line);
|
|
}
|
|
}
|
|
|
|
findById(sketchObjectId) {
|
|
return this.sketch3DGroup.children.find(o => o.__TCAD_SketchObject && o.__TCAD_SketchObject.id == sketchObjectId);
|
|
}
|
|
|
|
getSketchObjectVerticesIn3D(sketchObjectId) {
|
|
const object = this.findById(sketchObjectId);
|
|
if (!object) {
|
|
return undefined;
|
|
}
|
|
return object.geometry.vertices;
|
|
}
|
|
}
|
|
|
|
const SKETCH_MATERIAL = new THREE.LineBasicMaterial({color: 0xFFFFFF, linewidth: 3/DPR});
|
|
const SKETCH_CONSTRUCTION_MATERIAL = new THREE.LineBasicMaterial({color: 0x777777, linewidth: 2/DPR});
|
|
const WIREFRAME_MATERIAL = new THREE.LineBasicMaterial({color: 0x2B3856, linewidth: 3/DPR});
|