From aa7b5bd1e3bf3eb9cccf17209859528d4a8a2fbc Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Sat, 29 Jul 2023 10:06:44 +0800 Subject: [PATCH] Implement IfcGridPlacement --- src/ifcgeom/mapping/IfcObjectPlacement.cpp | 126 +++++++++++++++++++++ 1 file changed, 126 insertions(+) diff --git a/src/ifcgeom/mapping/IfcObjectPlacement.cpp b/src/ifcgeom/mapping/IfcObjectPlacement.cpp index ae817bb424..f041c43145 100644 --- a/src/ifcgeom/mapping/IfcObjectPlacement.cpp +++ b/src/ifcgeom/mapping/IfcObjectPlacement.cpp @@ -89,3 +89,129 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcObjectPlacement* inst) { // @todo // m4->components() = offset_and_rotation_ * m4->components(); } + +/* +// @todo + +if (gridp = inst->as()) { + gp_Trsf grid_position; + + auto axes = gridp->PlacementLocation()->IntersectingAxes(); + auto offsets = gridp->PlacementLocation()->OffsetDistances(); + Handle(Geom_Curve) c1, c2; + std::unique_ptr ecc; + +#ifdef SCHEMA_IfcObjectPlacement_HAS_PlacementRelTo + // From 4.3 onwards the parent grid placement is directly referenced + // in the schema to translate the grid axes to world coords + convert(l->PlacementRelTo(), grid_position); +#else + IfcSchema::IfcGrid* grid = nullptr; + auto grids = (*axes->begin())->data().file->getInverse((*axes->begin())->data().id(), -1); + if (grids && grids->size()) { + grid = *grids->begin(); + if (grid->ObjectPlacement()) { + convert(grid->ObjectPlacement(), grid_position); + } + } +#endif + + auto get_point = [this, &c1, &c2, &ecc](IfcSchema::IfcVirtualGridIntersection const* x, gp_Pnt& P) { + auto axes = x->IntersectingAxes(); + auto offsets = x->OffsetDistances(); + + if (axes->size() != 2) { + Logger::Message(Logger::LOG_WARNING, "Unexpected grid axes count:" + std::to_string(axes->size()), x); + return false; + } + if (offsets.size() != 3) { + Logger::Message(Logger::LOG_WARNING, "Unexpected offset count:" + std::to_string(offsets.size()), x); + return false; + } + auto first = *axes->begin(); + auto second = *++axes->begin(); + TopoDS_Wire w; + // Might display a lot of 'No operation defined for ...' messages + if (!convert_curve(first->AxisCurve(), c1)) { + if (!convert_wire(first->AxisCurve(), w)) { + return false; + } + double a, b; + c1 = BRep_Tool::Curve(TopoDS::Edge(TopoDS_Iterator(w).Value()), a, b); + } + if (!convert_curve(second->AxisCurve(), c2)) { + if (!convert_wire(second->AxisCurve(), w)) { + return false; + } + double a, b; + c2 = BRep_Tool::Curve(TopoDS::Edge(TopoDS_Iterator(w).Value()), a, b); + } + if (std::fabs(offsets[0]) > getValue(GV_PRECISION)) { + c1 = new Geom_OffsetCurve(c1, offsets[0], gp::DZ()); + } + if (std::fabs(offsets[1]) > getValue(GV_PRECISION)) { + c2 = new Geom_OffsetCurve(c2, offsets[1], gp::DZ()); + } + ecc.reset(new GeomAPI_ExtremaCurveCurve(c1, c2)); + gp_Pnt pp1, pp2; + ecc->Points(1, pp1, pp2); + if (pp1.Distance(pp2) > getValue(GV_PRECISION)) { + Logger::Message(Logger::LOG_WARNING, "No axis intersection:", x); + return false; + } + P = pp1; + return true; + }; + + gp_Pnt origin; + if (!get_point(gridp->PlacementLocation(), origin)) { + return false; + } + + gp_Vec V; + gp_Dir D; + if (gridp->PlacementRefDirection()) { + IfcSchema::IfcDirection const* dir; + IfcSchema::IfcVirtualGridIntersection const* refx; + + if ((dir = gridp->PlacementRefDirection()->as())) { + if (!convert(dir, D)) { + return false; + } + } else if ((refx = gridp->PlacementRefDirection()->as())) { + gp_Pnt P; + if (!get_point(refx, P)) { + return false; + } + V = P.XYZ() - origin.XYZ(); + if (V.Magnitude() > 1.e-9) { + D = V; + } else { + Logger::Message(Logger::LOG_ERROR, "Unable to obtain ref direction:", l); + return false; + } + } + } else { + gp_Pnt tmp_; + double u1, u2; + ecc->Parameters(1, u1, u2); + + c1->D1(u1, tmp_, V); + if (V.Magnitude() > 1.e-9) { + D = V; + } else { + Logger::Message(Logger::LOG_ERROR, "Unable to obtain ref direction:", l); + return false; + } + } + + // Can be applied post hoc because z component of offsets for origin + // and ref direction should be sme. + origin.SetZ(origin.Z() + offsets[2]); + + gp_Ax2 ax(origin, gp::DZ(), D); + trsf.SetTransformation(ax, gp::XOY()); + + trsf.PreMultiply(grid_position); +} +*/ \ No newline at end of file