UNPKG

@polygonjs/polygonjs

Version:

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

78 lines (71 loc) 2.42 kB
import type {FaceData, OpenCascadeInstance, TopoDS_Face} from '../CadCommon'; import {CadGC} from '../CadCommon'; import {CadLoaderSync} from '../CadLoaderSync'; enum FaceOrientation { BACKWARD = 0, FORWARD = 1, } function faceOrientation(oc: OpenCascadeInstance, face: TopoDS_Face): FaceOrientation { return face.Orientation_1() === oc.TopAbs_Orientation.TopAbs_FORWARD ? FaceOrientation.FORWARD : FaceOrientation.BACKWARD; } const STRIDE = 3; export function faceData(oc: OpenCascadeInstance, face: TopoDS_Face, index0 = 0): FaceData | void { return CadGC.withGC((r) => { const location = CadLoaderSync.TopLoc_Location; const triangulation = oc.BRep_Tool.Triangulation(face, location, 0); if (triangulation.IsNull()) { return; } const transformation = location.Transformation(); const tri = triangulation.get(); const nbNodes = tri.NbNodes(); // init const normalsArray = r(new oc.TColgp_Array1OfDir_2(1, nbNodes)); const pc = r(new oc.Poly_Connect_2(triangulation)); oc.StdPrs_ToolTriangulatedShape.Normal(face, pc, normalsArray); const nbTriangles = tri.NbTriangles(); const faceData: FaceData = { positions: new Array(nbNodes * 3), normals: new Array(normalsArray.Length() * 3), indices: new Array(nbTriangles * 3), }; // positions for (let i = 1; i <= nbNodes; i++) { const p = tri.Node(i).Transformed(transformation); const index = (i - 1) * STRIDE; faceData.positions[index] = p.X(); faceData.positions[index + 1] = p.Y(); faceData.positions[index + 2] = p.Z(); } // normals for (let i = normalsArray.Lower(); i <= normalsArray.Upper(); i++) { const d = normalsArray.Value(i).Transformed(transformation); const index = (i - 1) * STRIDE; faceData.normals[index] = d.X(); faceData.normals[index + 1] = d.Y(); faceData.normals[index + 2] = d.Z(); } // indices let trisCount = 0; const orientation = faceOrientation(oc, face); for (let nt = 1; nt <= nbTriangles; nt++) { const t = tri.Triangle(nt); let n1 = t.Value(1); let n2 = t.Value(2); const n3 = t.Value(3); if (orientation == FaceOrientation.BACKWARD) { const tmp = n1; n1 = n2; n2 = tmp; } const index = trisCount * STRIDE; faceData.indices[index] = n1 - 1 + index0; faceData.indices[index + 1] = n2 - 1 + index0; faceData.indices[index + 2] = n3 - 1 + index0; trisCount++; } return faceData; }); }