From 6fdf46f151f4b12712f14885ea5d269d144f9776 Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Mon, 29 Apr 2024 20:54:36 +0200 Subject: [PATCH] Add back support for IfcSphere --- src/ifcgeom/AbstractKernel.h | 1 + src/ifcgeom/kernels/opencascade/solid.cpp | 31 ++++++++++++++++++----- src/ifcgeom/mapping/IfcSphere.cpp | 24 ++++++++---------- src/ifcgeom/taxonomy.cpp | 6 ++++- src/ifcgeom/taxonomy.h | 23 ++++++++++++++--- 5 files changed, 60 insertions(+), 25 deletions(-) diff --git a/src/ifcgeom/AbstractKernel.h b/src/ifcgeom/AbstractKernel.h index c8f12cc2b2..4c05b07c5b 100644 --- a/src/ifcgeom/AbstractKernel.h +++ b/src/ifcgeom/AbstractKernel.h @@ -50,6 +50,7 @@ namespace ifcopenshell { namespace geometry { namespace kernels { 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::sphere::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"); } diff --git a/src/ifcgeom/kernels/opencascade/solid.cpp b/src/ifcgeom/kernels/opencascade/solid.cpp index 06d52be2f3..cb6c69d9df 100644 --- a/src/ifcgeom/kernels/opencascade/solid.cpp +++ b/src/ifcgeom/kernels/opencascade/solid.cpp @@ -24,6 +24,7 @@ #include #include #include +#include using namespace ifcopenshell::geometry; using namespace ifcopenshell::geometry::kernels; @@ -64,18 +65,34 @@ bool OpenCascadeKernel::convert(const taxonomy::solid::ptr solid, TopoDS_Shape& result = halfspace; return true; + } else if (solid->children.size() == 1 + && solid->children[0]->children.size() == 1 + && solid->children[0]->children[0]->basis + && solid->children[0]->children[0]->basis->kind() == taxonomy::SPHERE) + { + auto sphere = taxonomy::cast(solid->children[0]->children[0]->basis); + gp_GTrsf gtrsf; + convert(sphere->matrix, gtrsf); + BRepPrimAPI_MakeSphere builder(sphere->radius); + auto s = builder.Solid(); + s.Move(gtrsf.Trsf()); + result = s; + return true; } for (auto& s : solid->children) { TopoDS_Shape shl; - convert(s, shl); - if (shl.ShapeType() == TopAbs_SHELL) { - ShapeFix_Solid solid; - S = solid.SolidFromShell(TopoDS::Shell(shl)); - } else if (solid->children.size() == 1) { - S = shl; + if (convert(s, shl)) { + if (shl.ShapeType() == TopAbs_SHELL) { + ShapeFix_Solid solid; + S = solid.SolidFromShell(TopoDS::Shell(shl)); + } else if (solid->children.size() == 1) { + S = shl; + } else { + throw std::runtime_error("Unexpected configuration of subshapes"); + } } else { - throw std::runtime_error("Unexpected configuration of subshapes"); + Logger::Warning("Ignored shell", s->instance); } } if (!S.IsNull()) { diff --git a/src/ifcgeom/mapping/IfcSphere.cpp b/src/ifcgeom/mapping/IfcSphere.cpp index e37234d9e0..ce56c0d680 100644 --- a/src/ifcgeom/mapping/IfcSphere.cpp +++ b/src/ifcgeom/mapping/IfcSphere.cpp @@ -22,18 +22,14 @@ using namespace ifcopenshell::geometry; taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSphere* inst) { - // @todo - return nullptr; - /* - const double r = inst->Radius() * length_unit_; - - BRepPrimAPI_MakeSphere builder(r); - gp_Trsf trsf; - IfcGeom::Kernel::convert(inst->Position(),trsf); - - // IfcCsgPrimitive3D.Position has unit scale factor - shape = builder.Solid().Moved(trsf); - - return true; - */ + auto sol = taxonomy::make(); + auto shl = taxonomy::make(); + auto fac = taxonomy::make(); + auto spr = taxonomy::make(); + spr->matrix = taxonomy::cast(map(inst->Position())); + spr->radius = inst->Radius() * length_unit_; + fac->basis = spr; + shl->children.push_back(fac); + sol->children.push_back(shl); + return sol; } diff --git a/src/ifcgeom/taxonomy.cpp b/src/ifcgeom/taxonomy.cpp index c987da3acb..2c94820255 100644 --- a/src/ifcgeom/taxonomy.cpp +++ b/src/ifcgeom/taxonomy.cpp @@ -149,6 +149,10 @@ namespace { throw std::runtime_error("not implemented"); } + bool compare(const sphere&, const sphere&) { + throw std::runtime_error("not implemented"); + } + bool compare(const surface_curve_sweep&, const surface_curve_sweep&) { throw std::runtime_error("not implemented"); } @@ -512,7 +516,7 @@ const std::string& ifcopenshell::geometry::taxonomy::kind_to_string(kinds k) { using namespace std::string_literals; static std::string values[] = { - "matrix4"s, "point3"s, "direction3"s, "line"s, "circle"s, "ellipse"s, "bspline_curve"s, "offset_curve"s, "plane"s, "cylinder"s, "bspline_surface"s, "edge"s, "loop"s, "face"s, "shell"s, "solid"s, "loft"s, "extrusion"s, "revolve"s, "surface_curve_sweep"s, "node"s, "collection"s, "boolean_result"s, "piecewise_function"s, "colour"s, "style"s, + "matrix4"s, "point3"s, "direction3"s, "line"s, "circle"s, "ellipse"s, "bspline_curve"s, "offset_curve"s, "plane"s, "cylinder"s, "sphere"s, "bspline_surface"s, "edge"s, "loop"s, "face"s, "shell"s, "solid"s, "loft"s, "extrusion"s, "revolve"s, "surface_curve_sweep"s, "node"s, "collection"s, "boolean_result"s, "piecewise_function"s, "colour"s, "style"s, }; return values[k]; diff --git a/src/ifcgeom/taxonomy.h b/src/ifcgeom/taxonomy.h index 7ffa57816c..ee0bf04687 100644 --- a/src/ifcgeom/taxonomy.h +++ b/src/ifcgeom/taxonomy.h @@ -90,7 +90,7 @@ typedef item const* ptr; topology_error(const char* const s) : std::runtime_error(s) {} }; - enum kinds { MATRIX4, POINT3, DIRECTION3, LINE, CIRCLE, ELLIPSE, BSPLINE_CURVE, OFFSET_CURVE, PLANE, CYLINDER, BSPLINE_SURFACE, EDGE, LOOP, FACE, SHELL, SOLID, LOFT, EXTRUSION, REVOLVE, SURFACE_CURVE_SWEEP, NODE, COLLECTION, BOOLEAN_RESULT, PIECEWISE_FUNCTION, COLOUR, STYLE }; + enum kinds { MATRIX4, POINT3, DIRECTION3, LINE, CIRCLE, ELLIPSE, BSPLINE_CURVE, OFFSET_CURVE, PLANE, CYLINDER, SPHERE, BSPLINE_SURFACE, EDGE, LOOP, FACE, SHELL, SOLID, LOFT, EXTRUSION, REVOLVE, SURFACE_CURVE_SWEEP, NODE, COLLECTION, BOOLEAN_RESULT, PIECEWISE_FUNCTION, COLOUR, STYLE }; const std::string& kind_to_string(kinds k); @@ -875,6 +875,23 @@ typedef item const* ptr; } }; + struct sphere : public surface { + DECLARE_PTR(sphere) + + double radius; + + virtual sphere* clone_() const { return new sphere(*this); } + virtual kinds kind() const { return SPHERE; } + + void print(std::ostream& o, int) const { + o << "not implemented"; + } + virtual size_t calc_hash() const { + auto v = std::make_tuple(static_cast(SPHERE), matrix->hash_components()); + return boost::hash{}(v); + } + }; + struct bspline_surface : public surface { DECLARE_PTR(bspline_surface) @@ -1037,9 +1054,9 @@ typedef item const* ptr; }; namespace impl { - typedef std::tuple KindsTuple; + typedef std::tuple KindsTuple; typedef std::tuple CurvesTuple; - typedef std::tuple SurfacesTuple; + typedef std::tuple SurfacesTuple; } struct type_by_kind {