diff --git a/src/ifcconvert/IfcConvert.cpp b/src/ifcconvert/IfcConvert.cpp index 292a0a4859..ee085eac2f 100644 --- a/src/ifcconvert/IfcConvert.cpp +++ b/src/ifcconvert/IfcConvert.cpp @@ -211,11 +211,6 @@ int main(int argc, char** argv) "Specifies whether to convert back geometrical output back to the " "unit of measure in which it is defined in the IFC file. Default is " "to use meters.") - ("sew-shells", - "Specifies whether to sew the faces of IfcConnectedFaceSets together. " - "This is a potentially time consuming operation, but guarantees a " - "consistent orientation of surface normals, even if the faces are not " - "properly oriented in the IFC file.") #if OCC_VERSION_HEX < 0x60900 // In Open CASCADE version prior to 6.9.0 boolean operations with multiple // arguments where not introduced yet and a work-around was implemented to @@ -360,7 +355,6 @@ int main(int argc, char** argv) const bool weld_vertices = vmap.count("weld-vertices") != 0; const bool use_world_coords = vmap.count("use-world-coords") != 0; const bool convert_back_units = vmap.count("convert-back-units") != 0; - const bool sew_shells = vmap.count("sew-shells") != 0; #if OCC_VERSION_HEX < 0x60900 const bool merge_boolean_operands = vmap.count("merge-boolean-operands") != 0; #endif @@ -558,7 +552,6 @@ int main(int argc, char** argv) settings.set(IfcGeom::IteratorSettings::APPLY_DEFAULT_MATERIALS, true); settings.set(IfcGeom::IteratorSettings::USE_WORLD_COORDS, use_world_coords); settings.set(IfcGeom::IteratorSettings::WELD_VERTICES, weld_vertices); - settings.set(IfcGeom::IteratorSettings::SEW_SHELLS, sew_shells); settings.set(IfcGeom::IteratorSettings::CONVERT_BACK_UNITS, convert_back_units); #if OCC_VERSION_HEX < 0x60900 settings.set(IfcGeom::IteratorSettings::FASTER_BOOLEANS, merge_boolean_operands); @@ -1117,7 +1110,6 @@ void fix_quantities(IfcParse::IfcFile& f, bool no_progress, bool quiet, bool std IfcGeom::IteratorSettings settings; settings.set(IfcGeom::IteratorSettings::USE_WORLD_COORDS, false); settings.set(IfcGeom::IteratorSettings::WELD_VERTICES, false); - settings.set(IfcGeom::IteratorSettings::SEW_SHELLS, true); settings.set(IfcGeom::IteratorSettings::CONVERT_BACK_UNITS, true); settings.set(IfcGeom::IteratorSettings::DISABLE_TRIANGULATION, true); diff --git a/src/ifcgeom/IfcGeom.h b/src/ifcgeom/IfcGeom.h index 4035c1c107..d75a448d30 100644 --- a/src/ifcgeom/IfcGeom.h +++ b/src/ifcgeom/IfcGeom.h @@ -248,7 +248,6 @@ public: setValue(GV_DEFLECTION_TOLERANCE, other.getValue(GV_DEFLECTION_TOLERANCE)); setValue(GV_WIRE_CREATION_TOLERANCE, other.getValue(GV_WIRE_CREATION_TOLERANCE)); setValue(GV_POINT_EQUALITY_TOLERANCE, other.getValue(GV_POINT_EQUALITY_TOLERANCE)); - setValue(GV_MAX_FACES_TO_SEW, other.getValue(GV_MAX_FACES_TO_SEW)); setValue(GV_LENGTH_UNIT, other.getValue(GV_LENGTH_UNIT)); setValue(GV_PLANEANGLE_UNIT, other.getValue(GV_PLANEANGLE_UNIT)); setValue(GV_PRECISION, other.getValue(GV_PRECISION)); diff --git a/src/ifcgeom/IfcGeomFaces.cpp b/src/ifcgeom/IfcGeomFaces.cpp index 7af92d2855..4d82409291 100644 --- a/src/ifcgeom/IfcGeomFaces.cpp +++ b/src/ifcgeom/IfcGeomFaces.cpp @@ -304,9 +304,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcFace* l, TopoDS_Shape& face) { const bool non_planar = mf->Error() == BRepBuilderAPI_NotPlanar; delete mf; - const bool sewing_shells = getValue(GV_MAX_FACES_TO_SEW) > -1; - - if (non_planar && sewing_shells && bounds->size() == 1 && face_surface.IsNull()) { + if (non_planar && bounds->size() == 1 && face_surface.IsNull()) { Logger::Message(Logger::LOG_ERROR, "Triangulating face boundary", bound); // When creating a solid, flatting the boundary only postpones the issue to diff --git a/src/ifcgeom/IfcGeomFunctions.cpp b/src/ifcgeom/IfcGeomFunctions.cpp index 13857c22c5..16691d49ed 100644 --- a/src/ifcgeom/IfcGeomFunctions.cpp +++ b/src/ifcgeom/IfcGeomFunctions.cpp @@ -363,15 +363,6 @@ bool IfcGeom::Kernel::create_solid_from_faces(const TopTools_ListOfShape& face_l return false; } - int max_faces = getValue(GV_MAX_FACES_TO_SEW); - if (max_faces == -1) { - max_faces = 1000; - } - - if (face_list.Extent() > max_faces) { - throw too_many_faces_exception(); - } - TopTools_ListIteratorOfListOfShape face_iterator; BRepOffsetAPI_Sewing builder; @@ -1087,9 +1078,6 @@ void IfcGeom::Kernel::setValue(GeomValue var, double value) { case GV_POINT_EQUALITY_TOLERANCE: point_equality_tolerance = value; break; - case GV_MAX_FACES_TO_SEW: - max_faces_to_sew = value; - break; case GV_LENGTH_UNIT: ifc_length_unit = value; break; @@ -1119,8 +1107,6 @@ double IfcGeom::Kernel::getValue(GeomValue var) const { return modelling_precision * modelling_precision / 2.; case GV_POINT_EQUALITY_TOLERANCE: return point_equality_tolerance; - case GV_MAX_FACES_TO_SEW: - return max_faces_to_sew; case GV_LENGTH_UNIT: return ifc_length_unit; break; diff --git a/src/ifcgeom/IfcGeomIteratorImplementation.h b/src/ifcgeom/IfcGeomIteratorImplementation.h index cc3e05fa57..98158c6475 100644 --- a/src/ifcgeom/IfcGeomIteratorImplementation.h +++ b/src/ifcgeom/IfcGeomIteratorImplementation.h @@ -706,7 +706,6 @@ namespace IfcGeom { unit_name = "METER"; unit_magnitude = 1.f; - kernel.setValue(IfcGeom::Kernel::GV_MAX_FACES_TO_SEW, settings.get(IteratorSettings::SEW_SHELLS) ? 1000 : -1); kernel.setValue(IfcGeom::Kernel::GV_DIMENSIONALITY, (settings.get(IteratorSettings::INCLUDE_CURVES) ? (settings.get(IteratorSettings::EXCLUDE_SOLIDS_AND_SURFACES) ? -1. : 0.) : +1.)); if (settings.get(IteratorSettings::BUILDING_LOCAL_PLACEMENT)) { diff --git a/src/ifcgeom/IfcGeomShapes.cpp b/src/ifcgeom/IfcGeomShapes.cpp index d1e80b870b..b854aedaec 100644 --- a/src/ifcgeom/IfcGeomShapes.cpp +++ b/src/ifcgeom/IfcGeomShapes.cpp @@ -595,10 +595,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcBooleanResult* l, TopoDS_Shape bool IfcGeom::Kernel::convert(const IfcSchema::IfcConnectedFaceSet* l, TopoDS_Shape& shape) { std::unique_ptr helper_scope; - - if (getValue(GV_MAX_FACES_TO_SEW) != -1) { - helper_scope.reset(new faceset_helper(this, l)); - } + helper_scope.reset(new faceset_helper(this, l)); IfcSchema::IfcFace::list::ptr faces = l->CfsFaces(); @@ -652,7 +649,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcConnectedFaceSet* l, TopoDS_Sh return false; } - if (face_list.Extent() > getValue(GV_MAX_FACES_TO_SEW) || !create_solid_from_faces(face_list, shape)) { + if (!create_solid_from_faces(face_list, shape)) { TopoDS_Compound compound; BRep_Builder builder; builder.MakeCompound(compound); @@ -1151,37 +1148,36 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcTriangulatedFaceSet* l, TopoDS bool valid_shell = false; - if (faces.size() < getValue(GV_MAX_FACES_TO_SEW)) { - BRepOffsetAPI_Sewing builder; - builder.SetTolerance(getValue(GV_POINT_EQUALITY_TOLERANCE)); - builder.SetMaxTolerance(getValue(GV_POINT_EQUALITY_TOLERANCE)); - builder.SetMinTolerance(getValue(GV_POINT_EQUALITY_TOLERANCE)); + // @todo Do this more efficiently by creating proper half-edge pairs. + BRepOffsetAPI_Sewing builder; + builder.SetTolerance(getValue(GV_POINT_EQUALITY_TOLERANCE)); + builder.SetMaxTolerance(getValue(GV_POINT_EQUALITY_TOLERANCE)); + builder.SetMinTolerance(getValue(GV_POINT_EQUALITY_TOLERANCE)); - for (std::vector::const_iterator it = faces.begin(); it != faces.end(); ++it) { - builder.Add(*it); - } + for (std::vector::const_iterator it = faces.begin(); it != faces.end(); ++it) { + builder.Add(*it); + } + try { + builder.Perform(); + shape = builder.SewedShape(); + valid_shell = BRepCheck_Analyzer(shape).IsValid(); + } catch(...) {} + + if (valid_shell) { try { - builder.Perform(); - shape = builder.SewedShape(); - valid_shell = BRepCheck_Analyzer(shape).IsValid(); + ShapeFix_Solid solid; + solid.LimitTolerance(getValue(GV_POINT_EQUALITY_TOLERANCE)); + TopoDS_Solid solid_shape = solid.SolidFromShell(TopoDS::Shell(shape)); + if (!solid_shape.IsNull()) { + try { + BRepClass3d_SolidClassifier classifier(solid_shape); + shape = solid_shape; + } catch (...) {} + } } catch(...) {} - - if (valid_shell) { - try { - ShapeFix_Solid solid; - solid.LimitTolerance(getValue(GV_POINT_EQUALITY_TOLERANCE)); - TopoDS_Solid solid_shape = solid.SolidFromShell(TopoDS::Shell(shape)); - if (!solid_shape.IsNull()) { - try { - BRepClass3d_SolidClassifier classifier(solid_shape); - shape = solid_shape; - } catch (...) {} - } - } catch(...) {} - } else { - Logger::Message(Logger::LOG_WARNING, "Failed to sew faceset:", l); - } + } else { + Logger::Message(Logger::LOG_WARNING, "Failed to sew faceset:", l); } if (!valid_shell) { diff --git a/src/ifcgeom/IfcGeomTree.h b/src/ifcgeom/IfcGeomTree.h index 8911183b58..d2acf71c33 100644 --- a/src/ifcgeom/IfcGeomTree.h +++ b/src/ifcgeom/IfcGeomTree.h @@ -262,7 +262,6 @@ namespace IfcGeom { IfcGeom::IteratorSettings settings_ = settings; settings_.set(IfcGeom::IteratorSettings::DISABLE_TRIANGULATION, true); settings_.set(IfcGeom::IteratorSettings::USE_WORLD_COORDS, true); - settings_.set(IfcGeom::IteratorSettings::SEW_SHELLS, true); IfcGeom::Iterator it(settings_, &f); diff --git a/src/ifcgeom_schema_agnostic/Kernel.h b/src/ifcgeom_schema_agnostic/Kernel.h index 338995d9d7..c924f8af6a 100644 --- a/src/ifcgeom_schema_agnostic/Kernel.h +++ b/src/ifcgeom_schema_agnostic/Kernel.h @@ -36,10 +36,6 @@ namespace IfcGeom { // Specifies the threshold distance under which cartesian points are deemed equal // Default: 0.00001m / 0.01mm GV_POINT_EQUALITY_TOLERANCE, - // Specifies maximum number of faces for a shell to be sewed. Sewing shells - // that consist of many faces is really detrimental for the performance. - // Default: 1000 - GV_MAX_FACES_TO_SEW, // The length unit used the creation of TopoDS_Shapes, primarily affects the // interpretation of IfcCartesianPoints and IfcVector magnitudes // DefaultL 1.0 diff --git a/src/ifcwrap/IfcGeomWrapper.i b/src/ifcwrap/IfcGeomWrapper.i index 6d63ca12c9..ce359b1708 100644 --- a/src/ifcwrap/IfcGeomWrapper.i +++ b/src/ifcwrap/IfcGeomWrapper.i @@ -289,7 +289,6 @@ struct ShapeRTTI : public boost::static_visitor IfcParse::IfcFile* file = instance->data().file; IfcGeom::Kernel kernel(file); - kernel.setValue(IfcGeom::Kernel::GV_MAX_FACES_TO_SEW, settings.get(IfcGeom::IteratorSettings::SEW_SHELLS) ? 1000 : -1); kernel.setValue(IfcGeom::Kernel::GV_DIMENSIONALITY, (settings.get(IfcGeom::IteratorSettings::INCLUDE_CURVES) ? (settings.get(IfcGeom::IteratorSettings::EXCLUDE_SOLIDS_AND_SURFACES) ? -1. : 0.) : +1.)); if (instance->declaration().is(Schema::IfcProduct::Class())) {