jsketcher/web/app/cad/scene/wrappers/sceneObject.js
2020-07-18 23:11:02 -07:00

196 lines
5.1 KiB
JavaScript

import Vector from 'math/vector';
import DPR from 'dpr'
import {getAttribute, setAttribute} from "scene/objectData";
import {BasisForPlane} from 'math/basis';
//todo: rename to shell
export class SceneSolid {
ID = 0;
constructor(type, id, skin) {
this.tCadType = type || 'SHELL';
this.cadGroup = new THREE.Object3D();
setAttribute(this.cadGroup, 'shell', this);
this.tCadId = SceneSolid.ID++;
this.id = id === undefined ? this.tCadId : id; // to keep identity through the history
this.faceCounter = 0;
this.edgeCounter = 0;
this.wireframeGroup = new THREE.Object3D();
this.cadGroup.add(this.wireframeGroup);
this.mergeable = true;
this.sceneFaces = [];
this.sceneEdges = [];
this.sketch = null;
this.material = createSolidMaterial(skin);
}
addLineToScene(a, b) {
let lg = new THREE.Geometry();
lg.vertices.push(a);
lg.vertices.push(b);
let line = new THREE.Line(lg, WIREFRAME_MATERIAL);
this.wireframeGroup.add(line);
return line;
}
dispose() {
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
}, skin));
}
const OFF_LINES_VECTOR = new Vector();//normal.multiply(0); // disable it. use polygon offset feature of material
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';
}
surface() {
throw 'not implemented';
}
calcBasis() {
return BasisForPlane(this.normal());
};
basis() {
if (!this._basis) {
this._basis = this.calcBasis();
}
return this._basis;
}
createMeshFace(a, b, c, normales) {
const face = new THREE.Face3(a, b, c, normales);
this.registerMeshFace(face);
return face;
}
registerMeshFace(threeFace) {
this.meshFaces.push(threeFace);
setAttribute(threeFace, 'face', this);
}
updateSketch(sketch) {
this.sketch = sketch;
if (this.sketch !== null) {
this.syncSketch(this.sketch);
}
}
syncSketch(geom) {
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);
}
let surface = this.surface();
const _3dTransformation = surface.tangentPlaneInMiddle().get3DTransformation();
const addSketchObjects = (sketchObjects, material, close) => {
for (let sketchObject of sketchObjects) {
let line = new THREE.Line(new THREE.Geometry(), material);
let sceneSketchObject = new SceneSketchObject(sketchObject, line);
setAttribute(line, 'sketchObject', sceneSketchObject);
const chunks = sketchObject.tessellate(10);
function addLine(p, q) {
const lg = line.geometry;
const a = _3dTransformation.apply(chunks[p]);
const b = _3dTransformation.apply(chunks[q]);
lg.vertices.push(a._plus(OFF_LINES_VECTOR).three());
lg.vertices.push(b._plus(OFF_LINES_VECTOR).three());
}
for (let q = 1; q < chunks.length; q ++) {
addLine(q - 1, q);
}
this.sketch3DGroup.add(line);
}
};
addSketchObjects(geom.constructionSegments, SKETCH_CONSTRUCTION_MATERIAL);
addSketchObjects(geom.connections, SKETCH_MATERIAL);
addSketchObjects(geom.loops, SKETCH_MATERIAL);
}
findById(sketchObjectId) {
for (let o of this.sketch3DGroup.children) {
let sceneSketchObject = getAttribute(o, 'sketchObject');
if (sceneSketchObject && sceneSketchObject.id === sketchObjectId) {
return sceneSketchObject;
}
}
}
getSketchObjectVerticesIn3D(sketchObjectId) {
const object = this.findById(sketchObjectId);
if (!object) {
return undefined;
}
return object.geometry.vertices;
}
}
export class SceneEdge {
constructor(curve, solid, representation, marker) {
this.id = solid.tCadId + ":" + (solid.edgeCounter++);
this.curve = curve;
this.solid = solid;
this.representation = representation;
this.marker = marker;
}
}
export class SceneSketchObject {
constructor(model, viewObject) {
this.id = model.id;
this.model = model;
this.viewObject = viewObject;
}
}
export const SKETCH_MATERIAL = new THREE.LineBasicMaterial({color: 0xFFFFFF, linewidth: 3/DPR});
export const SKETCH_CONSTRUCTION_MATERIAL = new THREE.LineBasicMaterial({color: 0x777777, linewidth: 2/DPR});
export const WIREFRAME_MATERIAL = new THREE.LineBasicMaterial({color: 0x2B3856, linewidth: 3/DPR});