Conditionally sew faces based on detection of shared edges

This commit is contained in:
Thomas Krijnen
2019-02-12 13:59:49 +01:00
parent 826752ca6c
commit 68151b970a
+51 -16
View File
@@ -101,6 +101,7 @@
#include <ShapeFix_Shape.hxx> #include <ShapeFix_Shape.hxx>
#include <ShapeFix_ShapeTolerance.hxx> #include <ShapeFix_ShapeTolerance.hxx>
#include <ShapeFix_Solid.hxx> #include <ShapeFix_Solid.hxx>
#include <ShapeFix_Shell.hxx>
#include <ShapeAnalysis_Curve.hxx> #include <ShapeAnalysis_Curve.hxx>
#include <ShapeAnalysis_Wire.hxx> #include <ShapeAnalysis_Wire.hxx>
@@ -365,30 +366,64 @@ bool IfcGeom::Kernel::create_solid_from_faces(const TopTools_ListOfShape& face_l
TopTools_ListIteratorOfListOfShape face_iterator; TopTools_ListIteratorOfListOfShape face_iterator;
BRepOffsetAPI_Sewing builder; bool has_shared_edges = false;
builder.SetTolerance(getValue(GV_PRECISION)); TopTools_MapOfShape edge_set;
builder.SetMaxTolerance(getValue(GV_PRECISION));
builder.SetMinTolerance(getValue(GV_PRECISION));
for (face_iterator.Initialize(face_list); face_iterator.More(); face_iterator.Next()) { for (face_iterator.Initialize(face_list); face_iterator.More(); face_iterator.Next()) {
builder.Add(face_iterator.Value()); // As soon as is detected one of the edges is shared, the assumption is made no
// additional sewing is necessary.
if (!has_shared_edges) {
TopExp_Explorer exp(face_iterator.Value(), TopAbs_EDGE);
for (; exp.More(); exp.Next()) {
if (edge_set.Contains(exp.Current())) {
has_shared_edges = true;
break;
}
edge_set.Add(exp.Current());
}
}
}
BRepOffsetAPI_Sewing sewing_builder;
sewing_builder.SetTolerance(getValue(GV_PRECISION));
sewing_builder.SetMaxTolerance(getValue(GV_PRECISION));
sewing_builder.SetMinTolerance(getValue(GV_PRECISION));
BRep_Builder builder;
TopoDS_Shell shell;
builder.MakeShell(shell);
for (face_iterator.Initialize(face_list); face_iterator.More(); face_iterator.Next()) {
if (has_shared_edges) {
builder.Add(shell, face_iterator.Value());
} else {
sewing_builder.Add(face_iterator.Value());
}
} }
try { try {
builder.Perform(); if (has_shared_edges) {
shape = builder.SewedShape(); ShapeFix_Shell fix;
fix.FixFaceOrientation(shell);
{ shape = fix.Shape();
BRepCheck_Analyzer ana(shape); } else {
if (!ana.IsValid()) { sewing_builder.Perform();
ShapeFix_Shape sfs(shape); shape = sewing_builder.SewedShape();
sfs.Perform();
shape = sfs.Shape();
}
} }
BRepCheck_Analyzer ana(shape); BRepCheck_Analyzer ana(shape);
valid_shell = ana.IsValid() != 0 && count(shape, TopAbs_SHELL) > 0; valid_shell = ana.IsValid();
if (!valid_shell) {
ShapeFix_Shape sfs(shape);
sfs.Perform();
shape = sfs.Shape();
BRepCheck_Analyzer reana(shape);
valid_shell = reana.IsValid();
}
valid_shell &= count(shape, TopAbs_SHELL) > 0;
} catch (const Standard_Failure& e) { } catch (const Standard_Failure& e) {
if (e.GetMessageString() && strlen(e.GetMessageString())) { if (e.GetMessageString() && strlen(e.GetMessageString())) {
Logger::Error(e.GetMessageString()); Logger::Error(e.GetMessageString());