diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index a77db1cddf..88191a7f5b 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -610,7 +610,7 @@ if (BUILD_IFCGEOM) foreach(s ${SCHEMA_VERSIONS}) set(IFCGEOM_SCHEMA_LIBRARIES ${IFCGEOM_SCHEMA_LIBRARIES} geometry_mapping_ifc${s}) endforeach() - set(IFCOPENSHELL_LIBRARIES ${IFCOPENSHELL_LIBRARIES} IfcGeom geometry_mapping ${IFCGEOM_SCHEMA_LIBRARIES}) + set(IFCOPENSHELL_LIBRARIES ${IFCOPENSHELL_LIBRARIES} IfcGeom geometry_mappings ${IFCGEOM_SCHEMA_LIBRARIES}) endif() if (BUILD_CONVERT) foreach(s ${SCHEMA_VERSIONS}) diff --git a/src/ifcgeom/schema/mapping.cpp b/src/ifcgeom/schema/mapping.cpp index f21e58cf34..c2c74fcb27 100644 --- a/src/ifcgeom/schema/mapping.cpp +++ b/src/ifcgeom/schema/mapping.cpp @@ -648,8 +648,7 @@ namespace { } } - -IfcUtil::IfcBaseEntity* get_decomposing_entity(IfcUtil::IfcBaseEntity* inst, bool include_openings) { +IfcUtil::IfcBaseEntity* mapping::get_decomposing_entity(IfcUtil::IfcBaseEntity* inst, bool include_openings) { IfcSchema::IfcObjectDefinition* parent = 0; auto product = inst->as(); if (!product) { diff --git a/src/ifcgeom/schema_agnostic/ConversionResult.h b/src/ifcgeom/schema_agnostic/ConversionResult.h index cd967a6eee..0ccae1ccf0 100644 --- a/src/ifcgeom/schema_agnostic/ConversionResult.h +++ b/src/ifcgeom/schema_agnostic/ConversionResult.h @@ -33,59 +33,56 @@ namespace ifcopenshell { namespace geometry { // @todo, this class is no longer necessary, we can directly use // taxonomy::matrix4, which does not need to be implemented specifically // in the respective kernels + /* class IFC_GEOM_API ConversionResultPlacement { public: - virtual void Multiply(const ConversionResultPlacement*) = 0; - virtual void PreMultiply(const ConversionResultPlacement*) = 0; + virtual void Multiply(const ifcopenshell::geometry::taxonomy::matrix4&) = 0; + virtual void PreMultiply(const ifcopenshell::geometry::taxonomy::matrix4&) = 0; virtual void TranslationPart(double& X, double& Y, double& Z) const = 0; virtual ConversionResultPlacement* inverted() const = 0; - virtual ConversionResultPlacement* multiplied(const ConversionResultPlacement*) const = 0; + virtual ConversionResultPlacement* multiplied(const ifcopenshell::geometry::taxonomy::matrix4&) const = 0; virtual double Value(int i, int j) const = 0; virtual ConversionResultPlacement* clone() const = 0; virtual ~ConversionResultPlacement() {} }; + */ class IFC_GEOM_API ConversionResultShape { public: - virtual void Triangulate(const ifcopenshell::geometry::settings & settings, const ifcopenshell::geometry::ConversionResultPlacement* place, ifcopenshell::geometry::Representation::Triangulation* t, int surface_style_id) const = 0; + virtual void Triangulate(const ifcopenshell::geometry::settings & settings, const ifcopenshell::geometry::taxonomy::matrix4& place, ifcopenshell::geometry::Representation::Triangulation* t, int surface_style_id) const = 0; virtual void Serialize(std::string&) const = 0; virtual ConversionResultShape* clone() const = 0; virtual int surface_genus() const = 0; + virtual bool is_manifold() const = 0; virtual ~ConversionResultShape() {} }; class IFC_GEOM_API ConversionResult { private: int id; - ConversionResultPlacement* placement; + ifcopenshell::geometry::taxonomy::matrix4 placement; ConversionResultShape* shape; ifcopenshell::geometry::taxonomy::style style; public: - ConversionResult(int id, const ConversionResultPlacement* placement, const ConversionResultShape* shape, const ifcopenshell::geometry::taxonomy::style& style) - : id(id), placement(placement->clone()), shape(shape->clone()), style(style) {} - ConversionResult(int id, const ConversionResultPlacement* placement, const ConversionResultShape* shape) - : id(id), placement(placement->clone()), shape(shape->clone()) {} + 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()), 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), placement(0), shape(shape->clone()), style(style) {} + : id(id), shape(shape->clone()), style(style) {} ConversionResult(int id, const ConversionResultShape* shape) - : id(id), placement(0), shape(shape->clone()) {} - void append(const ConversionResultPlacement* trsf) { - if (placement == 0) { - placement = trsf->clone(); - } else { - placement->Multiply(trsf); - } + : id(id), shape(shape->clone()) {} + void append(const ifcopenshell::geometry::taxonomy::matrix4& trsf) { + // @todo verify order + placement.components = placement.components * trsf.components; } - void prepend(const ConversionResultPlacement* trsf) { - if (placement == 0) { - placement = trsf->clone(); - } else { - placement->PreMultiply(trsf); - } + void prepend(const ifcopenshell::geometry::taxonomy::matrix4& trsf) { + // @todo verify order + placement.components = trsf.components * placement.components; } const ConversionResultShape* Shape() const { return shape; } - const ConversionResultPlacement* Placement() const { return placement; } + const ifcopenshell::geometry::taxonomy::matrix4& Placement() const { return placement; } // @todo bool hasStyle() const { return style.diffuse.is_initialized(); } const ifcopenshell::geometry::taxonomy::style& Style() const { return style; } diff --git a/src/ifcgeom/schema_agnostic/IfcGeomElement.h b/src/ifcgeom/schema_agnostic/IfcGeomElement.h index d51329a342..cc8544be5f 100644 --- a/src/ifcgeom/schema_agnostic/IfcGeomElement.h +++ b/src/ifcgeom/schema_agnostic/IfcGeomElement.h @@ -28,57 +28,32 @@ #include "../../ifcgeom/schema_agnostic/IfcGeomRepresentation.h" #include "../../ifcgeom/settings.h" +#include "../../ifcgeom/taxonomy.h" #include "ifc_geom_api.h" namespace ifcopenshell { namespace geometry { - class Matrix { + class Transformation { private: - std::vector _data; + element_settings settings_; + ifcopenshell::geometry::taxonomy::matrix4 matrix_; public: - Matrix(const element_settings& settings, const ConversionResultPlacement* trsf) { - // Convert the gp_Trsf into a 4x3 Matrix + Transformation(const element_settings& settings, const ifcopenshell::geometry::taxonomy::matrix4& trsf) + : settings_(settings) + , matrix_(trsf) + { // Note that in case the CONVERT_BACK_UNITS setting is enabled // the translation component of the matrix needs to be divided // by the magnitude of the IFC model length unit because // internally in IfcOpenShell everything is measured in meters. - for(int i = 1; i < 5; ++i) { - for (int j = 1; j < 4; ++j) { - const double trsf_value = (trsf == nullptr) - ? (i == j ? 1. : 0.) - : trsf->Value(j,i); - const double matrix_value = (i == 4 && settings.get(settings::CONVERT_BACK_UNITS)) - ? trsf_value / settings.unit_magnitude() - : trsf_value; - _data.push_back(static_cast(matrix_value)); + if (settings.get(settings::CONVERT_BACK_UNITS)) { + for (int i = 0; i <= 2; ++i) { + matrix_.components(3, i) /= settings.unit_magnitude(); } } } - const std::vector& data() const { return _data; } - }; - - class Transformation { - private: - element_settings settings_; - ConversionResultPlacement* trsf_; - Matrix matrix_; - public: - Transformation(const element_settings& settings, const ConversionResultPlacement* trsf) - : settings_(settings) - , trsf_(trsf ? trsf->clone() : nullptr) - , matrix_(settings, trsf) - {} - const ConversionResultPlacement* data() const { return trsf_; } - const Matrix& matrix() const { return matrix_; } - - Transformation inverted() const { - return Transformation(settings_, trsf_->inverted()); - } - - Transformation multiplied(const Transformation& other) const { - return Transformation(settings_, trsf_->multiplied(other.data())); - } + const ifcopenshell::geometry::taxonomy::matrix4& data() const { return matrix_; } }; class Element { @@ -130,7 +105,7 @@ namespace ifcopenshell { namespace geometry { void SetParents(std::vector newparents) { _parents = newparents; } Element(const element_settings& settings, int id, int parent_id, const std::string& name, const std::string& type, - const std::string& guid, const std::string& context, const ConversionResultPlacement* trsf, IfcUtil::IfcBaseEntity* product) + const std::string& guid, const std::string& context, const ifcopenshell::geometry::taxonomy::matrix4& trsf, IfcUtil::IfcBaseEntity* product) : _id(id), _parent_id(parent_id), _name(name), _type(type), _guid(guid), _context(context), _transformation(settings, trsf) , product_(product) { @@ -166,7 +141,7 @@ namespace ifcopenshell { namespace geometry { const boost::shared_ptr& geometry_pointer() const { return _geometry; } const Representation::BRep& geometry() const { return *_geometry; } NativeElement(int id, int parent_id, const std::string& name, const std::string& type, const std::string& guid, - const std::string& context, const ConversionResultPlacement* trsf, const boost::shared_ptr& geometry, + const std::string& context, const ifcopenshell::geometry::taxonomy::matrix4& trsf, const boost::shared_ptr& geometry, IfcUtil::IfcBaseEntity* product) : Element(geometry->settings() ,id, parent_id, name, type, guid, context, trsf, product) , _geometry(geometry) diff --git a/src/ifcgeom/schema_agnostic/IfcGeomRepresentation.cpp b/src/ifcgeom/schema_agnostic/IfcGeomRepresentation.cpp index 92ce22ae93..e71ef2fad0 100644 --- a/src/ifcgeom/schema_agnostic/IfcGeomRepresentation.cpp +++ b/src/ifcgeom/schema_agnostic/IfcGeomRepresentation.cpp @@ -29,29 +29,28 @@ #include "IfcGeomRepresentation.h" #include "../../ifcgeom/schema_agnostic/opencascade/OpenCascadeConversionResult.h" -#include "../../ifcgeom/schema_agnostic/Kernel.h" -IfcGeom::Representation::Serialization::Serialization(const BRep& brep) +ifcopenshell::geometry::Representation::Serialization::Serialization(const BRep& brep) : Representation(brep.settings()) , id_(brep.id()) { - IfcGeom::ConversionResultShape* shape = brep.as_compound(); + ifcopenshell::geometry::ConversionResultShape* shape = brep.as_compound(); TopoDS_Compound compound = TopoDS::Compound(((OpenCascadeShape*) shape)->shape()); delete shape; - for (IfcGeom::ConversionResults::const_iterator it = brep.begin(); it != brep.end(); ++ it) { - if (it->hasStyle() && it->Style().Diffuse()) { - const IfcGeom::SurfaceStyle::ColorComponent& clr = *it->Style().Diffuse(); - surface_styles_.push_back(clr.R()); - surface_styles_.push_back(clr.G()); - surface_styles_.push_back(clr.B()); + for (ifcopenshell::geometry::ConversionResults::const_iterator it = brep.begin(); it != brep.end(); ++ it) { + if (it->hasStyle() && it->Style().diffuse) { + auto clr = it->Style().diffuse.get().components; + surface_styles_.push_back(clr[0]); + surface_styles_.push_back(clr[1]); + surface_styles_.push_back(clr[2]); } else { surface_styles_.push_back(-1.); surface_styles_.push_back(-1.); surface_styles_.push_back(-1.); } - if (it->hasStyle() && it->Style().Transparency()) { - surface_styles_.push_back(1. - *it->Style().Transparency()); + if (it->hasStyle() && it->Style().transparency) { + surface_styles_.push_back(1. - *it->Style().transparency); } else { surface_styles_.push_back(1.); } @@ -86,19 +85,23 @@ TopoDS_Shape apply_transformation(const TopoDS_Shape& s, const gp_GTrsf& t) { } } -IfcGeom::ConversionResultShape* IfcGeom::Representation::BRep::as_compound(bool force_meters) const { +ifcopenshell::geometry::ConversionResultShape* ifcopenshell::geometry::Representation::BRep::as_compound(bool force_meters) const { TopoDS_Compound compound; BRep_Builder builder; builder.MakeCompound(compound); - for (IfcGeom::ConversionResults::const_iterator it = begin(); it != end(); ++it) { + for (ifcopenshell::geometry::ConversionResults::const_iterator it = begin(); it != end(); ++it) { const TopoDS_Shape& s = *(OpenCascadeShape*) it->Shape(); + + // @todo, check gp_GTrsf trsf; - if (it->Placement()) { - trsf = ((OpenCascadePlacement*)it->Placement())->trsf(); + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < j; ++i) { + trsf.SetValue(i + 1, j + 1, it->Placement().components(i, j)); + } } - if (!force_meters && settings().get(IteratorSettings::CONVERT_BACK_UNITS)) { + if (!force_meters && settings().get(ifcopenshell::geometry::settings::CONVERT_BACK_UNITS)) { gp_Trsf scale; scale.SetScaleFactor(1.0 / settings().unit_magnitude()); trsf.PreMultiply(scale); @@ -195,11 +198,11 @@ namespace { } } -bool IfcGeom::Representation::BRep::calculate_surface_area(double& area) const { +bool ifcopenshell::geometry::Representation::BRep::calculate_surface_area(double& area) const { try { area = 0.; - for (IfcGeom::ConversionResults::const_iterator it = begin(); it != end(); ++it) { + for (ifcopenshell::geometry::ConversionResults::const_iterator it = begin(); it != end(); ++it) { GProp_GProps prop; BRepGProp::SurfaceProperties(*(OpenCascadeShape*)it->Shape(), prop); area += prop.Mass(); @@ -212,12 +215,12 @@ bool IfcGeom::Representation::BRep::calculate_surface_area(double& area) const { } } -bool IfcGeom::Representation::BRep::calculate_volume(double& volume) const { +bool ifcopenshell::geometry::Representation::BRep::calculate_volume(double& volume) const { try { volume = 0.; - for (IfcGeom::ConversionResults::const_iterator it = begin(); it != end(); ++it) { - if (Kernel::is_manifold(it->Shape())) { + for (ifcopenshell::geometry::ConversionResults::const_iterator it = begin(); it != end(); ++it) { + if (it->Shape()->is_manifold()) { GProp_GProps prop; BRepGProp::VolumeProperties(*(OpenCascadeShape*)it->Shape(), prop); volume += prop.Mass(); @@ -233,19 +236,26 @@ bool IfcGeom::Representation::BRep::calculate_volume(double& volume) const { } } -bool IfcGeom::Representation::BRep::calculate_projected_surface_area(const ConversionResultPlacement* place, double & along_x, double & along_y, double & along_z) const { +bool ifcopenshell::geometry::Representation::BRep::calculate_projected_surface_area(const ifcopenshell::geometry::taxonomy::matrix4& place, double & along_x, double & along_y, double & along_z) const { try { - gp_Trsf trsf = ((OpenCascadePlacement*)place)->trsf().Trsf(); - gp_Mat mat = trsf.HVectorialPart(); + // @todo check + gp_GTrsf trsf; + for (int i = 0; i < 3; ++i) { + for (int j = 0; j < j; ++i) { + trsf.SetValue(i + 1, j + 1, place.components(i, j)); + } + } + + gp_Mat mat = trsf.Trsf().HVectorialPart(); gp_Ax3 ax(trsf.TranslationPart(), mat.Column(3), mat.Column(1)); along_x = along_y = along_z = 0.; - for (IfcGeom::ConversionResults::const_iterator it = begin(); it != end(); ++it) { + for (ifcopenshell::geometry::ConversionResults::const_iterator it = begin(); it != end(); ++it) { double x, y, z; surface_area_along_direction(settings().deflection_tolerance(), *(OpenCascadeShape*)it->Shape(), ax, x, y, z); - if (Kernel::is_manifold(it->Shape())) { + if (it->Shape()->is_manifold()) { x /= 2.; y /= 2.; z /= 2.; diff --git a/src/ifcgeom/schema_agnostic/IfcGeomRepresentation.h b/src/ifcgeom/schema_agnostic/IfcGeomRepresentation.h index 2f354acc3d..62194b0749 100644 --- a/src/ifcgeom/schema_agnostic/IfcGeomRepresentation.h +++ b/src/ifcgeom/schema_agnostic/IfcGeomRepresentation.h @@ -63,7 +63,7 @@ namespace ifcopenshell { namespace geometry { bool calculate_volume(double&) const; bool calculate_surface_area(double&) const; - bool calculate_projected_surface_area(const ifcopenshell::geometry::ConversionResultPlacement* ax, double& along_x, double& along_y, double& along_z) const; + bool calculate_projected_surface_area(const ifcopenshell::geometry::taxonomy::matrix4& ax, double& along_x, double& along_y, double& along_z) const; }; class IFC_GEOM_API Serialization : public Representation { diff --git a/src/ifcgeom/schema_agnostic/opencascade/OpenCascadeConversionResult.h b/src/ifcgeom/schema_agnostic/opencascade/OpenCascadeConversionResult.h index 25d26150f9..864e7f68fe 100644 --- a/src/ifcgeom/schema_agnostic/opencascade/OpenCascadeConversionResult.h +++ b/src/ifcgeom/schema_agnostic/opencascade/OpenCascadeConversionResult.h @@ -39,47 +39,6 @@ namespace ifcopenshell { namespace geometry { - class OpenCascadePlacement : public ConversionResultPlacement { - public: - OpenCascadePlacement(const gp_GTrsf& trsf) - : trsf_(trsf) {} - - const gp_GTrsf& trsf() const { return trsf_; } - operator const gp_GTrsf& () { return trsf_; } - - virtual double Value(int i, int j) const { - return trsf_.Value(i, j); - } - - virtual void Multiply(const ConversionResultPlacement* other) { - trsf_.Multiply(((OpenCascadePlacement*)other)->trsf_); - } - - virtual void PreMultiply(const ConversionResultPlacement* other) { - trsf_.PreMultiply(((OpenCascadePlacement*)other)->trsf_); - } - - virtual ConversionResultPlacement* clone() const { - return new OpenCascadePlacement(trsf_); - } - - virtual ConversionResultPlacement* inverted() const { - return new OpenCascadePlacement(trsf_.Inverted()); - } - - virtual ConversionResultPlacement* multiplied(const ConversionResultPlacement* other) const { - return new OpenCascadePlacement(trsf_.Multiplied(((OpenCascadePlacement*)other)->trsf_)); - } - - virtual void TranslationPart(double& X, double& Y, double& Z) const { - X = trsf_.TranslationPart().X(); - Y = trsf_.TranslationPart().Y(); - Z = trsf_.TranslationPart().Z(); - } - private: - gp_GTrsf trsf_; - }; - class OpenCascadeShape : public ConversionResultShape { public: OpenCascadeShape(const TopoDS_Shape& shape) @@ -88,7 +47,7 @@ namespace ifcopenshell { const TopoDS_Shape& shape() const { return shape_; } operator const TopoDS_Shape& () { return shape_; } - virtual void Triangulate(const settings & settings, const ConversionResultPlacement * place, Representation::Triangulation* t, int surface_style_id) const; + virtual void Triangulate(const settings & settings, const ifcopenshell::geometry::taxonomy::matrix4& place, Representation::Triangulation* t, int surface_style_id) const; virtual void Serialize(std::string&) const { throw std::runtime_error("Not implemented"); @@ -98,6 +57,8 @@ namespace ifcopenshell { return new OpenCascadeShape(shape_); } + virtual bool is_manifold() const; + virtual int surface_genus() const; private: TopoDS_Shape shape_;