From 65a5646bf06b6761a4c25e491c10d0b8dff9338d Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Thu, 27 Jul 2023 16:42:06 +0800 Subject: [PATCH] Major update: taxonomy shared pointers, collection type safety, work towards hashing --- src/ifcconvert/cityjson | 2 +- src/ifcconvert/validate_space_boundaries.cpp | 17 +- .../validate_storey_containment.cpp | 4 +- src/ifcconvert/validate_wall_connectivity.cpp | 18 +- src/ifcconvert/validation_utils.h | 4 +- src/ifcgeom/AbstractKernel.cpp | 10 +- src/ifcgeom/AbstractKernel.h | 65 +- src/ifcgeom/ConversionResult.h | 56 +- src/ifcgeom/Converter.cpp | 22 +- src/ifcgeom/Converter.h | 6 +- src/ifcgeom/IfcGeomElement.h | 12 +- src/ifcgeom/IfcGeomRepresentation.cpp | 6 +- src/ifcgeom/Iterator.h | 22 +- src/ifcgeom/abstract_mapping.h | 2 +- src/ifcgeom/kernels/cgal/CgalKernel.cpp | 229 +++--- src/ifcgeom/kernels/cgal/CgalKernel.h | 24 +- src/ifcgeom/kernels/opencascade/IfcGeomTree.h | 2 +- .../OpenCascadeConversionResult.cpp | 2 +- .../kernels/opencascade/OpenCascadeKernel.cpp | 18 +- .../kernels/opencascade/OpenCascadeKernel.h | 34 +- .../kernels/opencascade/base_utils.cpp | 2 +- .../kernels/opencascade/boolean_result.cpp | 10 +- .../kernels/opencascade/bspline_surface.cpp | 4 +- src/ifcgeom/kernels/opencascade/extrusion.cpp | 8 +- src/ifcgeom/kernels/opencascade/face.cpp | 14 +- .../kernels/opencascade/faceset_helper.cpp | 30 +- src/ifcgeom/kernels/opencascade/layerset.cpp | 16 +- src/ifcgeom/kernels/opencascade/layerset.h | 4 +- src/ifcgeom/kernels/opencascade/loop.cpp | 86 +- src/ifcgeom/kernels/opencascade/matrix4.cpp | 2 +- src/ifcgeom/kernels/opencascade/shell.cpp | 7 +- src/ifcgeom/kernels/opencascade/solid.cpp | 84 +- src/ifcgeom/mapping/IfcAnnotationFillArea.cpp | 12 +- .../mapping/IfcArbitraryClosedProfileDef.cpp | 12 +- .../mapping/IfcArbitraryOpenProfileDef.cpp | 2 +- src/ifcgeom/mapping/IfcAxis1Placement.cpp | 12 +- src/ifcgeom/mapping/IfcAxis2Placement2D.cpp | 12 +- src/ifcgeom/mapping/IfcAxis2Placement3D.cpp | 16 +- .../mapping/IfcBSplineCurveWithKnots.cpp | 8 +- .../mapping/IfcBSplineSurfaceWithKnots.cpp | 8 +- src/ifcgeom/mapping/IfcBlock.cpp | 4 +- src/ifcgeom/mapping/IfcBooleanResult.cpp | 2 +- src/ifcgeom/mapping/IfcBoundingBox.cpp | 6 +- src/ifcgeom/mapping/IfcCShapeProfileDef.cpp | 6 +- src/ifcgeom/mapping/IfcCartesianPoint.cpp | 4 +- .../IfcCartesianTransformationOperator2D.cpp | 16 +- .../IfcCartesianTransformationOperator3D.cpp | 20 +- .../mapping/IfcCenterLineProfileDef.cpp | 15 +- src/ifcgeom/mapping/IfcCircle.cpp | 6 +- src/ifcgeom/mapping/IfcCircleProfileDef.cpp | 15 +- src/ifcgeom/mapping/IfcCompositeCurve.cpp | 16 +- .../mapping/IfcCompositeProfileDef.cpp | 2 +- src/ifcgeom/mapping/IfcConnectedFaceSet.cpp | 4 +- .../mapping/IfcCraneRailAShapeProfileDef.cpp | 6 +- src/ifcgeom/mapping/IfcCsgSolid.cpp | 2 +- src/ifcgeom/mapping/IfcCurveBoundedPlane.cpp | 12 +- src/ifcgeom/mapping/IfcCylindricalSurface.cpp | 6 +- src/ifcgeom/mapping/IfcDerivedProfileDef.cpp | 6 +- src/ifcgeom/mapping/IfcDirection.cpp | 4 +- src/ifcgeom/mapping/IfcEdge.cpp | 8 +- src/ifcgeom/mapping/IfcEdgeLoop.cpp | 2 +- src/ifcgeom/mapping/IfcEllipse.cpp | 18 +- src/ifcgeom/mapping/IfcEllipseProfileDef.cpp | 18 +- src/ifcgeom/mapping/IfcExtrudedAreaSolid.cpp | 12 +- .../mapping/IfcExtrudedAreaSolidTapered.cpp | 16 +- src/ifcgeom/mapping/IfcFace.cpp | 12 +- .../mapping/IfcFaceBasedSurfaceModel.cpp | 2 +- src/ifcgeom/mapping/IfcGeometricSet.cpp | 2 +- src/ifcgeom/mapping/IfcHalfSpaceSolid.cpp | 16 +- src/ifcgeom/mapping/IfcIShapeProfileDef.cpp | 6 +- src/ifcgeom/mapping/IfcIndexedPolyCurve.cpp | 20 +- src/ifcgeom/mapping/IfcLShapeProfileDef.cpp | 6 +- src/ifcgeom/mapping/IfcLine.cpp | 10 +- src/ifcgeom/mapping/IfcLocalPlacement.cpp | 7 +- src/ifcgeom/mapping/IfcManifoldSolidBrep.cpp | 8 +- src/ifcgeom/mapping/IfcMappedItem.cpp | 17 +- src/ifcgeom/mapping/IfcOrientedEdge.cpp | 4 +- src/ifcgeom/mapping/IfcPlane.cpp | 6 +- src/ifcgeom/mapping/IfcPolyLoop.cpp | 6 +- .../mapping/IfcPolygonalBoundedHalfSpace.cpp | 10 +- src/ifcgeom/mapping/IfcPolygonalFaceSet.cpp | 58 +- src/ifcgeom/mapping/IfcPolyline.cpp | 8 +- src/ifcgeom/mapping/IfcProduct.cpp | 12 +- .../mapping/IfcRectangleHollowProfileDef.cpp | 9 +- .../mapping/IfcRectangleProfileDef.cpp | 6 +- src/ifcgeom/mapping/IfcRectangularPyramid.cpp | 100 +-- .../mapping/IfcRectangularTrimmedSurface.cpp | 2 +- src/ifcgeom/mapping/IfcRepresentation.cpp | 8 +- src/ifcgeom/mapping/IfcRevolvedAreaSolid.cpp | 16 +- src/ifcgeom/mapping/IfcRightCircularCone.cpp | 2 +- .../mapping/IfcRightCircularCylinder.cpp | 2 +- .../mapping/IfcRoundedRectangleProfileDef.cpp | 6 +- .../mapping/IfcShellBasedSurfaceModel.cpp | 2 +- src/ifcgeom/mapping/IfcSphere.cpp | 2 +- src/ifcgeom/mapping/IfcSphericalSurface.cpp | 2 +- src/ifcgeom/mapping/IfcSubedge.cpp | 2 +- src/ifcgeom/mapping/IfcSurfaceCurve.cpp | 2 +- .../mapping/IfcSurfaceCurveSweptAreaSolid.cpp | 10 +- .../mapping/IfcSurfaceOfLinearExtrusion.cpp | 2 +- .../mapping/IfcSurfaceOfRevolution.cpp | 2 +- src/ifcgeom/mapping/IfcSweptDiskSolid.cpp | 18 +- src/ifcgeom/mapping/IfcTShapeProfileDef.cpp | 6 +- src/ifcgeom/mapping/IfcToroidalSurface.cpp | 2 +- .../mapping/IfcTrapeziumProfileDef.cpp | 6 +- .../mapping/IfcTriangulatedFaceSet.cpp | 18 +- src/ifcgeom/mapping/IfcTrimmedCurve.cpp | 22 +- src/ifcgeom/mapping/IfcUShapeProfileDef.cpp | 6 +- src/ifcgeom/mapping/IfcVector.cpp | 4 +- src/ifcgeom/mapping/IfcZShapeProfileDef.cpp | 6 +- src/ifcgeom/mapping/bind_convert_decl.i | 2 +- src/ifcgeom/mapping/bind_convert_impl.i | 4 +- src/ifcgeom/mapping/mapping.cpp | 80 +- src/ifcgeom/mapping/mapping.h | 110 +-- src/ifcgeom/profile_helper.cpp | 70 +- src/ifcgeom/profile_helper.h | 10 +- src/ifcgeom/taxonomy.cpp | 215 +++-- src/ifcgeom/taxonomy.h | 740 ++++++++++++++---- src/serializers/ColladaSerializer.cpp | 6 +- src/serializers/GltfSerializer.cpp | 2 +- src/serializers/HdfSerializer.cpp | 16 +- src/serializers/SvgSerializer.cpp | 10 +- .../schema_dependent/XmlSerializer.cpp | 4 +- 122 files changed, 1669 insertions(+), 1203 deletions(-) diff --git a/src/ifcconvert/cityjson b/src/ifcconvert/cityjson index 551780d76a..d784dca579 160000 --- a/src/ifcconvert/cityjson +++ b/src/ifcconvert/cityjson @@ -1 +1 @@ -Subproject commit 551780d76aa9c95df725778671ae45f32c611df8 +Subproject commit d784dca5795c424141fb214b45c7b07a946b4440 diff --git a/src/ifcconvert/validate_space_boundaries.cpp b/src/ifcconvert/validate_space_boundaries.cpp index fcaafd4804..c15c7c763d 100644 --- a/src/ifcconvert/validate_space_boundaries.cpp +++ b/src/ifcconvert/validate_space_boundaries.cpp @@ -63,18 +63,15 @@ void fix_spaceboundaries(IfcParse::IfcFile& f, bool no_progress, bool quiet, boo auto g1 = n.substr(0, 22); auto g2 = n.substr(23); auto item = c.mapping()->map(i); - if (((ifcopenshell::geometry::taxonomy::collection*) item)->children[0] == nullptr) { + if (taxonomy::cast(item)->children[0] == nullptr) { continue; } - auto shell = (taxonomy::shell*) ((taxonomy::collection*)((taxonomy::collection*) item)->children[0])->children[0]; - for (auto& f : shell->children) { - auto face = (taxonomy::face*) f; - for (auto& w : face->children) { - auto wire = (taxonomy::loop*) w; - for (auto& e : wire->children) { - auto edge = (taxonomy::edge*) e; - auto p3 = boost::get(edge->start); - auto p4 = ((taxonomy::geom_item*)item)->matrix.ccomponents() * p3.ccomponents().homogeneous(); + auto shell = taxonomy::cast(taxonomy::cast(taxonomy::cast(item)->children[0])->children[0]); + for (auto& face : shell->children) { + for (auto& wire : face->children) { + for (auto& edge : wire->children) { + auto p3 = boost::get(edge->start); + auto p4 = taxonomy::cast(item)->matrix->ccomponents() * p3->ccomponents().homogeneous(); Kernel_::Point_3 P(p4(0), p4(1), p4(2)); elem_to_space_boundary_coords[{g1, g2}].emplace_back(P); } diff --git a/src/ifcconvert/validate_storey_containment.cpp b/src/ifcconvert/validate_storey_containment.cpp index 41d31ea0b9..9bd60d701a 100644 --- a/src/ifcconvert/validate_storey_containment.cpp +++ b/src/ifcconvert/validate_storey_containment.cpp @@ -134,8 +134,8 @@ void fix_storeycontainment(IfcParse::IfcFile& f, bool no_progress, bool quiet, b for (auto& g : geom_object->geometry()) { auto s = ((ifcopenshell::geometry::CgalShape*) g.Shape())->shape(); - const auto& m = g.Placement().ccomponents(); - const auto& n = geom_object->transformation().data().ccomponents(); + const auto& m = g.Placement()->ccomponents(); + const auto& n = geom_object->transformation().data()->ccomponents(); const cgal_placement_t trsf( m(0, 0), m(0, 1), m(0, 2), m(0, 3), diff --git a/src/ifcconvert/validate_wall_connectivity.cpp b/src/ifcconvert/validate_wall_connectivity.cpp index c72e035c43..fdb6e91b1a 100644 --- a/src/ifcconvert/validate_wall_connectivity.cpp +++ b/src/ifcconvert/validate_wall_connectivity.cpp @@ -110,23 +110,23 @@ void fix_wallconnectivity(IfcParse::IfcFile& f, bool no_progress, bool quiet, bo auto get_axis_parameter_min_max = [&c, &x_poly](const IfcUtil::IfcBaseEntity* inst) { auto item = c.mapping()->map(inst); - auto shaperep = ((taxonomy::collection*) item)->children[0]; - auto loop = ((taxonomy::collection*) shaperep)->children[0]; + auto shaperep = taxonomy::cast(item)->children[0]; + auto loop = taxonomy::dcast(taxonomy::cast(shaperep)->children[0]); - if (loop->kind() != taxonomy::LOOP) { + if (!loop) { // std::wcout << "no suitable axis" << std::endl; } else { - auto first_vertex = ((taxonomy::edge*) ((taxonomy::loop*) loop)->children.front())->start; - auto last_vertex = ((taxonomy::edge*) ((taxonomy::loop*) loop)->children.back())->end; + auto first_vertex = loop->children.front()->start; + auto last_vertex = loop->children.back()->end; if (first_vertex.which() != 0 || last_vertex.which() != 0) { // std::wcout << "trims not supported" << std::endl; } else { - auto p0 = boost::get(first_vertex); - auto p1 = boost::get(last_vertex); + auto p0 = boost::get(first_vertex); + auto p1 = boost::get(last_vertex); - auto v0 = ((taxonomy::geom_item*)item)->matrix.ccomponents() * p0.ccomponents().homogeneous(); - auto v1 = ((taxonomy::geom_item*)item)->matrix.ccomponents() * p1.ccomponents().homogeneous(); + auto v0 = taxonomy::cast(item)->matrix->ccomponents() * p0->ccomponents().homogeneous(); + auto v1 = taxonomy::cast(item)->matrix->ccomponents() * p1->ccomponents().homogeneous(); auto P0 = Kernel_::Point_3(v0(0), v0(1), v0(2)); auto P1 = Kernel_::Point_3(v1(0), v1(1), v1(2)); diff --git a/src/ifcconvert/validation_utils.h b/src/ifcconvert/validation_utils.h index 6939dfd95d..ecd119df76 100644 --- a/src/ifcconvert/validation_utils.h +++ b/src/ifcconvert/validation_utils.h @@ -477,8 +477,8 @@ struct intersection_validator { for (auto& g : geom_object->geometry()) { auto s = ((ifcopenshell::geometry::CgalShape*) g.Shape())->shape(); - const auto& m = g.Placement().ccomponents(); - const auto& n = geom_object->transformation().data().ccomponents(); + const auto& m = g.Placement()->ccomponents(); + const auto& n = geom_object->transformation().data()->ccomponents(); const cgal_placement_t trsf( m(0, 0), m(0, 1), m(0, 2), m(0, 3), diff --git a/src/ifcgeom/AbstractKernel.cpp b/src/ifcgeom/AbstractKernel.cpp index 4047fa09ec..3286624949 100644 --- a/src/ifcgeom/AbstractKernel.cpp +++ b/src/ifcgeom/AbstractKernel.cpp @@ -18,7 +18,7 @@ using namespace ifcopenshell::geometry; -bool ifcopenshell::geometry::kernels::AbstractKernel::convert(const taxonomy::item* item, IfcGeom::ConversionResults& results) { +bool ifcopenshell::geometry::kernels::AbstractKernel::convert(const taxonomy::ptr item, IfcGeom::ConversionResults& results) { // std::stringstream ss; // item->print(ss); // auto sss = ss.str(); @@ -59,15 +59,17 @@ ifcopenshell::geometry::kernels::AbstractKernel* ifcopenshell::geometry::kernels throw IfcParse::IfcException("No geometry kernel registered for " + geometry_library); } -bool ifcopenshell::geometry::kernels::AbstractKernel::convert_impl(const taxonomy::collection* collection, IfcGeom::ConversionResults& r) { +bool ifcopenshell::geometry::kernels::AbstractKernel::convert_impl(const taxonomy::collection::ptr collection, IfcGeom::ConversionResults& r) { auto s = r.size(); for (auto& c : collection->children) { convert(c, r); } for (auto i = s; i < r.size(); ++i) { - r[i].prepend(collection->matrix); + if (collection->matrix) { + r[i].prepend(collection->matrix); + } if (!r[i].hasStyle() && collection->surface_style) { - r[i].setStyle(*collection->surface_style); + r[i].setStyle(collection->surface_style); } } return r.size() > s; diff --git a/src/ifcgeom/AbstractKernel.h b/src/ifcgeom/AbstractKernel.h index 197e38e0e8..761f03e983 100644 --- a/src/ifcgeom/AbstractKernel.h +++ b/src/ifcgeom/AbstractKernel.h @@ -27,32 +27,33 @@ namespace ifcopenshell { namespace geometry { namespace kernels { : geometry_library(geometry_library) , conv_settings_(settings) {} - bool convert(const taxonomy::item*, IfcGeom::ConversionResults&); + bool convert(const taxonomy::ptr, IfcGeom::ConversionResults&); const ConversionSettings& settings() const; - virtual bool convert_impl(const taxonomy::matrix4*, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::point3*, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::direction3*, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::line*, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::circle*, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::ellipse*, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::bspline_curve*, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::edge*, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::loop*, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::shell*, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::face*, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::extrusion*, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::node*, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::colour*, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::boolean_result*, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::plane*, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::offset_curve*, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::revolve*, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::bspline_surface*, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::cylinder*, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::solid*, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::surface_curve_sweep*, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_impl(const taxonomy::collection*, IfcGeom::ConversionResults&); + virtual bool convert_impl(const taxonomy::matrix4::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } + virtual bool convert_impl(const taxonomy::point3::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } + virtual bool convert_impl(const taxonomy::direction3::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } + virtual bool convert_impl(const taxonomy::line::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } + virtual bool convert_impl(const taxonomy::circle::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } + virtual bool convert_impl(const taxonomy::ellipse::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } + virtual bool convert_impl(const taxonomy::bspline_curve::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } + virtual bool convert_impl(const taxonomy::edge::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } + virtual bool convert_impl(const taxonomy::loop::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } + virtual bool convert_impl(const taxonomy::shell::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } + virtual bool convert_impl(const taxonomy::face::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } + virtual bool convert_impl(const taxonomy::extrusion::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } + virtual bool convert_impl(const taxonomy::node::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } + virtual bool convert_impl(const taxonomy::colour::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } + virtual bool convert_impl(const taxonomy::boolean_result::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } + virtual bool convert_impl(const taxonomy::plane::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } + virtual bool convert_impl(const taxonomy::offset_curve::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } + virtual bool convert_impl(const taxonomy::revolve::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } + virtual bool convert_impl(const taxonomy::bspline_surface::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } + virtual bool convert_impl(const taxonomy::cylinder::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } + virtual bool convert_impl(const taxonomy::solid::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } + virtual bool convert_impl(const taxonomy::surface_curve_sweep::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } + virtual bool convert_impl(const taxonomy::loft::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); } + virtual bool convert_impl(const taxonomy::collection::ptr, IfcGeom::ConversionResults&); /* virtual void set_offset(const std::array &p_offset); @@ -61,7 +62,7 @@ namespace ifcopenshell { namespace geometry { namespace kernels { virtual bool apply_layerset(IfcGeom::ConversionResults&, const ifcopenshell::geometry::layerset_information&) { throw std::runtime_error("Not implemented"); } virtual bool apply_folded_layerset(IfcGeom::ConversionResults&, const ifcopenshell::geometry::layerset_information&, const std::map&) { throw std::runtime_error("Not implemented"); } - virtual bool convert_openings(const IfcUtil::IfcBaseEntity* entity, const std::vector>& openings, + virtual bool convert_openings(const IfcUtil::IfcBaseEntity* entity, const std::vector>& openings, const IfcGeom::ConversionResults& entity_shapes, const ifcopenshell::geometry::taxonomy::matrix4& entity_trsf, IfcGeom::ConversionResults& cut_shapes) = 0; }; @@ -77,9 +78,9 @@ namespace { /* A compile-time for loop over the taxonomy kinds */ template struct dispatch_conversion { - static bool dispatch(ifcopenshell::geometry::kernels::AbstractKernel* kernel, const ifcopenshell::geometry::taxonomy::item* item, IfcGeom::ConversionResults& results) { + static bool dispatch(ifcopenshell::geometry::kernels::AbstractKernel* kernel, const ifcopenshell::geometry::taxonomy::ptr item, IfcGeom::ConversionResults& results) { if (N == item->kind()) { - auto concrete_item = static_cast*>(item); + auto concrete_item = taxonomy::template cast>(item); return kernel->convert_impl(concrete_item, results); } else { return dispatch_conversion::dispatch(kernel, item, results); @@ -89,7 +90,7 @@ namespace { template <> struct dispatch_conversion { - static bool dispatch(ifcopenshell::geometry::kernels::AbstractKernel*, const ifcopenshell::geometry::taxonomy::item* item, IfcGeom::ConversionResults&) { + static bool dispatch(ifcopenshell::geometry::kernels::AbstractKernel*, const ifcopenshell::geometry::taxonomy::ptr item, IfcGeom::ConversionResults&) { Logger::Error("No conversion for " + std::to_string(item->kind())); return false; } @@ -98,11 +99,11 @@ namespace { /* A compile-time for loop over the curve kinds */ template struct dispatch_curve_creation { - static bool dispatch(const ifcopenshell::geometry::taxonomy::item* item, T& visitor) { + static bool dispatch(const ifcopenshell::geometry::taxonomy::ptr item, T& visitor) { // @todo it should be possible to eliminate this dynamic_cast when there is a static equivalent to kind() - const ifcopenshell::geometry::taxonomy::curves::type* v = dynamic_cast*>(item); + auto v = taxonomy::template dcast>(item); if (v) { - visitor(*v); + visitor(v); return true; } else { return dispatch_curve_creation::dispatch(item, visitor); @@ -112,7 +113,7 @@ namespace { template struct dispatch_curve_creation { - static bool dispatch(const ifcopenshell::geometry::taxonomy::item* item, T&) { + static bool dispatch(const ifcopenshell::geometry::taxonomy::ptr item, T&) { Logger::Error("No conversion for " + std::to_string(item->kind())); return false; } diff --git a/src/ifcgeom/ConversionResult.h b/src/ifcgeom/ConversionResult.h index 8a5eab846a..860e241056 100644 --- a/src/ifcgeom/ConversionResult.h +++ b/src/ifcgeom/ConversionResult.h @@ -50,42 +50,36 @@ namespace IfcGeom { class IFC_GEOM_API ConversionResult { private: int id; - ifcopenshell::geometry::taxonomy::matrix4 placement; - ConversionResultShape* shape; - ifcopenshell::geometry::taxonomy::style style_; + ifcopenshell::geometry::taxonomy::matrix4::ptr placement_; + ConversionResultShape* shape_; + ifcopenshell::geometry::taxonomy::style::ptr style_; public: - ConversionResult(int id, const ifcopenshell::geometry::taxonomy::matrix4& placement, const ConversionResultShape* shape, const ifcopenshell::geometry::taxonomy::style* style) - : id(id), placement(placement), shape(shape->clone()) - { - if (style) { - style_ = *style; - } - } - ConversionResult(int id, const ifcopenshell::geometry::taxonomy::matrix4& placement, const ConversionResultShape* shape) - : id(id), placement(placement), shape(shape->clone()) {} - ConversionResult(int id, const ConversionResultShape* shape, const ifcopenshell::geometry::taxonomy::style* style) - : id(id), shape(shape->clone()) - { - if (style) { - style_ = *style; - } - } - ConversionResult(int id, const ConversionResultShape* shape) - : id(id), shape(shape->clone()) {} - void append(const ifcopenshell::geometry::taxonomy::matrix4& trsf) { + ConversionResult(int id, ifcopenshell::geometry::taxonomy::matrix4::ptr placement, ConversionResultShape* shape, ifcopenshell::geometry::taxonomy::style::ptr style) + : id(id), placement_(placement ? placement : ifcopenshell::geometry::taxonomy::make()), shape_(shape), style_(style) + {} + ConversionResult(int id, ifcopenshell::geometry::taxonomy::matrix4::ptr placement, ConversionResultShape* shape) + : id(id), placement_(placement ? placement : ifcopenshell::geometry::taxonomy::make()), shape_(shape) + {} + ConversionResult(int id, ConversionResultShape* shape, ifcopenshell::geometry::taxonomy::style::ptr style) + : id(id), placement_(ifcopenshell::geometry::taxonomy::make()), shape_(shape), style_(style) + {} + ConversionResult(int id, ConversionResultShape* shape) + : id(id), placement_(ifcopenshell::geometry::taxonomy::make()), shape_(shape) + {} + void append(ifcopenshell::geometry::taxonomy::matrix4::ptr trsf) { // @todo verify order - placement.components() = placement.ccomponents() * trsf.ccomponents(); + placement_->components() = placement_->ccomponents() * trsf->ccomponents(); } - void prepend(const ifcopenshell::geometry::taxonomy::matrix4& trsf) { + void prepend(ifcopenshell::geometry::taxonomy::matrix4::ptr trsf) { // @todo verify order - placement.components() = trsf.ccomponents() * placement.ccomponents(); + placement_->components() = trsf->ccomponents() * placement_->ccomponents(); } - const ConversionResultShape* Shape() const { return shape; } - ConversionResultShape* Shape() { return shape; } - const ifcopenshell::geometry::taxonomy::matrix4& Placement() const { return placement; } - bool hasStyle() const { return !!style_.diffuse; } - const ifcopenshell::geometry::taxonomy::style& Style() const { return style_; } - void setStyle(const ifcopenshell::geometry::taxonomy::style& newStyle) { style_ = newStyle; } + ConversionResultShape* Shape() const { return shape_; } + ifcopenshell::geometry::taxonomy::matrix4::ptr Placement() const { return placement_; } + bool hasStyle() const { return !!style_; } + const ifcopenshell::geometry::taxonomy::style& Style() const { return *style_; } + ifcopenshell::geometry::taxonomy::style::ptr StylePtr() const { return style_; } + void setStyle(ifcopenshell::geometry::taxonomy::style::ptr newStyle) { style_ = newStyle; } int ItemId() const { return id; } }; diff --git a/src/ifcgeom/Converter.cpp b/src/ifcgeom/Converter.cpp index 64c2615938..1d3590234d 100644 --- a/src/ifcgeom/Converter.cpp +++ b/src/ifcgeom/Converter.cpp @@ -30,7 +30,7 @@ namespace { } } -IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_representation_and_product(taxonomy::item* representation_node, const IfcUtil::IfcBaseEntity* product, const taxonomy::matrix4& place_) { +IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_representation_and_product(taxonomy::ptr representation_node, const IfcUtil::IfcBaseEntity* product, const taxonomy::matrix4::ptr& place_) { std::stringstream representation_id_builder; auto place = place_; @@ -108,10 +108,10 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_represe auto single_material = mapping_->get_single_material_association(product); if (single_material) { - auto s = (taxonomy::style*) mapping_->map(single_material); + auto s = taxonomy::cast(mapping_->map(single_material)); for (auto it = shapes.begin(); it != shapes.end(); ++it) { if (!it->hasStyle() && s) { - it->setStyle(*s); + it->setStyle(s); material_style_applied = true; } } @@ -137,7 +137,7 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_represe for (auto& s : shapes) { if (s.hasStyle()) { // @todo the uglyness - const_cast(&s.Style())->transparency = settings_.force_space_transparency(); + const_cast(&*s.StylePtr())->transparency = settings_.force_space_transparency(); } } } @@ -172,14 +172,14 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_represe IfcGeom::ConversionResults opened_shapes; bool caught_error = false; try { - std::vector> opening_items; + std::vector> opening_items; std::transform(openings->begin(), openings->end(), std::back_inserter(opening_items), [this](IfcUtil::IfcBaseClass* opening) { auto prod_item = mapping()->map(opening); - return std::make_pair(mapping()->map(mapping()->representation_of(opening->as())), ((taxonomy::geom_item*)prod_item)->matrix); + return std::make_pair(mapping()->map(mapping()->representation_of(opening->as())), *taxonomy::cast(prod_item)->matrix); }); - kernel_->convert_openings(product, opening_items, shapes, place, opened_shapes); + kernel_->convert_openings(product, opening_items, shapes, *place, opened_shapes); } catch (const std::exception& e) { Logger::Message(Logger::LOG_ERROR, std::string("Error processing openings for: ") + e.what() + ":", product); caught_error = true; @@ -195,7 +195,7 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_represe for (auto it = opened_shapes.begin(); it != opened_shapes.end(); ++it) { it->prepend(place); } - place = ifcopenshell::geometry::taxonomy::matrix4(); + place = ifcopenshell::geometry::taxonomy::make(); representation_id_builder << "-world-coords"; } shape = new IfcGeom::Representation::BRep(element_settings, representation_id_builder.str(), opened_shapes); @@ -203,7 +203,7 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_represe for (auto it = shapes.begin(); it != shapes.end(); ++it) { it->prepend(place); } - place = ifcopenshell::geometry::taxonomy::matrix4(); + place = ifcopenshell::geometry::taxonomy::make(); representation_id_builder << "-world-coords"; shape = new IfcGeom::Representation::BRep(element_settings, representation_id_builder.str(), shapes); } else { @@ -308,7 +308,7 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_represe return elem; } -IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_processed_representation(const IfcUtil::IfcBaseEntity* product, const taxonomy::matrix4& place, IfcGeom::BRepElement* brep) { +IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_processed_representation(const IfcUtil::IfcBaseEntity* product, const taxonomy::matrix4::ptr& place, IfcGeom::BRepElement* brep) { int parent_id = -1; try { @@ -352,7 +352,7 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_represe return create_brep_for_representation_and_product( mapping_->map(representation), product, - ((taxonomy::geom_item*)mapping_->map(product))->matrix + taxonomy::cast(mapping_->map(product))->matrix ); } diff --git a/src/ifcgeom/Converter.h b/src/ifcgeom/Converter.h index a90f79f29d..9870f9f6af 100644 --- a/src/ifcgeom/Converter.h +++ b/src/ifcgeom/Converter.h @@ -21,7 +21,7 @@ namespace ifcopenshell { namespace geometry { abstract_mapping* mapping_; kernels::AbstractKernel* kernel_; IfcGeom::IteratorSettings settings_; - std::map cache_; + std::map cache_; public: kernels::AbstractKernel* kernel() { return kernel_; } @@ -59,8 +59,8 @@ namespace ifcopenshell { namespace geometry { IfcGeom::BRepElement* create_brep_for_representation_and_product(const IfcUtil::IfcBaseEntity* representation, const IfcUtil::IfcBaseEntity* product); // IfcGeom::BRepElement* create_brep_for_processed_representation(const IfcUtil::IfcBaseEntity* representation, const IfcUtil::IfcBaseEntity* product, IfcGeom::BRepElement* brep); - IfcGeom::BRepElement* create_brep_for_representation_and_product(taxonomy::item*, const IfcUtil::IfcBaseEntity* product, const taxonomy::matrix4& place); - IfcGeom::BRepElement* create_brep_for_processed_representation(const IfcUtil::IfcBaseEntity* product, const taxonomy::matrix4& place, IfcGeom::BRepElement*); + IfcGeom::BRepElement* create_brep_for_representation_and_product(taxonomy::ptr, const IfcUtil::IfcBaseEntity* product, const taxonomy::matrix4::ptr& place); + IfcGeom::BRepElement* create_brep_for_processed_representation(const IfcUtil::IfcBaseEntity* product, const taxonomy::matrix4::ptr& place, IfcGeom::BRepElement*); }; }} diff --git a/src/ifcgeom/IfcGeomElement.h b/src/ifcgeom/IfcGeomElement.h index e4e02f10a5..8577754b96 100644 --- a/src/ifcgeom/IfcGeomElement.h +++ b/src/ifcgeom/IfcGeomElement.h @@ -36,13 +36,13 @@ namespace IfcGeom { class Transformation { private: ElementSettings settings_; - ifcopenshell::geometry::taxonomy::matrix4 matrix_; + ifcopenshell::geometry::taxonomy::matrix4::ptr matrix_; public: - Transformation(const ElementSettings& settings, const ifcopenshell::geometry::taxonomy::matrix4& matrix) + Transformation(const ElementSettings& settings, const ifcopenshell::geometry::taxonomy::matrix4::ptr& matrix) : settings_(settings) , matrix_(matrix) {} - const ifcopenshell::geometry::taxonomy::matrix4& data() const { return matrix_; } + const ifcopenshell::geometry::taxonomy::matrix4::ptr& data() const { return matrix_; } }; class Element { @@ -94,7 +94,7 @@ namespace IfcGeom { void SetParents(std::vector newparents) { _parents = newparents; } Element(const ElementSettings& settings, int id, int parent_id, const std::string& name, const std::string& type, - const std::string& guid, const std::string& context, const ifcopenshell::geometry::taxonomy::matrix4& trsf, const IfcUtil::IfcBaseEntity* product) + const std::string& guid, const std::string& context, const ifcopenshell::geometry::taxonomy::matrix4::ptr& trsf, const IfcUtil::IfcBaseEntity* product) : _id(id), _parent_id(parent_id), _name(name), _type(type), _guid(guid), _context(context), _transformation(settings, trsf) , product_(product) { @@ -130,14 +130,14 @@ namespace IfcGeom { const boost::shared_ptr& geometry_pointer() const { return _geometry; } const IfcGeom::Representation::BRep& geometry() const { return *_geometry; } BRepElement(int id, int parent_id, const std::string& name, const std::string& type, const std::string& guid, - const std::string& context, const ifcopenshell::geometry::taxonomy::matrix4& trsf, const boost::shared_ptr& geometry, + const std::string& context, const ifcopenshell::geometry::taxonomy::matrix4::ptr& trsf, const boost::shared_ptr& geometry, const IfcUtil::IfcBaseEntity* product) : Element(geometry->settings() ,id, parent_id, name, type, guid, context, trsf, product) , _geometry(geometry) {} bool calculate_projected_surface_area(double& along_x, double& along_y, double& along_z) const { - return geometry().calculate_projected_surface_area(this->transformation().data(), along_x, along_y, along_z); + return geometry().calculate_projected_surface_area(*this->transformation().data(), along_x, along_y, along_z); } private: BRepElement(const BRepElement& other); diff --git a/src/ifcgeom/IfcGeomRepresentation.cpp b/src/ifcgeom/IfcGeomRepresentation.cpp index 04de3b73cb..e1c1c4e167 100644 --- a/src/ifcgeom/IfcGeomRepresentation.cpp +++ b/src/ifcgeom/IfcGeomRepresentation.cpp @@ -194,9 +194,9 @@ IfcGeom::ConversionResultShape* IfcGeom::Representation::BRep::as_compound(bool // @todo, check gp_GTrsf trsf; - if (it->Placement().components_) { + if (it->Placement()->components_) { gp_Trsf tr; - const auto& m = it->Placement().ccomponents(); + const auto& m = it->Placement()->ccomponents(); tr.SetValues( m(0, 0), m(0, 1), m(0, 2), m(0, 3), m(1, 0), m(1, 1), m(1, 2), m(1, 3), @@ -346,7 +346,7 @@ IfcGeom::Representation::Triangulation::Triangulation(const BRep& shape_model) } } - iit->Shape()->Triangulate(settings(), iit->Placement(), this, surface_style_id); + iit->Shape()->Triangulate(settings(), *iit->Placement(), this, surface_style_id); } } diff --git a/src/ifcgeom/Iterator.h b/src/ifcgeom/Iterator.h index 650f1b0c50..8190783713 100644 --- a/src/ifcgeom/Iterator.h +++ b/src/ifcgeom/Iterator.h @@ -91,8 +91,8 @@ using namespace ifcopenshell::geometry; namespace { struct geometry_conversion_result { int index; - ifcopenshell::geometry::taxonomy::item* item; - std::vector> products; + ifcopenshell::geometry::taxonomy::ptr item; + std::vector> products; std::vector breps; std::vector elements; }; @@ -180,7 +180,7 @@ namespace IfcGeom { res.item = converter_->mapping()->map(task.representation); std::transform(task.products->begin(), task.products->end(), std::back_inserter(res.products), [this, &res](IfcUtil::IfcBaseClass* prod) { auto prod_item = converter_->mapping()->map(prod); - return std::make_pair(prod->as(), ((taxonomy::geom_item*)prod_item)->matrix); + return std::make_pair(prod->as(), taxonomy::cast(prod_item)->matrix); }); tasks_.push_back(res); } @@ -195,13 +195,13 @@ namespace IfcGeom { // There needs to be two options, mapped item respecting (does that still work?), and optimized based on topology sorting. // Or is the sorting not necessary if we just cache? - std::vector items; - std::map placements; + std::vector items; + std::map placements; std::transform(products.begin(), products.end(), std::back_inserter(items), [this, &placements](IfcUtil::IfcBaseClass* p) { auto item = converter_->mapping()->map(p); // Product placements do not affect item reuse and should temporarily be swapped to identity if (item) { - std::swap(placements[item], ((taxonomy::geom_item*)item)->matrix); + std::swap(placements[item], ((taxonomy::geom_ptr)item)->matrix); } return item; }); @@ -212,7 +212,7 @@ namespace IfcGeom { auto jt = std::upper_bound(it, items.end(), *it, taxonomy::less); geometry_conversion_result r; r.item = *it; - std::transform(it, jt, std::back_inserter(r.products), [&r, &placements](taxonomy::item* product_node) { + std::transform(it, jt, std::back_inserter(r.products), [&r, &placements](taxonomy::ptr product_node) { return std::make_pair((IfcUtil::IfcBaseEntity*) product_node->instance, placements[product_node]); }); tasks_.push_back(r); @@ -344,7 +344,7 @@ namespace IfcGeom { IfcGeom::Element* geom_object = get(); const IfcGeom::TriangulationElement* o = static_cast(geom_object); const IfcGeom::Representation::Triangulation& mesh = o->geometry(); - auto mat = o->transformation().data().ccomponents(); + auto mat = o->transformation().data()->ccomponents(); Eigen::Vector4d vec, transformed; for (typename std::vector::const_iterator it = mesh.verts().begin(); it != mesh.verts().end();) { @@ -371,7 +371,7 @@ namespace IfcGeom { for (auto& product : products) { auto prod_item = converter_->mapping()->map(product); - auto vec = ((taxonomy::geom_item*)prod_item)->matrix.translation_part(); + auto vec = taxonomy::cast(prod_item)->matrix->translation_part(); for (int i = 0; i < 3; ++i) { bounds_min_.components()(i) = std::min(bounds_min_.components()(i), vec(i)); @@ -660,7 +660,7 @@ namespace IfcGeom { } const Element* get_object(int id) { - taxonomy::matrix4 m4; + taxonomy::matrix4::ptr m4; int parent_id = -1; std::string instance_type, product_name, product_guid; IfcUtil::IfcBaseEntity* ifc_product = 0; @@ -679,7 +679,7 @@ namespace IfcGeom { parent_id = parent_object->data().id(); } - m4 = ((taxonomy::geom_item*) converter_->mapping()->map(ifc_product))->matrix; + m4 = taxonomy::cast(converter_->mapping()->map(ifc_product))->matrix; } catch (const std::exception& e) { Logger::Error(e); } diff --git a/src/ifcgeom/abstract_mapping.h b/src/ifcgeom/abstract_mapping.h index 0fed9a21de..e6230fc062 100644 --- a/src/ifcgeom/abstract_mapping.h +++ b/src/ifcgeom/abstract_mapping.h @@ -32,7 +32,7 @@ namespace geometry { public: abstract_mapping(IfcGeom::IteratorSettings& s) : settings_(s) {} - virtual ifcopenshell::geometry::taxonomy::item* map(const IfcUtil::IfcBaseInterface*) = 0; + virtual ifcopenshell::geometry::taxonomy::ptr map(const IfcUtil::IfcBaseInterface*) = 0; virtual void get_representations(std::vector& tasks, std::vector& filters) = 0; virtual IfcUtil::IfcBaseEntity* get_decomposing_entity(const IfcUtil::IfcBaseEntity* product, bool include_openings = true) = 0; virtual std::map get_layers(IfcUtil::IfcBaseEntity*) = 0; diff --git a/src/ifcgeom/kernels/cgal/CgalKernel.cpp b/src/ifcgeom/kernels/cgal/CgalKernel.cpp index 8d1f34f7af..36b0564ca0 100644 --- a/src/ifcgeom/kernels/cgal/CgalKernel.cpp +++ b/src/ifcgeom/kernels/cgal/CgalKernel.cpp @@ -151,17 +151,15 @@ CGAL::Nef_polyhedron_3 ifcopenshell::geometry::utils::create_nef_polyhe } #endif -bool CgalKernel::convert(const taxonomy::shell* l, cgal_shape_t& shape) { - auto faces = l->children_as(); - - if (faces.size() > 100) { +bool CgalKernel::convert(const taxonomy::shell::ptr l, cgal_shape_t& shape) { + if (l->children.size() > 100) { static double inf = 1.e9; // std::numeric_limits::infinity(); std::pair minmax( Eigen::Vector3d(+inf, +inf, +inf), Eigen::Vector3d(-inf, -inf, -inf) ); size_t num_points = 0; - visit_2(l, [&minmax, &num_points](const taxonomy::point3* p) { + visit_2(l, [&minmax, &num_points](const taxonomy::point3::ptr p) { auto& c = p->ccomponents(); ++num_points; for (int i = 0; i < 3; ++i) { @@ -187,7 +185,7 @@ bool CgalKernel::convert(const taxonomy::shell* l, cgal_shape_t& shape) { } std::list face_list; - for (auto& f : faces) { + for (auto& f : l->children) { bool success = false; cgal_face_t face; @@ -212,12 +210,10 @@ bool CgalKernel::convert(const taxonomy::shell* l, cgal_shape_t& shape) { return shape.size_of_facets(); } -bool CgalKernel::convert(const taxonomy::face* face, cgal_face_t& result) { - auto bounds = face->children_as(); - +bool CgalKernel::convert(const taxonomy::face::ptr face, cgal_face_t& result) { int num_outer_bounds = 0; - for (auto& bound : bounds) { + for (auto& bound : face->children) { if (bound->external.get_value_or(false)) num_outer_bounds++; } @@ -228,7 +224,7 @@ bool CgalKernel::convert(const taxonomy::face* face, cgal_face_t& result) { cgal_face_t mf; - for (auto& bound : bounds) { + for (auto& bound : face->children) { const bool is_interior = !bound->external.get_value_or(false); @@ -257,28 +253,26 @@ bool CgalKernel::convert(const taxonomy::face* face, cgal_face_t& result) { namespace { // @todo obsolete? - bool convert_curve(CgalKernel* kernel, const taxonomy::item* curve, cgal_wire_t& builder) { - if (curve->kind() == taxonomy::EDGE) { - auto e = (taxonomy::edge*) curve; + bool convert_curve(CgalKernel* kernel, const taxonomy::ptr curve, cgal_wire_t& builder) { + if (auto e = taxonomy::dcast(curve)) { if (true || e->basis == nullptr) { if (builder.empty()) { - const auto& p = boost::get(e->start); - cgal_point_t pnt(p.ccomponents()(0), p.ccomponents()(1), p.ccomponents()(2)); + const auto& p = boost::get(e->start); + cgal_point_t pnt(p->ccomponents()(0), p->ccomponents()(1), p->ccomponents()(2)); builder.push_back(pnt); } - const auto& p = boost::get(e->end); - cgal_point_t pnt(p.ccomponents()(0), p.ccomponents()(1), p.ccomponents()(2)); + const auto& p = boost::get(e->end); + cgal_point_t pnt(p->ccomponents()(0), p->ccomponents()(1), p->ccomponents()(2)); builder.push_back(pnt); } else if (e->basis->kind() == taxonomy::CIRCLE) { // @todo } else if (e->basis->kind() == taxonomy::ELLIPSE) { - + // @todo } else { throw std::runtime_error("Not implemented basis kind"); } - } else if (curve->kind() == taxonomy::LOOP) { - const auto& edges = ((taxonomy::loop*) curve)->children; - for (auto& c : edges) { + } else if (auto lp = taxonomy::dcast(curve)) { + for (auto& c : lp->children) { convert_curve(kernel, c, builder); } } else { @@ -295,34 +289,34 @@ namespace { +std::numeric_limits::infinity() }; - void evaluate_curve(const taxonomy::line& c, double u, taxonomy::point3& p) { + void evaluate_curve(const taxonomy::line::ptr& c, double u, taxonomy::point3& p) { Eigen::Vector4d xy{ u, 0, 0, 1. }; - p.components() = (c.matrix.ccomponents() * xy).head<3>(); + p.components() = (c->matrix->ccomponents() * xy).head<3>(); } - void evaluate_curve(const taxonomy::circle& c, double u, taxonomy::point3& p) { - Eigen::Vector4d xy{ c.radius * std::cos(u), c.radius * std::sin(u), 0, 1. }; - p.components() = (c.matrix.ccomponents() * xy).head<3>(); + void evaluate_curve(const taxonomy::circle::ptr& c, double u, taxonomy::point3& p) { + Eigen::Vector4d xy{ c->radius * std::cos(u), c->radius * std::sin(u), 0, 1. }; + p.components() = (c->matrix->ccomponents() * xy).head<3>(); } - void evaluate_curve(const taxonomy::ellipse& c, double u, taxonomy::point3& p) { - Eigen::Vector4d xy{ c.radius * std::cos(u), c.radius2 * std::sin(u), 0, 1. }; - p.components() = (c.matrix.ccomponents() * xy).head<3>(); + void evaluate_curve(const taxonomy::ellipse::ptr& c, double u, taxonomy::point3& p) { + Eigen::Vector4d xy{ c->radius * std::cos(u), c->radius2 * std::sin(u), 0, 1. }; + p.components() = (c->matrix->ccomponents() * xy).head<3>(); } // ---- - void project_onto_curve(const taxonomy::line& c, const taxonomy::point3& p, double& u) { - u = (c.matrix.ccomponents().inverse() * p.ccomponents().homogeneous())(0); + void project_onto_curve(const taxonomy::line::ptr& c, const taxonomy::point3& p, double& u) { + u = (c->matrix->ccomponents().inverse() * p.ccomponents().homogeneous())(0); } - void project_onto_curve(const taxonomy::circle& c, const taxonomy::point3& p, double& u) { - Eigen::Vector2d xy = (c.matrix.ccomponents().inverse() * p.ccomponents().homogeneous()).head<2>(); + void project_onto_curve(const taxonomy::circle::ptr& c, const taxonomy::point3& p, double& u) { + Eigen::Vector2d xy = (c->matrix->ccomponents().inverse() * p.ccomponents().homogeneous()).head<2>(); u = std::atan2(xy(1), xy(0)); } - void project_onto_curve(const taxonomy::ellipse& c, const taxonomy::point3& p, double& u) { - Eigen::Vector2d xy = (c.matrix.ccomponents().inverse() * p.ccomponents().homogeneous()).head<2>(); + void project_onto_curve(const taxonomy::ellipse::ptr& c, const taxonomy::point3& p, double& u) { + Eigen::Vector2d xy = (c->matrix->ccomponents().inverse() * p.ccomponents().homogeneous()).head<2>(); u = std::atan2(xy(1), xy(0)); } @@ -331,30 +325,30 @@ namespace { double u; typedef void result_type; - void operator()(const taxonomy::line& c) { + void operator()(const taxonomy::line::ptr& c) { project_onto_curve(c, p, u); } - void operator()(const taxonomy::circle& c) { + void operator()(const taxonomy::circle::ptr& c) { project_onto_curve(c, p, u); } - void operator()(const taxonomy::ellipse& c) { + void operator()(const taxonomy::ellipse::ptr& c) { project_onto_curve(c, p, u); } - void operator()(const taxonomy::item& c) { + void operator()(const taxonomy::item::ptr&) { throw std::runtime_error("Point projection not implemented on this geometry type"); } }; struct point_projection_visitor { - taxonomy::item* curve; + taxonomy::ptr curve; double u; typedef void result_type; - void operator()(const taxonomy::point3& p) { - point_projection_visitor_ v{ p }; + void operator()(const taxonomy::point3::ptr& p) { + point_projection_visitor_ v{ *p }; dispatch_curve_creation::dispatch(curve, v); u = v.u; } @@ -373,7 +367,7 @@ namespace { cgal_curve_creation_visitor() : param(unbounded) {} cgal_curve_creation_visitor(const parameter_range& p) : param(p) {} - void operator()(const taxonomy::line& l) { + void operator()(const taxonomy::line::ptr& l) { if (param == unbounded) { throw std::runtime_error("Cannot represent infinite line segment"); } @@ -413,39 +407,43 @@ namespace { points.push_back(P); } - void operator()(const taxonomy::circle& c) { + void operator()(const taxonomy::circle::ptr& c) { evaluate_conic(c); } - void operator()(const taxonomy::ellipse& e) { + void operator()(const taxonomy::ellipse::ptr& e) { evaluate_conic(e); } - void operator()(const taxonomy::trimmed_curve& e) { - point_projection_visitor v1{ e.basis }, v2{ e.basis }; - boost::apply_visitor(v1, e.start); - boost::apply_visitor(v2, e.end); + void operator()(const taxonomy::trimmed_curve::ptr& e) { + point_projection_visitor v1{ e->basis }, v2{ e->basis }; + boost::apply_visitor(v1, e->start); + boost::apply_visitor(v2, e->end); - if (!e.orientation.get_value_or(true)) { + if (!e->orientation.get_value_or(true)) { std::swap(v1.u, v2.u); } cgal_curve_creation_visitor v({ v1.u, v2.u }); - dispatch_curve_creation::dispatch(e.basis, v); + dispatch_curve_creation::dispatch(e->basis, v); this->points = v.points; - if (!e.orientation.get_value_or(true)) { + if (!e->orientation.get_value_or(true)) { std::reverse(this->points.begin(), this->points.end()); } } - void operator()(const taxonomy::item& e) { + void operator()(const taxonomy::edge::ptr& e) { + return (*this)(taxonomy::dcast(e)); + } + + void operator()(const taxonomy::item::ptr&) { throw std::runtime_error("Not supported"); } }; - void convert_curve(taxonomy::item* i, std::vector& points) { + void convert_curve(taxonomy::ptr i, std::vector& points) { cgal_curve_creation_visitor v; dispatch_curve_creation::dispatch(i, v); points = v.points; @@ -540,11 +538,10 @@ namespace { } namespace { - CGAL::Polygon_2 loop_to_polygon_2(taxonomy::loop* loop) { + CGAL::Polygon_2 loop_to_polygon_2(taxonomy::loop::ptr loop) { CGAL::Polygon_2 polygon; - auto edges = loop->children_as(); - for (auto& e : edges) { - auto& p = boost::get(e->start); + for (auto& e : loop->children) { + auto& p = *boost::get(e->start); CGAL::Point_2 pnt(p.ccomponents()(0), p.ccomponents()(1)); polygon.push_back(pnt); } @@ -637,13 +634,12 @@ namespace { } -bool CgalKernel::convert(const taxonomy::loop* loop, cgal_wire_t& result) { +bool CgalKernel::convert(const taxonomy::loop::ptr loop, cgal_wire_t& result) { // @todo only implement polygonal loops - auto edges = loop->children_as(); std::vector points; - for (auto& e : edges) { + for (auto& e : loop->children) { std::vector edge; if (e->basis) { convert_curve(e, edge); @@ -652,8 +648,8 @@ bool CgalKernel::convert(const taxonomy::loop* loop, cgal_wire_t& result) { } } else { edge = { - boost::get(e->start), - boost::get(e->end) + *boost::get(e->start), + *boost::get(e->end) }; } extend_wire(points, edge); @@ -748,7 +744,7 @@ bool CgalKernel::convert(const taxonomy::loop* loop, cgal_wire_t& result) { } -bool CgalKernel::convert_impl(const taxonomy::shell *shell, ConversionResults& results) { +bool CgalKernel::convert_impl(const taxonomy::shell::ptr shell, ConversionResults& results) { cgal_shape_t shape; if (!convert(shell, shape)) { return false; @@ -765,13 +761,13 @@ bool CgalKernel::convert_impl(const taxonomy::shell *shell, ConversionResults& r return true; } -bool CgalKernel::convert_impl(const taxonomy::solid *solid, ConversionResults& results) { +bool CgalKernel::convert_impl(const taxonomy::solid::ptr solid, ConversionResults& results) { cgal_shape_t shape; if (solid->children.empty()) { return false; } // @todo - if (!convert((taxonomy::shell*)solid->children[0], shape)) { + if (!convert((taxonomy::shell::ptr)solid->children[0], shape)) { return false; } if (shape.size_of_facets() == 0) { @@ -787,9 +783,7 @@ bool CgalKernel::convert_impl(const taxonomy::solid *solid, ConversionResults& r } namespace { - bool convert_placement(const ifcopenshell::geometry::taxonomy::matrix4& place, cgal_placement_t& trsf) { - const auto& m = place.ccomponents(); - + bool convert_placement(const Eigen::Matrix4d& m, cgal_placement_t& trsf) { // @todo check trsf = cgal_placement_t( m(0, 0), m(0, 1), m(0, 2), m(0, 3), @@ -798,9 +792,12 @@ namespace { return true; } + bool convert_placement(ifcopenshell::geometry::taxonomy::matrix4::ptr place, cgal_placement_t& trsf) { + return convert_placement(place->ccomponents(), trsf); + } } -bool ifcopenshell::geometry::kernels::CgalKernel::convert_openings(const IfcUtil::IfcBaseEntity * entity, const std::vector>& openings, const IfcGeom::ConversionResults & entity_shapes, const ifcopenshell::geometry::taxonomy::matrix4 & entity_trsf, IfcGeom::ConversionResults & cut_shapes) +bool ifcopenshell::geometry::kernels::CgalKernel::convert_openings(const IfcUtil::IfcBaseEntity * entity, const std::vector>& openings, const IfcGeom::ConversionResults & entity_shapes, const ifcopenshell::geometry::taxonomy::matrix4 & entity_trsf, IfcGeom::ConversionResults & cut_shapes) { #ifdef IFOPSH_SIMPLE_KERNEL return false; @@ -823,7 +820,7 @@ bool ifcopenshell::geometry::kernels::CgalKernel::convert_openings(const IfcUtil cgal_shape_t entity_shape(entity_shape_unlocated); auto gtrsf = opening_shapes[i].Placement(); // @todo check - Eigen::Matrix4d m = opening_trsf.ccomponents() * gtrsf.ccomponents(); + Eigen::Matrix4d m = opening_trsf.ccomponents() * gtrsf->ccomponents(); if (!m.isIdentity()) { cgal_placement_t trsf; convert_placement(m, trsf); @@ -848,7 +845,7 @@ bool ifcopenshell::geometry::kernels::CgalKernel::convert_openings(const IfcUtil for (auto& shp : entity_shapes) { auto entity_shape = ((CgalShape*)shp.Shape())->shape(); - const auto& m = shp.Placement().ccomponents(); + const auto& m = shp.Placement()->ccomponents(); if (!m.isIdentity()) { cgal_placement_t trsf; convert_placement(m, trsf); @@ -872,7 +869,7 @@ bool ifcopenshell::geometry::kernels::CgalKernel::convert_openings(const IfcUtil return false; } - cut_shapes.push_back(IfcGeom::ConversionResult(shp.ItemId(), new CgalShape(a_poly), &shp.Style())); + cut_shapes.push_back(IfcGeom::ConversionResult(shp.ItemId(), new CgalShape(a_poly), shp.StylePtr())); } return true; @@ -880,7 +877,7 @@ bool ifcopenshell::geometry::kernels::CgalKernel::convert_openings(const IfcUtil } -bool CgalKernel::convert_impl(const taxonomy::extrusion* extrusion, ConversionResults& results) { +bool CgalKernel::convert_impl(const taxonomy::extrusion::ptr extrusion, ConversionResults& results) { cgal_shape_t shape; if (!convert(extrusion, shape)) { return false; @@ -894,14 +891,14 @@ bool CgalKernel::convert_impl(const taxonomy::extrusion* extrusion, ConversionRe return true; } -bool CgalKernel::process_extrusion(const cgal_face_t& bottom_face, const taxonomy::direction3& direction, double height, cgal_shape_t& shape) { +bool CgalKernel::process_extrusion(const cgal_face_t& bottom_face, taxonomy::direction3::ptr direction, double height, cgal_shape_t& shape) { bool has_inner_bounds = !bottom_face.inner.empty(); std::list faces_to_extrude; std::set> internal_edges; - CGAL::Cartesian_converter> C; + // CGAL::Cartesian_converter> C; if (has_inner_bounds) { CGAL::Polygon_with_holes_2 pwh; @@ -966,7 +963,7 @@ bool CgalKernel::process_extrusion(const cgal_face_t& bottom_face, const taxonom face_list.push_back(cgal_face_t{ w }); - auto& fs = direction.ccomponents(); + auto& fs = direction->ccomponents(); cgal_direction_t dir(fs(0), fs(1), fs(2)); int si = 0; @@ -1065,7 +1062,7 @@ bool CgalKernel::process_extrusion(const cgal_face_t& bottom_face, const taxonom */ } -bool CgalKernel::convert(const taxonomy::extrusion* extrusion, cgal_shape_t &shape) { +bool CgalKernel::convert(const taxonomy::extrusion::ptr extrusion, cgal_shape_t &shape) { const double& height = extrusion->depth; if (height < conv_settings_.getValue(ConversionSettings::GV_PRECISION)) { Logger::Message(Logger::LOG_ERROR, "Non-positive extrusion height encountered for:", extrusion->instance); @@ -1073,7 +1070,7 @@ bool CgalKernel::convert(const taxonomy::extrusion* extrusion, cgal_shape_t &sha } cgal_face_t bottom_face; - if (!convert(&extrusion->basis, bottom_face)) { + if (!convert(extrusion->basis, bottom_face)) { return false; } @@ -1270,41 +1267,41 @@ bool CgalKernel::preprocess_boolean_operand(const IfcUtil::IfcBaseClass* log_ref #endif -bool CgalKernel::process_as_2d_polygon(const taxonomy::boolean_result* br, std::list>& loops, double& z0, double& z1) { +bool CgalKernel::process_as_2d_polygon(const taxonomy::boolean_result::ptr br, std::list>& loops, double& z0, double& z1) { // @todo can also be for other boolean operations, just depth/matrix operands are different if (br->operation != taxonomy::boolean_result::SUBTRACTION) { return false; } - typedef std::pair extrusion_pair; + typedef std::pair extrusion_pair; // @todo delete extrusion_pair.first auto& ops = br->children; std::vector extrusions; - std::transform(ops.begin(), ops.end(), std::back_inserter(extrusions), [](taxonomy::item* op) { - static std::pair nptr = { nullptr, nullptr }; + std::transform(ops.begin(), ops.end(), std::back_inserter(extrusions), [](taxonomy::ptr op) { + static std::pair nptr = { nullptr, nullptr }; Eigen::Matrix4d* m4 = nullptr; - if (op->kind() == taxonomy::EXTRUSION) { - return std::make_pair(m4, (taxonomy::extrusion*) op); + if (auto ex = taxonomy::dcast(op)) { + return std::make_pair(m4, ex); } - if (op->kind() != taxonomy::COLLECTION) return nptr; - auto cl = (taxonomy::collection*) op; + auto cl = taxonomy::dcast(op); + if (!cl) return nptr; if ((cl)->children.size() != 1) return nptr; - m4 = new Eigen::Matrix4d(cl->matrix.ccomponents()); + m4 = new Eigen::Matrix4d(cl->matrix->ccomponents()); if (cl->children[0]->kind() == taxonomy::COLLECTION) { - cl = (taxonomy::collection*) cl->children[0]; + cl = taxonomy::cast(cl->children[0]); if ((cl)->children.size() != 1) { delete m4; return nptr; } - (*m4) = (*m4) * cl->matrix.ccomponents(); + (*m4) = (*m4) * cl->matrix->ccomponents(); } if (cl->children[0]->kind() != taxonomy::EXTRUSION) { delete m4; return nptr; } - auto ex = (taxonomy::extrusion*) cl->children[0]; + auto ex = taxonomy::cast(cl->children[0]); return std::make_pair(m4, ex); }); @@ -1319,7 +1316,7 @@ bool CgalKernel::process_as_2d_polygon(const taxonomy::boolean_result* br, std:: if (std::find_if(extrusions.begin(), extrusions.end(), [&Z](extrusion_pair& p) { // @todo factor in p.first; auto ex = p.second; - auto& m = ex->matrix.ccomponents(); + auto& m = ex->matrix->ccomponents(); return std::abs(1. - std::abs(m.col(2).head<3>().dot(Z))) > 1.e-5; }) != extrusions.end()) { return false; @@ -1328,8 +1325,8 @@ bool CgalKernel::process_as_2d_polygon(const taxonomy::boolean_result* br, std:: // | op[i].matrix[2,0:3] . op[i].direction | = 1 if (std::find_if(extrusions.begin(), extrusions.end(), [](extrusion_pair& p) { auto ex = p.second; - auto& d = ex->direction.ccomponents(); - auto& m = ex->matrix.ccomponents(); + auto& d = ex->direction->ccomponents(); + auto& m = ex->matrix->ccomponents(); return std::abs(1. - std::abs(m.col(2).head<3>().dot(d))) > 1.e-5; }) != extrusions.end()) { return false; @@ -1344,10 +1341,10 @@ bool CgalKernel::process_as_2d_polygon(const taxonomy::boolean_result* br, std:: return false; } - const auto& op_0_matrix_2_3 = extrusions[0].second->matrix.ccomponents()(2, 3); + const auto& op_0_matrix_2_3 = extrusions[0].second->matrix->ccomponents()(2, 3); if (std::find_if(extrusions.begin() + 1, extrusions.end(), [&op_0_matrix_2_3](extrusion_pair& p) { auto ex = p.second; - return op_0_matrix_2_3 < ex->matrix.components()(2, 3); + return op_0_matrix_2_3 < ex->matrix->components()(2, 3); }) != extrusions.end()) { return false; } @@ -1356,8 +1353,8 @@ bool CgalKernel::process_as_2d_polygon(const taxonomy::boolean_result* br, std:: try { std::transform(extrusions.begin(), extrusions.end(), std::back_inserter(wires), [this](extrusion_pair& p) { auto ex = p.second; - if (ex->basis.children.size() == 1 && ex->basis.children[0]->kind() == taxonomy::LOOP) { - auto l = (taxonomy::loop*) ex->basis.children[0]; + if (ex->basis->children.size() == 1 && ex->basis->children[0]->kind() == taxonomy::LOOP) { + auto l = (taxonomy::loop::ptr) ex->basis->children[0]; cgal_wire_t w; cgal_placement_t trsf; convert_placement(ex->matrix, trsf); @@ -1396,9 +1393,9 @@ bool CgalKernel::process_as_2d_polygon(const taxonomy::boolean_result* br, std:: loops.clear(); std::transform(wires.begin(), wires.end(), std::back_inserter(loops), wire_to_polygon_2); - auto& op_0_matrix = extrusions[0].second->matrix.ccomponents(); + auto& op_0_matrix = extrusions[0].second->matrix->ccomponents(); Eigen::Vector4d op_0_dir; - op_0_dir << extrusions[0].second->direction.ccomponents(), 0; + op_0_dir << extrusions[0].second->direction->ccomponents(), 0; op_0_dir = op_0_matrix * op_0_dir; z0 = op_0_matrix_2_3; z1 = z0 + extrusions[0].second->depth * op_0_dir(2); @@ -1501,7 +1498,7 @@ bool CgalKernel::process_as_2d_polygon(const std::listbegin(); jt != it->end(); ++jt) { auto& nth_op = jt->second; std::pair operand_n_distance_along_normal; - if (!orthogonal_edge_length(first_op, fnorm, operand_n_distance_along_normal)) { + if (!orthogonal_edge_length(nth_op, fnorm, operand_n_distance_along_normal)) { return false; } @@ -1525,7 +1522,7 @@ bool CgalKernel::process_as_2d_polygon(const std::list void project_onto_plane(const taxonomy::plane& p, It i, It j, Fn fn) { - auto mi = p.matrix.ccomponents().inverse(); + auto mi = p.matrix->ccomponents().inverse(); Eigen::Vector4d v; std::for_each(i, j, [&mi, &v, &fn](const cgal_shape_t& shp) { for (auto& vv : vertices(shp)) { @@ -1541,22 +1538,22 @@ namespace { } } -bool CgalKernel::convert_impl(const taxonomy::boolean_result* br, ConversionResults& results) { +bool CgalKernel::convert_impl(const taxonomy::boolean_result::ptr br, ConversionResults& results) { double z0, z1; std::list> loops; if (process_as_2d_polygon(br, loops, z0, z1)) { - taxonomy::style* first_item_style = nullptr; + taxonomy::style::ptr first_item_style = nullptr; { - auto gi = dynamic_cast(br->children[0]); + auto gi = br->children[0]; while (gi) { if (gi->surface_style) { first_item_style = gi->surface_style; break; } - auto ci = dynamic_cast(gi); + auto ci = taxonomy::dcast(gi); if (ci && ci->children.size() == 1) { - gi = dynamic_cast(ci->children[0]); + gi = ci->children[0]; } else { break; } @@ -1614,7 +1611,7 @@ bool CgalKernel::convert_impl(const taxonomy::boolean_result* br, ConversionResu ); cgal_shape_t shp; - taxonomy::direction3 d(0, 0, 1); + auto d = taxonomy::make(0, 0, 1); process_extrusion(f, d, z1 - z0, shp); for (auto it = shp.vertices_begin(); it != shp.vertices_end(); ++it) { @@ -1646,7 +1643,7 @@ bool CgalKernel::convert_impl(const taxonomy::boolean_result* br, ConversionResu CGAL::Nef_nary_union_3> second_operand_collector; size_t second_operand_collector_size = 0; - taxonomy::style* first_item_style = nullptr; + taxonomy::style::ptr first_item_style = nullptr; std::list>> operands; @@ -1660,7 +1657,7 @@ bool CgalKernel::convert_impl(const taxonomy::boolean_result* br, ConversionResu operands.back().first = c->instance->as(); if (c->kind() == taxonomy::SOLID && c->instance->declaration().is("IfcHalfSpaceSolid") && !first) { - auto face = (taxonomy::face*) ((taxonomy::solid*) c)->children[0]; + auto face = taxonomy::cast(c)->children[0]->children[0]; if (face->basis == nullptr || face->basis->kind() != taxonomy::PLANE) { return false; @@ -1671,7 +1668,7 @@ bool CgalKernel::convert_impl(const taxonomy::boolean_result* br, ConversionResu double uvw_min[3] = { +inf, +inf, +inf }; double uvw_max[3] = { -inf, -inf, -inf }; - auto& p = *((taxonomy::plane*)face->basis); + auto& p = *taxonomy::cast(face->basis); project_onto_plane(p, operands.front().second.begin(), operands.front().second.end(), @@ -1710,7 +1707,7 @@ bool CgalKernel::convert_impl(const taxonomy::boolean_result* br, ConversionResu return false; } // static - taxonomy::direction3 z(0, 0, 1); + auto z = taxonomy::make(0, 0, 1); cgal_shape_t poly; process_extrusion(f, z, 200, poly); for (auto& v : vertices(poly)) { @@ -1741,17 +1738,17 @@ bool CgalKernel::convert_impl(const taxonomy::boolean_result* br, ConversionResu AbstractKernel::convert(c, cr); if (first && br->operation == taxonomy::boolean_result::SUBTRACTION) { - first_item_style = ((taxonomy::geom_item*)c)->surface_style; + first_item_style = c->surface_style; if (!first_item_style && c->kind() == taxonomy::COLLECTION) { // @todo recursively right? - first_item_style = ((taxonomy::geom_item*) ((taxonomy::collection*)c)->children[0])->surface_style; + first_item_style = taxonomy::cast(c)->children[0]->surface_style; } } for (auto it = cr.begin(); it != cr.end(); ++it) { const cgal_shape_t& entity_shape_unlocated(((CgalShape*)it->Shape())->shape()); cgal_shape_t entity_shape(entity_shape_unlocated); - if (!it->Placement().is_identity()) { + if (!it->Placement()->is_identity()) { cgal_placement_t trsf; convert_placement(it->Placement(), trsf); for (auto &vertex : vertices(entity_shape)) { diff --git a/src/ifcgeom/kernels/cgal/CgalKernel.h b/src/ifcgeom/kernels/cgal/CgalKernel.h index ac7916b99d..5db393f93b 100644 --- a/src/ifcgeom/kernels/cgal/CgalKernel.h +++ b/src/ifcgeom/kernels/cgal/CgalKernel.h @@ -91,22 +91,22 @@ namespace ifcopenshell { void remove_duplicate_points_from_loop(cgal_wire_t& polygon); - bool convert(const taxonomy::extrusion*, cgal_shape_t&); - bool convert(const taxonomy::face*, cgal_face_t&); - bool convert(const taxonomy::loop*, cgal_wire_t&); - // bool convert(const taxonomy::matrix4*, cgal_placement_t&); - bool convert(const taxonomy::shell*, cgal_shape_t&); + bool convert(const taxonomy::extrusion::ptr, cgal_shape_t&); + bool convert(const taxonomy::face::ptr, cgal_face_t&); + bool convert(const taxonomy::loop::ptr, cgal_wire_t&); + // bool convert(const taxonomy::matrix4::ptr, cgal_placement_t&); + bool convert(const taxonomy::shell::ptr, cgal_shape_t&); - bool process_extrusion(const cgal_face_t& bottom_face, const taxonomy::direction3& direction, double height, cgal_shape_t& shape); - bool process_as_2d_polygon(const taxonomy::boolean_result* br, std::list>& loops, double& z0, double& z1); + bool process_extrusion(const cgal_face_t& bottom_face, taxonomy::direction3::ptr direction, double height, cgal_shape_t& shape); + bool process_as_2d_polygon(const taxonomy::boolean_result::ptr br, std::list>& loops, double& z0, double& z1); bool process_as_2d_polygon(const std::list>>& operands, std::list>& loops, double& z0, double& z1); - virtual bool convert_impl(const taxonomy::shell*, IfcGeom::ConversionResults&); - virtual bool convert_impl(const taxonomy::extrusion*, IfcGeom::ConversionResults&); - virtual bool convert_impl(const taxonomy::boolean_result*, IfcGeom::ConversionResults&); - virtual bool convert_impl(const taxonomy::solid*, IfcGeom::ConversionResults&); + virtual bool convert_impl(const taxonomy::shell::ptr, IfcGeom::ConversionResults&); + virtual bool convert_impl(const taxonomy::extrusion::ptr, IfcGeom::ConversionResults&); + virtual bool convert_impl(const taxonomy::boolean_result::ptr, IfcGeom::ConversionResults&); + virtual bool convert_impl(const taxonomy::solid::ptr, IfcGeom::ConversionResults&); - virtual bool convert_openings(const IfcUtil::IfcBaseEntity* entity, const std::vector>& openings, + virtual bool convert_openings(const IfcUtil::IfcBaseEntity* entity, const std::vector>& openings, const IfcGeom::ConversionResults& entity_shapes, const ifcopenshell::geometry::taxonomy::matrix4& entity_trsf, IfcGeom::ConversionResults& cut_shapes); #ifndef IFOPSH_SIMPLE_KERNEL diff --git a/src/ifcgeom/kernels/opencascade/IfcGeomTree.h b/src/ifcgeom/kernels/opencascade/IfcGeomTree.h index 586358d4b4..29b4bcec01 100644 --- a/src/ifcgeom/kernels/opencascade/IfcGeomTree.h +++ b/src/ifcgeom/kernels/opencascade/IfcGeomTree.h @@ -406,7 +406,7 @@ namespace IfcGeom { auto compound_generic = elem->geometry().as_compound(); auto compound = ((ifcopenshell::geometry::OpenCascadeShape*)compound_generic)->shape(); - const auto& m = elem->transformation().data().ccomponents(); + const auto& m = elem->transformation().data()->ccomponents(); gp_Trsf tr; tr.SetValues( m(0, 0), m(0, 1), m(0, 2), m(0, 3), diff --git a/src/ifcgeom/kernels/opencascade/OpenCascadeConversionResult.cpp b/src/ifcgeom/kernels/opencascade/OpenCascadeConversionResult.cpp index aede4adbc7..789de9d4ae 100644 --- a/src/ifcgeom/kernels/opencascade/OpenCascadeConversionResult.cpp +++ b/src/ifcgeom/kernels/opencascade/OpenCascadeConversionResult.cpp @@ -23,7 +23,7 @@ namespace { void ifcopenshell::geometry::OpenCascadeShape::Triangulate(const IfcGeom::IteratorSettings& settings, const ifcopenshell::geometry::taxonomy::matrix4& place, IfcGeom::Representation::Triangulation* t, int surface_style_id) const { - // @todo remove duplication with OpenCascadeKernel::convert(const taxonomy::matrix4* matrix, gp_GTrsf& trsf); + // @todo remove duplication with OpenCascadeKernel::convert(const taxonomy::matrix4::ptr matrix, gp_GTrsf& trsf); // above can be static? // A 3x3 matrix to rotate the vertex normals diff --git a/src/ifcgeom/kernels/opencascade/OpenCascadeKernel.cpp b/src/ifcgeom/kernels/opencascade/OpenCascadeKernel.cpp index 299857f65d..b41c5c40d9 100644 --- a/src/ifcgeom/kernels/opencascade/OpenCascadeKernel.cpp +++ b/src/ifcgeom/kernels/opencascade/OpenCascadeKernel.cpp @@ -201,7 +201,7 @@ namespace { }; } -bool IfcGeom::OpenCascadeKernel::convert_openings(const IfcUtil::IfcBaseEntity* entity, const std::vector>& openings, +bool IfcGeom::OpenCascadeKernel::convert_openings(const IfcUtil::IfcBaseEntity* entity, const std::vector>& openings, const IfcGeom::ConversionResults& entity_shapes, const ifcopenshell::geometry::taxonomy::matrix4& entity_trsf, IfcGeom::ConversionResults& cut_shapes) { util::boolean_settings bst; @@ -252,7 +252,7 @@ bool IfcGeom::OpenCascadeKernel::convert_openings(const IfcUtil::IfcBaseEntity* auto gtrsf = opening_shapes[i].Placement(); // @todo check - Eigen::Matrix4d m = relative * gtrsf.ccomponents(); + Eigen::Matrix4d m = relative * gtrsf->ccomponents(); gp_Trsf trsf; trsf.SetValues( m(0, 0), m(0, 1), m(0, 2), m(0, 3), @@ -308,7 +308,7 @@ bool IfcGeom::OpenCascadeKernel::convert_openings(const IfcUtil::IfcBaseEntity* } else { entity_shape_unlocated = util::ensure_fit_for_subtraction(entity_part, entity_shape_solid, conv_settings_.getValue(ConversionSettings::GV_PRECISION)); } - const auto& m = it3->Placement().ccomponents(); + const auto& m = it3->Placement()->ccomponents(); // @todo // if (entity_shape_gtrsf.Form() == gp_Other) { // Logger::Message(Logger::LOG_WARNING, "Applying non uniform transformation to:", entity); @@ -383,7 +383,7 @@ bool IfcGeom::OpenCascadeKernel::convert_openings(const IfcUtil::IfcBaseEntity* combined_result = C; } - cut_shapes.push_back(IfcGeom::ConversionResult(it3->ItemId(), new OpenCascadeShape(combined_result), &it3->Style())); + cut_shapes.push_back(IfcGeom::ConversionResult(it3->ItemId(), new OpenCascadeShape(combined_result), it3->StylePtr())); } return true; } @@ -713,10 +713,10 @@ bool IfcGeom::OpenCascadeKernel::convert_openings(const IfcUtil::IfcBaseEntity* // try { // IfcSchema::IfcRepresentationItem::list::ptr items = representation->Items(); // if (items->size() == 1) { -// IfcSchema::IfcRepresentationItem* item = *items->begin(); +// IfcSchema::IfcRepresentationptr item = *items->begin(); // if (item->declaration().is(IfcSchema::IfcMappedItem::Class())) { // if (item->StyledByItem()->size() == 0) { -// IfcSchema::IfcMappedItem* mapped_item = item->as(); +// IfcSchema::IfcMappedptr mapped_item = item->as(); // if (is_identity_transform(mapped_item->MappingTarget())) { // IfcSchema::IfcRepresentationMap* map = mapped_item->MappingSource(); // if (is_identity_transform(map->MappingOrigin())) { @@ -767,7 +767,7 @@ bool IfcGeom::OpenCascadeKernel::convert_openings(const IfcUtil::IfcBaseEntity* // if (is_identity_transform(map->MappingOrigin())) { // IfcSchema::IfcMappedItem::list::ptr items = map->MapUsage(); // for (IfcSchema::IfcMappedItem::list::it it = items->begin(); it != items->end(); ++it) { -// IfcSchema::IfcMappedItem* item = *it; +// IfcSchema::IfcMappedptr item = *it; // if (item->StyledByItem()->size() != 0) continue; // // if (!is_identity_transform(item->MappingTarget())) { @@ -1265,7 +1265,7 @@ bool IfcGeom::OpenCascadeKernel::convert_openings(const IfcUtil::IfcBaseEntity* // return 0; // } // -// const IfcSchema::IfcRepresentationItem* IfcGeom::Kernel::find_item_carrying_style(const IfcSchema::IfcRepresentationItem* item) { +// const IfcSchema::IfcRepresentationptr IfcGeom::Kernel::find_item_carrying_style(const IfcSchema::IfcRepresentationptr item) { // if (item->StyledByItem()->size()) { // return item; // } @@ -1435,7 +1435,7 @@ bool IfcGeom::OpenCascadeKernel::convert_openings(const IfcUtil::IfcBaseEntity* // return style_cache[surface_style_id] = surface_style_ptr_const; // } // -// std::shared_ptr IfcGeom::Kernel::get_style(const IfcSchema::IfcRepresentationItem* item) { +// std::shared_ptr IfcGeom::Kernel::get_style(const IfcSchema::IfcRepresentationptr item) { // return internalize_surface_style(get_surface_style(item)); // } // diff --git a/src/ifcgeom/kernels/opencascade/OpenCascadeKernel.h b/src/ifcgeom/kernels/opencascade/OpenCascadeKernel.h index 3abfb8bc38..db70f81b51 100644 --- a/src/ifcgeom/kernels/opencascade/OpenCascadeKernel.h +++ b/src/ifcgeom/kernels/opencascade/OpenCascadeKernel.h @@ -81,7 +81,7 @@ private: double eps_; bool non_manifold_; - void loop_(const taxonomy::loop* ps, const std::function& callback); + void loop_(const taxonomy::loop::ptr ps, const std::function& callback); /* bool construct(const IfcSchema::IfcCartesianPoint* cp, gp_Pnt* l); @@ -99,7 +99,7 @@ private: std::vector get_idxs(const std::vector& it); */ public: - faceset_helper(OpenCascadeKernel* kernel, const taxonomy::shell* l); + faceset_helper(OpenCascadeKernel* kernel, const taxonomy::shell::ptr l); ~faceset_helper(); bool non_manifold() const { return non_manifold_; } @@ -108,8 +108,8 @@ private: bool edge(int A, int B, TopoDS_Edge& e); - bool wire(const taxonomy::loop* loop, TopoDS_Wire& wire); - bool wires(const taxonomy::loop* loop, TopTools_ListOfShape& wires); + bool wire(const taxonomy::loop::ptr loop, TopoDS_Wire& wire); + bool wires(const taxonomy::loop::ptr loop, TopTools_ListOfShape& wires); }; faceset_helper* faceset_helper_; @@ -130,25 +130,25 @@ public: , precision_(settings.getValue(ConversionSettings::GV_PRECISION)) {} - bool convert(const taxonomy::extrusion*, TopoDS_Shape&); - bool convert(const taxonomy::face*, TopoDS_Shape&); - bool convert(const taxonomy::loop*, TopoDS_Wire&); - bool convert(const taxonomy::matrix4*, gp_GTrsf&); - bool convert(const taxonomy::shell*, TopoDS_Shape&); - bool convert(const taxonomy::solid*, TopoDS_Shape&); - bool convert(const taxonomy::bspline_surface* bs, Handle(Geom_Surface) surf); + bool convert(const taxonomy::extrusion::ptr, TopoDS_Shape&); + bool convert(const taxonomy::face::ptr, TopoDS_Shape&); + bool convert(const taxonomy::loop::ptr, TopoDS_Wire&); + bool convert(const taxonomy::matrix4::ptr, gp_GTrsf&); + bool convert(const taxonomy::shell::ptr, TopoDS_Shape&); + bool convert(const taxonomy::solid::ptr, TopoDS_Shape&); + bool convert(const taxonomy::bspline_surface::ptr bs, Handle(Geom_Surface) surf); TopoDS_Shape apply_transformation(const TopoDS_Shape& s, const taxonomy::matrix4& t); TopoDS_Shape apply_transformation(const TopoDS_Shape& s, const gp_GTrsf& t); TopoDS_Shape apply_transformation(const TopoDS_Shape& s, const gp_Trsf& t); - virtual bool convert_impl(const taxonomy::face*, IfcGeom::ConversionResults&); - virtual bool convert_impl(const taxonomy::solid*, IfcGeom::ConversionResults&); - virtual bool convert_impl(const taxonomy::shell*, IfcGeom::ConversionResults&); - virtual bool convert_impl(const taxonomy::extrusion*, IfcGeom::ConversionResults&); - virtual bool convert_impl(const taxonomy::boolean_result*, IfcGeom::ConversionResults&); + virtual bool convert_impl(const taxonomy::face::ptr, IfcGeom::ConversionResults&); + virtual bool convert_impl(const taxonomy::solid::ptr, IfcGeom::ConversionResults&); + virtual bool convert_impl(const taxonomy::shell::ptr, IfcGeom::ConversionResults&); + virtual bool convert_impl(const taxonomy::extrusion::ptr, IfcGeom::ConversionResults&); + virtual bool convert_impl(const taxonomy::boolean_result::ptr, IfcGeom::ConversionResults&); - virtual bool convert_openings(const IfcUtil::IfcBaseEntity* entity, const std::vector>& openings, + virtual bool convert_openings(const IfcUtil::IfcBaseEntity* entity, const std::vector>& openings, const IfcGeom::ConversionResults& entity_shapes, const ifcopenshell::geometry::taxonomy::matrix4& entity_trsf, IfcGeom::ConversionResults& cut_shapes); template diff --git a/src/ifcgeom/kernels/opencascade/base_utils.cpp b/src/ifcgeom/kernels/opencascade/base_utils.cpp index 28668f7bfc..37b019c722 100644 --- a/src/ifcgeom/kernels/opencascade/base_utils.cpp +++ b/src/ifcgeom/kernels/opencascade/base_utils.cpp @@ -761,7 +761,7 @@ bool IfcGeom::util::flatten_shape_list(const IfcGeom::ConversionResults& shapes, } // @todo refactor, also should be GTrsf - const auto& m = it->Placement().ccomponents(); + const auto& m = it->Placement()->ccomponents(); gp_Trsf trsf; trsf.SetValues( m(0, 0), m(0, 1), m(0, 2), m(0, 3), diff --git a/src/ifcgeom/kernels/opencascade/boolean_result.cpp b/src/ifcgeom/kernels/opencascade/boolean_result.cpp index aa6c4ba267..365419b500 100644 --- a/src/ifcgeom/kernels/opencascade/boolean_result.cpp +++ b/src/ifcgeom/kernels/opencascade/boolean_result.cpp @@ -43,7 +43,7 @@ namespace { } } -bool OpenCascadeKernel::convert_impl(const taxonomy::boolean_result* br, ConversionResults& results) { +bool OpenCascadeKernel::convert_impl(const taxonomy::boolean_result::ptr br, ConversionResults& results) { bool valid_result = false; bool first = true; const double tol = conv_settings_.getValue(ConversionSettings::GV_PRECISION); @@ -51,7 +51,7 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::boolean_result* br, Convers TopoDS_Shape a; TopTools_ListOfShape b; - taxonomy::style* first_item_style = nullptr; + taxonomy::style::ptr first_item_style; for (auto& c : br->children) { IfcGeom::ConversionResults cr; @@ -59,10 +59,10 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::boolean_result* br, Convers if (first && br->operation == taxonomy::boolean_result::SUBTRACTION) { // @todo A will be null on union/intersection, intended? IfcGeom::util::flatten_shape_list(cr, a, false, conv_settings_.getValue(ifcopenshell::geometry::ConversionSettings::GV_PRECISION)); - first_item_style = ((taxonomy::geom_item*)c)->surface_style; + first_item_style = c->surface_style; if (!first_item_style && c->kind() == taxonomy::COLLECTION) { // @todo recursively right? - first_item_style = ((taxonomy::geom_item*) ((taxonomy::collection*)c)->children[0])->surface_style; + first_item_style = taxonomy::cast(taxonomy::cast(c)->children[0])->surface_style; } if (conv_settings_.getValue(ConversionSettings::GV_DISABLE_BOOLEAN_RESULT) > 0.0) { @@ -84,7 +84,7 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::boolean_result* br, Convers for (auto& r : cr) { auto S = ((OpenCascadeShape*)r.Shape())->shape(); gp_GTrsf trsf; - convert(&r.Placement(), trsf); + convert(r.Placement(), trsf); // @todo it really confuses me why I cannot use Moved() here instead S.Location(S.Location() * trsf.Trsf()); diff --git a/src/ifcgeom/kernels/opencascade/bspline_surface.cpp b/src/ifcgeom/kernels/opencascade/bspline_surface.cpp index 76e073ff3d..2f854268e7 100644 --- a/src/ifcgeom/kernels/opencascade/bspline_surface.cpp +++ b/src/ifcgeom/kernels/opencascade/bspline_surface.cpp @@ -6,7 +6,7 @@ using namespace ifcopenshell::geometry; using namespace ifcopenshell::geometry::kernels; using namespace IfcGeom; -bool OpenCascadeKernel::convert(const taxonomy::bspline_surface* bs, Handle(Geom_Surface) surf) { +bool OpenCascadeKernel::convert(const taxonomy::bspline_surface::ptr bs, Handle(Geom_Surface) surf) { const bool is_rational = !!bs->weights; TColgp_Array2OfPnt Poles(0, (int)bs->control_points.size() - 1, 0, (int)(*bs->control_points.begin()).size() - 1); @@ -22,7 +22,7 @@ bool OpenCascadeKernel::convert(const taxonomy::bspline_surface* bs, Handle(Geom for (auto it = bs->control_points.begin(); it != bs->control_points.end(); ++it, ++i) { j = 0; for (auto jt = (*it).begin(); jt != (*it).end(); ++jt, ++j) { - Poles(i, j) = convert_xyz(*jt); + Poles(i, j) = convert_xyz(**jt); } } diff --git a/src/ifcgeom/kernels/opencascade/extrusion.cpp b/src/ifcgeom/kernels/opencascade/extrusion.cpp index 24bad0ce55..e5c6c6d5c1 100644 --- a/src/ifcgeom/kernels/opencascade/extrusion.cpp +++ b/src/ifcgeom/kernels/opencascade/extrusion.cpp @@ -6,7 +6,7 @@ using namespace ifcopenshell::geometry; using namespace ifcopenshell::geometry::kernels; using namespace IfcGeom; -bool OpenCascadeKernel::convert(const taxonomy::extrusion* extrusion, TopoDS_Shape& shape) { +bool OpenCascadeKernel::convert(const taxonomy::extrusion::ptr extrusion, TopoDS_Shape& shape) { const double& height = extrusion->depth; if (height < conv_settings_.getValue(ConversionSettings::GV_PRECISION)) { @@ -15,7 +15,7 @@ bool OpenCascadeKernel::convert(const taxonomy::extrusion* extrusion, TopoDS_Sha } TopoDS_Shape face; - if (!convert(&extrusion->basis, face)) { + if (!convert(extrusion->basis, face)) { return false; } @@ -29,7 +29,7 @@ bool OpenCascadeKernel::convert(const taxonomy::extrusion* extrusion, TopoDS_Sha auto trsf = gtrsf.Trsf(); */ - const auto& fs = extrusion->direction.ccomponents(); + const auto& fs = extrusion->direction->ccomponents(); gp_Dir dir(fs(0), fs(1), fs(2)); shape.Nullify(); @@ -71,7 +71,7 @@ bool OpenCascadeKernel::convert(const taxonomy::extrusion* extrusion, TopoDS_Sha return !shape.IsNull(); } -bool OpenCascadeKernel::convert_impl(const taxonomy::extrusion* extrusion, IfcGeom::ConversionResults& results) { +bool OpenCascadeKernel::convert_impl(const taxonomy::extrusion::ptr extrusion, IfcGeom::ConversionResults& results) { TopoDS_Shape shape; if (!convert(extrusion, shape)) { return false; diff --git a/src/ifcgeom/kernels/opencascade/face.cpp b/src/ifcgeom/kernels/opencascade/face.cpp index 4a0e1d94b7..55ec2ace3c 100644 --- a/src/ifcgeom/kernels/opencascade/face.cpp +++ b/src/ifcgeom/kernels/opencascade/face.cpp @@ -47,9 +47,7 @@ using namespace ifcopenshell::geometry::kernels; using namespace IfcGeom; using namespace IfcGeom::util; -bool OpenCascadeKernel::convert(const taxonomy::face* face, TopoDS_Shape& result) { - auto bounds = face->children_as(); - +bool OpenCascadeKernel::convert(const taxonomy::face::ptr face, TopoDS_Shape& result) { face_definition fd; const bool is_face_surface = false; /* todo */ @@ -71,10 +69,10 @@ bool OpenCascadeKernel::convert(const taxonomy::face* face, TopoDS_Shape& result } */ - const int num_bounds = bounds.size(); + const int num_bounds = face->children.size(); int num_outer_bounds = 0; - for (auto& bound : bounds) { + for (auto& bound : face->children) { if (bound->external.get_value_or(false)) { num_outer_bounds++; } @@ -97,7 +95,7 @@ bool OpenCascadeKernel::convert(const taxonomy::face* face, TopoDS_Shape& result TopTools_DataMapOfShapeInteger wire_senses; for (int process_interior = 0; process_interior <= 1; ++process_interior) { - for (auto& bound : bounds) { + for (auto& bound : face->children) { bool same_sense = true; /* todo bound->Orientation(); */ const bool is_interior = @@ -302,7 +300,7 @@ bool OpenCascadeKernel::convert(const taxonomy::face* face, TopoDS_Shape& result return true; } -bool OpenCascadeKernel::convert_impl(const taxonomy::face* face, IfcGeom::ConversionResults& results) { +bool OpenCascadeKernel::convert_impl(const taxonomy::face::ptr face, IfcGeom::ConversionResults& results) { throw std::runtime_error("Root-level face not expected"); /* @@ -320,7 +318,7 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::face* face, IfcGeom::Conver } // @todo boundary - const auto& m = ((taxonomy::geom_item*)face->basis)->matrix.ccomponents(); + const auto& m = ((taxonomy::geom_ptr)face->basis)->matrix.ccomponents(); gp_Pln pln(convert_xyz2(m.col(3)), convert_xyz2(m.col(2))); const gp_Pnt pnt = pln.Location().Translated(face->orientation.get_value_or(false) ? -pln.Axis().Direction() : pln.Axis().Direction()); TopoDS_Shape shape = BRepPrimAPI_MakeHalfSpace(BRepBuilderAPI_MakeFace(pln), pnt).Solid(); diff --git a/src/ifcgeom/kernels/opencascade/faceset_helper.cpp b/src/ifcgeom/kernels/opencascade/faceset_helper.cpp index 643a9588fe..7f2ea86104 100644 --- a/src/ifcgeom/kernels/opencascade/faceset_helper.cpp +++ b/src/ifcgeom/kernels/opencascade/faceset_helper.cpp @@ -27,21 +27,21 @@ namespace { IfcGeom::OpenCascadeKernel::faceset_helper::faceset_helper( OpenCascadeKernel* kernel, - const taxonomy::shell* shell + const taxonomy::shell::ptr shell ) : kernel_(kernel) , non_manifold_(false) { // @todo use pointers? - std::vector points; - std::vector loops; + std::vector points; + std::vector loops; - for (auto& f : shell->children_as()) { - for (auto& l : f->children_as()) { + for (auto& f : shell->children) { + for (auto& l : f->children) { loops.push_back(l); - for (auto& e : l->children_as()) { + for (auto& e : l->children) { // @todo make sure only cartesian points are provided here - points.push_back(boost::get(e->start)); + points.push_back(boost::get(e->start)); } } } @@ -55,7 +55,7 @@ IfcGeom::OpenCascadeKernel::faceset_helper::faceset_helper( Bnd_Box box; for (size_t i = 0; i < points.size(); ++i) { - gp_Pnt* p = new gp_Pnt(convert_xyz(points[i])); + gp_Pnt* p = new gp_Pnt(convert_xyz(*points[i])); pnts[i].reset(p); B.MakeVertex(vertices[i], *p, Precision::Confusion()); tree.add(i, vertices[i]); @@ -116,7 +116,7 @@ IfcGeom::OpenCascadeKernel::faceset_helper::faceset_helper( find_neighbours(tree, pnts, vs, pnt_i, eps_); for (int v : vs) { - auto& pt = points[v]; + auto& pt = *points[v]; // NB: insert() ignores duplicate keys // v-1? // @todo this reliable also in case of tesselations? @@ -192,15 +192,15 @@ IfcGeom::OpenCascadeKernel::faceset_helper::faceset_helper( } } -void IfcGeom::OpenCascadeKernel::faceset_helper::loop_(const taxonomy::loop* ps, const std::function& callback) { +void IfcGeom::OpenCascadeKernel::faceset_helper::loop_(const taxonomy::loop::ptr ps, const std::function& callback) { if (ps->children.size() < 3) { return; } - auto a = boost::get(((taxonomy::edge*) ps->children.back())->start); - auto A = a.identity(); + auto a = boost::get(ps->children.back()->start); + auto A = a->identity(); for (auto& b : ps->children) { - auto B = boost::get(((taxonomy::edge*) b)->start).identity(); + auto B = boost::get(b->start)->identity(); auto C = vertex_mapping_[A], D = vertex_mapping_[B]; bool fwd = C < D; if (!fwd) { @@ -222,7 +222,7 @@ bool IfcGeom::OpenCascadeKernel::faceset_helper::edge(int A, int B, TopoDS_Edge& return true; } -bool IfcGeom::OpenCascadeKernel::faceset_helper::wire(const taxonomy::loop* loop, TopoDS_Wire& w) { +bool IfcGeom::OpenCascadeKernel::faceset_helper::wire(const taxonomy::loop::ptr loop, TopoDS_Wire& w) { TopTools_ListOfShape ws; if (!wires(loop, ws)) { return false; @@ -231,7 +231,7 @@ bool IfcGeom::OpenCascadeKernel::faceset_helper::wire(const taxonomy::loop* loop return true; } -bool IfcGeom::OpenCascadeKernel::faceset_helper::wires(const taxonomy::loop* loop, TopTools_ListOfShape& wires) { +bool IfcGeom::OpenCascadeKernel::faceset_helper::wires(const taxonomy::loop::ptr loop, TopTools_ListOfShape& wires) { if (duplicates_.find(loop->identity()) != duplicates_.end()) { return false; } diff --git a/src/ifcgeom/kernels/opencascade/layerset.cpp b/src/ifcgeom/kernels/opencascade/layerset.cpp index 498f42a207..9f53f2fe38 100644 --- a/src/ifcgeom/kernels/opencascade/layerset.cpp +++ b/src/ifcgeom/kernels/opencascade/layerset.cpp @@ -164,7 +164,7 @@ namespace { } -bool IfcGeom::util::apply_folded_layerset(const ConversionResults& items, const std::vector< std::vector >& surfaces, const std::vector& styles, ConversionResults& result, double tol) { +bool IfcGeom::util::apply_folded_layerset(const ConversionResults& items, const std::vector< std::vector >& surfaces, const std::vector& styles, ConversionResults& result, double tol) { Bnd_Box bb; TopoDS_Shape input; flatten_shape_list(items, input, false, tol); @@ -249,8 +249,8 @@ bool IfcGeom::util::apply_folded_layerset(const ConversionResults& items, const for (ConversionResults::const_iterator it = items.begin(); it != items.end(); ++it) { TopoDS_Shape a, b; if (split_solid_by_shell(((OpenCascadeShape*)it->Shape())->shape(), shells.First(), a, b, tol)) { - result.push_back(ConversionResult(it->ItemId(), it->Placement(), new OpenCascadeShape(b), &(!!styles[0].diffuse ? styles[0] : it->Style()))); - result.push_back(ConversionResult(it->ItemId(), it->Placement(), new OpenCascadeShape(a), &(!!styles[1].diffuse ? styles[1] : it->Style()))); + result.push_back(ConversionResult(it->ItemId(), it->Placement(), new OpenCascadeShape(b), (!!styles[0] ? styles[0] : it->StylePtr()))); + result.push_back(ConversionResult(it->ItemId(), it->Placement(), new OpenCascadeShape(a), (!!styles[1] ? styles[1] : it->StylePtr()))); } else { continue; } @@ -269,7 +269,7 @@ bool IfcGeom::util::apply_folded_layerset(const ConversionResults& items, const std::vector slices; if (split(s, shells, tol, slices) && slices.size() == styles.size()) { for (size_t i = 0; i < slices.size(); ++i) { - result.push_back(ConversionResult(it->ItemId(), it->Placement(), new OpenCascadeShape(slices[i]), &(!!styles[i].diffuse ? styles[i] : it->Style()))); + result.push_back(ConversionResult(it->ItemId(), it->Placement(), new OpenCascadeShape(slices[i]), (!!styles[i] ? styles[i] : it->StylePtr()))); } } else { return false; @@ -282,7 +282,7 @@ bool IfcGeom::util::apply_folded_layerset(const ConversionResults& items, const } -bool IfcGeom::util::apply_layerset(const ConversionResults& items, const std::vector& surfaces, const std::vector& styles, ConversionResults& result, double tol) { +bool IfcGeom::util::apply_layerset(const ConversionResults& items, const std::vector& surfaces, const std::vector& styles, ConversionResults& result, double tol) { if (surfaces.size() < 3) { return false; @@ -292,8 +292,8 @@ bool IfcGeom::util::apply_layerset(const ConversionResults& items, const std::ve for (ConversionResults::const_iterator it = items.begin(); it != items.end(); ++it) { TopoDS_Shape a, b; if (split_solid_by_surface(((OpenCascadeShape*)it->Shape())->shape(), surfaces[1], a, b, tol)) { - result.push_back(ConversionResult(it->ItemId(), it->Placement(),new OpenCascadeShape(b), &(!!styles[0].diffuse ? styles[0] : it->Style()))); - result.push_back(ConversionResult(it->ItemId(), it->Placement(),new OpenCascadeShape(a), &(!!styles[1].diffuse ? styles[1] : it->Style()))); + result.push_back(ConversionResult(it->ItemId(), it->Placement(),new OpenCascadeShape(b), (!!styles[0] ? styles[0] : it->StylePtr()))); + result.push_back(ConversionResult(it->ItemId(), it->Placement(),new OpenCascadeShape(a), (!!styles[1] ? styles[1] : it->StylePtr()))); } else { continue; } @@ -360,7 +360,7 @@ bool IfcGeom::util::apply_layerset(const ConversionResults& items, const std::ve std::vector slices; if (split(s, operands, tol, slices) && slices.size() == styles.size()) { for (size_t i = 0; i < slices.size(); ++i) { - result.push_back(ConversionResult(it->ItemId(), it->Placement(), new OpenCascadeShape(slices[i]), &(!!styles[i].diffuse ? styles[i] : it->Style()))); + result.push_back(ConversionResult(it->ItemId(), it->Placement(), new OpenCascadeShape(slices[i]), (!!styles[i] ? styles[i] : it->StylePtr()))); } } else { return false; diff --git a/src/ifcgeom/kernels/opencascade/layerset.h b/src/ifcgeom/kernels/opencascade/layerset.h index b14d7589e5..4d51cb8ffe 100644 --- a/src/ifcgeom/kernels/opencascade/layerset.h +++ b/src/ifcgeom/kernels/opencascade/layerset.h @@ -11,9 +11,9 @@ namespace IfcGeom { namespace util { - bool apply_layerset(const ConversionResults&, const std::vector&, const std::vector&, ConversionResults&, double tol); + bool apply_layerset(const ConversionResults&, const std::vector&, const std::vector&, ConversionResults&, double tol); - bool apply_folded_layerset(const ConversionResults&, const std::vector< std::vector >&, const std::vector&, ConversionResults&, double tol); + bool apply_folded_layerset(const ConversionResults&, const std::vector< std::vector >&, const std::vector&, ConversionResults&, double tol); bool split_solid_by_surface(const TopoDS_Shape&, const Handle_Geom_Surface&, TopoDS_Shape&, TopoDS_Shape&, double tol); diff --git a/src/ifcgeom/kernels/opencascade/loop.cpp b/src/ifcgeom/kernels/opencascade/loop.cpp index 93c144b5b5..cdade4e16e 100644 --- a/src/ifcgeom/kernels/opencascade/loop.cpp +++ b/src/ifcgeom/kernels/opencascade/loop.cpp @@ -26,21 +26,21 @@ using namespace IfcGeom::util; namespace { typedef boost::variant curve_creation_visitor_result_type; - curve_creation_visitor_result_type convert_curve(OpenCascadeKernel* kernel, const taxonomy::item* curve); + curve_creation_visitor_result_type convert_curve(OpenCascadeKernel* kernel, const taxonomy::ptr curve); struct curve_creation_visitor { OpenCascadeKernel* kernel; curve_creation_visitor_result_type result; - curve_creation_visitor_result_type operator()(const taxonomy::bspline_curve& bc) { + curve_creation_visitor_result_type operator()(const taxonomy::bspline_curve::ptr& bc) { - const bool is_rational = !!bc.weights; + const bool is_rational = !!bc->weights; - TColgp_Array1OfPnt Poles(0, bc.control_points.size() - 1); - TColStd_Array1OfReal Weights(0, bc.control_points.size() - 1); - TColStd_Array1OfReal Knots(0, (int)bc.knots.size() - 1); - TColStd_Array1OfInteger Mults(0, (int)bc.knots.size() - 1); - Standard_Integer Degree = bc.degree; + TColgp_Array1OfPnt Poles(0, bc->control_points.size() - 1); + TColStd_Array1OfReal Weights(0, bc->control_points.size() - 1); + TColStd_Array1OfReal Knots(0, (int)bc->knots.size() - 1); + TColStd_Array1OfInteger Mults(0, (int)bc->knots.size() - 1); + Standard_Integer Degree = bc->degree; Standard_Boolean Periodic = false; // @tfk: it appears to be wrong to expect a period curve when the curve is closed, see #586 // Standard_Boolean Periodic = l->ClosedCurve(); @@ -49,23 +49,23 @@ namespace { if (is_rational) { i = 0; - for (auto it = bc.weights->begin(); it != bc.weights->end(); ++it, ++i) { + for (auto it = bc->weights->begin(); it != bc->weights->end(); ++it, ++i) { Weights(i) = *it; } } i = 0; - for (auto it = bc.control_points.begin(); it != bc.control_points.end(); ++it, ++i) { - Poles(i) = OpenCascadeKernel::convert_xyz(*it); + for (auto it = bc->control_points.begin(); it != bc->control_points.end(); ++it, ++i) { + Poles(i) = OpenCascadeKernel::convert_xyz(**it); } i = 0; - for (auto it = bc.multiplicities.begin(); it != bc.multiplicities.end(); ++it, ++i) { + for (auto it = bc->multiplicities.begin(); it != bc->multiplicities.end(); ++it, ++i) { Mults(i) = *it; } i = 0; - for (auto it = bc.knots.begin(); it != bc.knots.end(); ++it, ++i) { + for (auto it = bc->knots.begin(); it != bc->knots.end(); ++it, ++i) { Knots(i) = *it; } @@ -76,44 +76,44 @@ namespace { } } - curve_creation_visitor_result_type operator()(const taxonomy::line& l) { - const auto& m = l.matrix.ccomponents(); + curve_creation_visitor_result_type operator()(const taxonomy::line::ptr& l) { + const auto& m = l->matrix->ccomponents(); return result = Handle(Geom_Curve)(new Geom_Line(OpenCascadeKernel::convert_xyz2(m.col(3)), OpenCascadeKernel::convert_xyz2(m.col(0)))); } - curve_creation_visitor_result_type operator()(const taxonomy::circle& c) { - const auto& m = c.matrix.ccomponents(); - return result = Handle(Geom_Curve)(new Geom_Circle(gp_Ax2(OpenCascadeKernel::convert_xyz2(m.col(3)), OpenCascadeKernel::convert_xyz2(m.col(2)), OpenCascadeKernel::convert_xyz2(m.col(0))), c.radius)); + curve_creation_visitor_result_type operator()(const taxonomy::circle::ptr& c) { + const auto& m = c->matrix->ccomponents(); + return result = Handle(Geom_Curve)(new Geom_Circle(gp_Ax2(OpenCascadeKernel::convert_xyz2(m.col(3)), OpenCascadeKernel::convert_xyz2(m.col(2)), OpenCascadeKernel::convert_xyz2(m.col(0))), c->radius)); } - curve_creation_visitor_result_type operator()(const taxonomy::ellipse& e) { - const auto& m = e.matrix.ccomponents(); - return result = Handle(Geom_Curve)(new Geom_Ellipse(gp_Ax2(OpenCascadeKernel::convert_xyz2(m.col(3)), OpenCascadeKernel::convert_xyz2(m.col(2)), OpenCascadeKernel::convert_xyz2(m.col(0))), e.radius, e.radius2)); + curve_creation_visitor_result_type operator()(const taxonomy::ellipse::ptr& e) { + const auto& m = e->matrix->ccomponents(); + return result = Handle(Geom_Curve)(new Geom_Ellipse(gp_Ax2(OpenCascadeKernel::convert_xyz2(m.col(3)), OpenCascadeKernel::convert_xyz2(m.col(2)), OpenCascadeKernel::convert_xyz2(m.col(0))), e->radius, e->radius2)); } - curve_creation_visitor_result_type operator()(const taxonomy::loop& l) { + curve_creation_visitor_result_type operator()(const taxonomy::loop::ptr& l) { TopoDS_Wire wire; - kernel->convert(&l, wire); + kernel->convert(l, wire); return result = wire; } - curve_creation_visitor_result_type operator()(const taxonomy::edge& e) { + curve_creation_visitor_result_type operator()(const taxonomy::edge::ptr& e) { // @todo for polyloops/-lines we should probably construct edges based on correct oriented TopoDS_Vertex instead. - if (e.start.which() != e.end.which()) { + if (e->start.which() != e->end.which()) { throw std::runtime_error("Different trim types not supported"); } TopoDS_Edge E; - if (e.basis) { - auto crv_or_wire = convert_curve(kernel, e.basis); + if (e->basis) { + auto crv_or_wire = convert_curve(kernel, e->basis); Handle(Geom_Curve) curve; if (crv_or_wire.which() == 0) { curve = boost::get(crv_or_wire); } else { // @todo const double precision_ = 1.e-5; - Logger::Warning("Approximating BasisCurve due to possible discontinuities", e.instance); + Logger::Warning("Approximating BasisCurve due to possible discontinuities", e->instance); const auto& w = boost::get(crv_or_wire); #if OCC_VERSION_HEX < 0x70600 BRepAdaptor_CompCurve cc(w, true); @@ -126,13 +126,13 @@ namespace { curve = approx.Curve(); } - const bool reversed = !((taxonomy::geom_item*)e.basis)->orientation.get_value_or(true); - const bool is_conic = e.basis->kind() == taxonomy::ELLIPSE || e.basis->kind() == taxonomy::CIRCLE; + const bool reversed = !taxonomy::cast(e->basis)->orientation.get_value_or(true); + const bool is_conic = e->basis->kind() == taxonomy::ELLIPSE || e->basis->kind() == taxonomy::CIRCLE; // @todo, copy over logic from previous IfcTrimmedCurve handling - if (e.start.which() == 0) { - auto p1 = OpenCascadeKernel::convert_xyz(boost::get(e.start)); - auto p2 = OpenCascadeKernel::convert_xyz(boost::get(e.end)); + if (e->start.which() == 0) { + auto p1 = OpenCascadeKernel::convert_xyz(*boost::get(e->start)); + auto p2 = OpenCascadeKernel::convert_xyz(*boost::get(e->end)); if (reversed) { std::swap(p1, p2); @@ -140,8 +140,8 @@ namespace { E = BRepBuilderAPI_MakeEdge(curve, p1, p2).Edge(); } else { - auto v1 = boost::get(e.start); - auto v2 = boost::get(e.end); + auto v1 = boost::get(e->start); + auto v2 = boost::get(e->end); if (reversed) { std::swap(v1, v2); @@ -158,11 +158,11 @@ namespace { E.Reverse(); } } else { - if (e.start.which() != 0) { + if (e->start.which() != 0) { throw std::runtime_error("Non-cartesian trim on edge without curve"); } - auto p1 = OpenCascadeKernel::convert_xyz(boost::get(e.start)); - auto p2 = OpenCascadeKernel::convert_xyz(boost::get(e.end)); + auto p1 = OpenCascadeKernel::convert_xyz(*boost::get(e->start)); + auto p2 = OpenCascadeKernel::convert_xyz(*boost::get(e->end)); E = BRepBuilderAPI_MakeEdge(p1, p2).Edge(); } @@ -173,13 +173,13 @@ namespace { return result = W; } - curve_creation_visitor_result_type operator()(const taxonomy::offset_curve& l) { + curve_creation_visitor_result_type operator()(const taxonomy::offset_curve::ptr&) { // @todo throw std::runtime_error("Offset curves not supported as part of loop"); } }; - curve_creation_visitor_result_type convert_curve(OpenCascadeKernel* kernel, const taxonomy::item* curve) { + curve_creation_visitor_result_type convert_curve(OpenCascadeKernel* kernel, const taxonomy::ptr curve) { curve_creation_visitor v{ kernel }; if (dispatch_curve_creation::dispatch(curve, v)) { return v.result; @@ -189,12 +189,10 @@ namespace { } } -bool OpenCascadeKernel::convert(const taxonomy::loop* loop, TopoDS_Wire& wire) { - auto segments = loop->children_as(); - +bool OpenCascadeKernel::convert(const taxonomy::loop::ptr loop, TopoDS_Wire& wire) { TopTools_ListOfShape converted_segments; - for (auto& segment : segments) { + for (auto& segment : loop->children) { auto segment_wire = boost::get(convert_curve(this, segment)); #ifdef IFOPSH_DEBUG diff --git a/src/ifcgeom/kernels/opencascade/matrix4.cpp b/src/ifcgeom/kernels/opencascade/matrix4.cpp index 64fca27085..7559915f37 100644 --- a/src/ifcgeom/kernels/opencascade/matrix4.cpp +++ b/src/ifcgeom/kernels/opencascade/matrix4.cpp @@ -5,7 +5,7 @@ using namespace ifcopenshell::geometry::kernels; using namespace IfcGeom; using namespace IfcGeom::util; -bool OpenCascadeKernel::convert(const taxonomy::matrix4* matrix, gp_GTrsf& trsf) { +bool OpenCascadeKernel::convert(const taxonomy::matrix4::ptr matrix, gp_GTrsf& trsf) { // @todo check const auto& m = matrix->ccomponents(); gp_Mat mat( diff --git a/src/ifcgeom/kernels/opencascade/shell.cpp b/src/ifcgeom/kernels/opencascade/shell.cpp index f35ec60088..25defac364 100644 --- a/src/ifcgeom/kernels/opencascade/shell.cpp +++ b/src/ifcgeom/kernels/opencascade/shell.cpp @@ -7,13 +7,12 @@ using namespace ifcopenshell::geometry::kernels; using namespace IfcGeom; using namespace IfcGeom::util; -bool OpenCascadeKernel::convert(const taxonomy::shell* l, TopoDS_Shape& shape) { +bool OpenCascadeKernel::convert(const taxonomy::shell::ptr l, TopoDS_Shape& shape) { std::unique_ptr helper_scope; helper_scope.reset(new faceset_helper(this, l)); faceset_helper_ = helper_scope.get(); - auto faces = l->children_as(); double minimal_face_area = precision_ * precision_ * 0.5; double min_face_area = faceset_helper_ @@ -21,7 +20,7 @@ bool OpenCascadeKernel::convert(const taxonomy::shell* l, TopoDS_Shape& shape) { : minimal_face_area; TopTools_ListOfShape face_list; - for (auto& face : faces) { + for (auto& face : l->children) { bool success = false; TopoDS_Face occ_face; @@ -88,7 +87,7 @@ bool OpenCascadeKernel::convert(const taxonomy::shell* l, TopoDS_Shape& shape) { return true; } -bool OpenCascadeKernel::convert_impl(const taxonomy::shell *shell, IfcGeom::ConversionResults& results) { +bool OpenCascadeKernel::convert_impl(const taxonomy::shell::ptr shell, IfcGeom::ConversionResults& results) { TopoDS_Shape shape; if (!convert(shell, shape)) { return false; diff --git a/src/ifcgeom/kernels/opencascade/solid.cpp b/src/ifcgeom/kernels/opencascade/solid.cpp index ac42722ecf..7692c2ea17 100644 --- a/src/ifcgeom/kernels/opencascade/solid.cpp +++ b/src/ifcgeom/kernels/opencascade/solid.cpp @@ -29,59 +29,57 @@ using namespace ifcopenshell::geometry::kernels; using namespace IfcGeom; using namespace IfcGeom::util; -bool OpenCascadeKernel::convert(const taxonomy::solid* solid, TopoDS_Shape& result) { +bool OpenCascadeKernel::convert(const taxonomy::solid::ptr solid, TopoDS_Shape& result) { BRep_Builder BB; TopoDS_Solid S; - for (auto& s : solid->children) { - if (s->kind() == taxonomy::FACE) { - // halfspace - if (solid->children.size() != 1) { - throw std::runtime_error("Unexpected number of children on solid"); - } - auto face = (taxonomy::face*) s; - - const auto& m = ((taxonomy::geom_item*)face->basis)->matrix.ccomponents(); - gp_Pln pln(convert_xyz2(m.col(3)), convert_xyz2(m.col(2))); - const gp_Pnt pnt = pln.Location().Translated(face->orientation.get_value_or(false) ? pln.Axis().Direction() : -pln.Axis().Direction()); - TopoDS_Shape halfspace = BRepPrimAPI_MakeHalfSpace(BRepBuilderAPI_MakeFace(pln), pnt).Solid(); - - if (!face->children.empty()) { - TopoDS_Wire wire; - gp_GTrsf gtrsf; - - if (convert((taxonomy::loop*)face->children[0], wire) && wire.Closed() && convert(&face->matrix, gtrsf)) { - gp_Trsf trsf = gtrsf.Trsf(); - TopoDS_Shape prism = BRepPrimAPI_MakePrism(BRepBuilderAPI_MakeFace(wire), gp_Vec(0, 0, 200)); - gp_Trsf down; down.SetTranslation(gp_Vec(0, 0, -100.0)); - - // `trsf` and `down` both have a unit scale factor - prism.Move(trsf*down); - - halfspace = BRepAlgoAPI_Common(halfspace, prism); - } - } - - result = halfspace; - return true; - } else { - if (s->kind() != taxonomy::SHELL) { - throw std::runtime_error("Unexpected child in solid"); - } - if (S.IsNull()) { - BB.MakeSolid(S); - } - TopoDS_Shell shl; - convert(((taxonomy::shell*)s), shl); - BB.Add(S, shl); + if (solid->instance->declaration().is("IfcHalfSpaceSolid")) { + // halfspace + if (solid->children.size() != 1) { + throw std::runtime_error("Unexpected number of children on solid"); } + + auto face = solid->children[0]->children[0]; + + const auto& m = taxonomy::cast(face->basis)->matrix->ccomponents(); + gp_Pln pln(convert_xyz2(m.col(3)), convert_xyz2(m.col(2))); + const gp_Pnt pnt = pln.Location().Translated(face->orientation.get_value_or(false) ? pln.Axis().Direction() : -pln.Axis().Direction()); + TopoDS_Shape halfspace = BRepPrimAPI_MakeHalfSpace(BRepBuilderAPI_MakeFace(pln), pnt).Solid(); + + if (!face->children.empty()) { + TopoDS_Wire wire; + gp_GTrsf gtrsf; + + if (convert((taxonomy::loop::ptr)face->children[0], wire) && wire.Closed() && convert(face->matrix, gtrsf)) { + gp_Trsf trsf = gtrsf.Trsf(); + TopoDS_Shape prism = BRepPrimAPI_MakePrism(BRepBuilderAPI_MakeFace(wire), gp_Vec(0, 0, 200)); + gp_Trsf down; down.SetTranslation(gp_Vec(0, 0, -100.0)); + + // `trsf` and `down` both have a unit scale factor + prism.Move(trsf*down); + + halfspace = BRepAlgoAPI_Common(halfspace, prism); + } + } + + result = halfspace; + return true; + } + + for (auto& s : solid->children) { + if (S.IsNull()) { + BB.MakeSolid(S); + } + TopoDS_Shell shl; + convert(((taxonomy::shell::ptr)s), shl); + BB.Add(S, shl); } if (!S.IsNull()) { result = S; } } -bool OpenCascadeKernel::convert_impl(const taxonomy::solid* solid , IfcGeom::ConversionResults& results) { +bool OpenCascadeKernel::convert_impl(const taxonomy::solid::ptr solid , IfcGeom::ConversionResults& results) { TopoDS_Shape shape; if (!convert(solid, shape)) { return false; diff --git a/src/ifcgeom/mapping/IfcAnnotationFillArea.cpp b/src/ifcgeom/mapping/IfcAnnotationFillArea.cpp index d3dc456623..c091635342 100644 --- a/src/ifcgeom/mapping/IfcAnnotationFillArea.cpp +++ b/src/ifcgeom/mapping/IfcAnnotationFillArea.cpp @@ -23,19 +23,19 @@ using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcAnnotationFillArea* inst) { - auto loop = map(inst->OuterBoundary()); +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcAnnotationFillArea* inst) { + auto loop = taxonomy::cast(map(inst->OuterBoundary())); if (loop) { - auto face = new taxonomy::face; - ((taxonomy::loop*)loop)->external = true; + auto face = taxonomy::make(); + loop->external = true; face->children = { loop }; if (inst->InnerBoundaries()) { IfcSchema::IfcCurve::list::ptr inner_boundaries = *inst->InnerBoundaries(); for (auto& v : *inner_boundaries) { - auto inner_loop = map(v); + auto inner_loop = taxonomy::cast(map(v)); if (inner_loop) { - ((taxonomy::loop*)inner_loop)->external = false; + inner_loop->external = false; face->children.push_back(inner_loop); } } diff --git a/src/ifcgeom/mapping/IfcArbitraryClosedProfileDef.cpp b/src/ifcgeom/mapping/IfcArbitraryClosedProfileDef.cpp index 655807bb77..6a51091f99 100644 --- a/src/ifcgeom/mapping/IfcArbitraryClosedProfileDef.cpp +++ b/src/ifcgeom/mapping/IfcArbitraryClosedProfileDef.cpp @@ -23,20 +23,20 @@ using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcArbitraryClosedProfileDef* inst) { - auto loop = map(inst->OuterCurve()); +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcArbitraryClosedProfileDef* inst) { + auto loop = taxonomy::cast(map(inst->OuterCurve())); if (loop) { - auto face = new taxonomy::face; - ((taxonomy::loop*)loop)->external = true; + auto face = taxonomy::make(); + loop->external = true; face->children = { loop }; if (inst->as()) { auto with_voids = inst->as(); auto voids = with_voids->InnerCurves(); for (auto& v : *voids) { - auto inner_loop = map(v); + auto inner_loop = taxonomy::cast(map(v)); if (inner_loop) { - ((taxonomy::loop*)inner_loop)->external = false; + inner_loop->external = false; face->children.push_back(inner_loop); } } diff --git a/src/ifcgeom/mapping/IfcArbitraryOpenProfileDef.cpp b/src/ifcgeom/mapping/IfcArbitraryOpenProfileDef.cpp index 7dce615c80..ef39550354 100644 --- a/src/ifcgeom/mapping/IfcArbitraryOpenProfileDef.cpp +++ b/src/ifcgeom/mapping/IfcArbitraryOpenProfileDef.cpp @@ -23,6 +23,6 @@ using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcArbitraryOpenProfileDef* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcArbitraryOpenProfileDef* inst) { return map(inst->Curve()); } diff --git a/src/ifcgeom/mapping/IfcAxis1Placement.cpp b/src/ifcgeom/mapping/IfcAxis1Placement.cpp index 345a141c49..db4e76b4b0 100644 --- a/src/ifcgeom/mapping/IfcAxis1Placement.cpp +++ b/src/ifcgeom/mapping/IfcAxis1Placement.cpp @@ -22,16 +22,16 @@ using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcAxis1Placement* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcAxis1Placement* inst) { Eigen::Vector3d P, axis(0, 0, 1), ref; { - taxonomy::point3 v = as(map(inst->Location())); - P = *v.components_; + taxonomy::point3::ptr v = taxonomy::cast(map(inst->Location())); + P = *v->components_; } const bool hasAxis = inst->Axis(); if (hasAxis) { - taxonomy::direction3 v = as(map(inst->Axis())); - axis = *v.components_; + taxonomy::direction3::ptr v = taxonomy::cast(map(inst->Axis())); + axis = *v->components_; } // @todo not sure what to do with ref, we're probably never reading it, @@ -43,5 +43,5 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcAxis1Placement* inst) { ref = Eigen::Vector3d(1, 0, 0).cross(axis).normalized(); } - return new taxonomy::matrix4(P, axis, ref); + return taxonomy::make(P, axis, ref); } diff --git a/src/ifcgeom/mapping/IfcAxis2Placement2D.cpp b/src/ifcgeom/mapping/IfcAxis2Placement2D.cpp index 6e03b08cae..19dbbd2da2 100644 --- a/src/ifcgeom/mapping/IfcAxis2Placement2D.cpp +++ b/src/ifcgeom/mapping/IfcAxis2Placement2D.cpp @@ -23,16 +23,16 @@ using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcAxis2Placement2D* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcAxis2Placement2D* inst) { Eigen::Vector3d P, axis(0, 0, 1), V(1, 0, 0); { - taxonomy::point3 v = as(map(inst->Location())); - P = *v.components_; + taxonomy::point3::ptr v = taxonomy::cast(map(inst->Location())); + P = *v->components_; } const bool hasRef = !!inst->RefDirection(); if (hasRef) { - taxonomy::direction3 v = as(map(inst->RefDirection())); - V = *v.components_; + taxonomy::direction3::ptr v = taxonomy::cast(map(inst->RefDirection())); + V = *v->components_; } - return new taxonomy::matrix4(P, axis, V); + return taxonomy::make(P, axis, V); } diff --git a/src/ifcgeom/mapping/IfcAxis2Placement3D.cpp b/src/ifcgeom/mapping/IfcAxis2Placement3D.cpp index d6c2695d2d..b3f40dc989 100644 --- a/src/ifcgeom/mapping/IfcAxis2Placement3D.cpp +++ b/src/ifcgeom/mapping/IfcAxis2Placement3D.cpp @@ -23,11 +23,11 @@ using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcAxis2Placement3D* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcAxis2Placement3D* inst) { Eigen::Vector3d o, axis(0, 0, 1), refDirection, X(1, 0, 0); { - taxonomy::point3 v = as(map(inst->Location())); - o = *v.components_; + taxonomy::point3::ptr v = taxonomy::cast(map(inst->Location())); + o = *v->components_; } const bool hasAxis = !!inst->Axis(); const bool hasRef = !!inst->RefDirection(); @@ -37,13 +37,13 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcAxis2Placement3D* inst) { } if (hasAxis) { - taxonomy::direction3 v = as(map(inst->Axis())); - axis = *v.components_; + taxonomy::direction3::ptr v = taxonomy::cast(map(inst->Axis())); + axis = *v->components_; } if (hasRef) { - taxonomy::direction3 v = as(map(inst->RefDirection())); - refDirection = *v.components_; + taxonomy::direction3::ptr v = taxonomy::cast(map(inst->RefDirection())); + refDirection = *v->components_; } else { if (acos(axis.dot(X)) > 1.e-5) { refDirection = { 1., 0., 0. }; @@ -54,5 +54,5 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcAxis2Placement3D* inst) { auto Xaxis = refDirection - Xvec; refDirection = Xaxis; } - return new taxonomy::matrix4(o, axis, refDirection); + return taxonomy::make(o, axis, refDirection); } diff --git a/src/ifcgeom/mapping/IfcBSplineCurveWithKnots.cpp b/src/ifcgeom/mapping/IfcBSplineCurveWithKnots.cpp index 676c61d04a..304741cb21 100644 --- a/src/ifcgeom/mapping/IfcBSplineCurveWithKnots.cpp +++ b/src/ifcgeom/mapping/IfcBSplineCurveWithKnots.cpp @@ -25,12 +25,12 @@ using namespace ifcopenshell::geometry; #ifdef SCHEMA_HAS_IfcBSplineCurveWithKnots -taxonomy::item* mapping::map_impl(const IfcSchema::IfcBSplineCurveWithKnots* inst) { - auto bc = new taxonomy::bspline_curve; +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcBSplineCurveWithKnots* inst) { + auto bc = taxonomy::make(); const IfcSchema::IfcCartesianPoint::list::ptr cps = inst->ControlPointsList(); - std::vector points; - std::transform(cps->begin(), cps->end(), std::back_inserter(points), [this](IfcSchema::IfcCartesianPoint* cp) { return as(map(cp)); }); + std::vector points; + std::transform(cps->begin(), cps->end(), std::back_inserter(points), [this](IfcSchema::IfcCartesianPoint* cp) { return taxonomy::cast(map(cp)); }); bc->control_points = points; bc->multiplicities = inst->KnotMultiplicities(); diff --git a/src/ifcgeom/mapping/IfcBSplineSurfaceWithKnots.cpp b/src/ifcgeom/mapping/IfcBSplineSurfaceWithKnots.cpp index abdb75b118..3f11dcb44c 100644 --- a/src/ifcgeom/mapping/IfcBSplineSurfaceWithKnots.cpp +++ b/src/ifcgeom/mapping/IfcBSplineSurfaceWithKnots.cpp @@ -25,13 +25,13 @@ using namespace ifcopenshell::geometry; #ifdef SCHEMA_HAS_IfcBSplineSurfaceWithKnots -taxonomy::item* mapping::map_impl(const IfcSchema::IfcBSplineSurfaceWithKnots* inst) { - auto bs = new taxonomy::bspline_surface; +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcBSplineSurfaceWithKnots* inst) { + auto bs = taxonomy::make(); auto cps = inst->ControlPointsList(); std::transform(cps->begin(), cps->end(), std::back_inserter(bs->control_points), [this](const std::vector& inner) { - std::vector ps; - std::transform(inner.begin(), inner.end(), std::back_inserter(ps), [this](IfcSchema::IfcCartesianPoint* cp) { return as(map(cp)); }); + std::vector ps; + std::transform(inner.begin(), inner.end(), std::back_inserter(ps), [this](IfcSchema::IfcCartesianPoint* cp) { return taxonomy::cast(map(cp)); }); return ps; }); diff --git a/src/ifcgeom/mapping/IfcBlock.cpp b/src/ifcgeom/mapping/IfcBlock.cpp index b2a218eb4d..9087efa14c 100644 --- a/src/ifcgeom/mapping/IfcBlock.cpp +++ b/src/ifcgeom/mapping/IfcBlock.cpp @@ -22,13 +22,13 @@ using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcBlock* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcBlock* inst) { const double dx = inst->XLength() * length_unit_; const double dy = inst->YLength() * length_unit_; const double dz = inst->ZLength() * length_unit_; auto solid = create_box(dx, dy, dz); - solid->matrix = as(map(inst->Position())); + solid->matrix = taxonomy::cast(map(inst->Position())); return solid; } diff --git a/src/ifcgeom/mapping/IfcBooleanResult.cpp b/src/ifcgeom/mapping/IfcBooleanResult.cpp index 2b7f4b1933..d02104b0ac 100644 --- a/src/ifcgeom/mapping/IfcBooleanResult.cpp +++ b/src/ifcgeom/mapping/IfcBooleanResult.cpp @@ -37,7 +37,7 @@ namespace { } } -taxonomy::item* mapping::map_impl(const IfcSchema::IfcBooleanResult* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcBooleanResult* inst) { IfcSchema::IfcBooleanOperand* operand1 = inst->FirstOperand(); IfcSchema::IfcBooleanOperand* operand2 = inst->SecondOperand(); bool has_halfspace_operand = false; diff --git a/src/ifcgeom/mapping/IfcBoundingBox.cpp b/src/ifcgeom/mapping/IfcBoundingBox.cpp index 0b34c37192..d2a3a507f1 100644 --- a/src/ifcgeom/mapping/IfcBoundingBox.cpp +++ b/src/ifcgeom/mapping/IfcBoundingBox.cpp @@ -22,13 +22,13 @@ using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcBoundingBox* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcBoundingBox* inst) { const double dx = inst->XDim() * length_unit_; const double dy = inst->YDim() * length_unit_; const double dz = inst->ZDim() * length_unit_; - taxonomy::point3 corner = as(map(inst->Corner())); - auto solid = create_box(corner.ccomponents().x(), corner.ccomponents().y(), corner.ccomponents().z(), dx, dy, dz); + taxonomy::point3::ptr corner = taxonomy::cast(map(inst->Corner())); + auto solid = create_box(corner->ccomponents().x(), corner->ccomponents().y(), corner->ccomponents().z(), dx, dy, dz); return solid; } diff --git a/src/ifcgeom/mapping/IfcCShapeProfileDef.cpp b/src/ifcgeom/mapping/IfcCShapeProfileDef.cpp index c09a8bfbf4..2b62b44fcd 100644 --- a/src/ifcgeom/mapping/IfcCShapeProfileDef.cpp +++ b/src/ifcgeom/mapping/IfcCShapeProfileDef.cpp @@ -27,7 +27,7 @@ using namespace ifcopenshell::geometry; #include #include -taxonomy::item* mapping::map_impl(const IfcSchema::IfcCShapeProfileDef* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCShapeProfileDef* inst) { const double y = inst->Depth() / 2.0f * length_unit_; const double x = inst->Width() / 2.0f * length_unit_; const double d1 = inst->WallThickness() * length_unit_; @@ -47,13 +47,13 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcCShapeProfileDef* inst) { return nullptr; } - taxonomy::matrix4 m4; + taxonomy::matrix4::ptr m4; bool has_position = true; #ifdef SCHEMA_IfcParameterizedProfileDef_Position_IS_OPTIONAL has_position = !!inst->Position(); #endif if (has_position) { - m4 = as(map(inst->Position())); + m4 = taxonomy::cast(map(inst->Position())); } return profile_helper(m4, { diff --git a/src/ifcgeom/mapping/IfcCartesianPoint.cpp b/src/ifcgeom/mapping/IfcCartesianPoint.cpp index 5ee07f44e6..d959f26174 100644 --- a/src/ifcgeom/mapping/IfcCartesianPoint.cpp +++ b/src/ifcgeom/mapping/IfcCartesianPoint.cpp @@ -21,9 +21,9 @@ #define mapping POSTFIX_SCHEMA(mapping) using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcCartesianPoint* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCartesianPoint* inst) { std::vector xyz = inst->Coordinates(); - return new taxonomy::point3( + return taxonomy::make( xyz.size() >= 1 ? xyz[0] * length_unit_ : 0., xyz.size() >= 2 ? xyz[1] * length_unit_ : 0., xyz.size() >= 3 ? xyz[2] * length_unit_ : 0. diff --git a/src/ifcgeom/mapping/IfcCartesianTransformationOperator2D.cpp b/src/ifcgeom/mapping/IfcCartesianTransformationOperator2D.cpp index dbc68fde0a..fa2a215dc3 100644 --- a/src/ifcgeom/mapping/IfcCartesianTransformationOperator2D.cpp +++ b/src/ifcgeom/mapping/IfcCartesianTransformationOperator2D.cpp @@ -21,21 +21,21 @@ #define mapping POSTFIX_SCHEMA(mapping) using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcCartesianTransformationOperator2D* inst) { - auto m = new taxonomy::matrix4; +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCartesianTransformationOperator2D* inst) { + auto m = taxonomy::make(); Eigen::Vector4d origin, axis1(1.0, 0.0, 0.0, 0.0), axis2(0.0, 1.0, 0.0, 0.0), axis3(0.0, 0.0, 1.0, 0.0); - taxonomy::point3 O = as(map(inst->LocalOrigin())); - origin << *O.components_, 1.0; + taxonomy::point3::ptr O = taxonomy::cast(map(inst->LocalOrigin())); + origin << *O->components_, 1.0; if (inst->Axis1()) { - taxonomy::direction3 ax1 = as(map(inst->Axis1())); - axis1 << *ax1.components_, 0.0; + taxonomy::direction3::ptr ax1 = taxonomy::cast(map(inst->Axis1())); + axis1 << *ax1->components_, 0.0; } if (inst->Axis2()) { - taxonomy::direction3 ax2 = as(map(inst->Axis1())); - axis2 << *ax2.components_, 0.0; + taxonomy::direction3::ptr ax2 = taxonomy::cast(map(inst->Axis1())); + axis2 << *ax2->components_, 0.0; } double scale1, scale2; diff --git a/src/ifcgeom/mapping/IfcCartesianTransformationOperator3D.cpp b/src/ifcgeom/mapping/IfcCartesianTransformationOperator3D.cpp index 9aa073f482..1a4c3f5d4e 100644 --- a/src/ifcgeom/mapping/IfcCartesianTransformationOperator3D.cpp +++ b/src/ifcgeom/mapping/IfcCartesianTransformationOperator3D.cpp @@ -21,30 +21,30 @@ #define mapping POSTFIX_SCHEMA(mapping) using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcCartesianTransformationOperator3D* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCartesianTransformationOperator3D* inst) { Eigen::Vector4d origin; Eigen::Vector4d axis1(1., 0., 0., 0.); Eigen::Vector4d axis2(0., 1., 0., 0.); Eigen::Vector4d axis3(0., 0., 1., 0.); - taxonomy::point3 O = as(map(inst->LocalOrigin())); - origin << *O.components_, 1.0; + taxonomy::point3::ptr O = taxonomy::cast(map(inst->LocalOrigin())); + origin << *O->components_, 1.0; if (inst->Axis1()) { - taxonomy::direction3 ax1 = as(map(inst->Axis1())); - axis1 << *ax1.components_, 0.0; + taxonomy::direction3::ptr ax1 = taxonomy::cast(map(inst->Axis1())); + axis1 << *ax1->components_, 0.0; } if (inst->Axis2()) { - taxonomy::direction3 ax2 = as(map(inst->Axis2())); - axis2 << *ax2.components_, 0.0; + taxonomy::direction3::ptr ax2 = taxonomy::cast(map(inst->Axis2())); + axis2 << *ax2->components_, 0.0; } if (inst->Axis3()) { - taxonomy::direction3 ax3 = as(map(inst->Axis3())); - axis3 << *ax3.components_, 0.0; + taxonomy::direction3::ptr ax3 = taxonomy::cast(map(inst->Axis3())); + axis3 << *ax3->components_, 0.0; } - auto m4 = new taxonomy::matrix4(origin.head<3>(), axis3.head<3>(), axis1.head<3>()); + auto m4 = taxonomy::make(origin.head<3>(), axis3.head<3>(), axis1.head<3>()); if (m4->ccomponents().col(1).dot(axis2) < 0.) { m4->components().col(1) *= -1.; } diff --git a/src/ifcgeom/mapping/IfcCenterLineProfileDef.cpp b/src/ifcgeom/mapping/IfcCenterLineProfileDef.cpp index e749d6d05e..64409e4263 100644 --- a/src/ifcgeom/mapping/IfcCenterLineProfileDef.cpp +++ b/src/ifcgeom/mapping/IfcCenterLineProfileDef.cpp @@ -21,16 +21,21 @@ #define mapping POSTFIX_SCHEMA(mapping) using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcCenterLineProfileDef* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCenterLineProfileDef* inst) { + return nullptr; + + /* const double d = inst->Thickness() * length_unit_ / 2.; - auto f = new taxonomy::face; - auto ofc = new taxonomy::offset_curve; + auto f = taxonomy::make(); + auto ofc = taxonomy::make(); ofc->basis = map(inst->Curve()); ofc->offset = d; - f->children.push_back(ofc); + // @todo + // f->children.push_back(ofc); return f; + */ - // @todo we still need to handle this in the l + // @todo we still need to handle this in the geometry libraries /* TopoDS_Wire wire; diff --git a/src/ifcgeom/mapping/IfcCircle.cpp b/src/ifcgeom/mapping/IfcCircle.cpp index 4637aee3d4..fe470c8062 100644 --- a/src/ifcgeom/mapping/IfcCircle.cpp +++ b/src/ifcgeom/mapping/IfcCircle.cpp @@ -23,7 +23,7 @@ using namespace ifcopenshell::geometry; #define ALMOST_ZERO 1.e-7; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcCircle* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCircle* inst) { const double r = inst->Radius() * length_unit_; if (r < conv_settings_.getValue(ConversionSettings::GV_PRECISION)) { Logger::Message(Logger::LOG_ERROR, "Radius not greater than zero for:", inst); @@ -31,8 +31,8 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcCircle* inst) { } IfcSchema::IfcAxis2Placement* placement = inst->Position(); - auto c = new taxonomy::circle; + auto c = taxonomy::make(); c->radius = r; - c->matrix = as(map(placement)); + c->matrix = taxonomy::cast(map(placement)); return c; } diff --git a/src/ifcgeom/mapping/IfcCircleProfileDef.cpp b/src/ifcgeom/mapping/IfcCircleProfileDef.cpp index 826e5220ef..983aa7f0ea 100644 --- a/src/ifcgeom/mapping/IfcCircleProfileDef.cpp +++ b/src/ifcgeom/mapping/IfcCircleProfileDef.cpp @@ -23,7 +23,7 @@ using namespace ifcopenshell::geometry; #include -taxonomy::item* mapping::map_impl(const IfcSchema::IfcCircleProfileDef* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCircleProfileDef* inst) { std::vector radii = { inst->Radius() * length_unit_ }; if (inst->as()) { @@ -31,13 +31,13 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcCircleProfileDef* inst) { radii.push_back(radii.front() - t); } - auto f = new taxonomy::face; + auto f = taxonomy::make(); for (auto it = radii.begin(); it != radii.end(); ++it) { const double r = *it; const bool exterior = it == radii.begin(); - auto c = new taxonomy::circle; + auto c = taxonomy::make(); c->radius = r; bool has_position = true; @@ -45,18 +45,15 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcCircleProfileDef* inst) { has_position = !!inst->Position(); #endif if (has_position) { - taxonomy::matrix4 m = as(map(inst->Position())); - if (m.components_) { - c->matrix = *m.components_; - } + c->matrix = taxonomy::cast(map(inst->Position())); } - auto e = new taxonomy::edge; + auto e = taxonomy::make(); e->basis = c; e->start = 0.; e->end = 2 * boost::math::constants::pi(); - auto l = new taxonomy::loop; + auto l = taxonomy::make(); l->children = { e }; l->external = exterior; diff --git a/src/ifcgeom/mapping/IfcCompositeCurve.cpp b/src/ifcgeom/mapping/IfcCompositeCurve.cpp index d342305ffb..db61d37b86 100644 --- a/src/ifcgeom/mapping/IfcCompositeCurve.cpp +++ b/src/ifcgeom/mapping/IfcCompositeCurve.cpp @@ -21,8 +21,8 @@ #define mapping POSTFIX_SCHEMA(mapping) using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcCompositeCurve* inst) { - auto loop = new taxonomy::loop; +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCompositeCurve* inst) { + auto loop = taxonomy::make(); #ifdef SCHEMA_HAS_IfcSegment // 4x3 @@ -49,7 +49,7 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcCompositeCurve* inst) { Logger::Warning("Segment length below tolerance", segment); } - auto e = new taxonomy::edge; + auto e = taxonomy::make(); e->basis = map(curve); e->start = u0; e->end = u1; @@ -60,14 +60,14 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcCompositeCurve* inst) { auto crv = map(segment->ParentCurve()); if (crv) { if (crv->kind() == taxonomy::EDGE) { - ((taxonomy::edge*)crv)->orientation_2.reset(segment->SameSense()); - loop->children.push_back(crv); + auto ecrv = taxonomy::cast(crv); + ecrv->orientation_2.reset(segment->SameSense()); + loop->children.push_back(ecrv); } else if (crv->kind() == taxonomy::LOOP) { if (!segment->SameSense()) { crv->reverse(); } - auto curve_segments = ((taxonomy::loop*)crv)->children_as(); - for (auto& s : curve_segments) { + for (auto& s : taxonomy::cast(crv)->children) { loop->children.push_back(s); } // @todo delete crv without children @@ -95,7 +95,7 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcCompositeCurve* inst) { #define _USE_MATH_DEFINES #define mapping POSTFIX_SCHEMA(mapping) -taxonomy::item* mapping::map_impl(const IfcSchema::IfcCompositeCurve* l, TopoDS_Wire& wire) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCompositeCurve* l, TopoDS_Wire& wire) { TopTools_ListOfShape converted_segments; diff --git a/src/ifcgeom/mapping/IfcCompositeProfileDef.cpp b/src/ifcgeom/mapping/IfcCompositeProfileDef.cpp index 257ca9debf..d1bad7fd8f 100644 --- a/src/ifcgeom/mapping/IfcCompositeProfileDef.cpp +++ b/src/ifcgeom/mapping/IfcCompositeProfileDef.cpp @@ -21,7 +21,7 @@ #define mapping POSTFIX_SCHEMA(mapping) using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcCompositeProfileDef* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCompositeProfileDef* inst) { // @todo double check that this is actually supported IfcSchema::IfcProfileDef::list::ptr profiles = inst->Profiles(); return map_to_collection<>(this, profiles); diff --git a/src/ifcgeom/mapping/IfcConnectedFaceSet.cpp b/src/ifcgeom/mapping/IfcConnectedFaceSet.cpp index a2e7f78640..04904e4be4 100644 --- a/src/ifcgeom/mapping/IfcConnectedFaceSet.cpp +++ b/src/ifcgeom/mapping/IfcConnectedFaceSet.cpp @@ -21,9 +21,9 @@ #define mapping POSTFIX_SCHEMA(mapping) using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcConnectedFaceSet* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcConnectedFaceSet* inst) { auto shell = map_to_collection(this, inst->CfsFaces()); - if (shell == nullptr) { + if (!shell) { return nullptr; } shell->closed = inst->declaration().is(IfcSchema::IfcClosedShell::Class()); diff --git a/src/ifcgeom/mapping/IfcCraneRailAShapeProfileDef.cpp b/src/ifcgeom/mapping/IfcCraneRailAShapeProfileDef.cpp index dc544aa923..491c61f1e3 100644 --- a/src/ifcgeom/mapping/IfcCraneRailAShapeProfileDef.cpp +++ b/src/ifcgeom/mapping/IfcCraneRailAShapeProfileDef.cpp @@ -25,7 +25,7 @@ using namespace ifcopenshell::geometry; #ifdef SCHEMA_HAS_IfcCraneRailAShapeProfileDef -taxonomy::item* mapping::map_impl(const IfcSchema::IfcCraneRailAShapeProfileDef* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCraneRailAShapeProfileDef* inst) { double oh = inst->OverallHeight() * length_unit_; double bw2 = inst->BaseWidth2() * length_unit_; double hw = inst->HeadWidth() * length_unit_; @@ -37,13 +37,13 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcCraneRailAShapeProfileDef* double bd2 = inst->BaseDepth2() * length_unit_; double bd3 = inst->BaseDepth3() * length_unit_; - taxonomy::matrix4 m4; + taxonomy::matrix4::ptr m4; bool has_position = true; #ifdef SCHEMA_IfcParameterizedProfileDef_Position_IS_OPTIONAL has_position = !!inst->Position(); #endif if (has_position) { - m4 = as(map(inst->Position())); + m4 = taxonomy::cast(map(inst->Position())); } return profile_helper(m4, { diff --git a/src/ifcgeom/mapping/IfcCsgSolid.cpp b/src/ifcgeom/mapping/IfcCsgSolid.cpp index 6394c7dd34..8e2b8d4860 100644 --- a/src/ifcgeom/mapping/IfcCsgSolid.cpp +++ b/src/ifcgeom/mapping/IfcCsgSolid.cpp @@ -21,6 +21,6 @@ #define mapping POSTFIX_SCHEMA(mapping) using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcCsgSolid* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCsgSolid* inst) { return map(inst->TreeRootExpression()); } diff --git a/src/ifcgeom/mapping/IfcCurveBoundedPlane.cpp b/src/ifcgeom/mapping/IfcCurveBoundedPlane.cpp index 99e85364a7..55e47855fd 100644 --- a/src/ifcgeom/mapping/IfcCurveBoundedPlane.cpp +++ b/src/ifcgeom/mapping/IfcCurveBoundedPlane.cpp @@ -21,17 +21,17 @@ #define mapping POSTFIX_SCHEMA(mapping) using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcCurveBoundedPlane* inst) { - taxonomy::plane pl = as(map(inst->BasisSurface())); - auto f = new taxonomy::face; - f->children.push_back(map(inst->OuterBoundary())); +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCurveBoundedPlane* inst) { + taxonomy::plane::ptr pl = taxonomy::cast(map(inst->BasisSurface())); + auto f = taxonomy::make(); + f->children.push_back(taxonomy::cast(map(inst->OuterBoundary()))); IfcSchema::IfcCurve::list::ptr boundaries = inst->InnerBoundaries(); for (IfcSchema::IfcCurve::list::it it = boundaries->begin(); it != boundaries->end(); ++it) { - f->children.push_back(map(*it)); + f->children.push_back(taxonomy::cast(map(*it))); } - f->matrix = pl.matrix; + f->matrix = pl->matrix; return f; } diff --git a/src/ifcgeom/mapping/IfcCylindricalSurface.cpp b/src/ifcgeom/mapping/IfcCylindricalSurface.cpp index 5e222d4ce5..a60def0163 100644 --- a/src/ifcgeom/mapping/IfcCylindricalSurface.cpp +++ b/src/ifcgeom/mapping/IfcCylindricalSurface.cpp @@ -23,10 +23,10 @@ using namespace ifcopenshell::geometry; #ifdef SCHEMA_HAS_IfcCylindricalSurface -taxonomy::item* mapping::map_impl(const IfcSchema::IfcCylindricalSurface* inst) { - auto c = new taxonomy::cylinder; +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCylindricalSurface* inst) { + auto c = taxonomy::make(); c->radius = inst->Radius() * length_unit_; - c->matrix = as(map(inst->Position())); + c->matrix = taxonomy::cast(map(inst->Position())); return c; } diff --git a/src/ifcgeom/mapping/IfcDerivedProfileDef.cpp b/src/ifcgeom/mapping/IfcDerivedProfileDef.cpp index 3562e67f44..18953c8d90 100644 --- a/src/ifcgeom/mapping/IfcDerivedProfileDef.cpp +++ b/src/ifcgeom/mapping/IfcDerivedProfileDef.cpp @@ -21,9 +21,9 @@ #define mapping POSTFIX_SCHEMA(mapping) using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcDerivedProfileDef* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcDerivedProfileDef* inst) { auto it = map(inst->ParentProfile()); - taxonomy::matrix4 m = as(map(inst->Operator())); - ((taxonomy::geom_item*)it)->matrix.components() *= m.ccomponents(); + taxonomy::matrix4::ptr m = taxonomy::cast(map(inst->Operator())); + taxonomy::cast(it)->matrix->components() *= m->ccomponents(); return it; } diff --git a/src/ifcgeom/mapping/IfcDirection.cpp b/src/ifcgeom/mapping/IfcDirection.cpp index b86fb59f5e..2058307018 100644 --- a/src/ifcgeom/mapping/IfcDirection.cpp +++ b/src/ifcgeom/mapping/IfcDirection.cpp @@ -21,9 +21,9 @@ #define mapping POSTFIX_SCHEMA(mapping) using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcDirection* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcDirection* inst) { auto coords = inst->DirectionRatios(); - return new taxonomy::direction3( + return taxonomy::make( coords.size() >= 1 ? coords[0] : 0., coords.size() >= 2 ? coords[1] : 0., coords.size() >= 3 ? coords[2] : 0. diff --git a/src/ifcgeom/mapping/IfcEdge.cpp b/src/ifcgeom/mapping/IfcEdge.cpp index af55e6616f..cffc491839 100644 --- a/src/ifcgeom/mapping/IfcEdge.cpp +++ b/src/ifcgeom/mapping/IfcEdge.cpp @@ -21,7 +21,7 @@ #define mapping POSTFIX_SCHEMA(mapping) using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcEdge* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcEdge* inst) { if (!inst->EdgeStart()->declaration().is(IfcSchema::IfcVertexPoint::Class()) || !inst->EdgeEnd()->declaration().is(IfcSchema::IfcVertexPoint::Class())) { Logger::Message(Logger::LOG_ERROR, "Only IfcVertexPoints are supported for EdgeStart and -End", inst); return nullptr; @@ -34,10 +34,10 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcEdge* inst) { return nullptr; } - auto e = new taxonomy::edge; + auto e = taxonomy::make(); - e->start = as(map(pnt1)); - e->end = as(map(pnt2)); + e->start = taxonomy::cast(map(pnt1)); + e->end = taxonomy::cast(map(pnt2)); if (inst->as()) { e->basis = map(inst->as()->EdgeGeometry()); diff --git a/src/ifcgeom/mapping/IfcEdgeLoop.cpp b/src/ifcgeom/mapping/IfcEdgeLoop.cpp index 77cfaf3e4e..f4c77ab4a4 100644 --- a/src/ifcgeom/mapping/IfcEdgeLoop.cpp +++ b/src/ifcgeom/mapping/IfcEdgeLoop.cpp @@ -21,6 +21,6 @@ #define mapping POSTFIX_SCHEMA(mapping) using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcEdgeLoop* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcEdgeLoop* inst) { return map_to_collection(this, inst->EdgeList()); } diff --git a/src/ifcgeom/mapping/IfcEllipse.cpp b/src/ifcgeom/mapping/IfcEllipse.cpp index 664309e157..c6e6fe5955 100644 --- a/src/ifcgeom/mapping/IfcEllipse.cpp +++ b/src/ifcgeom/mapping/IfcEllipse.cpp @@ -21,7 +21,7 @@ #define mapping POSTFIX_SCHEMA(mapping) using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcEllipse* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcEllipse* inst) { double x = inst->SemiAxis1() * length_unit_; double y = inst->SemiAxis2() * length_unit_; const double tol = conv_settings_.getValue(ConversionSettings::GV_PRECISION); @@ -30,19 +30,21 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcEllipse* inst) { return nullptr; } - auto el = new taxonomy::ellipse; - el->matrix = as(map(inst->Position())); + auto el = taxonomy::make(); + el->matrix = taxonomy::cast(map(inst->Position())); // Open Cascade does not allow ellipses of which the minor radius // is greater than the major radius. Hence, in this case, the // ellipse is rotated. Note that special care is taken // when creating a trimmed curve off of an ellipse like this. if (y > x) { - el->matrix.components() << - -el->matrix.ccomponents().col(1), - el->matrix.ccomponents().col(0), - el->matrix.ccomponents().col(2), - el->matrix.ccomponents().col(3); + // @todo is a copy necesary here or can this be done in place? + auto m4_copy = *el->matrix; + el->matrix->components() << + -m4_copy.components().col(1), + m4_copy.components().col(0), + m4_copy.components().col(2), + m4_copy.components().col(3); std::swap(x, y); } diff --git a/src/ifcgeom/mapping/IfcEllipseProfileDef.cpp b/src/ifcgeom/mapping/IfcEllipseProfileDef.cpp index 5e853e5f7c..925ca5b508 100644 --- a/src/ifcgeom/mapping/IfcEllipseProfileDef.cpp +++ b/src/ifcgeom/mapping/IfcEllipseProfileDef.cpp @@ -21,7 +21,7 @@ #define mapping POSTFIX_SCHEMA(mapping) using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcEllipseProfileDef* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcEllipseProfileDef* inst) { double rx = inst->SemiAxis1() * length_unit_; double ry = inst->SemiAxis2() * length_unit_; const double tol = conv_settings_.getValue(ConversionSettings::GV_PRECISION); @@ -32,19 +32,19 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcEllipseProfileDef* inst) { const bool rotated = ry > rx; - taxonomy::matrix4 m4; + taxonomy::matrix4::ptr m4; bool has_position = true; #ifdef SCHEMA_IfcParameterizedProfileDef_Position_IS_OPTIONAL has_position = !!inst->Position(); #endif if (has_position) { - m4 = as(map(inst->Position())); + m4 = taxonomy::cast(map(inst->Position())); } if (ry > rx) { // @todo is a copy necesary here or can this be done in place? - auto m4_copy = m4; - m4.components() << + auto m4_copy = *m4; + m4->components() << -m4_copy.components().col(1), m4_copy.components().col(0), m4_copy.components().col(2), @@ -52,10 +52,10 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcEllipseProfileDef* inst) { std::swap(rx, ry); } - auto fc = new taxonomy::face; - auto lp = new taxonomy::loop; - auto ed = new taxonomy::edge; - auto el = new taxonomy::ellipse; + auto fc = taxonomy::make(); + auto lp = taxonomy::make(); + auto ed = taxonomy::make(); + auto el = taxonomy::make(); el->radius = rx; el->radius2 = ry; ed->basis = el; diff --git a/src/ifcgeom/mapping/IfcExtrudedAreaSolid.cpp b/src/ifcgeom/mapping/IfcExtrudedAreaSolid.cpp index 931ade758c..4c27fbd3ee 100644 --- a/src/ifcgeom/mapping/IfcExtrudedAreaSolid.cpp +++ b/src/ifcgeom/mapping/IfcExtrudedAreaSolid.cpp @@ -24,7 +24,7 @@ #define mapping POSTFIX_SCHEMA(mapping) using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcExtrudedAreaSolid* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcExtrudedAreaSolid* inst) { const double height = inst->Depth() * length_unit_; if (height < conv_settings_.getValue(ConversionSettings::GV_PRECISION)) { Logger::Message(Logger::LOG_ERROR, "Non-positive extrusion height encountered for:", inst); @@ -33,13 +33,13 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcExtrudedAreaSolid* inst) { #endif } - taxonomy::matrix4 matrix; + taxonomy::matrix4::ptr matrix; bool has_position = true; #ifdef SCHEMA_IfcSweptAreaSolid_Position_IS_OPTIONAL has_position = inst->Position() != nullptr; #endif if (has_position) { - matrix = as(map(inst->Position())); + matrix = taxonomy::cast(map(inst->Position())); } #ifdef PERMISSIVE_EXTRUSION @@ -49,10 +49,10 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcExtrudedAreaSolid* inst) { } #endif - return new taxonomy::extrusion( + return taxonomy::make( matrix, - as(map(inst->SweptArea())), - as(map(inst->ExtrudedDirection())), + taxonomy::cast(map(inst->SweptArea())), + taxonomy::cast(map(inst->ExtrudedDirection())), height ); } diff --git a/src/ifcgeom/mapping/IfcExtrudedAreaSolidTapered.cpp b/src/ifcgeom/mapping/IfcExtrudedAreaSolidTapered.cpp index 0737602fb4..47209846d2 100644 --- a/src/ifcgeom/mapping/IfcExtrudedAreaSolidTapered.cpp +++ b/src/ifcgeom/mapping/IfcExtrudedAreaSolidTapered.cpp @@ -24,25 +24,25 @@ using namespace ifcopenshell::geometry; #ifdef SCHEMA_HAS_IfcExtrudedAreaSolidTapered #define mapping POSTFIX_SCHEMA(mapping) -taxonomy::item* mapping::map_impl(const IfcSchema::IfcExtrudedAreaSolidTapered* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcExtrudedAreaSolidTapered* inst) { const double height = inst->Depth() * length_unit_; if (height < conv_settings_.getValue(ConversionSettings::GV_PRECISION)) { Logger::Message(Logger::LOG_ERROR, "Non-positive extrusion height encountered for:", inst); return nullptr; } - taxonomy::direction3 dir = as(map(inst->ExtrudedDirection())); - Eigen::Affine3d af3d(Eigen::Translation3d(height * dir.ccomponents())); + taxonomy::direction3::ptr dir = taxonomy::cast(map(inst->ExtrudedDirection())); + Eigen::Affine3d af3d(Eigen::Translation3d(height * dir->ccomponents())); Eigen::Matrix4d end_profile = af3d.matrix(); - auto loft = new taxonomy::loft; + auto loft = taxonomy::make(); loft->children = { - map(inst->SweptArea()), - map(inst->EndSweptArea()) + taxonomy::cast(map(inst->SweptArea())), + taxonomy::cast(map(inst->EndSweptArea())) }; - auto old = ((taxonomy::geom_item*)loft->children.back())->matrix.ccomponents(); - ((taxonomy::geom_item*)loft->children.back())->matrix.components() = old * end_profile; + auto old = loft->children.back()->matrix->ccomponents(); + loft->children.back()->matrix->components() = old * end_profile; return loft; diff --git a/src/ifcgeom/mapping/IfcFace.cpp b/src/ifcgeom/mapping/IfcFace.cpp index 8bc3366b06..3ee01c26b3 100644 --- a/src/ifcgeom/mapping/IfcFace.cpp +++ b/src/ifcgeom/mapping/IfcFace.cpp @@ -21,16 +21,16 @@ #define mapping POSTFIX_SCHEMA(mapping) using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcFace* inst) { - taxonomy::face* face = new taxonomy::face; +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcFace* inst) { + auto face = taxonomy::make(); auto bounds = inst->Bounds(); for (auto& bound : *bounds) { - if (auto r = map(bound->Bound())) { + if (auto r = taxonomy::cast(map(bound->Bound()))) { if (!bound->Orientation()) { r->reverse(); } if (bound->declaration().is(IfcSchema::IfcFaceOuterBound::Class())) { - ((taxonomy::loop*)r)->external = true; + r->external = true; /* // Make a copy in case we need immutability later for e.g. caching auto s = r->clone(); @@ -43,7 +43,9 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcFace* inst) { } } if (face->children.empty()) { +#ifdef TAXONOMY_USE_NAKED_PTR delete face; +#endif return nullptr; } return face; @@ -76,7 +78,7 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcFace* inst) { #define mapping POSTFIX_SCHEMA(mapping) -taxonomy::item* mapping::map_impl(const IfcSchema::IfcFace* l, TopoDS_Shape& result) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcFace* l, TopoDS_Shape& result) { IfcSchema::IfcFaceBound::list::ptr bounds = inst->Bounds(); util::face_definition fd; diff --git a/src/ifcgeom/mapping/IfcFaceBasedSurfaceModel.cpp b/src/ifcgeom/mapping/IfcFaceBasedSurfaceModel.cpp index f50361a0bb..eb64ff5e90 100644 --- a/src/ifcgeom/mapping/IfcFaceBasedSurfaceModel.cpp +++ b/src/ifcgeom/mapping/IfcFaceBasedSurfaceModel.cpp @@ -21,7 +21,7 @@ #define mapping POSTFIX_SCHEMA(mapping) using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcFaceBasedSurfaceModel* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcFaceBasedSurfaceModel* inst) { // @todo check styles? return map_to_collection(this, inst->FbsmFaces()); } diff --git a/src/ifcgeom/mapping/IfcGeometricSet.cpp b/src/ifcgeom/mapping/IfcGeometricSet.cpp index 9364c81bcf..2865c6a3e0 100644 --- a/src/ifcgeom/mapping/IfcGeometricSet.cpp +++ b/src/ifcgeom/mapping/IfcGeometricSet.cpp @@ -21,6 +21,6 @@ #define mapping POSTFIX_SCHEMA(mapping) using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcGeometricSet* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcGeometricSet* inst) { return map_to_collection(this, inst->Elements()); } diff --git a/src/ifcgeom/mapping/IfcHalfSpaceSolid.cpp b/src/ifcgeom/mapping/IfcHalfSpaceSolid.cpp index d68bd32100..cb407c4508 100644 --- a/src/ifcgeom/mapping/IfcHalfSpaceSolid.cpp +++ b/src/ifcgeom/mapping/IfcHalfSpaceSolid.cpp @@ -21,18 +21,20 @@ #define mapping POSTFIX_SCHEMA(mapping) using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcHalfSpaceSolid* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcHalfSpaceSolid* inst) { IfcSchema::IfcSurface* surface = inst->BaseSurface(); if (!surface->declaration().is(IfcSchema::IfcPlane::Class())) { Logger::Message(Logger::LOG_ERROR, "Unsupported BaseSurface:", surface); return nullptr; } - auto p = new taxonomy::plane; - p->matrix = as(map(((IfcSchema::IfcPlane*)surface)->Position())); - auto f = new taxonomy::face; + auto p = taxonomy::make(); + p->matrix = taxonomy::cast(map(((IfcSchema::IfcPlane*)surface)->Position())); + auto f = taxonomy::make(); f->orientation.reset(!inst->AgreementFlag()); f->basis = p; - auto s = new taxonomy::solid; - s->children.push_back(f); - return s; + auto sh = taxonomy::make(); + sh->children.push_back(f); + auto so = taxonomy::make(); + so->children.push_back(sh); + return so; } diff --git a/src/ifcgeom/mapping/IfcIShapeProfileDef.cpp b/src/ifcgeom/mapping/IfcIShapeProfileDef.cpp index 40ebd4442b..1e3be1b571 100644 --- a/src/ifcgeom/mapping/IfcIShapeProfileDef.cpp +++ b/src/ifcgeom/mapping/IfcIShapeProfileDef.cpp @@ -23,7 +23,7 @@ using namespace ifcopenshell::geometry; #include "../profile_helper.h" -taxonomy::item* mapping::map_impl(const IfcSchema::IfcIShapeProfileDef* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcIShapeProfileDef* inst) { const bool doFillet1 = !!inst->FilletRadius(); #ifdef SCHEMA_IfcIShapeProfileDef_HAS_FlangeEdgeRadius const bool doFlangeEdgeRadius = !!inst->FlangeEdgeRadius(); @@ -85,13 +85,13 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcIShapeProfileDef* inst) { return nullptr; } - taxonomy::matrix4 m4; + taxonomy::matrix4::ptr m4; bool has_position = true; #ifdef SCHEMA_IfcParameterizedProfileDef_Position_IS_OPTIONAL has_position = !!inst->Position(); #endif if (has_position) { - m4 = as(map(inst->Position())); + m4 = taxonomy::cast(map(inst->Position())); } return profile_helper(m4, { diff --git a/src/ifcgeom/mapping/IfcIndexedPolyCurve.cpp b/src/ifcgeom/mapping/IfcIndexedPolyCurve.cpp index e9b155c819..c0ceac76d8 100644 --- a/src/ifcgeom/mapping/IfcIndexedPolyCurve.cpp +++ b/src/ifcgeom/mapping/IfcIndexedPolyCurve.cpp @@ -23,7 +23,7 @@ using namespace ifcopenshell::geometry; #ifdef SCHEMA_HAS_IfcIndexedPolyCurve -taxonomy::item* mapping::map_impl(const IfcSchema::IfcIndexedPolyCurve* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcIndexedPolyCurve* inst) { IfcSchema::IfcCartesianPointList* point_list = inst->Points(); std::vector< std::vector > coordinates; @@ -33,10 +33,10 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcIndexedPolyCurve* inst) { coordinates = point_list->as()->CoordList(); } - std::vector points; + std::vector points; points.reserve(coordinates.size()); for (auto& coords : coordinates) { - points.push_back(taxonomy::point3( + points.push_back(taxonomy::make( coords.size() < 1 ? 0. : coords[0] * length_unit_, coords.size() < 2 ? 0. : coords[1] * length_unit_, coords.size() < 3 ? 0. : coords[2] * length_unit_)); @@ -44,7 +44,7 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcIndexedPolyCurve* inst) { int max_index = (int) points.size(); - auto loop = new taxonomy::loop; + auto loop = taxonomy::make(); if(inst->Segments()) { aggregate_of_instance::ptr segments = *inst->Segments(); @@ -53,14 +53,14 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcIndexedPolyCurve* inst) { if (segment->declaration().is(IfcSchema::IfcLineIndex::Class())) { IfcSchema::IfcLineIndex* line = (IfcSchema::IfcLineIndex*) segment; std::vector indices = *line; - taxonomy::point3 previous; + taxonomy::point3::ptr previous; for (std::vector::const_iterator jt = indices.begin(); jt != indices.end(); ++jt) { if (*jt < 1 || *jt > max_index) { throw IfcParse::IfcException("IfcIndexedPolyCurve index out of bounds for index " + boost::lexical_cast(*jt)); } - const taxonomy::point3& current = points[*jt - 1]; + auto current = points[*jt - 1]; if (jt != indices.begin()) { - loop->children.push_back(new taxonomy::edge(previous, current)); + loop->children.push_back(taxonomy::make(previous, current)); } previous = current; } @@ -80,9 +80,9 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcIndexedPolyCurve* inst) { const auto& b = points[indices[1] - 1]; const auto& c = points[indices[2] - 1]; - auto circ = taxonomy::circle::from_3_points(a.ccomponents(), b.ccomponents(), c.ccomponents()); + auto circ = taxonomy::circle::from_3_points(a->ccomponents(), b->ccomponents(), c->ccomponents()); if (circ) { - auto e = new taxonomy::edge(a, c); + auto e = taxonomy::make(a, c); e->basis = circ; loop->children.push_back(e); } else { @@ -95,7 +95,7 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcIndexedPolyCurve* inst) { } else if (points.begin() < points.end()) { auto previous = points.begin(); for (auto current = previous+1; current < points.end(); ++current){ - loop->children.push_back(new taxonomy::edge(*previous, *current)); + loop->children.push_back(taxonomy::make(*previous, *current)); previous = current; } } diff --git a/src/ifcgeom/mapping/IfcLShapeProfileDef.cpp b/src/ifcgeom/mapping/IfcLShapeProfileDef.cpp index 6a74da17e1..047af31d8b 100644 --- a/src/ifcgeom/mapping/IfcLShapeProfileDef.cpp +++ b/src/ifcgeom/mapping/IfcLShapeProfileDef.cpp @@ -23,7 +23,7 @@ using namespace ifcopenshell::geometry; #include "../profile_helper.h" -taxonomy::item* mapping::map_impl(const IfcSchema::IfcLShapeProfileDef* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcLShapeProfileDef* inst) { const bool hasSlope = !!inst->LegSlope(); const bool doEdgeFillet = !!inst->EdgeRadius(); const bool doFillet = !!inst->FilletRadius(); @@ -85,13 +85,13 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcLShapeProfileDef* inst) { xy = (a1*c2 - a2*c1) / det; } - taxonomy::matrix4 m4; + taxonomy::matrix4::ptr m4; bool has_position = true; #ifdef SCHEMA_IfcParameterizedProfileDef_Position_IS_OPTIONAL has_position = !!inst->Position(); #endif if (has_position) { - m4 = as(map(inst->Position())); + m4 = taxonomy::cast(map(inst->Position())); } return profile_helper(m4, { diff --git a/src/ifcgeom/mapping/IfcLine.cpp b/src/ifcgeom/mapping/IfcLine.cpp index 5cf7e64b00..5f0e556a1d 100644 --- a/src/ifcgeom/mapping/IfcLine.cpp +++ b/src/ifcgeom/mapping/IfcLine.cpp @@ -21,11 +21,11 @@ #define mapping POSTFIX_SCHEMA(mapping) using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcLine* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcLine* inst) { // @todo test with trimmed curve on non-normalized direction - auto l = new taxonomy::line; - taxonomy::point3 pnt = as(map(inst->Pnt())); - taxonomy::direction3 dir = as(map(inst->Dir())); - l->matrix = taxonomy::matrix4(pnt.ccomponents(), dir.ccomponents()); + auto l = taxonomy::make(); + auto pnt = taxonomy::cast(map(inst->Pnt())); + auto dir = taxonomy::cast(map(inst->Dir())); + l->matrix = taxonomy::make(pnt->ccomponents(), dir->ccomponents()); return l; } diff --git a/src/ifcgeom/mapping/IfcLocalPlacement.cpp b/src/ifcgeom/mapping/IfcLocalPlacement.cpp index f2320d7d6d..ac275c8201 100644 --- a/src/ifcgeom/mapping/IfcLocalPlacement.cpp +++ b/src/ifcgeom/mapping/IfcLocalPlacement.cpp @@ -21,16 +21,15 @@ #define mapping POSTFIX_SCHEMA(mapping) using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcLocalPlacement* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcLocalPlacement* inst) { IfcSchema::IfcLocalPlacement* current = (IfcSchema::IfcLocalPlacement*)inst; - auto m4 = new taxonomy::matrix4; + auto m4 = taxonomy::make(); for (;;) { IfcSchema::IfcAxis2Placement* relplacement = current->RelativePlacement(); // @todo this type check is wrong and unnecessary? if (relplacement->as()) { - taxonomy::matrix4 trsf2 = as(map(relplacement)); // @todo check - m4->components() = trsf2.ccomponents() * m4->ccomponents(); + m4->components() = taxonomy::cast(map(relplacement))->ccomponents() * m4->ccomponents(); } if (current->PlacementRelTo()) { IfcSchema::IfcObjectPlacement* parent = current->PlacementRelTo(); diff --git a/src/ifcgeom/mapping/IfcManifoldSolidBrep.cpp b/src/ifcgeom/mapping/IfcManifoldSolidBrep.cpp index 70e4be50e1..4d6f23fd46 100644 --- a/src/ifcgeom/mapping/IfcManifoldSolidBrep.cpp +++ b/src/ifcgeom/mapping/IfcManifoldSolidBrep.cpp @@ -21,7 +21,7 @@ #define mapping POSTFIX_SCHEMA(mapping) using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcManifoldSolidBrep* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcManifoldSolidBrep* inst) { IfcSchema::IfcClosedShell::list::ptr voids(new IfcSchema::IfcClosedShell::list); if (inst->declaration().is(IfcSchema::IfcFacetedBrepWithVoids::Class())) { voids = inst->as()->Voids(); @@ -32,13 +32,13 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcManifoldSolidBrep* inst) { } #endif - taxonomy::solid* solid; + taxonomy::solid::ptr solid; if (voids->size()) { solid = map_to_collection(this, voids); } else { - solid = new taxonomy::solid; + solid = taxonomy::make(); } - solid->children.insert(solid->children.begin(), map(inst->Outer())); + solid->children.insert(solid->children.begin(), taxonomy::cast(map(inst->Outer()))); return solid; } diff --git a/src/ifcgeom/mapping/IfcMappedItem.cpp b/src/ifcgeom/mapping/IfcMappedItem.cpp index 5d6bf597dd..e13bf486f8 100644 --- a/src/ifcgeom/mapping/IfcMappedItem.cpp +++ b/src/ifcgeom/mapping/IfcMappedItem.cpp @@ -21,28 +21,27 @@ #define mapping POSTFIX_SCHEMA(mapping) using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcMappedItem* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcMappedItem* inst) { IfcSchema::IfcCartesianTransformationOperator* transform = inst->MappingTarget(); - auto qqq = (taxonomy::matrix4*)map(transform); - taxonomy::matrix4 gtrsf = *qqq; + taxonomy::matrix4::ptr gtrsf = taxonomy::cast(map(transform)); IfcSchema::IfcRepresentationMap* rmap = inst->MappingSource(); IfcSchema::IfcAxis2Placement* placement = rmap->MappingOrigin(); - taxonomy::matrix4 trsf2 = *(taxonomy::matrix4*)(map(placement)); - Eigen::Matrix4d res = gtrsf.ccomponents() * trsf2.ccomponents(); + taxonomy::matrix4::ptr trsf2 = taxonomy::cast(map(placement)); + Eigen::Matrix4d res = gtrsf->ccomponents() * trsf2->ccomponents(); // @todo immutable for caching? // @todo allow for multiple levels of matrix? - auto shapes = map(rmap->MappedRepresentation()); + auto shapes = taxonomy::cast(map(rmap->MappedRepresentation())); if (shapes == nullptr) { return shapes; } - auto collection = new taxonomy::collection; + auto collection = taxonomy::make(); collection->children.push_back(shapes); - collection->matrix = res; + collection->matrix = taxonomy::make(res); if (shapes != nullptr) { - for (auto& c : ((taxonomy::collection*)shapes)->children) { + for (auto& c : taxonomy::cast(shapes)->children) { // @todo previously style was also copied. } } diff --git a/src/ifcgeom/mapping/IfcOrientedEdge.cpp b/src/ifcgeom/mapping/IfcOrientedEdge.cpp index ddf5475d6e..81c8e1c09d 100644 --- a/src/ifcgeom/mapping/IfcOrientedEdge.cpp +++ b/src/ifcgeom/mapping/IfcOrientedEdge.cpp @@ -21,8 +21,8 @@ #define mapping POSTFIX_SCHEMA(mapping) using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcOrientedEdge* inst) { - auto e = map(inst->EdgeElement()); +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOrientedEdge* inst) { + auto e = taxonomy::cast(map(inst->EdgeElement())); if (!inst->Orientation()) { e->reverse(); } diff --git a/src/ifcgeom/mapping/IfcPlane.cpp b/src/ifcgeom/mapping/IfcPlane.cpp index 70c11ca132..cd2326bb31 100644 --- a/src/ifcgeom/mapping/IfcPlane.cpp +++ b/src/ifcgeom/mapping/IfcPlane.cpp @@ -21,8 +21,8 @@ #define mapping POSTFIX_SCHEMA(mapping) using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcPlane* inst) { - auto p = new taxonomy::plane; - p->matrix = as(map(inst->Position())); +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPlane* inst) { + auto p = taxonomy::make(); + p->matrix = taxonomy::cast(map(inst->Position())); return p; } diff --git a/src/ifcgeom/mapping/IfcPolyLoop.cpp b/src/ifcgeom/mapping/IfcPolyLoop.cpp index 45f0067b71..1e334d8f8f 100644 --- a/src/ifcgeom/mapping/IfcPolyLoop.cpp +++ b/src/ifcgeom/mapping/IfcPolyLoop.cpp @@ -23,14 +23,14 @@ using namespace ifcopenshell::geometry; #include "../profile_helper.h" -taxonomy::item* mapping::map_impl(const IfcSchema::IfcPolyLoop* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPolyLoop* inst) { IfcSchema::IfcCartesianPoint::list::ptr points = inst->Polygon(); // Parse and store the points in a sequence - std::vector polygon; + std::vector polygon; polygon.reserve(points->size()); std::transform(points->begin(), points->end(), std::back_inserter(polygon), [this](const IfcSchema::IfcCartesianPoint* p) { - return as(map(p)); + return taxonomy::cast(map(p)); }); // A loop should consist of at least three vertices diff --git a/src/ifcgeom/mapping/IfcPolygonalBoundedHalfSpace.cpp b/src/ifcgeom/mapping/IfcPolygonalBoundedHalfSpace.cpp index f9e13b4940..950d19c625 100644 --- a/src/ifcgeom/mapping/IfcPolygonalBoundedHalfSpace.cpp +++ b/src/ifcgeom/mapping/IfcPolygonalBoundedHalfSpace.cpp @@ -21,10 +21,10 @@ #define mapping POSTFIX_SCHEMA(mapping) using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcPolygonalBoundedHalfSpace* inst) { - auto s = (taxonomy::solid*)map_impl((IfcSchema::IfcHalfSpaceSolid*) inst); - auto f = (taxonomy::face*)s->children[0]; - f->children = { map(inst->PolygonalBoundary()) }; - f->matrix = as(map(inst->Position())); +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPolygonalBoundedHalfSpace* inst) { + auto s = taxonomy::cast(map_impl((IfcSchema::IfcHalfSpaceSolid*) inst)); + auto f = s->children[0]->children[0]; + f->children = { taxonomy::cast(map(inst->PolygonalBoundary())) }; + f->matrix = taxonomy::cast(map(inst->Position())); return s; } diff --git a/src/ifcgeom/mapping/IfcPolygonalFaceSet.cpp b/src/ifcgeom/mapping/IfcPolygonalFaceSet.cpp index fe0c90de18..c3f7ff7219 100644 --- a/src/ifcgeom/mapping/IfcPolygonalFaceSet.cpp +++ b/src/ifcgeom/mapping/IfcPolygonalFaceSet.cpp @@ -23,15 +23,15 @@ using namespace ifcopenshell::geometry; #ifdef SCHEMA_HAS_IfcPolygonalFaceSet -taxonomy::item* mapping::map_impl(const IfcSchema::IfcPolygonalFaceSet* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPolygonalFaceSet* inst) { IfcSchema::IfcCartesianPointList3D* point_list = inst->Coordinates(); auto coordinates = point_list->CoordList(); auto polygonal_faces = inst->Faces(); - std::vector points; + std::vector points; points.reserve(coordinates.size()); for (auto& coords : coordinates) { - points.push_back(taxonomy::point3( + points.push_back(taxonomy::make( coords.size() < 1 ? 0. : coords[0] * length_unit_, coords.size() < 2 ? 0. : coords[1] * length_unit_, coords.size() < 3 ? 0. : coords[2] * length_unit_)); @@ -39,57 +39,59 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcPolygonalFaceSet* inst) { int max_index = (int)points.size(); - auto shell = new taxonomy::shell; + auto shell = taxonomy::make(); for (auto& f : *polygonal_faces) { - auto fa = new taxonomy::face; + auto fa = taxonomy::make(); shell->children.push_back(fa); { - auto loop = new taxonomy::loop; + auto loop = taxonomy::make(); fa->children = { loop }; loop->external = true; auto indices = f->CoordIndex(); - taxonomy::point3 previous; + taxonomy::point3::ptr previous; for (std::vector::const_iterator jt = indices.begin(); jt != indices.end(); ++jt) { if (*jt < 1 || *jt > max_index) { throw IfcParse::IfcException("IfcPolygonalFaceSet index out of bounds for index " + boost::lexical_cast(*jt)); } - const taxonomy::point3& current = points[(*jt) - 1]; + auto current = points[(*jt) - 1]; if (jt != indices.begin()) { - loop->children.push_back(new taxonomy::edge(previous, current)); + loop->children.push_back(taxonomy::make(previous, current)); } previous = current; } if (!indices.empty()) { - const taxonomy::point3& current = points[indices.front() - 1]; - loop->children.push_back(new taxonomy::edge(previous, current)); + auto current = points[indices.front() - 1]; + loop->children.push_back(taxonomy::make(previous, current)); } } if (f->as()) { auto indices = f->as()->InnerCoordIndices(); - { - auto loop = new taxonomy::loop; - fa->children.push_back(loop); - loop->external = false; - auto indices = f->CoordIndex(); - taxonomy::point3 previous; - for (std::vector::const_iterator jt = indices.begin(); jt != indices.end(); ++jt) { - if (*jt < 1 || *jt > max_index) { - throw IfcParse::IfcException("IfcPolygonalFaceSet index out of bounds for index " + boost::lexical_cast(*jt)); + taxonomy::point3::ptr previous; + for (auto& li : indices) { + auto loop = taxonomy::make(); + fa->children.push_back(loop); + loop->external = false; + + for (std::vector::const_iterator jt = li.begin(); jt != li.end(); ++jt) { + if (*jt < 1 || *jt > max_index) { + throw IfcParse::IfcException("IfcPolygonalFaceSet index out of bounds for index " + boost::lexical_cast(*jt)); + } + auto current = points[(*jt) - 1]; + if (jt != li.begin()) { + loop->children.push_back(taxonomy::make(previous, current)); + } + previous = current; } - const taxonomy::point3& current = points[(*jt) - 1]; - if (jt != indices.begin()) { - loop->children.push_back(new taxonomy::edge(previous, current)); + if (!li.empty()) { + auto current = points[li.front() - 1]; + loop->children.push_back(taxonomy::make(previous, current)); } - previous = current; - } - if (!indices.empty()) { - const taxonomy::point3& current = points[indices.front() - 1]; - loop->children.push_back(new taxonomy::edge(previous, current)); } + } } } diff --git a/src/ifcgeom/mapping/IfcPolyline.cpp b/src/ifcgeom/mapping/IfcPolyline.cpp index 4b4eac8d53..8b166e1e31 100644 --- a/src/ifcgeom/mapping/IfcPolyline.cpp +++ b/src/ifcgeom/mapping/IfcPolyline.cpp @@ -23,17 +23,17 @@ using namespace ifcopenshell::geometry; #include "../profile_helper.h" -taxonomy::item* mapping::map_impl(const IfcSchema::IfcPolyline* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPolyline* inst) { IfcSchema::IfcCartesianPoint::list::ptr points = inst->Points(); // Parse and store the points in a sequence - std::vector polygon; + std::vector polygon; polygon.reserve(points->size()); std::transform(points->begin(), points->end(), std::back_inserter(polygon), [this](const IfcSchema::IfcCartesianPoint* p) { - return as(map(p)); + return taxonomy::cast(map(p)); }); - const bool closed_by_proximity = polygon.size() >= 3 && (*polygon.front().components_ - *polygon.back().components_).norm() < conv_settings_.getValue(ConversionSettings::GV_PRECISION); + const bool closed_by_proximity = polygon.size() >= 3 && (*polygon.front()->components_ - *polygon.back()->components_).norm() < conv_settings_.getValue(ConversionSettings::GV_PRECISION); if (closed_by_proximity) { polygon.resize(polygon.size() - 1); polygon.push_back(polygon.front()); diff --git a/src/ifcgeom/mapping/IfcProduct.cpp b/src/ifcgeom/mapping/IfcProduct.cpp index 934a3f99db..5c48dbfe6d 100644 --- a/src/ifcgeom/mapping/IfcProduct.cpp +++ b/src/ifcgeom/mapping/IfcProduct.cpp @@ -4,11 +4,11 @@ using namespace ifcopenshell::geometry; using namespace IfcGeom; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcProduct* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcProduct* inst) { // @todo decide on this, what happens in the product mapping? // currently things like openings, layers and materials are processed in the converter - auto c = new taxonomy::collection; - c->matrix = as(map(inst->ObjectPlacement())); + auto c = taxonomy::make(); + c->matrix = taxonomy::cast(map(inst->ObjectPlacement())); return c; /* @@ -30,7 +30,7 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcProduct* inst) { } auto c = new taxonomy::collection; - c->matrix = as(map(inst->ObjectPlacement())); + c->matrix = taxonomy::cast(map(inst->ObjectPlacement())); const auto single_material = get_single_material_association(inst); if (single_material) { @@ -53,8 +53,8 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcProduct* inst) { operands->push(body); operands->push(openings); auto n = map_to_collection(this, operands); - std::for_each(n->children.begin() + 1, n->children.end(), [&ci](taxonomy::item* i) { - ((taxonomy::geom_item*)i)->matrix.components() = ci * ((taxonomy::geom_item*)i)->matrix.ccomponents(); + std::for_each(n->children.begin() + 1, n->children.end(), [&ci](taxonomy::ptr i) { + ((taxonomy::geom_ptr)i)->matrix.components() = ci * ((taxonomy::geom_ptr)i)->matrix.ccomponents(); }); n->operation = taxonomy::boolean_result::SUBTRACTION; // @todo one indirection too many diff --git a/src/ifcgeom/mapping/IfcRectangleHollowProfileDef.cpp b/src/ifcgeom/mapping/IfcRectangleHollowProfileDef.cpp index f20b05bb8b..c5be1981d7 100644 --- a/src/ifcgeom/mapping/IfcRectangleHollowProfileDef.cpp +++ b/src/ifcgeom/mapping/IfcRectangleHollowProfileDef.cpp @@ -23,7 +23,7 @@ using namespace ifcopenshell::geometry; #include "../profile_helper.h" -taxonomy::item* mapping::map_impl(const IfcSchema::IfcRectangleHollowProfileDef* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRectangleHollowProfileDef* inst) { const double x = inst->XDim() / 2.0f * length_unit_; const double y = inst->YDim() / 2.0f * length_unit_; const double d = inst->WallThickness() * length_unit_; @@ -41,13 +41,13 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcRectangleHollowProfileDef* return nullptr; } - taxonomy::matrix4 m4; + taxonomy::matrix4::ptr m4; bool has_position = true; #ifdef SCHEMA_IfcParameterizedProfileDef_Position_IS_OPTIONAL has_position = !!inst->Position(); #endif if (has_position) { - m4 = as(map(inst->Position())); + m4 = taxonomy::cast(map(inst->Position())); } auto s1 = profile_helper(m4, { @@ -69,7 +69,10 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcRectangleHollowProfileDef* } s1->children.push_back(s2->children[0]); + +#ifdef TAXONOMY_USE_NAKED_PTR delete s2; +#endif return s1; } diff --git a/src/ifcgeom/mapping/IfcRectangleProfileDef.cpp b/src/ifcgeom/mapping/IfcRectangleProfileDef.cpp index e33c46e892..5418274879 100644 --- a/src/ifcgeom/mapping/IfcRectangleProfileDef.cpp +++ b/src/ifcgeom/mapping/IfcRectangleProfileDef.cpp @@ -23,7 +23,7 @@ using namespace ifcopenshell::geometry; #include "../profile_helper.h" -taxonomy::item* mapping::map_impl(const IfcSchema::IfcRectangleProfileDef* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRectangleProfileDef* inst) { const double x = inst->XDim() / 2.0f * length_unit_; const double y = inst->YDim() / 2.0f * length_unit_; @@ -34,13 +34,13 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcRectangleProfileDef* inst) return nullptr; } - taxonomy::matrix4 m4; + taxonomy::matrix4::ptr m4; bool has_position = true; #ifdef SCHEMA_IfcParameterizedProfileDef_Position_IS_OPTIONAL has_position = !!inst->Position(); #endif if (has_position) { - m4 = as(map(inst->Position())); + m4 = taxonomy::cast(map(inst->Position())); } return profile_helper(m4, { diff --git a/src/ifcgeom/mapping/IfcRectangularPyramid.cpp b/src/ifcgeom/mapping/IfcRectangularPyramid.cpp index 8d4167cab5..70ff3e9a9d 100644 --- a/src/ifcgeom/mapping/IfcRectangularPyramid.cpp +++ b/src/ifcgeom/mapping/IfcRectangularPyramid.cpp @@ -21,107 +21,107 @@ #define mapping POSTFIX_SCHEMA(mapping) using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcRectangularPyramid* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRectangularPyramid* inst) { const double dx = inst->XLength() * length_unit_; const double dy = inst->YLength() * length_unit_; const double dz = inst->Height() * length_unit_; - auto solid = new taxonomy::solid; - auto shell = new taxonomy::shell; + auto solid = taxonomy::make(); + auto shell = taxonomy::make(); solid->children.push_back(shell); // Base { - auto face = new taxonomy::face; - auto loop = new taxonomy::loop; + auto face = taxonomy::make(); + auto loop = taxonomy::make(); face->children.push_back(loop); loop->external = true; shell->children.push_back(face); - std::array points{ - taxonomy::point3(0, 0, 0), - taxonomy::point3(dx, 0, 0), - taxonomy::point3(dx, dy, 0), - taxonomy::point3(0, dy, 0) + std::array points{ + taxonomy::make(0, 0, 0), + taxonomy::make(dx, 0, 0), + taxonomy::make(dx, dy, 0), + taxonomy::make(0, dy, 0) }; - loop->children.push_back(new taxonomy::edge(points[0], points[1])); - loop->children.push_back(new taxonomy::edge(points[1], points[2])); - loop->children.push_back(new taxonomy::edge(points[2], points[3])); - loop->children.push_back(new taxonomy::edge(points[3], points[0])); + loop->children.push_back(taxonomy::make(points[0], points[1])); + loop->children.push_back(taxonomy::make(points[1], points[2])); + loop->children.push_back(taxonomy::make(points[2], points[3])); + loop->children.push_back(taxonomy::make(points[3], points[0])); } // Lateral faces { - auto face = new taxonomy::face; - auto loop = new taxonomy::loop; + auto face = taxonomy::make(); + auto loop = taxonomy::make(); face->children.push_back(loop); loop->external = true; shell->children.push_back(face); - std::array points{ - taxonomy::point3(0, 0, 0), - taxonomy::point3(0, dy, 0), - taxonomy::point3(0.5*dx, 0.5*dy, dz) + std::array points{ + taxonomy::make(0, 0, 0), + taxonomy::make(0, dy, 0), + taxonomy::make(0.5*dx, 0.5*dy, dz) }; - loop->children.push_back(new taxonomy::edge(points[0], points[1])); - loop->children.push_back(new taxonomy::edge(points[1], points[2])); - loop->children.push_back(new taxonomy::edge(points[2], points[0])); + loop->children.push_back(taxonomy::make(points[0], points[1])); + loop->children.push_back(taxonomy::make(points[1], points[2])); + loop->children.push_back(taxonomy::make(points[2], points[0])); } { - auto face = new taxonomy::face; - auto loop = new taxonomy::loop; + auto face = taxonomy::make(); + auto loop = taxonomy::make(); face->children.push_back(loop); loop->external = true; shell->children.push_back(face); - std::array points{ - taxonomy::point3(0, dy, 0), - taxonomy::point3(dx, dy, 0), - taxonomy::point3(0.5*dx, 0.5*dy, dz) + std::array points{ + taxonomy::make(0, dy, 0), + taxonomy::make(dx, dy, 0), + taxonomy::make(0.5*dx, 0.5*dy, dz) }; - loop->children.push_back(new taxonomy::edge(points[0], points[1])); - loop->children.push_back(new taxonomy::edge(points[1], points[2])); - loop->children.push_back(new taxonomy::edge(points[2], points[0])); + loop->children.push_back(taxonomy::make(points[0], points[1])); + loop->children.push_back(taxonomy::make(points[1], points[2])); + loop->children.push_back(taxonomy::make(points[2], points[0])); } { - auto face = new taxonomy::face; - auto loop = new taxonomy::loop; + auto face = taxonomy::make(); + auto loop = taxonomy::make(); face->children.push_back(loop); loop->external = true; shell->children.push_back(face); - std::array points{ - taxonomy::point3(dx, dy, 0), - taxonomy::point3(dx, 0, 0), - taxonomy::point3(0.5*dx, 0.5*dy, dz) + std::array points{ + taxonomy::make(dx, dy, 0), + taxonomy::make(dx, 0, 0), + taxonomy::make(0.5*dx, 0.5*dy, dz) }; - loop->children.push_back(new taxonomy::edge(points[0], points[1])); - loop->children.push_back(new taxonomy::edge(points[1], points[2])); - loop->children.push_back(new taxonomy::edge(points[2], points[0])); + loop->children.push_back(taxonomy::make(points[0], points[1])); + loop->children.push_back(taxonomy::make(points[1], points[2])); + loop->children.push_back(taxonomy::make(points[2], points[0])); } { - auto face = new taxonomy::face; - auto loop = new taxonomy::loop; + auto face = taxonomy::make(); + auto loop = taxonomy::make(); face->children.push_back(loop); loop->external = true; shell->children.push_back(face); - std::array points{ - taxonomy::point3(dx, 0, 0), - taxonomy::point3(0, 0, 0), - taxonomy::point3(0.5*dx, 0.5*dy, dz) + std::array points{ + taxonomy::make(dx, 0, 0), + taxonomy::make(0, 0, 0), + taxonomy::make(0.5*dx, 0.5*dy, dz) }; - loop->children.push_back(new taxonomy::edge(points[0], points[1])); - loop->children.push_back(new taxonomy::edge(points[1], points[2])); - loop->children.push_back(new taxonomy::edge(points[2], points[0])); + loop->children.push_back(taxonomy::make(points[0], points[1])); + loop->children.push_back(taxonomy::make(points[1], points[2])); + loop->children.push_back(taxonomy::make(points[2], points[0])); } return solid; diff --git a/src/ifcgeom/mapping/IfcRectangularTrimmedSurface.cpp b/src/ifcgeom/mapping/IfcRectangularTrimmedSurface.cpp index 5dbf3fd484..ae910c1354 100644 --- a/src/ifcgeom/mapping/IfcRectangularTrimmedSurface.cpp +++ b/src/ifcgeom/mapping/IfcRectangularTrimmedSurface.cpp @@ -21,7 +21,7 @@ #define mapping POSTFIX_SCHEMA(mapping) using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcRectangularTrimmedSurface* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRectangularTrimmedSurface* inst) { // @todo we'll need to add support for p-curves at some point, but not now. return nullptr; diff --git a/src/ifcgeom/mapping/IfcRepresentation.cpp b/src/ifcgeom/mapping/IfcRepresentation.cpp index 6790765cc2..198447c2fa 100644 --- a/src/ifcgeom/mapping/IfcRepresentation.cpp +++ b/src/ifcgeom/mapping/IfcRepresentation.cpp @@ -21,7 +21,7 @@ #define mapping POSTFIX_SCHEMA(mapping) using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcRepresentation* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRepresentation* inst) { const bool use_body = !this->settings_.get(IfcGeom::IteratorSettings::INCLUDE_CURVES); auto items = map_to_collection(this, inst->Items()); @@ -41,19 +41,19 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcRepresentation* inst) { // @todo // if (s.ShapeType() == TopAbs_COMPOUND && TopoDS_Iterator(s).More() && TopoDS_Iterator(s).Value().ShapeType() == TopAbs_SOLID) { - return filter_in_place(items, [&use_body](taxonomy::item* i) { + return filter_in_place(items, [&use_body](taxonomy::ptr i) { // @todo just filter loops for now. return (i->kind() != taxonomy::LOOP) == use_body; }); } /* -taxonomy::item* mapping::map_impl(const IfcSchema::IfcRepresentation* l, ConversionResults& shapes) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRepresentation* l, ConversionResults& shapes) { IfcSchema::IfcRepresentationItem::list::ptr items = inst->Items(); bool part_succes = false; if ( items->size() ) { for ( IfcSchema::IfcRepresentationItem::list::it it = items->begin(); it != items->end(); ++ it ) { - IfcSchema::IfcRepresentationItem* representation_item = *it; + IfcSchema::IfcRepresentationptr representation_item = *it; if ( shape_type(representation_item) == ST_SHAPELIST ) { part_succes |= convert_shapes(*it, shapes); } else { diff --git a/src/ifcgeom/mapping/IfcRevolvedAreaSolid.cpp b/src/ifcgeom/mapping/IfcRevolvedAreaSolid.cpp index e518abf49f..8b2fe01272 100644 --- a/src/ifcgeom/mapping/IfcRevolvedAreaSolid.cpp +++ b/src/ifcgeom/mapping/IfcRevolvedAreaSolid.cpp @@ -23,31 +23,31 @@ using namespace ifcopenshell::geometry; #include -taxonomy::item* mapping::map_impl(const IfcSchema::IfcRevolvedAreaSolid* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRevolvedAreaSolid* inst) { const double ang = inst->Angle() * angle_unit_; - as(map(inst->SweptArea())); + taxonomy::cast(map(inst->SweptArea())); boost::optional angle; - taxonomy::matrix4 matrix; + taxonomy::matrix4::ptr matrix; bool has_position = true; #ifdef SCHEMA_IfcSweptAreaSolid_Position_IS_OPTIONAL has_position = inst->Position() != nullptr; #endif if (has_position) { - matrix = as(map(inst->Position())); + matrix = taxonomy::cast(map(inst->Position())); } if (ang < boost::math::constants::pi() * 2. - 1.e-5) { angle = ang; } - return new taxonomy::revolve( + return taxonomy::make( matrix, - as(map(inst->SweptArea())), - as(map(inst->Axis()->Location())), - as(map(inst->Axis()->Axis())), + taxonomy::cast(map(inst->SweptArea())), + taxonomy::cast(map(inst->Axis()->Location())), + taxonomy::cast(map(inst->Axis()->Axis())), angle ); diff --git a/src/ifcgeom/mapping/IfcRightCircularCone.cpp b/src/ifcgeom/mapping/IfcRightCircularCone.cpp index 56c09c3b6d..309e138151 100644 --- a/src/ifcgeom/mapping/IfcRightCircularCone.cpp +++ b/src/ifcgeom/mapping/IfcRightCircularCone.cpp @@ -21,7 +21,7 @@ #define mapping POSTFIX_SCHEMA(mapping) using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcRightCircularCone* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRightCircularCone* inst) { // @todo return nullptr; /* diff --git a/src/ifcgeom/mapping/IfcRightCircularCylinder.cpp b/src/ifcgeom/mapping/IfcRightCircularCylinder.cpp index 608b5847c6..618e2f8869 100644 --- a/src/ifcgeom/mapping/IfcRightCircularCylinder.cpp +++ b/src/ifcgeom/mapping/IfcRightCircularCylinder.cpp @@ -21,7 +21,7 @@ #define mapping POSTFIX_SCHEMA(mapping) using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcRightCircularCylinder* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRightCircularCylinder* inst) { // @todo return nullptr; /* diff --git a/src/ifcgeom/mapping/IfcRoundedRectangleProfileDef.cpp b/src/ifcgeom/mapping/IfcRoundedRectangleProfileDef.cpp index 2ff5832af3..40a08d14e9 100644 --- a/src/ifcgeom/mapping/IfcRoundedRectangleProfileDef.cpp +++ b/src/ifcgeom/mapping/IfcRoundedRectangleProfileDef.cpp @@ -23,7 +23,7 @@ using namespace ifcopenshell::geometry; #include "../profile_helper.h" -taxonomy::item* mapping::map_impl(const IfcSchema::IfcRoundedRectangleProfileDef* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRoundedRectangleProfileDef* inst) { const double x = inst->XDim() / 2.0f * length_unit_; const double y = inst->YDim() / 2.0f * length_unit_; const double r = inst->RoundingRadius() * length_unit_; @@ -35,13 +35,13 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcRoundedRectangleProfileDef return nullptr; } - taxonomy::matrix4 m4; + taxonomy::matrix4::ptr m4; bool has_position = true; #ifdef SCHEMA_IfcParameterizedProfileDef_Position_IS_OPTIONAL has_position = !!inst->Position(); #endif if (has_position) { - m4 = as(map(inst->Position())); + m4 = taxonomy::cast(map(inst->Position())); } return profile_helper(m4, { diff --git a/src/ifcgeom/mapping/IfcShellBasedSurfaceModel.cpp b/src/ifcgeom/mapping/IfcShellBasedSurfaceModel.cpp index 7077188199..f01f471ee7 100644 --- a/src/ifcgeom/mapping/IfcShellBasedSurfaceModel.cpp +++ b/src/ifcgeom/mapping/IfcShellBasedSurfaceModel.cpp @@ -21,6 +21,6 @@ #define mapping POSTFIX_SCHEMA(mapping) using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcShellBasedSurfaceModel* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcShellBasedSurfaceModel* inst) { return map_to_collection(this, inst->SbsmBoundary()); } diff --git a/src/ifcgeom/mapping/IfcSphere.cpp b/src/ifcgeom/mapping/IfcSphere.cpp index db104f3c8a..e37234d9e0 100644 --- a/src/ifcgeom/mapping/IfcSphere.cpp +++ b/src/ifcgeom/mapping/IfcSphere.cpp @@ -21,7 +21,7 @@ #define mapping POSTFIX_SCHEMA(mapping) using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcSphere* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSphere* inst) { // @todo return nullptr; /* diff --git a/src/ifcgeom/mapping/IfcSphericalSurface.cpp b/src/ifcgeom/mapping/IfcSphericalSurface.cpp index ca4ee390b6..13c2286e03 100644 --- a/src/ifcgeom/mapping/IfcSphericalSurface.cpp +++ b/src/ifcgeom/mapping/IfcSphericalSurface.cpp @@ -23,7 +23,7 @@ using namespace ifcopenshell::geometry; #ifdef SCHEMA_HAS_IfcSphericalSurface -taxonomy::item* mapping::map_impl(const IfcSchema::IfcSphericalSurface* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSphericalSurface* inst) { return nullptr; /* diff --git a/src/ifcgeom/mapping/IfcSubedge.cpp b/src/ifcgeom/mapping/IfcSubedge.cpp index 8fe77bb421..2e9a037596 100644 --- a/src/ifcgeom/mapping/IfcSubedge.cpp +++ b/src/ifcgeom/mapping/IfcSubedge.cpp @@ -22,7 +22,7 @@ using namespace ifcopenshell::geometry; /* -taxonomy::item* mapping::map_impl(const IfcSchema::IfcSubedge* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSubedge* inst) { // @todo return nullptr; } diff --git a/src/ifcgeom/mapping/IfcSurfaceCurve.cpp b/src/ifcgeom/mapping/IfcSurfaceCurve.cpp index 83e9be58af..592c250464 100644 --- a/src/ifcgeom/mapping/IfcSurfaceCurve.cpp +++ b/src/ifcgeom/mapping/IfcSurfaceCurve.cpp @@ -22,7 +22,7 @@ using namespace ifcopenshell::geometry; #ifdef SCHEMA_HAS_IfcSurfaceCurve -taxonomy::item* mapping::map_impl(const IfcSchema::IfcSurfaceCurve* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSurfaceCurve* inst) { // @todo take into account PCurves. return map(inst->Curve3D()); } diff --git a/src/ifcgeom/mapping/IfcSurfaceCurveSweptAreaSolid.cpp b/src/ifcgeom/mapping/IfcSurfaceCurveSweptAreaSolid.cpp index cc8794f986..e99b5da83f 100644 --- a/src/ifcgeom/mapping/IfcSurfaceCurveSweptAreaSolid.cpp +++ b/src/ifcgeom/mapping/IfcSurfaceCurveSweptAreaSolid.cpp @@ -21,19 +21,19 @@ #define mapping POSTFIX_SCHEMA(mapping) using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcSurfaceCurveSweptAreaSolid* inst) { - taxonomy::face f = as(map(inst->SweptArea())); +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSurfaceCurveSweptAreaSolid* inst) { + taxonomy::face::ptr f = taxonomy::cast(map(inst->SweptArea())); - taxonomy::matrix4 matrix; + taxonomy::matrix4::ptr matrix; bool has_position = true; #ifdef SCHEMA_IfcSweptAreaSolid_Position_IS_OPTIONAL has_position = inst->Position() != nullptr; #endif if (has_position) { - matrix = as(map(inst->Position())); + matrix = taxonomy::cast(map(inst->Position())); } - auto scs = new taxonomy::surface_curve_sweep(matrix, f, map(inst->ReferenceSurface()), map(inst->Directrix())); + auto scs = taxonomy::make(matrix, f, map(inst->ReferenceSurface()), map(inst->Directrix())); scs->matrix = matrix; return scs; diff --git a/src/ifcgeom/mapping/IfcSurfaceOfLinearExtrusion.cpp b/src/ifcgeom/mapping/IfcSurfaceOfLinearExtrusion.cpp index 25cdeda425..b18c56b73d 100644 --- a/src/ifcgeom/mapping/IfcSurfaceOfLinearExtrusion.cpp +++ b/src/ifcgeom/mapping/IfcSurfaceOfLinearExtrusion.cpp @@ -21,7 +21,7 @@ #define mapping POSTFIX_SCHEMA(mapping) using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcSurfaceOfLinearExtrusion* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSurfaceOfLinearExtrusion* inst) { return nullptr; /* diff --git a/src/ifcgeom/mapping/IfcSurfaceOfRevolution.cpp b/src/ifcgeom/mapping/IfcSurfaceOfRevolution.cpp index 1ff305f494..b7043e9e4f 100644 --- a/src/ifcgeom/mapping/IfcSurfaceOfRevolution.cpp +++ b/src/ifcgeom/mapping/IfcSurfaceOfRevolution.cpp @@ -21,7 +21,7 @@ #define mapping POSTFIX_SCHEMA(mapping) using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcSurfaceOfRevolution* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSurfaceOfRevolution* inst) { return nullptr; /* diff --git a/src/ifcgeom/mapping/IfcSweptDiskSolid.cpp b/src/ifcgeom/mapping/IfcSweptDiskSolid.cpp index b7df25c9ea..67aa117e68 100644 --- a/src/ifcgeom/mapping/IfcSweptDiskSolid.cpp +++ b/src/ifcgeom/mapping/IfcSweptDiskSolid.cpp @@ -49,8 +49,8 @@ namespace { } */ -taxonomy::item* mapping::map_impl(const IfcSchema::IfcSweptDiskSolid* inst) { - auto loop = map(inst->Directrix()); +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSweptDiskSolid* inst) { + auto loop = taxonomy::cast(map(inst->Directrix())); // Start- EndParam became optional in IFC4 #ifdef SCHEMA_IfcSweptDiskSolid_StartParam_IS_OPTIONAL @@ -68,7 +68,7 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcSweptDiskSolid* inst) { if (inst->as()) { auto fr = inst->as()->FilletRadius(); if (fr && *fr > tol) { - fillet_loop((taxonomy::loop*)loop, *fr); + fillet_loop(loop, *fr); } } #endif @@ -80,30 +80,30 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcSweptDiskSolid* inst) { radii.push_back(*inst->InnerRadius() * length_unit_); } - taxonomy::face f; + auto f = taxonomy::make(); { for (auto it = radii.begin(); it != radii.end(); ++it) { const double r = *it; const bool exterior = it == radii.begin(); - auto c = new taxonomy::circle; + auto c = taxonomy::make(); c->radius = r; - auto e = new taxonomy::edge; + auto e = taxonomy::make(); e->basis = c; e->start = 0.; e->end = 2 * boost::math::constants::pi(); - auto l = new taxonomy::loop; + auto l = taxonomy::make(); l->children = { e }; l->external = exterior; - f.children.push_back(l); + f->children.push_back(l); } } - return new taxonomy::surface_curve_sweep(taxonomy::matrix4(), f, nullptr, loop); + return taxonomy::make(taxonomy::make(), f, nullptr, loop); diff --git a/src/ifcgeom/mapping/IfcTShapeProfileDef.cpp b/src/ifcgeom/mapping/IfcTShapeProfileDef.cpp index 723f289555..809441a743 100644 --- a/src/ifcgeom/mapping/IfcTShapeProfileDef.cpp +++ b/src/ifcgeom/mapping/IfcTShapeProfileDef.cpp @@ -23,7 +23,7 @@ using namespace ifcopenshell::geometry; #include "../profile_helper.h" -taxonomy::item* mapping::map_impl(const IfcSchema::IfcTShapeProfileDef* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcTShapeProfileDef* inst) { const bool doFlangeEdgeFillet = !!inst->FlangeEdgeRadius(); const bool doWebEdgeFillet = !!inst->WebEdgeRadius(); const bool doFillet = !!inst->FilletRadius(); @@ -99,13 +99,13 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcTShapeProfileDef* inst) { xy = y - d2; } - taxonomy::matrix4 m4; + taxonomy::matrix4::ptr m4; bool has_position = true; #ifdef SCHEMA_IfcParameterizedProfileDef_Position_IS_OPTIONAL has_position = !!inst->Position(); #endif if (has_position) { - m4 = as(map(inst->Position())); + m4 = taxonomy::cast(map(inst->Position())); } return profile_helper(m4, { diff --git a/src/ifcgeom/mapping/IfcToroidalSurface.cpp b/src/ifcgeom/mapping/IfcToroidalSurface.cpp index 8fcf9b4631..ce17a37dbc 100644 --- a/src/ifcgeom/mapping/IfcToroidalSurface.cpp +++ b/src/ifcgeom/mapping/IfcToroidalSurface.cpp @@ -23,7 +23,7 @@ using namespace ifcopenshell::geometry; #ifdef SCHEMA_HAS_IfcToroidalSurface -taxonomy::item* mapping::map_impl(const IfcSchema::IfcToroidalSurface* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcToroidalSurface* inst) { return nullptr; /* diff --git a/src/ifcgeom/mapping/IfcTrapeziumProfileDef.cpp b/src/ifcgeom/mapping/IfcTrapeziumProfileDef.cpp index 09ed65c850..d3d1ac8f06 100644 --- a/src/ifcgeom/mapping/IfcTrapeziumProfileDef.cpp +++ b/src/ifcgeom/mapping/IfcTrapeziumProfileDef.cpp @@ -23,7 +23,7 @@ using namespace ifcopenshell::geometry; #include "../profile_helper.h" -taxonomy::item* mapping::map_impl(const IfcSchema::IfcTrapeziumProfileDef* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcTrapeziumProfileDef* inst) { const double x1 = inst->BottomXDim() / 2. * length_unit_; const double w = inst->TopXDim() * length_unit_; const double dx = inst->TopXOffset() * length_unit_; @@ -40,13 +40,13 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcTrapeziumProfileDef* inst) return nullptr; } - taxonomy::matrix4 m4; + taxonomy::matrix4::ptr m4; bool has_position = true; #ifdef SCHEMA_IfcParameterizedProfileDef_Position_IS_OPTIONAL has_position = !!inst->Position(); #endif if (has_position) { - m4 = as(map(inst->Position())); + m4 = taxonomy::cast(map(inst->Position())); } return profile_helper(m4, { diff --git a/src/ifcgeom/mapping/IfcTriangulatedFaceSet.cpp b/src/ifcgeom/mapping/IfcTriangulatedFaceSet.cpp index 73b16f52e4..62886fdffd 100644 --- a/src/ifcgeom/mapping/IfcTriangulatedFaceSet.cpp +++ b/src/ifcgeom/mapping/IfcTriangulatedFaceSet.cpp @@ -23,15 +23,15 @@ using namespace ifcopenshell::geometry; #ifdef SCHEMA_HAS_IfcTriangulatedFaceSet -taxonomy::item* mapping::map_impl(const IfcSchema::IfcTriangulatedFaceSet* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcTriangulatedFaceSet* inst) { IfcSchema::IfcCartesianPointList3D* point_list = inst->Coordinates(); auto coordinates = point_list->CoordList(); std::vector> indices_list = inst->CoordIndex(); - std::vector points; + std::vector points; points.reserve(coordinates.size()); for (auto& coords : coordinates) { - points.push_back(taxonomy::point3( + points.push_back(taxonomy::make( coords.size() < 1 ? 0. : coords[0] * length_unit_, coords.size() < 2 ? 0. : coords[1] * length_unit_, coords.size() < 3 ? 0. : coords[2] * length_unit_)); @@ -39,24 +39,24 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcTriangulatedFaceSet* inst) int max_index = (int)points.size(); - auto shell = new taxonomy::shell; + auto shell = taxonomy::make(); for (auto& indices : indices_list) { - auto fa = new taxonomy::face; + auto fa = taxonomy::make(); shell->children.push_back(fa); { - auto loop = new taxonomy::loop; + auto loop = taxonomy::make(); fa->children = { loop }; loop->external = true; - taxonomy::point3 previous; + taxonomy::point3::ptr previous; for (std::vector::const_iterator jt = indices.begin(); jt != indices.end(); ++jt) { if (*jt < 1 || *jt > max_index) { throw IfcParse::IfcException("IfcTriangulatedFaceSet index out of bounds for index " + boost::lexical_cast(*jt)); } - const taxonomy::point3& current = points[(*jt) - 1]; + const taxonomy::point3::ptr& current = points[(*jt) - 1]; if (jt != indices.begin()) { - loop->children.push_back(new taxonomy::edge(previous, current)); + loop->children.push_back(taxonomy::make(previous, current)); } previous = current; } diff --git a/src/ifcgeom/mapping/IfcTrimmedCurve.cpp b/src/ifcgeom/mapping/IfcTrimmedCurve.cpp index 614d8219d6..608e945db8 100644 --- a/src/ifcgeom/mapping/IfcTrimmedCurve.cpp +++ b/src/ifcgeom/mapping/IfcTrimmedCurve.cpp @@ -23,14 +23,14 @@ using namespace ifcopenshell::geometry; #include -taxonomy::item* mapping::map_impl(const IfcSchema::IfcTrimmedCurve* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcTrimmedCurve* inst) { static const double pi = boost::math::constants::pi(); IfcSchema::IfcCurve* basis_curve = inst->BasisCurve(); bool isConic = basis_curve->declaration().is(IfcSchema::IfcConic::Class()); double parameterFactor = isConic ? angle_unit_ : length_unit_; - auto tc = new taxonomy::edge; + auto tc = taxonomy::make(); tc->basis = map(inst->BasisCurve()); bool trim_cartesian = inst->MasterRepresentation() != IfcSchema::IfcTrimmingPreference::IfcTrimmingPreference_PARAMETER; @@ -40,7 +40,7 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcTrimmedCurve* inst) { // reversed orientation handling happens in geometry kernel unsigned sense_agreement = 0; double flts[2]; - taxonomy::point3 pnts[2]; + taxonomy::point3::ptr pnts[2]; bool has_flts[2] = {false,false}; bool has_pnts[2] = {false,false}; @@ -49,7 +49,7 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcTrimmedCurve* inst) { for ( aggregate_of_instance::it it = trims1->begin(); it != trims1->end(); it ++ ) { IfcUtil::IfcBaseClass* i = *it; if ( i->declaration().is(IfcSchema::IfcCartesianPoint::Class()) ) { - pnts[sense_agreement] = as(map(i)); + pnts[sense_agreement] = taxonomy::cast(map(i)); has_pnts[sense_agreement] = true; } else if ( i->declaration().is(IfcSchema::IfcParameterValue::Class()) ) { const double value = *((IfcSchema::IfcParameterValue*)i); @@ -61,7 +61,7 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcTrimmedCurve* inst) { for ( aggregate_of_instance::it it = trims2->begin(); it != trims2->end(); it ++ ) { IfcUtil::IfcBaseClass* i = *it; if ( i->declaration().is(IfcSchema::IfcCartesianPoint::Class()) ) { - pnts[1 - sense_agreement] = as(map(i)); + pnts[1 - sense_agreement] = taxonomy::cast(map(i)); has_pnts[1-sense_agreement] = true; } else if ( i->declaration().is(IfcSchema::IfcParameterValue::Class()) ) { const double value = *((IfcSchema::IfcParameterValue*)i); @@ -75,7 +75,7 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcTrimmedCurve* inst) { trim_cartesian &= has_pnts[0] && has_pnts[1]; bool trim_cartesian_failed = !trim_cartesian; if (trim_cartesian) { - if ((pnts[0].ccomponents() - pnts[1].ccomponents()).norm() < (2 * tol)) { + if ((pnts[0]->ccomponents() - pnts[1]->ccomponents()).norm() < (2 * tol)) { Logger::Message(Logger::LOG_WARNING, "Skipping segment with length below tolerance level:", inst); return nullptr; } @@ -104,12 +104,10 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcTrimmedCurve* inst) { } double radius = 1.0; - if (tc->basis->kind() == taxonomy::CIRCLE) { - auto typed_curve = (taxonomy::circle*) tc->basis; - radius = typed_curve->radius; - } else if (tc->basis->kind() == taxonomy::ELLIPSE) { - auto typed_curve = (taxonomy::ellipse*) tc->basis; - radius = (typed_curve->radius + typed_curve->radius2) / 2.; + if (auto typed_circle = taxonomy::dcast(tc->basis)) { + radius = typed_circle->radius; + } else if (auto typed_ellipse = taxonomy::dcast(tc->basis)) { + radius = (typed_ellipse->radius + typed_ellipse->radius2) / 2.; } // Fix from @sanderboer to compare using model tolerance, see #744 diff --git a/src/ifcgeom/mapping/IfcUShapeProfileDef.cpp b/src/ifcgeom/mapping/IfcUShapeProfileDef.cpp index 1d7abbec52..c9bb0b3a0c 100644 --- a/src/ifcgeom/mapping/IfcUShapeProfileDef.cpp +++ b/src/ifcgeom/mapping/IfcUShapeProfileDef.cpp @@ -23,7 +23,7 @@ using namespace ifcopenshell::geometry; #include "../profile_helper.h" -taxonomy::item* mapping::map_impl(const IfcSchema::IfcUShapeProfileDef* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcUShapeProfileDef* inst) { const bool doEdgeFillet = !!inst->EdgeRadius(); const bool doFillet = !!inst->FilletRadius(); const bool hasSlope = !!inst->FlangeSlope(); @@ -58,13 +58,13 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcUShapeProfileDef* inst) { return nullptr; } - taxonomy::matrix4 m4; + taxonomy::matrix4::ptr m4; bool has_position = true; #ifdef SCHEMA_IfcParameterizedProfileDef_Position_IS_OPTIONAL has_position = !!inst->Position(); #endif if (has_position) { - m4 = as(map(inst->Position())); + m4 = taxonomy::cast(map(inst->Position())); } return profile_helper(m4, { diff --git a/src/ifcgeom/mapping/IfcVector.cpp b/src/ifcgeom/mapping/IfcVector.cpp index 942a1d957e..c88e22a774 100644 --- a/src/ifcgeom/mapping/IfcVector.cpp +++ b/src/ifcgeom/mapping/IfcVector.cpp @@ -21,8 +21,8 @@ #define mapping POSTFIX_SCHEMA(mapping) using namespace ifcopenshell::geometry; -taxonomy::item* mapping::map_impl(const IfcSchema::IfcVector* inst) { - auto d = (taxonomy::direction3*) map(inst->Orientation()); +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcVector* inst) { + auto d = taxonomy::cast(map(inst->Orientation())); d->components() *= inst->Magnitude() * length_unit_; return d; } diff --git a/src/ifcgeom/mapping/IfcZShapeProfileDef.cpp b/src/ifcgeom/mapping/IfcZShapeProfileDef.cpp index da2a5840aa..e5cb99209e 100644 --- a/src/ifcgeom/mapping/IfcZShapeProfileDef.cpp +++ b/src/ifcgeom/mapping/IfcZShapeProfileDef.cpp @@ -23,7 +23,7 @@ using namespace ifcopenshell::geometry; #include "../profile_helper.h" -taxonomy::item* mapping::map_impl(const IfcSchema::IfcZShapeProfileDef* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcZShapeProfileDef* inst) { const double x = inst->FlangeWidth() * length_unit_; const double y = inst->Depth() / 2.0f * length_unit_; const double dx = inst->WebThickness() / 2.0f * length_unit_; @@ -49,13 +49,13 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcZShapeProfileDef* inst) { return nullptr; } - taxonomy::matrix4 m4; + taxonomy::matrix4::ptr m4; bool has_position = true; #ifdef SCHEMA_IfcParameterizedProfileDef_Position_IS_OPTIONAL has_position = !!inst->Position(); #endif if (has_position) { - m4 = as(map(inst->Position())); + m4 = taxonomy::cast(map(inst->Position())); } return profile_helper(m4, { diff --git a/src/ifcgeom/mapping/bind_convert_decl.i b/src/ifcgeom/mapping/bind_convert_decl.i index 67a5f7b091..64509f4c32 100644 --- a/src/ifcgeom/mapping/bind_convert_decl.i +++ b/src/ifcgeom/mapping/bind_convert_decl.i @@ -2,6 +2,6 @@ #undef BIND #endif -#define BIND(T) ifcopenshell::geometry::taxonomy::item* map_impl(const IfcSchema::T*); +#define BIND(T) ifcopenshell::geometry::taxonomy::ptr map_impl(const IfcSchema::T*); #include "mapping.i" diff --git a/src/ifcgeom/mapping/bind_convert_impl.i b/src/ifcgeom/mapping/bind_convert_impl.i index 5757fd9825..e9c6f3f6e2 100644 --- a/src/ifcgeom/mapping/bind_convert_impl.i +++ b/src/ifcgeom/mapping/bind_convert_impl.i @@ -5,7 +5,7 @@ #define BIND(T) \ if (inst->as()) { \ try { \ - taxonomy::item* item = map_impl(inst->as()); \ + taxonomy::ptr item = map_impl(inst->as()); \ if (item != nullptr) { \ item->instance = inst; \ try { \ @@ -15,7 +15,7 @@ ) { \ auto style = find_style(inst->as()); \ if (style) { \ - ((taxonomy::geom_item*)item)->surface_style = (taxonomy::style*) map(style); \ + taxonomy::cast(item)->surface_style = taxonomy::cast(map(style)); \ } \ } \ } catch (const std::exception& e) { \ diff --git a/src/ifcgeom/mapping/mapping.cpp b/src/ifcgeom/mapping/mapping.cpp index 5b8ed835a5..304dc22793 100644 --- a/src/ifcgeom/mapping/mapping.cpp +++ b/src/ifcgeom/mapping/mapping.cpp @@ -69,15 +69,15 @@ IfcSchema::IfcProduct::list::ptr mapping::products_represented_by(const IfcSchem IfcSchema::IfcRepresentationMap::list::ptr maps = representation->RepresentationMap(); if (maps->size() == 1) { IfcSchema::IfcRepresentationMap* rmap = *maps->begin(); - taxonomy::matrix4 origin = as(map(rmap->MappingOrigin())); - if (origin.is_identity()) { + taxonomy::matrix4::ptr origin = taxonomy::cast(map(rmap->MappingOrigin())); + if (origin->is_identity()) { IfcSchema::IfcMappedItem::list::ptr items = rmap->MapUsage(); for (IfcSchema::IfcMappedItem::list::it it = items->begin(); it != items->end(); ++it) { IfcSchema::IfcMappedItem* item = *it; if (item->StyledByItem()->size() != 0) continue; - taxonomy::matrix4 target = as(map(item->MappingTarget())); - if (!target.is_identity()) { + taxonomy::matrix4::ptr target = taxonomy::cast(map(item->MappingTarget())); + if (!target->is_identity()) { continue; } @@ -278,11 +278,11 @@ IfcSchema::IfcRepresentation* mapping::representation_mapped_to(const IfcSchema: if (item->declaration().is(IfcSchema::IfcMappedItem::Class())) { if (item->StyledByItem()->size() == 0) { IfcSchema::IfcMappedItem* mapped_item = item->as(); - taxonomy::matrix4 target = as(map(mapped_item->MappingTarget())); - if (target.is_identity()) { + taxonomy::matrix4::ptr target = taxonomy::cast(map(mapped_item->MappingTarget())); + if (target->is_identity()) { IfcSchema::IfcRepresentationMap* rmap = mapped_item->MappingSource(); - taxonomy::matrix4 origin = as(map(rmap->MappingOrigin())); - if (origin.is_identity()) { + taxonomy::matrix4::ptr origin = taxonomy::cast(map(rmap->MappingOrigin())); + if (origin->is_identity()) { representation_mapped_to = rmap->MappedRepresentation(); } } @@ -406,7 +406,7 @@ namespace { } } -taxonomy::item* mapping::map_impl(const IfcSchema::IfcMaterial* material) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcMaterial* material) { IfcSchema::IfcMaterialDefinitionRepresentation::list::ptr defs = material->HasRepresentation(); for (IfcSchema::IfcMaterialDefinitionRepresentation::list::it jt = defs->begin(); jt != defs->end(); ++jt) { IfcSchema::IfcRepresentation::list::ptr reps = (*jt)->Representations(); @@ -419,7 +419,7 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcMaterial* material) { } } - taxonomy::style* material_style = new taxonomy::style; + taxonomy::style::ptr material_style = taxonomy::make(); return material_style; // @todo @@ -427,7 +427,7 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcMaterial* material) { // return &(style_cache[material->data().id()] = material_style); } -taxonomy::item* mapping::map_impl(const IfcSchema::IfcStyledItem* inst) { +taxonomy::ptr mapping::map_impl(const IfcSchema::IfcStyledItem* inst) { auto style_pair = get_surface_style(inst); IfcSchema::IfcSurfaceStyle* style = style_pair.first; @@ -439,7 +439,7 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcStyledItem* inst) { static taxonomy::colour white = taxonomy::colour(1., 1., 1.); - taxonomy::style* surface_style = new taxonomy::style; + taxonomy::style::ptr surface_style = taxonomy::make(); surface_style->instance = style; if (style->Name()) { @@ -489,7 +489,7 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcStyledItem* inst) { } -taxonomy::item* mapping::map(const IfcBaseInterface* inst) { +taxonomy::ptr mapping::map(const IfcBaseInterface* inst) { // std::wcout << inst->data().toString().c_str() << std::endl; #include "bind_convert_impl.i" Logger::Message(Logger::LOG_ERROR, "No operation defined for:", inst); @@ -745,29 +745,33 @@ bool mapping::get_layerset_information(const IfcUtil::IfcBaseInterface* p, layer return false; } - auto* curve = map(axis_representation); - auto* product_node = map(product); + auto curve = map(axis_representation); + auto product_node = taxonomy::cast(map(product)); - auto& m4 = ((taxonomy::geom_item*) product_node)->matrix; - auto c2 = flatten((taxonomy::collection*)curve); + auto& m4 = product_node->matrix; + auto c2 = flatten(taxonomy::cast(curve)); if (c2->children.empty()) { return false; } +#ifdef TAXONOMY_USE_NAKED_PTR delete curve; delete product_node; +#endif auto c = c2->children[0]; - auto ofc = new taxonomy::offset_curve; + auto Z = taxonomy::make(0, 0, 1);; + + auto ofc = taxonomy::make(); ofc->offset = -offset; - ofc->reference = taxonomy::direction3(0, 0, 1); - ofc->basis = c2->children[0]->clone(); + ofc->reference = Z; + ofc->basis = c2->children[0]; ofc->matrix = m4; info.layers.push_back(ofc); for (IfcSchema::IfcMaterialLayer::list::it it = material_layers->begin(); it != material_layers->end(); ++it) { - info.styles.push_back(as(map((*it)->Material()))); + info.styles.push_back(*taxonomy::cast(map((*it)->Material()))); double thickness = (*it)->LayerThickness() * this->length_unit_; @@ -780,20 +784,22 @@ bool mapping::get_layerset_information(const IfcUtil::IfcBaseInterface* p, layer offset += thickness; if (fabs(offset) < 1.e-7) { - auto ofc = c->clone(); - ((taxonomy::geom_item*)ofc)->matrix = m4; + auto ofc = c; + c->matrix = m4; info.layers.push_back(ofc); } else { - auto ofc = new taxonomy::offset_curve; + auto ofc = taxonomy::make(); ofc->offset = -offset; - ofc->reference = taxonomy::direction3(0, 0, 1); - ofc->basis = c2->children[0]->clone(); + ofc->reference = Z; + ofc->basis = c2; ofc->matrix = m4; info.layers.push_back(ofc); } } +#ifdef TAXONOMY_USE_NAKED_PTR delete c2; +#endif if (positive) { std::reverse(info.thicknesses.begin(), info.thicknesses.end()); @@ -810,23 +816,23 @@ bool mapping::get_layerset_information(const IfcUtil::IfcBaseInterface* p, layer IfcSchema::IfcExtrudedAreaSolid* extrusion = *extrusions->begin(); - taxonomy::matrix4 extrusion_position; + taxonomy::matrix4::ptr extrusion_position; bool has_position = true; #ifdef SCHEMA_IfcSweptAreaSolid_Position_IS_OPTIONAL has_position = extrusion->Position() != nullptr; #endif if (has_position) { - auto m4 = (taxonomy::matrix4*) map(extrusion->Position()); + auto m4 = taxonomy::cast(map(extrusion->Position())); if (!m4) { Logger::Message(Logger::LOG_ERROR, "Failed to convert placement for extrusion of:", product); return false; } else { - extrusion_position = *m4; + extrusion_position = m4; } } - taxonomy::direction3* extrusion_direction = (taxonomy::direction3*) map(extrusion->ExtrudedDirection()); + taxonomy::direction3::ptr extrusion_direction = taxonomy::cast(map(extrusion->ExtrudedDirection())); if (!extrusion_direction) { Logger::Message(Logger::LOG_ERROR, "Failed to convert direction for extrusion of:", product); @@ -837,14 +843,14 @@ bool mapping::get_layerset_information(const IfcUtil::IfcBaseInterface* p, layer // reference_surface = new Geom_Plane(extrusion_position.TranslationPart(), extrusion_direction); { - auto pln = new taxonomy::plane; + auto pln = taxonomy::make(); pln->matrix = extrusion_position; info.layers.push_back(pln); } for (IfcSchema::IfcMaterialLayer::list::it it = material_layers->begin(); it != material_layers->end(); ++it) { - info.styles.push_back(as(map((*it)->Material()))); + info.styles.push_back(*taxonomy::cast(map((*it)->Material()))); double thickness = (*it)->LayerThickness() * this->length_unit_; @@ -856,12 +862,12 @@ bool mapping::get_layerset_information(const IfcUtil::IfcBaseInterface* p, layer offset += thickness; - taxonomy::matrix4 offset_matrix; - offset_matrix.components()(2, 3) = offset; - offset_matrix.components()(3, 3) = 1.; - offset_matrix.components() *= extrusion_position.components(); + auto offset_matrix = taxonomy::make(); + offset_matrix->components()(2, 3) = offset; + offset_matrix->components()(3, 3) = 1.; + offset_matrix->components() *= extrusion_position->components(); - auto pln = new taxonomy::plane; + auto pln = taxonomy::make(); pln->matrix = offset_matrix; info.layers.push_back(pln); diff --git a/src/ifcgeom/mapping/mapping.h b/src/ifcgeom/mapping/mapping.h index ed6518b458..248fc4aca2 100644 --- a/src/ifcgeom/mapping/mapping.h +++ b/src/ifcgeom/mapping/mapping.h @@ -33,7 +33,7 @@ namespace geometry { initialize_units_(); apply_settings(); } - virtual ifcopenshell::geometry::taxonomy::item* map(const IfcUtil::IfcBaseInterface*); + virtual ifcopenshell::geometry::taxonomy::ptr map(const IfcUtil::IfcBaseInterface*); virtual void get_representations(std::vector& tasks, std::vector& filters); virtual std::map get_layers(IfcUtil::IfcBaseEntity*); virtual void initialize_settings(); @@ -56,103 +56,45 @@ namespace geometry { #include "bind_convert_decl.i" }; - - // Hacks around not wanting to use if constexpr - template - class loop_to_face_upgrade { - public: - loop_to_face_upgrade(taxonomy::item*) {} - - operator bool() const { - return false; - } - - operator taxonomy::face() const { - throw taxonomy::topology_error(); - } - - operator T() const { - throw taxonomy::topology_error(); - } + template + struct element_type { + typedef taxonomy::item type; }; - template <> - class loop_to_face_upgrade { - private: - boost::optional face_; - public: - loop_to_face_upgrade(taxonomy::item* item) { - taxonomy::loop* loop = dynamic_cast(item); - if (loop) { - loop->external = true; - - face_.emplace(); - face_->instance = loop->instance; - face_->matrix = loop->matrix; - face_->children = { loop->clone() }; - } - } - - operator bool() const { - return face_.is_initialized(); - } - - operator taxonomy::face() const { - return *face_; - } + struct element_type { + typedef taxonomy::geom_item type; }; - - // A RAII-based mechanism to cast the conversion results - // from map() into the right type expected by the higher - // level typology items. An exception is thrown if the - // types do not match or the result was nullptr. A copy - // will be assigned to the higher level topology member - // and the original pointer will be deleted. - - // This class is also able to uplift some topology items - // to higher level types, such as a loop to a face, which - // is why the cast operator does not return a reference. - template - class as { - private: - taxonomy::item* item_; - - public: - as(taxonomy::item* item) : item_(item) {} - operator T() const { - if (!item_) { - throw taxonomy::topology_error("item was nullptr"); - } - T* t = dynamic_cast(item_); - if (t) { - return T(*t); - } else { - { - loop_to_face_upgrade upgrade(item_); - if (upgrade) { - return upgrade; - } - } - throw taxonomy::topology_error("item does not match type"); - } - } - ~as() { - delete item_; - } + template <> + struct element_type { + typedef taxonomy::geom_item type; }; + template <> + struct element_type { + typedef taxonomy::face type; + }; + template <> + struct element_type { + typedef taxonomy::edge type; + }; + template <> + struct element_type { + typedef taxonomy::shell type; + }; template - U* map_to_collection(POSTFIX_SCHEMA(mapping)* m, const T& ts) { - auto c = new U; + typename U::ptr map_to_collection(POSTFIX_SCHEMA(mapping)* m, const T& ts) { + auto c = taxonomy::make(); if (ts->size()) { for (auto it = ts->begin(); it != ts->end(); ++it) { if (auto r = m->map(*it)) { - c->children.push_back(r); + c->children.push_back(taxonomy::cast::type>(r)); } } } if (c->children.empty()) { +#ifdef TAXONOMY_USE_NAKED_PTR delete c; +#endif return nullptr; } return c; diff --git a/src/ifcgeom/profile_helper.cpp b/src/ifcgeom/profile_helper.cpp index e5f960a3d3..b31689d498 100644 --- a/src/ifcgeom/profile_helper.cpp +++ b/src/ifcgeom/profile_helper.cpp @@ -2,13 +2,13 @@ using namespace ifcopenshell::geometry; -taxonomy::loop* ifcopenshell::geometry::fillet_loop(taxonomy::loop* loop, double radius) { +taxonomy::loop::ptr ifcopenshell::geometry::fillet_loop(taxonomy::loop::ptr loop, double radius) { std::vector pps(loop->children.size()); for (int b = 0; b < loop->children.size(); ++b) { int c = (b - 1) % loop->children.size(); pps[b] = { - boost::get(((taxonomy::edge*)loop->children[c])->start).ccomponents(), - radius, (taxonomy::edge*) loop->children[c], (taxonomy::edge*) loop->children[b] + boost::get(loop->children[c]->start)->ccomponents(), + radius, loop->children[c], loop->children[b] }; } size_t i = pps.size(); @@ -16,10 +16,10 @@ taxonomy::loop* ifcopenshell::geometry::fillet_loop(taxonomy::loop* loop, double const auto& p = pps[i]; if (p.radius && *p.radius > 0.) { - auto p0 = boost::get(p.previous->start).ccomponents(); - auto p1a = boost::get(p.previous->end).ccomponents(); - auto p2 = boost::get(p.next->end).ccomponents(); - auto p1b = boost::get(p.next->start).ccomponents(); + auto p0 = boost::get(p.previous->start)->ccomponents(); + auto p1a = boost::get(p.previous->end)->ccomponents(); + auto p2 = boost::get(p.next->end)->ccomponents(); + auto p1b = boost::get(p.next->start)->ccomponents(); auto ba_ = p0 - p1a; auto bc_ = p2 - p1b; @@ -30,10 +30,10 @@ taxonomy::loop* ifcopenshell::geometry::fillet_loop(taxonomy::loop* loop, double const double angle = std::acos(ba.dot(bc)); const double inset = *p.radius / std::tan(angle / 2.); - boost::get(p.previous->end).components() += ba * inset; - boost::get(p.next->start).components() += bc * inset; + boost::get(p.previous->end)->components() += ba * inset; + boost::get(p.next->start)->components() += bc * inset; - auto e = new taxonomy::edge; + auto e = taxonomy::make(); e->start = p.previous->end; e->end = p.next->start; @@ -41,10 +41,10 @@ taxonomy::loop* ifcopenshell::geometry::fillet_loop(taxonomy::loop* loop, double auto ab = ba.cross(bc); - auto O = boost::get(p.previous->end).ccomponents().head<3>() + ab * *p.radius; + auto O = boost::get(p.previous->end)->ccomponents().head<3>() + ab * *p.radius; - auto c = new taxonomy::circle; - c->matrix = taxonomy::matrix4(O, ab); + auto c = taxonomy::make(); + c->matrix = taxonomy::make(O, ab); c->radius = *p.radius; e->basis = c; @@ -54,14 +54,14 @@ taxonomy::loop* ifcopenshell::geometry::fillet_loop(taxonomy::loop* loop, double return loop; } -taxonomy::loop* ifcopenshell::geometry::polygon_from_points(const std::vector& ps, bool external) { - auto loop = new taxonomy::loop(); +taxonomy::loop::ptr ifcopenshell::geometry::polygon_from_points(const std::vector& ps, bool external) { + auto loop = taxonomy::make(); loop->external = external; - boost::optional previous; + taxonomy::point3::ptr previous; for (auto& p : ps) { if (previous) { - auto e = new taxonomy::edge; - e->start = *previous; + auto e = taxonomy::make(); + e->start = previous; e->end = p; loop->children.push_back(e); } @@ -70,7 +70,7 @@ taxonomy::loop* ifcopenshell::geometry::polygon_from_points(const std::vector& points) { +taxonomy::loop::ptr ifcopenshell::geometry::profile_helper(const taxonomy::matrix4::ptr& m4, const std::vector& points) { /* TopoDS_Vertex* vertices = new TopoDS_Vertex[numVerts]; for (int i = 0; i < numVerts; i++) { @@ -99,19 +99,19 @@ taxonomy::loop* ifcopenshell::geometry::profile_helper(const taxonomy::matrix4& } */ - const bool has_position = !m4.is_identity(); + const bool has_position = !m4->is_identity(); // @todo precision - std::vector ps; + std::vector ps; ps.reserve(points.size() + 1); std::transform(points.begin(), points.end(), std::back_inserter(ps), [&has_position, &m4](const profile_point& p) { if (has_position) { Eigen::Vector4d v(p.xy[0], p.xy[1], 0., 1.); - v = m4.ccomponents() * v; - return taxonomy::point3(v(0), v(1), 0.); + v = m4->ccomponents() * v; + return taxonomy::make(v(0), v(1), 0.); } else { - return taxonomy::point3(p.xy[0], p.xy[1], 0.); + return taxonomy::make(p.xy[0], p.xy[1], 0.); } }); ps.push_back(ps.front()); @@ -121,7 +121,7 @@ taxonomy::loop* ifcopenshell::geometry::profile_helper(const taxonomy::matrix4& std::vector pps(points.size()); for (int b = 0; b < points.size(); ++b) { int c = (b - 1) % points.size(); - pps[b] = { Eigen::Vector2d(points[b].xy[0], points[b].xy[1]), points[b].radius, (taxonomy::edge*) loop->children[c], (taxonomy::edge*) loop->children[b] }; + pps[b] = { Eigen::Vector2d(points[b].xy[0], points[b].xy[1]), points[b].radius, loop->children[c], loop->children[b] }; } size_t i = pps.size(); @@ -129,10 +129,10 @@ taxonomy::loop* ifcopenshell::geometry::profile_helper(const taxonomy::matrix4& const auto& p = pps[i]; if (p.radius && *p.radius > 0.) { // Position is a IfcAxis2Placement2D, so should remain 2d points - auto p0 = boost::get(p.previous->start).components_->head<2>(); - auto p1a = boost::get(p.previous->end).components_->head<2>(); - auto p2 = boost::get(p.next->end).components_->head<2>(); - auto p1b = boost::get(p.next->start).components_->head<2>(); + auto p0 = boost::get(p.previous->start)->components_->head<2>(); + auto p1a = boost::get(p.previous->end)->components_->head<2>(); + auto p2 = boost::get(p.next->end)->components_->head<2>(); + auto p1b = boost::get(p.next->start)->components_->head<2>(); auto ba_ = p0 - p1a; auto bc_ = p2 - p1b; @@ -143,10 +143,10 @@ taxonomy::loop* ifcopenshell::geometry::profile_helper(const taxonomy::matrix4& const double angle = std::acos(ba.dot(bc)); const double inset = *p.radius / std::tan(angle / 2.); - boost::get(p.previous->end).components_->head<2>() += ba * inset; - boost::get(p.next->start).components_->head<2>() += bc * inset; + boost::get(p.previous->end)->components_->head<2>() += ba * inset; + boost::get(p.next->start)->components_->head<2>() += bc * inset; - auto e = new taxonomy::edge; + auto e = taxonomy::make(); e->start = p.previous->end; e->end = p.next->start; @@ -154,10 +154,10 @@ taxonomy::loop* ifcopenshell::geometry::profile_helper(const taxonomy::matrix4& double sign = ab.head<2>().dot(bc) > 0 ? 1. : -1.; - auto O = boost::get(p.previous->end).ccomponents().head<3>() + ab * *p.radius * sign; + auto O = boost::get(p.previous->end)->ccomponents().head<3>() + ab * *p.radius * sign; - auto c = new taxonomy::circle; - c->matrix = Eigen::Matrix4d(Eigen::Affine3d(Eigen::Translation3d(O)).matrix()); + auto c = taxonomy::make(); + c->matrix = taxonomy::make(Eigen::Matrix4d(Eigen::Affine3d(Eigen::Translation3d(O)).matrix())); c->radius = *p.radius; e->basis = c; c->orientation.reset(sign == -1.); diff --git a/src/ifcgeom/profile_helper.h b/src/ifcgeom/profile_helper.h index d563e3387f..aa4d6a100f 100644 --- a/src/ifcgeom/profile_helper.h +++ b/src/ifcgeom/profile_helper.h @@ -14,20 +14,20 @@ namespace ifcopenshell { struct profile_point_with_edges { Eigen::Vector2d xy; boost::optional radius; - taxonomy::edge *previous, *next; + taxonomy::edge::ptr previous, next; }; struct profile_point_with_edges_3d { Eigen::Vector3d xy; boost::optional radius; - taxonomy::edge *previous, *next; + taxonomy::edge::ptr previous, next; }; - taxonomy::loop* polygon_from_points(const std::vector& ps, bool external = true); + taxonomy::loop::ptr polygon_from_points(const std::vector& ps, bool external = true); - taxonomy::loop* profile_helper(const taxonomy::matrix4& m4, const std::vector& points); + taxonomy::loop::ptr profile_helper(const taxonomy::matrix4::ptr& m4, const std::vector& points); - taxonomy::loop* fillet_loop(taxonomy::loop* lp, double radius); + taxonomy::loop::ptr fillet_loop(taxonomy::loop::ptr lp, double radius); } } diff --git a/src/ifcgeom/taxonomy.cpp b/src/ifcgeom/taxonomy.cpp index fd19ed56b1..495209136c 100644 --- a/src/ifcgeom/taxonomy.cpp +++ b/src/ifcgeom/taxonomy.cpp @@ -7,6 +7,18 @@ namespace { bool compare(const collection& a, const collection& b); + bool compare(const loop& a, const loop& b); + + bool compare(const face& a, const face& b); + + bool compare(const shell& a, const shell& b); + + bool compare(const solid& a, const solid& b); + + bool compare(const loft& a, const loft& b); + + bool compare(const boolean_result& a, const boolean_result& b); + template bool compare(const eigen_base& t, const eigen_base& u) { if (t.components_ == nullptr && u.components_ == nullptr) { @@ -27,23 +39,23 @@ namespace { } bool compare(const line& a, const line& b) { - return compare(a.matrix, b.matrix); + return compare(*a.matrix, *b.matrix); } bool compare(const plane& a, const plane& b) { - return compare(a.matrix, b.matrix); + return compare(*a.matrix, *b.matrix); } bool compare(const circle& a, const circle& b) { if (a.radius == b.radius) { - return compare(a.matrix, b.matrix); + return compare(*a.matrix, *b.matrix); } return a.radius < b.radius; } bool compare(const ellipse& a, const ellipse& b) { if (a.radius == b.radius && a.radius2 == b.radius2) { - return compare(a.matrix, b.matrix); + return compare(*a.matrix, *b.matrix); } return std::tie(a.radius, a.radius2) < @@ -83,11 +95,11 @@ namespace { } } - int compare(const boost::variant& a, const boost::variant& b) { + int compare(const boost::variant& a, const boost::variant& b) { bool a_lt_b, b_lt_a; if (a.which() == 0) { - a_lt_b = compare(boost::get(a), boost::get(b)); - b_lt_a = compare(boost::get(b), boost::get(a)); + a_lt_b = compare(*boost::get(a), *boost::get(b)); + b_lt_a = compare(*boost::get(b), *boost::get(a)); } else { a_lt_b = std::less()(boost::get(a), boost::get(b)); b_lt_a = std::less()(boost::get(b), boost::get(a)); @@ -132,7 +144,7 @@ namespace { bool compare(const surface_curve_sweep&, const surface_curve_sweep&) { throw std::runtime_error("not implemented"); } - + bool compare(const style& a, const style& b) { const int order[5] = { less_to_order(a.name, b.name), @@ -168,7 +180,7 @@ namespace { }; } -bool ifcopenshell::geometry::taxonomy::less(const item* a, const item* b) { +bool ifcopenshell::geometry::taxonomy::less(item::const_ptr a, item::const_ptr b) { if (a == b) { return false; } @@ -180,7 +192,9 @@ bool ifcopenshell::geometry::taxonomy::less(const item* a, const item* b) { return a_kind < b_kind; } - return dispatch_comparison<0>::dispatch(a, b); +#ifdef TAXONOMY_USE_SHARED_PTR + return dispatch_comparison<0>::dispatch(a.get(), b.get()); +#endif } @@ -232,7 +246,8 @@ namespace { } } - bool compare(const collection& a, const collection& b) { + template + bool compare_collection(const collection_base& a, const collection_base& b) { if (a.children.size() == b.children.size()) { auto at = a.children.begin(); auto bt = b.children.begin(); @@ -246,155 +261,183 @@ namespace { return a_lt_b; } // Vectors equal, compare matrix (in case of mapped items). - return compare(a.matrix, b.matrix); + return compare(*a.matrix, *b.matrix); } else { return a.children.size() < b.children.size(); } } + + bool compare(const loop& a, const loop& b) { + return compare_collection(a, b); + } + + bool compare(const face& a, const face& b) { + return compare_collection(a, b); + } + + bool compare(const shell& a, const shell& b) { + return compare_collection(a, b); + } + + bool compare(const solid& a, const solid& b) { + return compare_collection(a, b); + } + + bool compare(const loft& a, const loft& b) { + return compare_collection(a, b); + } + + bool compare(const collection& a, const collection& b) { + return compare_collection(a, b); + } + + bool compare(const boolean_result& a, const boolean_result& b) { + return compare_collection(a, b); + } } -ifcopenshell::geometry::taxonomy::solid* ifcopenshell::geometry::create_box(double dx, double dy, double dz) { +ifcopenshell::geometry::taxonomy::solid::ptr ifcopenshell::geometry::create_box(double dx, double dy, double dz) { return create_box(0., 0., 0., dx, dy, dz); } -ifcopenshell::geometry::taxonomy::solid* ifcopenshell::geometry::create_box(double x, double y, double z, double dx, double dy, double dz) { - auto solid = new taxonomy::solid; - auto shell = new taxonomy::shell; +ifcopenshell::geometry::taxonomy::solid::ptr ifcopenshell::geometry::create_box(double x, double y, double z, double dx, double dy, double dz) { + auto solid = make(); + auto shell = make(); solid->children.push_back(shell); // x = 0 { - auto face = new taxonomy::face; - auto loop = new taxonomy::loop; + auto face = make(); + auto loop = make(); face->children.push_back(loop); loop->external = true; shell->children.push_back(face); - std::array points{ - taxonomy::point3(x+0, y+0, z+ 0), - taxonomy::point3(x+0, y+dy, z+ 0), - taxonomy::point3(x+0, y+dy, z+dz), - taxonomy::point3(x+0, y+0, z+dz) + std::array points{ + taxonomy::make(x+0, y+0, z+ 0), + taxonomy::make(x+0, y+dy, z+ 0), + taxonomy::make(x+0, y+dy, z+dz), + taxonomy::make(x+0, y+0, z+dz) }; - loop->children.push_back(new taxonomy::edge(points[0], points[1])); - loop->children.push_back(new taxonomy::edge(points[1], points[2])); - loop->children.push_back(new taxonomy::edge(points[2], points[3])); - loop->children.push_back(new taxonomy::edge(points[3], points[0])); + loop->children.push_back(make(points[0], points[1])); + loop->children.push_back(make(points[1], points[2])); + loop->children.push_back(make(points[2], points[3])); + loop->children.push_back(make(points[3], points[0])); } // x = dx { - auto face = new taxonomy::face; - auto loop = new taxonomy::loop; + auto face = make(); + auto loop = make(); face->children.push_back(loop); loop->external = true; shell->children.push_back(face); - std::array points{ - taxonomy::point3(x+dx, y+0, z+ 0), - taxonomy::point3(x+dx, y+0, z+dz), - taxonomy::point3(x+dx, y+dy, z+dz), - taxonomy::point3(x+dx, y+dy, z+ 0) + std::array points{ + taxonomy::make(x+dx, y+0, z+ 0), + taxonomy::make(x+dx, y+0, z+dz), + taxonomy::make(x+dx, y+dy, z+dz), + taxonomy::make(x+dx, y+dy, z+ 0) }; - loop->children.push_back(new taxonomy::edge(points[0], points[1])); - loop->children.push_back(new taxonomy::edge(points[1], points[2])); - loop->children.push_back(new taxonomy::edge(points[2], points[3])); - loop->children.push_back(new taxonomy::edge(points[3], points[0])); + loop->children.push_back(make(points[0], points[1])); + loop->children.push_back(make(points[1], points[2])); + loop->children.push_back(make(points[2], points[3])); + loop->children.push_back(make(points[3], points[0])); } // y = 0 { - auto face = new taxonomy::face; - auto loop = new taxonomy::loop; + auto face = make(); + auto loop = make(); face->children.push_back(loop); loop->external = true; shell->children.push_back(face); - std::array points{ - taxonomy::point3(x+0, y+0, z+ 0), - taxonomy::point3(x+0, y+0, z+dz), - taxonomy::point3(x+dx, y+0, z+dz), - taxonomy::point3(x+dx, y+0, z+ 0) + std::array points{ + taxonomy::make(x+0, y+0, z+ 0), + taxonomy::make(x+0, y+0, z+dz), + taxonomy::make(x+dx, y+0, z+dz), + taxonomy::make(x+dx, y+0, z+ 0) }; - loop->children.push_back(new taxonomy::edge(points[0], points[1])); - loop->children.push_back(new taxonomy::edge(points[1], points[2])); - loop->children.push_back(new taxonomy::edge(points[2], points[3])); - loop->children.push_back(new taxonomy::edge(points[3], points[0])); + loop->children.push_back(make(points[0], points[1])); + loop->children.push_back(make(points[1], points[2])); + loop->children.push_back(make(points[2], points[3])); + loop->children.push_back(make(points[3], points[0])); } // y = dy { - auto face = new taxonomy::face; - auto loop = new taxonomy::loop; + auto face = make(); + auto loop = make(); face->children.push_back(loop); loop->external = true; shell->children.push_back(face); - std::array points{ - taxonomy::point3(x+ 0, y+dy, z+ 0), - taxonomy::point3(x+dx, y+dy, z+ 0), - taxonomy::point3(x+dx, y+dy, z+dz), - taxonomy::point3(x+ 0, y+dy, z+dz) + std::array points{ + taxonomy::make(x+ 0, y+dy, z+ 0), + taxonomy::make(x+dx, y+dy, z+ 0), + taxonomy::make(x+dx, y+dy, z+dz), + taxonomy::make(x+ 0, y+dy, z+dz) }; - loop->children.push_back(new taxonomy::edge(points[0], points[1])); - loop->children.push_back(new taxonomy::edge(points[1], points[2])); - loop->children.push_back(new taxonomy::edge(points[2], points[3])); - loop->children.push_back(new taxonomy::edge(points[3], points[0])); + loop->children.push_back(make(points[0], points[1])); + loop->children.push_back(make(points[1], points[2])); + loop->children.push_back(make(points[2], points[3])); + loop->children.push_back(make(points[3], points[0])); } // z = 0 { - auto face = new taxonomy::face; - auto loop = new taxonomy::loop; + auto face = make(); + auto loop = make(); face->children.push_back(loop); loop->external = true; shell->children.push_back(face); - std::array points{ - taxonomy::point3(x+ 0, y+ 0, z+0), - taxonomy::point3(x+dx, y+ 0, z+0), - taxonomy::point3(x+dx, y+dy, z+0), - taxonomy::point3(x+ 0, y+dy, z+0) + std::array points{ + taxonomy::make(x+ 0, y+ 0, z+0), + taxonomy::make(x+dx, y+ 0, z+0), + taxonomy::make(x+dx, y+dy, z+0), + taxonomy::make(x+ 0, y+dy, z+0) }; - loop->children.push_back(new taxonomy::edge(points[0], points[1])); - loop->children.push_back(new taxonomy::edge(points[1], points[2])); - loop->children.push_back(new taxonomy::edge(points[2], points[3])); - loop->children.push_back(new taxonomy::edge(points[3], points[0])); + loop->children.push_back(make(points[0], points[1])); + loop->children.push_back(make(points[1], points[2])); + loop->children.push_back(make(points[2], points[3])); + loop->children.push_back(make(points[3], points[0])); } // z = dz { - auto face = new taxonomy::face; - auto loop = new taxonomy::loop; + auto face = make(); + auto loop = make(); face->children.push_back(loop); loop->external = true; shell->children.push_back(face); - std::array points{ - taxonomy::point3(x+ 0, y+ 0, z+dz), - taxonomy::point3(x+ 0, y+dy, z+dz), - taxonomy::point3(x+dx, y+dy, z+dz), - taxonomy::point3(x+dx, y+ 0, z+dz) + std::array points{ + taxonomy::make(x+ 0, y+ 0, z+dz), + taxonomy::make(x+ 0, y+dy, z+dz), + taxonomy::make(x+dx, y+dy, z+dz), + taxonomy::make(x+dx, y+ 0, z+dz) }; - loop->children.push_back(new taxonomy::edge(points[0], points[1])); - loop->children.push_back(new taxonomy::edge(points[1], points[2])); - loop->children.push_back(new taxonomy::edge(points[2], points[3])); - loop->children.push_back(new taxonomy::edge(points[3], points[0])); + loop->children.push_back(make(points[0], points[1])); + loop->children.push_back(make(points[1], points[2])); + loop->children.push_back(make(points[2], points[3])); + loop->children.push_back(make(points[3], points[0])); } return solid; } -ifcopenshell::geometry::taxonomy::collection * ifcopenshell::geometry::flatten(const taxonomy::collection * deep) { - auto flat = new taxonomy::collection; - visit(deep, [&flat](taxonomy::item* i) { - flat->children.push_back(i); +ifcopenshell::geometry::taxonomy::collection::ptr ifcopenshell::geometry::flatten(taxonomy::collection::ptr deep) { + auto flat = make(); + ifcopenshell::geometry::visit(deep, [&flat](taxonomy::ptr i) { + flat->children.push_back(taxonomy::cast(clone(i))); }); return flat; } diff --git a/src/ifcgeom/taxonomy.h b/src/ifcgeom/taxonomy.h index 3894e737cd..a3514fc475 100644 --- a/src/ifcgeom/taxonomy.h +++ b/src/ifcgeom/taxonomy.h @@ -4,6 +4,7 @@ #include "../ifcparse/IfcBaseClass.h" #include +#include #include @@ -12,6 +13,16 @@ #include #include +#ifndef TAXONOMY_USE_UNIQUE_PTR +#ifndef TAXONOMY_USE_NAKED_PTR +#define TAXONOMY_USE_SHARED_PTR +#endif +#endif + +#ifdef TAXONOMY_USE_SHARED_PTR +#include +#endif + // @todo don't do std::less but use hashing and cache hash values. namespace ifcopenshell { @@ -20,6 +31,55 @@ namespace geometry { namespace taxonomy { +#ifdef TAXONOMY_USE_SHARED_PTR + template + T clone(T& t) { + return t; + } + template + std::shared_ptr cast(const std::shared_ptr& u); + template + std::shared_ptr dcast(const std::shared_ptr& u); +#endif +#ifdef TAXONOMY_USE_UNIQUE_PTR + // untested currently + template + T clone(T& t) { + return t->clone_(); + } + template + T* cast(const std::unique_ptr& u); + template + T* dcast(const std::unique_ptr& u); +#endif +#ifdef TAXONOMY_USE_NAKED_PTR + // untested currently + template + T clone(T& t) { + return t->clone_(); + } + template + T* cast(const U*& u); + template + T* dcast(const U*& u); +#endif + +#ifdef TAXONOMY_USE_SHARED_PTR +#define DECLARE_PTR(item) \ +typedef std::shared_ptr ptr; \ +typedef std::shared_ptr const_ptr; +#endif +#ifdef TAXONOMY_USE_UNIQUE_PTR +#define DECLARE_PTR(item) \ +typedef std::uniqe_ptr ptr; \ +typedef std::uniqe_ptr ptr; +#endif +#ifdef TAXONOMY_USE_NAKED_PTR +#define DECLARE_PTR(item) \ +typedef item* ptr; \ +typedef item const* ptr; +#endif + class topology_error : public std::runtime_error { public: topology_error() : std::runtime_error("Generic topology error") {} @@ -34,28 +94,67 @@ struct item { private: uint32_t identity_; static std::atomic_uint32_t counter_; - + mutable size_t computed_hash_; public: + DECLARE_PTR(item) + const IfcUtil::IfcBaseInterface* instance; boost::optional orientation; - virtual item* clone() const = 0; + virtual item* clone_() const = 0; virtual kinds kind() const = 0; virtual void print(std::ostream&, int indent=0) const = 0; virtual void reverse() { throw taxonomy::topology_error(); } + virtual size_t calc_hash() const = 0; + virtual size_t hash() const { + if (computed_hash_) { + return computed_hash_; + } + computed_hash_ = calc_hash(); + if (computed_hash_ == 0) { + computed_hash_++; + } + return computed_hash_; + } - item(const IfcUtil::IfcBaseInterface* instance = nullptr) : identity_(counter_++), instance(instance) {} + item(const IfcUtil::IfcBaseInterface* instance = nullptr) : identity_(counter_++), instance(instance), computed_hash_(0) {} virtual ~item() {} uint32_t identity() const { return identity_; } }; -bool less(const item*, const item*); + +#ifdef TAXONOMY_USE_SHARED_PTR +typedef std::shared_ptr ptr; +typedef std::shared_ptr const_ptr; +template +std::shared_ptr make(Args&&... args) { + return std::make_shared(std::forward(args)...); +} +#endif +#ifdef TAXONOMY_USE_UNIQUE_PTR +typedef std::uniqe_ptr ptr; +typedef std::uniqe_ptr ptr; +template +std::uniqe_ptr make(Args&&... args) { + return new T(std::forward(args)...)); +} +#endif +#ifdef TAXONOMY_USE_NAKED_PTR +typedef item* ptr; +typedef item const* ptr; +template +T* make(Args&&... args) { + return new T(std::forward(args)...)); +} +#endif + +bool less(item::const_ptr, item::const_ptr); struct less_functor { - bool operator()(const item* a, const item* b) const { + bool operator()(item::const_ptr a, item::const_ptr b) const { return less(a, b); } }; @@ -135,6 +234,18 @@ struct eigen_base { explicit operator bool() const { return components_; } + + uint32_t hash_components() const { + size_t h = std::hash{}(T::RowsAtCompileTime); + boost::hash_combine(h, std::hash{}(T::ColsAtCompileTime)); + if (components_) { + for (size_t i = 0; i < components_->size(); ++i) { + auto elem = *(components_->data() + i); + boost::hash_combine(h, std::hash()(elem)); + } + } + return h; + } }; struct matrix4 : public item, public eigen_base { @@ -157,6 +268,7 @@ private: } } public: + DECLARE_PTR(matrix4) enum tag_t { IDENTITY, AFFINE_WO_SCALE, AFFINE_W_UNIFORM_SCALE, AFFINE_W_NONUNIFORM_SCALE, OTHER @@ -185,20 +297,32 @@ public: print_impl(o, "matrix4", indent); } - virtual item* clone() const { return new matrix4(*this); } + virtual matrix4* clone_() const { return new matrix4(*this); } virtual kinds kind() const { return MATRIX4; } + virtual size_t calc_hash() const { + auto v = std::make_tuple(static_cast(MATRIX4), hash_components()); + return boost::hash{}(v); + } + Eigen::Vector3d translation_part() const { return ccomponents().col(3).head<3>(); } }; struct colour : public item, public eigen_base { + DECLARE_PTR(colour) + void print(std::ostream& o, int indent = 0) const { print_impl(o, "colour", indent); } - virtual item* clone() const { return new colour(*this); } + virtual colour* clone_() const { return new colour(*this); } virtual kinds kind() const { return COLOUR; } + virtual size_t calc_hash() const { + auto v = std::make_tuple(static_cast(COLOUR), hash_components()); + return boost::hash{}(v); + } + colour() : eigen_base() {} colour(double r, double g, double b) { components() << r, g, b; } @@ -208,6 +332,8 @@ struct colour : public item, public eigen_base { }; struct style : public item { + DECLARE_PTR(style) + std::string name; colour diffuse; colour specular; @@ -227,9 +353,14 @@ struct style : public item { // @todo } - virtual item* clone() const { return new style(*this); } + virtual style* clone_() const { return new style(*this); } virtual kinds kind() const { return STYLE; } + virtual size_t calc_hash() const { + auto v = std::make_tuple(static_cast(STYLE), name, diffuse.hash(), specular.hash(), specularity, transparency); + return boost::hash{}(v); + } + // @todo equality implementation based on values? bool operator==(const style& other) const { return instance == other.instance; } @@ -246,12 +377,14 @@ struct style : public item { }; struct geom_item : public item { - style* surface_style; - matrix4 matrix; + DECLARE_PTR(geom_item) + + style::ptr surface_style; + matrix4::ptr matrix; geom_item(const IfcUtil::IfcBaseClass* instance = nullptr) : item(instance), surface_style(nullptr) {} - geom_item(const IfcUtil::IfcBaseClass* instance, matrix4 m) : item(instance), surface_style(nullptr), matrix(m) {} - geom_item(matrix4 m) : surface_style(nullptr), matrix(m) {} + geom_item(const IfcUtil::IfcBaseClass* instance, matrix4::ptr m) : item(instance), surface_style(nullptr), matrix(m) {} + geom_item(matrix4::ptr m) : surface_style(nullptr), matrix(m) {} }; // @todo make 4d for easier multiplication @@ -262,9 +395,16 @@ struct cartesian_base : public item, public eigen_base { }; struct point3 : public cartesian_base<3> { - virtual item* clone() const { return new point3(*this); } + DECLARE_PTR(point3) + + virtual point3* clone_() const { return new point3(*this); } virtual kinds kind() const { return POINT3; } + virtual size_t calc_hash() const { + auto v = std::make_tuple(static_cast(POINT3), hash_components()); + return boost::hash{}(v); + } + void print(std::ostream& o, int indent = 0) const { print_impl(o, "point3", indent); } @@ -274,9 +414,16 @@ struct point3 : public cartesian_base<3> { }; struct direction3 : public cartesian_base<3> { - virtual item* clone() const { return new direction3(*this); } + DECLARE_PTR(direction3) + + virtual direction3* clone_() const { return new direction3(*this); } virtual kinds kind() const { return DIRECTION3; } + virtual size_t calc_hash() const { + auto v = std::make_tuple(static_cast(DIRECTION3), hash_components()); + return boost::hash{}(v); + } + void print(std::ostream& o, int indent = 0) const { print_impl(o, "direction3", indent); } @@ -288,30 +435,44 @@ struct direction3 : public cartesian_base<3> { struct curve : public geom_item { void print_impl(std::ostream& o, const std::string& classname, int indent = 0) const { o << std::string(indent, ' ') << classname << std::endl; - this->matrix.print(o, indent + 4); + this->matrix->print(o, indent + 4); } }; struct line : public curve { - virtual item* clone() const { return new line(*this); } + DECLARE_PTR(line) + + virtual line* clone_() const { return new line(*this); } virtual kinds kind() const { return LINE; } + virtual size_t calc_hash() const { + auto v = std::make_tuple(static_cast(LINE), matrix->hash_components()); + return boost::hash{}(v); + } + void print(std::ostream& o, int indent = 0) const { print_impl(o, "line", indent); } }; struct circle : public curve { + DECLARE_PTR(circle) + double radius; - virtual item* clone() const { return new circle(*this); } + virtual circle* clone_() const { return new circle(*this); } virtual kinds kind() const { return CIRCLE; } + virtual size_t calc_hash() const { + auto v = std::make_tuple(static_cast(CIRCLE), matrix->hash_components(), radius); + return boost::hash{}(v); + } + void print(std::ostream& o, int indent = 0) const { print_impl(o, "circle", indent); } - static circle* from_3_points(const Eigen::Vector3d& p1, const Eigen::Vector3d& p2, const Eigen::Vector3d& p3) { + static circle::ptr from_3_points(const Eigen::Vector3d& p1, const Eigen::Vector3d& p2, const Eigen::Vector3d& p3) { Eigen::Vector3d t = p2 - p1; Eigen::Vector3d u = p3 - p1; Eigen::Vector3d v = p3 - p2; @@ -330,9 +491,9 @@ struct circle : public curve { auto ax = norm / std::sqrt(mag); - auto c = new circle; + auto c = make(); c->radius = radius; - c->matrix = taxonomy::matrix4(orig, ax); + c->matrix = taxonomy::make(orig, ax); return c; } @@ -341,21 +502,50 @@ struct circle : public curve { }; struct ellipse : public circle { + DECLARE_PTR(ellipse) + double radius2; - virtual item* clone() const { return new ellipse(*this); } + virtual ellipse* clone_() const { return new ellipse(*this); } virtual kinds kind() const { return ELLIPSE; } + virtual size_t calc_hash() const { + auto v = std::make_tuple(static_cast(ELLIPSE), matrix->hash_components(), radius, radius2); + return boost::hash{}(v); + } + void print(std::ostream& o, int indent = 0) const { print_impl(o, "ellipse", indent); } }; struct bspline_curve : public curve { - virtual item* clone() const { return new bspline_curve(*this); } + DECLARE_PTR(bspline_curve) + + virtual bspline_curve* clone_() const { return new bspline_curve(*this); } virtual kinds kind() const { return BSPLINE_CURVE; } - std::vector control_points; + virtual size_t calc_hash() const { + size_t h = std::hash{}(BSPLINE_CURVE); + for (auto& x : control_points) { + boost::hash_combine(h, x->hash()); + } + for (auto& x : multiplicities) { + boost::hash_combine(h, std::hash{}(x)); + } + for (auto& x : knots) { + boost::hash_combine(h, std::hash{}(x)); + } + if (weights) { + for (auto& x : *weights) { + boost::hash_combine(h, std::hash{}(x)); + } + } + boost::hash_combine(h, std::hash{}(degree)); + return h; + } + + std::vector control_points; std::vector multiplicities; std::vector knots; boost::optional> weights; @@ -367,31 +557,40 @@ struct bspline_curve : public curve { }; struct offset_curve : public curve { - direction3 reference; - double offset; - item* basis; + DECLARE_PTR(offset_curve) - virtual item* clone() const { return new offset_curve(*this); } + direction3::ptr reference; + double offset; + item::ptr basis; + + virtual offset_curve* clone_() const { return new offset_curve(*this); } virtual kinds kind() const { return OFFSET_CURVE; } + virtual size_t calc_hash() const { + auto v = std::make_tuple(static_cast(OFFSET_CURVE), reference->hash(), offset, basis ? basis->hash() : size_t(0)); + return boost::hash{}(v); + } + void print(std::ostream& o, int indent = 0) const { o << std::string(indent, ' ') << "offset_curve" << std::endl; } }; struct trimmed_curve : public item { + DECLARE_PTR(trimmed_curve) + // @todo The copy constructor of point3 within the variant fails on the avx instruction // on the default gcc in Ubuntu 18.04 and a recent AMD Ryzen. Probably due to allignment. - boost::variant start, end; + boost::variant start, end; // @todo somehow account for the fact that curve in IFC can be trimmed curve, polyline and composite curve as well. - item* basis; + item::ptr basis; // @todo does this make sense? this is to accomodate for the fact that orientation is defined on both TrimmedCurve as well CompCurveSegment boost::optional orientation_2; trimmed_curve() : basis(nullptr), orientation_2(true) {} - trimmed_curve(const point3& a, const point3& b) : start(a), end(b), basis(nullptr) {} + trimmed_curve(const point3::ptr& a, const point3::ptr& b) : start(a), end(b), basis(nullptr) {} virtual void reverse() { // std::swap(start, end); @@ -404,11 +603,11 @@ struct trimmed_curve : public item { basis->print(o, indent + 4); } - const boost::variant * const start_end[2] = { &start, &end }; + const boost::variant * const start_end[2] = { &start, &end }; for (int i = 0; i < 2; ++i) { o << std::string(indent + 4, ' ') << (i == 0 ? "start" : "end") << std::endl; if (start_end[i]->which() == 0) { - boost::get(*start_end[i]).print(o, indent + 4); + boost::get(*start_end[i])->print(o, indent + 4); } else if (start_end[i]->which() == 1) { o << std::string(indent + 4, ' ') << "parameter " << boost::get(*start_end[i]) << std::endl; } @@ -421,39 +620,47 @@ struct trimmed_curve : public item { }; struct edge : public trimmed_curve { + DECLARE_PTR(edge) + edge() : trimmed_curve() {} - edge(const point3& a, const point3& b) : trimmed_curve(a, b) {} + edge(const point3::ptr& a, const point3::ptr& b) : trimmed_curve(a, b) {} // @todo how to express similarity between trimmed_curve and edge? - virtual item* clone() const { return new edge(*this); } + virtual edge* clone_() const { return new edge(*this); } virtual kinds kind() const { return EDGE; } + + virtual size_t calc_hash() const { + auto v = std::make_tuple(static_cast(EDGE), start, end, basis ? basis->hash() : size_t(0), orientation_2 ? *orientation_2 ? 2 : 1 : 0); + return boost::hash{}(v); + } }; -// template -struct collection : public geom_item { - std::vector children; +template +struct collection_base : public geom_item { + std::vector children; - collection() {} - collection(const collection& other) { - std::transform(other.children.begin(), other.children.end(), std::back_inserter(children), std::mem_fn(&item::clone)); + collection_base() {} + collection_base(const collection_base& other) { + std::transform(other.children.begin(), other.children.end(), std::back_inserter(children), [](typename T::ptr p) { return clone(p); }); } + /* template - std::vector children_as() const { - std::vector ts; + std::vector children_as() const { + std::vector ts; ts.reserve(children.size()); - std::for_each(children.begin(), children.end(), [&ts](item* i){ - auto v = dynamic_cast(i); + std::for_each(children.begin(), children.end(), [&ts](ptr i){ + auto v = dcast(i); if (v) { ts.push_back(v); } }); return ts; } + */ - virtual item* clone() const { return new collection(*this); } - virtual kinds kind() const { return COLLECTION; } - virtual void reverse() { + virtual void reverse() { + // @todo this needs to create copies of the children in case of shared_ptr std::reverse(children.begin(), children.end()); for (auto& child : children) { child->reverse(); @@ -462,67 +669,195 @@ struct collection : public geom_item { void print(std::ostream& o, int indent = 0) const { o << std::string(indent, ' ') << kind_to_string(kind()) << std::endl; - if (!matrix.is_identity()) { - matrix.print(o, indent + 4); + if (!matrix->is_identity()) { + matrix->print(o, indent + 4); } for (auto& c : children) { c->print(o, indent + 4); } } - virtual ~collection() { + virtual ~collection_base() { +#ifdef TAXONOMY_USE_NAKED_PTR for (auto& c : children) { delete c; } +#endif + } + + uint32_t hash_elements() const { + size_t h = 0; + for (auto& c : children) { + boost::hash_combine(h, c->hash()); + } + return h; } }; -struct shell : public collection /**/ { +struct collection : public collection_base { + DECLARE_PTR(collection) + + virtual collection_base* clone_() const { return new collection(*this); } + virtual kinds kind() const { return COLLECTION; } + + virtual size_t calc_hash() const { + auto v = std::make_tuple(static_cast(COLLECTION), hash_elements()); + return boost::hash{}(v); + } +}; + + +struct loop : public collection_base { + DECLARE_PTR(loop) + + boost::optional external, closed; + + bool is_polyhedron() const { + for (auto& e : children) { + if (e->basis != nullptr) { + if (e->basis->kind() != LINE) { + return false; + } + } + } + return true; + } + + virtual loop* clone_() const { return new loop(*this); } + virtual kinds kind() const { return LOOP; } + + virtual size_t calc_hash() const { + auto v = std::make_tuple(static_cast(LOOP), hash_elements(), external ? *external ? 2 : 1 : 0, closed ? *closed ? 2 : 1 : 0); + return boost::hash{}(v); + } +}; + +struct face : public collection_base { + DECLARE_PTR(face) + + item::ptr basis; + + virtual face* clone_() const { return new face(*this); } + virtual kinds kind() const { return FACE; } + + virtual size_t calc_hash() const { + auto v = std::make_tuple(static_cast(FACE), hash_elements(), basis ? basis->hash() : size_t(0)); + return boost::hash{}(v); + } +}; + +struct shell : public collection_base { + DECLARE_PTR(shell) + boost::optional closed; - virtual item* clone() const { return new shell(*this); } + virtual shell* clone_() const { return new shell(*this); } virtual kinds kind() const { return SHELL; } + + virtual size_t calc_hash() const { + auto v = std::make_tuple(static_cast(SHELL), hash_elements(), closed ? *closed ? 2 : 1 : 0); + return boost::hash{}(v); + } }; -struct solid : public collection /**/ { - virtual item* clone() const { return new solid(*this); } +struct solid : public collection_base { + DECLARE_PTR(solid) + + virtual solid* clone_() const { return new solid(*this); } virtual kinds kind() const { return SOLID; } + + virtual size_t calc_hash() const { + auto v = std::make_tuple(static_cast(SOLID), hash_elements()); + return boost::hash{}(v); + } }; -struct loft : public collection /**/ { - item* axis; +struct loft : public collection_base { + DECLARE_PTR(loft) - virtual item* clone() const { return new loft(*this); } + item::ptr axis; + + virtual loft* clone_() const { return new loft(*this); } virtual kinds kind() const { return LOFT; } + + virtual size_t calc_hash() const { + auto v = std::make_tuple(static_cast(LOFT), hash_elements(), axis ? axis->hash() : size_t(0)); + return boost::hash{}(v); + } }; struct surface : public geom_item {}; struct plane : public surface { - virtual item* clone() const { return new plane(*this); } + DECLARE_PTR(plane) + + virtual plane* clone_() const { return new plane(*this); } virtual kinds kind() const { return PLANE; } void print(std::ostream& o, int) const { o << "not implemented"; } + + virtual size_t calc_hash() const { + auto v = std::make_tuple(static_cast(PLANE), matrix->hash_components()); + return boost::hash{}(v); + } }; struct cylinder : public surface { + DECLARE_PTR(cylinder) + double radius; - virtual item* clone() const { return new cylinder(*this); } + virtual cylinder* clone_() const { return new cylinder(*this); } virtual kinds kind() const { return CYLINDER; } void print(std::ostream& o, int) const { o << "not implemented"; } + virtual size_t calc_hash() const { + auto v = std::make_tuple(static_cast(CYLINDER), matrix->hash_components()); + return boost::hash{}(v); + } }; struct bspline_surface : public surface { - virtual item* clone() const { return new bspline_surface(*this); } + DECLARE_PTR(bspline_surface) + + virtual bspline_surface* clone_() const { return new bspline_surface(*this); } virtual kinds kind() const { return BSPLINE_SURFACE; } - std::vector> control_points; + virtual size_t calc_hash() const { + size_t h = std::hash{}(BSPLINE_SURFACE); + boost::hash_combine(h, std::hash{}(control_points.size())); + for (auto& xs : control_points) { + for (auto& x : xs) { + boost::hash_combine(h, x->hash()); + } + } + for (auto& xs : multiplicities) { + for (auto& x : xs) { + boost::hash_combine(h, std::hash{}(x)); + } + } + for (auto& xs : knots) { + for (auto& x : xs) { + boost::hash_combine(h, std::hash{}(x)); + } + } + if (weights) { + for (auto& xs : *weights) { + for (auto& x : xs) { + boost::hash_combine(h, std::hash{}(x)); + } + } + } + boost::hash_combine(h, std::hash{}(degree[0])); + boost::hash_combine(h, std::hash{}(degree[1])); + return h; + } + + std::vector> control_points; std::array, 2> multiplicities; std::array, 2> knots; boost::optional>> weights; @@ -533,99 +868,105 @@ struct bspline_surface : public surface { } }; -struct face : public collection /**/ { - item* basis; - - virtual item* clone() const { return new face(*this); } - virtual kinds kind() const { return FACE; } -}; - -struct loop : public collection /**/ { - boost::optional external, closed; - - bool is_polyhedron() const { - for (auto& e_ : children) { - auto e = (taxonomy::edge*) e_; - if (e->basis != nullptr) { - if (e->basis->kind() != LINE) { - return false; - } - } - } - return true; - } - - virtual item* clone() const { return new loop(*this); } - virtual kinds kind() const { return LOOP; } -}; - struct sweep : public geom_item { - face basis; + DECLARE_PTR(sweep) - sweep(face b) : basis(b) {} - sweep(matrix4 m, face b) : geom_item(m), basis(b) {} + face::ptr basis; + + sweep(face::ptr b) : basis(b) {} + sweep(matrix4::ptr m, face::ptr b) : geom_item(m), basis(b) {} }; struct extrusion : public sweep { - direction3 direction; + DECLARE_PTR(extrusion) + + direction3::ptr direction; double depth; - virtual item* clone() const { return new extrusion(*this); } + virtual extrusion* clone_() const { return new extrusion(*this); } virtual kinds kind() const { return EXTRUSION; } - extrusion(matrix4 m, face basis, direction3 dir, double d) : sweep(m, basis), direction(dir), depth(d) {} + extrusion(matrix4::ptr m, face::ptr basis, direction3::ptr dir, double d) : sweep(m, basis), direction(dir), depth(d) {} void print(std::ostream& o, int indent = 0) const { o << std::string(indent, ' ') << "extrusion " << depth << std::endl; - direction.print(o, indent + 4); - basis.print(o, indent + 4); + direction->print(o, indent + 4); + basis->print(o, indent + 4); + } + + virtual size_t calc_hash() const { + auto v = std::make_tuple(static_cast(EXTRUSION), matrix->hash_components(), basis->calc_hash(), direction->hash_components(), depth); + return boost::hash{}(v); } }; struct revolve : public sweep { - point3 axis_origin; - direction3 direction; + DECLARE_PTR(revolve) + + point3::ptr axis_origin; + direction3::ptr direction; boost::optional angle; - virtual item* clone() const { return new revolve(*this); } + virtual revolve* clone_() const { return new revolve(*this); } virtual kinds kind() const { return REVOLVE; } - revolve(matrix4 m, face basis, point3 pnt, direction3 dir, const boost::optional& a) : sweep(m, basis), axis_origin(pnt), direction(dir), angle(a) {} + revolve(matrix4::ptr m, face::ptr basis, point3::ptr pnt, direction3::ptr dir, const boost::optional& a) : sweep(m, basis), axis_origin(pnt), direction(dir), angle(a) {} void print(std::ostream& o, int indent = 0) const { o << std::string(indent, ' ') << "revolve" << std::endl; } + + virtual size_t calc_hash() const { + auto v = std::make_tuple(static_cast(REVOLVE), matrix->hash_components(), basis->calc_hash(), axis_origin->hash_components(), direction->hash_components(), angle ? *angle : 1000.); + return boost::hash{}(v); + } }; struct surface_curve_sweep : public sweep { - item* surface; - item* curve; + DECLARE_PTR(surface_curve_sweep) - virtual item* clone() const { return new surface_curve_sweep(*this); } + item::ptr surface; + item::ptr curve; + + virtual surface_curve_sweep* clone_() const { return new surface_curve_sweep(*this); } virtual kinds kind() const { return SURFACE_CURVE_SWEEP; } - surface_curve_sweep(matrix4 m, face basis, item* surf, item* crv) : sweep(m, basis), surface(surf), curve(crv) {} + surface_curve_sweep(matrix4::ptr m, face::ptr basis, item::ptr surf, item::ptr crv) : sweep(m, basis), surface(surf), curve(crv) {} void print(std::ostream& o, int indent = 0) const { o << std::string(indent, ' ') << "surface_curve_sweep" << std::endl; } + + virtual size_t calc_hash() const { + auto v = std::make_tuple(static_cast(SURFACE_CURVE_SWEEP), matrix->hash_components(), basis->calc_hash(), surface->calc_hash(), curve->calc_hash()); + return boost::hash{}(v); + } }; struct node : public item { - std::map representations; + DECLARE_PTR(node) - virtual item* clone() const { return new node(*this); } + // std::map representations; + + virtual node* clone_() const { return new node(*this); } virtual kinds kind() const { return NODE; } void print(std::ostream&, int = 0) const {} + + virtual size_t calc_hash() const { + auto v = std::make_tuple(static_cast(NODE)); + return boost::hash{}(v); + } }; -struct boolean_result : public collection { +struct boolean_result : public collection_base { + DECLARE_PTR(boolean_result) + enum operation_t { UNION, SUBTRACTION, INTERSECTION }; - virtual item* clone() const { return new boolean_result(*this); } + virtual boolean_result* clone_() const { return new boolean_result(*this); } virtual kinds kind() const { return BOOLEAN_RESULT; } operation_t operation; @@ -634,6 +975,11 @@ struct boolean_result : public collection { static std::string s[] = { "union"s, "subtraction"s, "intersection"s }; return s[(size_t)op]; } + + virtual size_t calc_hash() const { + auto v = std::make_tuple(static_cast(BOOLEAN_RESULT), hash_elements(), static_cast(operation)); + return boost::hash{}(v); + } }; namespace impl { @@ -663,46 +1009,174 @@ struct surfaces { static const size_t max = std::tuple_size::value; }; +// Hacks around not wanting to use if constexpr +template +class loop_to_face_upgrade { +public: + loop_to_face_upgrade(taxonomy::ptr) {} + + operator bool() const { + return false; + } + + operator taxonomy::face::ptr() const { + throw taxonomy::topology_error(); + } + + operator typename T::ptr() const { + throw taxonomy::topology_error(); + } +}; + +template <> +class loop_to_face_upgrade { +private: + boost::optional face_; +public: + loop_to_face_upgrade(taxonomy::ptr item) { + auto loop = taxonomy::dcast(item); + if (loop) { + loop->external = true; + + face_ = taxonomy::make(); + (*face_)->instance = loop->instance; + (*face_)->matrix = loop->matrix; + (*face_)->children = { taxonomy::clone(loop) }; + } + } + + operator bool() const { + return face_.is_initialized(); + } + + operator taxonomy::face::ptr() const { + return *face_; + } +}; + + +#ifdef TAXONOMY_USE_SHARED_PTR +template +std::shared_ptr cast(const std::shared_ptr& u) { + loop_to_face_upgrade upg(u); + if (upg) { + return upg; + } + return std::static_pointer_cast(u); +} +template +std::shared_ptr dcast(const std::shared_ptr& u) { + loop_to_face_upgrade upg(u); + if (upg) { + return upg; + } + return std::dynamic_pointer_cast(u); +} +#endif +#ifdef TAXONOMY_USE_UNIQUE_PTR +template +T* cast(const std::unique_ptr& u) { + loop_to_face_upgrade upg(u); + if (upg) { + return upg; + } + return static_cast(&*u); +} +template +T* dcast(const std::unique_ptr& u) { + loop_to_face_upgrade upg(u); + if (upg) { + return upg; + } + return dynamic_cast(&*u); +} +#endif +#ifdef TAXONOMY_USE_NAKED_PTR +template +T* cast(const U*& u) { + loop_to_face_upgrade upg(u); + if (upg) { + return upg; + } + return std::static_cast(u); +} +template +T* dcast(const U*& u) { + loop_to_face_upgrade upg(u); + if (upg) { + return upg; + } + return std::dynamic_cast(u); +} +#endif + } - template - void visit(const taxonomy::collection* deep, Fn fn) { - for (auto& c : deep->children) { - if (c->kind() == taxonomy::COLLECTION) { - visit((taxonomy::collection*)c, fn); + template + void visit(typename U::ptr deep, Fn fn) { + for (auto& i : deep->children) { + // @todo Sad... now that we have templated collection members, + // we can't generally use collection_base anymore as a cast target. + if (auto s = taxonomy::dcast(i)) { + visit(s, fn); + } else if (auto s = taxonomy::dcast(i)) { + visit(s, fn); + } else if (auto s = taxonomy::dcast(i)) { + visit(s, fn); + } else if (auto s = taxonomy::dcast(i)) { + visit(s, fn); + } else if (auto s = taxonomy::dcast(i)) { + visit(s, fn); + } else if (auto s = taxonomy::dcast(i)) { + visit(s, fn); + } else if (auto s = taxonomy::dcast(i)) { + visit(s, fn); } else { - fn(c); + fn(i); } } } - template - void visit_2(const taxonomy::collection* c, const Fn& fn) { + template + void visit_2(typename U::ptr c, const Fn& fn) { static_assert(std::is_same::value, "@todo Only implemented for point3"); for (auto& i : c->children) { - if (dynamic_cast(i)) { - visit_2(dynamic_cast(i), fn); - } else if (i->kind() == taxonomy::POINT3) { - fn((const taxonomy::point3*) i); - } else if (i->kind() == taxonomy::EDGE) { + // @todo Sad... now that we have templated collection members, + // we can't generally use collection_base anymore as a cast target. + if (auto s = taxonomy::dcast(i)) { + visit_2(s, fn); + } else if (auto s = taxonomy::dcast(i)) { + visit_2(s, fn); + } else if (auto s = taxonomy::dcast(i)) { + visit_2(s, fn); + } else if (auto s = taxonomy::dcast(i)) { + visit_2(s, fn); + } else if (auto s = taxonomy::dcast(i)) { + visit_2(s, fn); + } else if (auto s = taxonomy::dcast(i)) { + visit_2(s, fn); + } else if (auto s = taxonomy::dcast(i)) { + visit_2(s, fn); + } else if (auto pt = taxonomy::dcast(i)) { + fn(pt); + } else if (auto l = taxonomy::dcast(i)) { // @todo maybe make edge a collection then as well? - auto l = (const taxonomy::edge *) i; if (l->start.which() == 0) { - fn(&boost::get(l->start)); + fn(boost::get(l->start)); } if (l->end.which() == 0) { - fn(&boost::get(l->end)); + fn(boost::get(l->end)); } } } } - taxonomy::collection* flatten(const taxonomy::collection* deep); + taxonomy::collection::ptr flatten(taxonomy::collection::ptr deep); template - bool apply_predicate_to_collection(taxonomy::item* i, Fn fn) { + bool apply_predicate_to_collection(taxonomy::ptr i, Fn fn) { if (i->kind() == taxonomy::COLLECTION) { - auto c = (taxonomy::collection*) i; + auto c = taxonomy::cast(i); for (auto& child : c->children) { if (apply_predicate_to_collection(child, fn)) { return true; @@ -715,11 +1189,11 @@ struct surfaces { // @nb traverses nested collections template - taxonomy::collection* filter(taxonomy::collection* collection, Fn fn) { + taxonomy::collection::ptr filter(taxonomy::collection* collection, Fn fn) { auto filtered = new taxonomy::collection; for (auto& child : collection->children) { if (apply_predicate_to_collection(child, fn)) { - filtered->children.push_back(child->clone()); + filtered->children.push_back(clone(child)); } } if (filtered->children.empty()) { @@ -731,22 +1205,24 @@ struct surfaces { // @nb traverses nested collections template - taxonomy::collection* filter_in_place(taxonomy::collection* collection, Fn fn) { + taxonomy::collection::ptr filter_in_place(taxonomy::collection::ptr collection, Fn fn) { for (auto it = --collection->children.end(); it >= collection->children.begin(); --it) { if (!apply_predicate_to_collection(*it, fn)) { +#ifdef TAXONOMY_USE_NAKED_PTR delete *it; +#endif collection->children.erase(it); } } return collection; } - taxonomy::solid* create_box(double dx, double dy, double dz); - taxonomy::solid* create_box(double x, double y, double z, double dx, double dy, double dz); + taxonomy::solid::ptr create_box(double dx, double dy, double dz); + taxonomy::solid::ptr create_box(double x, double y, double z, double dx, double dy, double dz); struct layerset_information { std::vector thicknesses; - std::vector layers; + std::vector layers; std::vector styles; }; diff --git a/src/serializers/ColladaSerializer.cpp b/src/serializers/ColladaSerializer.cpp index b091996cf4..d43243e53a 100644 --- a/src/serializers/ColladaSerializer.cpp +++ b/src/serializers/ColladaSerializer.cpp @@ -194,7 +194,7 @@ void ColladaSerializer::ColladaExporter::ColladaScene::add( // The matrix attribute of an entity is basically a 4x3 representation of its ObjectPlacement. // Note that this placement is absolute, ie it is multiplied with all parent placements. - auto transformation_towrite = transformation.data().ccomponents(); + auto transformation_towrite = transformation.data()->ccomponents(); // If this is not the first parent, get the relative placement if (parentNodes.size() > 0) @@ -238,7 +238,7 @@ void ColladaSerializer::ColladaExporter::ColladaScene::addParent(const IfcGeom:: const IfcGeom::Transformation& parent_trsf = parent.transformation(); - auto transformation_towrite = parent_trsf.data().ccomponents(); + auto transformation_towrite = parent_trsf.data()->ccomponents(); // If this is not the first parent, get the relative placement if (parentNodes.size() > 0) { @@ -268,7 +268,7 @@ void ColladaSerializer::ColladaExporter::ColladaScene::addParent(const IfcGeom:: current_node->addMatrix(matrix_array); // Add the node to the parent stack - matrixStack.push(ifcopenshell::geometry::taxonomy::matrix4(parent_trsf.data().ccomponents().inverse())); + matrixStack.push(ifcopenshell::geometry::taxonomy::matrix4(parent_trsf.data()->ccomponents().inverse())); parentNodes.push(current_node); serializer->parentStackId.push(parent.id()); } diff --git a/src/serializers/GltfSerializer.cpp b/src/serializers/GltfSerializer.cpp index c86d331bbd..4a5b7e827d 100644 --- a/src/serializers/GltfSerializer.cpp +++ b/src/serializers/GltfSerializer.cpp @@ -164,7 +164,7 @@ void GltfSerializer::write(const IfcGeom::TriangulationElement* o) { node_array_.push_back(json_["nodes"].size()); - const auto& m = o->transformation().data().ccomponents(); + const auto& m = o->transformation().data()->ccomponents(); // nb: note that this contains the Y-UP transform as well. // @todo check const std::array matrix_flat = { diff --git a/src/serializers/HdfSerializer.cpp b/src/serializers/HdfSerializer.cpp index fe03d3fea6..f2235c5a36 100644 --- a/src/serializers/HdfSerializer.cpp +++ b/src/serializers/HdfSerializer.cpp @@ -274,12 +274,12 @@ IfcGeom::Element* HdfSerializer::read(IfcParse::IfcFile& f, const std::string& g std::string context = read_scalar_attribute(element_group, "context"); std::string unique_id = read_scalar_attribute(element_group, "unique_id"); - ifcopenshell::geometry::taxonomy::matrix4 trsf; + auto trsf = ifcopenshell::geometry::taxonomy::make(); auto placeds = element_group.openDataSet(DATASET_NAME_PLACEMENT); double m44[4][4]; placeds.read(m44, H5::PredType::NATIVE_DOUBLE); // @todo check - trsf.components() << Eigen::Map(&m44[0][0]); + trsf->components() << Eigen::Map(&m44[0][0]); auto representation_group = element_group.openGroup(representation_id_str); std::string geom_id = read_scalar_attribute(representation_group, "geom_id"); @@ -348,10 +348,10 @@ IfcGeom::Element* HdfSerializer::read(IfcParse::IfcFile& f, const std::string& g TopoDS_Shape shp = read_shape(part.shape_serialization); // @todo check - ifcopenshell::geometry::taxonomy::matrix4 matrix; - matrix.components() << Eigen::Map(&part.matrix[0][0]); + auto matrix = ifcopenshell::geometry::taxonomy::make(); + matrix->components() << Eigen::Map(&part.matrix[0][0]); - auto style_ptr = new ifcopenshell::geometry::taxonomy::style; + auto style_ptr = ifcopenshell::geometry::taxonomy::make(); read_surface_style(part.surface_style, *style_ptr); shapes.push_back(IfcGeom::ConversionResult(part.id, matrix, new ifcopenshell::geometry::OpenCascadeShape(shp), style_ptr)); @@ -362,7 +362,7 @@ IfcGeom::Element* HdfSerializer::read(IfcParse::IfcFile& f, const std::string& g for (IfcGeom::ConversionResults::iterator it = shapes.begin(); it != shapes.end(); ++it) { it->prepend(trsf); } - trsf = ifcopenshell::geometry::taxonomy::matrix4(); + trsf = ifcopenshell::geometry::taxonomy::make(); } brep_geometry = boost::shared_ptr(new IfcGeom::Representation::BRep(element_settings, geom_id, shapes)); @@ -487,7 +487,7 @@ H5::Group HdfSerializer::write(const IfcGeom::Element* o) { H5::DataSpace dataspace_4x4(2, dims_4x4); auto placement_dataset = element_group.createDataSet(DATASET_NAME_PLACEMENT, H5::PredType::NATIVE_DOUBLE, dataspace_4x4); - const auto& m = o->transformation().data().ccomponents(); + const auto& m = o->transformation().data()->ccomponents(); // @todo check, is this needed, can we use the storage of Eigen? double m44[4][4] = { { m(0,0), m(1,0), m(2,0), m(3,0) }, @@ -580,7 +580,7 @@ void HdfSerializer::write(const IfcGeom::BRepElement* o) { size_t i = 0; for (auto it = o->geometry().begin(); it != o->geometry().end(); ++it, ++i) { parts[i].id = it->ItemId(); - const auto& m = o->transformation().data().ccomponents(); + const auto& m = o->transformation().data()->ccomponents(); // @todo check, is this needed, can we use the storage of Eigen? std::array, 4> arr = { { { { m(0,0), m(1,0), m(2,0), m(3,0) } }, diff --git a/src/serializers/SvgSerializer.cpp b/src/serializers/SvgSerializer.cpp index 570a94d30c..71e1c93593 100644 --- a/src/serializers/SvgSerializer.cpp +++ b/src/serializers/SvgSerializer.cpp @@ -584,7 +584,7 @@ void SvgSerializer::write(const IfcGeom::BRepElement* brep_obj) { gp_Trsf trsf; // @todo - const auto& m = brep_obj->transformation().data().ccomponents(); + const auto& m = brep_obj->transformation().data()->ccomponents(); trsf.SetValues( m(0, 0), m(0, 1), m(0, 2), m(0, 3), m(1, 0), m(1, 1), m(1, 2), m(1, 3), @@ -1885,7 +1885,7 @@ void SvgSerializer::addTextAnnotations(const drawing_key& k) { if (object_type == "Text") { auto mapping = ifcopenshell::geometry::impl::mapping_implementations().construct(file, settings_); auto item = mapping->map(*pl); - auto matrix = (ifcopenshell::geometry::taxonomy::matrix4*) item; + auto matrix = ifcopenshell::geometry::taxonomy::cast(item); delete mapping; if (item) { gp_Trsf trsf; @@ -1895,7 +1895,9 @@ void SvgSerializer::addTextAnnotations(const drawing_key& k) { m(1, 0), m(1, 1), m(1, 2), m(1, 3), m(2, 0), m(2, 1), m(2, 2), m(2, 3) ); +#ifdef TAXONOMY_USE_NAKED_PTR delete matrix; +#endif auto v = gp_Pnt(trsf.TranslationPart()); @@ -2350,12 +2352,14 @@ void SvgSerializer::setFile(IfcParse::IfcFile* f) { IfcUtil::IfcBaseEntity* product = (IfcUtil::IfcBaseEntity*) *jt; if (!product->get("ObjectPlacement")->isNull()) { auto item = mapping->map(*product->get("ObjectPlacement")); - auto matrix = (ifcopenshell::geometry::taxonomy::matrix4*) item; + auto matrix = ifcopenshell::geometry::taxonomy::cast(item); gp_Trsf trsf; if (matrix) { // @todo shouldn't this take into account configurable section height? setSectionHeight(matrix->translation_part()(3) + 1.); +#ifdef TAXONOMY_USE_NAKED_PTR delete matrix; +#endif Logger::Warning("No building storeys encountered, used for reference:", product); return; } diff --git a/src/serializers/schema_dependent/XmlSerializer.cpp b/src/serializers/schema_dependent/XmlSerializer.cpp index ff1c46487f..3d7236d51f 100644 --- a/src/serializers/schema_dependent/XmlSerializer.cpp +++ b/src/serializers/schema_dependent/XmlSerializer.cpp @@ -126,7 +126,7 @@ boost::optional format_attribute(ifcopenshell::geometry::abstract_m } else if (e->declaration().is(IfcSchema::IfcLocalPlacement::Class())) { IfcSchema::IfcLocalPlacement* placement = e->as(); auto item = mapping->map(e); - auto matrix = (ifcopenshell::geometry::taxonomy::matrix4*) item; + auto matrix = ifcopenshell::geometry::taxonomy::cast< ifcopenshell::geometry::taxonomy::matrix4>(item); std::stringstream stream; for (int i = 1; i < 5; ++i) { @@ -138,7 +138,9 @@ boost::optional format_attribute(ifcopenshell::geometry::abstract_m } value = stream.str(); +#ifdef TAXONOMY_USE_NAKED_PTR delete item; +#endif } break; } default: