mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 09:48:32 +00:00
Adds conversion settings to control the granularity of points computed for a piecewise_function
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
>
|
||||
{};
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)));
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user