]> SALOME platform Git repositories - tools/sat_salome.git/commitdiff
Salome HOME
added patches for IfcOpenShell and sbim_smodule
authormbs <martin.bernhard@opencascade.com>
Mon, 26 Jun 2023 21:06:07 +0000 (22:06 +0100)
committermbs <martin.bernhard@opencascade.com>
Mon, 26 Jun 2023 21:06:07 +0000 (22:06 +0100)
products/compil_scripts/IfcOpenShell.sh
products/patches/IfcOpenShell.patch [new file with mode: 0755]
products/patches/IfcOpenShell_EDF.patch [new file with mode: 0755]
products/patches/IfcOpenShell_OCC.patch [new file with mode: 0755]
products/patches/sbim_smodule.patch [new file with mode: 0644]

index 11c60e3f347608dec3cef0d976ff5cf2e4bdd2a2..912d8eeb9aa07b33946153f18b1e52f5fe677142 100755 (executable)
@@ -14,6 +14,7 @@ CMAKE_OPTIONS+=" -DCMAKE_PROGRAM_PATH=${PYTHON_ROOT_DIR}/bin"
 CMAKE_OPTIONS+=" -DCOLLADA_SUPPORT=OFF -DUNICODE_SUPPORT=OFF"
 CMAKE_OPTIONS+=" -DBUILD_SHARED_LIBS=ON"
 CMAKE_OPTIONS+=" -DCMAKE_INSTALL_PREFIX:STRING=${PRODUCT_INSTALL}"
+#CMAKE_OPTIONS+=" -DCMAKE_BUILD_TYPE=Debug"
 
 echo
 echo "*** cmake" ${CMAKE_OPTIONS}
diff --git a/products/patches/IfcOpenShell.patch b/products/patches/IfcOpenShell.patch
new file mode 100755 (executable)
index 0000000..ed95cb9
--- /dev/null
@@ -0,0 +1,587 @@
+diff --git a/src/ifcconvert/SvgSerializer.cpp b/src/ifcconvert/SvgSerializer.cpp
+index 0a895ff..91979dd 100644
+--- a/src/ifcconvert/SvgSerializer.cpp
++++ b/src/ifcconvert/SvgSerializer.cpp
+@@ -82,7 +82,7 @@ void SvgSerializer::write(path_object& p, const TopoDS_Wire& wire) {
+               Handle(Geom2d_Curve) curve2d;
+               if (curve.IsNull()) {
+                       TopLoc_Location loc;
+-                      Handle_Geom_Surface surf;
++                      Handle(Geom_Surface) surf;
+                       
+                       BRep_Tool::CurveOnSurface(edge, curve2d, surf, loc, u1, u2);
+                       
+diff --git a/src/ifcgeom/IfcGeom.h b/src/ifcgeom/IfcGeom.h
+index 88b05f0..c7979f3 100644
+--- a/src/ifcgeom/IfcGeom.h
++++ b/src/ifcgeom/IfcGeom.h
+@@ -179,12 +179,12 @@ public:
+       bool convert_openings(const IfcSchema::IfcProduct* entity, const IfcSchema::IfcRelVoidsElement::list::ptr& openings, const IfcRepresentationShapeItems& entity_shapes, const gp_Trsf& entity_trsf, IfcRepresentationShapeItems& cut_shapes);
+       bool convert_openings_fast(const IfcSchema::IfcProduct* entity, const IfcSchema::IfcRelVoidsElement::list::ptr& openings, const IfcRepresentationShapeItems& entity_shapes, const gp_Trsf& entity_trsf, IfcRepresentationShapeItems& cut_shapes);
+       
+-      bool convert_layerset(const IfcSchema::IfcProduct*, std::vector<Handle_Geom_Surface>&, std::vector<const SurfaceStyle*>&, std::vector<double>&);
+-      bool apply_layerset(const IfcRepresentationShapeItems&, const std::vector<Handle_Geom_Surface>&, const std::vector<const SurfaceStyle*>&, IfcRepresentationShapeItems&);
+-      bool apply_folded_layerset(const IfcRepresentationShapeItems&, const std::vector< std::vector<Handle_Geom_Surface> >&, const std::vector<const SurfaceStyle*>&, IfcRepresentationShapeItems&);
+-      bool fold_layers(const IfcSchema::IfcWall*, const IfcRepresentationShapeItems&, const std::vector<Handle_Geom_Surface>&, const std::vector<double>&, std::vector< std::vector<Handle_Geom_Surface> >&);
++      bool convert_layerset(const IfcSchema::IfcProduct*, std::vector<Handle(Geom_Surface)>&, std::vector<const SurfaceStyle*>&, std::vector<double>&);
++      bool apply_layerset(const IfcRepresentationShapeItems&, const std::vector<Handle(Geom_Surface)>&, const std::vector<const SurfaceStyle*>&, IfcRepresentationShapeItems&);
++      bool apply_folded_layerset(const IfcRepresentationShapeItems&, const std::vector< std::vector<Handle(Geom_Surface)> >&, const std::vector<const SurfaceStyle*>&, IfcRepresentationShapeItems&);
++      bool fold_layers(const IfcSchema::IfcWall*, const IfcRepresentationShapeItems&, const std::vector<Handle(Geom_Surface)>&, const std::vector<double>&, std::vector< std::vector<Handle(Geom_Surface)> >&);
+-      bool split_solid_by_surface(const TopoDS_Shape&, const Handle_Geom_Surface&, TopoDS_Shape&, TopoDS_Shape&);
++      bool split_solid_by_surface(const TopoDS_Shape&, const Handle(Geom_Surface)&, TopoDS_Shape&, TopoDS_Shape&);
+       bool split_solid_by_shell(const TopoDS_Shape&, const TopoDS_Shape& s, TopoDS_Shape&, TopoDS_Shape&);
+ #if OCC_VERSION_HEX < 0x60900
+@@ -195,16 +195,16 @@ public:
+       bool boolean_operation(const TopoDS_Shape&, const TopoDS_Shape&, BOPAlgo_Operation, TopoDS_Shape&, double fuzziness = -1.);
+ #endif
+-      const Handle_Geom_Curve intersect(const Handle_Geom_Surface&, const Handle_Geom_Surface&);
+-      const Handle_Geom_Curve intersect(const Handle_Geom_Surface&, const TopoDS_Face&);
+-      const Handle_Geom_Curve intersect(const TopoDS_Face&, const Handle_Geom_Surface&);
+-      bool intersect(const Handle_Geom_Curve&, const Handle_Geom_Surface&, gp_Pnt&);
+-      bool intersect(const Handle_Geom_Curve&, const TopoDS_Face&, gp_Pnt&);
+-      bool intersect(const Handle_Geom_Curve&, const TopoDS_Shape&, std::vector<gp_Pnt>&);
+-      bool intersect(const Handle_Geom_Surface&, const TopoDS_Shape&, std::vector< std::pair<Handle_Geom_Surface, Handle_Geom_Curve> >&);
++      const Handle(Geom_Curve) intersect(const Handle(Geom_Surface)&, const Handle(Geom_Surface)&);
++      const Handle(Geom_Curve) intersect(const Handle(Geom_Surface)&, const TopoDS_Face&);
++      const Handle(Geom_Curve) intersect(const TopoDS_Face&, const Handle(Geom_Surface)&);
++      bool intersect(const Handle(Geom_Curve)&, const Handle(Geom_Surface)&, gp_Pnt&);
++      bool intersect(const Handle(Geom_Curve)&, const TopoDS_Face&, gp_Pnt&);
++      bool intersect(const Handle(Geom_Curve)&, const TopoDS_Shape&, std::vector<gp_Pnt>&);
++      bool intersect(const Handle(Geom_Surface)&, const TopoDS_Shape&, std::vector< std::pair<Handle(Geom_Surface), Handle(Geom_Curve)> >&);
+       bool closest(const gp_Pnt&, const std::vector<gp_Pnt>&, gp_Pnt&);
+-      bool project(const Handle_Geom_Curve&, const gp_Pnt&, gp_Pnt& p, double& u, double& d);
+-      bool project(const Handle_Geom_Surface&, const TopoDS_Shape&, double& u1, double& v1, double& u2, double& v2, double widen=0.1);
++      bool project(const Handle(Geom_Curve)&, const gp_Pnt&, gp_Pnt& p, double& u, double& d);
++      bool project(const Handle(Geom_Surface)&, const TopoDS_Shape&, double& u1, double& v1, double& u2, double& v2, double widen=0.1);
+       static int count(const TopoDS_Shape&, TopAbs_ShapeEnum);
+       bool find_wall_end_points(const IfcSchema::IfcWall*, gp_Pnt& start, gp_Pnt& end);
+diff --git a/src/ifcgeom/IfcGeomFaces.cpp b/src/ifcgeom/IfcGeomFaces.cpp
+index b0ea4dd..5626864 100644
+--- a/src/ifcgeom/IfcGeomFaces.cpp
++++ b/src/ifcgeom/IfcGeomFaces.cpp
+@@ -344,7 +344,9 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcFace* l, TopoDS_Shape& face) {
+                                               TopTools_ListIteratorOfListOfShape it(shapes);
+                                               for (; it.More(); it.Next()) {
+                                                       // Apparently the wire got reversed, so register it with opposite orientation in the map
+-                                                      wire_senses.Bind(it.Value(), wire_senses.Find(w) == TopAbs_FORWARD ? TopAbs_REVERSED : TopAbs_FORWARD);
++                                                      Standard_Integer aValue;
++                                                      if (wire_senses.Find(w, aValue))
++                                                              wire_senses.Bind(it.Value(), wire_senses.Find(w) == TopAbs_FORWARD ? TopAbs_REVERSED : TopAbs_FORWARD);
+                                               }
+                                       }
+                               }
+@@ -1058,7 +1060,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcDerivedProfileDef* l, TopoDS_S
+ bool IfcGeom::Kernel::convert(const IfcSchema::IfcPlane* l, TopoDS_Shape& face) {
+       gp_Pln pln;
+       convert(l, pln);
+-      Handle_Geom_Surface surf = new Geom_Plane(pln);
++      Handle(Geom_Surface) surf = new Geom_Plane(pln);
+ #if OCC_VERSION_HEX < 0x60502
+       face = BRepBuilderAPI_MakeFace(surf);
+ #else
+@@ -1110,7 +1112,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcBSplineSurfaceWithKnots* l, To
+       for (std::vector<int>::const_iterator it = vmults.begin(); it != vmults.end(); ++it, ++i) {
+               VMults(i) = *it;
+       }
+-      Handle_Geom_Surface surf = new Geom_BSplineSurface(Poles, UKnots, VKnots, UMults, VMults, UDegree, VDegree);
++      Handle(Geom_Surface) surf = new Geom_BSplineSurface(Poles, UKnots, VKnots, UMults, VMults, UDegree, VDegree);
+ #if OCC_VERSION_HEX < 0x60502
+       face = BRepBuilderAPI_MakeFace(surf);
+diff --git a/src/ifcgeom/IfcGeomFunctions.cpp b/src/ifcgeom/IfcGeomFunctions.cpp
+index 099e4ec..a3ac68c 100644
+--- a/src/ifcgeom/IfcGeomFunctions.cpp
++++ b/src/ifcgeom/IfcGeomFunctions.cpp
+@@ -782,7 +782,7 @@ void IfcGeom::Kernel::apply_tolerance(TopoDS_Shape& s, double t) {
+       ShapeAnalysis_ShapeTolerance toler;
+       if (Logger::LOG_WARNING >= Logger::Verbosity()) {
+               if (toler.Tolerance(s, 0) > t * 10.) {
+-                      Handle_TopTools_HSequenceOfShape shapes = toler.OverTolerance(s, t * 10.);
++                      Handle(TopTools_HSequenceOfShape) shapes = toler.OverTolerance(s, t * 10.);
+                       for (int i = 1; i <= shapes->Length(); ++i) {
+                               const TopoDS_Shape& sub = shapes->Value(i);
+                               std::stringstream ss;
+@@ -1094,7 +1094,7 @@ bool IfcGeom::Kernel::wire_to_sequence_of_point(const TopoDS_Wire& w, TColgp_Seq
+       TopExp_Explorer exp(w, TopAbs_EDGE);
+       for (; exp.More(); exp.Next()) {
+               double a, b;
+-              Handle_Geom_Curve crv = BRep_Tool::Curve(TopoDS::Edge(exp.Current()), a, b);
++              Handle(Geom_Curve) crv = BRep_Tool::Curve(TopoDS::Edge(exp.Current()), a, b);
+               if (crv->DynamicType() != STANDARD_TYPE(Geom_Line)) {
+                       return false;
+               }
+@@ -1197,8 +1197,8 @@ IfcGeom::BRepElement<P>* IfcGeom::Kernel::create_brep_for_representation_and_pro
+               if (flatten_shape_list(shapes, merge, false)) {
+                       if (count(merge, TopAbs_FACE) > 0) {
+                               std::vector<double> thickness;
+-                              std::vector<Handle_Geom_Surface> layers;
+-                              std::vector< std::vector<Handle_Geom_Surface> > folded_layers;
++                              std::vector<Handle(Geom_Surface)> layers;
++                              std::vector< std::vector<Handle(Geom_Surface)> > folded_layers;
+                               std::vector<const SurfaceStyle*> styles;
+                               if (convert_layerset(product, layers, styles, thickness)) {
+@@ -1604,9 +1604,9 @@ std::pair<std::string, double> IfcGeom::Kernel::initializeUnits(IfcSchema::IfcUn
+       return std::pair<std::string, double>(unit_name, unit_magnitude);
+ }
+-bool IfcGeom::Kernel::convert_layerset(const IfcSchema::IfcProduct* product, std::vector<Handle_Geom_Surface>& surfaces, std::vector<const SurfaceStyle*>& styles, std::vector<double>& thicknesses) {
++bool IfcGeom::Kernel::convert_layerset(const IfcSchema::IfcProduct* product, std::vector<Handle(Geom_Surface)>& surfaces, std::vector<const SurfaceStyle*>& styles, std::vector<double>& thicknesses) {
+       IfcSchema::IfcMaterialLayerSetUsage* usage = 0;
+-      Handle_Geom_Surface reference_surface;
++      Handle(Geom_Surface) reference_surface;
+       IfcSchema::IfcRelAssociates::list::ptr associations = product->HasAssociations();
+       for (IfcSchema::IfcRelAssociates::list::it it = associations->begin(); it != associations->end(); ++it) {
+@@ -1653,14 +1653,14 @@ bool IfcGeom::Kernel::convert_layerset(const IfcSchema::IfcProduct* product, std
+               }
+               double u1, u2;
+-              Handle_Geom_Curve axis_curve = BRep_Tool::Curve(axis_edge, u1, u2);
++              Handle(Geom_Curve) axis_curve = BRep_Tool::Curve(axis_edge, u1, u2);
+               if (true) { /**< @todo Why always true? */
+                       if (axis_curve->DynamicType() == STANDARD_TYPE(Geom_Line)) {
+-                              Handle_Geom_Line axis_line = Handle_Geom_Line::DownCast(axis_curve);
++                              Handle(Geom_Line) axis_line = Handle(Geom_Line)::DownCast(axis_curve);
+                               reference_surface = new Geom_Plane(axis_line->Lin().Location(), axis_line->Lin().Direction() ^ gp::DZ());
+                       } else if (axis_curve->DynamicType() == STANDARD_TYPE(Geom_Circle)) {
+-                              Handle_Geom_Circle axis_line = Handle_Geom_Circle::DownCast(axis_curve);
++                              Handle(Geom_Circle) axis_line = Handle(Geom_Circle)::DownCast(axis_curve);
+                               reference_surface = new Geom_CylindricalSurface(axis_line->Position(), axis_line->Radius());
+                       } else {
+                               Logger::Message(Logger::LOG_ERROR, "Unsupported underlying curve of Axis representation:", product->entity);
+@@ -1739,24 +1739,24 @@ bool IfcGeom::Kernel::convert_layerset(const IfcSchema::IfcProduct* product, std
+       return true;
+ }
+-const Handle_Geom_Curve IfcGeom::Kernel::intersect(const Handle_Geom_Surface& a, const Handle_Geom_Surface& b) {
++const Handle(Geom_Curve) IfcGeom::Kernel::intersect(const Handle(Geom_Surface)& a, const Handle(Geom_Surface)& b) {
+       GeomAPI_IntSS x(a, b, 1.e-7);
+       if (x.IsDone() && x.NbLines() == 1) {
+               return x.Line(1);
+       } else {
+-              return Handle_Geom_Curve();
++              return Handle(Geom_Curve)();
+       }
+ }
+-const Handle_Geom_Curve IfcGeom::Kernel::intersect(const Handle_Geom_Surface& a, const TopoDS_Face& b) {
++const Handle(Geom_Curve) IfcGeom::Kernel::intersect(const Handle(Geom_Surface)& a, const TopoDS_Face& b) {
+       return intersect(a, BRep_Tool::Surface(b));
+ }
+-const Handle_Geom_Curve IfcGeom::Kernel::intersect(const TopoDS_Face& a, const Handle_Geom_Surface& b) {
++const Handle(Geom_Curve) IfcGeom::Kernel::intersect(const TopoDS_Face& a, const Handle(Geom_Surface)& b) {
+       return intersect(BRep_Tool::Surface(a), b);
+ }
+-bool IfcGeom::Kernel::intersect(const Handle_Geom_Curve& a, const Handle_Geom_Surface& b, gp_Pnt& p) {
++bool IfcGeom::Kernel::intersect(const Handle(Geom_Curve)& a, const Handle(Geom_Surface)& b, gp_Pnt& p) {
+       GeomAPI_IntCS x(a, b);
+       if (x.IsDone() && x.NbPoints() == 1) {
+               p = x.Point(1);
+@@ -1766,11 +1766,11 @@ bool IfcGeom::Kernel::intersect(const Handle_Geom_Curve& a, const Handle_Geom_Su
+       }
+ }
+-bool IfcGeom::Kernel::intersect(const Handle_Geom_Curve& a, const TopoDS_Face& b, gp_Pnt &c) {
++bool IfcGeom::Kernel::intersect(const Handle(Geom_Curve)& a, const TopoDS_Face& b, gp_Pnt &c) {
+       return intersect(a, BRep_Tool::Surface(b), c);
+ }
+-bool IfcGeom::Kernel::intersect(const Handle_Geom_Curve& a, const TopoDS_Shape& b, std::vector<gp_Pnt>& out) {
++bool IfcGeom::Kernel::intersect(const Handle(Geom_Curve)& a, const TopoDS_Shape& b, std::vector<gp_Pnt>& out) {
+       TopExp_Explorer exp(b, TopAbs_FACE);
+       gp_Pnt p;
+       for (; exp.More(); exp.Next()) {
+@@ -1781,12 +1781,12 @@ bool IfcGeom::Kernel::intersect(const Handle_Geom_Curve& a, const TopoDS_Shape&
+       return !out.empty();
+ }
+-bool IfcGeom::Kernel::intersect(const Handle_Geom_Surface& a, const TopoDS_Shape& b, std::vector< std::pair<Handle_Geom_Surface, Handle_Geom_Curve> >& out) {
++bool IfcGeom::Kernel::intersect(const Handle(Geom_Surface)& a, const TopoDS_Shape& b, std::vector< std::pair<Handle(Geom_Surface), Handle(Geom_Curve)> >& out) {
+       TopExp_Explorer exp(b, TopAbs_FACE);
+       for (; exp.More(); exp.Next()) {
+               const TopoDS_Face& f = TopoDS::Face(exp.Current());
+-              const Handle_Geom_Surface& s = BRep_Tool::Surface(f);
+-              Handle_Geom_Curve crv = intersect(a, s);
++              const Handle(Geom_Surface)& s = BRep_Tool::Surface(f);
++              Handle(Geom_Curve) crv = intersect(a, s);
+               if (!crv.IsNull()) {
+                       out.push_back(std::make_pair(s, crv));
+               }
+@@ -1806,7 +1806,7 @@ bool IfcGeom::Kernel::closest(const gp_Pnt& a, const std::vector<gp_Pnt>& b, gp_
+       return minimal_distance != std::numeric_limits<double>::infinity();
+ }
+-bool IfcGeom::Kernel::project(const Handle_Geom_Curve& crv, const gp_Pnt& pt, gp_Pnt& p, double& u, double& d) {
++bool IfcGeom::Kernel::project(const Handle(Geom_Curve)& crv, const gp_Pnt& pt, gp_Pnt& p, double& u, double& d) {
+       ShapeAnalysis_Curve sac;
+       sac.Project(crv, pt, 1e-3, p, u, false);
+       d = pt.Distance(p);
+@@ -1856,7 +1856,7 @@ bool IfcGeom::Kernel::find_wall_end_points(const IfcSchema::IfcWall* wall, gp_Pn
+       return true;
+ }
+-bool IfcGeom::Kernel::fold_layers(const IfcSchema::IfcWall* wall, const IfcRepresentationShapeItems& items, const std::vector<Handle_Geom_Surface>& surfaces, const std::vector<double>& thicknesses, std::vector< std::vector<Handle_Geom_Surface> >& result) {
++bool IfcGeom::Kernel::fold_layers(const IfcSchema::IfcWall* wall, const IfcRepresentationShapeItems& items, const std::vector<Handle(Geom_Surface)>& surfaces, const std::vector<double>& thicknesses, std::vector< std::vector<Handle(Geom_Surface)> >& result) {
+       bool folds_made = false;
+       
+       IfcSchema::IfcRelConnectsPathElements::list::ptr connections(new IfcSchema::IfcRelConnectsPathElements::list);
+@@ -1910,8 +1910,8 @@ bool IfcGeom::Kernel::fold_layers(const IfcSchema::IfcWall* wall, const IfcRepre
+       {
+               // Copy the unfolded surfaces
+               result.resize(surfaces.size());
+-              std::vector< std::vector<Handle_Geom_Surface> >::iterator result_it = result.begin() + 1;
+-              std::vector<Handle_Geom_Surface>::const_iterator input_it = surfaces.begin() + 1;
++              std::vector< std::vector<Handle(Geom_Surface)> >::iterator result_it = result.begin() + 1;
++              std::vector<Handle(Geom_Surface)>::const_iterator input_it = surfaces.begin() + 1;
+               for(; input_it != surfaces.end() - 1; ++result_it, ++input_it) {
+                       result_it->push_back(*input_it);
+               }
+@@ -2017,7 +2017,7 @@ bool IfcGeom::Kernel::fold_layers(const IfcSchema::IfcWall* wall, const IfcRepre
+               TopoDS_Shape body_shape;
+               flatten_shape_list(items, body_shape, false);
+-              Handle_Geom_Curve axis_curve;
++              Handle(Geom_Curve) axis_curve;
+               double axis_u1, axis_u2;
+                               
+               { 
+@@ -2065,7 +2065,7 @@ bool IfcGeom::Kernel::fold_layers(const IfcSchema::IfcWall* wall, const IfcRepre
+                       boost::optional<gp_Pnt> point_outside_param_range;
+                       //double param;
+                               
+-                      const Handle_Geom_Surface& surface = *jt;
++                      const Handle(Geom_Surface)& surface = *jt;
+                       GeomAPI_IntCS intersections(axis_curve, surface);
+                       if (intersections.IsDone() && intersections.NbPoints() == 1) {
+@@ -2087,22 +2087,22 @@ bool IfcGeom::Kernel::fold_layers(const IfcSchema::IfcWall* wall, const IfcRepre
+                               /*
+                               Is there a bug in Open Cascade related to the intersection
+                               of offset surfaces constructed from linear extrusions?
+-                              Handle_Geom_Surface xy = new Geom_Plane(gp::Origin(), gp::DZ());
+-                              // Handle_Geom_Surface yz = new Geom_Plane(gp::Origin(), gp::DX());
+-                              // Handle_Geom_Surface yz2 = new Geom_OffsetSurface(yz, 1.);
+-                              Handle_Geom_Curve ln = new Geom_Line(gp::Origin(), gp::DX());
+-                              Handle_Geom_Surface yz = new Geom_SurfaceOfLinearExtrusion(ln, gp::DZ());
+-                              Handle_Geom_Surface yz2 = new Geom_OffsetSurface(yz, 1.);
++                              Handle(Geom_Surface) xy = new Geom_Plane(gp::Origin(), gp::DZ());
++                              // Handle(Geom_Surface) yz = new Geom_Plane(gp::Origin(), gp::DX());
++                              // Handle(Geom_Surface) yz2 = new Geom_OffsetSurface(yz, 1.);
++                              Handle(Geom_Curve) ln = new Geom_Line(gp::Origin(), gp::DX());
++                              Handle(Geom_Surface) yz = new Geom_SurfaceOfLinearExtrusion(ln, gp::DZ());
++                              Handle(Geom_Surface) yz2 = new Geom_OffsetSurface(yz, 1.);
+                               intersect(xy, yz2);
+                               */
+                               
+-                              Handle_Geom_Surface plane = new Geom_Plane(*point_outside_param_range, gp::DZ());
++                              Handle(Geom_Surface) plane = new Geom_Plane(*point_outside_param_range, gp::DZ());
+                               curves_on_surfaces_t layer_ends;
+                               intersect(surface, body_shape, layer_ends);
+-                              Handle_Geom_Curve layer_body_intersection;
+-                              Handle_Geom_Surface body_surface;
++                              Handle(Geom_Curve) layer_body_intersection;
++                              Handle(Geom_Surface) body_surface;
+                               double mind = std::numeric_limits<double>::infinity();
+                               for (curves_on_surfaces_t::const_iterator kt = layer_ends.begin(); kt != layer_ends.end(); ++kt) {
+                                       gp_Pnt p;
+@@ -2127,7 +2127,7 @@ bool IfcGeom::Kernel::fold_layers(const IfcSchema::IfcWall* wall, const IfcRepre
+                                       const gp_Pnt& layer_end_point = intersection2.Point(1);
+                                       GeomAPI_IntSS intersection3(surface, plane, 1.e-7);
+                                       if (intersection3.IsDone() && intersection3.NbLines() == 1) {
+-                                              Handle_Geom_Curve layer_line = intersection3.Line(1);
++                                              Handle(Geom_Curve) layer_line = intersection3.Line(1);
+                                               GeomAdaptor_Curve layer_line_adaptor(layer_line);
+                                               ShapeAnalysis_Curve sac;
+                                               gp_Pnt layer_end_point_projected; double layer_end_point_param;
+@@ -2140,13 +2140,13 @@ bool IfcGeom::Kernel::fold_layers(const IfcSchema::IfcWall* wall, const IfcRepre
+                                                       
+                                                       GeomAPI_IntSS intersection4(body_surface, plane, 1.e-7);
+                                                       if (intersection4.IsDone() && intersection4.NbLines() == 1) {
+-                                                              Handle_Geom_Curve body_trim_curve = intersection4.Line(1);
++                                                              Handle(Geom_Curve) body_trim_curve = intersection4.Line(1);
+                                                               ShapeAnalysis_Curve sac2;
+                                                               gp_Pnt layer_fold_point_projected; double layer_fold_point_param;
+                                                               sac2.Project(body_trim_curve, layer_fold_point, 1.e-7, layer_fold_point_projected, layer_fold_point_param, false);
+-                                                              Handle_Geom_Curve fold_curve = new Geom_OffsetCurve(body_trim_curve->Reversed(), layer_fold_point_projected.Distance(layer_fold_point), gp::DZ());
++                                                              Handle(Geom_Curve) fold_curve = new Geom_OffsetCurve(body_trim_curve->Reversed(), layer_fold_point_projected.Distance(layer_fold_point), gp::DZ());
+-                                                              Handle_Geom_Surface fold_surface = new Geom_SurfaceOfLinearExtrusion(fold_curve, gp::DZ());
++                                                              Handle(Geom_Surface) fold_surface = new Geom_SurfaceOfLinearExtrusion(fold_curve, gp::DZ());
+                                                               result_vector->push_back(fold_surface);
+                                                               folds_made = true;
+                                                       }
+@@ -2162,7 +2162,7 @@ bool IfcGeom::Kernel::fold_layers(const IfcSchema::IfcWall* wall, const IfcRepre
+       return folds_made;
+ }
+-bool IfcGeom::Kernel::apply_folded_layerset(const IfcRepresentationShapeItems& items, const std::vector< std::vector<Handle_Geom_Surface> >& surfaces, const std::vector<const SurfaceStyle*>& styles, IfcRepresentationShapeItems& result) {
++bool IfcGeom::Kernel::apply_folded_layerset(const IfcRepresentationShapeItems& items, const std::vector< std::vector<Handle(Geom_Surface)> >& surfaces, const std::vector<const SurfaceStyle*>& styles, IfcRepresentationShapeItems& result) {
+       Bnd_Box bb;
+       TopoDS_Shape input;
+       flatten_shape_list(items, input, false);
+@@ -2180,7 +2180,7 @@ bool IfcGeom::Kernel::apply_folded_layerset(const IfcRepresentationShapeItems& i
+               if (it->empty()) {
+                       continue;
+               } else if (it->size() == 1) {
+-                      const Handle_Geom_Surface& surface = (*it)[0];
++                      const Handle(Geom_Surface)& surface = (*it)[0];
+                       double u1, v1, u2, v2;
+                       if (!project(surface, input, u1, v1, u2, v2)) {
+                               continue;
+@@ -2189,7 +2189,7 @@ bool IfcGeom::Kernel::apply_folded_layerset(const IfcRepresentationShapeItems& i
+               } else {
+                       faces_with_mass_t solids;               
+                       for (folded_surfaces_t::value_type::const_iterator jt = it->begin(); jt != it->end(); ++jt) {
+-                              const Handle_Geom_Surface& surface = *jt;
++                              const Handle(Geom_Surface)& surface = *jt;
+                               double u1, v1, u2, v2;
+                               if (!project(surface, input, u1, v1, u2, v2)) {
+                                       continue;
+@@ -2298,7 +2298,7 @@ bool IfcGeom::Kernel::apply_folded_layerset(const IfcRepresentationShapeItems& i
+ }
+-bool IfcGeom::Kernel::apply_layerset(const IfcRepresentationShapeItems& items, const std::vector<Handle_Geom_Surface>& surfaces, const std::vector<const SurfaceStyle*>& styles, IfcRepresentationShapeItems& result) {
++bool IfcGeom::Kernel::apply_layerset(const IfcRepresentationShapeItems& items, const std::vector<Handle(Geom_Surface)>& surfaces, const std::vector<const SurfaceStyle*>& styles, IfcRepresentationShapeItems& result) {
+       if (surfaces.size() < 3) {
+               return false;
+@@ -2401,7 +2401,7 @@ IfcSchema::IfcRepresentation* IfcGeom::Kernel::find_representation(const IfcSche
+       return 0;
+ }
+-bool IfcGeom::Kernel::split_solid_by_surface(const TopoDS_Shape& input, const Handle_Geom_Surface& surface, TopoDS_Shape& front, TopoDS_Shape& back) {
++bool IfcGeom::Kernel::split_solid_by_surface(const TopoDS_Shape& input, const Handle(Geom_Surface)& surface, TopoDS_Shape& front, TopoDS_Shape& back) {
+       // Use an unbounded surface, that isolate part of the input shape,
+       // to split this shape into two parts. Make sure that the addition
+       // of the two result volumes matches that of the input.
+@@ -2440,7 +2440,7 @@ bool IfcGeom::Kernel::split_solid_by_shell(const TopoDS_Shape& input, const Topo
+ #if OCC_VERSION_HEX >= 0x70300
+       TopTools_ListOfShape shapes;
+ #else
+-      BOPCol_ListOfShape shapes;
++      TopTools_ListOfShape shapes;
+ #endif
+       shapes.Append(input);
+       shapes.Append(solid);
+@@ -2493,7 +2493,7 @@ bool IfcGeom::Kernel::split_solid_by_shell(const TopoDS_Shape& input, const Topo
+       return ALMOST_THE_SAME(ab, a+b, 1.e-3);
+ }
+-bool IfcGeom::Kernel::project(const Handle_Geom_Surface& srf, const TopoDS_Shape& shp, double& u1, double& v1, double& u2, double& v2, double widen) {
++bool IfcGeom::Kernel::project(const Handle(Geom_Surface)& srf, const TopoDS_Shape& shp, double& u1, double& v1, double& u2, double& v2, double widen) {
+       ShapeAnalysis_Surface sas(srf);
+       u1 = v1 = +std::numeric_limits<double>::infinity();
+@@ -2523,7 +2523,7 @@ bool IfcGeom::Kernel::project(const Handle_Geom_Surface& srf, const TopoDS_Shape
+               const TopoDS_Edge& e = TopoDS::Edge(exp.Current());
+               
+               double a, b;
+-              Handle_Geom_Curve crv = BRep_Tool::Curve(e, a, b);
++              Handle(Geom_Curve) crv = BRep_Tool::Curve(e, a, b);
+               gp_Pnt p;
+               crv->D0((a + b) / 2., p);
+@@ -2719,7 +2719,7 @@ bool IfcGeom::Kernel::triangulate_wire(const TopoDS_Wire& wire, TopTools_ListOfS
+       int n123[3]; 
+       TopLoc_Location loc;
+-      Handle_Poly_Triangulation tri = BRep_Tool::Triangulation(face, loc);
++      Handle(Poly_Triangulation) tri = BRep_Tool::Triangulation(face, loc);
+       
+       if (!tri.IsNull()) {
+               const TColgp_Array1OfPnt& nodes = tri->Nodes();
+@@ -2931,7 +2931,7 @@ bool IfcGeom::Kernel::wire_intersections(const TopoDS_Wire& wire, TopTools_ListO
+                                                       // Substitute with a new edge from/to the intersection point
+                                                       if (p1.Distance(p2) > getValue(GV_PRECISION) * 2) {
+                                                               double _, __;
+-                                                              Handle_Geom_Curve crv = BRep_Tool::Curve(e, _, __);
++                                                              Handle(Geom_Curve) crv = BRep_Tool::Curve(e, _, __);
+                                                               BRepBuilderAPI_MakeEdge me(crv, p1, p2);
+                                                               TopoDS_Edge ed = me.Edge();
+                                                               mw.Add(ed);
+diff --git a/src/ifcgeom/IfcGeomRepresentation.h b/src/ifcgeom/IfcGeomRepresentation.h
+index fd9b5a2..6e3e8e7 100644
+--- a/src/ifcgeom/IfcGeomRepresentation.h
++++ b/src/ifcgeom/IfcGeomRepresentation.h
+@@ -173,7 +173,7 @@ namespace IfcGeom {
+                                       for ( exp.Init(s,TopAbs_FACE); exp.More(); exp.Next(), ++num_faces ) {
+                                               TopoDS_Face face = TopoDS::Face(exp.Current());
+                                               TopLoc_Location loc;
+-                                              Handle_Poly_Triangulation tri = BRep_Tool::Triangulation(face,loc);
++                                              Handle(Poly_Triangulation) tri = BRep_Tool::Triangulation(face,loc);
+                                               if ( ! tri.IsNull() ) {
+@@ -209,7 +209,7 @@ namespace IfcGeom {
+                                                                       if (normal_direction.Magnitude() > ALMOST_ZERO) {
+                                                                               normal = gp_Dir(normal_direction.XYZ() * rotation_matrix);
+                                                                       } else {
+-                                                                              Handle_Geom_Surface surf = BRep_Tool::Surface(face);
++                                                                              Handle(Geom_Surface) surf = BRep_Tool::Surface(face);
+                                                                               // Special case the normal at the poles of a spherical surface
+                                                                               if (surf->DynamicType() == STANDARD_TYPE(Geom_SphericalSurface)) {
+                                                                                       if (ALMOST_THE_SAME(fabs(uv.Y()), M_PI / 2.)) {
+diff --git a/src/ifcgeom/IfcGeomSerialisation.cpp b/src/ifcgeom/IfcGeomSerialisation.cpp
+index 20f82a9..495843e 100644
+--- a/src/ifcgeom/IfcGeomSerialisation.cpp
++++ b/src/ifcgeom/IfcGeomSerialisation.cpp
+@@ -86,12 +86,12 @@ IfcSchema::IfcKnotType::IfcKnotType opencascade_knotspec_to_ifc(GeomAbs_BSplKnot
+ #endif
+ template <>
+-int convert_to_ifc(const Handle_Geom_Curve& c, IfcSchema::IfcCurve*& curve, bool advanced) {
++int convert_to_ifc(const Handle(Geom_Curve)& c, IfcSchema::IfcCurve*& curve, bool advanced) {
+       if (c->DynamicType() == STANDARD_TYPE(Geom_Line)) {
+               IfcSchema::IfcDirection* d;
+               IfcSchema::IfcCartesianPoint* p;
+-              Handle_Geom_Line line = Handle_Geom_Line::DownCast(c);
++              Handle(Geom_Line) line = Handle(Geom_Line)::DownCast(c);
+               if (!convert_to_ifc(line->Position().Location(), p, advanced)) {
+                       return 0;
+@@ -107,7 +107,7 @@ int convert_to_ifc(const Handle_Geom_Curve& c, IfcSchema::IfcCurve*& curve, bool
+       } else if (c->DynamicType() == STANDARD_TYPE(Geom_Circle)) {
+               IfcSchema::IfcAxis2Placement3D* ax;
+-              Handle_Geom_Circle circle = Handle_Geom_Circle::DownCast(c);
++              Handle(Geom_Circle) circle = Handle(Geom_Circle)::DownCast(c);
+               convert_to_ifc(circle->Position(), ax, advanced);
+               curve = new IfcSchema::IfcCircle(ax, circle->Radius());
+@@ -116,7 +116,7 @@ int convert_to_ifc(const Handle_Geom_Curve& c, IfcSchema::IfcCurve*& curve, bool
+       } else if (c->DynamicType() == STANDARD_TYPE(Geom_Ellipse)) {
+               IfcSchema::IfcAxis2Placement3D* ax;
+-              Handle_Geom_Ellipse ellipse = Handle_Geom_Ellipse::DownCast(c);
++              Handle(Geom_Ellipse) ellipse = Handle(Geom_Ellipse)::DownCast(c);
+               convert_to_ifc(ellipse->Position(), ax, advanced);
+               curve = new IfcSchema::IfcEllipse(ax, ellipse->MajorRadius(), ellipse->MinorRadius());
+@@ -125,7 +125,7 @@ int convert_to_ifc(const Handle_Geom_Curve& c, IfcSchema::IfcCurve*& curve, bool
+       }
+ #ifdef USE_IFC4
+       else if (c->DynamicType() == STANDARD_TYPE(Geom_BSplineCurve)) {
+-              Handle_Geom_BSplineCurve bspline = Handle_Geom_BSplineCurve::DownCast(c);
++              Handle(Geom_BSplineCurve) bspline = Handle(Geom_BSplineCurve)::DownCast(c);
+               IfcSchema::IfcCartesianPoint::list::ptr points(new IfcSchema::IfcCartesianPoint::list);
+               TColgp_Array1OfPnt poles(1, bspline->NbPoles());
+@@ -195,9 +195,9 @@ int convert_to_ifc(const Handle_Geom_Curve& c, IfcSchema::IfcCurve*& curve, bool
+ }
+ template <>
+-int convert_to_ifc(const Handle_Geom_Surface& s, IfcSchema::IfcSurface*& surface, bool advanced) {
++int convert_to_ifc(const Handle(Geom_Surface)& s, IfcSchema::IfcSurface*& surface, bool advanced) {
+       if (s->DynamicType() == STANDARD_TYPE(Geom_Plane)) {
+-              Handle_Geom_Plane plane = Handle_Geom_Plane::DownCast(s);
++              Handle(Geom_Plane) plane = Handle(Geom_Plane)::DownCast(s);
+               IfcSchema::IfcAxis2Placement3D* place;
+               /// @todo: Note that the Ax3 is converted to an Ax2 here
+               if (!convert_to_ifc(plane->Position().Ax2(), place, advanced)) {
+@@ -208,7 +208,7 @@ int convert_to_ifc(const Handle_Geom_Surface& s, IfcSchema::IfcSurface*& surface
+       }
+ #ifdef USE_IFC4
+       else if (s->DynamicType() == STANDARD_TYPE(Geom_CylindricalSurface)) {
+-              Handle_Geom_CylindricalSurface cyl = Handle_Geom_CylindricalSurface::DownCast(s);
++              Handle(Geom_CylindricalSurface) cyl = Handle(Geom_CylindricalSurface)::DownCast(s);
+               IfcSchema::IfcAxis2Placement3D* place;
+               /// @todo: Note that the Ax3 is converted to an Ax2 here
+               if (!convert_to_ifc(cyl->Position().Ax2(), place, advanced)) {
+@@ -219,7 +219,7 @@ int convert_to_ifc(const Handle_Geom_Surface& s, IfcSchema::IfcSurface*& surface
+       } else if (s->DynamicType() == STANDARD_TYPE(Geom_BSplineSurface)) {
+               typedef IfcTemplatedEntityListList<IfcSchema::IfcCartesianPoint> points_t;
+-              Handle_Geom_BSplineSurface bspline = Handle_Geom_BSplineSurface::DownCast(s);
++              Handle(Geom_BSplineSurface) bspline = Handle(Geom_BSplineSurface)::DownCast(s);
+               points_t::ptr points(new points_t);
+               TColgp_Array2OfPnt poles(1, bspline->NbUPoles(), 1, bspline->NbVPoles());
+@@ -322,7 +322,7 @@ int convert_to_ifc(const TopoDS_Edge& e, IfcSchema::IfcCurve*& c, bool advanced)
+       double a, b;
+       IfcSchema::IfcCurve* base;
+-      Handle_Geom_Curve crv = BRep_Tool::Curve(e, a, b);
++      Handle(Geom_Curve) crv = BRep_Tool::Curve(e, a, b);
+       if (!convert_to_ifc(crv, base, advanced)) {
+               return 0;
+       }
+@@ -353,7 +353,7 @@ int convert_to_ifc(const TopoDS_Edge& e, IfcSchema::IfcEdge*& edge, bool advance
+               return 0;
+       }
+-      Handle_Geom_Curve crv = BRep_Tool::Curve(e, a, b);
++      Handle(Geom_Curve) crv = BRep_Tool::Curve(e, a, b);
+       if (crv.IsNull()) {
+               return 0;
+@@ -381,7 +381,7 @@ int convert_to_ifc(const TopoDS_Wire& wire, IfcSchema::IfcLoop*& loop, bool adva
+       bool polygonal = true;
+       for (TopExp_Explorer exp(wire, TopAbs_EDGE); exp.More(); exp.Next()) {
+               double a, b;
+-              Handle_Geom_Curve crv = BRep_Tool::Curve(TopoDS::Edge(exp.Current()), a, b);
++              Handle(Geom_Curve) crv = BRep_Tool::Curve(TopoDS::Edge(exp.Current()), a, b);
+               if (crv.IsNull()) {
+                       continue;
+               }
+@@ -428,7 +428,7 @@ int convert_to_ifc(const TopoDS_Wire& wire, IfcSchema::IfcLoop*& loop, bool adva
+ template <>
+ int convert_to_ifc(const TopoDS_Face& f, IfcSchema::IfcFace*& face, bool advanced) {
+-      Handle_Geom_Surface surf = BRep_Tool::Surface(f);
++      Handle(Geom_Surface) surf = BRep_Tool::Surface(f);
+       TopExp_Explorer exp(f, TopAbs_WIRE);
+       IfcSchema::IfcFaceBound::list::ptr bounds(new IfcSchema::IfcFaceBound::list);
+       int index = 0;
+diff --git a/src/ifcgeom/IfcGeomShapes.cpp b/src/ifcgeom/IfcGeomShapes.cpp
+index b3c0901..2742726 100644
+--- a/src/ifcgeom/IfcGeomShapes.cpp
++++ b/src/ifcgeom/IfcGeomShapes.cpp
+@@ -445,8 +445,8 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcPolygonalBoundedHalfSpace* l,
+               sequence_of_point_to_wire(points, wire, wire.Closed() != 0);
+       }
+-      TopoDS_Shape prism = BRepPrimAPI_MakePrism(BRepBuilderAPI_MakeFace(wire),gp_Vec(0,0,200));
+-      gp_Trsf down; down.SetTranslation(gp_Vec(0,0,-100.0));
++      TopoDS_Shape prism = BRepPrimAPI_MakePrism(BRepBuilderAPI_MakeFace(wire),gp_Vec(0, 0, 200*getValue(GV_LENGTH_UNIT)));
++      gp_Trsf down; down.SetTranslation(gp_Vec(0, 0, -100.0*getValue(GV_LENGTH_UNIT)));
+       
+       // `trsf` and `down` both have a unit scale factor
+       prism.Move(trsf*down);  
+diff --git a/src/ifcgeom/IfcGeomWires.cpp b/src/ifcgeom/IfcGeomWires.cpp
+index d6f6b63..f6338e8 100644
+--- a/src/ifcgeom/IfcGeomWires.cpp
++++ b/src/ifcgeom/IfcGeomWires.cpp
+@@ -582,7 +582,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcEdgeCurve* l, TopoDS_Wire& res
+       }
+       
+       BRepBuilderAPI_MakeWire mw;
+-      Handle_Geom_Curve crv;
++      Handle(Geom_Curve) crv;
+       // The lack of a clear separation between topological and geometrical entities
+       // is starting to get problematic. If the underlying curve is bounded it is
+diff --git a/src/ifcwrap/CMakeLists.txt b/src/ifcwrap/CMakeLists.txt
+index 2401b8d..93417d6 100644
+--- a/src/ifcwrap/CMakeLists.txt
++++ b/src/ifcwrap/CMakeLists.txt
+@@ -75,6 +75,8 @@ IF(PYTHONINTERP_FOUND AND NOT "${PYTHON_EXECUTABLE}" STREQUAL "")
+         OUTPUT_VARIABLE python_package_dir
+     )
++    SET(python_package_dir lib/python)
++
+     IF("${python_package_dir}" STREQUAL "")
+         MESSAGE(WARNING "Unable to locate Python site-package directory, unable to install the Python wrapper")
+     ELSE()
diff --git a/products/patches/IfcOpenShell_EDF.patch b/products/patches/IfcOpenShell_EDF.patch
new file mode 100755 (executable)
index 0000000..1269676
--- /dev/null
@@ -0,0 +1,21 @@
+diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
+index b157cd5..6882bb2 100644
+--- a/cmake/CMakeLists.txt
++++ b/cmake/CMakeLists.txt
+@@ -435,9 +435,15 @@ function(files_for_ifc_version IFC_VERSION RESULT_NAME)
+     )
+ endfunction()
++# GBO warning: We force the detection of python interp at this step instead of
++# in src/ifcwrap/CMakeListes.txt, to be sure that the SALOME python is used
++SET(PythonInterp_FIND_VERSION 3)
++SET(PythonInterp_FIND_VERSION_MAJOR 3)
++find_package(PythonInterp)
++
+ if(COMPILE_SCHEMA)
+     find_package(PythonInterp)
+-    
++
+     IF(NOT PYTHONINTERP_FOUND)
+         MESSAGE(FATAL_ERROR "A Python interpreter is necessary when COMPILE_SCHEMA is enabled. Disable COMPILE_SCHEMA or fix Python paths to proceed.")
+     ENDIF()
diff --git a/products/patches/IfcOpenShell_OCC.patch b/products/patches/IfcOpenShell_OCC.patch
new file mode 100755 (executable)
index 0000000..610dbaa
--- /dev/null
@@ -0,0 +1,217 @@
+diff --git a/src/ifcgeom/IfcGeomFunctions.cpp b/src/ifcgeom/IfcGeomFunctions.cpp
+index a3ac68c..fc988bd 100644
+--- a/src/ifcgeom/IfcGeomFunctions.cpp
++++ b/src/ifcgeom/IfcGeomFunctions.cpp
+@@ -145,7 +145,7 @@
+ #ifdef _MSC_VER
+ #pragma message("warning: You are linking against Open CASCADE version " OCC_VERSION_COMPLETE ". Version 6.9.0 introduces various improvements with relation to boolean operations. You are advised to upgrade.")
+ #else
+-#warning "You are linking against linking against an older version of Open CASCADE. Version 6.9.0 introduces various improvements with relation to boolean operations. You are advised to upgrade."
++#warning "You are linking against an older version of Open CASCADE. Version 6.9.0 introduces various improvements with relation to boolean operations. You are advised to upgrade."
+ #endif
+ #endif
+@@ -332,7 +332,7 @@ bool IfcGeom::Kernel::convert_openings(const IfcSchema::IfcProduct* entity, cons
+                               convert_shapes(*it2,opening_shapes);
+                       }
+-                      const unsigned int current_size = (const unsigned int) opening_shapes.size();
++                      const unsigned int current_size = (unsigned int) opening_shapes.size();
+                       for ( unsigned int i = last_size; i < current_size; ++ i ) {
+                               opening_shapes[i].prepend(opening_trsf);
+                       }
+@@ -2864,12 +2864,11 @@ bool IfcGeom::Kernel::wire_intersections(const TopoDS_Wire& wire, TopTools_ListO
+       // tfk: Extrema on infinite curves proved to be more robust.
+       // TopoDS_Face face = BRepBuilderAPI_MakeFace(wire, true).Face();
+       // ShapeAnalysis_Wire saw(wd, face, getValue(GV_PRECISION));
+-                      
++
+       for (int i = 2; i < n; ++i) {
+               for (int j = 0; j < i - 1; ++j) {
+                       if (i == n - 1 && j == 0) continue;
+-                      bool unbounded_intersects;
+                       const double eps = getValue(GV_PRECISION) * 2.;
+                       double u11, u12, u21, u22, U1, U2;
+@@ -2878,88 +2877,89 @@ bool IfcGeom::Kernel::wire_intersections(const TopoDS_Wire& wire, TopTools_ListO
+                               BRep_Tool::Curve(wd->Edge(j + 1), u21, u22)
+                       );
+-                      if ((unbounded_intersects = (ecc.NbExtrema() == 1 && ecc.Distance(1) < eps))) {
+-                              ecc.Parameters(1, U1, U2);
+-                      }
+-
+-                      if (u11 > u12) {
+-                              std::swap(u11, u12);
+-                      }
+-                      if (u21 > u22) {
+-                              std::swap(u21, u22);
+-                      }
+-
+-                      /// @todo: tfk: probably need different thresholds on non-linear curves
+-                      u11 -= eps;
+-                      u12 += eps;
+-                      u21 -= eps;
+-                      u22 += eps;
+-
+-                      // tfk: code below is for ShapeAnalysis_Wire::CheckIntersectingEdges()
+-                      // IntRes2d_SequenceOfIntersectionPoint points2d;
+-                      // TColgp_SequenceOfPnt points3d;
+-                      // TColStd_SequenceOfReal errors;
+-                      // if (saw.CheckIntersectingEdges(i + 1, j + 1, points2d, points3d, errors)) {
+-
+-                      if (unbounded_intersects &&     u11 < U1 && U1 < u12 && u21 < U2 && U2 < u22) {
+-
+-                              intersected = true;
+-
+-                              // Explore a forward and backward cycle from the intersection point
+-                              for (int fb = 0; fb <= 1; ++fb) {
+-                                      const bool forward = fb == 0;
+-
+-                                      BRepBuilderAPI_MakeWire mw;
+-                                      bool first = true;
+-
+-                                      for (bounded_int k(j, n);;) {
+-                                              bool intersecting = k == j || k == i;
+-                                              if (intersecting) {
+-                                                      TopoDS_Edge e = wd->Edge(k + 1);
+-                                                      
+-                                                      TopoDS_Vertex v1, v2;
+-                                                      TopExp::Vertices(e, v1, v2);
+-                                                      const TopoDS_Vertex* v = first == forward ? &v2 : &v1;
+-
+-                                                      // gp_Pnt p2 = points3d.Value(1);
+-                                                      
+-                                                      gp_Pnt p1 = BRep_Tool::Pnt(*v);
+-                                                      gp_Pnt pp1, pp2;
+-                                                      ecc.Points(1, pp1, pp2);
+-                                                      const gp_Pnt& p2 = k == i ? pp1 : pp2;
+-                                                      
+-                                                      // Substitute with a new edge from/to the intersection point
+-                                                      if (p1.Distance(p2) > getValue(GV_PRECISION) * 2) {
+-                                                              double _, __;
+-                                                              Handle(Geom_Curve) crv = BRep_Tool::Curve(e, _, __);
+-                                                              BRepBuilderAPI_MakeEdge me(crv, p1, p2);
+-                                                              TopoDS_Edge ed = me.Edge();
+-                                                              mw.Add(ed);
+-                                                      }
+-
+-                                                      first = false;
+-                                              } else {
+-                                                      // Re-use original edge
+-                                                      mw.Add(wd->Edge(k+1));
+-                                              }
++                      bool unbounded_intersects = (!ecc.Extrema().IsParallel() && ecc.NbExtrema() == 1 && ecc.Distance(1) < eps);
++      if (unbounded_intersects) {
++        ecc.Parameters(1, U1, U2);
+-                                              if (k == i) {
+-                                                      break;
+-                                              }
++        if (u11 > u12) {
++          std::swap(u11, u12);
++        }
++        if (u21 > u22) {
++          std::swap(u21, u22);
++        }
+-                                              if (forward) {
+-                                                      ++k;
+-                                              } else {
+-                                                      --k;
+-                                              }
+-                                      }
++        /// @todo: tfk: probably need different thresholds on non-linear curves
++        u11 -= eps;
++        u12 += eps;
++        u21 -= eps;
++        u22 += eps;
++
++        // tfk: code below is for ShapeAnalysis_Wire::CheckIntersectingEdges()
++        // IntRes2d_SequenceOfIntersectionPoint points2d;
++        // TColgp_SequenceOfPnt points3d;
++        // TColStd_SequenceOfReal errors;
++        // if (saw.CheckIntersectingEdges(i + 1, j + 1, points2d, points3d, errors)) {
++
++        if (u11 < U1 && U1 < u12 && u21 < U2 && U2 < u22) {
++
++          intersected = true;
++
++          // Explore a forward and backward cycle from the intersection point
++          for (int fb = 0; fb <= 1; ++fb) {
++            const bool forward = fb == 0;
++
++            BRepBuilderAPI_MakeWire mw;
++            bool first = true;
++
++            for (bounded_int k(j, n);;) {
++              bool intersecting = k == j || k == i;
++              if (intersecting) {
++                TopoDS_Edge e = wd->Edge(k + 1);
++                
++                TopoDS_Vertex v1, v2;
++                TopExp::Vertices(e, v1, v2);
++                const TopoDS_Vertex* v = first == forward ? &v2 : &v1;
++
++                // gp_Pnt p2 = points3d.Value(1);
++                
++                gp_Pnt p1 = BRep_Tool::Pnt(*v);
++                gp_Pnt pp1, pp2;
++                ecc.Points(1, pp1, pp2);
++                const gp_Pnt& p2 = k == i ? pp1 : pp2;
++                
++                // Substitute with a new edge from/to the intersection point
++                if (p1.Distance(p2) > getValue(GV_PRECISION) * 2) {
++                  double _, __;
++                  Handle(Geom_Curve) crv = BRep_Tool::Curve(e, _, __);
++                  BRepBuilderAPI_MakeEdge me(crv, p1, p2);
++                  TopoDS_Edge ed = me.Edge();
++                  mw.Add(ed);
++                }
++
++                first = false;
++              } else {
++                // Re-use original edge
++                mw.Add(wd->Edge(k+1));
++              }
++
++              if (k == i) {
++                break;
++              }
++
++              if (forward) {
++                ++k;
++              } else {
++                --k;
++              }
++            }
+-                                      // Recursively process both cuts
+-                                      wire_intersections(mw.Wire(), wires);
+-                              }
++            // Recursively process both cuts
++            wire_intersections(mw.Wire(), wires);
++          }
+-                              return true;
+-                      }
++          return true;
++        }
++      }
+               }
+       }
+diff --git a/src/ifcwrap/IfcGeomWrapper.i b/src/ifcwrap/IfcGeomWrapper.i
+index 05a39fd..157f4c6 100644
+--- a/src/ifcwrap/IfcGeomWrapper.i
++++ b/src/ifcwrap/IfcGeomWrapper.i
+@@ -51,7 +51,7 @@
+ %extend IfcGeom::tree {
+-      static IfcEntityList::ptr vector_to_list(const std::vector<IfcSchema::IfcProduct*>& ps) const {
++      static IfcEntityList::ptr vector_to_list(const std::vector<IfcSchema::IfcProduct*>& ps) {
+               IfcEntityList::ptr r(new IfcEntityList);
+               for (std::vector<IfcSchema::IfcProduct*>::const_iterator it = ps.begin(); it != ps.end(); ++it) {
+                       r->push(*it);
diff --git a/products/patches/sbim_smodule.patch b/products/patches/sbim_smodule.patch
new file mode 100644 (file)
index 0000000..028fc79
--- /dev/null
@@ -0,0 +1,592 @@
+diff -ruN BuildingIS/idl/BuildingIS_Gen.idl sbim_smodule/idl/BuildingIS_Gen.idl
+--- BuildingIS/idl/BuildingIS_Gen.idl  2023-06-26 17:02:06.295100754 +0100
++++ sbim_smodule/idl/BuildingIS_Gen.idl        2023-06-26 17:02:06.295100754 +0100
+@@ -38,7 +38,7 @@
+   */
+   interface BuildingIS_Gen : Engines::EngineComponent
+   {
+-    boolean importIfcFile(in SALOMEDS::Study study, in string fileName, in string filterFileName, in boolean logImport)
++    boolean importIfcFile(in SALOMEDS::Study study, in string fileName, in string filterFileName, in boolean logImport, in boolean enableFilter)
+       raises (SALOME::SALOME_Exception);
+     boolean publishToGeom(in SALOMEDS::Study study, in string name, in string brep)
+diff -ruN BuildingIS/resources/BuildingISCatalog.xml.in sbim_smodule/resources/BuildingISCatalog.xml.in
+--- BuildingIS/resources/BuildingISCatalog.xml.in      2023-02-16 09:43:48.000000000 +0000
++++ sbim_smodule/resources/BuildingISCatalog.xml.in    2023-06-23 14:54:51.388740186 +0100
+@@ -55,6 +55,11 @@
+                 <inParameter-type>boolean</inParameter-type>
+                 <inParameter-comment>log import operations</inParameter-comment>
+               </inParameter>
++              <inParameter>
++                <inParameter-name>enableFilter</inParameter-name>
++                <inParameter-type>boolean</inParameter-type>
++                <inParameter-comment>enable import filter</inParameter-comment>
++              </inParameter>
+             </inParameter-list>
+             <outParameter-list>
+               <outParameter>
+diff -ruN BuildingIS/src/BasicLogger.hxx sbim_smodule/src/BasicLogger.hxx
+--- BuildingIS/src/BasicLogger.hxx     2023-02-16 09:43:48.000000000 +0000
++++ sbim_smodule/src/BasicLogger.hxx   2023-06-26 15:46:39.895941467 +0100
+@@ -1,4 +1,4 @@
+-// Copyright (C) 2013-2018  OPEN CASCADE
++// Copyright (C) 2013-2023  OPEN CASCADE
+ //
+ // This library is free software; you can redistribute it and/or
+ // modify it under the terms of the GNU Lesser General Public
+diff -ruN BuildingIS/src/BuildingImport/BuildingObject.cxx sbim_smodule/src/BuildingImport/BuildingObject.cxx
+--- BuildingIS/src/BuildingImport/BuildingObject.cxx   2023-06-26 14:36:31.241500894 +0100
++++ sbim_smodule/src/BuildingImport/BuildingObject.cxx 2023-06-26 14:36:31.241500894 +0100
+@@ -57,7 +57,7 @@
+ void BuildingObject::addChildren(std::vector<BuildingObject*> elements)
+ {
+-    for (int i = 0; i < elements.size(); ++i)
++    for (std::size_t i = 0; i < elements.size(); ++i)
+     {
+         addChild(elements[i]);
+     }
+diff -ruN BuildingIS/src/BuildingImport/BuildingObject.hxx sbim_smodule/src/BuildingImport/BuildingObject.hxx
+--- BuildingIS/src/BuildingImport/BuildingObject.hxx   2023-06-26 14:39:57.717495418 +0100
++++ sbim_smodule/src/BuildingImport/BuildingObject.hxx 2023-06-26 14:39:57.717495418 +0100
+@@ -33,7 +33,7 @@
+             const std::string& uniqueId, const std::string& dataType);
+     virtual ~BuildingObject();
+-    const unsigned int getId() const
++    unsigned int getId() const
+     {
+         return m_id;
+     }
+@@ -80,7 +80,7 @@
+     void addChild(BuildingObject* element);
+     void addChildren(std::vector<BuildingObject*> elements);
+     void removeChildren(BuildingObject* element);
+-    const int getNbChildren() const
++    int getNbChildren() const
+     {
+         return m_children.size();
+     }
+@@ -96,15 +96,19 @@
+     void setBrep(const std::string& brep)
+     {
++        // if (brep.size() > 0)
++        //   std::cout << "BREP_DATA [" << this << "]: size=" << brep.size() << std::endl;
++        // else
++        //   std::cout << "BREP_DATA [" << this << "]: setting EMPTY brep..." << std::endl;
+         m_brep = brep;
+     }
+-    const bool hasBrep() const
++    bool hasBrep() const
+     {
+         return (!m_brep.empty());
+     }
+-    const bool hasRepresentation() const
++    bool hasRepresentation() const
+     {
+         return m_hasRepresentation;
+     }
+diff -ruN BuildingIS/src/BuildingImport/IfcImporter.cxx sbim_smodule/src/BuildingImport/IfcImporter.cxx
+--- BuildingIS/src/BuildingImport/IfcImporter.cxx      2023-06-26 14:41:02.197493708 +0100
++++ sbim_smodule/src/BuildingImport/IfcImporter.cxx    2023-06-26 14:41:02.197493708 +0100
+@@ -65,7 +65,7 @@
+     BasicLogger(level) << message << std::endl;
+ }
+-const bool IfcImporter::readFile(const std::string& fileName, const bool& logImport)
++bool IfcImporter::readFile(const std::string& fileName, const bool& logImport)
+ {
+     bool res = false;
+     setlocale(LC_NUMERIC, "C");
+@@ -102,8 +102,12 @@
+     return res;
+ }
+-const bool IfcImporter::readIfcFile(const std::string& fileName, std::ostream* outStream, std::ostream* errStream)
++bool IfcImporter::readIfcFile(const std::string& fileName, std::ostream* outStream, std::ostream* errStream)
+ {
++    // Logger::SetOutput(outStream, errStream);
++    // Logger::Verbosity(Logger::LOG_NOTICE);
++    // Logger::OutputFormat(Logger::FMT_PLAIN);
++
+     IfcGeom::IteratorSettings settings;
+     settings.set(IfcGeom::IteratorSettings::USE_BREP_DATA, true);
+     settings.set(IfcGeom::IteratorSettings::USE_WORLD_COORDS, true);
+@@ -225,6 +229,16 @@
+     }
+ }
++void IfcImporter::setFilterEnabled(const bool& enableFilter)
++{
++  m_filter.setEnabled(enableFilter);
++}
++
++bool IfcImporter::isFilterEnabled() const
++{
++  return m_filter.isEnabled();
++}
++
+ void IfcImporter::readUnits()
+ {
+     if (!m_geomIterator)
+@@ -543,7 +557,7 @@
+     std::stringstream strThickness;
+     strThickness << thickness;
+     elt->setProperty("Thickness", strThickness.str());
+-    for (int i = 0; i < materials.size(); i++)
++    for (std::size_t i = 0; i < materials.size(); i++)
+     {
+         elt->setProperty("#Layer", materials[i]);
+     }
+diff -ruN BuildingIS/src/BuildingImport/IfcImporter.hxx sbim_smodule/src/BuildingImport/IfcImporter.hxx
+--- BuildingIS/src/BuildingImport/IfcImporter.hxx      2023-02-16 09:43:48.000000000 +0000
++++ sbim_smodule/src/BuildingImport/IfcImporter.hxx    2023-06-23 14:55:23.280741159 +0100
+@@ -46,14 +46,16 @@
+     std::vector<int> m_parsed;
+ public:
+-    const bool readFile(const std::string& fileName, const bool& logImport);
++    bool readFile(const std::string& fileName, const bool& logImport);
+     BuildingObject* getIfcTree(const std::string& filterFileName);
+     std::vector<BuildingObject*> getMaterials();
+     void getMaterialLayers(const std::string& guid, LayersMaterial& materials, double& totalLayersThickness);
++    void setFilterEnabled(const bool& enableFilter);
++    bool isFilterEnabled() const;
+ private:
+-    const bool readIfcFile(const std::string& fileName, std::ostream* outStream, std::ostream* errStream);
++    bool readIfcFile(const std::string& fileName, std::ostream* outStream, std::ostream* errStream);
+     void readMaterials();
+     void readUnits();
+     void readGeometries();
+diff -ruN BuildingIS/src/BuildingImport/IfcImportFilter.cxx sbim_smodule/src/BuildingImport/IfcImportFilter.cxx
+--- BuildingIS/src/BuildingImport/IfcImportFilter.cxx  2023-06-26 15:13:22.069442259 +0100
++++ sbim_smodule/src/BuildingImport/IfcImportFilter.cxx        2023-06-26 15:13:22.069442259 +0100
+@@ -50,7 +50,7 @@
+ void IfcImportFilter::addElement(const std::string& type, const bool& skip)
+ {
+-    //std::cout << "addElement( " << type << " )" << std::endl;
++    //std::cout << "addElement( " << type << " , skip=" << (skip?"true":"false") << " )" << std::endl;
+     try
+     {
+         m_filter[Ifc2x3::Type::FromString(type)] = skip;
+@@ -108,7 +108,7 @@
+     }
+ }
+-const bool IfcImportFilter::isInFilter(const Ifc2x3::Type::Enum& type)
++bool IfcImportFilter::isInFilter(const Ifc2x3::Type::Enum& type)
+ {
+     if (!m_enabled)
+         return true;
+@@ -130,7 +130,7 @@
+     return res;
+ }
+-const bool IfcImportFilter::skipType(const Ifc2x3::Type::Enum& type)
++bool IfcImportFilter::skipType(const Ifc2x3::Type::Enum& type)
+ {
+     if (!m_enabled)
+         return false;
+@@ -176,7 +176,7 @@
+     return m_followMap[type];
+ }
+-const bool IfcImportFilter::followRelation(const Ifc2x3::Type::Enum& relType, const Ifc2x3::Type::Enum& targetType)
++bool IfcImportFilter::followRelation(const Ifc2x3::Type::Enum& relType, const Ifc2x3::Type::Enum& targetType)
+ {
+     if (!m_enabled)
+         return true;
+@@ -185,7 +185,7 @@
+         return true;
+     std::vector<Ifc2x3::Type::Enum> f = m_followRel[relType];
+-    for (int i = 0; i < f.size(); ++i)
++    for (std::size_t i = 0; i < f.size(); ++i)
+     {
+         if (f[i] == targetType)
+             return true;
+@@ -288,7 +288,7 @@
+     }
+ }
+-const bool IfcImportFilter::importFile(const std::string& fileName)
++bool IfcImportFilter::importFile(const std::string& fileName)
+ {
+     bool res = false;
+diff -ruN BuildingIS/src/BuildingImport/IfcImportFilter.hxx sbim_smodule/src/BuildingImport/IfcImportFilter.hxx
+--- BuildingIS/src/BuildingImport/IfcImportFilter.hxx  2023-02-16 09:43:48.000000000 +0000
++++ sbim_smodule/src/BuildingImport/IfcImportFilter.hxx        2023-06-20 12:17:49.993355789 +0100
+@@ -41,15 +41,15 @@
+     void addElementFollow(const std::string& type, const std::string& relType);
+     void addRelationFollow(const Ifc2x3::Type::Enum& relType, const Ifc2x3::Type::Enum& type);
+     void addRelationFollow(const std::string& relType, const std::string& type);
+-    const bool importFile(const std::string& fileName);
++    bool importFile(const std::string& fileName);
+-    const bool isInFilter(const Ifc2x3::Type::Enum& type);
+-    const bool skipType(const Ifc2x3::Type::Enum& type);
++    bool isInFilter(const Ifc2x3::Type::Enum& type);
++    bool skipType(const Ifc2x3::Type::Enum& type);
+     std::vector<Ifc2x3::Type::Enum> follow(const Ifc2x3::Type::Enum& type);
+-    const bool followRelation(const Ifc2x3::Type::Enum& type, const Ifc2x3::Type::Enum& targetType);
++    bool followRelation(const Ifc2x3::Type::Enum& type, const Ifc2x3::Type::Enum& targetType);
+-    const bool isEnabled() const
++    bool isEnabled() const
+     {
+         return m_enabled;
+     }
+diff -ruN BuildingIS/src/BuildingImport/Swig/BuildingIsImport.i sbim_smodule/src/BuildingImport/Swig/BuildingIsImport.i
+--- BuildingIS/src/BuildingImport/Swig/BuildingIsImport.i      2023-02-21 13:58:37.000000000 +0000
++++ sbim_smodule/src/BuildingImport/Swig/BuildingIsImport.i    2023-06-23 14:52:05.640735128 +0100
+@@ -84,6 +84,8 @@
+     IfcImporter();
+     const bool readFile(const std::string& fileName, const bool& logImport);
+     BuildingObject* getIfcTree(const std::string& filterFileName);
++    void setFilterEnabled(const bool& enableFilter);
++    bool isFilterEnabled() const;
+     %extend
+     {
+       PyObject *getMaterialLayers(const std::string& guid)
+diff -ruN BuildingIS/src/BuildingImport/Swig/TestBuildingIS.py sbim_smodule/src/BuildingImport/Swig/TestBuildingIS.py
+--- BuildingIS/src/BuildingImport/Swig/TestBuildingIS.py       2023-06-26 14:36:21.505501152 +0100
++++ sbim_smodule/src/BuildingImport/Swig/TestBuildingIS.py     2023-06-26 14:36:21.505501152 +0100
+@@ -7,7 +7,7 @@
+ geompy = geomBuilder.New()
+ def walkIfc(elt,lev):
+-    print("{} - {} {} {} {}".format(lev*" ",elt.getName(),elt.getUniqueId(),len(elt.getBrep()),elt.getDataType()))
++    print('{}- [{}] "{}" {:7} {}'.format(lev*"  ",elt.getName(),elt.getUniqueId(),len(elt.getBrep()),elt.getDataType()))
+     for i in range(elt.getNbChildren()):
+         walkIfc(elt.getElementAt(i),lev+1)
+@@ -27,6 +27,7 @@
+             f2.write(elt.getBrep().encode("ascii"))
+         BREP = geompy.ImportBREP(f.name)
+     return BREP
++
+ s_importer = BuildingIsImport.IfcImporter()
+ fname = os.path.join(os.environ["BuildingIS_SRC_DIR"],"tests","data","IfcOpenHouse.ifc")
+ #fname = "/home/H87074/TRENDS/BIM/test-tuyau_coude.ifc"
+@@ -37,7 +38,8 @@
+ elt = s_importer.getIfcTree("")
+ walkIfc(elt,0)
+ sel = [elt1 for elt1 in walk_on_all_objects(elt) if elt1.getName() == "South wall"]
+-#assert(len(sel)==1)
+-#sel = sel[0]
+-#s_importer.getMaterialLayers(sel.getUniqueId())
+-#brep = GetBREPObjFrom(sel)
++assert(len(sel)==1)
++sel = sel[0]
++s_importer.getMaterialLayers(sel.getUniqueId())
++brep = GetBREPObjFrom(sel)
++geompy.addToStudy(brep, 'South wall')
+diff -ruN BuildingIS/src/BuildingIS/BuildingIS.cxx sbim_smodule/src/BuildingIS/BuildingIS.cxx
+--- BuildingIS/src/BuildingIS/BuildingIS.cxx   2023-02-20 10:13:05.000000000 +0000
++++ sbim_smodule/src/BuildingIS/BuildingIS.cxx 2023-06-23 14:56:37.820743434 +0100
+@@ -167,7 +167,8 @@
+ bool BuildingIS_Gen_i::importIfcFile(SALOMEDS::Study_ptr study,
+         const char* fileName,
+         const char* filterFileName,
+-        bool logImport) throw (SALOME::SALOME_Exception)
++        bool logImport,
++        bool enableFilter) /*throw (SALOME::SALOME_Exception)*/
+ {
+     // set exception handler to catch unexpected CORBA exceptions
+     Unexpect aCatch(SALOME_SalomeException);
+@@ -185,6 +186,7 @@
+     // read file
+     IfcImporter importer;
++    importer.setFilterEnabled(enableFilter);
+     bool read = importer.readFile(fileName, logImport);
+     if (!read)
+         return false;
+@@ -257,7 +259,7 @@
+ bool BuildingIS_Gen_i::publishToGeom(SALOMEDS::Study_ptr study,
+         const char* name,
+-        const char* brep) throw (SALOME::SALOME_Exception)
++        const char* brep) /*throw (SALOME::SALOME_Exception)*/
+ {
+     // set exception handler to catch unexpected CORBA exceptions
+     //Unexpect aCatch(SALOME_SalomeException);
+@@ -310,7 +312,7 @@
+ bool BuildingIS_Gen_i::hasProperty(SALOMEDS::Study_ptr study,
+         const char* entry,
+-        const char* propertyName) throw (SALOME::SALOME_Exception)
++        const char* propertyName) /*throw (SALOME::SALOME_Exception)*/
+ {
+     SALOMEDS::SObject_var aSObj = study->FindObjectID(entry);
+@@ -326,7 +328,7 @@
+ char* BuildingIS_Gen_i::getProperty(SALOMEDS::Study_ptr study,
+         const char* entry,
+-        const char* propertyName) throw (SALOME::SALOME_Exception)
++        const char* propertyName) /*throw (SALOME::SALOME_Exception)*/
+ {
+     SALOMEDS::SObject_var aSObj = study->FindObjectID(entry);
+     std::string result = "";
+diff -ruN BuildingIS/src/BuildingIS/BuildingIS.hxx sbim_smodule/src/BuildingIS/BuildingIS.hxx
+--- BuildingIS/src/BuildingIS/BuildingIS.hxx   2023-02-16 09:43:48.000000000 +0000
++++ sbim_smodule/src/BuildingIS/BuildingIS.hxx 2023-06-23 14:54:23.508739335 +0100
+@@ -48,14 +48,14 @@
+             const char* interfaceName);
+     virtual ~BuildingIS_Gen_i();
+-    bool importIfcFile(SALOMEDS::Study_ptr study, const char* fileName, const char* filterFileName, bool logImport)
+-        throw (SALOME::SALOME_Exception);
++    bool importIfcFile(SALOMEDS::Study_ptr study, const char* fileName, const char* filterFileName, bool logImport, bool enableFilter)
++        /*throw (SALOME::SALOME_Exception)*/;
+     bool publishToGeom(SALOMEDS::Study_ptr study, const char* name, const char* brep)
+-        throw (SALOME::SALOME_Exception);
++        /*throw (SALOME::SALOME_Exception)*/;
+     bool hasProperty(SALOMEDS::Study_ptr study, const char* entry, const char* propertyName)
+-        throw (SALOME::SALOME_Exception);
++        /*throw (SALOME::SALOME_Exception)*/;
+     char* getProperty(SALOMEDS::Study_ptr study, const char* entry, const char* propertyName)
+-        throw (SALOME::SALOME_Exception);
++        /*throw (SALOME::SALOME_Exception)*/;
+     virtual char* getVersion();
+     virtual bool hasObjectInfo();
+diff -ruN BuildingIS/src/BuildingISGUI/BuildingISGUI.cxx sbim_smodule/src/BuildingISGUI/BuildingISGUI.cxx
+--- BuildingIS/src/BuildingISGUI/BuildingISGUI.cxx     2023-06-26 15:20:31.029430882 +0100
++++ sbim_smodule/src/BuildingISGUI/BuildingISGUI.cxx   2023-06-26 15:46:20.997395963 +0100
+@@ -1,4 +1,4 @@
+-// Copyright (C) 2013-2018  OPEN CASCADE
++// Copyright (C) 2013-2023  OPEN CASCADE
+ //
+ // This library is free software; you can redistribute it and/or
+ // modify it under the terms of the GNU Lesser General Public
+@@ -30,6 +30,8 @@
+ #include <QtxPopupMgr.h>
+ #include <OCCViewer_ViewManager.h>
++//#include <algorithm> //MBS:
++
+ #include <SalomeApp_Application.h>
+ #include <SalomeApp_Study.h>
+ #include <SalomeApp_DataObject.h>
+@@ -115,6 +117,14 @@
+             tr("MEN_OP_HIDE_GEOMETRY_WITH_CHILDREN"),
+             tr("STS_OP_HIDE_GEOMETRY_WITH_CHILDREN"),
+             0, dsk, false, this, SLOT(onHideGeometryWithChildren()));
++    //MBS:
++    // createAction(OpSaveToBRep,
++    //         tr("Save to BREP"),
++    //         resMgr->loadPixmap("BuildingIS", tr("ICON_OP_PUBLISH")),
++    //         tr("Save To BRep"),
++    //         tr("Save To BRep"),
++    //         0, dsk, false, this, SLOT(onSaveToBRep()));
++
+     createAction(OpPublishToGeom,
+             tr("TLT_OP_PUBLISH"),
+             resMgr->loadPixmap("BuildingIS", tr("ICON_OP_PUBLISH")),
+@@ -143,6 +153,7 @@
+     // create toolbars
+     int aToolId = createTool(tr("TOOL_BUILDINGIS"));
+     createTool(OpImportIfc, aToolId);
++    //createTool(OpSaveToBRep, aToolId);//MBS:
+     createTool(OpPublishToGeom, aToolId);
+     createTool(OpPublishToSmesh, aToolId);
+@@ -153,6 +164,7 @@
+     mgr->insert(action(OpShowGeometryWithChildren), -1, -1);
+     mgr->insert(action(OpHideGeometry), -1, -1);
+     mgr->insert(action(OpHideGeometryWithChildren), -1, -1);
++    //mgr->insert(action(OpSaveToBRep), -1, -1);//MBS:
+     mgr->insert(action(OpPublishToGeom), -1, -1);
+     QString ifcCloseRule = "client='ObjectBrowser' and selcount=1"
+@@ -166,6 +178,7 @@
+     mgr->setRule(action(OpShowGeometryWithChildren), baseRuleChildren, QtxPopupMgr::VisibleRule);
+     mgr->setRule(action(OpHideGeometry), baseRule, QtxPopupMgr::VisibleRule);
+     mgr->setRule(action(OpHideGeometryWithChildren), baseRuleChildren, QtxPopupMgr::VisibleRule);
++    //mgr->setRule(action(OpSaveToBRep), baseRule, QtxPopupMgr::VisibleRule);//MBS:
+     mgr->setRule(action(OpPublishToGeom), baseRule, QtxPopupMgr::VisibleRule);
+ }
+@@ -232,7 +245,7 @@
+     // filter preferences
+     groupId = addPreference(tr("Import"), tabId, LightApp_Preferences::GroupBox);
+-    //pid = addPreference(tr("Enable Filter"), groupId, LightApp_Preferences::Bool, "BuildingIS", "FilterIsEnabled");
++    pid = addPreference(tr("Enable Filter"), groupId, LightApp_Preferences::Bool, "BuildingIS", "FilterIsEnabled");
+     pid = addPreference("Filter", groupId, LightApp_Preferences::File, "BuildingIS", "IfcImportFilter");
+     setPreferenceProperty(pid, "path_type", Qtx::PT_OpenFile);
+     setPreferenceProperty(pid, "path_filter", "XML files (*.xml);;All Files (*.*)");
+@@ -355,12 +368,14 @@
+             QApplication::setOverrideCursor( Qt::WaitCursor );
+             QString filterFile = resmgr->stringValue("BuildingIS", "IfcImportFilter", QDir::homePath());
+             bool logImport = resmgr->booleanValue("BuildingIS", "LogIfcImport", false);
++            bool enableFilter = resmgr->booleanValue("BuildingIS", "FilterIsEnabled", true);
+             SALOMEDS::Study_var aStudy = KERNEL::getStudyServant();
+             bool status = getBuildingISEngine()->importIfcFile(aStudy,
+                     fileName.toStdString().c_str(),
+                     filterFile.toStdString().c_str(),
+-                    logImport);
++                    logImport,
++                    enableFilter);
+           std::cout << "homePath: " << QDir::homePath().toStdString().c_str() << std::endl;
+           std::cout << "filename: " << fileName.toStdString().c_str() << std::endl;
+@@ -600,6 +615,71 @@
+     QApplication::restoreOverrideCursor();
+ }
++//MBS:
++// void BuildingISGUI::onSaveToBRep()
++// {
++//   QApplication::setOverrideCursor( Qt::WaitCursor );
++//
++//   SalomeApp_Application* app = dynamic_cast<SalomeApp_Application*>(application());
++//
++//   // get selection
++//   SALOME_ListIO selected;
++//   app->selectionMgr()->selectedObjects(selected);
++//   if (selected.Extent() == 0)
++//   {
++//     QApplication::restoreOverrideCursor();
++//     return;
++//   }
++//
++//   SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>(application()->activeStudy());
++//   SALOME_ListIteratorOfListIO it(selected);
++//   for (; it.More(); it.Next())
++//   {
++//     Handle(SALOME_InteractiveObject) io = it.Value();
++//
++//     _PTR(SObject)so = study->studyDS()->FindObjectID(io->getEntry());
++//     if (!so)
++//       continue;
++//
++//     _PTR(SComponent)comp = so->GetFatherComponent();
++//     if (!comp || comp->ComponentDataType() != "BuildingIS"
++//               || io->getEntry() == comp->GetID())
++//       continue;
++//
++//     // get brep
++//     std::string brep;
++//     _PTR(GenericAttribute)attr;
++//     if (so->FindAttribute(attr, "AttributeParameter"))
++//     {
++//       _PTR(AttributeParameter) strAttr(attr);
++//       brep = strAttr->GetString("brep");
++//     }
++//
++//     if (brep.size() > 0)
++//     {
++//       // get name
++//       std::string name;
++//       if (so->FindAttribute(attr, "AttributeName"))
++//       {
++//         _PTR(AttributeName) strAttr(attr);
++//         name = strAttr->Value();
++//       }
++//       name = name + "-" + io->getEntry();
++//       std::size_t idx = name.find("0:1:1:1:1:1");
++//       if (idx != std::string::npos) name.erase(idx, 11);
++//       std::replace_if(name.begin(), name.end(), ::ispunct, '_');
++//       name.erase(remove_if(name.begin(), name.end(), ::isspace), name.end());
++//       name += ".brep";
++//       std::cout << "Saving BREP (" << brep.size() << " bytes) to \"" << name << "\" ..." << std::flush;
++//       std::ofstream out(std::string("/tmp/") + name);
++//       out << brep;
++//       out.close();
++//       std::cout << " done." << std::endl;
++//     }
++//   }
++//   QApplication::restoreOverrideCursor();
++// }
++
+ void BuildingISGUI::onPublishToGeom()
+ {
+     QApplication::setOverrideCursor( Qt::WaitCursor );
+diff -ruN BuildingIS/src/BuildingISGUI/BuildingISGUI_Displayer.cxx sbim_smodule/src/BuildingISGUI/BuildingISGUI_Displayer.cxx
+--- BuildingIS/src/BuildingISGUI/BuildingISGUI_Displayer.cxx   2023-06-26 17:01:42.047101397 +0100
++++ sbim_smodule/src/BuildingISGUI/BuildingISGUI_Displayer.cxx 2023-06-26 17:01:42.047101397 +0100
+@@ -62,11 +62,6 @@
+ {
+ }
+-bool BuildingISGUI_Displayer::canBeDisplayed(const QString& entry, const QString& viewer_type) const
+-{
+-    return true;
+-}
+-
+ int getStudyID()
+ {
+     int studyID = -1;
+@@ -78,6 +73,35 @@
+     return studyID;
+ }
++bool BuildingISGUI_Displayer::canBeDisplayed(const QString& entry, const QString& viewer_type) const
++{
++    const int studyID = getStudyID();
++    if (studyID == -1)
++        return false;
++
++    SUIT_Session* session = SUIT_Session::session();
++    assert(session != NULL);
++    SUIT_Application* app = session->activeApplication();
++    if (!app) return false;
++
++    SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>(app->activeStudy());
++    assert(study != NULL);
++    _PTR(SObject) so = study->studyDS()->FindObjectID(entry.toStdString());
++    assert(so != NULL);
++    _PTR(GenericAttribute) attr;
++    if (!so->FindAttribute(attr, "AttributeParameter"))
++        return false;
++
++    _PTR(AttributeParameter) paramAttr(attr);
++    assert(paramAttr != NULL);
++    std::string brep =  paramAttr->GetString("brep");
++    if (brep.size() == 0)
++    {
++        return false;
++    }
++    return true;
++}
++
+ SALOME_Prs* BuildingISGUI_Displayer::buildPresentation(const QString& entry, SALOME_View* view)
+ {
+     assert(view != NULL);
+diff -ruN BuildingIS/src/BuildingISGUI/BuildingISGUI.h sbim_smodule/src/BuildingISGUI/BuildingISGUI.h
+--- BuildingIS/src/BuildingISGUI/BuildingISGUI.h       2023-06-26 15:21:22.369429521 +0100
++++ sbim_smodule/src/BuildingISGUI/BuildingISGUI.h     2023-06-26 15:46:08.867464272 +0100
+@@ -1,4 +1,4 @@
+-// Copyright (C) 2013-2018  OPEN CASCADE
++// Copyright (C) 2013-2023  OPEN CASCADE
+ //
+ // This library is free software; you can redistribute it and/or
+ // modify it under the terms of the GNU Lesser General Public
+@@ -50,6 +50,7 @@
+         OpShowGeometryWithChildren,
+         OpHideGeometry,
+         OpHideGeometryWithChildren,
++        //OpSaveToBRep,//MBS:
+         OpPublishToGeom,
+       OpPublishToSmesh,
+     };
+@@ -107,6 +108,7 @@
+     void onShowGeometryWithChildren();
+     void onHideGeometry();
+     void onHideGeometryWithChildren();
++    //void onSaveToBRep();//MBS:
+     void onPublishToGeom();
+     void onPublishToSmesh();
+     void onCloseIfc();