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;
}
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.";
};
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>
class IFC_GEOM_API SettingsContainer {
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:
settings_t settings;
@@ -385,7 +402,7 @@ namespace ifcopenshell {
};
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) {
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
// 4x3
+1 -1
View File
@@ -942,7 +942,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCurveSegment* inst) {
auto length = fabs(cse.length());
// @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->instance = inst;
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
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();
@@ -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->instance = inst;
return pwf;
@@ -46,7 +46,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcOffsetCurveByDistances* inst
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
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
// 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->instance = inst;
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
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();
@@ -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->instance = inst;
return pwf;
+13 -4
View File
@@ -459,11 +459,20 @@ ifcopenshell::geometry::taxonomy::item::ptr ifcopenshell::geometry::taxonomy::pi
length += s.first;
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;
int num_steps = 0;
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;
static const double target_resolution = 0.5;
int num_steps = (int)std::ceil(length / target_resolution);
auto resolution = length / num_steps;
for (int i = 0; i <= num_steps; ++i) {
for (int i = 0; i <= num_steps; ++i) {
auto u = resolution * i;
Eigen::Matrix4d m = evaluate(u);
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 "ConversionSettings.h"
#include <boost/variant.hpp>
#include <boost/functional/hash.hpp>
@@ -127,6 +129,7 @@ typedef item const* ptr;
struct implicit_item : public item {
DECLARE_PTR(implicit_item)
using item::item;
virtual item::ptr evaluate() const = 0;
};
@@ -134,6 +137,13 @@ typedef item const* ptr;
struct piecewise_function : public implicit_item {
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
std::vector<std::pair<double, std::function<Eigen::Matrix4d(double u)>>> spans;