mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-20 12:12:15 +00:00
Work towards v1.0 data model with encapsulated weak_ptr as basis for instances
This commit is contained in:
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user