edges and normals using opencascade.js

This commit is contained in:
xibyte 2021-10-07 19:09:46 -07:00 committed by Val Erastov
parent c107f6148f
commit 705b86cdde
4 changed files with 197 additions and 166 deletions

View file

@ -20,46 +20,46 @@ import {Edge} from "brep/topo/edge";
import {ParametricSurface} from "geom/surfaces/parametricSurface";
//Extensions for topo objects
declare module '../topo/shell' {
interface Shell {
data: {
externals: {
ptr?: number
}
}
}
}
declare module '../topo/face' {
interface Face {
data: {
id: string,
productionInfo: ProductionInfo,
tessellation: {
format: string,
data: any;
}
externals: {
ref: number,
ptr: number
}
}
}
}
declare module '../topo/edge' {
interface Edge {
data: {
tessellation: Tessellation1D<Vec3>
externals: {
ptr?: number
}
}
}
}
// declare module '../topo/shell' {
//
// interface Shell {
// data: {
// externals: {
// ptr?: number
// }
// }
// }
// }
//
// declare module '../topo/face' {
//
// interface Face {
// data: {
// id: string,
// productionInfo: ProductionInfo,
// tessellation: {
// format: string,
// data: any;
// }
// externals: {
// ref: number,
// ptr: number
// }
// }
// }
// }
//
// declare module '../topo/edge' {
//
// interface Edge {
// data: {
// tessellation: Tessellation1D<Vec3>
// externals: {
// ptr?: number
// }
// }
// }
// }
export function readBrep(data: BrepOutputData) {

View file

@ -1,7 +1,7 @@
export class TopoObject {
data: {};
data: any;
op: OperationTemporaryData;
constructor() {

View file

@ -0,0 +1,36 @@
import {Shell} from "brep/topo/shell";
export function assignEntityIdentity(created: Shell[], consumed: Shell[]) {
let refIndex = indexFacesByRef(consumed);
let shell = readBrep(data);
for (let face of shell.faces) {
let ref = getRef(face);
if (ref !== undefined) {
let consumedFace = refIndex.get(ref);
if (consumedFace) {
face.data.id = consumedFace.id;
}
}
}
return new MBrepShell(shell, csys);
}
function indexFacesByRef(shells: Shell[]) {
let index = new Map();
if (shells) {
for (let shell of shells) {
for (let face of shell.faces) {
let ref = getRef(face.brepFace);
if (ref !== undefined) {
index.set(ref, face);
}
}
}
}
return index;
}
const getRef = brepFace => brepFace && brepFace.data.externals && brepFace.data.externals.ref;

View file

@ -3,7 +3,9 @@ import { normalizetessellationData } from "brep/io/brepIO";
import VertexFactory from "brep/vertexFactory";
import { BrepSurface } from "geom/surfaces/brepSurface";
import NullSurface from "geom/surfaces/nullSurface";
import {ProductionInfo} from "engine/productionInfo";
export type OCCShape = any;
export function occ2brep(aShape: any, oc: any) {
@ -11,11 +13,8 @@ export function occ2brep(aShape: any, oc: any) {
let vf = new VertexFactory();
new oc.BRepMesh_IncrementalMesh_2(aShape, 3, false, 0.5, false);
console.log(oc.TopAbs_ShapeEnum.TopAbs_FACE)
bb._shell.data.occShape = aShape;
const aExpFace = new oc.TopExp_Explorer_2(aShape, oc.TopAbs_ShapeEnum.TopAbs_FACE, oc.TopAbs_ShapeEnum.TopAbs_SHAPE);
const out = {};
const facesOut = [];
for (; aExpFace.More(); aExpFace.Next()) {
const aFace = oc.TopoDS.Face_1(aExpFace.Current());
@ -26,51 +25,27 @@ export function occ2brep(aShape: any, oc: any) {
let inverted = aFace.Orientation_1() == oc.TopAbs_Orientation.TopAbs_REVERSED !== nonDirect;
const aSurface = oc.BRep_Tool.Surface_2(aFace).get();
aSurface.IsKind = () => false
// let surfaceOut = {};
if (aSurface.IsKind("Geom_BoundedSurface")) {
const bSpline = oc.GeomConvert.prototype.SurfaceToBSplineSurface(aSurface).get();
// surfaceOut = {"TYPE": "UNKNOWN"};//surfaceWriteBounded(bSpline);
//if BRepPrimAPI_MakePrism(,,,canonicalize = true ) then all swept surfaces(walls) are forced to planes if possible
} else if (aSurface.IsKind("Geom_ElementarySurface")) {
// printf("INTER TYPE: Geom_ElementarySurface \n");
if (aSurface.IsKind("Geom_Plane")) {
// surfaceOut = surfaceWritePlane(aSurface);
} else {
// surfaceOut = {"TYPE": "UNKNOWN"};
}
} else if (aSurface.IsKind("Geom_SweptSurface")) {
// printf("INTER TYPE: Geom_SweptSurface \n");
// surfaceOut = {"TYPE": "SWEPT"};
} else if (aSurface.IsKind("Geom_OffsetSurface")) {
// printf("INTER TYPE: Geom_OffsetSurface \n");
// surfaceOut = {"TYPE": "OFFSET"};
} else {
bb._face.surface = new BrepSurface(new NullSurface());
}
bb._face.surface = new BrepSurface(new NullSurface());
console.log("string tesselation");
let aLocation = new oc.TopLoc_Location_1();
let aTrHandler = oc.BRep_Tool.Triangulation(aFace, aLocation);
console.log("got triangles");
const aLocation = new oc.TopLoc_Location_1();
const locationTransformation = aLocation.Transformation();
const aTrHandler = oc.BRep_Tool.Triangulation(aFace, aLocation);
const tessOut = [];
const tessPoints = [];
if (!aTrHandler.IsNull()) {
const aTr = aTrHandler.get();
const aNodes = aTr.Nodes();
const points = [];
for (let i = 0; i < aNodes.Length(); i++) {
let p = aNodes.Value(i + 1).Transformed(aLocation.Transformation());
points.push([p.X(), p.Y(), p.Z()]);
let p = aNodes.Value(i + 1).Transformed(locationTransformation);
tessPoints.push([p.X(), p.Y(), p.Z()]);
}
const triangles = aTr.Triangles();
const nnn = aTr.NbTriangles();
const isPlane = aSurface.IsKind("Geom_Plane");
for (let nt = 1; nt < nnn + 1; nt++) {
// takes the node indices of each triangle in n1,n2,n3:
@ -80,9 +55,9 @@ export function occ2brep(aShape: any, oc: any) {
let n2 = t.Value(2);
let n3 = t.Value(3);
const aPnt1 = points[n1 - 1];
const aPnt2 = points[n2 - 1];
const aPnt3 = points[n3 - 1];
const aPnt1 = tessPoints[n1 - 1];
const aPnt2 = tessPoints[n2 - 1];
const aPnt3 = tessPoints[n3 - 1];
const def = [];
@ -93,13 +68,11 @@ export function occ2brep(aShape: any, oc: any) {
def.push(tr);
if (!isPlane) {
// const norms = [];
// norms.push(dirWrite(computeNormal(aTr->UVNode(n1), aSurface).Transformed(aLocation)));
// norms.push(dirWrite(computeNormal(aTr->UVNode(n2), aSurface).Transformed(aLocation)));
// norms.push(dirWrite(computeNormal(aTr->UVNode(n3), aSurface).Transformed(aLocation)));
// def.push(norms);
}
const norms = [];
norms.push(pntWrite(computeNormal(aTr.UVNode(n1), aSurface, oc).Transformed(locationTransformation)));
norms.push(pntWrite(computeNormal(aTr.UVNode(n2), aSurface, oc).Transformed(locationTransformation)));
norms.push(pntWrite(computeNormal(aTr.UVNode(n3), aSurface, oc).Transformed(locationTransformation)));
def.push(norms);
tessOut.push(def);
}
@ -108,105 +81,111 @@ export function occ2brep(aShape: any, oc: any) {
format: 'verbose',
data: normalizetessellationData(tessOut, inverted, null)
};
bb._face.data.externals = {
// bb._face.data.externals = {
// ref: ((std::uintptr_t)aFace.TShape().get())
}
// }
bb._face.data.occShape = aExpFace;
// bb._face.data.productionInfo = faceData.productionInfo;
}
// const edgeFaceMap = new oc.TopTools_IndexedDataMapOfShapeListOfShape();
// oc.TopExp_MapShapesAndAncestors(aShape, oc.TopAbs_ShapeEnum.TopAbs_EDGE, oc.TopAbs_ShapeEnum.TopAbs_FACE, edgeFaceMap);
//
// console.log(edgeFaceMap);
//BRepTools::OuterWire(face) - return outer wire for classification if needed
const wires = new oc.TopExp_Explorer_2(aFace, oc.TopAbs_ShapeEnum.TopAbs_WIRE, oc.TopAbs_ShapeEnum.TopAbs_SHAPE);
while (wires.More()) {
bb.loop();
bb.loop();
const wire = oc.TopoDS.Wire_1(wires.Current());
console.log("processing wires");
const wire = oc.TopoDS.Wire_1(wires.Current());
bb._loop.data.occShape = wire;
wires.Next();
const aExpEdge = new oc.BRepTools_WireExplorer_2(wire);
// const edgesOut = [];
while (aExpEdge.More()) {
const aEdge = oc.TopoDS.Edge_1(aExpEdge.Current());
aExpEdge.Next();
wires.Next();
const aExpEdge = new oc.BRepTools_WireExplorer_2(wire);
while (aExpEdge.More()) {
const aEdge = oc.TopoDS.Edge_1(aExpEdge.Current());
aExpEdge.Next();
if(aEdge.IsNull()) {
console.log("edge is null, skipping");
continue;
}
// const edgeOut = {};//edgeWrite(aEdge);
// if (!edgeOut.hasKey("a") || !edgeOut.hasKey("b")) {
// std::cout << "can't write edge, skipping" << std::endl;
// continue;
// }
// const edgeTessOut = Array();
// let a = vf.getData(edgeData.inverted ? edgeData.b : edgeData.a);
// let b = vf.getData(edgeData.inverted ? edgeData.a : edgeData.b);
// bb.edge(a, b, () => undefined, edgeData.inverted, edgeData.edgeRef);
// bb.lastHalfEdge.edge.data.tessellation = edgeData.tess;
// //todo: data should provide full externals object
// bb.lastHalfEdge.edge.data.externals = {
// ptr: edgeData.ptr
// };
const edgePolHandler = oc.BRep_Tool.PolygonOnTriangulation_1(aEdge, aTrHandler, aLocation);
if(!edgePolHandler.IsNull()) {
// const edgePol = edgePolHandler.get();
// const TColStd_Array1OfInteger& edgeIndices = edgePol->Nodes();
// for( Standard_Integer j = 1; j <= edgeIndices.Length(); j++ ) {
// gp_Pnt edgePoint = fPoints(edgeIndices(j));
// edgeTessOut.append(pntWrite(edgePoint));
// }
// const eNodes = edgePol.Nodes();
// const points = [];
// for (let i = 0; i < eNodes.Length(); i++) {
// let p = eNodes.Value(i + 1).Transformed(aLocation.Transformation());
// points.push([p.X(), p.Y(), p.Z()]);
// }
} else {
// Handle(Poly_PolygonOnTriangulation) pt;
// Handle(Poly_Triangulation) edgeTr;
// TopLoc_Location edgeLoc;
// BRep_Tool::PolygonOnTriangulation(aEdge, pt, edgeTr, edgeLoc);
// if(!pt.IsNull()) {
// const TColStd_Array1OfInteger& edgeIndices = pt->Nodes();
// const TColgp_Array1OfPnt& edgeNodes = edgeTr->Nodes();
// for( Standard_Integer j = 1; j <= edgeIndices.Length(); j++ ) {
// gp_Pnt edgePoint = edgeNodes(j).Transformed(edgeLoc);
// edgeTessOut.append(pntWrite(edgePoint));
// }
// }
// }
// if (!INTERROGATE_STRUCT_ONLY) {
// edgeOut["tess"] = edgeTessOut;
if (aEdge.IsNull()) {
continue;
}
// TopoDS_Edge* persistEdge = new TopoDS_Edge(aEdge);
// edgeOut["ptr"] = ((std::uintptr_t)persistEdge);
// edgeOut["edgeRef"] = edgeFaceMap.FindIndex(aEdge);
// edgesOut.append(edgeOut);
const edgeKey = occShapeKey(aEdge);
const ex = new oc.TopExp_Explorer_2(aEdge, oc.TopAbs_ShapeEnum.TopAbs_VERTEX, oc.TopAbs_ShapeEnum.TopAbs_SHAPE);
let vertexA = null;
let vertexB = null;
for (; ex.More(); ex.Next()) {
const vertex = oc.TopoDS.Vertex_1(ex.Current());
if (vertexA === null) {
vertexA = vertex;
} else {
vertexB = vertex;
}
}
const getVertex = occVertex => {
const pnt = oc.BRep_Tool.Pnt(occVertex);
const vertex = vf.getData(pntWrite(pnt));
vertex.data.occShape = occVertex;
return vertex;
};
bb.edge(getVertex(vertexA), getVertex(vertexB), () => undefined, false, edgeKey);
const edgeTessOut = [];
const edgePolHandler = oc.BRep_Tool.PolygonOnTriangulation_1(aEdge, aTrHandler, aLocation);
if (!edgePolHandler.IsNull()) {
const edgePol = edgePolHandler.get();
const edgeIndices = edgePol.Nodes();
for (let i = 0; i < edgeIndices.Length(); i++) {
edgeTessOut.push(tessPoints[edgeIndices.Value(i + 1) - 1]);
}
}
bb.lastHalfEdge.data.occShape = aEdge;
bb.lastHalfEdge.edge.data.tessellation = edgeTessOut;
}
// loopsOut.append(edgesOut);
}
// if (model != NULL) {
// if (model->hasData(aFace)) {
// faceOut["productionInfo"] = model->getData(aFace);
// }
// }
// faceOut["ref"] = ((std::uintptr_t)aFace.TShape().get());
// if (model != NULL) {
// if (model->hasData(aFace)) {
// faceOut["productionInfo"] = model->getData(aFace);
// }
// }
// faceOut["ref"] = ((std::uintptr_t)aFace.TShape().get());
}
}
return bb.build();;
return bb.build();
}
// function edgeWrite(edge, oc) {
//
// // returns the 3d curve of the edge and the parameter range
// const ex = new oc.TopExp_Explorer_2(edge, oc.TopAbs_ShapeEnum.TopAbs_VERTEX, oc.TopAbs_ShapeEnum.TopAbs_SHAPE);
// let a = null;
// let b = null;
// for (; ex.More(); ex.Next()) {
// const vertex = oc.TopoDS.Vertex_1(ex.Current());
// console.log("processing vertex " + vertex);
// const pnt = oc.BRep_Tool.Pnt(vertex);
// const out = pntWrite(pnt);
// console.log("got point", out);
// if (a === null) {
// a = out;
// } else {
// b = out;
// }
// }
//
// return {a, b};
// }
// function readBrep(data: BrepOutputData) {
// let bb = new BrepBuilder();
@ -256,3 +235,19 @@ export function occ2brep(aShape: any, oc: any) {
// };
// return bb.build();
// }
function computeNormal(aUVNode, aSurface, oc) {
const aDummyPnt = new oc.gp_Pnt_1();
const aV1 = new oc.gp_Vec_1();
const aV2 = new oc.gp_Vec_1();
aSurface.D1(aUVNode.X(), aUVNode.Y(), aDummyPnt, aV1, aV2);
const aNormal = aV1.Crossed(aV2);
aNormal.Multiply (1 / aNormal.Magnitude());
return aNormal;
}
export function occShapeKey(occShape: OCCShape) {
return occShape.TShape_1().get().$$.ptr;
}
const pntWrite = p => [p.X(), p.Y(), p.Z()];