Work towards v1.0 data model with encapsulated weak_ptr as basis for instances

This commit is contained in:
Thomas Krijnen
2026-01-04 10:40:02 +01:00
parent f09ca658f1
commit 7098beb819
210 changed files with 28269 additions and 26471 deletions
+133 -137
View File
@@ -44,19 +44,19 @@ enum segment_type_t {
// @todo use std::numbers::pi when upgrading to C++ 20
static const double PI = boost::math::constants::pi<double>();
double translate_to_length_measure(const IfcSchema::IfcCurve* crv, double param_value) {
double translate_to_length_measure(const IfcSchema::IfcCurve& crv, double param_value) {
if (std::abs(param_value) < 1.e-7) {
return param_value;
} else if (auto line = crv->as<IfcSchema::IfcLine>()) {
return line->Dir()->Magnitude() * param_value;
} else if (auto clothoid = crv->as<IfcSchema::IfcClothoid>()) {
} else if (auto line = crv.as<IfcSchema::IfcLine>()) {
return line.Dir().Magnitude() * param_value;
} else if (auto clothoid = crv.as<IfcSchema::IfcClothoid>()) {
// param_value = 1.0, corresponds to tangent direction = PI/2
// param_value = (arc length)/fabs(A*PI)
return fabs(clothoid->ClothoidConstant()*sqrt(PI))*param_value;
} else if (auto circ = crv->as<IfcSchema::IfcCircle>()) {
return circ->Radius() * param_value;
return fabs(clothoid.ClothoidConstant()*sqrt(PI))*param_value;
} else if (auto circ = crv.as<IfcSchema::IfcCircle>()) {
return circ.Radius() * param_value;
#ifdef SCHEMA_HAS_IfcPolynomialCurve
} else if (auto poly = crv->as<IfcSchema::IfcPolynomialCurve>()) {
} else if (auto poly = crv.as<IfcSchema::IfcPolynomialCurve>()) {
return param_value;
#endif
} else {
@@ -64,12 +64,12 @@ double translate_to_length_measure(const IfcSchema::IfcCurve* crv, double param_
}
}
double translate_if_param_value(const IfcSchema::IfcCurve* crv, IfcSchema::IfcCurveMeasureSelect* val) {
if (auto param = val->as<IfcSchema::IfcParameterValue>()) {
double translate_if_param_value(const IfcSchema::IfcCurve& crv, const IfcSchema::IfcCurveMeasureSelect& val) {
if (auto param = val.as<IfcSchema::IfcParameterValue>()) {
// We don't care whether length- or positive length measure.
return translate_to_length_measure(crv, *param);
return translate_to_length_measure(crv, param);
} else {
return val->as<IfcUtil::IfcBaseClass>()->get_attribute_value(0);
return val.concrete().get_attribute_value(0);
}
}
@@ -181,12 +181,12 @@ struct cant_curve_segment_function {
class curve_segment_evaluator {
private:
mapping* mapping_ = nullptr;
const IfcSchema::IfcCurveSegment* inst_ = nullptr; // this curve segment instance
IfcSchema::IfcCurveSegment inst_; // this curve segment instance
double length_unit_;
double start_;
double length_; // length along the curve, as provided from the IfcCurveSegment
segment_type_t segment_type_;
const IfcSchema::IfcCurve* parent_curve_ = nullptr;
IfcSchema::IfcCurve parent_curve_;
double projected_length_; // for vertical segments, this is the length of curve projected onto the "Distance Along" axis
@@ -197,51 +197,47 @@ class curve_segment_evaluator {
std::optional<Eigen::Matrix4d> next_segment_placement_; // placement of the next segment
public:
curve_segment_evaluator(mapping* mapping, const IfcSchema::IfcCurveSegment* inst, double length_unit)
curve_segment_evaluator(mapping* mapping, const IfcSchema::IfcCurveSegment& inst, double length_unit)
: mapping_(mapping),
inst_(inst),
length_unit_(length_unit),
parent_curve_(inst->ParentCurve()) {
parent_curve_(inst.ParentCurve()) {
#ifdef SCHEMA_IfcSegment_HAS_UsingCurves
auto composite_curves = inst->UsingCurves();
auto composite_curves = inst.UsingCurves();
#else
aggregate_of<IfcSchema::IfcCompositeCurve>::ptr composite_curves;
throw std::runtime_error("Schema not supported");
#endif
// Find the next segment after inst
const IfcSchema::IfcCurveSegment* next_inst = nullptr;
if (composite_curves) {
if (composite_curves->size() == 1) {
auto segments = (*composite_curves->begin())->as<IfcSchema::IfcCompositeCurve>()->Segments();
bool emit_next = false;
for (auto& s : *segments) {
if (emit_next) {
next_inst = s->as<IfcSchema::IfcCurveSegment>();
break;
}
if (s == inst) {
emit_next = true;
}
IfcSchema::IfcCurveSegment next_inst;
if (composite_curves.size() == 1) {
auto segments = composite_curves.front().as<IfcSchema::IfcCompositeCurve>().Segments();
bool emit_next = false;
for (auto& s : segments) {
if (emit_next) {
next_inst = s.as<IfcSchema::IfcCurveSegment>();
break;
}
if (s == inst) {
emit_next = true;
}
} else {
Logger::Warning("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.");
}
bool is_horizontal = false;
bool is_vertical = false;
bool is_cant = false;
if (composite_curves) {
for (auto& cc : *composite_curves) {
if (cc->as<IfcSchema::IfcSegmentedReferenceCurve>()) {
is_cant = true;
} else if (cc->as<IfcSchema::IfcGradientCurve>()) {
is_vertical = true;
} else {
is_horizontal = true;
}
for (auto& cc : composite_curves) {
if (cc.as<IfcSchema::IfcSegmentedReferenceCurve>()) {
is_cant = true;
} else if (cc.as<IfcSchema::IfcGradientCurve>()) {
is_vertical = true;
} else {
is_horizontal = true;
}
}
@@ -254,36 +250,36 @@ class curve_segment_evaluator {
segment_type_ = is_horizontal ? ST_HORIZONTAL : is_vertical ? ST_VERTICAL : is_cant ? ST_CANT : ST_HORIZONTAL;
#ifdef SCHEMA_IfcCurveSegment_HAS_SegmentStart
start_ = translate_if_param_value(inst->ParentCurve(), inst->SegmentStart()) * length_unit;
start_ = translate_if_param_value(inst.ParentCurve(), inst.SegmentStart()) * length_unit;
#else
throw std::runtime_error("Schema not supported");
#endif
length_ = translate_if_param_value(inst->ParentCurve(), inst->SegmentLength()) * length_unit;
length_ = translate_if_param_value(inst.ParentCurve(), inst.SegmentLength()) * length_unit;
projected_length_ = length_; // initialize with something reasonable
if (inst) {
#ifdef SCHEMA_IfcCurveSegment_HAS_Placement
curve_segment_placement_ = taxonomy::cast<taxonomy::matrix4>(mapping_->map(inst->Placement()))->ccomponents();
curve_segment_placement_ = taxonomy::cast<taxonomy::matrix4>(mapping_->map(inst.Placement()))->ccomponents();
#endif
}
if (next_inst) {
#ifdef SCHEMA_IfcCurveSegment_HAS_Placement
next_segment_placement_ = taxonomy::cast<taxonomy::matrix4>(mapping_->map(next_inst->Placement()))->ccomponents();
next_segment_placement_ = taxonomy::cast<taxonomy::matrix4>(mapping_->map(next_inst.Placement()))->ccomponents();
#endif
} else {
// there is not a next segment, however IfcGradientCurve and IfcSegmentReferenceCurve have an
// optional EndPoint which services the same purpose as the zero-length last segment.
IfcSchema::IfcPlacement* end_point = nullptr;
if (composite_curves->size() == 1) {
auto& cc = *(composite_curves)->begin();
IfcSchema::IfcPlacement end_point;
if (composite_curves.size() == 1) {
auto& cc = composite_curves.front();
if (segment_type_ == ST_VERTICAL) {
auto gradient_curve = cc->as<IfcSchema::IfcGradientCurve>();
auto gradient_curve = cc.as<IfcSchema::IfcGradientCurve>();
#ifdef SCHEMA_IfcCurveSegment_HAS_Placement
end_point = gradient_curve->EndPoint();
end_point = gradient_curve.EndPoint();
#endif
} else if (segment_type_ == ST_CANT) {
auto segmented_reference_curve = cc->as<IfcSchema::IfcSegmentedReferenceCurve>();
end_point = segmented_reference_curve->EndPoint();
auto segmented_reference_curve = cc.as<IfcSchema::IfcSegmentedReferenceCurve>();
end_point = segmented_reference_curve.EndPoint();
}
} else {
Logger::Warning("IfcCurveSegment belongs to multiple IfcCompositeCurve instances. Cannot determine the end point.");
@@ -297,8 +293,8 @@ class curve_segment_evaluator {
// Take the boost::type value from mpl::for_each and test it against our curve instance
template <typename T>
void operator()(boost::type<T>) {
if (parent_curve_->as<T>()) {
(*this)(parent_curve_->as<T>());
if (parent_curve_.as<T>()) {
(*this)(parent_curve_.as<T>());
}
}
@@ -308,7 +304,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_);
Logger::Error(std::runtime_error(inst_.ParentCurve().declaration().name() + " not implemented"), inst_);
}
auto length = fabs(this->length());
@@ -521,9 +517,9 @@ class curve_segment_evaluator {
// returns function for super elevation and the slope of the super elevation curve if the super elevation is constant
// over the length of the segment. otherwise, no functions are returned because they are the same as the cant tilt angle
// functions.
std::pair<boost::optional<std::function<double(double)>>, boost::optional<std::function<double(double)>>> get_superelevation_functions() {
boost::optional<std::function<double(double)>> superelevation_fn;
boost::optional<std::function<double(double)>> superelevation_slope_fn;
std::pair<std::optional<std::function<double(double)>>, std::optional<std::function<double(double)>>> get_superelevation_functions() {
std::optional<std::function<double(double)>> superelevation_fn;
std::optional<std::function<double(double)>> superelevation_slope_fn;
if (curve_segment_placement_.has_value() && next_segment_placement_.has_value()) {
double y1 = (*curve_segment_placement_)(1, 3);
@@ -541,12 +537,12 @@ class curve_segment_evaluator {
}
#ifdef SCHEMA_HAS_IfcClothoid
void operator()(const IfcSchema::IfcClothoid* c) {
auto A = c->ClothoidConstant() * length_unit_;
void operator()(const IfcSchema::IfcClothoid& c) {
auto A = c.ClothoidConstant() * length_unit_;
auto L = length(); // already includes length_unit_
if (segment_type_ == ST_CANT) {
boost::optional<std::function<double(double)>> super, slope;
std::optional<std::function<double(double)>> super, slope;
std::tie(super, slope) = get_superelevation_functions();
auto cant = [A, L](double t) -> double { return A ? L * L * A * t / fabs(pow(A, 3)) : 0.0; };
@@ -570,12 +566,12 @@ class curve_segment_evaluator {
#endif
#if defined SCHEMA_HAS_IfcCosineSpiral
void operator()(const IfcSchema::IfcCosineSpiral* c) {
auto constant_term = c->ConstantTerm();
void operator()(const IfcSchema::IfcCosineSpiral& c) {
auto constant_term = c.ConstantTerm();
if (constant_term.has_value()) {
constant_term.value() *= length_unit_;
}
auto cosine_term = c->CosineTerm() * length_unit_;
auto cosine_term = c.CosineTerm() * length_unit_;
auto L = length(); // already converted to internal units by constructor
if (segment_type_ == ST_HORIZONTAL) {
@@ -594,7 +590,7 @@ class curve_segment_evaluator {
double s = 1.0;
set_spiral_function(s, fn_x, fn_y, curvature);
} else if (segment_type_ == ST_CANT) {
boost::optional<std::function<double(double)>> super, slope;
std::optional<std::function<double(double)>> super, slope;
std::tie(super, slope) = get_superelevation_functions();
auto cant = [constant_term, cosine_term, L](double t) -> double {
@@ -632,16 +628,16 @@ class curve_segment_evaluator {
#endif
#if defined SCHEMA_HAS_IfcSineSpiral
void operator()(const IfcSchema::IfcSineSpiral* c) {
auto constant_term = c->ConstantTerm();
void operator()(const IfcSchema::IfcSineSpiral& c) {
auto constant_term = c.ConstantTerm();
if (constant_term.has_value()) {
constant_term.value() *= length_unit_;
}
auto linear_term = c->LinearTerm();
auto linear_term = c.LinearTerm();
if (linear_term.has_value()) {
linear_term.value() *= length_unit_;
}
auto sine_term = c->SineTerm() * length_unit_;
auto sine_term = c.SineTerm() * length_unit_;
auto L = length(); // already converted to internal units by constructor
if (segment_type_ == ST_HORIZONTAL) {
auto theta = [constant_term, linear_term, sine_term, L](double t) -> double {
@@ -661,7 +657,7 @@ class curve_segment_evaluator {
double s = 1.0;
set_spiral_function(s, fn_x, fn_y, curvature);
} else if (segment_type_ == ST_CANT) {
boost::optional<std::function<double(double)>> super, slope;
std::optional<std::function<double(double)>> super, slope;
std::tie(super, slope) = get_superelevation_functions();
auto cant = [constant_term, linear_term, sine_term, L](double t) -> double {
@@ -698,16 +694,16 @@ class curve_segment_evaluator {
}
#endif
void polynomial_spiral(boost::optional<double> A0, boost::optional<double> A1, boost::optional<double> A2, boost::optional<double> A3, boost::optional<double> A4, boost::optional<double> A5, boost::optional<double> A6, boost::optional<double> A7) {
void polynomial_spiral(std::optional<double> A0, std::optional<double> A1, std::optional<double> A2, std::optional<double> A3, std::optional<double> A4, std::optional<double> A5, std::optional<double> A6, std::optional<double> A7) {
auto theta = [A0, A1, A2, A3, A4, A5, A6, A7, start = start_ * length_unit_, lu = length_unit_](double t) -> double {
auto a0 = A0.get_value_or(0.0) != 0.0 ? t / (A0.value() * lu) : 0.0;
auto a1 = A1.get_value_or(0.0) != 0.0 ? A1.value() * lu * std::pow(t, 2) / (2 * fabs(std::pow(A1.value() * lu, 3))) : 0.0;
auto a2 = A2.get_value_or(0.0) != 0.0 ? std::pow(t, 3) / (3 * std::pow(A2.value() * lu, 3)) : 0.0;
auto a3 = A3.get_value_or(0.0) != 0.0 ? A3.value() * lu * std::pow(t, 4) / (4 * fabs(std::pow(A3.value() * lu, 5))) : 0.0;
auto a4 = A4.get_value_or(0.0) != 0.0 ? std::pow(t, 5) / (5 * std::pow(A4.value() * lu, 5)) : 0.0;
auto a5 = A5.get_value_or(0.0) != 0.0 ? A5.value() * lu * std::pow(t, 6) / (6 * fabs(std::pow(A5.value() * lu, 7))) : 0.0;
auto a6 = A6.get_value_or(0.0) != 0.0 ? std::pow(t, 7) / (7 * std::pow(A6.value() * lu, 7)) : 0.0;
auto a7 = A7.get_value_or(0.0) != 0.0 ? A7.value() * lu * std::pow(t, 8) / (8 * fabs(std::pow(A7.value() * lu, 9))) : 0.0;
auto a0 = A0.value_or(0.0) != 0.0 ? t / (A0.value() * lu) : 0.0;
auto a1 = A1.value_or(0.0) != 0.0 ? A1.value() * lu * std::pow(t, 2) / (2 * fabs(std::pow(A1.value() * lu, 3))) : 0.0;
auto a2 = A2.value_or(0.0) != 0.0 ? std::pow(t, 3) / (3 * std::pow(A2.value() * lu, 3)) : 0.0;
auto a3 = A3.value_or(0.0) != 0.0 ? A3.value() * lu * std::pow(t, 4) / (4 * fabs(std::pow(A3.value() * lu, 5))) : 0.0;
auto a4 = A4.value_or(0.0) != 0.0 ? std::pow(t, 5) / (5 * std::pow(A4.value() * lu, 5)) : 0.0;
auto a5 = A5.value_or(0.0) != 0.0 ? A5.value() * lu * std::pow(t, 6) / (6 * fabs(std::pow(A5.value() * lu, 7))) : 0.0;
auto a6 = A6.value_or(0.0) != 0.0 ? std::pow(t, 7) / (7 * std::pow(A6.value() * lu, 7)) : 0.0;
auto a7 = A7.value_or(0.0) != 0.0 ? A7.value() * lu * std::pow(t, 8) / (8 * fabs(std::pow(A7.value() * lu, 9))) : 0.0;
return a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7;
};
@@ -718,14 +714,14 @@ class curve_segment_evaluator {
// this is same as cant function in polynomial_cant_spiral
auto curvature = [A0, A1, A2, A3, A4, A5, A6, A7, start = start_, L = length_, lu = length_unit_, length = length_](double t) -> double {
t += start;
auto a0 = A0.get_value_or(0.0) != 0.0 ? 1 / (A0.value() * lu) : 0.0;
auto a1 = A1.get_value_or(0.0) != 0.0 ? A1.value() * lu * t / fabs(std::pow(A1.value() * lu, 3)) : 0.0;
auto a2 = A2.get_value_or(0.0) != 0.0 ? std::pow(t, 2) / std::pow(A2.value() * lu, 3) : 0.0;
auto a3 = A3.get_value_or(0.0) != 0.0 ? A3.value() * lu * std::pow(t, 3) / fabs(std::pow(A3.value() * lu, 5)) : 0.0;
auto a4 = A4.get_value_or(0.0) != 0.0 ? std::pow(t, 4) / std::pow(A4.value() * lu, 5) : 0.0;
auto a5 = A5.get_value_or(0.0) != 0.0 ? A5.value() * lu * std::pow(t, 5) / fabs(std::pow(A5.value() * lu, 7)) : 0.0;
auto a6 = A6.get_value_or(0.0) != 0.0 ? std::pow(t, 6) / std::pow(A6.value() * lu, 7) : 0.0;
auto a7 = A7.get_value_or(0.0) != 0.0 ? A7.value() * lu * std::pow(t, 7) / fabs(std::pow(A7.value() * lu, 9)) : 0.0;
auto a0 = A0.value_or(0.0) != 0.0 ? 1 / (A0.value() * lu) : 0.0;
auto a1 = A1.value_or(0.0) != 0.0 ? A1.value() * lu * t / fabs(std::pow(A1.value() * lu, 3)) : 0.0;
auto a2 = A2.value_or(0.0) != 0.0 ? std::pow(t, 2) / std::pow(A2.value() * lu, 3) : 0.0;
auto a3 = A3.value_or(0.0) != 0.0 ? A3.value() * lu * std::pow(t, 3) / fabs(std::pow(A3.value() * lu, 5)) : 0.0;
auto a4 = A4.value_or(0.0) != 0.0 ? std::pow(t, 4) / std::pow(A4.value() * lu, 5) : 0.0;
auto a5 = A5.value_or(0.0) != 0.0 ? A5.value() * lu * std::pow(t, 5) / fabs(std::pow(A5.value() * lu, 7)) : 0.0;
auto a6 = A6.value_or(0.0) != 0.0 ? std::pow(t, 6) / std::pow(A6.value() * lu, 7) : 0.0;
auto a7 = A7.value_or(0.0) != 0.0 ? A7.value() * lu * std::pow(t, 7) / fabs(std::pow(A7.value() * lu, 9)) : 0.0;
return L * (a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7);
};
@@ -734,20 +730,20 @@ class curve_segment_evaluator {
set_spiral_function(s, fn_x, fn_y, curvature);
}
void polynomial_cant_spiral(boost::optional<double> A0, boost::optional<double> A1, boost::optional<double> A2, boost::optional<double> A3, boost::optional<double> A4, boost::optional<double> A5, boost::optional<double> A6, boost::optional<double> A7) {
boost::optional<std::function<double(double)>> super, slope;
void polynomial_cant_spiral(std::optional<double> A0, std::optional<double> A1, std::optional<double> A2, std::optional<double> A3, std::optional<double> A4, std::optional<double> A5, std::optional<double> A6, std::optional<double> A7) {
std::optional<std::function<double(double)>> super, slope;
std::tie(super, slope) = get_superelevation_functions();
auto cant = [A0, A1, A2, A3, A4, A5, A6, A7, start = start_, L = length_, lu = length_unit_, length = length_](double t) -> double {
t += start;
auto a0 = A0.get_value_or(0.0) != 0.0 ? 1 / (A0.value() * lu) : 0.0;
auto a1 = A1.get_value_or(0.0) != 0.0 ? A1.value() * lu * t / fabs(std::pow(A1.value() * lu, 3)) : 0.0;
auto a2 = A2.get_value_or(0.0) != 0.0 ? std::pow(t, 2) / std::pow(A2.value() * lu, 3) : 0.0;
auto a3 = A3.get_value_or(0.0) != 0.0 ? A3.value() * lu * std::pow(t, 3) / fabs(std::pow(A3.value() * lu, 5)) : 0.0;
auto a4 = A4.get_value_or(0.0) != 0.0 ? std::pow(t, 4) / std::pow(A4.value() * lu, 5) : 0.0;
auto a5 = A5.get_value_or(0.0) != 0.0 ? A5.value() * lu * std::pow(t, 5) / fabs(std::pow(A5.value() * lu, 7)) : 0.0;
auto a6 = A6.get_value_or(0.0) != 0.0 ? std::pow(t, 6) / std::pow(A6.value() * lu, 7) : 0.0;
auto a7 = A7.get_value_or(0.0) != 0.0 ? A7.value() * lu * std::pow(t, 7) / fabs(std::pow(A7.value() * lu, 9)) : 0.0;
auto a0 = A0.value_or(0.0) != 0.0 ? 1 / (A0.value() * lu) : 0.0;
auto a1 = A1.value_or(0.0) != 0.0 ? A1.value() * lu * t / fabs(std::pow(A1.value() * lu, 3)) : 0.0;
auto a2 = A2.value_or(0.0) != 0.0 ? std::pow(t, 2) / std::pow(A2.value() * lu, 3) : 0.0;
auto a3 = A3.value_or(0.0) != 0.0 ? A3.value() * lu * std::pow(t, 3) / fabs(std::pow(A3.value() * lu, 5)) : 0.0;
auto a4 = A4.value_or(0.0) != 0.0 ? std::pow(t, 4) / std::pow(A4.value() * lu, 5) : 0.0;
auto a5 = A5.value_or(0.0) != 0.0 ? A5.value() * lu * std::pow(t, 5) / fabs(std::pow(A5.value() * lu, 7)) : 0.0;
auto a6 = A6.value_or(0.0) != 0.0 ? std::pow(t, 6) / std::pow(A6.value() * lu, 7) : 0.0;
auto a7 = A7.value_or(0.0) != 0.0 ? A7.value() * lu * std::pow(t, 7) / fabs(std::pow(A7.value() * lu, 9)) : 0.0;
return L * L * (a0 + a1 + a2 + a3 + a4 + a5 + a6 + a7);
};
@@ -758,13 +754,13 @@ class curve_segment_evaluator {
if (!slope.has_value()) {
slope = [A1, A2, A3, A4, A5, A6, A7, start = start_, L = length_, lu = length_unit_, length = length_](double t) -> double {
t += start;
auto a1 = A1.get_value_or(0.0) != 0.0 ? A1.value() * lu / fabs(std::pow(A1.value() * lu, 3)) : 0.0;
auto a2 = A2.get_value_or(0.0) != 0.0 ? 2 * t / std::pow(A2.value() * lu, 3) : 0.0;
auto a3 = A3.get_value_or(0.0) != 0.0 ? 3 * A3.value() * lu * std::pow(t, 2) / fabs(std::pow(A3.value() * lu, 5)) : 0.0;
auto a4 = A4.get_value_or(0.0) != 0.0 ? 4 * std::pow(t, 3) / std::pow(A4.value() * lu, 5) : 0.0;
auto a5 = A5.get_value_or(0.0) != 0.0 ? 5 * A5.value() * lu * std::pow(t, 4) / fabs(std::pow(A5.value() * lu, 7)) : 0.0;
auto a6 = A6.get_value_or(0.0) != 0.0 ? 6 * std::pow(t, 5) / std::pow(A6.value() * lu, 7) : 0.0;
auto a7 = A7.get_value_or(0.0) != 0.0 ? 7 * A7.value() * lu * std::pow(t, 6) / fabs(std::pow(A7.value() * lu, 9)) : 0.0;
auto a1 = A1.value_or(0.0) != 0.0 ? A1.value() * lu / fabs(std::pow(A1.value() * lu, 3)) : 0.0;
auto a2 = A2.value_or(0.0) != 0.0 ? 2 * t / std::pow(A2.value() * lu, 3) : 0.0;
auto a3 = A3.value_or(0.0) != 0.0 ? 3 * A3.value() * lu * std::pow(t, 2) / fabs(std::pow(A3.value() * lu, 5)) : 0.0;
auto a4 = A4.value_or(0.0) != 0.0 ? 4 * std::pow(t, 3) / std::pow(A4.value() * lu, 5) : 0.0;
auto a5 = A5.value_or(0.0) != 0.0 ? 5 * A5.value() * lu * std::pow(t, 4) / fabs(std::pow(A5.value() * lu, 7)) : 0.0;
auto a6 = A6.value_or(0.0) != 0.0 ? 6 * std::pow(t, 5) / std::pow(A6.value() * lu, 7) : 0.0;
auto a7 = A7.value_or(0.0) != 0.0 ? 7 * A7.value() * lu * std::pow(t, 6) / fabs(std::pow(A7.value() * lu, 9)) : 0.0;
return L * L * (a1 + a2 + a3 + a4 + a5 + a6 + a7);
};
}
@@ -773,11 +769,11 @@ class curve_segment_evaluator {
}
#ifdef SCHEMA_HAS_IfcSecondOrderPolynomialSpiral
void operator()(const IfcSchema::IfcSecondOrderPolynomialSpiral* c) {
auto A0 = c->ConstantTerm();
auto A1 = c->LinearTerm();
auto A2 = c->QuadraticTerm();
boost::optional<double> A3, A4, A5, A6, A7;
void operator()(const IfcSchema::IfcSecondOrderPolynomialSpiral& c) {
auto A0 = c.ConstantTerm();
auto A1 = c.LinearTerm();
auto A2 = c.QuadraticTerm();
std::optional<double> A3, A4, A5, A6, A7;
if (segment_type_ == ST_CANT) {
polynomial_cant_spiral(A0, A1, A2, A3, A4, A5, A6, A7);
@@ -788,15 +784,15 @@ class curve_segment_evaluator {
#endif
#ifdef SCHEMA_HAS_IfcThirdOrderPolynomialSpiral
void operator()(const IfcSchema::IfcThirdOrderPolynomialSpiral* c) {
auto A0 = c->ConstantTerm();
auto A1 = c->LinearTerm();
auto A2 = c->QuadraticTerm();
boost::optional<double> A3, A4, A5, A6, A7;
void operator()(const IfcSchema::IfcThirdOrderPolynomialSpiral& c) {
auto A0 = c.ConstantTerm();
auto A1 = c.LinearTerm();
auto A2 = c.QuadraticTerm();
std::optional<double> A3, A4, A5, A6, A7;
#ifdef SCHEMA_IfcThirdOrderPolynomialSpiral_HAS_CubicTerm
A3 = c->CubicTerm();
A3 = c.CubicTerm();
#else
A3 = c->QubicTerm();
A3 = c.QubicTerm();
#endif
if (segment_type_ == ST_CANT) {
@@ -808,15 +804,15 @@ class curve_segment_evaluator {
#endif
#ifdef SCHEMA_HAS_IfcSeventhOrderPolynomialSpiral
void operator()(const IfcSchema::IfcSeventhOrderPolynomialSpiral* c) {
auto A0 = c->ConstantTerm();
auto A1 = c->LinearTerm();
auto A2 = c->QuadraticTerm();
auto A3 = c->CubicTerm();
auto A4 = c->QuarticTerm();
auto A5 = c->QuinticTerm();
auto A6 = c->SexticTerm();
auto A7 = c->SepticTerm();
void operator()(const IfcSchema::IfcSeventhOrderPolynomialSpiral& c) {
auto A0 = c.ConstantTerm();
auto A1 = c.LinearTerm();
auto A2 = c.QuadraticTerm();
auto A3 = c.CubicTerm();
auto A4 = c.QuarticTerm();
auto A5 = c.QuinticTerm();
auto A6 = c.SexticTerm();
auto A7 = c.SepticTerm();
if (segment_type_ == ST_CANT) {
polynomial_cant_spiral(A0, A1, A2, A3, A4, A5, A6, A7);
@@ -826,10 +822,10 @@ class curve_segment_evaluator {
}
#endif
void operator()(const IfcSchema::IfcCircle* c) {
void operator()(const IfcSchema::IfcCircle& c) {
if (segment_type_ == ST_HORIZONTAL || segment_type_ == ST_VERTICAL) {
auto R = c->Radius() * length_unit_;
auto parent_curve_position = taxonomy::cast<taxonomy::matrix4>(mapping_->map(c->Position()))->ccomponents();
auto R = c.Radius() * length_unit_;
auto parent_curve_position = taxonomy::cast<taxonomy::matrix4>(mapping_->map(c.Position()))->ccomponents();
// center point of the parent curve
auto pcCenterX = parent_curve_position(0, 3);
@@ -854,7 +850,7 @@ class curve_segment_evaluator {
} else {
Eigen::Matrix4d curve_segment_placement;
#ifdef SCHEMA_IfcCurveSegment_HAS_Placement
curve_segment_placement = taxonomy::cast<taxonomy::matrix4>(mapping_->map(inst_->Placement()))->ccomponents();
curve_segment_placement = taxonomy::cast<taxonomy::matrix4>(mapping_->map(inst_.Placement()))->ccomponents();
#endif
auto csStartX = curve_segment_placement(0, 3);
auto csStartY = curve_segment_placement(1, 3);
@@ -965,10 +961,10 @@ class curve_segment_evaluator {
}
}
void operator()(const IfcSchema::IfcLine* l) {
void operator()(const IfcSchema::IfcLine& l) {
projected_length_ = length_;
auto c = l->Pnt()->Coordinates();
auto c = l.Pnt().Coordinates();
auto pcX = c[0] * length_unit_;
auto pcY = c[1] * length_unit_;
@@ -980,7 +976,7 @@ class curve_segment_evaluator {
//
// Magnitude is not used because it relates to the parameterization of the line, which isn't currently done for IfcCurveSegment
// @todo - parameterization was recently added so Magnitude needs to be taking into consideration
auto dr = l->Dir()->Orientation()->DirectionRatios();
auto dr = l.Dir().Orientation().DirectionRatios();
// normalize the direction ratios
double m_squared = std::inner_product(dr.begin(), dr.end(), dr.begin(), 0.0);
@@ -1039,11 +1035,11 @@ class curve_segment_evaluator {
}
#ifdef SCHEMA_HAS_IfcPolynomialCurve
void operator()(const IfcSchema::IfcPolynomialCurve* pc) {
void operator()(const IfcSchema::IfcPolynomialCurve& pc) {
// see https://forums.buildingsmart.org/t/ifcpolynomialcurve-clarification/4716 for discussion on IfcPolynomialCurve
auto coeffX = pc->CoefficientsX().get_value_or(std::vector<double>());
auto coeffY = pc->CoefficientsY().get_value_or(std::vector<double>());
auto coeffZ = pc->CoefficientsZ().get_value_or(std::vector<double>());
auto coeffX = pc.CoefficientsX().value_or(std::vector<double>());
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);
}
@@ -1187,7 +1183,7 @@ class curve_segment_evaluator {
};
} // namespace
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCurveSegment* inst) {
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCurveSegment& inst) {
curve_segment_evaluator cse(this, inst, length_unit_);
boost::mpl::for_each<curve_seg_types, boost::type<boost::mpl::_>>(std::ref(cse));
return cse.get_segment_curve_function();