_data; public: Matrix(const ElementSettings& settings, const gp_Trsf& trsf) { // Convert the gp_Trsf into a 4x3 Matrix // 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.Value(j,i); const double matrix_value = i == 4 && settings.get(IteratorSettings::CONVERT_BACK_UNITS) ? trsf_value / settings.unit_magnitude() : trsf_value; _data.push_back(static_cast
(matrix_value)); } } } const std::vector
& data() const { return _data; }
};
template matrix_;
public:
Transformation(const ElementSettings& settings, const gp_Trsf& trsf)
: settings_(settings)
, trsf_(trsf)
, matrix_(settings, trsf)
{}
const gp_Trsf& 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()));
}
};
template & element1, const Element & element2) {
return element1.id() == element2.id();
}
// Use the id to compare, or the elevation is the elements are IfcBuildingStoreys and the elevation is set
friend bool operator < (const Element & element1, const Element & element2) {
if (element1.type() == "IfcBuildingStorey" && element2.type() == "IfcBuildingStorey") {
size_t attr_index = element1.product()->declaration().attribute_index("Elevation");
Argument* elev_attr1 = element1.product()->data().getArgument(attr_index);
Argument* elev_attr2 = element2.product()->data().getArgument(attr_index);
if (!elev_attr1->isNull() && !elev_attr2->isNull()) {
double elev1 = *elev_attr1;
double elev2 = *elev_attr2;
return elev1 < elev2;
}
}
return element1.id() < element2.id();
}
int id() const { return _id; }
int parent_id() const { return _parent_id; }
const std::string& name() const { return _name; }
const std::string& type() const { return _type; }
const std::string& guid() const { return _guid; }
const std::string& context() const { return _context; }
const std::string& unique_id() const { return _unique_id; }
const Transformation {
private:
boost::shared_ptr (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 {
const auto& trsf = this->transformation().data();
const gp_Mat& mat = trsf.HVectorialPart();
gp_Ax3 ax(trsf.TranslationPart(), mat.Column(3), mat.Column(1));
return geometry().calculate_projected_surface_area(ax, along_x, along_y, along_z);
}
private:
BRepElement(const BRepElement& other);
BRepElement& operator=(const BRepElement& other);
};
template {
private:
boost::shared_ptr< Representation::Triangulation > _geometry;
public:
const Representation::Triangulation & geometry() const { return *_geometry; }
const boost::shared_ptr< Representation::Triangulation >& geometry_pointer() const { return _geometry; }
TriangulationElement(const BRepElement & shape_model)
: Element (shape_model)
, _geometry(boost::shared_ptr (shape_model.geometry())))
{}
TriangulationElement(const Element & element, const boost::shared_ptr (element)
, _geometry(geometry)
{}
private:
TriangulationElement(const TriangulationElement& other);
TriangulationElement& operator=(const TriangulationElement& other);
};
template {
private:
Representation::Serialization* _geometry;
public:
const Representation::Serialization& geometry() const { return *_geometry; }
SerializedElement(const BRepElement & shape_model)
: Element (shape_model)
, _geometry(new Representation::Serialization(shape_model.geometry()))
{}
virtual ~SerializedElement() {
delete _geometry;
}
private:
SerializedElement(const SerializedElement& other);
SerializedElement& operator=(const SerializedElement& other);
};
}
#endif