5050#include < Geom_Circle.hxx>
5151#include < Geom_Ellipse.hxx>
5252#include < Geom_TrimmedCurve.hxx>
53+ #include < Geom_OffsetCurve.hxx>
54+
55+ #include < BRepPrimAPI_MakePrism.hxx>
56+ #include < BRepPrimAPI_MakeHalfSpace.hxx>
5357
5458#include < BRepOffsetAPI_Sewing.hxx>
59+ #include < BRepOffsetAPI_MakeOffset.hxx>
60+
5561#include < BRepBuilderAPI_MakeFace.hxx>
5662#include < BRepBuilderAPI_MakeEdge.hxx>
5763#include < BRepBuilderAPI_MakeWire.hxx>
5864#include < BRepBuilderAPI_MakePolygon.hxx>
5965#include < BRepBuilderAPI_MakeVertex.hxx>
66+ #include < BRepBuilderAPI_MakeShell.hxx>
67+ #include < BRepBuilderAPI_MakeSolid.hxx>
6068
6169#include < TopoDS.hxx>
6270#include < TopoDS_Wire.hxx>
6371#include < TopoDS_Face.hxx>
6472#include < TopExp_Explorer.hxx>
6573
66- #include < BRepPrimAPI_MakePrism.hxx>
67- #include < BRepBuilderAPI_MakeShell.hxx>
68- #include < BRepBuilderAPI_MakeSolid.hxx>
69- #include < BRepPrimAPI_MakeHalfSpace.hxx>
7074#include < BRepAlgoAPI_Cut.hxx>
7175
7276#include < ShapeFix_Shape.hxx>
7680#include < TopLoc_Location.hxx>
7781#include < BRepGProp_Face.hxx>
7882
83+ #include < Standard_Failure.hxx>
84+
85+ #include < BRep_Tool.hxx>
86+
7987#include " ../ifcgeom/IfcGeom.h"
8088
8189bool IfcGeom::convert (const IfcSchema::IfcFace::ptr l, TopoDS_Face& face) {
@@ -183,11 +191,13 @@ bool IfcGeom::convert(const IfcSchema::IfcFace::ptr l, TopoDS_Face& face) {
183191 // return face_area(face) > 0.0001;
184192 return true ;
185193}
194+
186195bool IfcGeom::convert (const IfcSchema::IfcArbitraryClosedProfileDef::ptr l, TopoDS_Face& face) {
187196 TopoDS_Wire wire;
188197 if ( ! IfcGeom::convert_wire (l->OuterCurve (),wire) ) return false ;
189198 return IfcGeom::convert_wire_to_face (wire,face);
190199}
200+
191201bool IfcGeom::convert (const IfcSchema::IfcArbitraryProfileDefWithVoids::ptr l, TopoDS_Face& face) {
192202 TopoDS_Wire profile;
193203 if ( ! IfcGeom::convert_wire (l->OuterCurve (),profile) ) return false ;
@@ -204,6 +214,7 @@ bool IfcGeom::convert(const IfcSchema::IfcArbitraryProfileDefWithVoids::ptr l, T
204214 face = TopoDS::Face (sfs.Shape ());
205215 return true ;
206216}
217+
207218bool IfcGeom::convert (const IfcSchema::IfcRectangleProfileDef::ptr l, TopoDS_Face& face) {
208219 const double x = l->XDim () / 2 .0f * IfcGeom::GetValue (GV_LENGTH_UNIT);
209220 const double y = l->YDim () / 2 .0f * IfcGeom::GetValue (GV_LENGTH_UNIT);
@@ -218,6 +229,7 @@ bool IfcGeom::convert(const IfcSchema::IfcRectangleProfileDef::ptr l, TopoDS_Fac
218229 double coords[8 ] = {-x,-y,x,-y,x,y,-x,y};
219230 return IfcGeom::profile_helper (4 ,coords,0 ,0 ,0 ,trsf2d,face);
220231}
232+
221233bool IfcGeom::convert (const IfcSchema::IfcRoundedRectangleProfileDef::ptr l, TopoDS_Face& face) {
222234 const double x = l->XDim () / 2 .0f * IfcGeom::GetValue (GV_LENGTH_UNIT);
223235 const double y = l->YDim () / 2 .0f * IfcGeom::GetValue (GV_LENGTH_UNIT);
@@ -235,6 +247,7 @@ bool IfcGeom::convert(const IfcSchema::IfcRoundedRectangleProfileDef::ptr l, Top
235247 double radii[4 ] = {r,r,r,r};
236248 return IfcGeom::profile_helper (4 ,coords,4 ,fillets,radii,trsf2d,face);
237249}
250+
238251bool IfcGeom::convert (const IfcSchema::IfcRectangleHollowProfileDef::ptr l, TopoDS_Face& face) {
239252 const double x = l->XDim () / 2 .0f * IfcGeom::GetValue (GV_LENGTH_UNIT);
240253 const double y = l->YDim () / 2 .0f * IfcGeom::GetValue (GV_LENGTH_UNIT);
@@ -281,6 +294,7 @@ bool IfcGeom::convert(const IfcSchema::IfcRectangleHollowProfileDef::ptr l, Topo
281294 face = TopoDS::Face (sfs.Shape ());
282295 return true ;
283296}
297+
284298bool IfcGeom::convert (const IfcSchema::IfcTrapeziumProfileDef::ptr l, TopoDS_Face& face) {
285299 const double x1 = l->BottomXDim () / 2 .0f * IfcGeom::GetValue (GV_LENGTH_UNIT);
286300 const double w = l->TopXDim () * IfcGeom::GetValue (GV_LENGTH_UNIT);
@@ -297,6 +311,7 @@ bool IfcGeom::convert(const IfcSchema::IfcTrapeziumProfileDef::ptr l, TopoDS_Fac
297311 double coords[8 ] = {-x1,-y, x1,-y, dx+w-x1,y, dx-x1,y};
298312 return IfcGeom::profile_helper (4 ,coords,0 ,0 ,0 ,trsf2d,face);
299313}
314+
300315bool IfcGeom::convert (const IfcSchema::IfcIShapeProfileDef::ptr l, TopoDS_Face& face) {
301316 const double x = l->OverallWidth () / 2 .0f * IfcGeom::GetValue (GV_LENGTH_UNIT);
302317 const double y = l->OverallDepth () / 2 .0f * IfcGeom::GetValue (GV_LENGTH_UNIT);
@@ -321,6 +336,7 @@ bool IfcGeom::convert(const IfcSchema::IfcIShapeProfileDef::ptr l, TopoDS_Face&
321336 double radii[4 ] = {f,f,f,f};
322337 return IfcGeom::profile_helper (12 ,coords,doFillet ? 4 : 0 ,fillets,radii,trsf2d,face);
323338}
339+
324340bool IfcGeom::convert (const IfcSchema::IfcZShapeProfileDef::ptr l, TopoDS_Face& face) {
325341 const double x = l->FlangeWidth () * IfcGeom::GetValue (GV_LENGTH_UNIT);
326342 const double y = l->Depth () / 2 .0f * IfcGeom::GetValue (GV_LENGTH_UNIT);
@@ -353,6 +369,7 @@ bool IfcGeom::convert(const IfcSchema::IfcZShapeProfileDef::ptr l, TopoDS_Face&
353369 double radii[4 ] = {f2,f1,f2,f1};
354370 return IfcGeom::profile_helper (8 ,coords,(doFillet || doEdgeFillet) ? 4 : 0 ,fillets,radii,trsf2d,face);
355371}
372+
356373bool IfcGeom::convert (const IfcSchema::IfcCShapeProfileDef::ptr l, TopoDS_Face& face) {
357374 const double y = l->Depth () / 2 .0f * IfcGeom::GetValue (GV_LENGTH_UNIT);
358375 const double x = l->Width () / 2 .0f * IfcGeom::GetValue (GV_LENGTH_UNIT);
@@ -379,6 +396,7 @@ bool IfcGeom::convert(const IfcSchema::IfcCShapeProfileDef::ptr l, TopoDS_Face&
379396 double radii[8 ] = {f2,f2,f1,f1,f1,f1,f2,f2};
380397 return IfcGeom::profile_helper (12 ,coords,doFillet ? 8 : 0 ,fillets,radii,trsf2d,face);
381398}
399+
382400bool IfcGeom::convert (const IfcSchema::IfcLShapeProfileDef::ptr l, TopoDS_Face& face) {
383401 const bool hasSlope = l->hasLegSlope ();
384402 const bool doEdgeFillet = l->hasEdgeRadius ();
@@ -447,6 +465,7 @@ bool IfcGeom::convert(const IfcSchema::IfcLShapeProfileDef::ptr l, TopoDS_Face&
447465 double radii[3 ] = {f2,f1,f2};
448466 return IfcGeom::profile_helper (6 ,coords,doFillet ? 3 : 0 ,fillets,radii,trsf2d,face);
449467}
468+
450469bool IfcGeom::convert (const IfcSchema::IfcUShapeProfileDef::ptr l, TopoDS_Face& face) {
451470 const bool doEdgeFillet = l->hasEdgeRadius ();
452471 const bool doFillet = l->hasFilletRadius ();
@@ -488,6 +507,7 @@ bool IfcGeom::convert(const IfcSchema::IfcUShapeProfileDef::ptr l, TopoDS_Face&
488507 double radii[4 ] = {f2,f1,f1,f2};
489508 return IfcGeom::profile_helper (8 , coords, (doFillet || doEdgeFillet) ? 4 : 0 , fillets, radii, trsf2d, face);
490509}
510+
491511bool IfcGeom::convert (const IfcSchema::IfcTShapeProfileDef::ptr l, TopoDS_Face& face) {
492512 const bool doFlangeEdgeFillet = l->hasFlangeEdgeRadius ();
493513 const bool doWebEdgeFillet = l->hasWebEdgeRadius ();
@@ -570,6 +590,7 @@ bool IfcGeom::convert(const IfcSchema::IfcTShapeProfileDef::ptr l, TopoDS_Face&
570590 double radii[6 ] = {f2,f1,f3,f3,f1,f2};
571591 return IfcGeom::profile_helper (8 , coords, (doFillet || doWebEdgeFillet || doFlangeEdgeFillet) ? 6 : 0 , fillets, radii, trsf2d, face);
572592}
593+
573594bool IfcGeom::convert (const IfcSchema::IfcCircleProfileDef::ptr l, TopoDS_Face& face) {
574595 const double r = l->Radius () * IfcGeom::GetValue (GV_LENGTH_UNIT);
575596 if ( r == 0 .0f ) {
@@ -587,6 +608,7 @@ bool IfcGeom::convert(const IfcSchema::IfcCircleProfileDef::ptr l, TopoDS_Face&
587608 w.Add (edge);
588609 return IfcGeom::convert_wire_to_face (w,face);
589610}
611+
590612bool IfcGeom::convert (const IfcSchema::IfcCircleHollowProfileDef::ptr l, TopoDS_Face& face) {
591613 const double r = l->Radius () * IfcGeom::GetValue (GV_LENGTH_UNIT);
592614 const double t = l->WallThickness () * IfcGeom::GetValue (GV_LENGTH_UNIT);
@@ -615,6 +637,7 @@ bool IfcGeom::convert(const IfcSchema::IfcCircleHollowProfileDef::ptr l, TopoDS_
615637 face = TopoDS::Face (sfs.Shape ());
616638 return true ;
617639}
640+
618641bool IfcGeom::convert (const IfcSchema::IfcEllipseProfileDef::ptr l, TopoDS_Face& face) {
619642 double rx = l->SemiAxis1 () * IfcGeom::GetValue (GV_LENGTH_UNIT);
620643 double ry = l->SemiAxis2 () * IfcGeom::GetValue (GV_LENGTH_UNIT);
@@ -640,4 +663,53 @@ bool IfcGeom::convert(const IfcSchema::IfcEllipseProfileDef::ptr l, TopoDS_Face&
640663 TopoDS_Edge edge = BRepBuilderAPI_MakeEdge (ellipse);
641664 w.Add (edge);
642665 return IfcGeom::convert_wire_to_face (w, face);
643- }
666+ }
667+
668+ bool IfcGeom::convert (const IfcSchema::IfcCenterLineProfileDef::ptr l, TopoDS_Face& face) {
669+ const double d = l->Thickness () * IfcGeom::GetValue (GV_LENGTH_UNIT) / 2 .;
670+
671+ TopoDS_Wire wire;
672+ if (!IfcGeom::convert_wire (l->Curve (), wire)) return false ;
673+
674+ // BRepOffsetAPI_MakeOffset insists on creating circular arc
675+ // segments for joining the curves that constitute the center
676+ // line. This is probably not in accordance with the IFC spec.
677+ // Although it does not specify a method to join segments
678+ // explicitly, it does dictate 'a constant thickness along the
679+ // curve'. Therefore for simple singular wires a quick
680+ // alternative is provided that uses a straight join.
681+
682+ TopExp_Explorer exp (wire, TopAbs_EDGE);
683+ TopoDS_Edge edge = TopoDS::Edge (exp.Current ());
684+ exp.Next ();
685+
686+ if (!exp.More ()) {
687+ double u1, u2;
688+ Handle (Geom_Curve) curve = BRep_Tool::Curve (edge, u1, u2);
689+
690+ Handle (Geom_TrimmedCurve) trim = new Geom_TrimmedCurve (curve, u1, u2);
691+
692+ Handle (Geom_OffsetCurve) c1 = new Geom_OffsetCurve (trim, d, gp::DZ ());
693+ Handle (Geom_OffsetCurve) c2 = new Geom_OffsetCurve (trim, -d, gp::DZ ());
694+
695+ gp_Pnt c1a, c1b, c2a, c2b;
696+ c1->D0 (c1->FirstParameter (), c1a);
697+ c1->D0 (c1->LastParameter (), c1b);
698+ c2->D0 (c2->FirstParameter (), c2a);
699+ c2->D0 (c2->LastParameter (), c2b);
700+
701+ BRepBuilderAPI_MakeWire mw;
702+ mw.Add (BRepBuilderAPI_MakeEdge (c1));
703+ mw.Add (BRepBuilderAPI_MakeEdge (c1a, c2a));
704+ mw.Add (BRepBuilderAPI_MakeEdge (c2));
705+ mw.Add (BRepBuilderAPI_MakeEdge (c2b, c1b));
706+
707+ face = BRepBuilderAPI_MakeFace (mw.Wire ());
708+ } else {
709+ BRepOffsetAPI_MakeOffset offset (BRepBuilderAPI_MakeFace (gp_Pln (gp::Origin (), gp::DZ ())));
710+ offset.AddWire (wire);
711+ offset.Perform (d);
712+ face = BRepBuilderAPI_MakeFace (TopoDS::Wire (offset));
713+ }
714+ return true ;
715+ }
0 commit comments