Fix face orientation in BuildFMap to change the original shape

This commit is contained in:
Matthias Hochsteger 2023-10-12 16:10:50 +02:00
parent 06d6780cc8
commit 20fd3af5b4
2 changed files with 38 additions and 17 deletions

View File

@ -16,6 +16,7 @@
#include <BOPAlgo_Builder.hxx>
#include <BRepBndLib.hxx>
#include <BRepBuilderAPI_Copy.hxx>
#include <BRepBuilderAPI_MakeSolid.hxx>
#include <BRepBuilderAPI_MakeVertex.hxx>
#include <BRepCheck_Analyzer.hxx>
@ -71,6 +72,15 @@ namespace netgen
void LoadOCCInto(OCCGeometry* occgeo, const filesystem::path & filename);
void PrintContents (OCCGeometry * geom);
// Utility function to apply builder and propagate properties
template <typename T>
static TopoDS_Shape Apply(T & builder, TopoDS_Shape & shape) {
auto newshape = builder->Apply(shape);
PropagateProperties(*builder, newshape);
return newshape;
};
TopTools_IndexedMapOfShape OCCGeometry::global_shape_property_indices;
std::vector<ShapeProperties> OCCGeometry::global_shape_properties;
TopTools_IndexedMapOfShape OCCGeometry::global_identification_indices;
@ -435,12 +445,6 @@ namespace netgen
TopExp_Explorer exp0;
TopExp_Explorer exp1;
const auto Apply = [](auto & rebuild, auto & shape) {
auto newshape = rebuild->Apply(shape);
PropagateProperties(*rebuild, newshape);
return newshape;
};
for (exp0.Init(shape, TopAbs_COMPOUND); exp0.More(); exp0.Next()) nrc++;
for (exp0.Init(shape, TopAbs_COMPSOLID); exp0.More(); exp0.Next()) nrcs++;
@ -907,6 +911,30 @@ namespace netgen
}
// For 2d geometries, make sure all faces have a normal vector with positive z-component
void OCCGeometry :: FixFaceOrientation()
{
if(dimension!=2) return;
bool needs_fix = false;
Handle(ShapeBuild_ReShape) rebuild = new ShapeBuild_ReShape;
for (auto face : GetFaces(shape))
{
auto occface = OCCFace(face);
auto normal = occface.GetNormal(occ2ng(GetVertices(face)[0]));
if(normal[2] < 0) {
needs_fix = true;
// Need do copy the face, otherwise replace is ignored
BRepBuilderAPI_Copy copy(face);
auto newface = copy.Shape().Reversed();
GetProperties(newface).Merge(GetProperties(face));
rebuild->Replace(face, newface);
}
}
if(needs_fix )
shape = Apply(rebuild, shape);
}
void OCCGeometry :: BuildFMap()
{
@ -919,6 +947,9 @@ namespace netgen
TopExp_Explorer exp0, exp1, exp2, exp3, exp4, exp5;
// Check face orientation in 2d geometries
FixFaceOrientation();
for (exp0.Init(shape, TopAbs_COMPOUND);
exp0.More(); exp0.Next())
{
@ -992,15 +1023,6 @@ namespace netgen
}
}
auto fixFaceOrientation = [=] (TopoDS_Shape & face)
{
if(dimension != 2) return;
auto occface = OCCFace(face);
auto normal = occface.GetNormal(occ2ng(GetVertices(face)[0]));
if(normal[2] < 0)
face.Reverse();
};
// Free Shells
for (exp1.Init(shape, TopAbs_SHELL, TopAbs_SOLID); exp1.More(); exp1.Next())
{
@ -1018,7 +1040,6 @@ namespace netgen
TopoDS_Face face = TopoDS::Face(exp2.Current());
if (fmap.FindIndex(face) < 1)
{
fixFaceOrientation(face);
fmap.Add (face);
for (exp3.Init(face, TopAbs_WIRE); exp3.More(); exp3.Next())
@ -1054,7 +1075,6 @@ namespace netgen
for (auto face : MyExplorer(shape, TopAbs_FACE, TopAbs_SHELL))
if (!fmap.Contains(face))
{
fixFaceOrientation(face);
fmap.Add (face);
for (auto wire : MyExplorer(face, TopAbs_WIRE))
if (!wmap.Contains(wire))

View File

@ -315,6 +315,7 @@ namespace netgen
Array<const GeometryVertex*> GetFaceVertices(const GeometryFace& face) const override;
void FixFaceOrientation();
void HealGeometry();
void GlueGeometry();