From 944813146ebb31bc7c4274b1c8316f382d7fde11 Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Wed, 16 Jan 2019 12:28:58 +0100 Subject: [PATCH] Close polylines on closed profile def. Fixes #538 --- src/ifcgeom/IfcGeom.h | 3 ++- src/ifcgeom/IfcGeomFaces.cpp | 27 ++++++++++++++++++++++----- src/ifcgeom/IfcGeomFunctions.cpp | 21 +++++++++++++++++++++ 3 files changed, 45 insertions(+), 6 deletions(-) diff --git a/src/ifcgeom/IfcGeom.h b/src/ifcgeom/IfcGeom.h index 71e738f09d..a927e42efd 100644 --- a/src/ifcgeom/IfcGeom.h +++ b/src/ifcgeom/IfcGeom.h @@ -195,7 +195,8 @@ public: bool convert_face(const IfcUtil::IfcBaseClass* L, TopoDS_Shape& result); 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); - + void assert_closed_wire(TopoDS_Wire& wire); + bool convert_layerset(const IfcSchema::IfcProduct*, std::vector&, std::vector&, std::vector&); bool apply_layerset(const IfcRepresentationShapeItems&, const std::vector&, const std::vector&, IfcRepresentationShapeItems&); bool apply_folded_layerset(const IfcRepresentationShapeItems&, const std::vector< std::vector >&, const std::vector&, IfcRepresentationShapeItems&); diff --git a/src/ifcgeom/IfcGeomFaces.cpp b/src/ifcgeom/IfcGeomFaces.cpp index 9b3cbea356..103497a7b7 100644 --- a/src/ifcgeom/IfcGeomFaces.cpp +++ b/src/ifcgeom/IfcGeomFaces.cpp @@ -67,6 +67,7 @@ #include #include +#include #include #include #include @@ -396,28 +397,44 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcFace* l, TopoDS_Shape& face) { bool IfcGeom::Kernel::convert(const IfcSchema::IfcArbitraryClosedProfileDef* l, TopoDS_Shape& face) { TopoDS_Wire wire; - if ( ! convert_wire(l->OuterCurve(),wire) ) return false; + if (!convert_wire(l->OuterCurve(), wire)) { + return false; + } + + assert_closed_wire(wire); TopoDS_Face f; bool success = convert_wire_to_face(wire, f); - if (success) face = f; + if (success) { + face = f; + } return success; } bool IfcGeom::Kernel::convert(const IfcSchema::IfcArbitraryProfileDefWithVoids* l, TopoDS_Shape& face) { TopoDS_Wire profile; - if ( ! convert_wire(l->OuterCurve(),profile) ) return false; + if (!convert_wire(l->OuterCurve(), profile)) { + return false; + } + + assert_closed_wire(profile); + BRepBuilderAPI_MakeFace mf(profile); + IfcSchema::IfcCurve::list::ptr voids = l->InnerCurves(); - for( IfcSchema::IfcCurve::list::it it = voids->begin(); it != voids->end(); ++ it ) { + + for(IfcSchema::IfcCurve::list::it it = voids->begin(); it != voids->end(); ++it) { TopoDS_Wire hole; - if ( convert_wire(*it,hole) ) { + if (convert_wire(*it, hole)) { + assert_closed_wire(hole); mf.Add(hole); } } + ShapeFix_Shape sfs(mf.Face()); sfs.Perform(); face = sfs.Shape(); + return true; } diff --git a/src/ifcgeom/IfcGeomFunctions.cpp b/src/ifcgeom/IfcGeomFunctions.cpp index 4b738f0963..416a5d51d0 100644 --- a/src/ifcgeom/IfcGeomFunctions.cpp +++ b/src/ifcgeom/IfcGeomFunctions.cpp @@ -876,6 +876,27 @@ bool IfcGeom::Kernel::convert_wire_to_face(const TopoDS_Wire& w, TopoDS_Face& fa return true; } +void IfcGeom::Kernel::assert_closed_wire(TopoDS_Wire& wire) { + if (wire.Closed() == 0) { + TopoDS_Vertex v0, v1; + TopExp::Vertices(wire, v0, v1); + + gp_Pnt p1 = BRep_Tool::Pnt(v0); + gp_Pnt p2 = BRep_Tool::Pnt(v1); + + if (p1.Distance(p2) > getValue(GV_PRECISION)) { + + BRepBuilderAPI_MakeWire mw; + mw.Add(wire); + mw.Add(BRepBuilderAPI_MakeEdge(v0, v1).Edge()); + wire = mw.Wire(); + + } + + Logger::Warning("Wire not closed:"); + } +} + bool IfcGeom::Kernel::convert_curve_to_wire(const Handle(Geom_Curve)& curve, TopoDS_Wire& wire) { try { wire = BRepBuilderAPI_MakeWire(BRepBuilderAPI_MakeEdge(curve));