@polygonjs/polygonjs
Version:
node-based WebGL 3D engine https://polygonjs.com
241 lines (240 loc) • 7.3 kB
JavaScript
"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);
}