/******************************************************************************** * * * This file is part of IfcOpenShell. * * * * IfcOpenShell is free software: you can redistribute it and/or modify * * it under the terms of the Lesser GNU General Public License as published by * * the Free Software Foundation, either version 3.0 of the License, or * * (at your option) any later version. * * * * IfcOpenShell is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * Lesser GNU General Public License for more details. * * * * You should have received a copy of the Lesser GNU General Public License * * along with this program. If not, see . * * * ********************************************************************************/ #ifndef CGALCONVERSIONRESULT_H #define CGALCONVERSIONRESULT_H #include "../../../ifcgeom/IfcGeomElement.h" #undef Handle #include "../../../ifcgeom/kernels/cgal/nef_to_halfspace_tree.h" #define CGAL_NO_DEPRECATED_CODE #include #include #include #include #include #include #include #include #ifdef IFOPSH_SIMPLE_KERNEL #include #define Kernel_ SimpleKernel_ #define CgalShape SimpleCgalShape #define cgal_placement_t cgal_simple_placement_t #define cgal_point_t cgal_simple_point_t #define cgal_direction_t cgal_simple_direction_t #define cgal_vector_t cgal_simple_vector_t #define cgal_plane_t cgal_simple_plane_t #define cgal_curve_t cgal_simple_curve_t #define cgal_wire_t cgal_simple_wire_t #define cgal_face_t cgal_simple_face_t #define cgal_shape_t cgal_simple_shape_t #define cgal_vertex_descriptor_t cgal_simple_vertex_descriptor_t #define cgal_face_descriptor_t cgal_simple_face_descriptor_t typedef CGAL::Simple_cartesian Kernel_; #else #include #include typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel_; #endif typedef Kernel_::Aff_transformation_3 cgal_placement_t; typedef Kernel_::Point_3 cgal_point_t; typedef Kernel_::Vector_3 cgal_direction_t; typedef Kernel_::Vector_3 cgal_vector_t; typedef Kernel_::Plane_3 cgal_plane_t; typedef std::vector cgal_curve_t; typedef std::vector cgal_wire_t; namespace { struct cgal_face_t { cgal_wire_t outer; std::vector inner; }; } typedef CGAL::Polyhedron_3 cgal_shape_t; typedef boost::graph_traits>::vertex_descriptor cgal_vertex_descriptor_t; typedef boost::graph_traits>::face_descriptor cgal_face_descriptor_t; #include "../../../ifcgeom/ConversionResult.h" namespace ifcopenshell { namespace geometry { using IfcGeom::OpaqueCoordinate; using IfcGeom::OpaqueNumber; using IfcGeom::add_; using IfcGeom::subtract_; using IfcGeom::multiply_; using IfcGeom::divide_; using IfcGeom::equals_; using IfcGeom::less_than_; using IfcGeom::negate_; #ifndef IFOPSH_SIMPLE_KERNEL class IFC_GEOM_API NumberEpeck : public OpaqueNumber { private: CGAL::Epeck::FT value_; template OpaqueNumber* binary_op(OpaqueNumber* other) const { auto nnd = dynamic_cast(other); if (nnd) { return new NumberEpeck(Fn(value_, nnd->value_)); } else { return nullptr; } } template bool binary_op_bool(OpaqueNumber* other) const { auto nnd = dynamic_cast(other); if (nnd) { return Fn(value_, nnd->value_); } else { return false; } } template OpaqueNumber* unary_op() const { return new NumberEpeck(Fn(value_)); } public: NumberEpeck(const CGAL::Epeck::FT& v) : value_(v) {} virtual double to_double() const { return CGAL::to_double(value_); } const CGAL::Epeck::FT& value() const { return value_; } virtual OpaqueNumber* operator+(OpaqueNumber* other) const { return binary_op>(other); } virtual OpaqueNumber* operator-(OpaqueNumber* other) const { return binary_op>(other); } virtual OpaqueNumber* operator*(OpaqueNumber* other) const { return binary_op>(other); } virtual OpaqueNumber* operator/(OpaqueNumber* other) const { return binary_op>(other); } virtual bool operator==(OpaqueNumber* other) const { return binary_op_bool>(other); } virtual bool operator<(OpaqueNumber* other) const { return binary_op_bool>(other); } virtual OpaqueNumber* operator-() const { return unary_op>(); } }; #endif class CgalShape : public IfcGeom::ConversionResultShape { private: mutable boost::optional shape_; #ifndef IFOPSH_SIMPLE_KERNEL mutable boost::optional> nef_; #endif public: CgalShape(const cgal_shape_t& shape) { shape_ = shape; } #ifndef IFOPSH_SIMPLE_KERNEL CgalShape(const CGAL::Nef_polyhedron_3& shape) { nef_ = shape; } #endif #ifndef IFOPSH_SIMPLE_KERNEL void to_poly() const { if (!shape_) { shape_.emplace(); nef_->convert_to_polyhedron(*shape_); } } void to_nef() const { if (!nef_) { nef_.emplace(*shape_); } } operator const CGAL::Nef_polyhedron_3& () const { to_nef(); return *nef_; } const CGAL::Nef_polyhedron_3& nef() const { to_nef(); return *nef_; } #else // noop on simple kernel void to_poly() const {} #endif operator const cgal_shape_t& () const { to_poly(); return *shape_; } const cgal_shape_t& poly() const { to_poly(); return *shape_; } virtual void Triangulate(ifcopenshell::geometry::Settings settings, const ifcopenshell::geometry::taxonomy::matrix4& place, IfcGeom::Representation::Triangulation* t, int surface_style_id) const; virtual void Serialize(const ifcopenshell::geometry::taxonomy::matrix4& place, std::string&) const; virtual IfcGeom::ConversionResultShape* clone() const { return new CgalShape(*shape_); } virtual bool is_manifold() const; virtual double bounding_box(void*&) const; virtual int num_vertices() const; virtual void set_box(void*); virtual int surface_genus() const; virtual int num_edges() const; virtual int num_faces() const; // @todo this must be something with a virtual dtor so that we can delete it. virtual std::pair, OpaqueCoordinate<3>> bounding_box() const; virtual std::shared_ptr length(); virtual std::shared_ptr area(); virtual std::shared_ptr volume(); virtual OpaqueCoordinate<3> position(); virtual OpaqueCoordinate<3> axis(); virtual OpaqueCoordinate<4> plane_equation(); virtual std::vector convex_decomposition(); virtual ConversionResultShape* halfspaces(); virtual ConversionResultShape* solid(); virtual ConversionResultShape* box(); virtual std::vector edges(); virtual std::vector facets(); virtual ConversionResultShape* add(ConversionResultShape*); virtual ConversionResultShape* subtract(ConversionResultShape*); virtual ConversionResultShape* intersect(ConversionResultShape*); virtual void map(OpaqueCoordinate<4>& from, OpaqueCoordinate<4>& to); virtual ConversionResultShape* moved(ifcopenshell::geometry::taxonomy::matrix4::ptr) const; }; #ifndef IFOPSH_SIMPLE_KERNEL class CgalShapeHalfSpaceDecomposition : public IfcGeom::ConversionResultShape { private: std::unique_ptr> shape_; std::list> planes_; public: CgalShapeHalfSpaceDecomposition(const CGAL::Nef_polyhedron_3& shape) { auto shape_copy = shape; shape_ = std::move(build_halfspace_tree_decomposed(shape_copy, planes_)); } CgalShapeHalfSpaceDecomposition(const CGAL::Plane_3& shape) { shape_.reset(new halfspace_tree_plane(shape)); planes_.push_back(shape); } virtual void Triangulate(ifcopenshell::geometry::Settings settings, const ifcopenshell::geometry::taxonomy::matrix4& place, IfcGeom::Representation::Triangulation* t, int surface_style_id) const; virtual void Serialize(const ifcopenshell::geometry::taxonomy::matrix4& place, std::string&) const; virtual int surface_genus() const; virtual bool is_manifold() const; virtual int num_vertices() const; virtual int num_edges() const; virtual int num_faces() const; virtual double bounding_box(void*&) const; // @todo this must be something with a virtual dtor so that we can delete it. virtual std::pair, OpaqueCoordinate<3>> bounding_box() const; virtual void set_box(void* b); virtual std::shared_ptr length(); virtual std::shared_ptr area(); virtual std::shared_ptr volume(); virtual OpaqueCoordinate<3> position(); virtual OpaqueCoordinate<3> axis(); virtual OpaqueCoordinate<4> plane_equation(); virtual std::vector convex_decomposition(); virtual ConversionResultShape* halfspaces(); virtual ConversionResultShape* solid(); virtual ConversionResultShape* box(); virtual std::vector edges(); virtual std::vector facets(); virtual ConversionResultShape* add(ConversionResultShape*); virtual ConversionResultShape* subtract(ConversionResultShape*); virtual ConversionResultShape* intersect(ConversionResultShape*); virtual void map(OpaqueCoordinate<4>& from, OpaqueCoordinate<4>& to); virtual ConversionResultShape* moved(ifcopenshell::geometry::taxonomy::matrix4::ptr) const; }; #endif }} #endif