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
+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(); });