UNPKG

@polygonjs/polygonjs

Version:

node-based WebGL 3D engine https://polygonjs.com

241 lines (240 loc) 7.3 kB
"use strict"; import { CadGeometryType, cadGeometryTypeFromShape, cadDowncast, _createCadBox3Handle } from "./CadCommon"; import { objectContentCopyProperties } from "../../ObjectContent"; import { cadPnt2dClone, cadPnt2dToObject3D } from "./toObject3D/CadPnt2d"; import { cadVertexClone, cadVertexToObject3D } from "./toObject3D/CadVertex"; import { cadGeom2dCurveClone, cadGeom2dCurveToBufferGeometry, cadGeom2dCurveToObject3D, CURVE_2D_TESSELATION_PARAMS } from "./toObject3D/CadGeom2dCurve"; import { cadEdgeClone, cadEdgeObjectToObject3D } from "./toObject3D/CadEdge"; import { cadWireClone, cadWireToObject3D } from "./toObject3D/CadWire"; import { CoreCadType } from "./CadCoreType"; import { CadLoaderSync } from "./CadLoaderSync"; import { cadShapeClone } from "./toObject3D/CadShapeCommon"; import { TypeAssert } from "../../../../engine/poly/Assert"; import { cadShapeToObject3D } from "./toObject3D/CadShape"; import { Box3, Vector3, Quaternion, Euler } from "three"; import { cadGeometryTransform } from "./operations/CadTransform"; import { cadCompoundToObject3D } from "./toObject3D/CadCompound"; const t = new Vector3(); const q = new Quaternion(); const s = new Vector3(); const euler = new Euler(); const r = new Vector3(); const pivot = new Vector3(); const DEFAULT_BND_BOX = _createCadBox3Handle(); const BBOX_EMPTY = new Box3(); const RAD2DEG = 180 / Math.PI; export class CadObject { constructor(_geometry, _type) { this._geometry = _geometry; this._type = _type; this.visible = true; this.userData = {}; this.name = ""; this.castShadow = true; this.receiveShadow = true; this.renderOrder = 0; this.frustumCulled = true; this.matrixAutoUpdate = false; this.children = []; this.parent = null; this._validate(); } get geometry() { return this._geometry; } get type() { return this._type; } setGeometry(geometry, type) { this._geometry = geometry; this._type = type; this._validate(); } _validate() { if (CoreCadType.isGeometryShape(this._geometry)) { const oc = CadLoaderSync.oc(); if (oc) { this._geometry = cadDowncast(oc, this._geometry); const type = cadGeometryTypeFromShape(oc, this._geometry); if (type) { this._type = type; } else { console.error("no type for geometry", this._geometry); } } } else { if (this.type == null) { console.error("type is required for geometry", this._geometry); } } } // static fromGeometry<T extends CadGeometryType>(geometry: CadTypeMap[T], type: T) { // return new CadObject(geometry, type); // } // type() { // return this._type!; // } cadGeometry() { return this.geometry; } dispose() { } applyMatrix4(matrix) { matrix.decompose(t, q, s); euler.setFromQuaternion(q); r.set(euler.x, euler.y, euler.z).multiplyScalar(RAD2DEG); const newGeometry = cadGeometryTransform(this.type, this.cadGeometry(), t, r, s.x, pivot); if (newGeometry) { const oc = CadLoaderSync.oc(); if (CoreCadType.isGeometryShape(newGeometry)) { const newType = cadGeometryTypeFromShape(oc, newGeometry); if (newType) { this.setGeometry(newGeometry, newType); } } else { } } } add(...object) { } remove(...object) { } dispatchEvent(event) { } traverse(callback) { callback(this); } clone() { const geometry = cloneCadGeometry(this.type, this.cadGeometry()); const clone = new CadObject(geometry, this.type); objectContentCopyProperties(this, clone); return clone; } toObject3D(tesselationParams, displayNode) { return CadObject.toObject3D(this, this.type, tesselationParams, displayNode); } static toObject3D(cadObject, type, tesselationParams, displayNode) { switch (type) { case CadGeometryType.POINT_2D: { return cadPnt2dToObject3D(cadObject); } case CadGeometryType.CURVE_2D: { return cadGeom2dCurveToObject3D(cadObject, tesselationParams); } case CadGeometryType.VERTEX: { return cadVertexToObject3D(cadObject); } case CadGeometryType.EDGE: { return cadEdgeObjectToObject3D(cadObject, tesselationParams); } case CadGeometryType.WIRE: { return cadWireToObject3D(cadObject, tesselationParams); } case CadGeometryType.FACE: case CadGeometryType.SHELL: case CadGeometryType.SOLID: case CadGeometryType.COMPSOLID: { return cadShapeToObject3D(cadObject, tesselationParams, displayNode); } case CadGeometryType.COMPOUND: { return cadCompoundToObject3D( cadObject, tesselationParams, displayNode ); } } TypeAssert.unreachable(type); } boundingBox(target) { const oc = CadLoaderSync.oc(); const Bnd_Box = CadLoaderSync.Bnd_Box; Bnd_Box.SetVoid(); const useTriangulation = true; if (CoreCadType.isShape(this)) { oc.BRepBndLib.Add(this.cadGeometry(), Bnd_Box, useTriangulation); Bnd_Box.Get( DEFAULT_BND_BOX.min.x, DEFAULT_BND_BOX.min.y, DEFAULT_BND_BOX.min.z, DEFAULT_BND_BOX.max.x, DEFAULT_BND_BOX.max.y, DEFAULT_BND_BOX.max.z ); target.min.x = DEFAULT_BND_BOX.min.x.current; target.min.y = DEFAULT_BND_BOX.min.y.current; target.min.z = DEFAULT_BND_BOX.min.z.current; target.max.x = DEFAULT_BND_BOX.max.x.current; target.max.y = DEFAULT_BND_BOX.max.y.current; target.max.z = DEFAULT_BND_BOX.max.z.current; return; } else { switch (this.type) { case CadGeometryType.POINT_2D: { const point = this.cadGeometry(); target.min.x = point.X(); target.min.y = point.Y(); target.min.z = 0; target.max.x = point.X(); target.max.y = point.Y(); target.max.z = 0; return; } case CadGeometryType.CURVE_2D: { const geometry = cadGeom2dCurveToBufferGeometry( this, CURVE_2D_TESSELATION_PARAMS ); geometry.computeBoundingBox(); if (geometry.boundingBox) { target.copy(geometry.boundingBox); } else { target.copy(BBOX_EMPTY); } return; } default: { console.warn("cad BoundingBox not implemented for type", this.type); target.copy(BBOX_EMPTY); } } } } } function cloneCadGeometry(type, srcGeometry) { switch (type) { case CadGeometryType.POINT_2D: { return cadPnt2dClone(srcGeometry); } case CadGeometryType.CURVE_2D: { return cadGeom2dCurveClone(srcGeometry); } case CadGeometryType.VERTEX: { return cadVertexClone(srcGeometry); } case CadGeometryType.EDGE: { return cadEdgeClone(srcGeometry); } case CadGeometryType.WIRE: { return cadWireClone(srcGeometry); } case CadGeometryType.FACE: case CadGeometryType.SHELL: case CadGeometryType.SOLID: case CadGeometryType.COMPSOLID: case CadGeometryType.COMPOUND: { return cadShapeClone(srcGeometry); } } TypeAssert.unreachable(type); }