mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-17 22:11:36 +00:00
Conditionally sew faces based on detection of shared edges
This commit is contained in:
@@ -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());
|
||||||
|
|||||||
Reference in New Issue
Block a user