mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-31 00:46:36 +00:00
Fixes domain of vertical and cant pwf (Issue #5072)
This commit is contained in:
+48
-39
@@ -462,59 +462,67 @@ ifcopenshell::geometry::taxonomy::solid::ptr ifcopenshell::geometry::create_box(
|
||||
return solid;
|
||||
}
|
||||
|
||||
ifcopenshell::geometry::taxonomy::item::ptr ifcopenshell::geometry::taxonomy::piecewise_function::evaluate() const {
|
||||
return evaluate2().first;
|
||||
}
|
||||
std::vector<double> ifcopenshell::geometry::taxonomy::piecewise_function::evaluation_points() const {
|
||||
if (!eval_points_.has_value()) {
|
||||
double curve_length = length();
|
||||
|
||||
std::pair<item::ptr, std::vector<double>> ifcopenshell::geometry::taxonomy::piecewise_function::evaluate2() const {
|
||||
double curve_length = length();
|
||||
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);
|
||||
}
|
||||
|
||||
std::vector<taxonomy::point3::ptr> polygon;
|
||||
|
||||
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);
|
||||
eval_points_ = evaluation_points(start_, start_ + curve_length, num_steps);
|
||||
}
|
||||
|
||||
num_steps = std::max(1u, num_steps); // never have fewer than 1 step
|
||||
|
||||
return evaluate2(0.0, curve_length, num_steps);
|
||||
return *eval_points_;
|
||||
}
|
||||
|
||||
item::ptr ifcopenshell::geometry::taxonomy::piecewise_function::evaluate(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 {
|
||||
std::vector<double> ifcopenshell::geometry::taxonomy::piecewise_function::evaluation_points(double ustart, double uend, unsigned nsteps) const {
|
||||
double curve_length = length();
|
||||
ustart = std::max(0.0, ustart);
|
||||
uend = std::min(uend, curve_length);
|
||||
ustart = std::max(start_, ustart);
|
||||
uend = std::min(uend, start_ + curve_length);
|
||||
|
||||
nsteps = std::max(1u, nsteps); // never have fewer than 1 step
|
||||
|
||||
auto resolution = (uend - ustart) / nsteps;
|
||||
|
||||
std::vector<taxonomy::point3::ptr> polygon;
|
||||
std::vector<double> u_values;
|
||||
polygon.reserve(nsteps);
|
||||
u_values.reserve(nsteps);
|
||||
|
||||
for (unsigned i = 0; i <= nsteps; ++i) {
|
||||
auto u = resolution * i + ustart;
|
||||
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);
|
||||
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 {
|
||||
// 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)) {
|
||||
// there isn't a current span or u is outside the range of the 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 {
|
||||
// force u to be within bounds of the curve
|
||||
double curve_length = length();
|
||||
u = std::max(0.0, u);
|
||||
u = std::min(u, curve_length);
|
||||
double s = start();
|
||||
double e = end();
|
||||
u = std::max(s, u);
|
||||
u = std::min(u, e);
|
||||
|
||||
double start = 0;
|
||||
double span_start = s;
|
||||
for (auto& [length, fn] : spans_) {
|
||||
double span_end = span_start + length;
|
||||
auto tolerance = settings_ ? settings_->get<ifcopenshell::geometry::settings::Precision>().get() : 0.001;
|
||||
if (u < length + tolerance) {
|
||||
return {start, start+length, &fn} ;
|
||||
if (span_start <= u && u < span_end + tolerance) {
|
||||
return {span_start, span_end, &fn} ;
|
||||
}
|
||||
start += length;
|
||||
u -= length;
|
||||
span_start += length;
|
||||
}
|
||||
|
||||
Logger::Error("taxonomy::piecewise_function::get_span span not found.");
|
||||
|
||||
Reference in New Issue
Block a user