diff --git a/src/ifcconvert/OpenCascadeBasedSerializer.cpp b/src/ifcconvert/OpenCascadeBasedSerializer.cpp index 1400d7c400..cf5ae2df62 100644 --- a/src/ifcconvert/OpenCascadeBasedSerializer.cpp +++ b/src/ifcconvert/OpenCascadeBasedSerializer.cpp @@ -21,9 +21,6 @@ #include #include -#include -#include - #include #include "OpenCascadeBasedSerializer.h" @@ -49,18 +46,8 @@ void OpenCascadeBasedSerializer::write(const IfcGeom::BRepElement* o) { gtrsf.PreMultiply(scale); } - const TopoDS_Shape& s = it->Shape(); - - bool trsf_valid = false; - gp_Trsf trsf; - try { - trsf = gtrsf.Trsf(); - trsf_valid = true; - } catch (...) {} - - const TopoDS_Shape moved_shape = trsf_valid - ? BRepBuilderAPI_Transform(s, trsf, true).Shape() - : BRepBuilderAPI_GTransform(s, gtrsf, true).Shape(); + const TopoDS_Shape& s = it->Shape(); + const TopoDS_Shape moved_shape = IfcGeom::Kernel::apply_transformation(s, gtrsf); writeShape(moved_shape); } diff --git a/src/ifcconvert/SvgSerializer.cpp b/src/ifcconvert/SvgSerializer.cpp index 25fbe49198..bf64e82db4 100644 --- a/src/ifcconvert/SvgSerializer.cpp +++ b/src/ifcconvert/SvgSerializer.cpp @@ -28,8 +28,6 @@ #include #include #include -#include -#include #include #include #include @@ -222,17 +220,7 @@ void SvgSerializer::write(const IfcGeom::BRepElement* o) gtrsf.PreMultiply(o_trsf); const TopoDS_Shape& s = it->Shape(); - - bool trsf_valid = false; - gp_Trsf trsf; - try { - trsf = gtrsf.Trsf(); - trsf_valid = true; - } catch (...) {} - - const TopoDS_Shape moved_shape = trsf_valid - ? BRepBuilderAPI_Transform(s, trsf, true).Shape() - : BRepBuilderAPI_GTransform(s, gtrsf, true).Shape(); + const TopoDS_Shape moved_shape = IfcGeom::Kernel::apply_transformation(s, gtrsf); const double inf = std::numeric_limits::infinity(); double zmin = inf; diff --git a/src/ifcgeom/IfcGeom.h b/src/ifcgeom/IfcGeom.h index e5fdeb7f95..6397f6d16f 100644 --- a/src/ifcgeom/IfcGeom.h +++ b/src/ifcgeom/IfcGeom.h @@ -219,6 +219,9 @@ public: bool approximate_plane_through_wire(const TopoDS_Wire&, gp_Pln&); bool flatten_wire(TopoDS_Wire&); + static TopoDS_Shape apply_transformation(const TopoDS_Shape&, const gp_Trsf&); + static TopoDS_Shape apply_transformation(const TopoDS_Shape&, const gp_GTrsf&); + bool is_identity_transform(IfcUtil::IfcBaseClass*); IfcSchema::IfcRelVoidsElement::list::ptr find_openings(IfcSchema::IfcProduct* product); diff --git a/src/ifcgeom/IfcGeomFunctions.cpp b/src/ifcgeom/IfcGeomFunctions.cpp index 041a401d2c..2dd24b51ff 100644 --- a/src/ifcgeom/IfcGeomFunctions.cpp +++ b/src/ifcgeom/IfcGeomFunctions.cpp @@ -103,6 +103,7 @@ #include #include +#include #include #include @@ -231,13 +232,10 @@ bool IfcGeom::Kernel::convert_openings(const IfcSchema::IfcProduct* entity, cons TopoDS_Shape entity_shape_solid; const TopoDS_Shape& entity_shape_unlocated = ensure_fit_for_subtraction(it3->Shape(),entity_shape_solid); const gp_GTrsf& entity_shape_gtrsf = it3->Placement(); - TopoDS_Shape entity_shape; if ( entity_shape_gtrsf.Form() == gp_Other ) { - Logger::Message(Logger::LOG_WARNING,"Applying non uniform transformation to:",entity->entity); - entity_shape = BRepBuilderAPI_GTransform(entity_shape_unlocated,entity_shape_gtrsf,true).Shape(); - } else { - entity_shape = entity_shape_unlocated.Moved(entity_shape_gtrsf.Trsf()); + Logger::Message(Logger::LOG_WARNING, "Applying non uniform transformation to:", entity->entity); } + TopoDS_Shape entity_shape = apply_transformation(entity_shape_unlocated, entity_shape_gtrsf); // Iterate over the shapes of the IfcOpeningElements for ( IfcGeom::IfcRepresentationShapeItems::const_iterator it4 = opening_shapes.begin(); it4 != opening_shapes.end(); ++ it4 ) { @@ -247,9 +245,7 @@ bool IfcGeom::Kernel::convert_openings(const IfcSchema::IfcProduct* entity, cons if ( opening_shape_gtrsf.Form() == gp_Other ) { Logger::Message(Logger::LOG_WARNING,"Applying non uniform transformation to opening of:",entity->entity); } - const TopoDS_Shape& opening_shape = opening_shape_gtrsf.Form() == gp_Other - ? BRepBuilderAPI_GTransform(opening_shape_unlocated,opening_shape_gtrsf,true).Shape() - : opening_shape_unlocated.Moved(opening_shape_gtrsf.Trsf()); + TopoDS_Shape opening_shape = apply_transformation(opening_shape_unlocated, opening_shape_gtrsf); double opening_volume; if ( Logger::Verbosity() >= Logger::LOG_WARNING ) { @@ -397,10 +393,8 @@ bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity, for ( unsigned int i = 0; i < opening_shapes.size(); ++ i ) { gp_GTrsf gtrsf = opening_shapes[i].Placement(); gtrsf.PreMultiply(opening_trsf); - const TopoDS_Shape& opening_shape = gtrsf.Form() == gp_Other - ? BRepBuilderAPI_GTransform(opening_shapes[i].Shape(),gtrsf,true).Shape() - : (opening_shapes[i].Shape()).Moved(gtrsf.Trsf()); - builder.Add(opening_compound,opening_shape); + TopoDS_Shape opening_shape = apply_transformation(opening_shapes[i].Shape(), gtrsf); + builder.Add(opening_compound, opening_shape); } } @@ -411,13 +405,10 @@ bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity, TopoDS_Shape entity_shape_solid; const TopoDS_Shape& entity_shape_unlocated = ensure_fit_for_subtraction(it3->Shape(),entity_shape_solid); const gp_GTrsf& entity_shape_gtrsf = it3->Placement(); - TopoDS_Shape entity_shape; - if ( entity_shape_gtrsf.Form() == gp_Other ) { - Logger::Message(Logger::LOG_WARNING,"Applying non uniform transformation to:",entity->entity); - entity_shape = BRepBuilderAPI_GTransform(entity_shape_unlocated,entity_shape_gtrsf,true).Shape(); - } else { - entity_shape = entity_shape_unlocated.Moved(entity_shape_gtrsf.Trsf()); + if (entity_shape_gtrsf.Form() == gp_Other) { + Logger::Message(Logger::LOG_WARNING, "Applying non uniform transformation to:", entity->entity); } + TopoDS_Shape entity_shape = apply_transformation(entity_shape_unlocated, entity_shape_gtrsf); BRepAlgoAPI_Cut brep_cut(entity_shape,opening_compound); @@ -477,9 +468,7 @@ bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity, for ( unsigned int i = 0; i < opening_shapes.size(); ++ i ) { gp_GTrsf gtrsf = opening_shapes[i].Placement(); gtrsf.PreMultiply(opening_trsf); - const TopoDS_Shape& opening_shape = gtrsf.Form() == gp_Other - ? BRepBuilderAPI_GTransform(opening_shapes[i].Shape(),gtrsf,true).Shape() - : (opening_shapes[i].Shape()).Moved(gtrsf.Trsf()); + TopoDS_Shape opening_shape = apply_transformation(opening_shapes[i].Shape(), gtrsf); opening_shapelist.Append(opening_shape); } @@ -491,14 +480,11 @@ bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity, TopoDS_Shape entity_shape_solid; const TopoDS_Shape& entity_shape_unlocated = ensure_fit_for_subtraction(it3->Shape(),entity_shape_solid); const gp_GTrsf& entity_shape_gtrsf = it3->Placement(); - TopoDS_Shape entity_shape; - if ( entity_shape_gtrsf.Form() == gp_Other ) { - Logger::Message(Logger::LOG_WARNING,"Applying non uniform transformation to:",entity->entity); - entity_shape = BRepBuilderAPI_GTransform(entity_shape_unlocated,entity_shape_gtrsf,true).Shape(); - } else { - entity_shape = entity_shape_unlocated.Moved(entity_shape_gtrsf.Trsf()); + if (entity_shape_gtrsf.Form() == gp_Other) { + Logger::Message(Logger::LOG_WARNING, "Applying non uniform transformation to:", entity->entity); } - + TopoDS_Shape entity_shape = apply_transformation(entity_shape_unlocated, entity_shape_gtrsf); + BRepAlgoAPI_Cut brep_cut; TopTools_ListOfShape s1s; s1s.Append(entity_shape); @@ -921,20 +907,7 @@ bool IfcGeom::Kernel::flatten_shape_list(const IfcGeom::IfcRepresentationShapeIt merged = s; } const gp_GTrsf& trsf = it->Placement(); - bool trsf_valid = false; - gp_Trsf _trsf; - try { - _trsf = trsf.Trsf(); - trsf_valid = true; - } catch (...) {} - - const TopoDS_Shape moved_shape = trsf.Form() == gp_Identity - ? merged - : ( - trsf_valid - ? merged.Moved(_trsf) - : BRepBuilderAPI_GTransform(merged,trsf,true).Shape() - ); + const TopoDS_Shape moved_shape = apply_transformation(merged, trsf); if (shapes.size() == 1) { result = moved_shape; @@ -1772,6 +1745,8 @@ bool IfcGeom::Kernel::fold_layers(const IfcSchema::IfcWall* wall, const IfcRepre TopoDS_Shape axis_shape; flatten_shape_list(axis_items, axis_shape, false); + // local and other are IfcLocalPlacements and therefore have a unit + // scale factor that can be applied by means of TopoDS_Shape::Move() axis_shape.Move(other); axis_shape.Move(local); @@ -2410,3 +2385,27 @@ bool IfcGeom::Kernel::flatten_wire(TopoDS_Wire& wire) { wire = TopoDS::Wire(list.First()); return true; } + + +TopoDS_Shape IfcGeom::Kernel::apply_transformation(const TopoDS_Shape& s, const gp_Trsf& t) { + if (t.Form() == gp_Identity) { + return s; + } else { + /// @todo set to 1. and exactly 1. or use epsilon? + if (t.ScaleFactor() != 1.) { + return BRepBuilderAPI_Transform(s, t, true); + } else { + return s.Moved(t); + } + } +} + +TopoDS_Shape IfcGeom::Kernel::apply_transformation(const TopoDS_Shape& s, const gp_GTrsf& t) { + if (t.Form() == gp_Other) { + return BRepBuilderAPI_GTransform(s, t, true); + } else { + + return apply_transformation(s, t.Trsf()); + } +} + diff --git a/src/ifcgeom/IfcGeomRepresentation.cpp b/src/ifcgeom/IfcGeomRepresentation.cpp index 06e5266cac..c5ecc7623c 100644 --- a/src/ifcgeom/IfcGeomRepresentation.cpp +++ b/src/ifcgeom/IfcGeomRepresentation.cpp @@ -22,7 +22,6 @@ #include #include -#include #include "../ifcgeom/IfcGeom.h" @@ -60,15 +59,10 @@ IfcGeom::Representation::Serialization::Serialization(const BRep& brep) scale.SetScaleFactor(1.0 / settings().unit_magnitude()); trsf.PreMultiply(scale); } - bool trsf_valid = false; - gp_Trsf _trsf; - try { - _trsf = trsf.Trsf(); - trsf_valid = true; - } catch (...) {} - const TopoDS_Shape moved_shape = trsf_valid ? s.Moved(_trsf) : - BRepBuilderAPI_GTransform(s,trsf,true).Shape(); - builder.Add(compound,moved_shape); + + const TopoDS_Shape moved_shape = IfcGeom::Kernel::apply_transformation(s, trsf); + + builder.Add(compound, moved_shape); } std::stringstream sstream; BRepTools::Write(compound,sstream); diff --git a/src/ifcgeom/IfcGeomShapes.cpp b/src/ifcgeom/IfcGeomShapes.cpp index 6a91581410..1ee77a77f9 100644 --- a/src/ifcgeom/IfcGeomShapes.cpp +++ b/src/ifcgeom/IfcGeomShapes.cpp @@ -146,7 +146,10 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcExtrudedAreaSolid* l, TopoDS_S shape = BRepPrimAPI_MakePrism(face, height*dir); } + // IfcSweptAreaSolid.Position (trsf) is an IfcAxis2Placement3D + // and therefore has a unit scale factor shape.Move(trsf); + return ! shape.IsNull(); } @@ -166,7 +169,11 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcSurfaceOfLinearExtrusion* l, T convert(l->ExtrudedDirection(),dir); shape = BRepPrimAPI_MakePrism(wire, height*dir); + + // IfcSweptSurface.Position (trsf) is an IfcAxis2Placement3D + // and therefore has a unit scale factor shape.Move(trsf); + return !shape.IsNull(); } @@ -187,7 +194,10 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcSurfaceOfRevolution* l, TopoDS shape = BRepPrimAPI_MakeRevol(wire, ax1); + // IfcSweptSurface.Position (trsf) is an IfcAxis2Placement3D + // and therefore has a unit scale factor shape.Move(trsf); + return !shape.IsNull(); } @@ -209,7 +219,10 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcRevolvedAreaSolid* l, TopoDS_S shape = BRepPrimAPI_MakeRevol(face, ax1, ang); } + // IfcSweptAreaSolid.Position (trsf) is an IfcAxis2Placement3D + // and therefore has a unit scale factor shape.Move(trsf); + return !shape.IsNull(); } @@ -269,7 +282,10 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcPolygonalBoundedHalfSpace* l, TopoDS_Shape prism = BRepPrimAPI_MakePrism(BRepBuilderAPI_MakeFace(wire),gp_Vec(0,0,200)); gp_Trsf down; down.SetTranslation(gp_Vec(0,0,-100.0)); - prism.Move(trsf*down); + + // `trsf` and `down` both have a unit scale factor + prism.Move(trsf*down); + shape = BRepAlgoAPI_Common(halfspace,prism); return true; } @@ -608,7 +624,10 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcBlock* l, TopoDS_Shape& shape) BRepPrimAPI_MakeBox builder(dx, dy, dz); gp_Trsf trsf; IfcGeom::Kernel::convert(l->Position(),trsf); + + // IfcCsgPrimitive3D.Position has unit scale factor shape = builder.Solid().Moved(trsf); + return true; } @@ -641,7 +660,10 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcRightCircularCylinder* l, Topo BRepPrimAPI_MakeCylinder builder(r, h); gp_Trsf trsf; IfcGeom::Kernel::convert(l->Position(),trsf); + + // IfcCsgPrimitive3D.Position has unit scale factor shape = builder.Solid().Moved(trsf); + return true; } @@ -652,7 +674,10 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcRightCircularCone* l, TopoDS_S BRepPrimAPI_MakeCone builder(r, 0., h); gp_Trsf trsf; IfcGeom::Kernel::convert(l->Position(),trsf); + + // IfcCsgPrimitive3D.Position has unit scale factor shape = builder.Solid().Moved(trsf); + return true; } @@ -662,7 +687,10 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcSphere* l, TopoDS_Shape& shape BRepPrimAPI_MakeSphere builder(r); gp_Trsf trsf; IfcGeom::Kernel::convert(l->Position(),trsf); + + // IfcCsgPrimitive3D.Position has unit scale factor shape = builder.Solid().Moved(trsf); + return true; } @@ -694,6 +722,8 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcCurveBoundedPlane* l, TopoDS_S ShapeFix_Shape sfs(mf.Face()); sfs.Perform(); + + // `trsf` consitutes the placement of the plane and therefore has unit scale factor face = TopoDS::Face(sfs.Shape()).Moved(trsf); return true; @@ -782,6 +812,9 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcSurfaceCurveSweptAreaSolid* l, builder.Build(); builder.MakeSolid(); shape = builder.Shape(); + + // IfcSweptAreaSolid.Position (trsf) is an IfcAxis2Placement3D + // and therefore has a unit scale factor shape.Move(position); return true; @@ -873,6 +906,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcCylindricalSurface* l, TopoDS_ gp_Trsf trsf; IfcGeom::Kernel::convert(l->Position(),trsf); + // IfcElementarySurface.Position has unit scale factor #if OCC_VERSION_HEX < 0x60502 face = BRepBuilderAPI_MakeFace(new Geom_CylindricalSurface(gp::XOY(), l->Radius())).Face().Moved(trsf); #else