diff --git a/src/ifcgeom/kernels/opencascade/OpenCascadeKernel.cpp b/src/ifcgeom/kernels/opencascade/OpenCascadeKernel.cpp index 42405a215b..c1ec1805fd 100644 --- a/src/ifcgeom/kernels/opencascade/OpenCascadeKernel.cpp +++ b/src/ifcgeom/kernels/opencascade/OpenCascadeKernel.cpp @@ -248,9 +248,8 @@ bool IfcGeom::OpenCascadeKernel::convert_openings(const IfcUtil::IfcBaseEntity* AbstractKernel::convert(op.first, opening_shapes); for (unsigned int i = 0; i < opening_shapes.size(); ++i) { - TopoDS_Shape opening_shape_solid; auto opening_shape_i = std::static_pointer_cast(opening_shapes[i].Shape())->shape(); - const TopoDS_Shape& opening_shape_unlocated = util::ensure_fit_for_subtraction(opening_shape_i, opening_shape_solid, settings_.get().get()); + const TopoDS_Shape& opening_shape_unlocated = util::ensure_fit_for_subtraction(opening_shape_i, settings_.get().get()); auto gtrsf = opening_shapes[i].Placement(); // @todo check @@ -306,13 +305,11 @@ bool IfcGeom::OpenCascadeKernel::convert_openings(const IfcUtil::IfcBaseEntity* TopoDS_Shape entity_part_result; for (int as_shell = 0; as_shell < 2; ++as_shell) { - - TopoDS_Shape entity_shape_solid; TopoDS_Shape entity_shape_unlocated; if (as_shell) { entity_shape_unlocated = entity_part; } else { - entity_shape_unlocated = util::ensure_fit_for_subtraction(entity_part, entity_shape_solid, settings_.get().get()); + entity_shape_unlocated = util::ensure_fit_for_subtraction(entity_part, settings_.get().get()); } const auto& m = it3->Placement()->ccomponents(); // @todo diff --git a/src/ifcgeom/kernels/opencascade/base_utils.cpp b/src/ifcgeom/kernels/opencascade/base_utils.cpp index e05dc4884d..7f56792d14 100644 --- a/src/ifcgeom/kernels/opencascade/base_utils.cpp +++ b/src/ifcgeom/kernels/opencascade/base_utils.cpp @@ -762,7 +762,7 @@ bool IfcGeom::util::create_solid_from_faces(const TopTools_ListOfShape& face_lis return valid_shell; } -bool IfcGeom::util::flatten_shape_list(const IfcGeom::ConversionResults& shapes, TopoDS_Shape& result, bool fuse, double tol) { +bool IfcGeom::util::flatten_shape_list(const IfcGeom::ConversionResults& shapes, TopoDS_Shape& result, bool fuse, bool create_shell, double tol) { TopoDS_Compound compound; BRep_Builder builder; builder.MakeCompound(compound); @@ -772,8 +772,8 @@ bool IfcGeom::util::flatten_shape_list(const IfcGeom::ConversionResults& shapes, for (IfcGeom::ConversionResults::const_iterator it = shapes.begin(); it != shapes.end(); ++it) { TopoDS_Shape merged; const TopoDS_Shape& s = std::static_pointer_cast(it->Shape())->shape(); - if (fuse) { - util::ensure_fit_for_subtraction(s, merged, tol); + if (fuse || create_shell) { + merged = util::ensure_fit_for_subtraction(s, tol); } else { merged = s; } diff --git a/src/ifcgeom/kernels/opencascade/base_utils.h b/src/ifcgeom/kernels/opencascade/base_utils.h index 23905f5f31..017262c179 100644 --- a/src/ifcgeom/kernels/opencascade/base_utils.h +++ b/src/ifcgeom/kernels/opencascade/base_utils.h @@ -73,7 +73,7 @@ namespace IfcGeom { TopoDS_Shape apply_transformation(const TopoDS_Shape&, const gp_Trsf&); TopoDS_Shape apply_transformation(const TopoDS_Shape&, const gp_GTrsf&); - bool flatten_shape_list(const IfcGeom::ConversionResults& shapes, TopoDS_Shape& result, bool fuse, double tol); + bool flatten_shape_list(const IfcGeom::ConversionResults& shapes, TopoDS_Shape& result, bool fuse, bool create_shell, double tol); bool validate_shape(const TopoDS_Shape&); } } diff --git a/src/ifcgeom/kernels/opencascade/boolean_result.cpp b/src/ifcgeom/kernels/opencascade/boolean_result.cpp index 83e4253102..d934ddf4fc 100644 --- a/src/ifcgeom/kernels/opencascade/boolean_result.cpp +++ b/src/ifcgeom/kernels/opencascade/boolean_result.cpp @@ -98,7 +98,7 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::boolean_result::ptr br, Con AbstractKernel::convert(c, cr); if (first && br->operation == taxonomy::boolean_result::SUBTRACTION) { // @todo A will be null on union/intersection, intended? - IfcGeom::util::flatten_shape_list(cr, a, false, settings_.get().get()); + IfcGeom::util::flatten_shape_list(cr, a, false, true, settings_.get().get()); first_item_style = c->surface_style; if (!first_item_style && c->kind() == taxonomy::COLLECTION) { // @todo recursively right? @@ -144,6 +144,8 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::boolean_result::ptr br, Con } else { S = result; } + } else { + S = util::ensure_fit_for_subtraction(S, tol); } b.Append(S); diff --git a/src/ifcgeom/kernels/opencascade/boolean_utils.cpp b/src/ifcgeom/kernels/opencascade/boolean_utils.cpp index 8fba911b6f..9347dec615 100644 --- a/src/ifcgeom/kernels/opencascade/boolean_utils.cpp +++ b/src/ifcgeom/kernels/opencascade/boolean_utils.cpp @@ -1430,14 +1430,15 @@ bool IfcGeom::util::boolean_operation(const boolean_settings& settings, const To return boolean_operation(settings, a, bs, op, result, fuzziness); } -const TopoDS_Shape& IfcGeom::util::ensure_fit_for_subtraction(const TopoDS_Shape& shape, TopoDS_Shape& solid, double tol) { +TopoDS_Shape IfcGeom::util::ensure_fit_for_subtraction(const TopoDS_Shape& shape, double tol) { const bool is_comp = is_compound(shape); if (!is_comp) { - return solid = shape; + return shape; } + TopoDS_Solid solid; if (!create_solid_from_compound(shape, solid, tol)) { - return solid = shape; + return shape; } return solid; diff --git a/src/ifcgeom/kernels/opencascade/boolean_utils.h b/src/ifcgeom/kernels/opencascade/boolean_utils.h index 3eda7f5c54..24b5d8587e 100644 --- a/src/ifcgeom/kernels/opencascade/boolean_utils.h +++ b/src/ifcgeom/kernels/opencascade/boolean_utils.h @@ -96,7 +96,7 @@ namespace IfcGeom { bool boolean_operation(const boolean_settings& settings, const TopoDS_Shape&, const TopoDS_Shape&, BOPAlgo_Operation, TopoDS_Shape&, double fuzziness = -1.); - const TopoDS_Shape& ensure_fit_for_subtraction(const TopoDS_Shape& shape, TopoDS_Shape& solid, double tol); + TopoDS_Shape ensure_fit_for_subtraction(const TopoDS_Shape& shape, double tol); } } diff --git a/src/ifcgeom/kernels/opencascade/layerset.cpp b/src/ifcgeom/kernels/opencascade/layerset.cpp index ceaaee4805..c80e4d9f60 100644 --- a/src/ifcgeom/kernels/opencascade/layerset.cpp +++ b/src/ifcgeom/kernels/opencascade/layerset.cpp @@ -167,7 +167,7 @@ namespace { bool IfcGeom::util::apply_folded_layerset(const ConversionResults& items, const std::vector< std::vector >& surfaces, const std::vector& styles, ConversionResults& result, double tol) { Bnd_Box bb; TopoDS_Shape input; - flatten_shape_list(items, input, false, tol); + flatten_shape_list(items, input, false, false, tol); typedef std::vector< std::vector > folded_surfaces_t; typedef std::vector< std::pair< TopoDS_Face, std::pair > > faces_with_mass_t; @@ -263,8 +263,7 @@ bool IfcGeom::util::apply_folded_layerset(const ConversionResults& items, const for (ConversionResults::const_iterator it = items.begin(); it != items.end(); ++it) { const TopoDS_Shape& s = std::static_pointer_cast(it->Shape())->shape(); - TopoDS_Solid sld; - ensure_fit_for_subtraction(s, sld, tol); + TopoDS_Shape sld = ensure_fit_for_subtraction(s, tol); std::vector slices; if (split(s, shells, tol, slices) && slices.size() == styles.size()) { @@ -335,8 +334,7 @@ bool IfcGeom::util::apply_layerset(const ConversionResults& items, const std::ve for (ConversionResults::const_iterator it = items.begin(); it != items.end(); ++it) { const TopoDS_Shape& s = std::static_pointer_cast(it->Shape())->shape(); - TopoDS_Solid sld; - ensure_fit_for_subtraction(s, sld, tol); + TopoDS_Shape sld = ensure_fit_for_subtraction(s, tol); TopTools_ListOfShape operands; for (unsigned i = 1; i < surfaces.size() - 1; ++i) {