Adds conversion settings to control the granularity of points computed for a piecewise_function

This commit is contained in:
Richard Brice
2023-11-22 15:49:24 -08:00
parent 39c3cac05d
commit 2126381a15
9 changed files with 64 additions and 14 deletions
+14
View File
@@ -37,3 +37,17 @@ std::istream& ifcopenshell::geometry::settings::operator>>(std::istream& in, Ite
} }
return in; return in;
} }
std::istream& ifcopenshell::geometry::settings::operator>>(std::istream& in, PiecewiseStepMethod& ioo) {
std::string token;
in >> token;
boost::to_upper(token);
if (token == "MAXSTEPSIZE") {
ioo = MAXSTEPSIZE;
} else if (token == "MINSTEPS") {
ioo = MINSTEPS;
} else {
in.setstate(std::ios_base::failbit);
}
return in;
}
+19 -2
View File
@@ -300,12 +300,29 @@ namespace ifcopenshell {
static constexpr const char* const description = "Overrides transparency of spaces in geometry output."; static constexpr const char* const description = "Overrides transparency of spaces in geometry output.";
}; };
enum PiecewiseStepMethod {
MAXSTEPSIZE,
MINSTEPS };
std::istream& operator>>(std::istream& in, PiecewiseStepMethod& ioo);
struct PiecewiseStepType : public SettingBase<PiecewiseStepType, PiecewiseStepMethod> {
static constexpr const char* const name = "piecewise-step-type";
static constexpr const char* const description = "Indicates the method used for defining step size when evaluating piecewise curves. Provides interpretation of piecewise-step-param";
static constexpr PiecewiseStepMethod defaultvalue = MAXSTEPSIZE;
};
struct PiecewiseStepParam : public SettingBase<PiecewiseStepParam, double> {
static constexpr const char* const name = "piecewise-step-param";
static constexpr const char* const description = "Indicates the parameter value for defining step size when evaluating piecewise curves.";
static constexpr double defaultvalue = 0.5; // ceiling of this value is used when PiecewiseStepMethod is MinSteps
};
} }
template <typename settings_t> template <typename settings_t>
class IFC_GEOM_API SettingsContainer { class IFC_GEOM_API SettingsContainer {
public: public:
typedef boost::variant<bool, int, double, std::string, std::set<int>, IteratorOutputOptions> value_variant_t; typedef boost::variant<bool, int, double, std::string, std::set<int>, IteratorOutputOptions, PiecewiseStepMethod> value_variant_t;
private: private:
settings_t settings; settings_t settings;
@@ -385,7 +402,7 @@ namespace ifcopenshell {
}; };
class IFC_GEOM_API Settings : public SettingsContainer< class IFC_GEOM_API Settings : public SettingsContainer<
std::tuple<MesherLinearDeflection, MesherAngularDeflection, ReorientShells, LengthUnit, PlaneUnit, Precision, IncludeCurves, IncludeSurfaces, LayersetFirst, DisableBooleanResult, NoWireIntersectionCheck, NoWireIntersectionTolerance, PrecisionFactor, DebugBooleanOperations, BooleanAttempt2d, WeldVertices, UseWorldCoords, ConvertBackUnits, ContextIds, IteratorOutput, DisableOpeningSubtractions, ApplyDefaultMaterials, DontEmitNormals, GenerateUvs, ApplyLayerSets, UseElementHierarchy, ValidateQuantities, EdgeArrows, BuildingLocalPlacement, SiteLocalPlacement, ForceSpaceTransparency> std::tuple<MesherLinearDeflection, MesherAngularDeflection, ReorientShells, LengthUnit, PlaneUnit, Precision, IncludeCurves, IncludeSurfaces, LayersetFirst, DisableBooleanResult, NoWireIntersectionCheck, NoWireIntersectionTolerance, PrecisionFactor, DebugBooleanOperations, BooleanAttempt2d, WeldVertices, UseWorldCoords, ConvertBackUnits, ContextIds, IteratorOutput, DisableOpeningSubtractions, ApplyDefaultMaterials, DontEmitNormals, GenerateUvs, ApplyLayerSets, UseElementHierarchy, ValidateQuantities, EdgeArrows, BuildingLocalPlacement, SiteLocalPlacement, ForceSpaceTransparency, PiecewiseStepType, PiecewiseStepParam>
> >
{}; {};
} }
+1 -1
View File
@@ -23,7 +23,7 @@ using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCompositeCurve* inst) { taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCompositeCurve* inst) {
auto loop = taxonomy::make<taxonomy::loop>(); auto loop = taxonomy::make<taxonomy::loop>();
auto pwf = taxonomy::make<taxonomy::piecewise_function>(); auto pwf = taxonomy::make<taxonomy::piecewise_function>(&settings_);
#ifdef SCHEMA_HAS_IfcSegment #ifdef SCHEMA_HAS_IfcSegment
// 4x3 // 4x3
+1 -1
View File
@@ -942,7 +942,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCurveSegment* inst) {
auto length = fabs(cse.length()); auto length = fabs(cse.length());
// @todo it might be suboptimal that we no longer have the spans now // @todo it might be suboptimal that we no longer have the spans now
auto pwf = taxonomy::make<taxonomy::piecewise_function>(); auto pwf = taxonomy::make<taxonomy::piecewise_function>(&settings_);
pwf->spans.push_back({ length, fn }); pwf->spans.push_back({ length, fn });
pwf->instance = inst; pwf->instance = inst;
return pwf; return pwf;
+2 -2
View File
@@ -28,7 +28,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcGradientCurve* inst) {
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 horizontal = taxonomy::cast<taxonomy::piecewise_function>(map(inst->BaseCurve()));
auto vertical = taxonomy::make<taxonomy::piecewise_function>(); auto vertical = taxonomy::make<taxonomy::piecewise_function>(&settings_);
auto segments = inst->Segments(); auto segments = inst->Segments();
@@ -73,7 +73,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcGradientCurve* inst) {
} }
} }
auto pwf = taxonomy::make<taxonomy::piecewise_function>(); auto pwf = taxonomy::make<taxonomy::piecewise_function>(&settings_);
pwf->spans.emplace_back( min_length, composition ); pwf->spans.emplace_back( min_length, composition );
pwf->instance = inst; pwf->instance = inst;
return pwf; return pwf;
@@ -46,7 +46,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOffsetCurveByDistances* inst
basis_curve_length += s.first; basis_curve_length += s.first;
} }
auto offsets = taxonomy::make<taxonomy::piecewise_function>(); auto offsets = taxonomy::make<taxonomy::piecewise_function>(&settings_);
#if defined SCHEMA_HAS_IfcDistanceExpression #if defined SCHEMA_HAS_IfcDistanceExpression
double first_distance = first_offset_value->DistanceAlong(); double first_distance = first_offset_value->DistanceAlong();
@@ -153,7 +153,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOffsetCurveByDistances* inst
// current implementation assumes that offsets is equal to the full length of basis curve // current implementation assumes that offsets is equal to the full length of basis curve
// this may change depending on decisions in the bSI-IF // this may change depending on decisions in the bSI-IF
auto pwf = taxonomy::make<taxonomy::piecewise_function>(); auto pwf = taxonomy::make<taxonomy::piecewise_function>(&settings_);
pwf->spans.emplace_back( basis_curve_length, composition ); pwf->spans.emplace_back( basis_curve_length, composition );
pwf->instance = inst; pwf->instance = inst;
return pwf; return pwf;
@@ -28,7 +28,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSegmentedReferenceCurve* ins
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 gradient = taxonomy::cast<taxonomy::piecewise_function>(map(inst->BaseCurve()));
auto cant = taxonomy::make<taxonomy::piecewise_function>(); auto cant = taxonomy::make<taxonomy::piecewise_function>(&settings_);
auto segments = inst->Segments(); auto segments = inst->Segments();
@@ -76,7 +76,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSegmentedReferenceCurve* ins
} }
} }
auto pwf = taxonomy::make<taxonomy::piecewise_function>(); auto pwf = taxonomy::make<taxonomy::piecewise_function>(&settings_);
pwf->spans.emplace_back( min_length, composition ); pwf->spans.emplace_back( min_length, composition );
pwf->instance = inst; pwf->instance = inst;
return pwf; return pwf;
+13 -4
View File
@@ -460,10 +460,19 @@ ifcopenshell::geometry::taxonomy::item::ptr ifcopenshell::geometry::taxonomy::pi
std::vector<taxonomy::point3::ptr> polygon; std::vector<taxonomy::point3::ptr> polygon;
static const double target_resolution = 0.5; auto param_type = settings_ ? settings_->get<ifcopenshell::geometry::settings::PiecewiseStepType>().get() : ifcopenshell::geometry::settings::PiecewiseStepMethod::MAXSTEPSIZE;
int num_steps = (int)std::ceil(length / target_resolution); auto param = settings_ ? settings_->get<ifcopenshell::geometry::settings::PiecewiseStepParam>().get() : 0.5;
auto resolution = length / num_steps; int num_steps = 0;
for (int i = 0; i <= num_steps; ++i) { if (param_type == ifcopenshell::geometry::settings::PiecewiseStepMethod::MAXSTEPSIZE) {
// parameter is max step size
num_steps = (int)std::ceil(length / param);
} else {
// parameter is minimum number of steps
num_steps = (int)std::ceil(param);
}
auto resolution = length / num_steps;
for (int i = 0; i <= num_steps; ++i) {
auto u = resolution * i; auto u = resolution * i;
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)));
+10
View File
@@ -3,6 +3,8 @@
#include "../ifcparse/IfcBaseClass.h" #include "../ifcparse/IfcBaseClass.h"
#include "ConversionSettings.h"
#include <boost/variant.hpp> #include <boost/variant.hpp>
#include <boost/functional/hash.hpp> #include <boost/functional/hash.hpp>
@@ -127,6 +129,7 @@ typedef item const* ptr;
struct implicit_item : public item { struct implicit_item : public item {
DECLARE_PTR(implicit_item) DECLARE_PTR(implicit_item)
using item::item;
virtual item::ptr evaluate() const = 0; virtual item::ptr evaluate() const = 0;
}; };
@@ -134,6 +137,13 @@ typedef item const* ptr;
struct piecewise_function : public implicit_item { struct piecewise_function : public implicit_item {
DECLARE_PTR(piecewise_function) DECLARE_PTR(piecewise_function)
piecewise_function(const IfcUtil::IfcBaseInterface* instance = nullptr) : implicit_item(instance){};
piecewise_function(ifcopenshell::geometry::Settings* settings) : settings_(settings){};
piecewise_function(piecewise_function&&) = default;
piecewise_function(const piecewise_function&) = default;
ifcopenshell::geometry::Settings* settings_ = nullptr;
// length of span, function to evaluate span // length of span, function to evaluate span
std::vector<std::pair<double, std::function<Eigen::Matrix4d(double u)>>> spans; std::vector<std::pair<double, std::function<Eigen::Matrix4d(double u)>>> spans;