mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-30 03:59:55 +00:00
Fixes domain of vertical and cant pwf (Issue #5072)
This commit is contained in:
@@ -92,7 +92,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCompositeCurve* inst) {
|
|||||||
return loop;
|
return loop;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
auto pwf = taxonomy::make<taxonomy::piecewise_function>(pwfs,&settings_,inst);
|
auto pwf = taxonomy::make<taxonomy::piecewise_function>(0.0,pwfs,&settings_,inst);
|
||||||
return pwf;
|
return pwf;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -890,7 +890,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCurveSegment* inst) {
|
|||||||
|
|
||||||
taxonomy::piecewise_function::spans spans;
|
taxonomy::piecewise_function::spans spans;
|
||||||
spans.emplace_back(fabs(length), fn);
|
spans.emplace_back(fabs(length), fn);
|
||||||
auto pwf = taxonomy::make<taxonomy::piecewise_function>(spans,&settings_,inst);
|
auto pwf = taxonomy::make<taxonomy::piecewise_function>(0.0, spans,&settings_,inst);
|
||||||
return pwf;
|
return pwf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,11 +27,9 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcGradientCurve* inst) {
|
|||||||
if (!inst->BaseCurve()->as<IfcSchema::IfcCompositeCurve>())
|
if (!inst->BaseCurve()->as<IfcSchema::IfcCompositeCurve>())
|
||||||
Logger::Warning("Expected IfcGradientCurve.BaseCurve to be IfcCompositeCurve", inst); // CT 4.1.7.1.1.2
|
Logger::Warning("Expected IfcGradientCurve.BaseCurve to be IfcCompositeCurve", inst); // CT 4.1.7.1.1.2
|
||||||
|
|
||||||
auto horizontal = taxonomy::cast<taxonomy::piecewise_function>(map(inst->BaseCurve()));
|
|
||||||
|
|
||||||
auto segments = inst->Segments();
|
auto segments = inst->Segments();
|
||||||
|
|
||||||
std::vector<taxonomy::piecewise_function::ptr> pwfs;
|
std::vector<taxonomy::piecewise_function::ptr> pwfs;
|
||||||
|
|
||||||
for (auto& segment : *segments) {
|
for (auto& segment : *segments) {
|
||||||
if (segment->as<IfcSchema::IfcCurveSegment>()) {
|
if (segment->as<IfcSchema::IfcCurveSegment>()) {
|
||||||
@@ -49,10 +47,32 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcGradientCurve* inst) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto vertical = taxonomy::make<taxonomy::piecewise_function>(pwfs,&settings_);
|
// Get starting position of gradient curve, which is relative to the base curve
|
||||||
|
// The gradient curve can start before or after the start of the base curve
|
||||||
|
auto first_segment = *(segments->begin());
|
||||||
|
auto p = taxonomy::cast<taxonomy::matrix4>(map(first_segment->as<IfcSchema::IfcCurveSegment>()->Placement()));
|
||||||
|
const Eigen::Matrix4d& m = p->ccomponents();
|
||||||
|
double gradient_start = m(0, 3); // start of vertical (row 0, col 3) - "Distance Along" horizontal curve
|
||||||
|
|
||||||
|
// create the vertical pwf
|
||||||
|
auto vertical = taxonomy::make<taxonomy::piecewise_function>(gradient_start, pwfs, &settings_);
|
||||||
|
|
||||||
|
// Determine the valid domain of the PWF... the valid domain is where both
|
||||||
|
// the base curve and gradient curves are defined
|
||||||
|
auto horizontal = taxonomy::cast<taxonomy::piecewise_function>(map(inst->BaseCurve()));
|
||||||
|
double start = std::max(horizontal->start(),vertical->start());
|
||||||
|
double end = std::min(horizontal->end(), vertical->end());
|
||||||
|
double length = end - start;
|
||||||
|
|
||||||
|
if (!(0 < length)) {
|
||||||
|
Logger::Error("IfcGradientCurve does not have a common domain with BaseCurve");
|
||||||
|
}
|
||||||
|
|
||||||
|
// define the callback function for the gradient curve
|
||||||
auto composition = [horizontal, vertical](double u)->Eigen::Matrix4d {
|
auto composition = [horizontal, vertical](double u)->Eigen::Matrix4d {
|
||||||
auto xy = horizontal->evaluate(u);
|
// u is distance from start of gradient curve (vertical)
|
||||||
|
// add vertical->start() to u to get distance from start of horizontal
|
||||||
|
auto xy = horizontal->evaluate(u + vertical->start());
|
||||||
auto uz = vertical->evaluate(u);
|
auto uz = vertical->evaluate(u);
|
||||||
|
|
||||||
uz.col(3)(0) = 0.0; // x is distance along. zero it out so it doesn't add to the x from horizontal
|
uz.col(3)(0) = 0.0; // x is distance along. zero it out so it doesn't add to the x from horizontal
|
||||||
@@ -64,11 +84,9 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcGradientCurve* inst) {
|
|||||||
return m;
|
return m;
|
||||||
};
|
};
|
||||||
|
|
||||||
double min_length = std::min(horizontal->length(), vertical->length());
|
|
||||||
|
|
||||||
taxonomy::piecewise_function::spans spans;
|
taxonomy::piecewise_function::spans spans;
|
||||||
spans.emplace_back(min_length, composition);
|
spans.emplace_back(length, composition);
|
||||||
auto pwf = taxonomy::make<taxonomy::piecewise_function>(spans, &settings_, inst);
|
auto pwf = taxonomy::make<taxonomy::piecewise_function>(start, spans, &settings_, inst);
|
||||||
return pwf;
|
return pwf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -38,8 +38,9 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOffsetCurveByDistances* inst
|
|||||||
auto first_offset_value = *(offset_values->begin());
|
auto first_offset_value = *(offset_values->begin());
|
||||||
|
|
||||||
auto basis_curve = inst->BasisCurve();
|
auto basis_curve = inst->BasisCurve();
|
||||||
//auto pw_curve = ifcopenshell::geometry::piecewise_from_item(map(basis_curve));
|
|
||||||
auto pw_curve = taxonomy::dcast<taxonomy::piecewise_function>(map(basis_curve));
|
auto pw_curve = taxonomy::dcast<taxonomy::piecewise_function>(map(basis_curve));
|
||||||
|
|
||||||
|
double start = pw_curve->start();
|
||||||
double basis_curve_length = pw_curve->length();
|
double basis_curve_length = pw_curve->length();
|
||||||
|
|
||||||
taxonomy::piecewise_function::spans offset_spans;
|
taxonomy::piecewise_function::spans offset_spans;
|
||||||
@@ -143,7 +144,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOffsetCurveByDistances* inst
|
|||||||
offset_spans.emplace_back(l, fn);
|
offset_spans.emplace_back(l, fn);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto offsets = taxonomy::make<taxonomy::piecewise_function>(offset_spans,&settings_);
|
auto offsets = taxonomy::make<taxonomy::piecewise_function>(start,offset_spans,&settings_);
|
||||||
|
|
||||||
auto composition = [pw_curve, offsets](double u) -> Eigen::Matrix4d {
|
auto composition = [pw_curve, offsets](double u) -> Eigen::Matrix4d {
|
||||||
auto p = pw_curve->evaluate(u);
|
auto p = pw_curve->evaluate(u);
|
||||||
@@ -156,7 +157,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOffsetCurveByDistances* inst
|
|||||||
// this may change depending on decisions in the bSI-IF
|
// this may change depending on decisions in the bSI-IF
|
||||||
taxonomy::piecewise_function::spans spans;
|
taxonomy::piecewise_function::spans spans;
|
||||||
spans.emplace_back(basis_curve_length, composition);
|
spans.emplace_back(basis_curve_length, composition);
|
||||||
auto pwf = taxonomy::make<taxonomy::piecewise_function>(spans,&settings_,inst);
|
auto pwf = taxonomy::make<taxonomy::piecewise_function>(start,spans,&settings_,inst);
|
||||||
return pwf;
|
return pwf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,8 +27,6 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSegmentedReferenceCurve* ins
|
|||||||
if (!inst->BaseCurve()->as<IfcSchema::IfcGradientCurve>())
|
if (!inst->BaseCurve()->as<IfcSchema::IfcGradientCurve>())
|
||||||
Logger::Warning("Expected IfcSegmentedReferenceCurve.BaseCurve to be IfcGradient", inst); // CT 4.1.7.1.1.3
|
Logger::Warning("Expected IfcSegmentedReferenceCurve.BaseCurve to be IfcGradient", inst); // CT 4.1.7.1.1.3
|
||||||
|
|
||||||
auto gradient = taxonomy::cast<taxonomy::piecewise_function>(map(inst->BaseCurve()));
|
|
||||||
|
|
||||||
auto segments = inst->Segments();
|
auto segments = inst->Segments();
|
||||||
|
|
||||||
std::vector<taxonomy::piecewise_function::ptr> pwfs;
|
std::vector<taxonomy::piecewise_function::ptr> pwfs;
|
||||||
@@ -46,11 +44,34 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSegmentedReferenceCurve* ins
|
|||||||
Logger::Error("Unsupported");
|
Logger::Error("Unsupported");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto cant = taxonomy::make<taxonomy::piecewise_function>(pwfs,&settings_);
|
|
||||||
|
|
||||||
|
// Get starting position of cant curve, relative to the gradient curve.
|
||||||
|
// The cant curve can start before or after the start of the gradient curve
|
||||||
|
auto first_segment = *(segments->begin());
|
||||||
|
auto p = taxonomy::cast<taxonomy::matrix4>(map(first_segment->as<IfcSchema::IfcCurveSegment>()->Placement()));
|
||||||
|
const Eigen::Matrix4d& m = p->ccomponents();
|
||||||
|
double cant_start = m(0, 3); // start of cant curve
|
||||||
|
|
||||||
|
auto cant = taxonomy::make<taxonomy::piecewise_function>(cant_start,pwfs,&settings_);
|
||||||
|
|
||||||
|
// Determine the valid domain of the PWF... the valid domain is where
|
||||||
|
// horizontal, gradient and cant curves are defined
|
||||||
|
auto gradient = taxonomy::cast<taxonomy::piecewise_function>(map(inst->BaseCurve()));
|
||||||
|
auto horizontal = taxonomy::cast<taxonomy::piecewise_function>(map(inst->BaseCurve()->as<IfcSchema::IfcGradientCurve>()->BaseCurve()));
|
||||||
|
double start = std::max(std::max(cant->start(), gradient->start()), horizontal->start());
|
||||||
|
double end = std::min(std::min(cant->end(), gradient->end()), horizontal->end());
|
||||||
|
double length = end - start;
|
||||||
|
|
||||||
|
if (!(0 < length)) {
|
||||||
|
Logger::Error("IfcSegmentedReferenceCurve does not have a common domain with BaseCurve");
|
||||||
|
}
|
||||||
|
|
||||||
|
// define the callback function for the segmented reference curve
|
||||||
auto composition = [gradient, cant](double u)->Eigen::Matrix4d {
|
auto composition = [gradient, cant](double u)->Eigen::Matrix4d {
|
||||||
auto g = gradient->evaluate(u);
|
// u is distance from start of cant curve
|
||||||
|
// add cant->start() to u to get the distance from start of gradient curve
|
||||||
|
auto g = gradient->evaluate(u+cant->start());
|
||||||
auto c = cant->evaluate(u);
|
auto c = cant->evaluate(u);
|
||||||
|
|
||||||
c.col(3)(0) = 0.0; // x is distance along. zero it out so it doesn't add to the x from gradient curve
|
c.col(3)(0) = 0.0; // x is distance along. zero it out so it doesn't add to the x from gradient curve
|
||||||
@@ -62,11 +83,9 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSegmentedReferenceCurve* ins
|
|||||||
return m;
|
return m;
|
||||||
};
|
};
|
||||||
|
|
||||||
double min_length = std::min(gradient->length(), cant->length());
|
|
||||||
|
|
||||||
taxonomy::piecewise_function::spans spans;
|
taxonomy::piecewise_function::spans spans;
|
||||||
spans.emplace_back(min_length, composition);
|
spans.emplace_back(length, composition);
|
||||||
auto pwf = taxonomy::make<taxonomy::piecewise_function>(spans, &settings_, inst);
|
auto pwf = taxonomy::make<taxonomy::piecewise_function>(start, spans, &settings_, inst);
|
||||||
return pwf;
|
return pwf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+48
-39
@@ -462,59 +462,67 @@ ifcopenshell::geometry::taxonomy::solid::ptr ifcopenshell::geometry::create_box(
|
|||||||
return solid;
|
return solid;
|
||||||
}
|
}
|
||||||
|
|
||||||
ifcopenshell::geometry::taxonomy::item::ptr ifcopenshell::geometry::taxonomy::piecewise_function::evaluate() const {
|
std::vector<double> ifcopenshell::geometry::taxonomy::piecewise_function::evaluation_points() const {
|
||||||
return evaluate2().first;
|
if (!eval_points_.has_value()) {
|
||||||
}
|
double curve_length = length();
|
||||||
|
|
||||||
std::pair<item::ptr, std::vector<double>> ifcopenshell::geometry::taxonomy::piecewise_function::evaluate2() const {
|
auto param_type = settings_ ? settings_->get<ifcopenshell::geometry::settings::PiecewiseStepType>().get() : ifcopenshell::geometry::settings::PiecewiseStepMethod::MAXSTEPSIZE;
|
||||||
double curve_length = length();
|
auto param = settings_ ? settings_->get<ifcopenshell::geometry::settings::PiecewiseStepParam>().get() : 0.5;
|
||||||
|
unsigned num_steps = 0;
|
||||||
|
if (param_type == ifcopenshell::geometry::settings::PiecewiseStepMethod::MAXSTEPSIZE) {
|
||||||
|
// parameter is max step size
|
||||||
|
num_steps = (unsigned)std::ceil(curve_length / param);
|
||||||
|
} else {
|
||||||
|
// parameter is minimum number of steps
|
||||||
|
num_steps = (unsigned)std::ceil(param);
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<taxonomy::point3::ptr> polygon;
|
eval_points_ = evaluation_points(start_, start_ + curve_length, num_steps);
|
||||||
|
|
||||||
auto param_type = settings_ ? settings_->get<ifcopenshell::geometry::settings::PiecewiseStepType>().get() : ifcopenshell::geometry::settings::PiecewiseStepMethod::MAXSTEPSIZE;
|
|
||||||
auto param = settings_ ? settings_->get<ifcopenshell::geometry::settings::PiecewiseStepParam>().get() : 0.5;
|
|
||||||
unsigned num_steps = 0;
|
|
||||||
if (param_type == ifcopenshell::geometry::settings::PiecewiseStepMethod::MAXSTEPSIZE) {
|
|
||||||
// parameter is max step size
|
|
||||||
num_steps = (unsigned)std::ceil(curve_length / param);
|
|
||||||
} else {
|
|
||||||
// parameter is minimum number of steps
|
|
||||||
num_steps = (unsigned)std::ceil(param);
|
|
||||||
}
|
}
|
||||||
|
return *eval_points_;
|
||||||
num_steps = std::max(1u, num_steps); // never have fewer than 1 step
|
|
||||||
|
|
||||||
return evaluate2(0.0, curve_length, num_steps);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
item::ptr ifcopenshell::geometry::taxonomy::piecewise_function::evaluate(double ustart, double uend,unsigned nsteps) const {
|
std::vector<double> ifcopenshell::geometry::taxonomy::piecewise_function::evaluation_points(double ustart, double uend, unsigned nsteps) const {
|
||||||
return evaluate2(ustart, uend, nsteps).first;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::pair<item::ptr, std::vector<double>> ifcopenshell::geometry::taxonomy::piecewise_function::evaluate2(double ustart, double uend, unsigned nsteps) const {
|
|
||||||
double curve_length = length();
|
double curve_length = length();
|
||||||
ustart = std::max(0.0, ustart);
|
ustart = std::max(start_, ustart);
|
||||||
uend = std::min(uend, curve_length);
|
uend = std::min(uend, start_ + curve_length);
|
||||||
|
|
||||||
|
nsteps = std::max(1u, nsteps); // never have fewer than 1 step
|
||||||
|
|
||||||
auto resolution = (uend - ustart) / nsteps;
|
auto resolution = (uend - ustart) / nsteps;
|
||||||
|
|
||||||
std::vector<taxonomy::point3::ptr> polygon;
|
|
||||||
std::vector<double> u_values;
|
std::vector<double> u_values;
|
||||||
polygon.reserve(nsteps);
|
|
||||||
u_values.reserve(nsteps);
|
u_values.reserve(nsteps);
|
||||||
|
|
||||||
for (unsigned i = 0; i <= nsteps; ++i) {
|
for (unsigned i = 0; i <= nsteps; ++i) {
|
||||||
auto u = resolution * i + ustart;
|
auto u = resolution * i + ustart;
|
||||||
u_values.push_back(u);
|
u_values.push_back(u);
|
||||||
|
}
|
||||||
|
|
||||||
|
return u_values;
|
||||||
|
}
|
||||||
|
|
||||||
|
ifcopenshell::geometry::taxonomy::item::ptr ifcopenshell::geometry::taxonomy::piecewise_function::evaluate() const {
|
||||||
|
return evaluate(evaluation_points());
|
||||||
|
}
|
||||||
|
|
||||||
|
item::ptr ifcopenshell::geometry::taxonomy::piecewise_function::evaluate(double ustart, double uend,unsigned nsteps) const {
|
||||||
|
return evaluate(evaluation_points(ustart,uend,nsteps));
|
||||||
|
}
|
||||||
|
|
||||||
|
item::ptr ifcopenshell::geometry::taxonomy::piecewise_function::evaluate(const std::vector<double>& dist) const {
|
||||||
|
std::vector<taxonomy::point3::ptr> polygon;
|
||||||
|
polygon.reserve(dist.size());
|
||||||
|
for (auto& u : dist) {
|
||||||
Eigen::Matrix4d m = evaluate(u);
|
Eigen::Matrix4d m = evaluate(u);
|
||||||
polygon.push_back(taxonomy::make<taxonomy::point3>(m.col(3)(0), m.col(3)(1), m.col(3)(2)));
|
polygon.push_back(taxonomy::make<taxonomy::point3>(m.col(3)(0), m.col(3)(1), m.col(3)(2)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return {polygon_from_points(polygon), u_values};
|
return polygon_from_points(polygon);
|
||||||
}
|
}
|
||||||
|
|
||||||
Eigen::Matrix4d ifcopenshell::geometry::taxonomy::piecewise_function::evaluate(double u) const {
|
Eigen::Matrix4d ifcopenshell::geometry::taxonomy::piecewise_function::evaluate(double u) const {
|
||||||
// assume monotonic evaluation and store last evaluated segment
|
// assume monotonic evaluation and store last evaluated segment
|
||||||
if (current_span_fn_ == nullptr || (u < current_span_start_ || current_span_end_ < u)) {
|
if (current_span_fn_ == nullptr || (u < current_span_start_ || current_span_end_ < u)) {
|
||||||
// there isn't a current span or u is outside the range of the current span
|
// there isn't a current span or u is outside the range of the current span
|
||||||
// get a new "current span"
|
// get a new "current span"
|
||||||
@@ -527,18 +535,19 @@ Eigen::Matrix4d ifcopenshell::geometry::taxonomy::piecewise_function::evaluate(d
|
|||||||
|
|
||||||
std::tuple<double, double, const std::function<Eigen::Matrix4d(double u)>*> ifcopenshell::geometry::taxonomy::piecewise_function::get_span(double u) const {
|
std::tuple<double, double, const std::function<Eigen::Matrix4d(double u)>*> ifcopenshell::geometry::taxonomy::piecewise_function::get_span(double u) const {
|
||||||
// force u to be within bounds of the curve
|
// force u to be within bounds of the curve
|
||||||
double curve_length = length();
|
double s = start();
|
||||||
u = std::max(0.0, u);
|
double e = end();
|
||||||
u = std::min(u, curve_length);
|
u = std::max(s, u);
|
||||||
|
u = std::min(u, e);
|
||||||
|
|
||||||
double start = 0;
|
double span_start = s;
|
||||||
for (auto& [length, fn] : spans_) {
|
for (auto& [length, fn] : spans_) {
|
||||||
|
double span_end = span_start + length;
|
||||||
auto tolerance = settings_ ? settings_->get<ifcopenshell::geometry::settings::Precision>().get() : 0.001;
|
auto tolerance = settings_ ? settings_->get<ifcopenshell::geometry::settings::Precision>().get() : 0.001;
|
||||||
if (u < length + tolerance) {
|
if (span_start <= u && u < span_end + tolerance) {
|
||||||
return {start, start+length, &fn} ;
|
return {span_start, span_end, &fn} ;
|
||||||
}
|
}
|
||||||
start += length;
|
span_start += length;
|
||||||
u -= length;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::Error("taxonomy::piecewise_function::get_span span not found.");
|
Logger::Error("taxonomy::piecewise_function::get_span span not found.");
|
||||||
|
|||||||
+34
-18
@@ -356,10 +356,10 @@ typedef item const* ptr;
|
|||||||
|
|
||||||
using spans = std::vector<std::pair<double, std::function<Eigen::Matrix4d(double u)>>>;
|
using spans = std::vector<std::pair<double, std::function<Eigen::Matrix4d(double u)>>>;
|
||||||
|
|
||||||
piecewise_function(const spans& s, ifcopenshell::geometry::Settings* settings = nullptr, const IfcUtil::IfcBaseInterface* instance = nullptr) :
|
piecewise_function(double start,const spans& s, ifcopenshell::geometry::Settings* settings = nullptr, const IfcUtil::IfcBaseInterface* instance = nullptr) :
|
||||||
implicit_item(instance), settings_(settings), spans_(s){};
|
implicit_item(instance), start_(start), settings_(settings), spans_(s){};
|
||||||
piecewise_function(const std::vector<piecewise_function::ptr>& pwfs, ifcopenshell::geometry::Settings* settings = nullptr, const IfcUtil::IfcBaseInterface* instance = nullptr) :
|
piecewise_function(double start,const std::vector<piecewise_function::ptr>& pwfs, ifcopenshell::geometry::Settings* settings = nullptr, const IfcUtil::IfcBaseInterface* instance = nullptr) :
|
||||||
implicit_item(instance), settings_(settings)
|
implicit_item(instance), start_(start), settings_(settings)
|
||||||
{
|
{
|
||||||
for (auto& pwf : pwfs) {
|
for (auto& pwf : pwfs) {
|
||||||
spans_.insert(spans_.end(), pwf->spans_.begin(), pwf->spans_.end());
|
spans_.insert(spans_.end(), pwf->spans_.begin(), pwf->spans_.end());
|
||||||
@@ -372,6 +372,14 @@ typedef item const* ptr;
|
|||||||
|
|
||||||
bool is_empty() const { return spans_.empty(); }
|
bool is_empty() const { return spans_.empty(); }
|
||||||
|
|
||||||
|
double start() const {
|
||||||
|
return start_;
|
||||||
|
}
|
||||||
|
|
||||||
|
double end() const {
|
||||||
|
return start_ + length();
|
||||||
|
}
|
||||||
|
|
||||||
double length() const {
|
double length() const {
|
||||||
if (!length_.has_value()) {
|
if (!length_.has_value()) {
|
||||||
length_ = std::accumulate(spans_.begin(), spans_.end(), 0.0, [](const auto& v, const auto& s) { return v + s.first; });
|
length_ = std::accumulate(spans_.begin(), spans_.end(), 0.0, [](const auto& v, const auto& s) { return v + s.first; });
|
||||||
@@ -387,35 +395,43 @@ typedef item const* ptr;
|
|||||||
return boost::hash<decltype(v)>{}(v);
|
return boost::hash<decltype(v)>{}(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
item::ptr evaluate() const override;
|
/// @brief returns a vector of "distance along" points where the evaluate function computes loop points
|
||||||
std::pair<item::ptr,std::vector<double>> evaluate2() const;
|
std::vector<double> evaluation_points() const;
|
||||||
|
|
||||||
|
/// @brief returns a vector of "distance along" points between ustart and uend
|
||||||
|
/// @param ustart starting location
|
||||||
|
/// @param uend ending location
|
||||||
|
/// @param nsteps number of steps to evaluate
|
||||||
|
std::vector<double> evaluation_points(double ustart, double uend, unsigned nsteps) const;
|
||||||
|
|
||||||
|
/// @brief evaluates the piecewise function between start and end
|
||||||
|
/// evaluation point step size is taken from the settings object
|
||||||
|
item::ptr evaluate() const override;
|
||||||
|
|
||||||
/// @brief evaluates the piecewise function between ustart and uend
|
/// @brief evaluates the piecewise function between ustart and uend
|
||||||
/// @param ustart starting location - taken as 0.0 if before start
|
/// if ustart and uend are out of range, the range of values evaluated
|
||||||
/// @param uend ending location - taken as length if beyond end
|
/// are constrained to start_ and start_+length_
|
||||||
|
/// @param ustart starting location
|
||||||
|
/// @param uend ending location
|
||||||
/// @param nsteps number of steps to evaluate
|
/// @param nsteps number of steps to evaluate
|
||||||
/// @return taxonomy::loop::ptr
|
/// @return taxonomy::loop::ptr
|
||||||
item::ptr evaluate(double ustart, double uend, unsigned nsteps) const;
|
item::ptr evaluate(double ustart, double uend, unsigned nsteps) const;
|
||||||
|
|
||||||
/// @brief evaluates the piecewise function between ustart and uend
|
|
||||||
/// @param ustart starting location - taken as 0.0 if before start
|
|
||||||
/// @param uend ending location - taken as length if beyond end
|
|
||||||
/// @param nsteps number of steps to evaluate
|
|
||||||
/// @return taxonomy::loop::ptr and vector of u values
|
|
||||||
std::pair<item::ptr, std::vector<double>> evaluate2(double ustart, double uend, unsigned nsteps) const;
|
|
||||||
|
|
||||||
/// @brief evaluates the piecewise function at u
|
/// @brief evaluates the piecewise function at u
|
||||||
/// @param u u is constrained to be between 0 and length
|
/// @param u u is constrained to be between start_ and start_+length
|
||||||
/// @return 4x4 placement matrix
|
/// @return 4x4 placement matrix
|
||||||
Eigen::Matrix4d evaluate(double u) const;
|
Eigen::Matrix4d evaluate(double u) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::tuple<double, double, const std::function<Eigen::Matrix4d(double u)>*> get_span(double u) const;
|
item::ptr evaluate(const std::vector<double>& dist) const;
|
||||||
|
std::tuple<double, double, const std::function<Eigen::Matrix4d(double u)>*> get_span(double u) const;
|
||||||
|
double start_ = 0.0; // starting value of the pwf
|
||||||
spans spans_;
|
spans spans_;
|
||||||
mutable double current_span_start_ = 0;
|
mutable double current_span_start_ = 0;
|
||||||
mutable double current_span_end_ = 0;
|
mutable double current_span_end_ = 0;
|
||||||
mutable const std::function<Eigen::Matrix4d(double u)>* current_span_fn_ = nullptr;
|
mutable const std::function<Eigen::Matrix4d(double u)>* current_span_fn_ = nullptr;
|
||||||
mutable boost::optional<double> length_;
|
mutable boost::optional<double> length_;
|
||||||
|
mutable boost::optional<std::vector<double>> eval_points_;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef TAXONOMY_USE_SHARED_PTR
|
#ifdef TAXONOMY_USE_SHARED_PTR
|
||||||
@@ -1341,7 +1357,7 @@ typedef item const* ptr;
|
|||||||
};
|
};
|
||||||
spans.emplace_back(l, fn);
|
spans.emplace_back(l, fn);
|
||||||
}
|
}
|
||||||
pwf_ = taxonomy::make<taxonomy::piecewise_function>(spans);
|
pwf_ = taxonomy::make<taxonomy::piecewise_function>(0.0,spans);
|
||||||
loop->pwf = pwf_;
|
loop->pwf = pwf_;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user