From 4a36816f8f56a29ee1d187b32ca1d23c4f772ace Mon Sep 17 00:00:00 2001 From: aothms Date: Sun, 16 Mar 2014 13:34:01 +0000 Subject: [PATCH] Support for IfcCompositeProfileDef and IfcDerivedProfileDef --- src/ifcgeom/IfcGeom.h | 4 +- src/ifcgeom/IfcGeomFaces.cpp | 97 ++++++++++++++++++++++------- src/ifcgeom/IfcGeomFunctions.cpp | 5 +- src/ifcgeom/IfcGeomHelpers.cpp | 56 +++++++++++++++-- src/ifcgeom/IfcRegister.cpp | 2 +- src/ifcgeom/IfcRegister.h | 2 + src/ifcgeom/IfcRegisterGeomHeader.h | 2 +- 7 files changed, 138 insertions(+), 30 deletions(-) diff --git a/src/ifcgeom/IfcGeom.h b/src/ifcgeom/IfcGeom.h index 270c19d5b4..f3623ea826 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 ab3e0fdb08..5ff7f59a8a 100644 --- a/src/ifcgeom/IfcGeomFunctions.cpp +++ b/src/ifcgeom/IfcGeomFunctions.cpp @@ -323,7 +323,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 ++ ) { @@ -336,6 +336,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 ) { @@ -349,6 +350,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"