diff --git a/src/ifcgeom/IfcGeom.h b/src/ifcgeom/IfcGeom.h index 3b7bc0cb46..e427a34130 100644 --- a/src/ifcgeom/IfcGeom.h +++ b/src/ifcgeom/IfcGeom.h @@ -86,7 +86,7 @@ namespace IfcGeom { bool convert_shape(const IfcUtil::IfcBaseClass* L, TopoDS_Shape& result); bool convert_wire(const IfcUtil::IfcBaseClass* L, TopoDS_Wire& result); bool convert_curve(const IfcUtil::IfcBaseClass* L, Handle(Geom_Curve)& result); - bool convert_face(const IfcUtil::IfcBaseClass* L, TopoDS_Face& result); + bool convert_face(const IfcUtil::IfcBaseClass* L, TopoDS_Shape& result); bool convert_openings(const IfcSchema::IfcProduct::ptr entity, const IfcSchema::IfcRelVoidsElement::list& openings, const IfcRepresentationShapeItems& entity_shapes, const gp_Trsf& entity_trsf, IfcRepresentationShapeItems& cut_shapes); bool convert_openings_fast(const IfcSchema::IfcProduct::ptr entity, const IfcSchema::IfcRelVoidsElement::list& openings, const IfcRepresentationShapeItems& entity_shapes, const gp_Trsf& entity_trsf, IfcRepresentationShapeItems& cut_shapes); IfcSchema::IfcSurfaceStyleShading* get_surface_style(IfcSchema::IfcRepresentationItem* item); @@ -97,7 +97,7 @@ namespace IfcGeom { gp_Pln plane_from_face(const TopoDS_Face& face); gp_Pnt point_above_plane(const gp_Pln& pln, bool agree=true); const TopoDS_Shape& ensure_fit_for_subtraction(const TopoDS_Shape& shape, TopoDS_Shape& solid); - bool profile_helper(int numVerts, double* verts, int numFillets, int* filletIndices, double* filletRadii, gp_Trsf2d trsf, TopoDS_Face& face); + bool profile_helper(int numVerts, double* verts, int numFillets, int* filletIndices, double* filletRadii, gp_Trsf2d trsf, TopoDS_Shape& face); double shape_volume(const TopoDS_Shape& s); double face_area(const TopoDS_Face& f); void apply_tolerance(TopoDS_Shape& s, double t); diff --git a/src/ifcgeom/IfcGeomFaces.cpp b/src/ifcgeom/IfcGeomFaces.cpp index 231809b300..8fc72eaf00 100644 --- a/src/ifcgeom/IfcGeomFaces.cpp +++ b/src/ifcgeom/IfcGeomFaces.cpp @@ -83,10 +83,11 @@ #include #include +#include #include "../ifcgeom/IfcGeom.h" -bool IfcGeom::convert(const IfcSchema::IfcFace::ptr l, TopoDS_Face& face) { +bool IfcGeom::convert(const IfcSchema::IfcFace::ptr l, TopoDS_Shape& face) { IfcSchema::IfcFaceBound::list bounds = l->Bounds(); IfcSchema::IfcFaceBound::it it = bounds->begin(); IfcSchema::IfcLoop::ptr loop = (*it)->Bound(); @@ -133,7 +134,7 @@ bool IfcGeom::convert(const IfcSchema::IfcFace::ptr l, TopoDS_Face& face) { // as a simple edge cross product can give opposite results // for a concave face boundary. // Reference: Graphics Gems III p. 231 - BRepGProp_Face prop(face); + BRepGProp_Face prop(TopoDS::Face(face)); gp_Vec normal_direction; gp_Pnt center; double u1,u2,v1,v2; @@ -192,13 +193,17 @@ bool IfcGeom::convert(const IfcSchema::IfcFace::ptr l, TopoDS_Face& face) { return true; } -bool IfcGeom::convert(const IfcSchema::IfcArbitraryClosedProfileDef::ptr l, TopoDS_Face& face) { +bool IfcGeom::convert(const IfcSchema::IfcArbitraryClosedProfileDef::ptr l, TopoDS_Shape& face) { TopoDS_Wire wire; if ( ! IfcGeom::convert_wire(l->OuterCurve(),wire) ) return false; - return IfcGeom::convert_wire_to_face(wire,face); + + TopoDS_Face f; + bool success = IfcGeom::convert_wire_to_face(wire, f); + if (success) face = f; + return success; } -bool IfcGeom::convert(const IfcSchema::IfcArbitraryProfileDefWithVoids::ptr l, TopoDS_Face& face) { +bool IfcGeom::convert(const IfcSchema::IfcArbitraryProfileDefWithVoids::ptr l, TopoDS_Shape& face) { TopoDS_Wire profile; if ( ! IfcGeom::convert_wire(l->OuterCurve(),profile) ) return false; BRepBuilderAPI_MakeFace mf(profile); @@ -215,7 +220,7 @@ bool IfcGeom::convert(const IfcSchema::IfcArbitraryProfileDefWithVoids::ptr l, T return true; } -bool IfcGeom::convert(const IfcSchema::IfcRectangleProfileDef::ptr l, TopoDS_Face& face) { +bool IfcGeom::convert(const IfcSchema::IfcRectangleProfileDef::ptr l, TopoDS_Shape& 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); @@ -230,7 +235,7 @@ bool IfcGeom::convert(const IfcSchema::IfcRectangleProfileDef::ptr l, TopoDS_Fac return IfcGeom::profile_helper(4,coords,0,0,0,trsf2d,face); } -bool IfcGeom::convert(const IfcSchema::IfcRoundedRectangleProfileDef::ptr l, TopoDS_Face& face) { +bool IfcGeom::convert(const IfcSchema::IfcRoundedRectangleProfileDef::ptr l, TopoDS_Shape& 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); const double r = l->RoundingRadius() * IfcGeom::GetValue(GV_LENGTH_UNIT); @@ -248,7 +253,7 @@ bool IfcGeom::convert(const IfcSchema::IfcRoundedRectangleProfileDef::ptr l, Top return IfcGeom::profile_helper(4,coords,4,fillets,radii,trsf2d,face); } -bool IfcGeom::convert(const IfcSchema::IfcRectangleHollowProfileDef::ptr l, TopoDS_Face& face) { +bool IfcGeom::convert(const IfcSchema::IfcRectangleHollowProfileDef::ptr l, TopoDS_Shape& 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); const double d = l->WallThickness() * IfcGeom::GetValue(GV_LENGTH_UNIT); @@ -295,7 +300,7 @@ bool IfcGeom::convert(const IfcSchema::IfcRectangleHollowProfileDef::ptr l, Topo return true; } -bool IfcGeom::convert(const IfcSchema::IfcTrapeziumProfileDef::ptr l, TopoDS_Face& face) { +bool IfcGeom::convert(const IfcSchema::IfcTrapeziumProfileDef::ptr l, TopoDS_Shape& face) { const double x1 = l->BottomXDim() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT); const double w = l->TopXDim() * IfcGeom::GetValue(GV_LENGTH_UNIT); const double dx = l->TopXOffset() * IfcGeom::GetValue(GV_LENGTH_UNIT); @@ -312,7 +317,7 @@ bool IfcGeom::convert(const IfcSchema::IfcTrapeziumProfileDef::ptr l, TopoDS_Fac return IfcGeom::profile_helper(4,coords,0,0,0,trsf2d,face); } -bool IfcGeom::convert(const IfcSchema::IfcIShapeProfileDef::ptr l, TopoDS_Face& face) { +bool IfcGeom::convert(const IfcSchema::IfcIShapeProfileDef::ptr l, TopoDS_Shape& 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); const double d1 = l->WebThickness() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT); @@ -337,7 +342,7 @@ bool IfcGeom::convert(const IfcSchema::IfcIShapeProfileDef::ptr l, TopoDS_Face& return IfcGeom::profile_helper(12,coords,doFillet ? 4 : 0,fillets,radii,trsf2d,face); } -bool IfcGeom::convert(const IfcSchema::IfcZShapeProfileDef::ptr l, TopoDS_Face& face) { +bool IfcGeom::convert(const IfcSchema::IfcZShapeProfileDef::ptr l, TopoDS_Shape& face) { const double x = l->FlangeWidth() * IfcGeom::GetValue(GV_LENGTH_UNIT); const double y = l->Depth() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT); const double dx = l->WebThickness() / 2.0f * IfcGeom::GetValue(GV_LENGTH_UNIT); @@ -370,7 +375,7 @@ bool IfcGeom::convert(const IfcSchema::IfcZShapeProfileDef::ptr l, TopoDS_Face& 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) { +bool IfcGeom::convert(const IfcSchema::IfcCShapeProfileDef::ptr l, TopoDS_Shape& 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); const double d1 = l->WallThickness() * IfcGeom::GetValue(GV_LENGTH_UNIT); @@ -397,7 +402,7 @@ bool IfcGeom::convert(const IfcSchema::IfcCShapeProfileDef::ptr l, TopoDS_Face& return IfcGeom::profile_helper(12,coords,doFillet ? 8 : 0,fillets,radii,trsf2d,face); } -bool IfcGeom::convert(const IfcSchema::IfcLShapeProfileDef::ptr l, TopoDS_Face& face) { +bool IfcGeom::convert(const IfcSchema::IfcLShapeProfileDef::ptr l, TopoDS_Shape& face) { const bool hasSlope = l->hasLegSlope(); const bool doEdgeFillet = l->hasEdgeRadius(); const bool doFillet = l->hasFilletRadius(); @@ -466,7 +471,7 @@ bool IfcGeom::convert(const IfcSchema::IfcLShapeProfileDef::ptr l, TopoDS_Face& return IfcGeom::profile_helper(6,coords,doFillet ? 3 : 0,fillets,radii,trsf2d,face); } -bool IfcGeom::convert(const IfcSchema::IfcUShapeProfileDef::ptr l, TopoDS_Face& face) { +bool IfcGeom::convert(const IfcSchema::IfcUShapeProfileDef::ptr l, TopoDS_Shape& face) { const bool doEdgeFillet = l->hasEdgeRadius(); const bool doFillet = l->hasFilletRadius(); const bool hasSlope = l->hasFlangeSlope(); @@ -508,7 +513,7 @@ bool IfcGeom::convert(const IfcSchema::IfcUShapeProfileDef::ptr l, TopoDS_Face& 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) { +bool IfcGeom::convert(const IfcSchema::IfcTShapeProfileDef::ptr l, TopoDS_Shape& face) { const bool doFlangeEdgeFillet = l->hasFlangeEdgeRadius(); const bool doWebEdgeFillet = l->hasWebEdgeRadius(); const bool doFillet = l->hasFilletRadius(); @@ -591,7 +596,7 @@ bool IfcGeom::convert(const IfcSchema::IfcTShapeProfileDef::ptr l, TopoDS_Face& 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) { +bool IfcGeom::convert(const IfcSchema::IfcCircleProfileDef::ptr l, TopoDS_Shape& face) { const double r = l->Radius() * IfcGeom::GetValue(GV_LENGTH_UNIT); if ( r == 0.0f ) { Logger::Message(Logger::LOG_NOTICE,"Skipping zero sized profile:",l->entity); @@ -606,10 +611,14 @@ bool IfcGeom::convert(const IfcSchema::IfcCircleProfileDef::ptr l, TopoDS_Face& Handle(Geom_Circle) circle = new Geom_Circle(ax, r); TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(circle); w.Add(edge); - return IfcGeom::convert_wire_to_face(w,face); + + TopoDS_Face f; + bool success = IfcGeom::convert_wire_to_face(w, f); + if (success) face = f; + return success; } -bool IfcGeom::convert(const IfcSchema::IfcCircleHollowProfileDef::ptr l, TopoDS_Face& face) { +bool IfcGeom::convert(const IfcSchema::IfcCircleHollowProfileDef::ptr l, TopoDS_Shape& face) { const double r = l->Radius() * IfcGeom::GetValue(GV_LENGTH_UNIT); const double t = l->WallThickness() * IfcGeom::GetValue(GV_LENGTH_UNIT); @@ -638,7 +647,7 @@ bool IfcGeom::convert(const IfcSchema::IfcCircleHollowProfileDef::ptr l, TopoDS_ return true; } -bool IfcGeom::convert(const IfcSchema::IfcEllipseProfileDef::ptr l, TopoDS_Face& face) { +bool IfcGeom::convert(const IfcSchema::IfcEllipseProfileDef::ptr l, TopoDS_Shape& face) { double rx = l->SemiAxis1() * IfcGeom::GetValue(GV_LENGTH_UNIT); double ry = l->SemiAxis2() * IfcGeom::GetValue(GV_LENGTH_UNIT); @@ -662,10 +671,14 @@ bool IfcGeom::convert(const IfcSchema::IfcEllipseProfileDef::ptr l, TopoDS_Face& Handle(Geom_Ellipse) ellipse = new Geom_Ellipse(ax, rx, ry); TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(ellipse); w.Add(edge); - return IfcGeom::convert_wire_to_face(w, face); + + TopoDS_Face f; + bool success = IfcGeom::convert_wire_to_face(w, f); + if (success) face = f; + return success; } -bool IfcGeom::convert(const IfcSchema::IfcCenterLineProfileDef::ptr l, TopoDS_Face& face) { +bool IfcGeom::convert(const IfcSchema::IfcCenterLineProfileDef::ptr l, TopoDS_Shape& face) { const double d = l->Thickness() * IfcGeom::GetValue(GV_LENGTH_UNIT) / 2.; TopoDS_Wire wire; @@ -713,3 +726,45 @@ bool IfcGeom::convert(const IfcSchema::IfcCenterLineProfileDef::ptr l, TopoDS_Fa } return true; } + +bool IfcGeom::convert(const IfcSchema::IfcCompositeProfileDef::ptr l, TopoDS_Shape& face) { + // BRepBuilderAPI_MakeFace mf; + + TopoDS_Compound compound; + BRep_Builder builder; + builder.MakeCompound(compound); + + IfcSchema::IfcProfileDef::list profiles = l->Profiles(); + bool first = true; + for (IfcSchema::IfcProfileDef::it it = profiles->begin(); it != profiles->end(); ++it) { + TopoDS_Face f; + if (IfcGeom::convert_face(*it, f)) { + builder.Add(compound, f); + /* TopExp_Explorer exp(f, TopAbs_WIRE); + for (; exp.More(); exp.Next()) { + const TopoDS_Wire& wire = TopoDS::Wire(exp.Current()); + if (first) { + mf.Init(BRepBuilderAPI_MakeFace(wire)); + } else { + mf.Add(wire); + } + first = false; + } */ + } + } + + face = compound; + return !face.IsNull(); +} + +bool IfcGeom::convert(const IfcSchema::IfcDerivedProfileDef::ptr l, TopoDS_Shape& face) { + TopoDS_Face f; + gp_Trsf2d trsf2d; + if (IfcGeom::convert_face(l->ParentProfile(), f) && IfcGeom::convert(l->Operator(), trsf2d)) { + gp_Trsf trsf = trsf2d; + face = TopoDS::Face(BRepBuilderAPI_Transform(f, trsf)); + return true; + } else { + return false; + } +} diff --git a/src/ifcgeom/IfcGeomFunctions.cpp b/src/ifcgeom/IfcGeomFunctions.cpp index 246df018e1..0f18ab99eb 100644 --- a/src/ifcgeom/IfcGeomFunctions.cpp +++ b/src/ifcgeom/IfcGeomFunctions.cpp @@ -321,7 +321,7 @@ bool IfcGeom::convert_curve_to_wire(const Handle(Geom_Curve)& curve, TopoDS_Wire return true; } -bool IfcGeom::profile_helper(int numVerts, double* verts, int numFillets, int* filletIndices, double* filletRadii, gp_Trsf2d trsf, TopoDS_Face& face) { +bool IfcGeom::profile_helper(int numVerts, double* verts, int numFillets, int* filletIndices, double* filletRadii, gp_Trsf2d trsf, TopoDS_Shape& face_shape) { TopoDS_Vertex* vertices = new TopoDS_Vertex[numVerts]; for ( int i = 0; i < numVerts; i ++ ) { @@ -334,6 +334,7 @@ bool IfcGeom::profile_helper(int numVerts, double* verts, int numFillets, int* f for ( int i = 0; i < numVerts; i ++ ) w.Add(BRepBuilderAPI_MakeEdge(vertices[i],vertices[(i+1)%numVerts])); + TopoDS_Face face; IfcGeom::convert_wire_to_face(w.Wire(),face); if ( numFillets ) { @@ -347,6 +348,8 @@ bool IfcGeom::profile_helper(int numVerts, double* verts, int numFillets, int* f face = TopoDS::Face(fillet.Shape()); } + face_shape = face; + delete[] vertices; return true; } diff --git a/src/ifcgeom/IfcGeomHelpers.cpp b/src/ifcgeom/IfcGeomHelpers.cpp index 0c58924e83..d76ba2600b 100644 --- a/src/ifcgeom/IfcGeomHelpers.cpp +++ b/src/ifcgeom/IfcGeomHelpers.cpp @@ -98,6 +98,7 @@ bool IfcGeom::convert(const IfcSchema::IfcCartesianPoint::ptr l, gp_Pnt& point) CACHE(IfcCartesianPoint,l,point) return true; } + bool IfcGeom::convert(const IfcSchema::IfcDirection::ptr l, gp_Dir& dir) { IN_CACHE(IfcDirection,l,gp_Dir,dir) std::vector xyz = l->DirectionRatios(); @@ -109,6 +110,7 @@ bool IfcGeom::convert(const IfcSchema::IfcDirection::ptr l, gp_Dir& dir) { CACHE(IfcDirection,l,dir) return true; } + bool IfcGeom::convert(const IfcSchema::IfcVector::ptr l, gp_Vec& v) { IN_CACHE(IfcVector,l,gp_Vec,v) gp_Dir d; @@ -117,6 +119,7 @@ bool IfcGeom::convert(const IfcSchema::IfcVector::ptr l, gp_Vec& v) { CACHE(IfcVector,l,v) return true; } + bool IfcGeom::convert(const IfcSchema::IfcAxis2Placement3D::ptr l, gp_Trsf& trsf) { IN_CACHE(IfcAxis2Placement3D,l,gp_Trsf,trsf) gp_Pnt o;gp_Dir axis = gp_Dir(0,0,1);gp_Dir refDirection; @@ -131,6 +134,7 @@ 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); @@ -140,6 +144,7 @@ bool IfcGeom::convert(const IfcSchema::IfcAxis1Placement::ptr l, gp_Ax1& ax) { 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; @@ -159,19 +164,41 @@ bool IfcGeom::convert(const IfcSchema::IfcCartesianTransformationOperator3D::ptr CACHE(IfcCartesianTransformationOperator3D,l,trsf) return true; } + bool IfcGeom::convert(const IfcSchema::IfcCartesianTransformationOperator2D::ptr l, gp_Trsf2d& trsf) { IN_CACHE(IfcCartesianTransformationOperator2D,l,gp_Trsf2d,trsf) + gp_Pnt origin; - IfcGeom::convert(l->LocalOrigin(),origin); gp_Dir axis1 (1.,0.,0.); + gp_Dir axis2 (0.,1.,0.); + + IfcGeom::convert(l->LocalOrigin(),origin); if ( l->hasAxis1() ) IfcGeom::convert(l->Axis1(),axis1); - const gp_Ax2d ax2d (gp_Pnt2d(origin.X(),origin.Y()),gp_Dir2d(axis1.X(),axis1.Y())); + if ( l->hasAxis2() ) IfcGeom::convert(l->Axis2(),axis2); + + const gp_Pnt2d origin2d(origin.X(), origin.Y()); + const gp_Dir2d axis12d(axis1.X(), axis1.Y()); + const gp_Dir2d axis22d(axis2.X(), axis2.Y()); + + // A better match to represent the IfcCartesianTransformationOperator2D would + // be the gp_Ax22d, but to my knowledge no easy way exists to convert it into + // a gp_Trsf2d. Easiest would probably be to simply update the underlying + // gp_Mat2d directly. + + const gp_Ax2d ax2d (origin2d, axis12d); trsf.SetTransformation(ax2d); + + if ( ax2d.Direction().Rotated(M_PI / 2.).Dot(axis22d) < 0. ) { + gp_Trsf2d mirror; mirror.SetMirror(ax2d); + trsf.Multiply(mirror); + } + trsf.Invert(); if ( l->hasScale() ) trsf.SetScaleFactor(l->Scale()); CACHE(IfcCartesianTransformationOperator2D,l,trsf) return true; } + bool IfcGeom::convert(const IfcSchema::IfcCartesianTransformationOperator3DnonUniform::ptr l, gp_GTrsf& gtrsf) { IN_CACHE(IfcCartesianTransformationOperator3DnonUniform,l,gp_GTrsf,gtrsf) gp_Trsf trsf; @@ -199,16 +226,33 @@ bool IfcGeom::convert(const IfcSchema::IfcCartesianTransformationOperator3DnonUn CACHE(IfcCartesianTransformationOperator3DnonUniform,l,gtrsf) return true; } + bool IfcGeom::convert(const IfcSchema::IfcCartesianTransformationOperator2DnonUniform::ptr l, gp_GTrsf2d& gtrsf) { IN_CACHE(IfcCartesianTransformationOperator2DnonUniform,l,gp_GTrsf2d,gtrsf) + gp_Trsf2d trsf; gp_Pnt origin; - IfcGeom::convert(l->LocalOrigin(),origin); gp_Dir axis1 (1.,0.,0.); + gp_Dir axis2 (0.,1.,0.); + + IfcGeom::convert(l->LocalOrigin(),origin); if ( l->hasAxis1() ) IfcGeom::convert(l->Axis1(),axis1); - const gp_Ax2d ax2d (gp_Pnt2d(origin.X(),origin.Y()),gp_Dir2d(axis1.X(),axis1.Y())); + if ( l->hasAxis2() ) IfcGeom::convert(l->Axis2(),axis2); + + const gp_Pnt2d origin2d(origin.X(), origin.Y()); + const gp_Dir2d axis12d(axis1.X(), axis1.Y()); + const gp_Dir2d axis22d(axis2.X(), axis2.Y()); + + const gp_Ax2d ax2d (origin2d, axis12d); trsf.SetTransformation(ax2d); + + if ( ax2d.Direction().Rotated(M_PI / 2.).Dot(axis22d) < 0. ) { + gp_Trsf2d mirror; mirror.SetMirror(ax2d); + trsf.Multiply(mirror); + } + trsf.Invert(); + const double scale1 = l->hasScale() ? l->Scale() : 1.0f; const double scale2 = l->hasScale2() ? l->Scale2() : scale1; gtrsf = gp_GTrsf2d(); @@ -218,6 +262,7 @@ bool IfcGeom::convert(const IfcSchema::IfcCartesianTransformationOperator2DnonUn CACHE(IfcCartesianTransformationOperator2DnonUniform,l,gtrsf) return true; } + bool IfcGeom::convert(const IfcSchema::IfcPlane::ptr pln, gp_Pln& plane) { IN_CACHE(IfcPlane,pln,gp_Pln,plane) IfcSchema::IfcAxis2Placement3D::ptr l = pln->Position(); @@ -233,6 +278,7 @@ bool IfcGeom::convert(const IfcSchema::IfcPlane::ptr pln, gp_Pln& plane) { CACHE(IfcPlane,pln,plane) return true; } + bool IfcGeom::convert(const IfcSchema::IfcAxis2Placement2D::ptr l, gp_Trsf2d& trsf) { IN_CACHE(IfcAxis2Placement2D,l,gp_Trsf2d,trsf) gp_Pnt P; gp_Dir V (1,0,0); @@ -245,6 +291,7 @@ bool IfcGeom::convert(const IfcSchema::IfcAxis2Placement2D::ptr l, gp_Trsf2d& tr CACHE(IfcAxis2Placement2D,l,trsf) return true; } + bool IfcGeom::convert(const IfcSchema::IfcObjectPlacement::ptr l, gp_Trsf& trsf) { IN_CACHE(IfcObjectPlacement,l,gp_Trsf,trsf) if ( ! l->is(IfcSchema::Type::IfcLocalPlacement) ) return false; @@ -266,6 +313,7 @@ bool IfcGeom::convert(const IfcSchema::IfcObjectPlacement::ptr l, gp_Trsf& trsf) CACHE(IfcObjectPlacement,l,trsf) return true; } + void IfcGeom::Cache::Purge() { #include "IfcRegisterPurgeCache.h" IfcGeom::Cache::PurgeShapeCache(); diff --git a/src/ifcgeom/IfcRegister.cpp b/src/ifcgeom/IfcRegister.cpp index 50a90f6cd8..8452568227 100644 --- a/src/ifcgeom/IfcRegister.cpp +++ b/src/ifcgeom/IfcRegister.cpp @@ -65,7 +65,7 @@ bool IfcGeom::convert_wire(const IfcBaseClass* l, TopoDS_Wire& r) { Logger::Message(Logger::LOG_ERROR,"No operation defined for:",l->entity); return false; } -bool IfcGeom::convert_face(const IfcBaseClass* l, TopoDS_Face& r) { +bool IfcGeom::convert_face(const IfcBaseClass* l, TopoDS_Shape& r) { #include "IfcRegisterConvertFace.h" 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 73abda60d9..b074dddcf9 100644 --- a/src/ifcgeom/IfcRegister.h +++ b/src/ifcgeom/IfcRegister.h @@ -75,6 +75,8 @@ FACE(IfcCircleHollowProfileDef); FACE(IfcCircleProfileDef); FACE(IfcEllipseProfileDef); FACE(IfcCenterLineProfileDef); +FACE(IfcCompositeProfileDef); +FACE(IfcDerivedProfileDef); FACE(IfcFace); WIRE(IfcPolyline); diff --git a/src/ifcgeom/IfcRegisterGeomHeader.h b/src/ifcgeom/IfcRegisterGeomHeader.h index e8588b0fa8..aaf1b6e702 100644 --- a/src/ifcgeom/IfcRegisterGeomHeader.h +++ b/src/ifcgeom/IfcRegisterGeomHeader.h @@ -3,7 +3,7 @@ #define SHAPES(T) CLASS(T,IfcRepresentationShapeItems) #define SHAPE(T) CLASS(T,TopoDS_Shape) #define WIRE(T) CLASS(T,TopoDS_Wire) -#define FACE(T) CLASS(T,TopoDS_Face) +#define FACE(T) CLASS(T,TopoDS_Shape) #define CURVE(T) CLASS(T,Handle(Geom_Curve)) #include "IfcRegisterDef.h" diff --git a/test/input/IfcCompositeProfileDef.ifc b/test/input/IfcCompositeProfileDef.ifc new file mode 100644 index 0000000000..fb4aa34c14 --- /dev/null +++ b/test/input/IfcCompositeProfileDef.ifc @@ -0,0 +1,90 @@ +ISO-10303-21; +HEADER; +FILE_DESCRIPTION(('ViewDefinition [CoordinationView]'),'2;1'); +FILE_NAME('IfcCompositeProfileDef.ifc','2014-03-16T10:22:14',(''),('',''),'IfcOpenShell 0.5.0-dev','IfcOpenShell 0.5.0-dev',''); +FILE_SCHEMA(('IFC2X3')); +ENDSEC; +DATA; +#1=IFCCARTESIANPOINT((40.,0.)); +#2=IFCDIRECTION((0.,-1.)); +#3=IFCDIRECTION((1.,0.)); +#4=IFCCARTESIANPOINT((40.,0.)); +#5=IFCDIRECTION((1.,0.)); +#6=IFCDIRECTION((0.,-1.)); +#7=IFCDIRECTION((1.,0.)); +#8=IFCCARTESIANPOINT((0.,0.)); +#9=IFCAXIS2PLACEMENT2D(#8,#7); +#10=IFCDIRECTION((1.,0.)); +#11=IFCCARTESIANPOINT((0.,0.)); +#12=IFCAXIS2PLACEMENT2D(#11,#10); +#13=IFCDIRECTION((1.,0.)); +#14=IFCCARTESIANPOINT((0.,0.)); +#15=IFCAXIS2PLACEMENT2D(#14,#13); +#16=IFCDIRECTION((1.,0.)); +#17=IFCCARTESIANPOINT((80.,0.)); +#18=IFCAXIS2PLACEMENT2D(#17,#16); +#19=IFCLSHAPEPROFILEDEF(.AREA.,$,#12,50.,25.,5.,1.,2.,2.,$,$); +#20=IFCTSHAPEPROFILEDEF(.AREA.,$,#15,50.,40.,10.,10.,3.,2.,1.,2.,2.,$); +#21=IFCCARTESIANTRANSFORMATIONOPERATOR2D(#3,#2,#1,$); +#22=IFCCARTESIANTRANSFORMATIONOPERATOR2D(#6,#5,#4,0.3); +#23=IFCISHAPEPROFILEDEF(.AREA.,$,#9,25.,50.,5.,5.,2.); +#24=IFCDERIVEDPROFILEDEF(.AREA.,$,#19,#21,$); +#25=IFCDERIVEDPROFILEDEF(.AREA.,$,#20,#22,$); +#26=IFCCSHAPEPROFILEDEF(.AREA.,$,#18,50.,25.,5.,10.,2.,$); +#27=IFCPERSON($,$,'',$,$,$,$,$); +#28=IFCORGANIZATION($,'IfcOpenShell',$,$,$); +#29=IFCPERSONANDORGANIZATION(#27,#28,$); +#30=IFCAPPLICATION(#28,'0.5.0-dev','IfcOpenShell','IfcOpenShell'); +#31=IFCOWNERHISTORY(#29,#30,$,.ADDED.,$,#29,#30,1394961734); +#32=IFCDIRECTION((0.,1.,0.)); +#33=IFCDIRECTION((1.,0.,0.)); +#34=IFCDIRECTION((0.,0.,1.)); +#35=IFCCARTESIANPOINT((0.,0.,0.)); +#36=IFCAXIS2PLACEMENT3D(#35,#34,#33); +#37=IFCGEOMETRICREPRESENTATIONCONTEXT('Plan','Model',3,1.E-005,#36,#32); +#38=IFCDIMENSIONALEXPONENTS(0,0,0,0,0,0,0); +#39=IFCSIUNIT(*,.LENGTHUNIT.,.MILLI.,.METRE.); +#40=IFCSIUNIT(*,.PLANEANGLEUNIT.,$,.RADIAN.); +#41=IFCMEASUREWITHUNIT(IFCPLANEANGLEMEASURE(0.0174533),#40); +#42=IFCCONVERSIONBASEDUNIT(#38,.PLANEANGLEUNIT.,'Degrees',#41); +#43=IFCUNITASSIGNMENT((#39,#42)); +#44=IFCPROJECT('2ksZObKFD9HusrYk4uMUU9',#31,'IfcCompositeProfileDef',$,$,$,$,(#37),#43); +#45=IFCDIRECTION((1.,0.,0.)); +#46=IFCDIRECTION((0.,0.,1.)); +#47=IFCCARTESIANPOINT((0.,0.,0.)); +#48=IFCAXIS2PLACEMENT3D(#47,#46,#45); +#49=IFCLOCALPLACEMENT($,#48); +#50=IFCSITE('3UH8_fRJ14bO11RLWcfDaG',#31,$,$,$,#49,$,$,.ELEMENT.,$,$,$,$,$); +#51=IFCRELAGGREGATES('0d_e2pRBz5EwbcE2Jlxmor',#31,$,$,#44,(#50)); +#52=IFCDIRECTION((1.,0.,0.)); +#53=IFCDIRECTION((0.,0.,1.)); +#54=IFCCARTESIANPOINT((0.,0.,0.)); +#55=IFCAXIS2PLACEMENT3D(#54,#53,#52); +#56=IFCLOCALPLACEMENT(#49,#55); +#57=IFCBUILDING('0_d_HoUTX9CRwB2hQNCKfF',#31,$,$,$,#56,$,$,.ELEMENT.,$,$,$); +#58=IFCRELAGGREGATES('3YNTjz3UTAreL7rtMwgZja',#31,$,$,#50,(#57)); +#59=IFCDIRECTION((1.,0.,0.)); +#60=IFCDIRECTION((0.,0.,1.)); +#61=IFCCARTESIANPOINT((0.,0.,0.)); +#62=IFCAXIS2PLACEMENT3D(#61,#60,#59); +#63=IFCLOCALPLACEMENT(#56,#62); +#64=IFCBUILDINGSTOREY('2r7DzLsTvBOvBpy8KFQofF',#31,$,$,$,#63,$,$,.ELEMENT.,$); +#65=IFCRELAGGREGATES('1NiveFQ1n2N9_KPmICXHc8',#31,$,$,#57,(#64)); +#66=IFCBUILDINGELEMENTPROXY('0Xroij9BHE2BHPOGPuqa$d',#31,'profile',$,$,#72,#81,$,$); +#67=IFCRELCONTAINEDINSPATIALSTRUCTURE('0duzsVh356ivGmTWCOFWGF',#31,$,$,(#66),#64); +#68=IFCDIRECTION((1.,0.,0.)); +#69=IFCDIRECTION((0.,0.,1.)); +#70=IFCCARTESIANPOINT((0.,0.,0.)); +#71=IFCAXIS2PLACEMENT3D(#70,#69,#68); +#72=IFCLOCALPLACEMENT($,#71); +#73=IFCDIRECTION((0.,0.,1.)); +#74=IFCDIRECTION((1.,0.,0.)); +#75=IFCDIRECTION((0.,0.,1.)); +#76=IFCCARTESIANPOINT((0.,0.,0.)); +#77=IFCAXIS2PLACEMENT3D(#76,#75,#74); +#78=IFCCOMPOSITEPROFILEDEF(.AREA.,'IFC',(#23,#24,#25,#26),$); +#79=IFCEXTRUDEDAREASOLID(#78,#77,#73,20.); +#80=IFCSHAPEREPRESENTATION(#37,'Body','SweptSolid',(#79)); +#81=IFCPRODUCTDEFINITIONSHAPE($,$,(#80)); +ENDSEC; +END-ISO-10303-21;