Merge remote-tracking branch 'origin/v0.8.0' into ifcviewer-wgpu

This commit is contained in:
Thomas Krijnen
2026-07-09 13:21:39 +02:00
373 changed files with 22411 additions and 4242 deletions
+1 -1
View File
@@ -28,7 +28,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcAxis1Placement& inst) {
taxonomy::point3::ptr v = taxonomy::cast<taxonomy::point3>(map(inst.Location()));
P = *v->components_;
} catch (const std::exception&) {
logger::warning("Placement with invalid Location:", inst);
logger_.Warning("GEO", 232, "Placement with invalid Location:", inst);
}
const bool hasAxis = inst.Axis();
if (hasAxis) {
+1 -1
View File
@@ -29,7 +29,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcAxis2Placement2D& inst) {
taxonomy::point3::ptr v = taxonomy::cast<taxonomy::point3>(map(inst.Location()));
P = *v->components_;
} catch (const std::exception&) {
logger::warning("Placement with invalid Location:", inst);
logger_.Warning("GEO", 233, "Placement with invalid Location:", inst);
}
const bool hasRef = !!inst.RefDirection();
if (hasRef) {
+2 -2
View File
@@ -29,13 +29,13 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcAxis2Placement3D& inst) {
taxonomy::point3::ptr v = taxonomy::cast<taxonomy::point3>(map(inst.Location()));
o = *v->components_;
} catch (const std::exception&) {
logger::warning("Placement with invalid Location:", inst);
logger_.Warning("GEO", 234, "Placement with invalid Location:", inst);
}
const bool hasAxis = !!inst.Axis();
const bool hasRef = !!inst.RefDirection();
if (hasAxis != hasRef) {
logger::warning("Axis and RefDirection should be specified together", inst);
logger_.Warning("GEO", 235, "Axis and RefDirection should be specified together", inst);
}
if (hasAxis) {
@@ -26,7 +26,7 @@ using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcAxis2PlacementLinear& inst) {
if (!inst.Location().as<IfcSchema::IfcPointByDistanceExpression>()) {
logger::error(std::runtime_error("Location must be IfcPointByDistanceExpression for IfcAxis2PlacementLinear"));
logger_.Error("GEO", 236, std::runtime_error("Location must be IfcPointByDistanceExpression for IfcAxis2PlacementLinear"));
}
Eigen::Vector3d o, axis(0, 0, 1), refDirection;
+1 -1
View File
@@ -43,7 +43,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCShapeProfileDef& inst) {
const double tol = settings_.get<settings::Precision>().get();
if ( x < tol || y < tol || d1 < tol || d2 < tol) {
logger::message(logger::LOG_NOTICE," Skipping zero sized profile:", inst);
logger_.Message(Logger::LOG_NOTICE, "GEO", 241, "Skipping zero sized profile:", inst);
return nullptr;
}
+1 -1
View File
@@ -24,7 +24,7 @@ using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCircle& inst) {
const double r = inst.Radius() * length_unit_;
if (r < settings_.get<settings::Precision>().get()) {
logger::message(logger::LOG_ERROR, "Radius not greater than zero for:", inst);
logger_.Message(Logger::LOG_ERROR, "GEO", 237, "Radius not greater than zero for:", inst);
return nullptr;
}
+3 -3
View File
@@ -34,11 +34,11 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCompositeCurve& inst) {
for (auto& segment : segments) {
if (segment.as<IfcSchema::IfcCompositeCurveSegment>() && segment.as<IfcSchema::IfcCompositeCurveSegment>().ParentCurve().as<IfcSchema::IfcLine>()) {
logger::notice("Infinite IfcLine used as ParentCurve of segment, treating as a segment", segment);
logger_.Notice("GEO", 238, "Infinite IfcLine used as ParentCurve of segment, treating as a segment", segment);
double u0 = 0.0;
double u1 = segment.as<IfcSchema::IfcCompositeCurveSegment>().ParentCurve().as<IfcSchema::IfcLine>().Dir().Magnitude() * length_unit_;
if (u1 < settings_.get<settings::Precision>().get()) {
logger::warning("Segment length below tolerance", segment);
logger_.Warning("GEO", 239, "Segment length below tolerance", segment);
}
auto e = taxonomy::make<taxonomy::edge>();
@@ -70,7 +70,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCompositeCurve& inst) {
e->end = 2.0 * boost::math::constants::pi<double>();
loop->children.push_back(e);
} else {
logger::warning("Unexpected segment type", segment);
logger_.Warning("GEO", 240, "Unexpected segment type", segment);
return nullptr;
}
}
+24 -18
View File
@@ -216,6 +216,7 @@ struct cant_curve_segment_function {
class curve_segment_evaluator {
private:
mapping* mapping_ = nullptr;
Logger& logger_;
IfcSchema::IfcCurveSegment inst_; // this curve segment instance
double length_unit_;
double start_;
@@ -234,6 +235,7 @@ class curve_segment_evaluator {
public:
curve_segment_evaluator(mapping* mapping, const IfcSchema::IfcCurveSegment& inst, double length_unit)
: mapping_(mapping),
logger_(mapping->logger()),
inst_(inst),
length_unit_(length_unit),
parent_curve_(inst.ParentCurve()) {
@@ -257,6 +259,8 @@ class curve_segment_evaluator {
if (s == inst) {
emit_next = true;
}
} else {
mapping_->logger().Warning("GEO", 242, "IfcCurveSegment belongs to multiple IfcCompositeCurve instances. Cannot determine the next segment.");
}
} else {
logger::warning("IfcCurveSegment belongs to multiple IfcCompositeCurve instances. Cannot determine the next segment.");
@@ -279,7 +283,7 @@ class curve_segment_evaluator {
if ((is_horizontal + is_vertical + is_cant) != 1) {
// We have to choose the correct functor based on usage. We can't
// support multiple, because we don't know the caller at this point.
logger::error(std::runtime_error("multiple uses of IfcSegmentCurve not supported"), inst_);
mapping_->logger().Error("UNS", 10, std::runtime_error("multiple uses of IfcSegmentCurve not supported"), inst_);
}
segment_type_ = is_horizontal ? ST_HORIZONTAL : is_vertical ? ST_VERTICAL : is_cant ? ST_CANT : ST_HORIZONTAL;
@@ -317,7 +321,7 @@ class curve_segment_evaluator {
end_point = segmented_reference_curve.EndPoint();
}
} else {
logger::warning("IfcCurveSegment belongs to multiple IfcCompositeCurve instances. Cannot determine the end point.");
mapping_->logger().Warning("GEO", 243, "IfcCurveSegment belongs to multiple IfcCompositeCurve instances. Cannot determine the end point.");
}
if (end_point) {
next_segment_placement_ = taxonomy::cast<taxonomy::matrix4>(mapping_->map(end_point))->ccomponents();
@@ -339,7 +343,7 @@ class curve_segment_evaluator {
taxonomy::ptr get_segment_curve_function() {
if (!parent_curve_fn_ || !parent_curve_start_point_) {
logger::error(std::runtime_error(inst_.ParentCurve().declaration().name() + " not implemented"), inst_);
mapping_->logger().Error("UNS", 11, std::runtime_error(inst_->ParentCurve()->declaration().name() + " not implemented"), inst_);
}
auto length = fabs(this->length());
@@ -472,13 +476,13 @@ class curve_segment_evaluator {
projected_length_ = length_;
}
} else if (segment_type_ == ST_CANT) {
logger::error(std::runtime_error("Unexpected segment type encountered - cant is handled in set_cant_spiral_function - should never get here"));
mapping_->logger().Error("GEO", 244, std::runtime_error("Unexpected segment type encountered - cant is handled in set_cant_spiral_function - should never get here"));
parent_curve_fn_ = std::make_shared<parent_curve_function>(
[](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); },
[](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); }
);
} else {
logger::error(std::runtime_error("Unexpected segment type encountered"));
mapping_->logger().Error("GEO", 245, "Unexpected segment type encountered");
parent_curve_fn_ = std::make_shared<parent_curve_function>(
[](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); },
[](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); }
@@ -639,13 +643,13 @@ class curve_segment_evaluator {
set_cant_spiral_function(*super, *slope, cant);
} else if (segment_type_ == ST_VERTICAL) {
logger::error(std::runtime_error("IfcCosineSpiral cannot be used for vertical alignment"));
mapping_->logger().Error("GEO", 246, "IfcCosineSpiral cannot be used for vertical alignment");
parent_curve_fn_ = std::make_shared<parent_curve_function>(
[](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); },
[](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); }
);
} else {
logger::error(std::runtime_error("Unexpected segment type encountered"));
mapping_->logger().Error("GEO", 247, "Unexpected segment type encountered");
parent_curve_fn_ = std::make_shared<parent_curve_function>(
[](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); },
[](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); }
@@ -708,12 +712,12 @@ class curve_segment_evaluator {
set_cant_spiral_function(*super, *slope, cant);
} else if (segment_type_ == ST_VERTICAL) {
logger::error(std::runtime_error("IfcSineSpiral cannot be used for vertical alignment"));
mapping_->logger().Error("GEO", 248, "IfcSineSpiral cannot be used for vertical alignment");
parent_curve_fn_ = std::make_shared<parent_curve_function>(
[](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); },
[](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); });
} else {
logger::error(std::runtime_error("Unexpected segment type encountered"));
mapping_->logger().Error("GEO", 249, "Unexpected segment type encountered");
parent_curve_fn_ = std::make_shared<parent_curve_function>(
[](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); },
[](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); });
@@ -856,6 +860,8 @@ class curve_segment_evaluator {
auto sign_l = sign(length_);
auto sign_l = sign(length_);
// center point of the parent curve
auto pcCenterX = parent_curve_position(0, 3);
auto pcCenterY = parent_curve_position(1, 3);
@@ -972,12 +978,12 @@ class curve_segment_evaluator {
}
} else if (segment_type_ == ST_CANT) {
logger::warning(std::runtime_error("Use of IfcCircle for cant is not supported"));
mapping_->logger().Warning("UNS", 12, "Use of IfcCircle for cant is not supported");
parent_curve_fn_ = std::make_shared<parent_curve_function>(
[](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); },
[](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); });
} else {
logger::error(std::runtime_error("Unexpected segment type encountered"));
mapping_->logger().Error("GEO", 250, "Unexpected segment type encountered");
parent_curve_fn_ = std::make_shared<parent_curve_function>(
[](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); },
[](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); });
@@ -1063,7 +1069,7 @@ class curve_segment_evaluator {
parent_curve_start_point_ = (*parent_curve_fn_)(start_);
} else {
logger::warning(std::runtime_error("Unexpected segment type encountered"));
mapping_->logger().Warning("GEO", 251, "Unexpected segment type encountered");
parent_curve_fn_ = std::make_shared<parent_curve_function>(
[](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); },
[](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); });
@@ -1077,7 +1083,7 @@ class curve_segment_evaluator {
auto coeffY = pc.CoefficientsY().value_or(std::vector<double>());
auto coeffZ = pc.CoefficientsZ().value_or(std::vector<double>());
if (!coeffZ.empty()) {
logger::warning("Expected IfcPolynomialCurve.CoefficientsZ to be undefined for alignment geometry. Coefficients ignored.", pc);
mapping_->logger().Warning("GEO", 252, "Expected IfcPolynomialCurve.CoefficientsZ to be undefined for alignment geometry. Coefficients ignored.", pc);
}
if (segment_type_ == ST_HORIZONTAL || segment_type_ == ST_VERTICAL) {
@@ -1097,7 +1103,7 @@ class curve_segment_evaluator {
// Distance along the curve is Integral[0,x] (sqrt(f'(x)^2 + 1) dx
// This functor is the derivative of y(x) => dy/dx = f'(x)
auto df = [lu=length_unit_,coeffY](double x) -> double {
auto df = [lu=length_unit_,coeffY,mapping=mapping_](double x) -> double {
auto begin = coeffY.begin();
auto iter = std::next(begin);
auto end = coeffY.end();
@@ -1132,7 +1138,7 @@ class curve_segment_evaluator {
// A numerical solution is required.
// This functor finds the value of x such that s(x) - u = 0, where u is the input value and s is the
// computed curve length.
x_at_dist_along = [curve_length_fn](double u) -> double {
x_at_dist_along = [curve_length_fn, this](double u) -> double {
std::uintmax_t max_iter = 9000;
auto tol = [](double a, double b) { return fabs(b - a) < 1.0E-11; };
auto x = u; // start by assuming u = x (it's not, but it will be close)
@@ -1143,7 +1149,7 @@ class curve_segment_evaluator {
auto result = boost::math::tools::bracket_and_solve_root(f, x, 2.0, true, tol, max_iter);
x = result.first;
} catch (...) {
logger::warning("root solver failed");
logger_.Warning("GEO", 253, "root solver failed");
}
return x;
};
@@ -1204,12 +1210,12 @@ class curve_segment_evaluator {
parent_curve_start_point_ = (*parent_curve_fn_)(0.0); // start is added to u in parent_curve_fn_, so use 0.0 here
} else if (segment_type_ == ST_CANT) {
logger::warning(std::runtime_error("Use of IfcPolynomialCurve for cant is not supported"));
mapping_->logger().Warning("UNS", 13, std::runtime_error("Use of IfcPolynomialCurve for cant is not supported"));
parent_curve_fn_ = std::make_shared<parent_curve_function>(
[](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); },
[](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); });
} else {
logger::error(std::runtime_error("Unexpected segment type encountered"));
mapping_->logger().Error("GEO", 254, std::runtime_error("Unexpected segment type encountered"));
parent_curve_fn_ = std::make_shared<parent_curve_function>(
[](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); },
[](double /*u*/) -> Eigen::Matrix4d { return Eigen::Matrix4d::Identity(); });
+2 -2
View File
@@ -25,14 +25,14 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcEdge& inst) {
auto v1 = inst.EdgeStart().as<IfcSchema::IfcVertexPoint>();
auto v2 = inst.EdgeEnd().as<IfcSchema::IfcVertexPoint>();
if (!v1 || !v2) {
logger::message(logger::LOG_ERROR, "Only IfcVertexPoints are supported for EdgeStart and -End", inst);
logger_.Message(Logger::LOG_ERROR, "GEO", 255, "Only IfcVertexPoints are supported for EdgeStart and -End", inst);
return nullptr;
}
auto pnt1 = v1.VertexGeometry();
auto pnt2 = v2.VertexGeometry();
if (!pnt1.declaration().is(IfcSchema::IfcCartesianPoint::Class()) || !pnt2.declaration().is(IfcSchema::IfcCartesianPoint::Class())) {
logger::message(logger::LOG_ERROR, "Only IfcCartesianPoints are supported for VertexGeometry", inst);
logger_.Message(Logger::LOG_ERROR, "GEO", 256, "Only IfcCartesianPoints are supported for VertexGeometry", inst);
return nullptr;
}
+1 -1
View File
@@ -26,7 +26,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcEllipse& inst) {
double y = inst.SemiAxis2() * length_unit_;
const double tol = settings_.get<settings::Precision>().get();
if (x < tol || y < tol) {
logger::message(logger::LOG_ERROR, "Radius not greater than zero for:", inst);
logger_.Message(Logger::LOG_ERROR, "GEO", 257, "Radius not greater than zero for:", inst);
return nullptr;
}
+1 -1
View File
@@ -26,7 +26,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcEllipseProfileDef& inst) {
double ry = inst.SemiAxis2() * length_unit_;
const double tol = settings_.get<settings::Precision>().get();
if (rx < tol || ry < tol) {
logger::message(logger::LOG_ERROR, "Radius not greater than zero for:", inst);
logger_.Message(Logger::LOG_ERROR, "GEO", 258, "Radius not greater than zero for:", inst);
return nullptr;
}
+1 -1
View File
@@ -27,7 +27,7 @@ using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcExtrudedAreaSolid& inst) {
const double height = inst.Depth() * length_unit_;
if (height < settings_.get<settings::Precision>().get()) {
logger::message(logger::LOG_ERROR, "Non-positive extrusion height encountered for:", inst);
logger_.Message(Logger::LOG_ERROR, "GEO", 89, "Non-positive extrusion height encountered for:", inst);
#ifndef PERMISSIVE_EXTRUSION
return nullptr;
#endif
@@ -27,7 +27,7 @@ using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcExtrudedAreaSolidTapered& inst) {
const double height = inst.Depth() * length_unit_;
if (height < settings_.get<settings::Precision>().get()) {
logger::message(logger::LOG_ERROR, "Non-positive extrusion height encountered for:", inst);
logger_.Message(Logger::LOG_ERROR, "GEO", 89, "Non-positive extrusion height encountered for:", inst);
return nullptr;
}
+4 -4
View File
@@ -26,7 +26,7 @@ using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcGradientCurve& inst) {
if (!inst.BaseCurve().as<IfcSchema::IfcCompositeCurve>())
logger::warning("Expected IfcGradientCurve.BaseCurve to be IfcCompositeCurve", inst); // CT 4.1.7.1.1.2
logger_.Warning("GEO", 261, "Expected IfcGradientCurve.BaseCurve to be IfcCompositeCurve", inst); // CT 4.1.7.1.1.2
auto segments = inst.Segments();
@@ -41,11 +41,11 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcGradientCurve& inst) {
// for this reason, a dynamic cast is used and if crv is a function_item it is added to the span
spans.push_back(fi);
} else {
logger::error("Unsupported");
logger_.Error("UNS", 14, "Unsupported");
return nullptr;
}
} else {
logger::error("Unsupported");
logger_.Error("UNS", 15, "Unsupported");
return nullptr;
}
}
@@ -73,7 +73,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcGradientCurve& inst) {
// check to see if there is valid overlap of the horizontal and vertical domains
if (!(0 < gradient_function->length())) {
logger::error("IfcGradientCurve does not have a common domain with BaseCurve");
logger_.Error("GEO", 262, "IfcGradientCurve does not have a common domain with BaseCurve");
gradient_function = nullptr; // not valid
}
+1 -1
View File
@@ -25,7 +25,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcHalfSpaceSolid& inst) {
auto surface = inst.BaseSurface();
auto plane = surface.as<IfcSchema::IfcPlane>();
if (!plane) {
logger::message(logger::LOG_ERROR, "Unsupported BaseSurface:", surface);
logger_.Message(Logger::LOG_ERROR, "UNS", 16, "Unsupported BaseSurface:", surface);
return nullptr;
}
auto p = taxonomy::make<taxonomy::plane>();
+1 -1
View File
@@ -80,7 +80,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcIShapeProfileDef& inst) {
const double tol = settings_.get<settings::Precision>().get();
if (x1 < tol || x2 < tol || y < tol || d1 < tol || ft1 < tol || ft2 < tol) {
logger::message(logger::LOG_NOTICE, "Skipping zero sized profile:", inst);
logger_.Message(Logger::LOG_NOTICE, "GEO", 264, "Skipping zero sized profile:", inst);
return nullptr;
}
+1 -1
View File
@@ -87,7 +87,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcIndexedPolyCurve& inst) {
e->basis = circ;
loop->children.push_back(e);
} else {
logger::warning("Ignoring segment on", inst);
logger_.Warning("GEO", 263, "Ignoring segment on", inst);
}
} else {
throw ifcopenshell::exception("Unexpected IfcIndexedPolyCurve segment of type " + segment.concrete().declaration().name());
+2 -2
View File
@@ -45,7 +45,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcLShapeProfileDef& inst) {
const double tol = settings_.get<settings::Precision>().get();
if ( x < tol || y < tol || d < tol) {
logger::message(logger::LOG_NOTICE, "Skipping zero sized profile:", inst);
logger_.Message(Logger::LOG_NOTICE, "GEO", 265, "Skipping zero sized profile:", inst);
return nullptr;
}
@@ -77,7 +77,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcLShapeProfileDef& inst) {
const double det = a1*b2 - a2*b1;
if (std::fabs(det) < 1.e-5) {
logger::message(logger::LOG_NOTICE, "Legs do not intersect for:", inst);
logger_.Message(Logger::LOG_NOTICE, "GEO", 266, "Legs do not intersect for:", inst);
return nullptr;
}
+37 -127
View File
@@ -21,7 +21,43 @@
#define mapping POSTFIX_SCHEMA(mapping)
using namespace ifcopenshell::geometry;
#include <deque>
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcObjectPlacement& inst) {
if (placement_rel_to_type_ || placement_rel_to_instance_) {
using QueueItem = std::pair<IfcSchema::IfcObjectPlacement, int>;
std::deque<QueueItem> q = {{inst, 0}};
while (!q.empty()) {
auto [placement, depth] = q.front();
q.pop_front();
if (!placement) {
continue;
}
std::vector<IfcSchema::IfcProduct> self_places = placement.PlacesObject();
for (auto& placed_product : self_places) {
if ((placement_rel_to_type_ && placed_product.declaration().is(*placement_rel_to_type_)) ||
(placement_rel_to_instance_ && placed_product == placement_rel_to_instance_)) {
return taxonomy::make<taxonomy::matrix4>();
}
}
// Look for two levels deep, we want to know if we're at or *above* the
// element we're ignoring, but we don't want to traverse the entire model.
#ifdef SCHEMA_IfcObjectPlacement_HAS_ReferencedByPlacements
if (depth < 2) {
std::vector<IfcSchema::IfcObjectPlacement> refs = placement.ReferencedByPlacements();
for (auto& ref : refs) {
q.emplace_back(ref, depth + 1);
}
}
#else
logger::warning("Using --site-local-placement or --building-local-placement on IFC4.2 might have issues");
#endif
}
}
IfcSchema::IfcObjectPlacement relative_to;
express::Base transform;
@@ -79,7 +115,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcObjectPlacement& inst) {
} else {
// The parent placement of the current is a placement for a type that is
// being ignored (Site or Building) or it is the host element of an opening.
// Create a new copy around `result` so that it's cached copy is not altered
// @todo immutability
result = taxonomy::make<taxonomy::matrix4>(
@@ -104,129 +140,3 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcObjectPlacement& inst) {
return result;
}
/*
// @todo
if (gridp = inst.as<IfcSchema::IfcGridPlacement>()) {
gp_Trsf grid_position;
auto axes = gridp->PlacementLocation()->IntersectingAxes();
auto offsets = gridp->PlacementLocation()->OffsetDistances();
Handle(Geom_Curve) c1, c2;
std::unique_ptr<GeomAPI_ExtremaCurveCurve> ecc;
#ifdef SCHEMA_IfcObjectPlacement_HAS_PlacementRelTo
// From 4.3 onwards the parent grid placement is directly referenced
// in the schema to translate the grid axes to world coords
convert(l->PlacementRelTo(), grid_position);
#else
IfcSchema::IfcGrid* grid = nullptr;
auto grids = (*axes->begin())->data().file->get_inverse<IfcSchema::IfcGrid>((*axes->begin())->data().id(), -1);
if (grids && grids->size()) {
grid = *grids->begin();
if (grid->ObjectPlacement()) {
convert(grid->ObjectPlacement(), grid_position);
}
}
#endif
auto get_point = [this, &c1, &c2, &ecc](IfcSchema::IfcVirtualGridIntersection const* x, gp_Pnt& P) {
auto axes = x->IntersectingAxes();
auto offsets = x->OffsetDistances();
if (axes->size() != 2) {
logger::message(logger::LOG_WARNING, "Unexpected grid axes count:" + std::to_string(axes->size()), x);
return false;
}
if (offsets.size() != 3) {
logger::message(logger::LOG_WARNING, "Unexpected offset count:" + std::to_string(offsets.size()), x);
return false;
}
auto first = *axes->begin();
auto second = *++axes->begin();
TopoDS_Wire w;
// Might display a lot of 'No operation defined for ...' messages
if (!convert_curve(first->AxisCurve(), c1)) {
if (!convert_wire(first->AxisCurve(), w)) {
return false;
}
double a, b;
c1 = BRep_Tool::Curve(TopoDS::Edge(TopoDS_Iterator(w).Value()), a, b);
}
if (!convert_curve(second->AxisCurve(), c2)) {
if (!convert_wire(second->AxisCurve(), w)) {
return false;
}
double a, b;
c2 = BRep_Tool::Curve(TopoDS::Edge(TopoDS_Iterator(w).Value()), a, b);
}
if (std::fabs(offsets[0]) > getValue(GV_PRECISION)) {
c1 = new Geom_OffsetCurve(c1, offsets[0], gp::DZ());
}
if (std::fabs(offsets[1]) > getValue(GV_PRECISION)) {
c2 = new Geom_OffsetCurve(c2, offsets[1], gp::DZ());
}
ecc.reset(new GeomAPI_ExtremaCurveCurve(c1, c2));
gp_Pnt pp1, pp2;
ecc->Points(1, pp1, pp2);
if (pp1.Distance(pp2) > getValue(GV_PRECISION)) {
logger::message(logger::LOG_WARNING, "No axis intersection:", x);
return false;
}
P = pp1;
return true;
};
gp_Pnt origin;
if (!get_point(gridp->PlacementLocation(), origin)) {
return false;
}
gp_Vec V;
gp_Dir D;
if (gridp->PlacementRefDirection()) {
IfcSchema::IfcDirection const* dir;
IfcSchema::IfcVirtualGridIntersection const* refx;
if ((dir = gridp->PlacementRefDirection()->as<IfcSchema::IfcDirection>())) {
if (!convert(dir, D)) {
return false;
}
} else if ((refx = gridp->PlacementRefDirection()->as<IfcSchema::IfcVirtualGridIntersection>())) {
gp_Pnt P;
if (!get_point(refx, P)) {
return false;
}
V = P.XYZ() - origin.XYZ();
if (V.Magnitude() > 1.e-9) {
D = V;
} else {
logger::message(logger::LOG_ERROR, "Unable to obtain ref direction:", l);
return false;
}
}
} else {
gp_Pnt tmp_;
double u1, u2;
ecc->Parameters(1, u1, u2);
c1->D1(u1, tmp_, V);
if (V.Magnitude() > 1.e-9) {
D = V;
} else {
logger::message(logger::LOG_ERROR, "Unable to obtain ref direction:", l);
return false;
}
}
// Can be applied post hoc because z component of offsets for origin
// and ref direction should be sme.
origin.SetZ(origin.Z() + offsets[2]);
gp_Ax2 ax(origin, gp::DZ(), D);
trsf.SetTransformation(ax, gp::XOY());
trsf.PreMultiply(grid_position);
}
*/
@@ -33,7 +33,7 @@ using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOffsetCurveByDistances& inst) {
auto offset_values = inst.OffsetValues();
if (offset_values.empty()) {
logger::error("IfcOffsetCurveByDistances must have at least one offset value");
logger_.Error("GEO", 270, "IfcOffsetCurveByDistances must have at least one offset value");
}
auto& first_offset_value = offset_values.front();
@@ -56,7 +56,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOffsetCurveByDistances& inst
auto basis_curve_fn = taxonomy::dcast<taxonomy::function_item>(map(basis_curve));
if (!basis_curve_fn) {
// Only implement on alignment curves
logger::warning("IfcOffsetCurveByDistances is only implemented for BasisCurves curves based on taxonomy::function_item", inst);
logger_.Warning("GEO", 271, "IfcOffsetCurveByDistances is only implemented for BasisCurves curves based on taxonomy::function_item", inst);
return nullptr;
}
@@ -73,7 +73,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOffsetCurveByDistances& inst
first_distance *= length_unit_;
if (first_distance < 0.0) {
logger::warning("IfcOffsetCurveByDistance first offset value is before the start of the curve.");
logger_.Warning("GEO", 272, "IfcOffsetCurveByDistance first offset value is before the start of the curve.");
}
if(0.0 < first_distance)
@@ -110,7 +110,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOffsetCurveByDistances& inst
if (dn < dp) // next is before previous
{
logger::warning("IfcOffsetCurveByDistance offset value is out of bounds.");
logger_.Warning("GEO", 273, "IfcOffsetCurveByDistance offset value is out of bounds.");
continue;
}
@@ -32,7 +32,7 @@ const double PI = boost::math::constants::pi<double>();
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOpenCrossProfileDef& inst) {
if (inst.ProfileType() != IfcSchema::IfcProfileTypeEnum::IfcProfileType_CURVE) {
logger::warning("Expected IfcOpenCrossProfileDef.ProfileType to be CURVE", inst);
logger_.Warning("GEO", 274, "Expected IfcOpenCrossProfileDef.ProfileType to be CURVE", inst);
return nullptr;
}
@@ -56,7 +56,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOpenCrossProfileDef& inst) {
auto angles = inst.Slopes(); // these are actually angles, but the attribute is called Slopes
if (widths.size() != angles.size()) {
logger::warning("Expected Widths and Slopes to be equal length, but got " + std::to_string(widths.size()) + " and " + std::to_string(angles.size()) + " respectively", inst);
logger_.Warning("GEO", 275, "Expected Widths and Slopes to be equal length, but got " + std::to_string(widths.size()) + " and " + std::to_string(angles.size()) + " respectively", inst);
return nullptr;
}
+4 -4
View File
@@ -36,7 +36,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPolyLoop& inst) {
// A loop should consist of at least three vertices
int original_count = polygon.size();
if (original_count < 3) {
logger::message(logger::LOG_WARNING, "Not enough edges for:", inst);
logger_.Message(Logger::LOG_WARNING, "GEO", 278, "Not enough edges for:", inst);
return nullptr;
}
@@ -45,17 +45,17 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPolyLoop& inst) {
auto previous_size = polygon.size();
remove_duplicate_points_from_loop(polygon, true, eps);
if (polygon.size() != previous_size) {
logger::warning("Removed " + std::to_string(previous_size - polygon.size()) + " (near) duplicate points from:", inst);
logger_.Warning("GEO", 279, "Removed " + std::to_string(previous_size - polygon.size()) + " (near) duplicate points from:", inst);
}
int count = polygon.size();
if (original_count - count != 0) {
std::stringstream ss; ss << (original_count - count) << " edges removed for:";
logger::message(logger::LOG_WARNING, ss.str(), inst);
logger_.Message(Logger::LOG_WARNING, "GEO", 280, ss.str(), inst);
}
if (count < 3) {
logger::message(logger::LOG_WARNING, "Not enough edges for:", inst);
logger_.Message(Logger::LOG_WARNING, "GEO", 281, "Not enough edges for:", inst);
return nullptr;
}
+2 -2
View File
@@ -44,12 +44,12 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPolyline& inst) {
auto previous_size = polygon.size();
remove_duplicate_points_from_loop(polygon, closed_by_proximity, eps);
if (polygon.size() != previous_size) {
logger::warning("Removed " + std::to_string(previous_size - polygon.size()) + " (near) duplicate points from:", inst);
logger_.Warning("GEO", 276, "Removed " + std::to_string(previous_size - polygon.size()) + " (near) duplicate points from:", inst);
}
if (polygon.size() < 2) {
// We somehow need to signal we fail this curve on purpose not to trigger an error.
logger::warning("Invalid polyline with " + std::to_string(polygon.size()) + " points:", inst);
logger_.Warning("GEO", 277, "Invalid polyline with " + std::to_string(polygon.size()) + " points:", inst);
return nullptr;
}
@@ -37,7 +37,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRectangleHollowProfileDef& i
const double tol = settings_.get<settings::Precision>().get();
if (x < tol || y < tol) {
logger::message(logger::LOG_NOTICE, "Skipping zero sized profile:", inst);
logger_.Message(Logger::LOG_NOTICE, "GEO", 282, "Skipping zero sized profile:", inst);
return nullptr;
}
@@ -30,7 +30,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRectangleProfileDef& inst) {
const double tol = settings_.get<settings::Precision>().get();
if (x < tol || y < tol) {
logger::message(logger::LOG_NOTICE, "Skipping zero sized profile:", inst);
logger_.Message(Logger::LOG_NOTICE, "GEO", 283, "Skipping zero sized profile:", inst);
return nullptr;
}
@@ -31,7 +31,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRoundedRectangleProfileDef&
const double tol = settings_.get<settings::Precision>().get();
if (x < tol || y < tol) {
logger::message(logger::LOG_NOTICE, "Skipping zero sized profile:", inst);
logger_.Message(Logger::LOG_NOTICE, "GEO", 284, "Skipping zero sized profile:", inst);
return nullptr;
}
@@ -34,7 +34,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSectionedSolidHorizontal& in
auto fn = taxonomy::dcast<taxonomy::function_item>(dir);
if (!fn) {
// Only implement on alignment curves
logger::warning("IfcSectionedSolidHorizontal is only implemented for Directrix curves based on taxonomy::function_item", inst);
logger_.Warning("GEO", 285, "IfcSectionedSolidHorizontal is only implemented for Directrix curves based on taxonomy::function_item", inst);
return nullptr;
}
@@ -91,11 +91,11 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSectionedSolidHorizontal& in
profile_rotations.push_back(rot);
}
if (faces.size() != profile_offsets.size()) {
logger::warning("Expected CrossSections and CrossSectionPositions to be equal length, but got " + std::to_string(faces.size()) + " and " + std::to_string(profile_offsets.size()) + " respectively", inst);
logger_.Warning("GEO", 286, "Expected CrossSections and CrossSectionPositions to be equal length, but got " + std::to_string(faces.size()) + " and " + std::to_string(profile_offsets.size()) + " respectively", inst);
return nullptr;
}
if (faces.size() < 2) {
logger::warning("Expected at least two cross sections, but got " + std::to_string(faces.size()), inst);
logger_.Warning("GEO", 287, "Expected at least two cross sections, but got " + std::to_string(faces.size()), inst);
return nullptr;
}
+3 -3
View File
@@ -34,7 +34,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSectionedSurface& inst) {
auto fn = taxonomy::dcast<taxonomy::function_item>(dir);
if (!fn) {
// Only implement on alignment curves
logger::warning("IfcSectionedSurface is only implemented for Directrix curves based on taxonomy::function_item", inst);
logger_.Warning("GEO", 288, "IfcSectionedSurface is only implemented for Directrix curves based on taxonomy::function_item", inst);
return nullptr;
}
@@ -97,11 +97,11 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSectionedSurface& inst) {
return nullptr;
#endif
if (faces.size() != profile_offsets.size()) {
logger::warning("Expected CrossSections and CrossSectionPositions to be equal length, but got " + std::to_string(faces.size()) + " and " + std::to_string(profile_offsets.size()) + " respectively", inst);
logger_.Warning("GEO", 289, "Expected CrossSections and CrossSectionPositions to be equal length, but got " + std::to_string(faces.size()) + " and " + std::to_string(profile_offsets.size()) + " respectively", inst);
return nullptr;
}
if (faces.size() < 2) {
logger::warning("Expected at least two cross sections, but got " + std::to_string(faces.size()), inst);
logger_.Warning("GEO", 290, "Expected at least two cross sections, but got " + std::to_string(faces.size()), inst);
return nullptr;
}
@@ -27,7 +27,7 @@ using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSegmentedReferenceCurve& inst) {
if (!inst.BaseCurve().as<IfcSchema::IfcGradientCurve>())
logger::warning("Expected IfcSegmentedReferenceCurve.BaseCurve to be IfcGradient", inst); // CT 4.1.7.1.1.3
logger_.Warning("GEO", 291, "Expected IfcSegmentedReferenceCurve.BaseCurve to be IfcGradient", inst); // CT 4.1.7.1.1.3
auto segments = inst.Segments();
@@ -41,11 +41,11 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSegmentedReferenceCurve& ins
// for this reason, a dynamic cast is used and if crv is a function_item it is added to the span
spans.push_back(fi);
} else {
logger::error("Unsupported");
logger_.Error("UNS", 17, "Unsupported");
return nullptr;
}
} else {
logger::error("Unsupported");
logger_.Error("UNS", 18, "Unsupported");
return nullptr;
}
}
@@ -67,7 +67,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSegmentedReferenceCurve& ins
auto cant_function = taxonomy::make<taxonomy::cant_function>(gradient, cant, inst);
if (!(0 < cant_function->length())) {
logger::error("IfcSegmentedReferenceCurve does not have a common domain with BaseCurve");
logger_.Error("GEO", 292, "IfcSegmentedReferenceCurve does not have a common domain with BaseCurve");
cant_function = nullptr;
}
return cant_function;
+1 -1
View File
@@ -62,7 +62,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSweptDiskSolid& inst) {
sp = inst.StartParam();
ep = inst.EndParam();
} catch (const ifcopenshell::exception& e) {
logger::warning(e);
logger_.Warning("GEO", 293, e);
}
#endif
+2 -2
View File
@@ -40,7 +40,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcTShapeProfileDef& inst) {
const double tol = settings_.get<settings::Precision>().get();
if (x < tol || y < tol || d1 < tol || d2 < tol) {
logger::message(logger::LOG_NOTICE, "Skipping zero sized profile:", inst);
logger_.Message(Logger::LOG_NOTICE, "GEO", 296, "Skipping zero sized profile:", inst);
return nullptr;
}
@@ -88,7 +88,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcTShapeProfileDef& inst) {
const double det = a1*b2 - a2*b1;
if (std::fabs(det) < 1.e-5) {
logger::message(logger::LOG_NOTICE, "Web and flange do not intersect for:", inst);
logger_.Message(Logger::LOG_NOTICE, "GEO", 297, "Web and flange do not intersect for:", inst);
return nullptr;
}
@@ -36,7 +36,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcTrapeziumProfileDef& inst) {
const double tol = settings_.get<settings::Precision>().get();
if (x1 < tol || w < tol || y < tol) {
logger::message(logger::LOG_NOTICE, "Skipping zero sized profile:", inst);
logger_.Message(Logger::LOG_NOTICE, "GEO", 294, "Skipping zero sized profile:", inst);
return nullptr;
}
+1 -1
View File
@@ -76,7 +76,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcTrimmedCurve& inst) {
bool trim_cartesian_failed = !trim_cartesian;
if (trim_cartesian) {
if ((pnts[0]->ccomponents() - pnts[1]->ccomponents()).norm() < (2 * tol)) {
logger::message(logger::LOG_WARNING, "Skipping segment with length below tolerance level:", inst);
logger_.Message(Logger::LOG_WARNING, "GEO", 295, "Skipping segment with length below tolerance level:", inst);
return nullptr;
}
tc->start = pnts[0];
+1 -1
View File
@@ -54,7 +54,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcUShapeProfileDef& inst) {
const double tol = settings_.get<settings::Precision>().get();
if (x < tol || y < tol || d1 < tol || d2 < tol) {
logger::message(logger::LOG_NOTICE, "Skipping zero sized profile:", inst);
logger_.Message(Logger::LOG_NOTICE, "GEO", 298, "Skipping zero sized profile:", inst);
return nullptr;
}
+1 -1
View File
@@ -45,7 +45,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcZShapeProfileDef& inst) {
const double tol = settings_.get<settings::Precision>().get();
if (x < tol || y < tol || dx < tol || dy < tol) {
logger::message(logger::LOG_NOTICE, "Skipping zero sized profile:", inst);
logger_.Message(Logger::LOG_NOTICE, "GEO", 299, "Skipping zero sized profile:", inst);
return nullptr;
}
+37 -33
View File
@@ -32,8 +32,8 @@ using namespace IfcGeom;
namespace {
struct POSTFIX_SCHEMA(factory_t) {
abstract_mapping* operator()(ifcopenshell::file* file, Settings& settings) const {
ifcopenshell::geometry::POSTFIX_SCHEMA(mapping)* m = new ifcopenshell::geometry::POSTFIX_SCHEMA(mapping)(file, settings);
abstract_mapping* operator()(ifcopenshell::file* file, Settings& settings, Logger& logger) const {
ifcopenshell::geometry::POSTFIX_SCHEMA(mapping)* m = new ifcopenshell::geometry::POSTFIX_SCHEMA(mapping)(file, settings, logger);
return m;
}
};
@@ -84,7 +84,7 @@ std::vector<IfcSchema::IfcProduct> mapping::products_represented_by(const IfcSch
try {
target = taxonomy::cast<taxonomy::matrix4>(map(item.MappingTarget()));
} catch (const std::exception& e) {
logger::error(e);
logger_.Error("GEO", 300, e);
continue;
}
if (!target->is_identity()) {
@@ -335,8 +335,8 @@ const express::Base mapping::get_single_material_association(const express::Base
try {
associated_material = associated_materials.front().RelatingMaterial().concrete();
} catch(ifcopenshell::exception& e) {
logger::error(e.what());
} catch(IfcParse::IfcException& e) {
logger_.Error("GEO", 301, e.what());
}
if (associated_material) {
@@ -349,7 +349,7 @@ const express::Base mapping::get_single_material_association(const express::Base
IfcSchema::IfcMaterialLayerSet layerset;
if (auto m = associated_material.as<IfcSchema::IfcMaterialLayerSetUsage>()) {
if (m.get("ForLayerSet").isNull()) {
logger::warning("Missing ForLayerSet for:", m);
logger_.Warning("GEO", 302, "Missing ForLayerSet for:", m);
return express::Base{};
}
layerset = m.ForLayerSet();
@@ -369,7 +369,7 @@ const express::Base mapping::get_single_material_association(const express::Base
IfcSchema::IfcMaterialProfileSet profileset;
if (auto m = associated_material.as<IfcSchema::IfcMaterialProfileSetUsage>()) {
if (m.get("ForProfileSet").isNull()) {
logger::warning("Missing ForProfileSet for:", m);
logger_.Warning("GEO", 303, "Missing ForProfileSet for:", m);
return express::Base{};
}
profileset = m.ForProfileSet();
@@ -414,7 +414,7 @@ IfcSchema::IfcRepresentation mapping::representation_mapped_to(const IfcSchema::
try {
target = taxonomy::cast<taxonomy::matrix4>(map(mapped_item.MappingTarget()));
} catch (const std::exception& e) {
logger::error(e);
logger_.Error("GEO", 304, e);
}
if (target && target->is_identity()) {
IfcSchema::IfcRepresentationMap rmap = mapped_item.MappingSource();
@@ -587,7 +587,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcMaterial& material) {
failed_on_purpose_.insert(material);
return nullptr;
}
logger::warning("Skipping unsupported material style for material: ", material);
logger_.Warning("UNS", 19, "Skipping unsupported material style for material: ", material);
}
}
@@ -620,7 +620,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcStyledItem& inst) {
if (!style) {
// E.g. IfcCurveStyle is skipped as unsupported.
logger::warning("Only IfcSurfaceStyle is supported, couldn't find it in IfcStyledItem: ", inst);
logger_.Warning("GEO", 305, "Only IfcSurfaceStyle is supported, couldn't find it in IfcStyledItem: ", inst);
failed_on_purpose_.insert(inst);
return nullptr;
}
@@ -714,6 +714,10 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSurfaceStyle& style) {
}
taxonomy::ptr mapping::map(const express::Base& inst) {
if (!inst) {
logger_.Error("GEO", 306, "Warning nullptr passed to map() function");
return nullptr;
}
auto iden = inst.identity();
if (use_caching_) {
std::lock_guard<std::mutex> guard(cache_guard_);
@@ -738,7 +742,7 @@ taxonomy::ptr mapping::map(const express::Base& inst) {
cache_.insert({iden, item});
}
} else if (!matched) {
logger::message(logger::LOG_ERROR, "No operation defined for:", inst);
logger_.Message(Logger::LOG_ERROR, "GEO", 307, "No operation defined for:", inst);
}
return item;
}
@@ -846,10 +850,10 @@ void mapping::initialize_units_() {
auto& project = projects.front();
unit_assignment = project.UnitsInContext();
} else {
logger::warning("Not a single project or context in file");
logger_.Warning("GEO", 308, "Not a single project or context in file");
}
if (!unit_assignment) {
logger::warning("Unable to detect unit information");
logger_.Warning("GEO", 309, "Unable to detect unit information");
return;
}
@@ -858,7 +862,7 @@ void mapping::initialize_units_() {
try {
auto units = unit_assignment.Units();
if (units.empty()) {
logger::warning("No unit information found");
logger_.Warning("GEO", 310, "No unit information found");
} else {
for (auto& base : units) {
if (auto named_unit = base.as<IfcSchema::IfcNamedUnit>()) {
@@ -891,15 +895,15 @@ void mapping::initialize_units_() {
} catch (const ifcopenshell::exception& ex) {
std::stringstream ss;
ss << "Failed to determine unit information '" << ex.what() << "'";
logger::message(logger::LOG_ERROR, ss.str());
logger_.Message(Logger::LOG_ERROR, "GEO", 311, ss.str());
}
if (!length_unit_encountered) {
logger::warning("No length unit encountered");
logger_.Warning("GEO", 312, "No length unit encountered");
}
if (!angle_unit_encountered) {
logger::warning("No plane angle unit encountered");
logger_.Warning("GEO", 313, "No plane angle unit encountered");
}
// @todo move to a more descriptive function
@@ -916,7 +920,7 @@ void mapping::initialize_units_() {
if (vs.size() == 3) {
offset_and_rotation_ *= Eigen::Affine3d(Eigen::Translation3d(vs[0], vs[1], vs[2])).matrix();
} else {
logger::error("Expected 3 values for model-offset setting");
logger_.Error("SYS", 31, "Expected 3 values for model-offset setting");
}
}
@@ -929,7 +933,7 @@ void mapping::initialize_units_() {
m4 << m3;
offset_and_rotation_ *= m4;
} else {
logger::error("Expected 4 values for model-rotation setting");
logger_.Error("SYS", 32, "Expected 4 values for model-rotation setting");
}
}
}
@@ -976,7 +980,7 @@ void mapping::initialize_settings() {
if (any_precision_encountered) {
if (lowest_precision_encountered < 1.e-7) {
logger::message(logger::LOG_WARNING, "Precision lower than 0.0000001 meter not enforced");
logger_.Message(Logger::LOG_WARNING, "SYS", 33, "Precision lower than 0.0000001 meter not enforced");
precision_to_set = 1.e-7;
} else {
precision_to_set = lowest_precision_encountered;
@@ -1013,7 +1017,7 @@ bool mapping::get_layerset_information(const express::Base& p, layerset_informat
IfcSchema::IfcRepresentation body_representation = find_representation(product, "Body");
if (!body_representation) {
logger::warning("No body representation for product", product);
logger_.Warning("GEO", 314, "No body representation for product", product);
return false;
}
@@ -1027,7 +1031,7 @@ bool mapping::get_layerset_information(const express::Base& p, layerset_informat
IfcSchema::IfcRepresentation axis_representation = find_representation(product, "Axis");
if (!axis_representation) {
logger::message(logger::LOG_WARNING, "No axis representation for:", product);
logger_.Message(Logger::LOG_WARNING, "GEO", 315, "No axis representation for:", product);
return false;
}
@@ -1102,7 +1106,7 @@ bool mapping::get_layerset_information(const express::Base& p, layerset_informat
}
if (extrusions.size() != 1) {
logger::message(logger::LOG_WARNING, "No single extrusion found in body representation for:", product);
logger_.Message(Logger::LOG_WARNING, "GEO", 316, "No single extrusion found in body representation for:", product);
return false;
}
@@ -1117,7 +1121,7 @@ bool mapping::get_layerset_information(const express::Base& p, layerset_informat
if (has_position) {
auto m4 = taxonomy::cast<taxonomy::matrix4>(map(extrusion.Position()));
if (!m4) {
logger::message(logger::LOG_ERROR, "Failed to convert placement for extrusion of:", product);
logger_.Message(Logger::LOG_ERROR, "GEO", 317, "Failed to convert placement for extrusion of:", product);
return false;
} else {
extrusion_position = m4;
@@ -1127,7 +1131,7 @@ bool mapping::get_layerset_information(const express::Base& p, layerset_informat
taxonomy::direction3::ptr extrusion_direction = taxonomy::cast<taxonomy::direction3>(map(extrusion.ExtrudedDirection()));
if (!extrusion_direction) {
logger::message(logger::LOG_ERROR, "Failed to convert direction for extrusion of:", product);
logger_.Message(Logger::LOG_ERROR, "GEO", 318, "Failed to convert direction for extrusion of:", product);
return false;
}
@@ -1199,13 +1203,13 @@ void mapping::addRepresentationsFromContextIds(std::vector<IfcSchema::IfcReprese
IfcSchema::IfcGeometricRepresentationContext context;
try {
context = file_->instance_by_id(context_id).as<IfcSchema::IfcGeometricRepresentationContext>();
} catch (ifcopenshell::exception& e) {
logger::error(e);
} catch (IfcParse::IfcException& e) {
logger_.Error("GEO", 319, e);
continue;
}
if (!context) {
logger::error("Failed to process context ID " + std::to_string(context_id));
logger_.Error("GEO", 320, "Failed to process context ID " + std::to_string(context_id));
continue;
}
@@ -1254,14 +1258,14 @@ void mapping::addRepresentationsFromDefaultContexts(std::vector<IfcSchema::IfcRe
boost::to_lower(context_type);
if (allowed_context_types.find(context_type) == allowed_context_types.end()) {
logger::warning(std::string("ContextType '") + *context.ContextType() + "' not allowed:", context);
logger_.Warning("GEO", 321, std::string("ContextType '") + *context->ContextType() + "' not allowed:", context);
}
if (context_types.find(context_type) != context_types.end()) {
filtered_contexts.push_back(context);
}
}
} catch (const std::exception& e) {
logger::error(e);
logger_.Error("GEO", 322, e);
}
}
@@ -1290,7 +1294,7 @@ void mapping::addRepresentationsFromDefaultContexts(std::vector<IfcSchema::IfcRe
}
if (representations.empty()) {
logger::warning("No representations encountered in relevant contexts, using all");
logger_.Warning("GEO", 323, "No representations encountered in relevant contexts, using all");
auto all_reps = file_->instances_by_type<IfcSchema::IfcRepresentation>();
representations = all_reps;
}
@@ -1371,8 +1375,8 @@ express::Base mapping::representation_of(const express::Base& product) {
}
intersection_no_box.push_back(r);
}
if (intersection_no_box.size() > 1) {
logger::warning("Multiple applicable representations found for element, selecting arbitrary");
if (intersection_no_box->size() > 1) {
logger_.Warning("GEO", 324, "Multiple applicable representations found for element, selecting arbitrary");
}
if (intersection_no_box.size()) {
return intersection_no_box.front();
+7 -11
View File
@@ -7,15 +7,11 @@
#include "../../ifcparse/logger.h"
#include <mutex>
#include <unordered_set>
#include <cstdint>
#include <unordered_set>
#define INCLUDE_SCHEMA(x) STRINGIFY(../../ifcparse/schemas/x.h)
#include INCLUDE_SCHEMA(IfcSchema)
#undef INCLUDE_SCHEMA
#define INCLUDE_SCHEMA(x) STRINGIFY(../../ifcparse/schemas/x-definitions.h)
#include INCLUDE_SCHEMA(IfcSchema)
#undef INCLUDE_SCHEMA
#include INCLUDE_SCHEMA(../../ifcparse, IfcSchema)
#include INCLUDE_SCHEMA_DEFINITIONS(../../ifcparse, IfcSchema)
namespace ifcopenshell {
@@ -75,19 +71,19 @@ namespace geometry {
}
}
} catch (const std::exception& e) {
logger::message(logger::LOG_ERROR, std::string(e.what()) + "\nFailed to convert:", inst);
logger_.Message(Logger::LOG_ERROR, "GEO", 325, std::string(e.what()) + "\nFailed to convert:", inst);
}
} else if (failed_on_purpose_.find(inst) == failed_on_purpose_.end()) {
logger::message(logger::LOG_ERROR, "Failed to convert:", inst);
logger_.Message(Logger::LOG_ERROR, "GEO", 326, "Failed to convert:", inst);
}
} catch (const std::exception& e) {
logger::message(logger::LOG_ERROR, std::string(e.what()) + "\nFailed to convert:", inst);
logger_.Message(Logger::LOG_ERROR, "GEO", 327, std::string(e.what()) + "\nFailed to convert:", inst);
}
}
}
IfcSchema::IfcStyledItem find_style(const IfcSchema::IfcRepresentationItem&);
public:
POSTFIX_SCHEMA(mapping)(ifcopenshell::file* file, Settings& settings) : abstract_mapping(settings), file_(file), placement_rel_to_type_(nullptr) {
POSTFIX_SCHEMA(mapping)(ifcopenshell::file* file, Settings& settings, Logger& logger = Logger::Root()) : abstract_mapping(settings), file_(file), placement_rel_to_type_(nullptr) {
initialize_units_();
}
virtual ifcopenshell::geometry::taxonomy::ptr map(const express::Base&);