diff --git a/src/ifcgeom/kernel_agnostic/AbstractKernel.h b/src/ifcgeom/kernel_agnostic/AbstractKernel.h index 0985b23745..3b3021b42f 100644 --- a/src/ifcgeom/kernel_agnostic/AbstractKernel.h +++ b/src/ifcgeom/kernel_agnostic/AbstractKernel.h @@ -48,6 +48,7 @@ namespace ifcopenshell { namespace geometry { namespace kernels { virtual bool convert_impl(const taxonomy::bspline*, ifcopenshell::geometry::ConversionResults&) { throw std::runtime_error("Not implemented"); } virtual bool convert_impl(const taxonomy::edge*, ifcopenshell::geometry::ConversionResults&) { throw std::runtime_error("Not implemented"); } virtual bool convert_impl(const taxonomy::loop*, ifcopenshell::geometry::ConversionResults&) { throw std::runtime_error("Not implemented"); } + virtual bool convert_impl(const taxonomy::shell*, ifcopenshell::geometry::ConversionResults&) { throw std::runtime_error("Not implemented"); } virtual bool convert_impl(const taxonomy::face*, ifcopenshell::geometry::ConversionResults&) { throw std::runtime_error("Not implemented"); } virtual bool convert_impl(const taxonomy::extrusion*, ifcopenshell::geometry::ConversionResults&) { throw std::runtime_error("Not implemented"); } virtual bool convert_impl(const taxonomy::node*, ifcopenshell::geometry::ConversionResults&) { throw std::runtime_error("Not implemented"); } diff --git a/src/ifcgeom/kernels/opencascade/IfcGeomShapes.cpp b/src/ifcgeom/kernels/opencascade/IfcGeomShapes.cpp index df2abbefe9..672789fc41 100644 --- a/src/ifcgeom/kernels/opencascade/IfcGeomShapes.cpp +++ b/src/ifcgeom/kernels/opencascade/IfcGeomShapes.cpp @@ -106,33 +106,33 @@ #include #include "../../../ifcparse/IfcLogger.h" +#include "../../../ifcgeom/kernels/opencascade/OpenCascadeConversionResult.h" using namespace ifcopenshell::geometry; using namespace ifcopenshell::geometry::kernels; -bool OpenCascadeKernel::convert(const taxonomy::extrusion& extrusion, TopoDS_Shape& shape) { - const double& height = extrusion.depth; +bool OpenCascadeKernel::convert(const taxonomy::extrusion* extrusion, TopoDS_Shape& shape) { + const double& height = extrusion->depth; if (height < precision_) { - Logger::Error("Non-positive extrusion height encountered for:", extrusion.instance); + Logger::Error("Non-positive extrusion height encountered for:", extrusion->instance); return false; } TopoDS_Shape face; - if (!convert(extrusion.basis, face)) { + if (!convert(&extrusion->basis, face)) { return false; } - gp_Trsf trsf; - if (!convert(extrusion.matrix, trsf)) { + gp_GTrsf gtrsf; + if (!convert(&extrusion->matrix, gtrsf)) { Logger::Error("Unable to move extrusion"); } + auto trsf = gtrsf.Trsf(); + + auto fs = extrusion->direction.components.data(); + gp_Dir dir(fs[0], fs[1], fs[2]); - gp_Dir dir; - if (!convert(extrusion.direction, dir)) { - return false; - } - shape.Nullify(); if (face.ShapeType() == TopAbs_COMPOUND) { @@ -169,3 +169,27 @@ bool OpenCascadeKernel::convert(const taxonomy::extrusion& extrusion, TopoDS_Sha return !shape.IsNull(); } + +bool OpenCascadeKernel::convert_impl(const taxonomy::extrusion* extrusion, ifcopenshell::geometry::ConversionResults& results) { + TopoDS_Shape shape; + if (!convert(extrusion, shape)) { + return false; + } + results.emplace_back(ConversionResult( + extrusion->instance->data().id(), + extrusion->matrix, + new OpenCascadeShape(shape), + extrusion->surface_style + )); + return true; +} + +bool OpenCascadeKernel::convert(const taxonomy::matrix4* matrix, gp_GTrsf& trsf) { + // @todo check + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < 4; ++i) { + trsf.SetValue(i + 1, j + 1, matrix->components(i, j)); + } + } + return true; +} \ No newline at end of file diff --git a/src/ifcgeom/kernels/opencascade/OpenCascadeConversionResult.cpp b/src/ifcgeom/kernels/opencascade/OpenCascadeConversionResult.cpp index 9478a64c15..6e45b00859 100644 --- a/src/ifcgeom/kernels/opencascade/OpenCascadeConversionResult.cpp +++ b/src/ifcgeom/kernels/opencascade/OpenCascadeConversionResult.cpp @@ -12,7 +12,7 @@ void ifcopenshell::geometry::OpenCascadeShape::Triangulate(const settings& setti // @todo check gp_GTrsf trsf; for (int i = 0; i < 3; ++i) { - for (int j = 0; j < j; ++i) { + for (int j = 0; j < 4; ++i) { trsf.SetValue(i + 1, j + 1, place.components(i, j)); } } diff --git a/src/ifcgeom/kernels/opencascade/OpenCascadeKernel.h b/src/ifcgeom/kernels/opencascade/OpenCascadeKernel.h index 0d5b37dfe6..ffce0fa956 100644 --- a/src/ifcgeom/kernels/opencascade/OpenCascadeKernel.h +++ b/src/ifcgeom/kernels/opencascade/OpenCascadeKernel.h @@ -111,7 +111,6 @@ namespace kernels { class IFC_GEOM_API OpenCascadeKernel : public AbstractKernel { private: - /* // faceset_helper traverses the forward instance references of IfcConnectedFaceSet and then provides a mapping // M of (IfcCartesianPoint, IfcCartesianPoint) -> TopoDS_Edge, where M(a, b) is a partner of M(b, a), ie share // the same underlying edge but with orientation reversed. This then later speeds op the process of creating a @@ -120,22 +119,22 @@ namespace kernels { class faceset_helper { private: OpenCascadeKernel* kernel_; - std::set duplicates_; + std::set duplicates_; std::map vertex_mapping_; std::map, TopoDS_Edge> edges_; double eps_; bool non_manifold_; template - void loop_(IfcSchema::IfcCartesianPoint::list::ptr& ps, const Fn& callback) { - if (ps->size() < 3) { + void loop_(const taxonomy::loop* ps, const Fn& callback) { + if (ps->children.size() < 3) { return; } - auto a = *(ps->end() - 1); + auto a = boost::get(((taxonomy::edge*) ps->children.back())->start).instance; auto A = a->data().id(); - for (auto& b : *ps) { - auto B = b->data().id(); + for (auto& b : ps->children) { + auto B = boost::get(((taxonomy::edge*) b)->start).instance->data().id(); auto C = vertex_mapping_[A], D = vertex_mapping_[B]; bool fwd = C < D; if (!fwd) { @@ -148,16 +147,16 @@ namespace kernels { } } public: - faceset_helper(OpenCascadeKernel* kernel, const IfcSchema::IfcConnectedFaceSet* l); + faceset_helper(OpenCascadeKernel* kernel, const taxonomy::shell* l); ~faceset_helper(); bool non_manifold() const { return non_manifold_; } bool& non_manifold() { return non_manifold_; } - bool edge(const IfcSchema::IfcCartesianPoint* a, const IfcSchema::IfcCartesianPoint* b, TopoDS_Edge& e) { - int A = vertex_mapping_[a->data().id()]; - int B = vertex_mapping_[b->data().id()]; + bool edge(const taxonomy::point3& a, const taxonomy::point3& b, TopoDS_Edge& e) { + int A = vertex_mapping_[a.instance->data().id()]; + int B = vertex_mapping_[b.instance->data().id()]; if (A == B) { return false; } @@ -174,15 +173,14 @@ namespace kernels { return true; } - bool wire(const IfcSchema::IfcPolyLoop* loop, TopoDS_Wire& wire) { - if (duplicates_.find(loop) != duplicates_.end()) { + bool wire(const taxonomy::loop* loop, TopoDS_Wire& wire) { + if (duplicates_.find(loop->instance->data().id()) != duplicates_.end()) { return false; } BRep_Builder builder; builder.MakeWire(wire); int count = 0; - auto ps = loop->Polygon(); - loop_(ps, [this, &builder, &wire, &count](int A, int B, bool fwd) { + loop_(loop, [this, &builder, &wire, &count](int A, int B, bool fwd) { TopoDS_Edge e; if (edge(A, B, e)) { if (!fwd) { @@ -195,12 +193,15 @@ namespace kernels { if (count >= 3) { wire.Closed(true); + /* + @todo TopTools_ListOfShape results; if (kernel_->wire_intersections(wire, results)) { Logger::Warning("Self-intersections with " + boost::lexical_cast(results.Extent()) + " cycles detected", loop); kernel_->select_largest(results, wire); non_manifold_ = true; } + */ return true; } else { @@ -213,13 +214,12 @@ namespace kernels { } }; +/* #ifndef NO_CACHE POSTFIX_SCHEMA(Cache) cache; #endif */ - class faceset_helper {}; - faceset_helper* faceset_helper_; double precision_; @@ -233,10 +233,12 @@ namespace kernels { *this = other; } - bool convert(const geometry::taxonomy::extrusion&, TopoDS_Shape&); - bool convert(const geometry::taxonomy::face&, TopoDS_Shape&); - bool convert(const geometry::taxonomy::matrix4&, gp_Trsf&); - bool convert(const geometry::taxonomy::direction3&, gp_Dir&); + bool convert(const taxonomy::extrusion*, TopoDS_Shape&); + bool convert(const taxonomy::face*, TopoDS_Shape&); + bool convert(const taxonomy::matrix4*, gp_GTrsf&); + + virtual bool convert_impl(const taxonomy::shell*, ifcopenshell::geometry::ConversionResults&); + virtual bool convert_impl(const taxonomy::extrusion*, ifcopenshell::geometry::ConversionResults&); }; /* diff --git a/src/ifcgeom/schema_agnostic/IfcGeomRepresentation.cpp b/src/ifcgeom/schema_agnostic/IfcGeomRepresentation.cpp index fcca0ad6be..28605992df 100644 --- a/src/ifcgeom/schema_agnostic/IfcGeomRepresentation.cpp +++ b/src/ifcgeom/schema_agnostic/IfcGeomRepresentation.cpp @@ -96,7 +96,7 @@ ifcopenshell::geometry::ConversionResultShape* ifcopenshell::geometry::Represent // @todo, check gp_GTrsf trsf; for (int i = 0; i < 3; ++i) { - for (int j = 0; j < j; ++i) { + for (int j = 0; j < 4; ++i) { trsf.SetValue(i + 1, j + 1, it->Placement().components(i, j)); } } @@ -241,7 +241,7 @@ bool ifcopenshell::geometry::Representation::BRep::calculate_projected_surface_a // @todo check gp_GTrsf trsf; for (int i = 0; i < 3; ++i) { - for (int j = 0; j < j; ++i) { + for (int j = 0; j < 4; ++i) { trsf.SetValue(i + 1, j + 1, place.components(i, j)); } }