mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-19 19:54:07 +00:00
heap alloc for eigen types for alignment issues
This commit is contained in:
@@ -72,7 +72,7 @@ void fix_spaceboundaries(IfcParse::IfcFile& f, bool no_progress, bool quiet, boo
|
||||
for (auto& e : wire->children) {
|
||||
auto edge = (taxonomy::edge*) e;
|
||||
auto p3 = boost::get<taxonomy::point3>(edge->start);
|
||||
auto p4 = ((taxonomy::geom_item*)item)->matrix.components * p3.components.homogeneous();
|
||||
auto p4 = *((taxonomy::geom_item*)item)->matrix.components * p3.components->homogeneous();
|
||||
Kernel_::Point_3 P(p4(0), p4(1), p4(2));
|
||||
elem_to_space_boundary_coords[{g1, g2}].emplace_back(P);
|
||||
}
|
||||
|
||||
@@ -132,8 +132,8 @@ void fix_storeycontainment(IfcParse::IfcFile& f, bool no_progress, bool quiet, b
|
||||
|
||||
for (auto& g : geom_object->geometry()) {
|
||||
auto s = ((ifcopenshell::geometry::CgalShape*) g.Shape())->shape();
|
||||
const auto& m = g.Placement().components;
|
||||
const auto& n = geom_object->transformation().data().components;
|
||||
const auto& m = *g.Placement().components;
|
||||
const auto& n = *geom_object->transformation().data().components;
|
||||
|
||||
const cgal_placement_t trsf(
|
||||
m(0, 0), m(0, 1), m(0, 2), m(0, 3),
|
||||
|
||||
@@ -123,8 +123,8 @@ void fix_wallconnectivity(IfcParse::IfcFile& f, bool no_progress, bool quiet, bo
|
||||
auto p0 = boost::get<taxonomy::point3>(first_vertex);
|
||||
auto p1 = boost::get<taxonomy::point3>(last_vertex);
|
||||
|
||||
auto v0 = ((taxonomy::geom_item*)item)->matrix.components * p0.components.homogeneous();
|
||||
auto v1 = ((taxonomy::geom_item*)item)->matrix.components * p1.components.homogeneous();
|
||||
auto v0 = *((taxonomy::geom_item*)item)->matrix.components * p0.components->homogeneous();
|
||||
auto v1 = *((taxonomy::geom_item*)item)->matrix.components * p1.components->homogeneous();
|
||||
|
||||
auto P0 = Kernel_::Point_3(v0(0), v0(1), v0(2));
|
||||
auto P1 = Kernel_::Point_3(v1(0), v1(1), v1(2));
|
||||
|
||||
@@ -475,8 +475,8 @@ struct intersection_validator {
|
||||
|
||||
for (auto& g : geom_object->geometry()) {
|
||||
auto s = ((ifcopenshell::geometry::CgalShape*) g.Shape())->shape();
|
||||
const auto& m = g.Placement().components;
|
||||
const auto& n = geom_object->transformation().data().components;
|
||||
const auto& m = *g.Placement().components;
|
||||
const auto& n = *geom_object->transformation().data().components;
|
||||
|
||||
const cgal_placement_t trsf(
|
||||
m(0, 0), m(0, 1), m(0, 2), m(0, 3),
|
||||
|
||||
@@ -7,8 +7,8 @@ void ifcopenshell::geometry::CgalShape::Triangulate(const settings& settings, co
|
||||
// Copy is made because triangulate_faces() does not accept a const argument
|
||||
cgal_shape_t s = shape_;
|
||||
|
||||
if (!place.components.isIdentity()) {
|
||||
const auto& m = place.components;
|
||||
if (!place.components->isIdentity()) {
|
||||
const auto& m = *place.components;
|
||||
|
||||
// @todo check
|
||||
const cgal_placement_t trsf(
|
||||
|
||||
@@ -183,17 +183,18 @@ bool CgalKernel::convert(const taxonomy::face* face, cgal_face_t& result) {
|
||||
}
|
||||
|
||||
namespace {
|
||||
// @todo obsolete?
|
||||
bool convert_curve(CgalKernel* kernel, const taxonomy::item* curve, cgal_wire_t& builder) {
|
||||
if (curve->kind() == taxonomy::EDGE) {
|
||||
auto e = (taxonomy::edge*) curve;
|
||||
if (true || e->basis == nullptr) {
|
||||
if (builder.empty()) {
|
||||
const auto& p = boost::get<taxonomy::point3>(e->start);
|
||||
cgal_point_t pnt(p.components(0), p.components(1), p.components(2));
|
||||
cgal_point_t pnt((*p.components)(0), (*p.components)(1), (*p.components)(2));
|
||||
builder.push_back(pnt);
|
||||
}
|
||||
const auto& p = boost::get<taxonomy::point3>(e->end);
|
||||
cgal_point_t pnt(p.components(0), p.components(1), p.components(2));
|
||||
cgal_point_t pnt((*p.components)(0), (*p.components)(1), (*p.components)(2));
|
||||
builder.push_back(pnt);
|
||||
} else if (e->basis->kind() == taxonomy::CIRCLE) {
|
||||
// @todo
|
||||
@@ -308,7 +309,7 @@ bool CgalKernel::convert(const taxonomy::extrusion* extrusion, cgal_shape_t &sha
|
||||
}
|
||||
// std::cout << "Face vertices: " << face.outer.size() << std::endl;
|
||||
|
||||
auto fs = extrusion->direction.components;
|
||||
auto fs = *extrusion->direction.components;
|
||||
cgal_direction_t dir(fs(0), fs(1), fs(2));
|
||||
// std::cout << "Direction: " << dir << std::endl;
|
||||
|
||||
@@ -584,7 +585,7 @@ bool CgalKernel::preprocess_boolean_operand(const IfcUtil::IfcBaseClass* log_ref
|
||||
|
||||
namespace {
|
||||
bool convert_placement(const ifcopenshell::geometry::taxonomy::matrix4& place, cgal_placement_t& trsf) {
|
||||
const auto& m = place.components;
|
||||
const auto& m = *place.components;
|
||||
|
||||
// @todo check
|
||||
trsf = cgal_placement_t(
|
||||
@@ -623,7 +624,7 @@ bool CgalKernel::convert_impl(const taxonomy::boolean_result* br, ifcopenshell::
|
||||
for (auto it = cr.begin(); it != cr.end(); ++it) {
|
||||
const cgal_shape_t& entity_shape_unlocated(((CgalShape*)it->Shape())->shape());
|
||||
cgal_shape_t entity_shape(entity_shape_unlocated);
|
||||
if (!it->Placement().components.isIdentity()) {
|
||||
if (!it->Placement().components->isIdentity()) {
|
||||
cgal_placement_t trsf;
|
||||
convert_placement(it->Placement(), trsf);
|
||||
for (auto &vertex : vertices(entity_shape)) {
|
||||
|
||||
@@ -134,8 +134,8 @@ bool OpenCascadeKernel::convert(const taxonomy::extrusion* extrusion, TopoDS_Sha
|
||||
auto trsf = gtrsf.Trsf();
|
||||
*/
|
||||
|
||||
auto fs = extrusion->direction.components.data();
|
||||
gp_Dir dir(fs[0], fs[1], fs[2]);
|
||||
const auto& fs = *extrusion->direction.components;
|
||||
gp_Dir dir(fs(0), fs(1), fs(2));
|
||||
|
||||
shape.Nullify();
|
||||
|
||||
@@ -559,17 +559,17 @@ namespace {
|
||||
}
|
||||
|
||||
curve_creation_visitor_result_type operator()(const taxonomy::line& l) {
|
||||
const auto& m = l.matrix.components;
|
||||
const auto& m = *l.matrix.components;
|
||||
return result = Handle(Geom_Curve)(new Geom_Line(convert_xyz2<gp_Pnt>(m.col(3)), convert_xyz2<gp_Dir>(m.col(0))));
|
||||
}
|
||||
|
||||
curve_creation_visitor_result_type operator()(const taxonomy::circle& c) {
|
||||
const auto& m = c.matrix.components;
|
||||
const auto& m = *c.matrix.components;
|
||||
return result = Handle(Geom_Curve)(new Geom_Circle(gp_Ax2(convert_xyz2<gp_Pnt>(m.col(3)), convert_xyz2<gp_Dir>(m.col(2)), convert_xyz2<gp_Dir>(m.col(0))), c.radius));
|
||||
}
|
||||
|
||||
curve_creation_visitor_result_type operator()(const taxonomy::ellipse& e) {
|
||||
const auto& m = e.matrix.components;
|
||||
const auto& m = *e.matrix.components;
|
||||
return result = Handle(Geom_Curve)(new Geom_Ellipse(gp_Ax2(convert_xyz2<gp_Pnt>(m.col(3)), convert_xyz2<gp_Dir>(m.col(2)), convert_xyz2<gp_Dir>(m.col(0))), e.radius, e.radius2));
|
||||
}
|
||||
|
||||
@@ -2251,7 +2251,7 @@ bool OpenCascadeKernel::flatten_shape_list(const ifcopenshell::geometry::Convers
|
||||
}
|
||||
|
||||
TopoDS_Shape OpenCascadeKernel::apply_transformation(const TopoDS_Shape& s, const taxonomy::matrix4& t) {
|
||||
if (t.components.isIdentity()) {
|
||||
if (t.components->isIdentity()) {
|
||||
return s;
|
||||
} else {
|
||||
gp_GTrsf trsf;
|
||||
@@ -2294,7 +2294,7 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::face* face, ifcopenshell::g
|
||||
}
|
||||
|
||||
// @todo boundary
|
||||
const auto& m = ((taxonomy::geom_item*)face->basis)->matrix.components;
|
||||
const auto& m = *((taxonomy::geom_item*)face->basis)->matrix.components;
|
||||
gp_Pln pln(convert_xyz2<gp_Pnt>(m.col(3)), convert_xyz2<gp_Dir>(m.col(2)));
|
||||
const gp_Pnt pnt = pln.Location().Translated(face->orientation.get_value_or(false) ? -pln.Axis().Direction() : pln.Axis().Direction());
|
||||
TopoDS_Shape shape = BRepPrimAPI_MakeHalfSpace(BRepBuilderAPI_MakeFace(pln), pnt).Solid();
|
||||
|
||||
@@ -343,14 +343,14 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcProduct* inst) {
|
||||
c->matrix = as<taxonomy::matrix4>(map(inst->ObjectPlacement()));
|
||||
|
||||
if (openings->size() && !settings_.get(settings::DISABLE_OPENING_SUBTRACTIONS) && use_body) {
|
||||
auto ci = c->matrix.components.inverse();
|
||||
auto ci = c->matrix.components->inverse();
|
||||
|
||||
IfcEntityList::ptr operands(new IfcEntityList);
|
||||
operands->push(body);
|
||||
operands->push(openings);
|
||||
auto n = map_to_collection<taxonomy::boolean_result>(this, operands);
|
||||
std::for_each(n->children.begin() + 1, n->children.end(), [&ci](taxonomy::item* i) {
|
||||
((taxonomy::geom_item*)i)->matrix.components = ci * ((taxonomy::geom_item*)i)->matrix.components;
|
||||
*((taxonomy::geom_item*)i)->matrix.components = ci * *((taxonomy::geom_item*)i)->matrix.components;
|
||||
});
|
||||
n->operation = taxonomy::boolean_result::SUBTRACTION;
|
||||
// @todo one indirection too many
|
||||
@@ -372,7 +372,7 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcAxis2Placement3D* inst) {
|
||||
Eigen::Vector3d o, axis(0, 0, 1), refDirection, X(1, 0, 0);
|
||||
{
|
||||
taxonomy::point3 v = as<taxonomy::point3>(map(inst->Location()));
|
||||
o = v.components;
|
||||
o = *v.components;
|
||||
}
|
||||
const bool hasAxis = inst->hasAxis();
|
||||
const bool hasRef = inst->hasRefDirection();
|
||||
@@ -383,12 +383,12 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcAxis2Placement3D* inst) {
|
||||
|
||||
if (hasAxis) {
|
||||
taxonomy::direction3 v = as<taxonomy::direction3>(map(inst->Axis()));
|
||||
axis = v.components;
|
||||
axis = *v.components;
|
||||
}
|
||||
|
||||
if (hasRef) {
|
||||
taxonomy::direction3 v = as<taxonomy::direction3>(map(inst->RefDirection()));
|
||||
refDirection = v.components;
|
||||
refDirection = *v.components;
|
||||
} else {
|
||||
if (acos(axis.dot(X)) > 1.e-5) {
|
||||
refDirection = { 1., 0., 0. };
|
||||
@@ -406,12 +406,12 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcAxis2Placement2D* inst) {
|
||||
Eigen::Vector3d P, axis(0, 0, 1), V(1, 0, 0);
|
||||
{
|
||||
taxonomy::point3 v = as<taxonomy::point3>(map(inst->Location()));
|
||||
P = v.components;
|
||||
P = *v.components;
|
||||
}
|
||||
const bool hasRef = inst->hasRefDirection();
|
||||
if (hasRef) {
|
||||
taxonomy::direction3 v = as<taxonomy::direction3>(map(inst->RefDirection()));
|
||||
V = v.components;
|
||||
V = *v.components;
|
||||
}
|
||||
return new taxonomy::matrix4(P, axis, V);
|
||||
}
|
||||
@@ -444,7 +444,7 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcLocalPlacement* inst) {
|
||||
if (relplacement->declaration().is(IfcSchema::IfcAxis2Placement3D::Class())) {
|
||||
taxonomy::matrix4 trsf2 = as<taxonomy::matrix4>(map(relplacement));
|
||||
// @todo check
|
||||
m4->components = trsf2.components * m4->components;
|
||||
*m4->components = *trsf2.components * *m4->components;
|
||||
}
|
||||
if (current->hasPlacementRelTo()) {
|
||||
IfcSchema::IfcObjectPlacement* parent = current->PlacementRelTo();
|
||||
@@ -489,14 +489,14 @@ IfcSchema::IfcProduct::list::ptr mapping::products_represented_by(const IfcSchem
|
||||
if (maps->size() == 1) {
|
||||
IfcSchema::IfcRepresentationMap* rmap = *maps->begin();
|
||||
taxonomy::matrix4 origin = as<taxonomy::matrix4>(map(rmap->MappingOrigin()));
|
||||
if (origin.components.isIdentity()) {
|
||||
if (origin.components->isIdentity()) {
|
||||
IfcSchema::IfcMappedItem::list::ptr items = rmap->MapUsage();
|
||||
for (IfcSchema::IfcMappedItem::list::it it = items->begin(); it != items->end(); ++it) {
|
||||
IfcSchema::IfcMappedItem* item = *it;
|
||||
if (item->StyledByItem()->size() != 0) continue;
|
||||
|
||||
taxonomy::matrix4 target = as<taxonomy::matrix4>(map(item->MappingTarget()));
|
||||
if (target.components.isIdentity()) {
|
||||
if (target.components->isIdentity()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -770,10 +770,10 @@ IfcSchema::IfcRepresentation* mapping::representation_mapped_to(const IfcSchema:
|
||||
if (item->StyledByItem()->size() == 0) {
|
||||
IfcSchema::IfcMappedItem* mapped_item = item->as<IfcSchema::IfcMappedItem>();
|
||||
taxonomy::matrix4 target = as<taxonomy::matrix4>(map(mapped_item->MappingTarget()));
|
||||
if (target.components.isIdentity()) {
|
||||
if (target.components->isIdentity()) {
|
||||
IfcSchema::IfcRepresentationMap* rmap = mapped_item->MappingSource();
|
||||
taxonomy::matrix4 origin = as<taxonomy::matrix4>(map(rmap->MappingOrigin()));
|
||||
if (origin.components.isIdentity()) {
|
||||
if (origin.components->isIdentity()) {
|
||||
representation_mapped_to = rmap->MappedRepresentation();
|
||||
}
|
||||
}
|
||||
@@ -927,7 +927,7 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcStyledItem* inst) {
|
||||
double rgb[3];
|
||||
if (process_colour(shading->SurfaceColour(), rgb)) {
|
||||
surface_style->diffuse.emplace();
|
||||
(*surface_style->diffuse).components << rgb[0], rgb[1], rgb[2];
|
||||
(*(*surface_style->diffuse).components) << rgb[0], rgb[1], rgb[2];
|
||||
}
|
||||
|
||||
if (auto rendering_style = shading->as<IfcSchema::IfcSurfaceStyleRendering>()) {
|
||||
@@ -1194,7 +1194,7 @@ namespace {
|
||||
#endif
|
||||
if (has_position) {
|
||||
taxonomy::matrix4 m = as<taxonomy::matrix4>(self->map(inst->Position()));
|
||||
m4 = m.components;
|
||||
m4 = *m.components;
|
||||
}
|
||||
|
||||
// @todo precision
|
||||
@@ -1228,10 +1228,10 @@ namespace {
|
||||
const auto& p = pps[i];
|
||||
if (p.radius && *p.radius > 0.) {
|
||||
// Position is a IfcAxis2Placement2D, so should remain 2d points
|
||||
auto p0 = boost::get<taxonomy::point3>(p.previous->start).components.head<2>();
|
||||
auto p1a = boost::get<taxonomy::point3>(p.previous->end).components.head<2>();
|
||||
auto p2 = boost::get<taxonomy::point3>(p.next->end).components.head<2>();
|
||||
auto p1b = boost::get<taxonomy::point3>(p.next->start).components.head<2>();
|
||||
auto p0 = boost::get<taxonomy::point3>(p.previous->start).components->head<2>();
|
||||
auto p1a = boost::get<taxonomy::point3>(p.previous->end).components->head<2>();
|
||||
auto p2 = boost::get<taxonomy::point3>(p.next->end).components->head<2>();
|
||||
auto p1b = boost::get<taxonomy::point3>(p.next->start).components->head<2>();
|
||||
|
||||
auto ba_ = p0 - p1a;
|
||||
auto bc_ = p2 - p1b;
|
||||
@@ -1242,8 +1242,8 @@ namespace {
|
||||
const double angle = std::acos(ba.dot(bc));
|
||||
const double inset = *p.radius / std::tan(angle / 2.);
|
||||
|
||||
boost::get<taxonomy::point3>(p.previous->end).components.head<2>() += ba * inset;
|
||||
boost::get<taxonomy::point3>(p.next->start).components.head<2>() += bc * inset;
|
||||
boost::get<taxonomy::point3>(p.previous->end).components->head<2>() += ba * inset;
|
||||
boost::get<taxonomy::point3>(p.next->start).components->head<2>() += bc * inset;
|
||||
|
||||
auto e = new taxonomy::edge;
|
||||
e->start = p.previous->end;
|
||||
@@ -1253,10 +1253,10 @@ namespace {
|
||||
|
||||
double sign = ab.head<2>().dot(bc) > 0 ? 1. : -1.;
|
||||
|
||||
auto O = boost::get<taxonomy::point3>(p.previous->end).components.head<3>() + ab * *p.radius * sign;
|
||||
auto O = boost::get<taxonomy::point3>(p.previous->end).components->head<3>() + ab * *p.radius * sign;
|
||||
|
||||
auto c = new taxonomy::circle;
|
||||
c->matrix.components = Eigen::Affine3d(Eigen::Translation3d(O)).matrix();
|
||||
*c->matrix.components = Eigen::Affine3d(Eigen::Translation3d(O)).matrix();
|
||||
c->radius = *p.radius;
|
||||
e->basis = c;
|
||||
c->orientation = sign == -1.;
|
||||
@@ -1364,7 +1364,7 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcCircleProfileDef* inst) {
|
||||
#endif
|
||||
if (has_position) {
|
||||
taxonomy::matrix4 m = as<taxonomy::matrix4>(map(inst->Position()));
|
||||
c->matrix = m.components;
|
||||
c->matrix = *m.components;
|
||||
}
|
||||
|
||||
auto e = new taxonomy::edge;
|
||||
@@ -1465,7 +1465,7 @@ namespace {
|
||||
for (int i = 1; i <= n; ++i) {
|
||||
// wrap around to the first point in case of a closed loop
|
||||
int j = (i % polygon.size()) + 1;
|
||||
double dist = (polygon.at(i - 1).components - polygon.at(j - 1).components).squaredNorm();
|
||||
double dist = (*polygon.at(i - 1).components - *polygon.at(j - 1).components).squaredNorm();
|
||||
if (dist < tol) {
|
||||
// do not remove the first or last point to
|
||||
// maintain connectivity with other wires
|
||||
@@ -1494,7 +1494,7 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcPolyline* inst) {
|
||||
});
|
||||
|
||||
const double eps = precision_ * 10;
|
||||
const bool closed_by_proximity = polygon.size() >= 3 && (polygon.front().components - polygon.back().components).norm() < eps;
|
||||
const bool closed_by_proximity = polygon.size() >= 3 && (*polygon.front().components - *polygon.back().components).norm() < eps;
|
||||
|
||||
// @todo this removes the end point, since it's identical to the beginning.
|
||||
if (closed_by_proximity) {
|
||||
@@ -1517,18 +1517,26 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcMappedItem* inst) {
|
||||
IfcSchema::IfcRepresentationMap* rmap = inst->MappingSource();
|
||||
IfcSchema::IfcAxis2Placement* placement = rmap->MappingOrigin();
|
||||
taxonomy::matrix4 trsf2 = as<taxonomy::matrix4>(map(placement));
|
||||
gtrsf.components = gtrsf.components * trsf2.components;
|
||||
*gtrsf.components = *gtrsf.components * *trsf2.components;
|
||||
|
||||
// @todo immutable for caching?
|
||||
// @todo allow for multiple levels of matrix?
|
||||
auto shapes = map(rmap->MappedRepresentation());
|
||||
for (auto& c : ((taxonomy::collection*)shapes)->children) {
|
||||
auto item = ((taxonomy::geom_item*)c);
|
||||
item->matrix.components = gtrsf.components * item->matrix.components;
|
||||
// @todo previously style was also copied.
|
||||
if (shapes == nullptr) {
|
||||
return shapes;
|
||||
}
|
||||
|
||||
return shapes;
|
||||
auto collection = new taxonomy::collection;
|
||||
collection->children.push_back(shapes);
|
||||
collection->matrix = *gtrsf.components;
|
||||
|
||||
if (shapes != nullptr) {
|
||||
for (auto& c : ((taxonomy::collection*)shapes)->children) {
|
||||
// @todo previously style was also copied.
|
||||
}
|
||||
}
|
||||
|
||||
return collection;
|
||||
}
|
||||
|
||||
taxonomy::item* mapping::map_impl(const IfcSchema::IfcCompositeCurve* inst) {
|
||||
@@ -1596,7 +1604,7 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcTrimmedCurve* inst) {
|
||||
|
||||
trim_cartesian &= has_pnts[0] && has_pnts[1];
|
||||
if (trim_cartesian) {
|
||||
if ((pnts[0].components - pnts[1].components).norm() < (2 * precision_)) {
|
||||
if ((*pnts[0].components - *pnts[1].components).norm() < (2 * precision_)) {
|
||||
Logger::Message(Logger::LOG_WARNING, "Skipping segment with length below tolerance level:", inst);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
@@ -75,11 +75,11 @@ namespace ifcopenshell { namespace geometry {
|
||||
: id(id), shape(shape->clone()) {}
|
||||
void append(const ifcopenshell::geometry::taxonomy::matrix4& trsf) {
|
||||
// @todo verify order
|
||||
placement.components = placement.components * trsf.components;
|
||||
*placement.components = *placement.components * *trsf.components;
|
||||
}
|
||||
void prepend(const ifcopenshell::geometry::taxonomy::matrix4& trsf) {
|
||||
// @todo verify order
|
||||
placement.components = trsf.components * placement.components;
|
||||
*placement.components = *trsf.components * *placement.components;
|
||||
}
|
||||
const ConversionResultShape* Shape() const { return shape; }
|
||||
const ifcopenshell::geometry::taxonomy::matrix4& Placement() const { return placement; }
|
||||
|
||||
@@ -49,14 +49,12 @@ namespace ifcopenshell { namespace geometry {
|
||||
// internally in IfcOpenShell everything is measured in meters.
|
||||
if (settings.get(settings::CONVERT_BACK_UNITS)) {
|
||||
for (int i = 0; i <= 2; ++i) {
|
||||
matrix_.components(3, i) /= settings.unit_magnitude();
|
||||
(*matrix_.components)(3, i) /= settings.unit_magnitude();
|
||||
}
|
||||
}
|
||||
}
|
||||
const ifcopenshell::geometry::taxonomy::matrix4& data() const { return matrix_; }
|
||||
const element_settings& settings() const { return settings_; }
|
||||
|
||||
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
|
||||
};
|
||||
|
||||
class Element {
|
||||
@@ -136,8 +134,6 @@ namespace ifcopenshell { namespace geometry {
|
||||
}
|
||||
|
||||
virtual ~Element() {}
|
||||
|
||||
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
|
||||
};
|
||||
|
||||
class NativeElement : public Element {
|
||||
|
||||
+122
-20
@@ -31,50 +31,90 @@ struct item {
|
||||
const IfcUtil::IfcBaseClass* instance;
|
||||
virtual item* clone() const = 0;
|
||||
virtual kinds kind() const = 0;
|
||||
virtual void print(std::ostream&, int indent=0) const = 0;
|
||||
virtual void reverse() { throw taxonomy::topology_error(); }
|
||||
|
||||
item(const IfcUtil::IfcBaseClass* instance = nullptr) : instance(instance) {}
|
||||
|
||||
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
|
||||
};
|
||||
|
||||
struct matrix4 : public item {
|
||||
template <typename T>
|
||||
struct eigen_base {
|
||||
T* components;
|
||||
|
||||
eigen_base() {
|
||||
components = new T;
|
||||
}
|
||||
|
||||
eigen_base(const eigen_base& other) {
|
||||
this->components = new T(*other.components);
|
||||
}
|
||||
|
||||
eigen_base(const T& other) {
|
||||
this->components = new T(other);
|
||||
}
|
||||
|
||||
eigen_base& operator=(const eigen_base& other) {
|
||||
if (this != &other) {
|
||||
this->components = new T(*other.components);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
void print_impl(std::ostream& o, const std::string& class_name, int indent = 0) const {
|
||||
o << std::string(indent, ' ') << class_name;
|
||||
for (size_t i = 0; i < 16; ++i) {
|
||||
o << " " << (*components)(i);
|
||||
}
|
||||
o << std::endl;
|
||||
}
|
||||
|
||||
~eigen_base() {
|
||||
delete this->components;
|
||||
}
|
||||
};
|
||||
|
||||
struct matrix4 : public item, public eigen_base<Eigen::Matrix4d> {
|
||||
enum tag_t {
|
||||
IDENTITY, AFFINE_WO_SCALE, AFFINE_W_UNIFORM_SCALE, AFFINE_W_NONUNIFORM_SCALE, OTHER
|
||||
};
|
||||
tag_t tag;
|
||||
|
||||
Eigen::Matrix4d components;
|
||||
|
||||
matrix4() : components(Eigen::Matrix4d::Identity()), tag(IDENTITY) {}
|
||||
matrix4(const Eigen::Matrix4d& c) : components(c), tag(OTHER) {}
|
||||
matrix4() : eigen_base(Eigen::Matrix4d::Identity()), tag(IDENTITY) {}
|
||||
matrix4(const Eigen::Matrix4d& c) : eigen_base(c), tag(OTHER) {}
|
||||
matrix4(const Eigen::Vector3d& o, const Eigen::Vector3d& z, const Eigen::Vector3d& x) : tag(AFFINE_WO_SCALE) {
|
||||
auto X = x.normalized();
|
||||
auto Y = z.cross(x).normalized();
|
||||
auto Z = z.normalized();
|
||||
components <<
|
||||
components = new Eigen::Matrix4d;
|
||||
(*components) <<
|
||||
X(0), Y(0), Z(0), o(0),
|
||||
X(1), Y(1), Z(1), o(1),
|
||||
X(2), Y(2), Z(2), o(2),
|
||||
0, 0, 0, 1.;
|
||||
}
|
||||
|
||||
void print(std::ostream& o, int indent = 0) const {
|
||||
print_impl(o, "matrix4", indent);
|
||||
}
|
||||
|
||||
virtual item* clone() const { return new matrix4(*this); }
|
||||
virtual kinds kind() const { return MATRIX4; }
|
||||
};
|
||||
|
||||
struct colour : public item {
|
||||
Eigen::Vector3d components;
|
||||
struct colour : public item, public eigen_base<Eigen::Vector3d> {
|
||||
void print(std::ostream& o, int indent = 0) const {
|
||||
print_impl(o, "colour", indent);
|
||||
}
|
||||
|
||||
virtual item* clone() const { return new colour(*this); }
|
||||
virtual kinds kind() const { return COLOUR; }
|
||||
|
||||
colour() : components(Eigen::Vector3d::Zero()) {}
|
||||
colour(double r, double g, double b) { components << r, g, b; }
|
||||
colour() : eigen_base(Eigen::Vector3d::Zero()) {}
|
||||
colour(double r, double g, double b) { (*components) << r, g, b; }
|
||||
|
||||
const double& r() const { return components[0]; }
|
||||
const double& g() const { return components[1]; }
|
||||
const double& b() const { return components[2]; }
|
||||
const double& r() const { return (*components)[0]; }
|
||||
const double& g() const { return (*components)[1]; }
|
||||
const double& b() const { return (*components)[2]; }
|
||||
};
|
||||
|
||||
struct style : public item {
|
||||
@@ -84,6 +124,22 @@ struct style : public item {
|
||||
boost::optional<colour> specular;
|
||||
boost::optional<double> specularity, transparency;
|
||||
|
||||
void print(std::ostream& o, int indent = 0) const {
|
||||
o << std::string(indent, ' ') << "style" << std::endl;
|
||||
if (name) {
|
||||
o << std::string(indent, ' ') << " " << "name" << (*name) << std::endl;
|
||||
}
|
||||
if (diffuse) {
|
||||
o << std::string(indent, ' ') << " " << "diffuse" << (*name) << std::endl;
|
||||
diffuse->print(o, indent + 5 + 7);
|
||||
}
|
||||
if (diffuse) {
|
||||
o << std::string(indent, ' ') << " " << "specular" << (*name) << std::endl;
|
||||
diffuse->print(o, indent + 5 + 8);
|
||||
}
|
||||
// @todo
|
||||
}
|
||||
|
||||
virtual item* clone() const { return new style(*this); }
|
||||
virtual kinds kind() const { return STYLE; }
|
||||
|
||||
@@ -105,17 +161,19 @@ struct geom_item : public item {
|
||||
};
|
||||
|
||||
template <size_t N>
|
||||
struct cartesian_base : public geom_item {
|
||||
Eigen::Vector3d components;
|
||||
|
||||
cartesian_base() : components(Eigen::Vector3d::Zero()) {}
|
||||
cartesian_base(double x, double y, double z = 0.) { components << x, y, z; }
|
||||
struct cartesian_base : public geom_item, public eigen_base<Eigen::Vector3d> {
|
||||
cartesian_base() : eigen_base(Eigen::Vector3d::Zero()) {}
|
||||
cartesian_base(double x, double y, double z = 0.) : eigen_base(Eigen::Vector3d(x, y, z)) {}
|
||||
};
|
||||
|
||||
struct point3 : public cartesian_base<3> {
|
||||
virtual item* clone() const { return new point3(*this); }
|
||||
virtual kinds kind() const { return POINT3; }
|
||||
|
||||
void print(std::ostream& o, int indent = 0) const {
|
||||
print_impl(o, "point3", indent);
|
||||
}
|
||||
|
||||
point3(double x = 0., double y = 0., double z = 0.) : cartesian_base(x, y, z) {}
|
||||
};
|
||||
|
||||
@@ -123,6 +181,10 @@ struct direction3 : public cartesian_base<3> {
|
||||
virtual item* clone() const { return new direction3(*this); }
|
||||
virtual kinds kind() const { return DIRECTION3; }
|
||||
|
||||
void print(std::ostream& o, int indent = 0) const {
|
||||
print_impl(o, "direction3", indent);
|
||||
}
|
||||
|
||||
direction3(double x = 0., double y = 0., double z = 0.) : cartesian_base(x, y, z) {}
|
||||
};
|
||||
|
||||
@@ -131,6 +193,10 @@ struct curve : public geom_item {};
|
||||
struct line : public curve {
|
||||
virtual item* clone() const { return new line(*this); }
|
||||
virtual kinds kind() const { return LINE; }
|
||||
|
||||
void print(std::ostream& o, int indent = 0) const {
|
||||
o << "not implemented";
|
||||
}
|
||||
};
|
||||
|
||||
struct circle : public curve {
|
||||
@@ -138,6 +204,10 @@ struct circle : public curve {
|
||||
|
||||
virtual item* clone() const { return new circle(*this); }
|
||||
virtual kinds kind() const { return CIRCLE; }
|
||||
|
||||
void print(std::ostream& o, int indent = 0) const {
|
||||
o << "not implemented";
|
||||
}
|
||||
};
|
||||
|
||||
struct ellipse : public circle {
|
||||
@@ -145,11 +215,19 @@ struct ellipse : public circle {
|
||||
|
||||
virtual item* clone() const { return new ellipse(*this); }
|
||||
virtual kinds kind() const { return ELLIPSE; }
|
||||
|
||||
void print(std::ostream& o, int indent = 0) const {
|
||||
o << "not implemented";
|
||||
}
|
||||
};
|
||||
|
||||
struct bspline_curve : public curve {
|
||||
virtual item* clone() const { return new bspline_curve(*this); }
|
||||
virtual kinds kind() const { return BSPLINE_CURVE; }
|
||||
|
||||
void print(std::ostream& o, int indent = 0) const {
|
||||
o << "not implemented";
|
||||
}
|
||||
};
|
||||
|
||||
struct trimmed_curve : public curve {
|
||||
@@ -167,6 +245,13 @@ struct trimmed_curve : public curve {
|
||||
// std::swap(start, end);
|
||||
orientation = !orientation;
|
||||
}
|
||||
|
||||
void print(std::ostream& o, int indent = 0) const {
|
||||
o << std::string(indent, ' ') << "trimmed_curve" << std::endl;
|
||||
if (basis) {
|
||||
basis->print(o, indent + 4);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct edge : public trimmed_curve {
|
||||
@@ -199,6 +284,13 @@ struct collection : public geom_item {
|
||||
child->reverse();
|
||||
}
|
||||
}
|
||||
|
||||
void print(std::ostream& o, int indent = 0) const {
|
||||
o << std::string(indent, ' ') << "collection" << std::endl;
|
||||
for (auto& c : children) {
|
||||
c->print(o, indent + 4);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct shell : public collection {
|
||||
@@ -213,6 +305,10 @@ struct surface : public geom_item {};
|
||||
struct plane : public surface {
|
||||
virtual item* clone() const { return new plane(*this); }
|
||||
virtual kinds kind() const { return PLANE; }
|
||||
|
||||
void print(std::ostream& o, int indent = 0) const {
|
||||
o << "not implemented";
|
||||
}
|
||||
};
|
||||
|
||||
struct face : public collection {
|
||||
@@ -244,6 +340,12 @@ struct extrusion : public sweep {
|
||||
virtual kinds kind() const { return EXTRUSION; }
|
||||
|
||||
extrusion(matrix4 m, face basis, direction3 dir, double d) : sweep(m, basis), direction(dir), depth(d) {}
|
||||
|
||||
void print(std::ostream& o, int indent = 0) const {
|
||||
o << std::string(indent, ' ') << "extrusion " << depth << std::endl;
|
||||
direction.print(o, indent + 4);
|
||||
basis.print(o, indent + 4);
|
||||
}
|
||||
};
|
||||
|
||||
struct node : public collection {
|
||||
|
||||
@@ -197,14 +197,14 @@ void ColladaSerializer::ColladaExporter::ColladaScene::add(
|
||||
// If this is not the first parent, get the relative placement
|
||||
if (parentNodes.size() > 0)
|
||||
{
|
||||
auto m4 = ifcopenshell::geometry::taxonomy::matrix4(matrixStack.top().data().components * transformation.data().components);
|
||||
auto m4 = ifcopenshell::geometry::taxonomy::matrix4(*matrixStack.top().data().components * *transformation.data().components);
|
||||
relative_trsf = new ifcopenshell::geometry::Transformation(transformation.settings(), m4);
|
||||
transformation_towrite = relative_trsf;
|
||||
}
|
||||
|
||||
// @todo verify
|
||||
|
||||
const double* m = transformation_towrite->data().components.data();
|
||||
const double* m = transformation_towrite->data().components->data();
|
||||
|
||||
double matrix_array[4][4] = {
|
||||
{ m[0], m[4], m[8], m[12] },
|
||||
@@ -251,14 +251,14 @@ void ColladaSerializer::ColladaExporter::ColladaScene::addParent(const ifcopensh
|
||||
// If this is not the first parent, get the relative placement
|
||||
if (parentNodes.size() > 0)
|
||||
{
|
||||
auto m4 = ifcopenshell::geometry::taxonomy::matrix4(matrixStack.top().data().components * parent_trsf.data().components);
|
||||
auto m4 = ifcopenshell::geometry::taxonomy::matrix4(*matrixStack.top().data().components * *parent_trsf.data().components);
|
||||
relative_trsf = new ifcopenshell::geometry::Transformation(parent_trsf.settings(), m4);
|
||||
transformation_towrite = relative_trsf;
|
||||
}
|
||||
|
||||
// @todo verify
|
||||
|
||||
const double* parentMatrix = transformation_towrite->data().components.data();
|
||||
const double* parentMatrix = transformation_towrite->data().components->data();
|
||||
|
||||
double matrix_array[4][4] = {
|
||||
{ (double)parentMatrix[0], (double)parentMatrix[3], (double)parentMatrix[6], (double)parentMatrix[9] },
|
||||
@@ -280,7 +280,7 @@ void ColladaSerializer::ColladaExporter::ColladaScene::addParent(const ifcopensh
|
||||
current_node->addMatrix(matrix_array);
|
||||
|
||||
// Add the node to the parent stack
|
||||
matrixStack.push(ifcopenshell::geometry::Transformation(parent_trsf.settings(), ifcopenshell::geometry::taxonomy::matrix4(parent_trsf.data().components.inverse())));
|
||||
matrixStack.push(ifcopenshell::geometry::Transformation(parent_trsf.settings(), ifcopenshell::geometry::taxonomy::matrix4(parent_trsf.data().components->inverse())));
|
||||
parentNodes.push(current_node);
|
||||
serializer->parentStackId.push(parent.id());
|
||||
}
|
||||
@@ -320,11 +320,11 @@ void ColladaSerializer::ColladaExporter::ColladaMaterials::ColladaEffects::write
|
||||
COLLADASW::EffectProfile effect(mSW);
|
||||
effect.setShaderType(COLLADASW::EffectProfile::LAMBERT);
|
||||
if (material.diffuse) {
|
||||
auto diffuse = material.diffuse.get().components;
|
||||
const auto& diffuse = *material.diffuse.get().components;
|
||||
effect.setDiffuse(COLLADASW::ColorOrTexture(COLLADASW::Color(diffuse[0],diffuse[1],diffuse[2])));
|
||||
}
|
||||
if (material.specular) {
|
||||
auto specular = material.specular.get().components;
|
||||
const auto& specular = *material.specular.get().components;
|
||||
effect.setSpecular(COLLADASW::ColorOrTexture(COLLADASW::Color(specular[0],specular[1],specular[2])));
|
||||
}
|
||||
if (material.specularity) {
|
||||
@@ -348,9 +348,11 @@ void ColladaSerializer::ColladaExporter::ColladaMaterials::ColladaEffects::close
|
||||
|
||||
void ColladaSerializer::ColladaExporter::ColladaMaterials::add(const ifcopenshell::geometry::taxonomy::style& material) {
|
||||
if (!contains(material)) {
|
||||
// @todo original_name
|
||||
std::string material_name = *(serializer->settings().get(SerializerSettings::USE_MATERIAL_NAMES)
|
||||
? material.name : material.name);
|
||||
// @todo original_name?
|
||||
|
||||
// @todo apparently material.name is unitialized in some cases now.
|
||||
|
||||
std::string material_name = material.name.get_value_or("missing-material");
|
||||
|
||||
if (material_name.empty()) {
|
||||
material_name = "missing-material-" + *material.name;
|
||||
|
||||
@@ -94,7 +94,7 @@ int GltfSerializer::writeMaterial(const ifcopenshell::geometry::taxonomy::style&
|
||||
base.fill(1.0);
|
||||
if (style.diffuse) {
|
||||
for (int i = 0; i < 3; ++i) {
|
||||
base[i] = style.diffuse->components[i];
|
||||
base[i] = (*style.diffuse->components)[i];
|
||||
}
|
||||
}
|
||||
if (style.transparency) {
|
||||
@@ -167,7 +167,7 @@ void GltfSerializer::write(const ifcopenshell::geometry::TriangulationElement* o
|
||||
|
||||
node_array_.push_back(json_["nodes"].size());
|
||||
|
||||
const double* m = o->transformation().data().components.data();
|
||||
const double* m = o->transformation().data().components->data();
|
||||
|
||||
// nb: note that this applies the Y-UP transform.
|
||||
const std::array<double, 16> matrix_flat = {
|
||||
|
||||
@@ -490,7 +490,7 @@ void SvgSerializer::setFile(IfcParse::IfcFile* f) {
|
||||
auto item = mapping_->map(*product->get("ObjectPlacement"));
|
||||
if (item) {
|
||||
auto matrix = (ifcopenshell::geometry::taxonomy::matrix4*) item;
|
||||
const double& Z = matrix->components(3, 2);
|
||||
const double& Z = (*matrix->components)(3, 2);
|
||||
setSectionHeight(Z + 1.);
|
||||
Logger::Warning("No building storeys encountered, used for reference:", product);
|
||||
return;
|
||||
|
||||
@@ -131,7 +131,7 @@ boost::optional<std::string> format_attribute(ifcopenshell::geometry::abstract_m
|
||||
std::stringstream stream;
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
for (int j = 0; j < 4; ++j) {
|
||||
const double trsf_value = matrix->components(j, i);
|
||||
const double trsf_value = (*matrix->components)(j, i);
|
||||
stream << trsf_value;
|
||||
if (i < 3 && j < 3) {
|
||||
stream << " ";
|
||||
|
||||
Reference in New Issue
Block a user