From 7b26d6d541396b85bdc66b870d6b97009496a574 Mon Sep 17 00:00:00 2001 From: Thomas Krijnen Date: Wed, 30 Sep 2020 13:52:57 +0200 Subject: [PATCH] try to reduce memory footprint --- src/ifcconvert/validate_space_boundaries.cpp | 2 +- .../validate_storey_containment.cpp | 4 +- src/ifcconvert/validate_wall_connectivity.cpp | 4 +- src/ifcconvert/validation_utils.h | 4 +- .../kernels/cgal/CgalConversionResult.cpp | 4 +- src/ifcgeom/kernels/cgal/CgalKernel.cpp | 77 +++++----- .../kernels/opencascade/IfcGeomShapes.cpp | 23 +-- .../OpenCascadeConversionResult.cpp | 37 +++-- src/ifcgeom/schema/bind_convert_impl.i | 2 +- src/ifcgeom/schema/mapping.cpp | 103 +++++++------ .../schema_agnostic/ConversionResult.h | 16 +- src/ifcgeom/schema_agnostic/IfcGeomElement.h | 2 +- .../schema_agnostic/IfcGeomRepresentation.cpp | 45 +++--- src/ifcgeom/schema_agnostic/SurfaceStyle.cpp | 34 +++-- src/ifcgeom/taxonomy.cpp | 37 +++-- src/ifcgeom/taxonomy.h | 138 ++++++++++++------ src/serializers/ColladaSerializer.cpp | 46 +++--- src/serializers/GltfSerializer.cpp | 24 ++- src/serializers/SvgSerializer.cpp | 2 +- src/serializers/WavefrontObjSerializer.cpp | 29 ++-- .../schema_dependent/XmlSerializer.cpp | 2 +- 21 files changed, 354 insertions(+), 281 deletions(-) diff --git a/src/ifcconvert/validate_space_boundaries.cpp b/src/ifcconvert/validate_space_boundaries.cpp index 0f660e5901..cecbe4f658 100644 --- a/src/ifcconvert/validate_space_boundaries.cpp +++ b/src/ifcconvert/validate_space_boundaries.cpp @@ -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(edge->start); - auto p4 = *((taxonomy::geom_item*)item)->matrix.components * p3.components->homogeneous(); + auto p4 = ((taxonomy::geom_item*)item)->matrix.ccomponents() * p3.ccomponents().homogeneous(); Kernel_::Point_3 P(p4(0), p4(1), p4(2)); elem_to_space_boundary_coords[{g1, g2}].emplace_back(P); } diff --git a/src/ifcconvert/validate_storey_containment.cpp b/src/ifcconvert/validate_storey_containment.cpp index c003291230..31c68a3c18 100644 --- a/src/ifcconvert/validate_storey_containment.cpp +++ b/src/ifcconvert/validate_storey_containment.cpp @@ -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().ccomponents(); + const auto& n = geom_object->transformation().data().ccomponents(); const cgal_placement_t trsf( m(0, 0), m(0, 1), m(0, 2), m(0, 3), diff --git a/src/ifcconvert/validate_wall_connectivity.cpp b/src/ifcconvert/validate_wall_connectivity.cpp index 28de1f22e3..c851a1702e 100644 --- a/src/ifcconvert/validate_wall_connectivity.cpp +++ b/src/ifcconvert/validate_wall_connectivity.cpp @@ -123,8 +123,8 @@ void fix_wallconnectivity(IfcParse::IfcFile& f, bool no_progress, bool quiet, bo auto p0 = boost::get(first_vertex); auto p1 = boost::get(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.ccomponents() * p0.ccomponents().homogeneous(); + auto v1 = ((taxonomy::geom_item*)item)->matrix.ccomponents() * p1.ccomponents().homogeneous(); auto P0 = Kernel_::Point_3(v0(0), v0(1), v0(2)); auto P1 = Kernel_::Point_3(v1(0), v1(1), v1(2)); diff --git a/src/ifcconvert/validation_utils.h b/src/ifcconvert/validation_utils.h index ecf4a876a4..39ed3b88a9 100644 --- a/src/ifcconvert/validation_utils.h +++ b/src/ifcconvert/validation_utils.h @@ -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().ccomponents(); + const auto& n = geom_object->transformation().data().ccomponents(); const cgal_placement_t trsf( m(0, 0), m(0, 1), m(0, 2), m(0, 3), diff --git a/src/ifcgeom/kernels/cgal/CgalConversionResult.cpp b/src/ifcgeom/kernels/cgal/CgalConversionResult.cpp index 6a7bfbd1b3..4d59b2af46 100644 --- a/src/ifcgeom/kernels/cgal/CgalConversionResult.cpp +++ b/src/ifcgeom/kernels/cgal/CgalConversionResult.cpp @@ -8,8 +8,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.is_identity()) { + const auto& m = place.ccomponents(); // @todo check const cgal_placement_t trsf( diff --git a/src/ifcgeom/kernels/cgal/CgalKernel.cpp b/src/ifcgeom/kernels/cgal/CgalKernel.cpp index 99e5cfdf20..ccbb85bc72 100644 --- a/src/ifcgeom/kernels/cgal/CgalKernel.cpp +++ b/src/ifcgeom/kernels/cgal/CgalKernel.cpp @@ -171,7 +171,7 @@ bool CgalKernel::convert(const taxonomy::shell* l, cgal_shape_t& shape) { ); size_t num_points = 0; visit(l, [&minmax, &num_points](const taxonomy::point3* p) { - auto& c = *p->components; + auto& c = p->ccomponents(); ++num_points; for (int i = 0; i < 3; ++i) { if (c(i) < minmax.first(i)) { @@ -271,11 +271,11 @@ namespace { if (true || e->basis == nullptr) { if (builder.empty()) { const auto& p = boost::get(e->start); - cgal_point_t pnt((*p.components)(0), (*p.components)(1), (*p.components)(2)); + cgal_point_t pnt(p.ccomponents()(0), p.ccomponents()(1), p.ccomponents()(2)); builder.push_back(pnt); } const auto& p = boost::get(e->end); - cgal_point_t pnt((*p.components)(0), (*p.components)(1), (*p.components)(2)); + cgal_point_t pnt(p.ccomponents()(0), p.ccomponents()(1), p.ccomponents()(2)); builder.push_back(pnt); } else if (e->basis->kind() == taxonomy::CIRCLE) { // @todo @@ -305,32 +305,32 @@ namespace { void evaluate_curve(const taxonomy::line& c, double u, taxonomy::point3& p) { Eigen::Vector4d xy{ u, 0, 0, 1. }; - *p.components = (*c.matrix.components * xy).head<3>(); + p.components() = (c.matrix.ccomponents() * xy).head<3>(); } void evaluate_curve(const taxonomy::circle& c, double u, taxonomy::point3& p) { Eigen::Vector4d xy{ c.radius * std::cos(u), c.radius * std::sin(u), 0, 1. }; - *p.components = (*c.matrix.components * xy).head<3>(); + p.components() = (c.matrix.ccomponents() * xy).head<3>(); } void evaluate_curve(const taxonomy::ellipse& c, double u, taxonomy::point3& p) { Eigen::Vector4d xy{ c.radius * std::cos(u), c.radius2 * std::sin(u), 0, 1. }; - *p.components = (*c.matrix.components * xy).head<3>(); + p.components() = (c.matrix.ccomponents() * xy).head<3>(); } // ---- void project_onto_curve(const taxonomy::line& c, const taxonomy::point3& p, double& u) { - u = (c.matrix.components->inverse() * p.components->homogeneous())(0); + u = (c.matrix.ccomponents().inverse() * p.ccomponents().homogeneous())(0); } void project_onto_curve(const taxonomy::circle& c, const taxonomy::point3& p, double& u) { - Eigen::Vector2d xy = (c.matrix.components->inverse() * p.components->homogeneous()).head<2>(); + Eigen::Vector2d xy = (c.matrix.ccomponents().inverse() * p.ccomponents().homogeneous()).head<2>(); u = std::atan2(xy(1), xy(0)); } void project_onto_curve(const taxonomy::ellipse& c, const taxonomy::point3& p, double& u) { - Eigen::Vector2d xy = (c.matrix.components->inverse() * p.components->homogeneous()).head<2>(); + Eigen::Vector2d xy = (c.matrix.ccomponents().inverse() * p.ccomponents().homogeneous()).head<2>(); u = std::atan2(xy(1), xy(0)); } @@ -468,7 +468,7 @@ namespace { if (b.empty()) { return; } - double d = (*a.back().components - *b.front().components).norm(); + double d = (a.back().ccomponents() - b.front().ccomponents()).norm(); size_t offset = d < 1.e-5 ? 1 : 0; a.insert(a.end(), b.begin() + offset, b.end()); } @@ -553,7 +553,7 @@ namespace { auto edges = loop->children_as(); for (auto& e : edges) { auto& p = boost::get(e->start); - CGAL::Point_2 pnt((*p.components)(0), (*p.components)(1)); + CGAL::Point_2 pnt(p.ccomponents()(0), p.ccomponents()(1)); polygon.push_back(pnt); } return polygon; @@ -667,7 +667,7 @@ bool CgalKernel::convert(const taxonomy::loop* loop, cgal_wire_t& result) { if (points.size() >= 2) { // the edges -> conversion left us with a duplicate global begin,end point. - double d = (*points.back().components - *points.front().components).norm(); + double d = (points.back().ccomponents() - points.front().ccomponents()).norm(); if (d < 1.e-5) { points.erase(points.end() - 1); } else { @@ -678,7 +678,7 @@ bool CgalKernel::convert(const taxonomy::loop* loop, cgal_wire_t& result) { // Parse and store the points in a sequence cgal_wire_t polygon = std::vector(); for (auto& p : points) { - cgal_point_t pnt((*p.components)(0), (*p.components)(1), (*p.components)(2)); + cgal_point_t pnt(p.ccomponents()(0), p.ccomponents()(1), p.ccomponents()(2)); polygon.push_back(pnt); } @@ -854,7 +854,7 @@ bool CgalKernel::process_extrusion(const cgal_face_t& bottom_face, const taxonom face_list.push_back(cgal_face_t{ w }); - auto& fs = *direction.components; + auto& fs = direction.ccomponents(); cgal_direction_t dir(fs(0), fs(1), fs(2)); int si = 0; @@ -1155,7 +1155,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.ccomponents(); // @todo check trsf = cgal_placement_t( @@ -1190,14 +1190,14 @@ bool CgalKernel::process_as_2d_polygon(const taxonomy::boolean_result* br, std:: if (op->kind() != taxonomy::COLLECTION) return nptr; auto cl = (taxonomy::collection*) op; if ((cl)->children.size() != 1) return nptr; - m4 = new Eigen::Matrix4d(*cl->matrix.components); + m4 = new Eigen::Matrix4d(cl->matrix.ccomponents()); if (cl->children[0]->kind() == taxonomy::COLLECTION) { cl = (taxonomy::collection*) cl->children[0]; if ((cl)->children.size() != 1) { delete m4; return nptr; } - (*m4) = (*m4) * *cl->matrix.components; + (*m4) = (*m4) * cl->matrix.ccomponents(); } if (cl->children[0]->kind() != taxonomy::EXTRUSION) { delete m4; @@ -1218,7 +1218,7 @@ bool CgalKernel::process_as_2d_polygon(const taxonomy::boolean_result* br, std:: if (std::find_if(extrusions.begin(), extrusions.end(), [&Z](extrusion_pair& p) { // @todo factor in p.first; auto ex = p.second; - auto& m = *ex->matrix.components; + auto& m = ex->matrix.ccomponents(); return std::abs(1. - std::abs(m.col(2).head<3>().dot(Z))) > 1.e-5; }) != extrusions.end()) { return false; @@ -1227,8 +1227,8 @@ bool CgalKernel::process_as_2d_polygon(const taxonomy::boolean_result* br, std:: // | op[i].matrix[2,0:3] . op[i].direction | = 1 if (std::find_if(extrusions.begin(), extrusions.end(), [](extrusion_pair& p) { auto ex = p.second; - auto& d = *ex->direction.components; - auto& m = *ex->matrix.components; + auto& d = ex->direction.ccomponents(); + auto& m = ex->matrix.ccomponents(); return std::abs(1. - std::abs(m.col(2).head<3>().dot(d))) > 1.e-5; }) != extrusions.end()) { return false; @@ -1243,10 +1243,10 @@ bool CgalKernel::process_as_2d_polygon(const taxonomy::boolean_result* br, std:: return false; } - const auto& op_0_matrix_2_3 = (*extrusions[0].second->matrix.components)(2, 3); + const auto& op_0_matrix_2_3 = extrusions[0].second->matrix.ccomponents()(2, 3); if (std::find_if(extrusions.begin() + 1, extrusions.end(), [&op_0_matrix_2_3](extrusion_pair& p) { auto ex = p.second; - return op_0_matrix_2_3 < (*ex->matrix.components)(2, 3); + return op_0_matrix_2_3 < ex->matrix.components()(2, 3); }) != extrusions.end()) { return false; } @@ -1295,9 +1295,9 @@ bool CgalKernel::process_as_2d_polygon(const taxonomy::boolean_result* br, std:: loops.clear(); std::transform(wires.begin(), wires.end(), std::back_inserter(loops), wire_to_polygon_2); - auto& op_0_matrix = *extrusions[0].second->matrix.components; + auto& op_0_matrix = extrusions[0].second->matrix.ccomponents(); Eigen::Vector4d op_0_dir; - op_0_dir << (*extrusions[0].second->direction.components), 0; + op_0_dir << extrusions[0].second->direction.ccomponents(), 0; op_0_dir = op_0_matrix * op_0_dir; z0 = op_0_matrix_2_3; z1 = z0 + extrusions[0].second->depth * op_0_dir(2); @@ -1423,7 +1423,7 @@ bool CgalKernel::process_as_2d_polygon(const std::list void project_onto_plane(const taxonomy::plane& p, It i, It j, Fn fn) { - auto mi = p.matrix.components->inverse(); + auto mi = p.matrix.ccomponents().inverse(); Eigen::Vector4d v; std::for_each(i, j, [&mi, &v, &fn](const cgal_shape_t& shp) { for (auto& vv : vertices(shp)) { @@ -1444,11 +1444,11 @@ bool CgalKernel::convert_impl(const taxonomy::boolean_result* br, ifcopenshell:: std::list> loops; if (process_as_2d_polygon(br, loops, z0, z1)) { - taxonomy::style first_item_style; + taxonomy::style* first_item_style = nullptr; { auto gi = dynamic_cast(br->children[0]); while (gi) { - if (gi->surface_style.diffuse) { + if (gi->surface_style) { first_item_style = gi->surface_style; break; } @@ -1524,7 +1524,7 @@ bool CgalKernel::convert_impl(const taxonomy::boolean_result* br, ifcopenshell:: br->instance->data().id(), br->matrix, new CgalShape(shp), - br->surface_style.diffuse ? br->surface_style : first_item_style + br->surface_style ? br->surface_style : first_item_style ); }); @@ -1541,7 +1541,7 @@ bool CgalKernel::convert_impl(const taxonomy::boolean_result* br, ifcopenshell:: CGAL::Nef_nary_union_3> second_operand_collector; size_t second_operand_collector_size = 0; - taxonomy::style first_item_style; + taxonomy::style* first_item_style = nullptr; std::list>> operands; @@ -1627,7 +1627,8 @@ bool CgalKernel::convert_impl(const taxonomy::boolean_result* br, ifcopenshell:: if (first && br->operation == taxonomy::boolean_result::SUBTRACTION) { first_item_style = ((taxonomy::geom_item*)c)->surface_style; - if (!first_item_style.diffuse && c->kind() == taxonomy::COLLECTION) { + if (!first_item_style && c->kind() == taxonomy::COLLECTION) { + // @todo recursively right? first_item_style = ((taxonomy::geom_item*) ((taxonomy::collection*)c)->children[0])->surface_style; } } @@ -1635,23 +1636,11 @@ 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().is_identity()) { cgal_placement_t trsf; convert_placement(it->Placement(), trsf); for (auto &vertex : vertices(entity_shape)) { - if (false) { - auto x = CGAL::to_double(vertex->point().x()); - auto y = CGAL::to_double(vertex->point().y()); - auto z = CGAL::to_double(vertex->point().z()); - std::wcout << x << " " << y << " " << z << std::endl; - } vertex->point() = vertex->point().transform(trsf); - if (false) { - auto x = CGAL::to_double(vertex->point().x()); - auto y = CGAL::to_double(vertex->point().y()); - auto z = CGAL::to_double(vertex->point().z()); - std::wcout << x << " " << y << " " << z << std::endl; - } } } operands.back().second.push_back(entity_shape); @@ -1720,7 +1709,7 @@ bool CgalKernel::convert_impl(const taxonomy::boolean_result* br, ifcopenshell:: br->instance->data().id(), br->matrix, new CgalShape(a_poly), - br->surface_style.diffuse ? br->surface_style : first_item_style + br->surface_style ? br->surface_style : first_item_style )); return true; } diff --git a/src/ifcgeom/kernels/opencascade/IfcGeomShapes.cpp b/src/ifcgeom/kernels/opencascade/IfcGeomShapes.cpp index 00505beb23..02aee40e49 100644 --- a/src/ifcgeom/kernels/opencascade/IfcGeomShapes.cpp +++ b/src/ifcgeom/kernels/opencascade/IfcGeomShapes.cpp @@ -134,7 +134,7 @@ bool OpenCascadeKernel::convert(const taxonomy::extrusion* extrusion, TopoDS_Sha auto trsf = gtrsf.Trsf(); */ - const auto& fs = *extrusion->direction.components; + const auto& fs = extrusion->direction.ccomponents(); gp_Dir dir(fs(0), fs(1), fs(2)); shape.Nullify(); @@ -514,7 +514,7 @@ bool OpenCascadeKernel::convert(const taxonomy::face* face, TopoDS_Shape& result namespace { template T convert_xyz(const U& u) { - const auto& vs = *u.components; + const auto& vs = u.ccomponents(); return T(vs(0), vs(1), vs(2)); } @@ -536,17 +536,17 @@ namespace { } curve_creation_visitor_result_type operator()(const taxonomy::line& l) { - const auto& m = *l.matrix.components; + const auto& m = l.matrix.ccomponents(); return result = Handle(Geom_Curve)(new Geom_Line(convert_xyz2(m.col(3)), convert_xyz2(m.col(0)))); } curve_creation_visitor_result_type operator()(const taxonomy::circle& c) { - const auto& m = *c.matrix.components; + const auto& m = c.matrix.ccomponents(); return result = Handle(Geom_Curve)(new Geom_Circle(gp_Ax2(convert_xyz2(m.col(3)), convert_xyz2(m.col(2)), convert_xyz2(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.ccomponents(); return result = Handle(Geom_Curve)(new Geom_Ellipse(gp_Ax2(convert_xyz2(m.col(3)), convert_xyz2(m.col(2)), convert_xyz2(m.col(0))), e.radius, e.radius2)); } @@ -926,7 +926,7 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::shell *shell, ifcopenshell: bool OpenCascadeKernel::convert(const taxonomy::matrix4* matrix, gp_GTrsf& trsf) { // @todo check - const auto& m = *matrix->components; + const auto& m = matrix->ccomponents(); gp_Mat mat( m(0, 0), m(0, 1), m(0, 2), m(1, 0), m(1, 1), m(1, 2), @@ -2134,7 +2134,7 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::boolean_result* br, ifcopen TopoDS_Shape a; TopTools_ListOfShape b; - taxonomy::style first_item_style; + taxonomy::style* first_item_style = nullptr; for (auto& c : br->children) { // AbstractKernel::convert(c, results); @@ -2147,7 +2147,8 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::boolean_result* br, ifcopen // @todo A will be null on union/intersection, intended? flatten_shape_list(cr, a, false); first_item_style = ((taxonomy::geom_item*)c)->surface_style; - if (!first_item_style.diffuse && c->kind() == taxonomy::COLLECTION) { + if (!first_item_style && c->kind() == taxonomy::COLLECTION) { + // @todo recursively right? first_item_style = ((taxonomy::geom_item*) ((taxonomy::collection*)c)->children[0])->surface_style; } } else { @@ -2188,7 +2189,7 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::boolean_result* br, ifcopen br->instance->data().id(), br->matrix, new OpenCascadeShape(r), - br->surface_style.diffuse ? br->surface_style : first_item_style + br->surface_style ? br->surface_style : first_item_style )); return true; } @@ -2268,7 +2269,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.is_identity()) { return s; } else { gp_GTrsf trsf; @@ -2311,7 +2312,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.ccomponents(); gp_Pln pln(convert_xyz2(m.col(3)), convert_xyz2(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(); diff --git a/src/ifcgeom/kernels/opencascade/OpenCascadeConversionResult.cpp b/src/ifcgeom/kernels/opencascade/OpenCascadeConversionResult.cpp index 1d02b90c11..3f9fd90e16 100644 --- a/src/ifcgeom/kernels/opencascade/OpenCascadeConversionResult.cpp +++ b/src/ifcgeom/kernels/opencascade/OpenCascadeConversionResult.cpp @@ -10,11 +10,13 @@ namespace { // We bypass the conversion to gp_GTrsf, because it does not work void taxonomy_transform(const Eigen::Matrix4d* m, gp_XYZ& xyz) { - Eigen::Vector4d v(xyz.X(), xyz.Y(), xyz.Z(), 1.0); - auto v2 = (*m * v).eval(); - xyz.ChangeData()[0] = v2(0); - xyz.ChangeData()[1] = v2(1); - xyz.ChangeData()[2] = v2(2); + if (m) { + Eigen::Vector4d v(xyz.X(), xyz.Y(), xyz.Z(), 1.0); + auto v2 = (*m * v).eval(); + xyz.ChangeData()[0] = v2(0); + xyz.ChangeData()[1] = v2(1); + xyz.ChangeData()[2] = v2(2); + } } } @@ -23,14 +25,17 @@ void ifcopenshell::geometry::OpenCascadeShape::Triangulate(const settings& setti // @todo remove duplication with OpenCascadeKernel::convert(const taxonomy::matrix4* matrix, gp_GTrsf& trsf); // above can be static? - const auto& m = *place.components; - // A 3x3 matrix to rotate the vertex normals - gp_Mat rotation_matrix( - m(0, 0), m(0, 1), m(0, 2), - m(1, 0), m(1, 1), m(1, 2), - m(2, 0), m(2, 1), m(2, 2) - ); + boost::optional rotation_matrix; + + if (place.components_) { + const auto& m = *place.components_; + rotation_matrix.emplace( + m(0, 0), m(0, 1), m(0, 2), + m(1, 0), m(1, 1), m(1, 2), + m(2, 0), m(2, 1), m(2, 2) + ); + } // Triangulate the shape try { @@ -70,7 +75,7 @@ void ifcopenshell::geometry::OpenCascadeShape::Triangulate(const settings& setti for (int i = 1; i <= nodes.Length(); ++i) { coords.push_back(nodes(i).Transformed(loc).XYZ()); - taxonomy_transform(place.components, *coords.rbegin()); + taxonomy_transform(place.components_, *coords.rbegin()); const gp_XYZ& last = *coords.rbegin(); dict[i] = t->addVertex(surface_style_id, last.X(), last.Y(), last.Z()); @@ -81,7 +86,11 @@ void ifcopenshell::geometry::OpenCascadeShape::Triangulate(const settings& setti prop.Normal(uv.X(), uv.Y(), p, normal_direction); gp_Vec normal(0., 0., 0.); if (normal_direction.Magnitude() > 1.e-9) { - normal = gp_Dir(normal_direction.XYZ() * rotation_matrix); + if (rotation_matrix) { + normal = gp_Dir(normal_direction.XYZ() * *rotation_matrix); + } else { + normal = normal_direction; + } } t->addNormal(normal.X(), normal.Y(), normal.Z()); } diff --git a/src/ifcgeom/schema/bind_convert_impl.i b/src/ifcgeom/schema/bind_convert_impl.i index 8bf303533a..3a03bdae6f 100644 --- a/src/ifcgeom/schema/bind_convert_impl.i +++ b/src/ifcgeom/schema/bind_convert_impl.i @@ -12,7 +12,7 @@ if (l->as() && !l->as()) { \ auto style = find_style(l->as()); \ if (style) { \ - ((taxonomy::geom_item*)item)->surface_style = as(map(style)); \ + ((taxonomy::geom_item*)item)->surface_style = (taxonomy::style*) map(style); \ } \ } \ } catch (const std::exception& e) { \ diff --git a/src/ifcgeom/schema/mapping.cpp b/src/ifcgeom/schema/mapping.cpp index a9208bbfd4..a3d0b992b8 100644 --- a/src/ifcgeom/schema/mapping.cpp +++ b/src/ifcgeom/schema/mapping.cpp @@ -368,19 +368,25 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcProduct* inst) { if (single_material) { auto material_style = map(single_material); if (material_style) { - c->surface_style = as(material_style); + c->surface_style = (taxonomy::style*) material_style; } } if (openings->size() && !settings_.get(settings::DISABLE_OPENING_SUBTRACTIONS) && use_body) { - auto ci = c->matrix.components->inverse(); + + Eigen::Matrix4d ci; + if (c->matrix.components_) { + ci = c->matrix.components_->inverse(); + } else { + ci.setIdentity(); + } IfcEntityList::ptr operands(new IfcEntityList); operands->push(body); operands->push(openings); auto n = map_to_collection(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.ccomponents(); }); n->operation = taxonomy::boolean_result::SUBTRACTION; // @todo one indirection too many @@ -403,7 +409,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(map(inst->Location())); - o = *v.components; + o = *v.components_; } const bool hasAxis = inst->hasAxis(); const bool hasRef = inst->hasRefDirection(); @@ -414,12 +420,12 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcAxis2Placement3D* inst) { if (hasAxis) { taxonomy::direction3 v = as(map(inst->Axis())); - axis = *v.components; + axis = *v.components_; } if (hasRef) { taxonomy::direction3 v = as(map(inst->RefDirection())); - refDirection = *v.components; + refDirection = *v.components_; } else { if (acos(axis.dot(X)) > 1.e-5) { refDirection = { 1., 0., 0. }; @@ -437,12 +443,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(map(inst->Location())); - P = *v.components; + P = *v.components_; } const bool hasRef = inst->hasRefDirection(); if (hasRef) { taxonomy::direction3 v = as(map(inst->RefDirection())); - V = *v.components; + V = *v.components_; } return new taxonomy::matrix4(P, axis, V); } @@ -453,15 +459,15 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcCartesianTransformationOpe Eigen::Vector4d origin, axis1(1.0, 0.0, 0.0, 0.0), axis2(0.0, 1.0, 0.0, 0.0), axis3(0.0, 0.0, 1.0, 0.0); taxonomy::point3 O = as(map(inst->LocalOrigin())); - origin << *O.components, 1.0; + origin << *O.components_, 1.0; if (inst->hasAxis1()) { taxonomy::direction3 ax1 = as(map(inst->Axis1())); - axis1 << *ax1.components, 0.0; + axis1 << *ax1.components_, 0.0; } if (inst->hasAxis2()) { taxonomy::direction3 ax2 = as(map(inst->Axis1())); - axis2 << *ax2.components, 0.0; + axis2 << *ax2.components_, 0.0; } double scale1, scale2; @@ -475,13 +481,13 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcCartesianTransformationOpe scale2 = nu->hasScale2() ? nu->Scale2() : scale1; } - *m->components << + m->components() << axis1 * scale1, axis2 * scale2, axis3, origin; - m->components->transposeInPlace(); + m->components().transposeInPlace(); return m; } @@ -495,19 +501,19 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcCartesianTransformationOpe Eigen::Vector4d axis3(0., 0., 1., 0.); taxonomy::point3 O = as(map(inst->LocalOrigin())); - origin << *O.components, 1.0; + origin << *O.components_, 1.0; if (inst->hasAxis1()) { taxonomy::direction3 ax1 = as(map(inst->Axis1())); - axis1 << *ax1.components, 0.0; + axis1 << *ax1.components_, 0.0; } if (inst->hasAxis2()) { taxonomy::direction3 ax2 = as(map(inst->Axis2())); - axis2 << *ax2.components, 0.0; + axis2 << *ax2.components_, 0.0; } if (inst->hasAxis3()) { taxonomy::direction3 ax3 = as(map(inst->Axis3())); - axis3 << *ax3.components, 0.0; + axis3 << *ax3.components_, 0.0; } double scale1, scale2, scale3; @@ -529,8 +535,8 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcCartesianTransformationOpe axis3 * scale3, origin; - *m->components = tmp.inverse(); - m->components->transposeInPlace(); + m->components() = tmp.inverse(); + m->components().transposeInPlace(); // @todo tag identity? @@ -545,7 +551,7 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcLocalPlacement* inst) { if (relplacement->declaration().is(IfcSchema::IfcAxis2Placement3D::Class())) { taxonomy::matrix4 trsf2 = as(map(relplacement)); // @todo check - *m4->components = *trsf2.components * *m4->components; + m4->components() = trsf2.ccomponents() * m4->ccomponents(); } if (current->hasPlacementRelTo()) { IfcSchema::IfcObjectPlacement* parent = current->PlacementRelTo(); @@ -594,14 +600,14 @@ IfcSchema::IfcProduct::list::ptr mapping::products_represented_by(const IfcSchem if (maps->size() == 1) { IfcSchema::IfcRepresentationMap* rmap = *maps->begin(); taxonomy::matrix4 origin = as(map(rmap->MappingOrigin())); - if (origin.components->isIdentity()) { + if (origin.is_identity()) { 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(map(item->MappingTarget())); - if (target.components->isIdentity()) { + if (target.is_identity()) { continue; } @@ -845,10 +851,10 @@ IfcSchema::IfcRepresentation* mapping::representation_mapped_to(const IfcSchema: if (item->StyledByItem()->size() == 0) { IfcSchema::IfcMappedItem* mapped_item = item->as(); taxonomy::matrix4 target = as(map(mapped_item->MappingTarget())); - if (target.components->isIdentity()) { + if (target.is_identity()) { IfcSchema::IfcRepresentationMap* rmap = mapped_item->MappingSource(); taxonomy::matrix4 origin = as(map(rmap->MappingOrigin())); - if (origin.components->isIdentity()) { + if (origin.is_identity()) { representation_mapped_to = rmap->MappedRepresentation(); } } @@ -1008,14 +1014,14 @@ 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()) { if (rendering_style->hasDiffuseColour() && process_colour(rendering_style->DiffuseColour(), rgb)) { - const taxonomy::colour& old_diffuse = surface_style->diffuse.get_value_or(white); - surface_style->diffuse.reset(taxonomy::colour(old_diffuse.r() * rgb[0], old_diffuse.g() * rgb[1], old_diffuse.b() * rgb[2])); + // @todo + // const taxonomy::colour& old_diffuse = surface_style->diffuse; // .get_value_or(white); + // surface_style->diffuse.reset(taxonomy::colour(old_diffuse.r() * rgb[0], old_diffuse.g() * rgb[1], old_diffuse.b() * rgb[2])); } if (rendering_style->hasDiffuseTransmissionColour()) { // Not supported @@ -1024,17 +1030,17 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcStyledItem* inst) { // Not supported } if (rendering_style->hasSpecularColour() && process_colour(rendering_style->SpecularColour(), rgb)) { - surface_style->specular.reset(taxonomy::colour(rgb[0], rgb[1], rgb[2])); + surface_style->specular.components() << rgb[0], rgb[1], rgb[2]; } if (rendering_style->hasSpecularHighlight()) { IfcSchema::IfcSpecularHighlightSelect* highlight = rendering_style->SpecularHighlight(); if (highlight->declaration().is(IfcSchema::IfcSpecularRoughness::Class())) { double roughness = *((IfcSchema::IfcSpecularRoughness*)highlight); if (roughness >= 1e-9) { - surface_style->specularity.reset(1.0 / roughness); + surface_style->specularity = 1.0 / roughness; } } else if (highlight->declaration().is(IfcSchema::IfcSpecularExponent::Class())) { - surface_style->specularity.reset(*((IfcSchema::IfcSpecularExponent*)highlight)); + surface_style->specularity = *((IfcSchema::IfcSpecularExponent*)highlight); } } if (rendering_style->hasTransmissionColour()) { @@ -1042,7 +1048,7 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcStyledItem* inst) { } if (rendering_style->hasTransparency()) { const double d = rendering_style->Transparency(); - surface_style->transparency.reset(d); + surface_style->transparency = d; } } @@ -1276,7 +1282,7 @@ namespace { #endif if (has_position) { taxonomy::matrix4 m = as(self->map(inst->Position())); - m4 = *m.components; + m4 = m.ccomponents(); } // @todo precision @@ -1310,10 +1316,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(p.previous->start).components->head<2>(); - auto p1a = boost::get(p.previous->end).components->head<2>(); - auto p2 = boost::get(p.next->end).components->head<2>(); - auto p1b = boost::get(p.next->start).components->head<2>(); + auto p0 = boost::get(p.previous->start).components_->head<2>(); + auto p1a = boost::get(p.previous->end).components_->head<2>(); + auto p2 = boost::get(p.next->end).components_->head<2>(); + auto p1b = boost::get(p.next->start).components_->head<2>(); auto ba_ = p0 - p1a; auto bc_ = p2 - p1b; @@ -1324,8 +1330,8 @@ namespace { const double angle = std::acos(ba.dot(bc)); const double inset = *p.radius / std::tan(angle / 2.); - boost::get(p.previous->end).components->head<2>() += ba * inset; - boost::get(p.next->start).components->head<2>() += bc * inset; + boost::get(p.previous->end).components_->head<2>() += ba * inset; + boost::get(p.next->start).components_->head<2>() += bc * inset; auto e = new taxonomy::edge; e->start = p.previous->end; @@ -1335,10 +1341,10 @@ namespace { double sign = ab.head<2>().dot(bc) > 0 ? 1. : -1.; - auto O = boost::get(p.previous->end).components->head<3>() + ab * *p.radius * sign; + auto O = boost::get(p.previous->end).ccomponents().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.reset(sign == -1.); @@ -1446,7 +1452,9 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcCircleProfileDef* inst) { #endif if (has_position) { taxonomy::matrix4 m = as(map(inst->Position())); - c->matrix = *m.components; + if (m.components_) { + c->matrix = *m.components_; + } } auto e = new taxonomy::edge; @@ -1547,7 +1555,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 @@ -1576,7 +1584,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) { @@ -1599,7 +1607,8 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcMappedItem* inst) { IfcSchema::IfcRepresentationMap* rmap = inst->MappingSource(); IfcSchema::IfcAxis2Placement* placement = rmap->MappingOrigin(); taxonomy::matrix4 trsf2 = as(map(placement)); - *gtrsf.components = *gtrsf.components * *trsf2.components; + // Cannot be nullptr here + *gtrsf.components_ = *gtrsf.components_ * *trsf2.components_; // @todo immutable for caching? // @todo allow for multiple levels of matrix? @@ -1610,7 +1619,7 @@ taxonomy::item* mapping::map_impl(const IfcSchema::IfcMappedItem* inst) { auto collection = new taxonomy::collection; collection->children.push_back(shapes); - collection->matrix = *gtrsf.components; + collection->matrix = *gtrsf.components_; if (shapes != nullptr) { for (auto& c : ((taxonomy::collection*)shapes)->children) { @@ -1698,7 +1707,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; } diff --git a/src/ifcgeom/schema_agnostic/ConversionResult.h b/src/ifcgeom/schema_agnostic/ConversionResult.h index 4b34363346..1b40ecca34 100644 --- a/src/ifcgeom/schema_agnostic/ConversionResult.h +++ b/src/ifcgeom/schema_agnostic/ConversionResult.h @@ -67,31 +67,31 @@ namespace ifcopenshell { namespace geometry { int id; ifcopenshell::geometry::taxonomy::matrix4 placement; ConversionResultShape* shape; - ifcopenshell::geometry::taxonomy::style style; + const ifcopenshell::geometry::taxonomy::style* style; public: - ConversionResult(int id, const ifcopenshell::geometry::taxonomy::matrix4& placement, const ConversionResultShape* shape, const ifcopenshell::geometry::taxonomy::style& style) + 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) + ConversionResult(int id, const ConversionResultShape* shape, const ifcopenshell::geometry::taxonomy::style* style) : id(id), shape(shape->clone()), style(style) {} ConversionResult(int id, const ConversionResultShape* shape) : 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.ccomponents() * trsf.ccomponents(); } void prepend(const ifcopenshell::geometry::taxonomy::matrix4& trsf) { // @todo verify order - *placement.components = *trsf.components * *placement.components; + placement.components() = trsf.ccomponents() * placement.ccomponents(); } const ConversionResultShape* Shape() const { return shape; } ConversionResultShape* Shape() { return shape; } 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; } - void setStyle(const ifcopenshell::geometry::taxonomy::style& newStyle) { style = newStyle; } + bool hasStyle() const { return style != nullptr; } + const ifcopenshell::geometry::taxonomy::style& Style() const { return *style; } + void setStyle(const ifcopenshell::geometry::taxonomy::style* newStyle) { style = newStyle; } int ItemId() const { return id; } }; diff --git a/src/ifcgeom/schema_agnostic/IfcGeomElement.h b/src/ifcgeom/schema_agnostic/IfcGeomElement.h index 3c1229844e..e1a02ac866 100644 --- a/src/ifcgeom/schema_agnostic/IfcGeomElement.h +++ b/src/ifcgeom/schema_agnostic/IfcGeomElement.h @@ -49,7 +49,7 @@ 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(); } } } diff --git a/src/ifcgeom/schema_agnostic/IfcGeomRepresentation.cpp b/src/ifcgeom/schema_agnostic/IfcGeomRepresentation.cpp index f216781d57..53b8d4fcaa 100644 --- a/src/ifcgeom/schema_agnostic/IfcGeomRepresentation.cpp +++ b/src/ifcgeom/schema_agnostic/IfcGeomRepresentation.cpp @@ -39,8 +39,8 @@ ifcopenshell::geometry::Representation::Serialization::Serialization(const BRep& delete shape; for (ifcopenshell::geometry::ConversionResults::const_iterator it = brep.begin(); it != brep.end(); ++ it) { - if (it->hasStyle() && it->Style().diffuse) { - const auto& clr = *it->Style().diffuse.get().components; + if (it->hasStyle()) { + const auto& clr = it->Style().diffuse.ccomponents(); surface_styles_.push_back(clr(0)); surface_styles_.push_back(clr(1)); surface_styles_.push_back(clr(2)); @@ -49,8 +49,8 @@ ifcopenshell::geometry::Representation::Serialization::Serialization(const BRep& 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().has_transparency()) { + surface_styles_.push_back(1. - it->Style().transparency); } else { surface_styles_.push_back(1.); } @@ -95,14 +95,16 @@ ifcopenshell::geometry::ConversionResultShape* ifcopenshell::geometry::Represent // @todo, check gp_GTrsf trsf; - gp_Trsf tr; - const auto& m = *it->Placement().components; - tr.SetValues( - m(0, 0), m(0, 1), m(0, 2), m(0, 3), - m(1, 0), m(1, 1), m(1, 2), m(1, 3), - m(2, 0), m(2, 1), m(2, 2), m(2, 3) - ); - trsf = tr; + if (it->Placement().components_) { + gp_Trsf tr; + const auto& m = it->Placement().ccomponents(); + tr.SetValues( + m(0, 0), m(0, 1), m(0, 2), m(0, 3), + m(1, 0), m(1, 1), m(1, 2), m(1, 3), + m(2, 0), m(2, 1), m(2, 2), m(2, 3) + ); + trsf = tr; + } if (!force_meters && settings().get(ifcopenshell::geometry::settings::CONVERT_BACK_UNITS)) { gp_Trsf scale; @@ -243,14 +245,17 @@ bool ifcopenshell::geometry::Representation::BRep::calculate_projected_surface_a try { // @todo check gp_GTrsf trsf; - gp_Trsf tr; - const auto& m = *place.components; - tr.SetValues( - m(0, 0), m(0, 1), m(0, 2), m(0, 3), - m(1, 0), m(1, 1), m(1, 2), m(1, 3), - m(2, 0), m(2, 1), m(2, 2), m(2, 3) - ); - trsf = tr; + + if (place.components_) { + gp_Trsf tr; + const auto& m = place.ccomponents(); + tr.SetValues( + m(0, 0), m(0, 1), m(0, 2), m(0, 3), + m(1, 0), m(1, 1), m(1, 2), m(1, 3), + m(2, 0), m(2, 1), m(2, 2), m(2, 3) + ); + trsf = tr; + } gp_Mat mat = trsf.Trsf().HVectorialPart(); gp_Ax3 ax(trsf.TranslationPart(), mat.Column(3), mat.Column(1)); diff --git a/src/ifcgeom/schema_agnostic/SurfaceStyle.cpp b/src/ifcgeom/schema_agnostic/SurfaceStyle.cpp index a936e30e19..c4784d6bf8 100644 --- a/src/ifcgeom/schema_agnostic/SurfaceStyle.cpp +++ b/src/ifcgeom/schema_agnostic/SurfaceStyle.cpp @@ -13,45 +13,46 @@ static bool default_materials_initialized = false; void InitDefaultMaterials() { default_materials.insert(std::make_pair("IfcSite", ifcopenshell::geometry::taxonomy::style("IfcSite"))); - default_materials["IfcSite"].diffuse.reset(ifcopenshell::geometry::taxonomy::colour(0.75, 0.8, 0.65)); + default_materials["IfcSite"].diffuse = ifcopenshell::geometry::taxonomy::colour(0.75, 0.8, 0.65); default_materials.insert(std::make_pair("IfcSlab", ifcopenshell::geometry::taxonomy::style("IfcSlab"))); - default_materials["IfcSlab"].diffuse.reset(ifcopenshell::geometry::taxonomy::colour(0.4, 0.4, 0.4)); + default_materials["IfcSlab"].diffuse = ifcopenshell::geometry::taxonomy::colour(0.4, 0.4, 0.4); default_materials.insert(std::make_pair("IfcWallStandardCase", ifcopenshell::geometry::taxonomy::style("IfcWallStandardCase"))); - default_materials["IfcWallStandardCase"].diffuse.reset(ifcopenshell::geometry::taxonomy::colour(0.9, 0.9, 0.9)); + default_materials["IfcWallStandardCase"].diffuse = ifcopenshell::geometry::taxonomy::colour(0.9, 0.9, 0.9); default_materials.insert(std::make_pair("IfcWall", ifcopenshell::geometry::taxonomy::style("IfcWall"))); - default_materials["IfcWall"].diffuse.reset(ifcopenshell::geometry::taxonomy::colour(0.9, 0.9, 0.9)); + default_materials["IfcWall"].diffuse = ifcopenshell::geometry::taxonomy::colour(0.9, 0.9, 0.9); default_materials.insert(std::make_pair("IfcWindow", ifcopenshell::geometry::taxonomy::style("IfcWindow"))); - default_materials["IfcWindow"].diffuse.reset(ifcopenshell::geometry::taxonomy::colour(0.75, 0.8, 0.75)); - default_materials["IfcWindow"].transparency.reset(0.3); + default_materials["IfcWindow"].diffuse = ifcopenshell::geometry::taxonomy::colour(0.75, 0.8, 0.75); + default_materials["IfcWindow"].transparency = 0.3; default_materials.insert(std::make_pair("IfcDoor", ifcopenshell::geometry::taxonomy::style("IfcDoor"))); - default_materials["IfcDoor"].diffuse.reset(ifcopenshell::geometry::taxonomy::colour(0.55, 0.3, 0.15)); + default_materials["IfcDoor"].diffuse = ifcopenshell::geometry::taxonomy::colour(0.55, 0.3, 0.15); default_materials.insert(std::make_pair("IfcBeam", ifcopenshell::geometry::taxonomy::style("IfcBeam"))); - default_materials["IfcBeam"].diffuse.reset(ifcopenshell::geometry::taxonomy::colour(0.75, 0.7, 0.7)); + default_materials["IfcBeam"].diffuse = ifcopenshell::geometry::taxonomy::colour(0.75, 0.7, 0.7); default_materials.insert(std::make_pair("IfcRailing", ifcopenshell::geometry::taxonomy::style("IfcRailing"))); - default_materials["IfcRailing"].diffuse.reset(ifcopenshell::geometry::taxonomy::colour(0.65, 0.6, 0.6)); + default_materials["IfcRailing"].diffuse = ifcopenshell::geometry::taxonomy::colour(0.65, 0.6, 0.6); default_materials.insert(std::make_pair("IfcMember", ifcopenshell::geometry::taxonomy::style("IfcMember"))); - default_materials["IfcMember"].diffuse.reset(ifcopenshell::geometry::taxonomy::colour(0.65, 0.6, 0.6)); + default_materials["IfcMember"].diffuse = ifcopenshell::geometry::taxonomy::colour(0.65, 0.6, 0.6); default_materials.insert(std::make_pair("IfcPlate", ifcopenshell::geometry::taxonomy::style("IfcPlate"))); - default_materials["IfcPlate"].diffuse.reset(ifcopenshell::geometry::taxonomy::colour(0.8, 0.8, 0.8)); + default_materials["IfcPlate"].diffuse = ifcopenshell::geometry::taxonomy::colour(0.8, 0.8, 0.8); default_material = ifcopenshell::geometry::taxonomy::style("DefaultMaterial"); - default_material.diffuse.reset(ifcopenshell::geometry::taxonomy::colour(0.7, 0.7, 0.7)); + default_material.diffuse = ifcopenshell::geometry::taxonomy::colour(0.7, 0.7, 0.7); default_materials_initialized = true; } -boost::optional read_colour_component(const boost::optional list) { +ifcopenshell::geometry::taxonomy::colour read_colour_component(const boost::optional list) { + ifcopenshell::geometry::taxonomy::colour clr; if (!list) { - return boost::none; + return clr; } double rgb[3]; int i = 0; @@ -65,7 +66,8 @@ boost::optional read_colour_component( if (i != 3) { throw std::runtime_error("rgb array less than 3 elements large (was " + std::to_string(i) + ")"); } - return ifcopenshell::geometry::taxonomy::colour(rgb[0], rgb[1], rgb[2]); + clr.components() << rgb[0], rgb[1], rgb[2]; + return clr; } void IfcGeom::set_default_style_file(const std::string& json_file) { @@ -88,7 +90,7 @@ void IfcGeom::set_default_style_file(const std::string& json_file) { default_materials[name].specular = read_colour_component(specular); if (material.get_child_optional("specular-roughness")) { - default_materials[name].specularity.reset(1.0 / material.get("specular-roughness")); + default_materials[name].specularity = 1.0 / material.get("specular-roughness"); } if (material.get_child_optional("transparency")) { default_materials[name].transparency = material.get("transparency"); diff --git a/src/ifcgeom/taxonomy.cpp b/src/ifcgeom/taxonomy.cpp index a6eb936920..2f6fc21101 100644 --- a/src/ifcgeom/taxonomy.cpp +++ b/src/ifcgeom/taxonomy.cpp @@ -9,11 +9,19 @@ namespace { template bool compare(const eigen_base& t, const eigen_base& u) { - auto t_begin = t.components->data(); - auto t_end = t.components->data() + t.components->size(); + if (t.components_ == nullptr && u.components_ == nullptr) { + return false; + } else if (t.components_ == nullptr && u.components_ != nullptr) { + return true; + } else if (t.components_ != nullptr && u.components_ == nullptr) { + return false; + } - auto u_begin = u.components->data(); - auto u_end = u.components->data() + u.components->size(); + auto t_begin = t.components_->data(); + auto t_end = t.components_->data() + t.components_->size(); + + auto u_begin = u.components_->data(); + auto u_end = u.components_->data() + u.components_->size(); return std::lexicographical_compare(t_begin, t_end, u_begin, u_end); } @@ -108,11 +116,11 @@ namespace { bool compare(const style& a, const style& b) { const int order[5] = { - less_to_order_optional(a.name, b.name), - less_to_order_optional(a.diffuse, b.diffuse), - less_to_order_optional(a.specular, b.specular), - less_to_order_optional(a.specularity, b.specularity), - less_to_order_optional(a.transparency, b.transparency) + less_to_order(a.name, b.name), + less_to_order(a.diffuse, b.diffuse), + less_to_order(a.specular, b.specular), + less_to_order(a.specularity, b.specularity), + less_to_order(a.transparency, b.transparency) }; auto it = std::find_if(std::begin(order), std::end(order), [](int x) { return x; }); if (it == std::end(order)) return false; @@ -221,7 +229,16 @@ namespace { // Vectors equal, compare matrix (in case of mapped items). int matrix_order = less_to_order(a.matrix, b.matrix); if (matrix_order == 0) { - return compare(a.surface_style, b.surface_style); + + if (a.surface_style == nullptr && b.surface_style == nullptr) { + return false; + } else if (a.surface_style == nullptr && b.surface_style != nullptr) { + return true; + } else if (a.surface_style != nullptr && b.surface_style == nullptr) { + return false; + } + + return compare(*a.surface_style, *b.surface_style); } else { return matrix_order == -1; } diff --git a/src/ifcgeom/taxonomy.h b/src/ifcgeom/taxonomy.h index 4b4e9816bb..43aa0d9f26 100644 --- a/src/ifcgeom/taxonomy.h +++ b/src/ifcgeom/taxonomy.h @@ -28,6 +28,9 @@ enum kinds { MATRIX4, POINT3, DIRECTION3, LINE, CIRCLE, ELLIPSE, BSPLINE_CURVE, struct item { const IfcUtil::IfcBaseClass* instance; + + boost::optional orientation; + virtual item* clone() const = 0; virtual kinds kind() const = 0; virtual void print(std::ostream&, int indent=0) const = 0; @@ -44,40 +47,76 @@ struct less_functor { } }; +namespace { + + template + const T& eigen_defaults(); + + template <> + const Eigen::Vector3d& eigen_defaults() { + static Eigen::Vector3d identity = Eigen::Vector3d::Zero(); + return identity; + } + + template <> + const Eigen::Matrix4d& eigen_defaults() { + static Eigen::Matrix4d identity = Eigen::Matrix4d::Identity(); + return identity; + } + +} + template struct eigen_base { - T* components; + T* components_; eigen_base() { - components = new T; + components_ = nullptr; } eigen_base(const eigen_base& other) { - this->components = new T(*other.components); + this->components_ = other.components_ ? new T(*other.components_) : nullptr; } eigen_base(const T& other) { - this->components = new T(other); + this->components_ = new T(other); } eigen_base& operator=(const eigen_base& other) { if (this != &other) { - this->components = new T(*other.components); + this->components_ = other.components_ ? new T(*other.components_) : nullptr; } return *this; } void print_impl(std::ostream& o, const std::string& class_name, int indent = 0) const { o << std::string(indent, ' ') << class_name; - int n = T::RowsAtCompileTime * T::ColsAtCompileTime; - for (size_t i = 0; i < n; ++i) { - o << " " << (*components)(i); + if (this->components_) { + int n = T::RowsAtCompileTime * T::ColsAtCompileTime; + for (size_t i = 0; i < n; ++i) { + o << " " << (*components_)(i); + } } o << std::endl; } ~eigen_base() { - delete this->components; + delete this->components_; + } + + const T& ccomponents() const { + if (this->components_) { + return *this->components_; + } else { + return eigen_defaults(); + } + } + + T& components() { + if (!this->components_) { + this->components_ = new T; + } + return *this->components_; } }; @@ -87,20 +126,24 @@ struct matrix4 : public item, public eigen_base { }; tag_t tag; - matrix4() : eigen_base(Eigen::Matrix4d::Identity()), tag(IDENTITY) {} + matrix4() : eigen_base(), 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 = new Eigen::Matrix4d; - (*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.; } + bool is_identity() const { + return !components_ || components_->isIdentity(); + } + void print(std::ostream& o, int indent = 0) const { print_impl(o, "matrix4", indent); } @@ -117,33 +160,30 @@ struct colour : public item, public eigen_base { virtual item* clone() const { return new colour(*this); } virtual kinds kind() const { return COLOUR; } - colour() : eigen_base(Eigen::Vector3d::Zero()) {} - colour(double r, double g, double b) { (*components) << r, g, b; } + colour() : eigen_base() {} + 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 ccomponents()[0]; } + const double& g() const { return ccomponents()[1]; } + const double& b() const { return ccomponents()[2]; } }; struct style : public item { - // @todo this is not very efficient wrt alignment - boost::optional name; - boost::optional diffuse; - boost::optional specular; - boost::optional specularity, transparency; + std::string name; + colour diffuse; + colour specular; + 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; + o << std::string(indent, ' ') << " " << "name" << (name) << std::endl; + if (diffuse.components_) { + o << std::string(indent, ' ') << " " << "diffuse" << (name) << std::endl; + diffuse.print(o, indent + 5 + 7); } - 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); + if (specular.components_) { + o << std::string(indent, ' ') << " " << "specular" << (name) << std::endl; + specular.print(o, indent + 5 + 8); } // @todo } @@ -154,23 +194,31 @@ struct style : public item { // @todo equality implementation based on values? bool operator==(const style& other) const { return instance == other.instance; } - style() {} - style(const std::string& name) : name(name) {} + style() : specularity(std::numeric_limits::quiet_NaN()), transparency(std::numeric_limits::quiet_NaN()) {} + style(const std::string& name) : name(name), specularity(std::numeric_limits::quiet_NaN()), transparency(std::numeric_limits::quiet_NaN()) {} + + bool has_specularity() const { + return !std::isnan(specularity); + } + + bool has_transparency() const { + return !std::isnan(transparency); + } }; struct geom_item : public item { - style surface_style; + style* surface_style; matrix4 matrix; - boost::optional orientation; - geom_item(const IfcUtil::IfcBaseClass* instance = nullptr) : item(instance) {} - geom_item(const IfcUtil::IfcBaseClass* instance, matrix4 m) : item(instance), matrix(m) {} - geom_item(matrix4 m) : matrix(m) {} + geom_item(const IfcUtil::IfcBaseClass* instance = nullptr) : item(instance), surface_style(nullptr) {} + geom_item(const IfcUtil::IfcBaseClass* instance, matrix4 m) : item(instance), surface_style(nullptr), matrix(m) {} + geom_item(matrix4 m) : surface_style(nullptr), matrix(m) {} }; +// @todo make 4d for easier multiplication template -struct cartesian_base : public geom_item, public eigen_base { - cartesian_base() : eigen_base(Eigen::Vector3d::Zero()) {} +struct cartesian_base : public item, public eigen_base { + cartesian_base() : eigen_base() {} cartesian_base(double x, double y, double z = 0.) : eigen_base(Eigen::Vector3d(x, y, z)) {} }; @@ -182,7 +230,8 @@ struct point3 : public cartesian_base<3> { print_impl(o, "point3", indent); } - point3(double x = 0., double y = 0., double z = 0.) : cartesian_base(x, y, z) {} + point3() : cartesian_base() {} + point3(double x, double y, double z = 0.) : cartesian_base(x, y, z) {} }; struct direction3 : public cartesian_base<3> { @@ -193,7 +242,8 @@ struct direction3 : public cartesian_base<3> { print_impl(o, "direction3", indent); } - direction3(double x = 0., double y = 0., double z = 0.) : cartesian_base(x, y, z) {} + direction3() : cartesian_base() {} + direction3(double x, double y, double z = 0.) : cartesian_base(x, y, z) {} }; struct curve : public geom_item { @@ -243,7 +293,7 @@ struct bspline_curve : public curve { } }; -struct trimmed_curve : public curve { +struct trimmed_curve : public item { // @todo The copy constructor of point3 within the variant fails on the avx instruction // on the default gcc in Ubuntu 18.04 and a recent AMD Ryzen. Probably due to allignment. boost::variant start, end; @@ -316,7 +366,7 @@ struct collection : public geom_item { void print(std::ostream& o, int indent = 0) const { o << std::string(indent, ' ') << "collection" << std::endl; - if (!matrix.components->isIdentity()) { + if (!matrix.components_->isIdentity()) { matrix.print(o, indent + 4); } for (auto& c : children) { diff --git a/src/serializers/ColladaSerializer.cpp b/src/serializers/ColladaSerializer.cpp index 19df0e2959..745447e22e 100644 --- a/src/serializers/ColladaSerializer.cpp +++ b/src/serializers/ColladaSerializer.cpp @@ -197,20 +197,20 @@ 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().ccomponents() * transformation.data().ccomponents()); relative_trsf = new ifcopenshell::geometry::Transformation(transformation.settings(), m4); transformation_towrite = relative_trsf; } // @todo verify - const double* m = transformation_towrite->data().components->data(); + const auto& m = transformation_towrite->data().ccomponents(); double matrix_array[4][4] = { - { m[0], m[4], m[8], m[12] }, - { m[1], m[5], m[9], m[13] }, - { m[2], m[6], m[10], m[14] }, - { m[3], m[7], m[11], m[15] } + { m(0), m(4), m(8), m(12) }, + { m(1), m(5), m(9), m(13) }, + { m(2), m(6), m(10), m(14) }, + { m(3), m(7), m(11), m(15) } }; /// @todo: TFK: Rather than applying this offset to all leafs (which might be undesirable) should this offset be applied to a node higher up in the hierarchy? @@ -251,19 +251,19 @@ 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().ccomponents() * parent_trsf.data().ccomponents()); 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 auto& parentMatrix = transformation_towrite->data().ccomponents(); double matrix_array[4][4] = { - { (double)parentMatrix[0], (double)parentMatrix[3], (double)parentMatrix[6], (double)parentMatrix[9] }, - { (double)parentMatrix[1], (double)parentMatrix[4], (double)parentMatrix[7], (double)parentMatrix[10] }, - { (double)parentMatrix[2], (double)parentMatrix[5], (double)parentMatrix[8], (double)parentMatrix[11] }, + { (double)parentMatrix(0), (double)parentMatrix(3), (double)parentMatrix(6), (double)parentMatrix(9) }, + { (double)parentMatrix(1), (double)parentMatrix(4), (double)parentMatrix(7), (double)parentMatrix(10) }, + { (double)parentMatrix(2), (double)parentMatrix(5), (double)parentMatrix(8), (double)parentMatrix(11) }, { 0, 0, 0, 1 } }; @@ -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().ccomponents().inverse()))); parentNodes.push(current_node); serializer->parentStackId.push(parent.id()); } @@ -319,19 +319,17 @@ void ColladaSerializer::ColladaExporter::ColladaMaterials::ColladaEffects::write openEffect(material_uri + "-fx"); COLLADASW::EffectProfile effect(mSW); effect.setShaderType(COLLADASW::EffectProfile::LAMBERT); - if (material.diffuse) { - const auto& diffuse = *material.diffuse.get().components; - effect.setDiffuse(COLLADASW::ColorOrTexture(COLLADASW::Color(diffuse[0],diffuse[1],diffuse[2]))); - } - if (material.specular) { - const auto& specular = *material.specular.get().components; + const auto& diffuse = material.diffuse.ccomponents(); + effect.setDiffuse(COLLADASW::ColorOrTexture(COLLADASW::Color(diffuse[0],diffuse[1],diffuse[2]))); + if (material.specular.components_) { + const auto& specular = material.specular.ccomponents(); effect.setSpecular(COLLADASW::ColorOrTexture(COLLADASW::Color(specular[0],specular[1],specular[2]))); } - if (material.specularity) { - effect.setShininess(*material.specularity); + if (material.has_specularity()) { + effect.setShininess(material.specularity); } - if (material.transparency) { - const double transparency = *material.transparency; + if (material.has_transparency()) { + const double transparency = material.transparency; if (transparency > 0) { // The default opacity mode for Collada is A_ONE, which apparently indicates a // transparency value of 1 to be fully opaque. Hence transparency is inverted. @@ -352,10 +350,10 @@ void ColladaSerializer::ColladaExporter::ColladaMaterials::add(const ifcopenshel // @todo apparently material.name is unitialized in some cases now. - std::string material_name = material.name.get_value_or("missing-material"); + std::string material_name = material.name; if (material_name.empty()) { - material_name = "missing-material-" + *material.name; + material_name = "missing-material-" + material.name; } collada_id(material_name); diff --git a/src/serializers/GltfSerializer.cpp b/src/serializers/GltfSerializer.cpp index 77454d82b4..a64d22feb9 100644 --- a/src/serializers/GltfSerializer.cpp +++ b/src/serializers/GltfSerializer.cpp @@ -80,7 +80,7 @@ void GltfSerializer::writeHeader() { int GltfSerializer::writeMaterial(const ifcopenshell::geometry::taxonomy::style& style) { // @todo is it safe to always dereference this optional? - const std::string& name = *style.name; + const std::string& name = style.name; auto it = materials_.find(name); if (it != materials_.end()) { @@ -92,18 +92,16 @@ int GltfSerializer::writeMaterial(const ifcopenshell::geometry::taxonomy::style& std::array base; base.fill(1.0); - if (style.diffuse) { - for (int i = 0; i < 3; ++i) { - base[i] = (*style.diffuse->components)[i]; - } + for (int i = 0; i < 3; ++i) { + base[i] = style.diffuse.ccomponents()(i); } - if (style.transparency) { - base[3] = 1. - *style.transparency; + if (style.has_transparency()) { + base[3] = 1. - style.transparency; } json_["materials"].push_back({ {"pbrMetallicRoughness", {{"baseColorFactor", base}, {"metallicFactor", 0}}} }); - if (style.transparency && *style.transparency > 1.e-9) { + if (style.has_transparency() && style.transparency > 1.e-9) { json_["materials"].back()["alphaMode"] = "BLEND"; } @@ -167,14 +165,14 @@ void GltfSerializer::write(const ifcopenshell::geometry::TriangulationElement* o node_array_.push_back(json_["nodes"].size()); - const double* m = o->transformation().data().components->data(); + const auto& m = o->transformation().data().ccomponents(); // nb: note that this applies the Y-UP transform. const std::array matrix_flat = { - m[ 0], m[ 2], -m[ 1], m[ 3], - m[ 4], m[ 6], -m[ 5], m[ 7], - m[ 8], m[10], -m[ 9], m[11], - m[12], m[14], -m[13], m[15] + m( 0), m( 2), -m( 1), m( 3), + m( 4), m( 6), -m( 5), m( 7), + m( 8), m(10), -m( 9), m(11), + m(12), m(14), -m(13), m(15) }; static const std::array identity_matrix = {1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1}; diff --git a/src/serializers/SvgSerializer.cpp b/src/serializers/SvgSerializer.cpp index 40fd128216..c42c9d6221 100644 --- a/src/serializers/SvgSerializer.cpp +++ b/src/serializers/SvgSerializer.cpp @@ -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->ccomponents()(3, 2); setSectionHeight(Z + 1.); Logger::Warning("No building storeys encountered, used for reference:", product); return; diff --git a/src/serializers/WavefrontObjSerializer.cpp b/src/serializers/WavefrontObjSerializer.cpp index 1297e37353..105ffd220a 100644 --- a/src/serializers/WavefrontObjSerializer.cpp +++ b/src/serializers/WavefrontObjSerializer.cpp @@ -61,24 +61,21 @@ void WaveFrontOBJSerializer::writeHeader() { void WaveFrontOBJSerializer::writeMaterial(const ifcopenshell::geometry::taxonomy::style& style) { // @todo original_name - std::string material_name = *(settings().get(SerializerSettings::USE_MATERIAL_NAMES) - ? style.name : style.name); + std::string material_name = style.name; IfcUtil::sanitate_material_name(material_name); mtl_stream << "newmtl " << material_name << "\n"; - if (style.diffuse) { - auto diffuse = style.diffuse->components; - mtl_stream << "Kd " << diffuse[0] << " " << diffuse[1] << " " << diffuse[2] << "\n"; + const auto& diffuse = style.diffuse.ccomponents(); + mtl_stream << "Kd " << diffuse(0) << " " << diffuse(1) << " " << diffuse(2) << "\n"; + if (style.specular.components_) { + const auto& specular = style.specular.ccomponents(); + mtl_stream << "Ks " << specular(0) << " " << specular(1) << " " << specular(2) << "\n"; } - if (style.specular) { - auto specular = style.specular->components; - mtl_stream << "Ks " << specular[0] << " " << specular[1] << " " << specular[2] << "\n"; + if (style.has_specularity()) { + mtl_stream << "Ns " << style.specularity << "\n"; } - if (style.specularity) { - mtl_stream << "Ns " << *style.specularity << "\n"; - } - if (style.transparency) { - const double transparency = 1.0 - *style.transparency; + if (style.has_transparency()) { + const double transparency = 1.0 - style.transparency; if (transparency < 1) { mtl_stream << "d " << transparency << "\n"; } @@ -124,8 +121,7 @@ void WaveFrontOBJSerializer::write(const ifcopenshell::geometry::TriangulationEl if (material_id != previous_material_id) { const ifcopenshell::geometry::taxonomy::style& material = mesh.materials()[material_id]; // @todo original_name - std::string material_name = *(settings().get(SerializerSettings::USE_MATERIAL_NAMES) - ? material.name : material.name); + std::string material_name = material.name; IfcUtil::sanitate_material_name(material_name); obj_stream << "usemtl " << material_name << "\n"; if (materials.find(material_name) == materials.end()) { @@ -169,8 +165,7 @@ void WaveFrontOBJSerializer::write(const ifcopenshell::geometry::TriangulationEl if (material_id != previous_material_id) { const ifcopenshell::geometry::taxonomy::style& material = mesh.materials()[material_id]; // @todo original_name - std::string material_name = *(settings().get(SerializerSettings::USE_MATERIAL_NAMES) - ? material.name : material.name); + std::string material_name = material.name; IfcUtil::sanitate_material_name(material_name); obj_stream << "usemtl " << material_name << "\n"; if (materials.find(material_name) == materials.end()) { diff --git a/src/serializers/schema_dependent/XmlSerializer.cpp b/src/serializers/schema_dependent/XmlSerializer.cpp index 2b388b6c68..7471c022b6 100644 --- a/src/serializers/schema_dependent/XmlSerializer.cpp +++ b/src/serializers/schema_dependent/XmlSerializer.cpp @@ -131,7 +131,7 @@ boost::optional 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->ccomponents()(j, i); stream << trsf_value; if (i < 3 && j < 3) { stream << " ";