mirror of
https://github.com/xibyte/jsketcher
synced 2025-12-09 18:02:50 +01:00
edges and normals using opencascade.js
This commit is contained in:
parent
c107f6148f
commit
705b86cdde
4 changed files with 197 additions and 166 deletions
|
|
@ -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) {
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
export class TopoObject {
|
||||
|
||||
data: {};
|
||||
data: any;
|
||||
op: OperationTemporaryData;
|
||||
|
||||
constructor() {
|
||||
|
|
|
|||
36
web/app/cad/occ/entityIdentity.ts
Normal file
36
web/app/cad/occ/entityIdentity.ts
Normal 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;
|
||||
|
|
@ -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()];
|
||||
Loading…
Reference in a new issue