diff --git a/src/examples/arbitrary_open_profile_def.cpp b/src/examples/arbitrary_open_profile_def.cpp new file mode 100644 index 0000000000..f20b4d8f7d --- /dev/null +++ b/src/examples/arbitrary_open_profile_def.cpp @@ -0,0 +1,140 @@ +/******************************************************************************** + * * + * This file is part of IfcOpenShell. * + * * + * IfcOpenShell is free software: you can redistribute it and/or modify * + * it under the terms of the Lesser GNU General Public License as published by * + * the Free Software Foundation, either version 3.0 of the License, or * + * (at your option) any later version. * + * * + * IfcOpenShell is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * Lesser GNU General Public License for more details. * + * * + * You should have received a copy of the Lesser GNU General Public License * + * along with this program. If not, see . * + * * + ********************************************************************************/ + +/******************************************************************************** + * * + * Example that generates various representations from * + * IfcArbitraryOpenProfileDefs and its subclass IfcCenterLineProfileDef * + * * + ********************************************************************************/ + +#include +#include +#include + +#include "../ifcparse/Ifc2x3.h" +#include "../ifcparse/IfcUtil.h" +#include "../ifcparse/IfcHierarchyHelper.h" + +typedef std::string S; +typedef IfcWrite::IfcGuidHelper guid; +boost::none_t const null = (static_cast(0)); +static int i = 0; + +void create_product_from_item(IfcHierarchyHelper& file, IfcSchema::IfcRepresentationItem* item, const std::string& s) { + IfcSchema::IfcBuildingElementProxy* product = new IfcSchema::IfcBuildingElementProxy( + guid(), 0, S("product"), null, null, 0, 0, null, null); + file.addBuildingProduct(product); + product->setOwnerHistory(file.getSingle()); + + product->setObjectPlacement(file.addLocalPlacement(120 * i++)); + + IfcSchema::IfcRepresentation::list reps (new IfcTemplatedEntityList()); + IfcSchema::IfcRepresentationItem::list items (new IfcTemplatedEntityList()); + items->push(item); + + if (s == "GeometricSet") { + IfcSchema::IfcGeometricSet* set = new IfcSchema::IfcGeometricSet(items->generalize()); + file.AddEntity(set); + items = IfcSchema::IfcRepresentationItem::list(new IfcTemplatedEntityList()); + items->push(set); + } + + IfcSchema::IfcShapeRepresentation* rep = new IfcSchema::IfcShapeRepresentation( + file.getSingle(), S("Body"), s, items); + reps->push(rep); + + IfcSchema::IfcProductDefinitionShape* shape = new IfcSchema::IfcProductDefinitionShape(0, 0, reps); + file.AddEntity(rep); + file.AddEntity(shape); + + product->setRepresentation(shape); +} + +void create_surfaces_from_profile(IfcHierarchyHelper& file, IfcSchema::IfcProfileDef* profile) { + IfcSchema::IfcSurfaceOfLinearExtrusion* extrusion = new IfcSchema::IfcSurfaceOfLinearExtrusion(profile, file.addPlacement3d(), file.addTriplet(0, 0, 1), 100.); + file.AddEntity(extrusion); + + IfcSchema::IfcAxis1Placement* ax1 = new IfcSchema::IfcAxis1Placement(file.addTriplet(0,100,0), file.addTriplet(1,0,0)); + IfcSchema::IfcSurfaceOfRevolution* revolution = new IfcSchema::IfcSurfaceOfRevolution(profile, file.addPlacement3d(), ax1); + file.AddEntity(ax1); + file.AddEntity(revolution); + + create_product_from_item(file, extrusion, "GeometricSet"); + create_product_from_item(file, revolution, "GeometricSet"); +} + +void create_solids_from_profile(IfcHierarchyHelper& file, IfcSchema::IfcProfileDef* profile) { + IfcSchema::IfcExtrudedAreaSolid* extrusion = new IfcSchema::IfcExtrudedAreaSolid(profile, file.addPlacement3d(), file.addTriplet(0, 0, 1), 100.); + file.AddEntity(extrusion); + + IfcSchema::IfcAxis1Placement* ax1 = new IfcSchema::IfcAxis1Placement(file.addTriplet(0,100,0), file.addTriplet(1,0,0)); + IfcSchema::IfcRevolvedAreaSolid* revolution1 = new IfcSchema::IfcRevolvedAreaSolid(profile, file.addPlacement3d(), ax1, 360.); + IfcSchema::IfcRevolvedAreaSolid* revolution2 = new IfcSchema::IfcRevolvedAreaSolid(profile, file.addPlacement3d(), ax1, 90.); + file.AddEntity(ax1); + file.AddEntity(revolution1); + file.AddEntity(revolution2); + + create_product_from_item(file, extrusion, "SweptSolid"); + create_product_from_item(file, revolution1, "SweptSolid"); + create_product_from_item(file, revolution2, "SweptSolid"); +} + +void create_products_from_curve(IfcHierarchyHelper& file, IfcSchema::IfcBoundedCurve* curve) { + IfcSchema::IfcArbitraryOpenProfileDef* open = new IfcSchema::IfcArbitraryOpenProfileDef(IfcSchema::IfcProfileTypeEnum::IfcProfileType_CURVE, null, curve); + IfcSchema::IfcCenterLineProfileDef* center_line = new IfcSchema::IfcCenterLineProfileDef(IfcSchema::IfcProfileTypeEnum::IfcProfileType_AREA, null, curve, 10.); + file.AddEntity(open); + file.AddEntity(center_line); + + create_surfaces_from_profile(file, open); + create_solids_from_profile(file, center_line); +} + +int main(int argc, char** argv) { + const char filename[] = "IfcArbitraryOpenProfileDef.ifc"; + IfcHierarchyHelper file; + file.filename(filename); + + double coords1[] = {-50.0, 0.0}; + double coords2[] = { 50.0, 0.0}; + IfcSchema::IfcCartesianPoint::list points (new IfcTemplatedEntityList()); + points->push(new IfcSchema::IfcCartesianPoint(std::vector(coords1, coords1+2))); + points->push(new IfcSchema::IfcCartesianPoint(std::vector(coords2, coords2+2))); + file.AddEntities(points->generalize()); + IfcSchema::IfcPolyline* poly = new IfcSchema::IfcPolyline(points); + file.AddEntity(poly); + + create_products_from_curve(file, poly); + + IfcSchema::IfcEllipse* ellipse = new IfcSchema::IfcEllipse(file.addPlacement2d(), 50., 25.); + file.AddEntity(ellipse); + IfcEntities trim1(new IfcEntityList()); + IfcEntities trim2(new IfcEntityList()); + trim1->push(new IfcWrite::IfcSelectHelper( 0., Ifc2x3::Type::IfcParameterValue)); + trim2->push(new IfcWrite::IfcSelectHelper(180., Ifc2x3::Type::IfcParameterValue)); + IfcSchema::IfcTrimmedCurve* trim = new IfcSchema::IfcTrimmedCurve(ellipse, trim1, trim2, true, IfcSchema::IfcTrimmingPreference::IfcTrimmingPreference_PARAMETER); + file.AddEntity(trim); + + create_products_from_curve(file, trim); + + file.getSingle()->setName("IfcArbitraryOpenProfileDef"); + + std::ofstream f(filename); + f << file; +} diff --git a/src/ifcgeom/IfcGeom.h b/src/ifcgeom/IfcGeom.h index b187fd0c40..270c19d5b4 100644 --- a/src/ifcgeom/IfcGeom.h +++ b/src/ifcgeom/IfcGeom.h @@ -80,6 +80,7 @@ namespace IfcGeom { }; bool convert_wire_to_face(const TopoDS_Wire& wire, TopoDS_Face& face); + bool convert_curve_to_wire(const Handle(Geom_Curve)& curve, TopoDS_Wire& wire); bool convert_shapes(const IfcUtil::IfcBaseClass* L, IfcRepresentationShapeItems& result); bool is_shape_collection(const IfcUtil::IfcBaseClass* L); bool convert_shape(const IfcUtil::IfcBaseClass* L, TopoDS_Shape& result); diff --git a/src/ifcgeom/IfcGeomFaces.cpp b/src/ifcgeom/IfcGeomFaces.cpp index 9532a53151..231809b300 100644 --- a/src/ifcgeom/IfcGeomFaces.cpp +++ b/src/ifcgeom/IfcGeomFaces.cpp @@ -50,23 +50,27 @@ #include #include #include +#include + +#include +#include #include +#include + #include #include #include #include #include +#include +#include #include #include #include #include -#include -#include -#include -#include #include #include @@ -76,6 +80,10 @@ #include #include +#include + +#include + #include "../ifcgeom/IfcGeom.h" bool 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) { // return face_area(face) > 0.0001; return true; } + bool IfcGeom::convert(const IfcSchema::IfcArbitraryClosedProfileDef::ptr l, TopoDS_Face& face) { TopoDS_Wire wire; if ( ! IfcGeom::convert_wire(l->OuterCurve(),wire) ) return false; return IfcGeom::convert_wire_to_face(wire,face); } + bool IfcGeom::convert(const IfcSchema::IfcArbitraryProfileDefWithVoids::ptr l, TopoDS_Face& face) { TopoDS_Wire profile; if ( ! IfcGeom::convert_wire(l->OuterCurve(),profile) ) return false; @@ -204,6 +214,7 @@ bool IfcGeom::convert(const IfcSchema::IfcArbitraryProfileDefWithVoids::ptr l, T face = TopoDS::Face(sfs.Shape()); return true; } + bool IfcGeom::convert(const IfcSchema::IfcRectangleProfileDef::ptr l, TopoDS_Face& face) { const double x = l->XDim() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT); 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 double coords[8] = {-x,-y,x,-y,x,y,-x,y}; return IfcGeom::profile_helper(4,coords,0,0,0,trsf2d,face); } + bool IfcGeom::convert(const IfcSchema::IfcRoundedRectangleProfileDef::ptr l, TopoDS_Face& face) { const double x = l->XDim() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT); 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 double radii[4] = {r,r,r,r}; return IfcGeom::profile_helper(4,coords,4,fillets,radii,trsf2d,face); } + bool IfcGeom::convert(const IfcSchema::IfcRectangleHollowProfileDef::ptr l, TopoDS_Face& face) { const double x = l->XDim() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT); 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 face = TopoDS::Face(sfs.Shape()); return true; } + bool IfcGeom::convert(const IfcSchema::IfcTrapeziumProfileDef::ptr l, TopoDS_Face& face) { const double x1 = l->BottomXDim() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT); const double w = l->TopXDim() * IfcGeom::GetValue(GV_LENGTH_UNIT); @@ -297,6 +311,7 @@ bool IfcGeom::convert(const IfcSchema::IfcTrapeziumProfileDef::ptr l, TopoDS_Fac double coords[8] = {-x1,-y, x1,-y, dx+w-x1,y, dx-x1,y}; return IfcGeom::profile_helper(4,coords,0,0,0,trsf2d,face); } + bool IfcGeom::convert(const IfcSchema::IfcIShapeProfileDef::ptr l, TopoDS_Face& face) { const double x = l->OverallWidth() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT); 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& double radii[4] = {f,f,f,f}; return IfcGeom::profile_helper(12,coords,doFillet ? 4 : 0,fillets,radii,trsf2d,face); } + bool IfcGeom::convert(const IfcSchema::IfcZShapeProfileDef::ptr l, TopoDS_Face& face) { const double x = l->FlangeWidth() * IfcGeom::GetValue(GV_LENGTH_UNIT); 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& double radii[4] = {f2,f1,f2,f1}; return IfcGeom::profile_helper(8,coords,(doFillet || doEdgeFillet) ? 4 : 0,fillets,radii,trsf2d,face); } + bool IfcGeom::convert(const IfcSchema::IfcCShapeProfileDef::ptr l, TopoDS_Face& face) { const double y = l->Depth() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT); 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& double radii[8] = {f2,f2,f1,f1,f1,f1,f2,f2}; return IfcGeom::profile_helper(12,coords,doFillet ? 8 : 0,fillets,radii,trsf2d,face); } + bool IfcGeom::convert(const IfcSchema::IfcLShapeProfileDef::ptr l, TopoDS_Face& face) { const bool hasSlope = l->hasLegSlope(); const bool doEdgeFillet = l->hasEdgeRadius(); @@ -447,6 +465,7 @@ bool IfcGeom::convert(const IfcSchema::IfcLShapeProfileDef::ptr l, TopoDS_Face& double radii[3] = {f2,f1,f2}; return IfcGeom::profile_helper(6,coords,doFillet ? 3 : 0,fillets,radii,trsf2d,face); } + bool IfcGeom::convert(const IfcSchema::IfcUShapeProfileDef::ptr l, TopoDS_Face& face) { const bool doEdgeFillet = l->hasEdgeRadius(); const bool doFillet = l->hasFilletRadius(); @@ -488,6 +507,7 @@ bool IfcGeom::convert(const IfcSchema::IfcUShapeProfileDef::ptr l, TopoDS_Face& double radii[4] = {f2,f1,f1,f2}; return IfcGeom::profile_helper(8, coords, (doFillet || doEdgeFillet) ? 4 : 0, fillets, radii, trsf2d, face); } + bool IfcGeom::convert(const IfcSchema::IfcTShapeProfileDef::ptr l, TopoDS_Face& face) { const bool doFlangeEdgeFillet = l->hasFlangeEdgeRadius(); const bool doWebEdgeFillet = l->hasWebEdgeRadius(); @@ -570,6 +590,7 @@ bool IfcGeom::convert(const IfcSchema::IfcTShapeProfileDef::ptr l, TopoDS_Face& double radii[6] = {f2,f1,f3,f3,f1,f2}; return IfcGeom::profile_helper(8, coords, (doFillet || doWebEdgeFillet || doFlangeEdgeFillet) ? 6 : 0, fillets, radii, trsf2d, face); } + bool IfcGeom::convert(const IfcSchema::IfcCircleProfileDef::ptr l, TopoDS_Face& face) { const double r = l->Radius() * IfcGeom::GetValue(GV_LENGTH_UNIT); if ( r == 0.0f ) { @@ -587,6 +608,7 @@ bool IfcGeom::convert(const IfcSchema::IfcCircleProfileDef::ptr l, TopoDS_Face& w.Add(edge); return IfcGeom::convert_wire_to_face(w,face); } + bool IfcGeom::convert(const IfcSchema::IfcCircleHollowProfileDef::ptr l, TopoDS_Face& face) { const double r = l->Radius() * IfcGeom::GetValue(GV_LENGTH_UNIT); const double t = l->WallThickness() * IfcGeom::GetValue(GV_LENGTH_UNIT); @@ -615,6 +637,7 @@ bool IfcGeom::convert(const IfcSchema::IfcCircleHollowProfileDef::ptr l, TopoDS_ face = TopoDS::Face(sfs.Shape()); return true; } + bool IfcGeom::convert(const IfcSchema::IfcEllipseProfileDef::ptr l, TopoDS_Face& face) { double rx = l->SemiAxis1() * IfcGeom::GetValue(GV_LENGTH_UNIT); double ry = l->SemiAxis2() * IfcGeom::GetValue(GV_LENGTH_UNIT); @@ -640,4 +663,53 @@ bool IfcGeom::convert(const IfcSchema::IfcEllipseProfileDef::ptr l, TopoDS_Face& TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(ellipse); w.Add(edge); return IfcGeom::convert_wire_to_face(w, face); -} \ No newline at end of file +} + +bool IfcGeom::convert(const IfcSchema::IfcCenterLineProfileDef::ptr l, TopoDS_Face& face) { + const double d = l->Thickness() * IfcGeom::GetValue(GV_LENGTH_UNIT) / 2.; + + TopoDS_Wire wire; + if (!IfcGeom::convert_wire(l->Curve(), wire)) return false; + + // BRepOffsetAPI_MakeOffset insists on creating circular arc + // segments for joining the curves that constitute the center + // line. This is probably not in accordance with the IFC spec. + // Although it does not specify a method to join segments + // explicitly, it does dictate 'a constant thickness along the + // curve'. Therefore for simple singular wires a quick + // alternative is provided that uses a straight join. + + TopExp_Explorer exp(wire, TopAbs_EDGE); + TopoDS_Edge edge = TopoDS::Edge(exp.Current()); + exp.Next(); + + if (!exp.More()) { + double u1, u2; + Handle(Geom_Curve) curve = BRep_Tool::Curve(edge, u1, u2); + + Handle(Geom_TrimmedCurve) trim = new Geom_TrimmedCurve(curve, u1, u2); + + Handle(Geom_OffsetCurve) c1 = new Geom_OffsetCurve(trim, d, gp::DZ()); + Handle(Geom_OffsetCurve) c2 = new Geom_OffsetCurve(trim, -d, gp::DZ()); + + gp_Pnt c1a, c1b, c2a, c2b; + c1->D0(c1->FirstParameter(), c1a); + c1->D0(c1->LastParameter(), c1b); + c2->D0(c2->FirstParameter(), c2a); + c2->D0(c2->LastParameter(), c2b); + + BRepBuilderAPI_MakeWire mw; + mw.Add(BRepBuilderAPI_MakeEdge(c1)); + mw.Add(BRepBuilderAPI_MakeEdge(c1a, c2a)); + mw.Add(BRepBuilderAPI_MakeEdge(c2)); + mw.Add(BRepBuilderAPI_MakeEdge(c2b, c1b)); + + face = BRepBuilderAPI_MakeFace(mw.Wire()); + } else { + BRepOffsetAPI_MakeOffset offset(BRepBuilderAPI_MakeFace(gp_Pln(gp::Origin(), gp::DZ()))); + offset.AddWire(wire); + offset.Perform(d); + face = BRepBuilderAPI_MakeFace(TopoDS::Wire(offset)); + } + return true; +} diff --git a/src/ifcgeom/IfcGeomFunctions.cpp b/src/ifcgeom/IfcGeomFunctions.cpp index 7739cd3897..ab3e0fdb08 100644 --- a/src/ifcgeom/IfcGeomFunctions.cpp +++ b/src/ifcgeom/IfcGeomFunctions.cpp @@ -317,6 +317,12 @@ bool IfcGeom::convert_wire_to_face(const TopoDS_Wire& wire, TopoDS_Face& face) { face = mf.Face(); return true; } + +bool IfcGeom::convert_curve_to_wire(const Handle(Geom_Curve)& curve, TopoDS_Wire& wire) { + wire = BRepBuilderAPI_MakeWire(BRepBuilderAPI_MakeEdge(curve)); + return true; +} + bool IfcGeom::profile_helper(int numVerts, double* verts, int numFillets, int* filletIndices, double* filletRadii, gp_Trsf2d trsf, TopoDS_Face& face) { TopoDS_Vertex* vertices = new TopoDS_Vertex[numVerts]; diff --git a/src/ifcgeom/IfcGeomHelpers.cpp b/src/ifcgeom/IfcGeomHelpers.cpp index 69d89d00fa..0c58924e83 100644 --- a/src/ifcgeom/IfcGeomHelpers.cpp +++ b/src/ifcgeom/IfcGeomHelpers.cpp @@ -131,6 +131,15 @@ bool IfcGeom::convert(const IfcSchema::IfcAxis2Placement3D::ptr l, gp_Trsf& trsf CACHE(IfcAxis2Placement3D,l,trsf) return true; } +bool IfcGeom::convert(const IfcSchema::IfcAxis1Placement::ptr l, gp_Ax1& ax) { + IN_CACHE(IfcAxis1Placement,l,gp_Ax1,ax) + gp_Pnt o;gp_Dir axis = gp_Dir(0,0,1); + IfcGeom::convert(l->Location(),o); + if ( l->hasAxis() ) IfcGeom::convert(l->Axis(), axis); + ax = gp_Ax1(o, axis); + CACHE(IfcAxis1Placement,l,ax) + return true; +} bool IfcGeom::convert(const IfcSchema::IfcCartesianTransformationOperator3D::ptr l, gp_Trsf& trsf) { IN_CACHE(IfcCartesianTransformationOperator3D,l,gp_Trsf,trsf) gp_Pnt origin; diff --git a/src/ifcgeom/IfcGeomShapes.cpp b/src/ifcgeom/IfcGeomShapes.cpp index 5ae2547256..aeb2138d65 100644 --- a/src/ifcgeom/IfcGeomShapes.cpp +++ b/src/ifcgeom/IfcGeomShapes.cpp @@ -35,6 +35,7 @@ #include #include #include +#include #include #include #include @@ -62,6 +63,7 @@ #include #include +#include #include #include #include @@ -92,6 +94,70 @@ bool IfcGeom::convert(const IfcSchema::IfcExtrudedAreaSolid::ptr l, TopoDS_Shape shape.Move(trsf); return ! shape.IsNull(); } + +bool IfcGeom::convert(const IfcSchema::IfcSurfaceOfLinearExtrusion::ptr l, TopoDS_Shape& shape) { + TopoDS_Wire wire; + if ( !IfcGeom::convert_wire(l->SweptCurve(), wire) ) { + TopoDS_Face face; + if ( !IfcGeom::convert_face(l->SweptCurve(),face) ) return false; + TopExp_Explorer exp(face, TopAbs_WIRE); + wire = TopoDS::Wire(exp.Current()); + } + const double height = l->Depth() * IfcGeom::GetValue(GV_LENGTH_UNIT); + gp_Trsf trsf; + IfcGeom::convert(l->Position(),trsf); + + gp_Dir dir; + convert(l->ExtrudedDirection(),dir); + + shape = BRepPrimAPI_MakePrism(wire, height*dir); + shape.Move(trsf); + return !shape.IsNull(); +} + +bool IfcGeom::convert(const IfcSchema::IfcSurfaceOfRevolution::ptr l, TopoDS_Shape& shape) { + TopoDS_Wire wire; + if ( !IfcGeom::convert_wire(l->SweptCurve(), wire) ) { + TopoDS_Face face; + if ( !IfcGeom::convert_face(l->SweptCurve(),face) ) return false; + TopExp_Explorer exp(face, TopAbs_WIRE); + wire = TopoDS::Wire(exp.Current()); + } + + gp_Ax1 ax1; + IfcGeom::convert(l->AxisPosition(), ax1); + + gp_Trsf trsf; + IfcGeom::convert(l->Position(),trsf); + + shape = BRepPrimAPI_MakeRevol(wire, ax1); + + shape.Move(trsf); + return !shape.IsNull(); +} + +bool IfcGeom::convert(const IfcSchema::IfcRevolvedAreaSolid::ptr l, TopoDS_Shape& shape) { + const double ang = l->Angle() * IfcGeom::GetValue(GV_PLANEANGLE_UNIT); + + TopoDS_Face face; + if ( ! IfcGeom::convert_face(l->SweptArea(),face) ) return false; + + gp_Ax1 ax1; + IfcGeom::convert(l->Axis(), ax1); + + gp_Trsf trsf; + IfcGeom::convert(l->Position(),trsf); + + if (ang >= M_PI * 2. - ALMOST_ZERO) { + shape = BRepPrimAPI_MakeRevol(face, ax1); + } else { + shape = BRepPrimAPI_MakeRevol(face, ax1, ang); + } + + shape.Move(trsf); + return !shape.IsNull(); +} + bool IfcGeom::convert(const IfcSchema::IfcFacetedBrep::ptr l, IfcRepresentationShapeItems& shape) { TopoDS_Shape s; if (IfcGeom::convert_shape(l->Outer(),s) ) { @@ -100,6 +166,7 @@ bool IfcGeom::convert(const IfcSchema::IfcFacetedBrep::ptr l, IfcRepresentationS } return false; } + bool IfcGeom::convert(const IfcSchema::IfcFaceBasedSurfaceModel::ptr l, IfcRepresentationShapeItems& shapes) { IfcSchema::IfcConnectedFaceSet::list facesets = l->FbsmFaces(); const SurfaceStyle* collective_style = get_style(l); @@ -112,6 +179,7 @@ bool IfcGeom::convert(const IfcSchema::IfcFaceBasedSurfaceModel::ptr l, IfcRepre } return true; } + bool IfcGeom::convert(const IfcSchema::IfcHalfSpaceSolid::ptr l, TopoDS_Shape& shape) { IfcSchema::IfcSurface::ptr surface = l->BaseSurface(); if ( ! surface->is(IfcSchema::Type::IfcPlane) ) { @@ -124,6 +192,7 @@ bool IfcGeom::convert(const IfcSchema::IfcHalfSpaceSolid::ptr l, TopoDS_Shape& s shape = BRepPrimAPI_MakeHalfSpace(BRepBuilderAPI_MakeFace(pln),pnt).Solid(); return true; } + bool IfcGeom::convert(const IfcSchema::IfcPolygonalBoundedHalfSpace::ptr l, TopoDS_Shape& shape) { TopoDS_Shape halfspace; if ( ! IfcGeom::convert(reinterpret_pointer_cast(l),halfspace) ) return false; @@ -137,6 +206,7 @@ bool IfcGeom::convert(const IfcSchema::IfcPolygonalBoundedHalfSpace::ptr l, Topo shape = BRepAlgoAPI_Common(halfspace,prism); return true; } + bool IfcGeom::convert(const IfcSchema::IfcShellBasedSurfaceModel::ptr l, IfcRepresentationShapeItems& shapes) { IfcUtil::IfcAbstractSelect::list shells = l->SbsmBoundary(); const SurfaceStyle* collective_style = get_style(l); @@ -152,6 +222,7 @@ bool IfcGeom::convert(const IfcSchema::IfcShellBasedSurfaceModel::ptr l, IfcRepr } return true; } + bool IfcGeom::convert(const IfcSchema::IfcBooleanClippingResult::ptr l, TopoDS_Shape& shape) { TopoDS_Shape s1, s2; TopoDS_Wire boundary_wire; @@ -205,6 +276,7 @@ bool IfcGeom::convert(const IfcSchema::IfcBooleanClippingResult::ptr l, TopoDS_S return true; } + bool IfcGeom::convert(const IfcSchema::IfcConnectedFaceSet::ptr l, TopoDS_Shape& shape) { IfcSchema::IfcFace::list faces = l->CfsFaces(); bool facesAdded = false; @@ -249,6 +321,7 @@ bool IfcGeom::convert(const IfcSchema::IfcConnectedFaceSet::ptr l, TopoDS_Shape& } return true; } + bool IfcGeom::convert(const IfcSchema::IfcMappedItem::ptr l, IfcRepresentationShapeItems& shapes) { gp_GTrsf gtrsf; IfcSchema::IfcCartesianTransformationOperator::ptr transform = l->MappingTarget(); @@ -301,4 +374,22 @@ bool IfcGeom::convert(const IfcSchema::IfcShapeRepresentation::ptr l, IfcReprese } } return true; +} + +bool IfcGeom::convert(const IfcSchema::IfcGeometricSet::ptr l, IfcRepresentationShapeItems& shapes) { + IfcUtil::IfcAbstractSelect::list elements = l->Elements(); + if ( !elements->Size() ) return false; + const IfcGeom::SurfaceStyle* parent_style = get_style(l); + for ( IfcUtil::IfcAbstractSelect::it it = elements->begin(); it != elements->end(); ++ it ) { + IfcSchema::IfcGeometricSetSelect element = *it; + if (element->is(IfcSchema::Type::IfcSurface)) { + IfcSchema::IfcSurface* surface = (IfcSchema::IfcSurface*) element; + TopoDS_Shape s; + if (IfcGeom::convert_shape(surface, s)) { + const IfcGeom::SurfaceStyle* style = get_style(surface); + shapes.push_back(IfcRepresentationShapeItem(s, style ? style : parent_style)); + } + } + } + return true; } \ No newline at end of file diff --git a/src/ifcgeom/IfcGeomWires.cpp b/src/ifcgeom/IfcGeomWires.cpp index b86bb6308a..9d6840d3c0 100644 --- a/src/ifcgeom/IfcGeomWires.cpp +++ b/src/ifcgeom/IfcGeomWires.cpp @@ -306,4 +306,7 @@ bool IfcGeom::convert(const IfcSchema::IfcPolyLoop::ptr l, TopoDS_Wire& result) result = w.Wire(); return true; -} \ No newline at end of file +} +bool IfcGeom::convert(const IfcSchema::IfcArbitraryOpenProfileDef::ptr l, TopoDS_Wire& result) { + return IfcGeom::convert_wire(l->Curve(), result); +} diff --git a/src/ifcgeom/IfcRegister.cpp b/src/ifcgeom/IfcRegister.cpp index d38b3d9766..50a90f6cd8 100644 --- a/src/ifcgeom/IfcRegister.cpp +++ b/src/ifcgeom/IfcRegister.cpp @@ -58,6 +58,10 @@ bool IfcGeom::convert_shape(const IfcBaseClass* l, TopoDS_Shape& r) { } bool IfcGeom::convert_wire(const IfcBaseClass* l, TopoDS_Wire& r) { #include "IfcRegisterConvertWire.h" + Handle(Geom_Curve) curve; + if (IfcGeom::convert_curve(l, curve)) { + return IfcGeom::convert_curve_to_wire(curve, r); + } Logger::Message(Logger::LOG_ERROR,"No operation defined for:",l->entity); return false; } diff --git a/src/ifcgeom/IfcRegister.h b/src/ifcgeom/IfcRegister.h index 0055947b14..73abda60d9 100644 --- a/src/ifcgeom/IfcRegister.h +++ b/src/ifcgeom/IfcRegister.h @@ -48,12 +48,16 @@ SHAPES(IfcFaceBasedSurfaceModel); SHAPES(IfcShapeRepresentation); SHAPES(IfcMappedItem); SHAPES(IfcFacetedBrep); +SHAPES(IfcGeometricSet); SHAPE(IfcExtrudedAreaSolid); +SHAPE(IfcRevolvedAreaSolid); SHAPE(IfcConnectedFaceSet); SHAPE(IfcBooleanClippingResult); SHAPE(IfcPolygonalBoundedHalfSpace); SHAPE(IfcHalfSpaceSolid); +SHAPE(IfcSurfaceOfLinearExtrusion); +SHAPE(IfcSurfaceOfRevolution); FACE(IfcArbitraryProfileDefWithVoids); FACE(IfcArbitraryClosedProfileDef); @@ -70,12 +74,14 @@ FACE(IfcZShapeProfileDef); FACE(IfcCircleHollowProfileDef); FACE(IfcCircleProfileDef); FACE(IfcEllipseProfileDef); +FACE(IfcCenterLineProfileDef); FACE(IfcFace); WIRE(IfcPolyline); WIRE(IfcPolyLoop); WIRE(IfcCompositeCurve); WIRE(IfcTrimmedCurve); +WIRE(IfcArbitraryOpenProfileDef); CURVE(IfcCircle); CURVE(IfcEllipse); @@ -85,6 +91,7 @@ CLASS(IfcCartesianPoint,gp_Pnt); CLASS(IfcDirection,gp_Dir); CLASS(IfcAxis2Placement2D,gp_Trsf2d); CLASS(IfcAxis2Placement3D,gp_Trsf); +CLASS(IfcAxis1Placement,gp_Ax1); CLASS(IfcCartesianTransformationOperator2DnonUniform,gp_GTrsf2d); CLASS(IfcCartesianTransformationOperator3DnonUniform,gp_GTrsf); CLASS(IfcCartesianTransformationOperator2D,gp_Trsf2d);