Drastic settings refactoring

This commit is contained in:
Thomas Krijnen
2023-11-15 10:32:20 +01:00
parent d2a2e0d7a0
commit 65e874c67f
80 changed files with 1057 additions and 723 deletions
+3 -3
View File
@@ -33,12 +33,12 @@ bool ifcopenshell::geometry::kernels::AbstractKernel::convert(const taxonomy::pt
}
}
const ConversionSettings & ifcopenshell::geometry::kernels::AbstractKernel::settings() const
const Settings& ifcopenshell::geometry::kernels::AbstractKernel::settings() const
{
return conv_settings_;
return settings_;
}
ifcopenshell::geometry::kernels::AbstractKernel* ifcopenshell::geometry::kernels::construct(const std::string& geometry_library, const ConversionSettings& conv_settings) {
ifcopenshell::geometry::kernels::AbstractKernel* ifcopenshell::geometry::kernels::construct(const std::string& geometry_library, const Settings& conv_settings) {
const std::string geometry_library_lower = boost::to_lower_copy(geometry_library);
#ifdef IFOPSH_WITH_OPENCASCADE
+5 -5
View File
@@ -20,15 +20,15 @@ namespace ifcopenshell { namespace geometry { namespace kernels {
class IFC_GEOM_API AbstractKernel {
protected:
std::string geometry_library;
ConversionSettings conv_settings_;
Settings settings_;
public:
AbstractKernel(const std::string& geometry_library, const ConversionSettings& settings)
AbstractKernel(const std::string& geometry_library, const Settings& settings)
: geometry_library(geometry_library)
, conv_settings_(settings) {}
, settings_(settings) {}
bool convert(const taxonomy::ptr, IfcGeom::ConversionResults&);
const ConversionSettings& settings() const;
const Settings& settings() const;
virtual bool convert_impl(const taxonomy::matrix4::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); }
virtual bool convert_impl(const taxonomy::point3::ptr, IfcGeom::ConversionResults&) { throw std::runtime_error("Not implemented"); }
@@ -68,7 +68,7 @@ namespace ifcopenshell { namespace geometry { namespace kernels {
};
AbstractKernel* construct(const std::string& geometry_library, const ConversionSettings& conv_settings);
AbstractKernel* construct(const std::string& geometry_library, const Settings& conv_settings);
}
}
+1 -1
View File
@@ -1,7 +1,7 @@
#include "ConversionResult.h"
#include "IfcGeomRepresentation.h"
IfcGeom::Representation::Triangulation * IfcGeom::ConversionResultShape::Triangulate(const IfcGeom::IteratorSettings & settings) const
IfcGeom::Representation::Triangulation * IfcGeom::ConversionResultShape::Triangulate(const ifcopenshell::geometry::Settings& settings) const
{
auto t = IfcGeom::Representation::Triangulation::empty(settings);
static ifcopenshell::geometry::taxonomy::matrix4 iden;
+4 -3
View File
@@ -21,7 +21,7 @@
#define IFCSHAPELIST_H
#include "../ifcgeom/IfcGeomRenderStyles.h"
#include "../ifcgeom/IteratorSettings.h"
#include "../ifcgeom/ConversionSettings.h"
#include "../ifcgeom/taxonomy.h"
#include <memory>
@@ -183,8 +183,8 @@ namespace IfcGeom {
class IFC_GEOM_API ConversionResultShape {
public:
virtual void Triangulate(const IfcGeom::IteratorSettings& settings, const ifcopenshell::geometry::taxonomy::matrix4& place, Representation::Triangulation* t, int surface_style_id) const = 0;
IfcGeom::Representation::Triangulation* Triangulate(const IfcGeom::IteratorSettings& settings) const;
virtual void Triangulate(ifcopenshell::geometry::Settings settings, const ifcopenshell::geometry::taxonomy::matrix4& place, Representation::Triangulation* t, int surface_style_id) const = 0;
IfcGeom::Representation::Triangulation* Triangulate(const ifcopenshell::geometry::Settings& settings) const;
virtual void Serialize(const ifcopenshell::geometry::taxonomy::matrix4& place, std::string&) const = 0;
virtual int surface_genus() const = 0;
@@ -223,6 +223,7 @@ namespace IfcGeom {
virtual ConversionResultShape* moved(ifcopenshell::geometry::taxonomy::matrix4::ptr) const = 0;
virtual ~ConversionResultShape() {}
};
class IFC_GEOM_API ConversionResult {
+30
View File
@@ -1,5 +1,6 @@
#include "ConversionSettings.h"
/*
void ifcopenshell::geometry::ConversionSettings::setValue(GeomValue var, double value) {
values_[var] = value;
}
@@ -7,3 +8,32 @@ void ifcopenshell::geometry::ConversionSettings::setValue(GeomValue var, double
double ifcopenshell::geometry::ConversionSettings::getValue(GeomValue var) const {
return values_[var];
}
*/
std::istream& std::operator>>(istream& in, set<int>& ints) {
string tokens;
in >> tokens;
vector<string> strs;
boost::split(strs, tokens, boost::is_any_of(","));
for (auto& s : strs) {
ints.insert(boost::lexical_cast<int>(s));
}
return in;
}
std::istream& ifcopenshell::geometry::settings::operator>>(std::istream& in, IteratorOutputOptions& ioo)
{
std::string token;
in >> token;
boost::to_upper(token);
if (token == "TRIANGULATED") {
ioo = TRIANGULATED;
} else if (token == "NATIVE") {
ioo = NATIVE;
} else if (token == "SERIALIZED") {
ioo = SERIALIZED;
} else {
in.setstate(std::ios_base::failbit);
}
return in;
}
+437 -61
View File
@@ -4,77 +4,453 @@
#include <array>
#include <limits>
#include <string>
#include <iostream>
#include <string>
#include <map>
#include <tuple>
#include <type_traits>
#include <boost/program_options.hpp>
#include <boost/optional.hpp>
#include <boost/variant.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/optional/optional_io.hpp>
#include "ifc_geom_api.h"
#ifndef SWIG
namespace po = boost::program_options;
namespace std {
istream& operator>>(istream& in, set<int>& ints);
}
#endif
namespace ifcopenshell {
namespace geometry {
inline namespace settings {
class IFC_GEOM_API ConversionSettings {
#ifndef SWIG
template <typename T, typename U = int>
struct HasDefault : std::false_type { };
template <typename T>
struct HasDefault<T, decltype((void)T::defaultvalue, 0)> : std::true_type { };
#endif
template <typename Derived, typename T>
struct SettingBase {
typedef T base_type;
boost::optional<T> value;
SettingBase() {}
void defineOption(po::options_description& desc) {
auto apply_default = [](auto x) {
if constexpr (HasDefault<Derived>()) {
return x->default_value(Derived::defaultvalue);
} else {
return x;
}
};
if constexpr (std::is_same_v<T, bool>) {
// @todo bool_switch doesn't work with optional unfortunately...
value.emplace();
desc.add_options()(Derived::name, apply_default(po::bool_switch(&*value)), Derived::description);
} else {
desc.add_options()(Derived::name, apply_default(po::value(&value)), Derived::description);
}
}
T get() const {
if (value) {
return value.get();
}
if constexpr (HasDefault<Derived>()) {
return Derived::defaultvalue;
}
throw std::runtime_error("Setting not set");
}
bool has() const {
// @todo this is not reliable, better use vmap[...].defaulted()
return !!value;
}
};
// These are the old geometry settings values from the kernel
struct MesherLinearDeflection : public SettingBase<MesherLinearDeflection, double> {
static constexpr const char* const name = "mesher-linear-deflection";
static constexpr const char* const description = "Specifies the linear deflection of the mesher. Controls the detail of curved surfaces in triangulated output formats.";
static constexpr double defaultvalue = 0.001;
};
struct MesherAngularDeflection : public SettingBase<MesherAngularDeflection, double> {
static constexpr const char* const name = "mesher-angular-deflection";
static constexpr const char* const description = "Sets the angular tolerance of the mesher in radians 0.5 by default if not specified.";
static constexpr double defaultvalue = 0.5;
};
struct ReorientShells : public SettingBase<ReorientShells, bool> {
static constexpr const char* const name = "reorient-shells";
static constexpr const char* const description = "Specifies whether to orient the faces of IfcConnectedFaceSets. "
"This is a potentially time consuming operation, but guarantees a "
"consistent orientation of surface normals, even if the faces are not "
"properly oriented in the IFC file.";
static constexpr bool defaultvalue = false;
};
struct LengthUnit : public SettingBase<LengthUnit, double> {
static constexpr const char* const name = "length-unit";
static constexpr const char* const description = "";
static constexpr double defaultvalue = 1.0;
};
struct PlaneUnit : public SettingBase<PlaneUnit, double> {
static constexpr const char* const name = "angle-unit";
static constexpr const char* const description = "";
static constexpr double defaultvalue = 1.0;
};
struct Precision : public SettingBase<Precision, double> {
static constexpr const char* const name = "precision";
static constexpr const char* const description = "";
static constexpr double defaultvalue = 0.00001;
};
struct IncludeCurves : public SettingBase<IncludeCurves, bool> {
static constexpr const char* const name = "plan";
static constexpr const char* const description = "Specifies whether to include curves in the output result. Typically "
"these are representations of type Plan or Axis. Excluded by default.";
static constexpr bool defaultvalue = false;
};
struct IncludeSurfaces : public SettingBase<IncludeSurfaces, bool> {
static constexpr const char* const name = "model";
static constexpr const char* const description = "Specifies whether to include surfaces and solids in the output result. "
"Typically these are representations of type Body or Facetation. "
"Included by default.";
static constexpr bool defaultvalue = true;
};
struct LayersetFirst : public SettingBase<LayersetFirst, bool> {
static constexpr const char* const name = "layerset-first";
static constexpr const char* const description = "Assigns the first layer material of the layerset "
"to the complete product.";
static constexpr bool defaultvalue = false;
};
struct DisableBooleanResult : public SettingBase<DisableBooleanResult, bool> {
static constexpr const char* const name = "disable-boolean-result";
static constexpr const char* const description = "Specifies whether to disable the boolean operation within representations "
"such as clippings by means of IfcBooleanResult and subtypes";
static constexpr bool defaultvalue = false;
};
struct NoWireIntersectionCheck : public SettingBase<NoWireIntersectionCheck, bool> {
static constexpr const char* const name = "no-wire-intersection-check";
static constexpr const char* const description = "Skip wire intersection check.";
static constexpr bool defaultvalue = false;
};
struct NoWireIntersectionTolerance : public SettingBase<NoWireIntersectionTolerance, double> {
static constexpr const char* const name = "no-wire-intersection-tolerance";
static constexpr const char* const description = "Set wire intersection tolerance to 0.";
static constexpr bool defaultvalue = false;
};
struct PrecisionFactor : public SettingBase<PrecisionFactor, double> {
static constexpr const char* const name = "precision-factor";
static constexpr const char* const description = "Option to increase linear tolerance for more permissive edge curves and fewer artifacts after "
"boolean operations at the expense of geometric detail "
"due to vertex collapsing and wire intersection fuzziness.";
static constexpr double defaultvalue = 1.0;
};
struct DebugBooleanOperations : public SettingBase<DebugBooleanOperations, double> {
static constexpr const char* const name = "debug-boolean";
static constexpr const char* const description = "";
static constexpr bool defaultvalue = false;
};
struct BooleanAttempt2d : public SettingBase<BooleanAttempt2d, double> {
static constexpr const char* const name = "boolean-attempt-2d";
static constexpr const char* const description = "Do not attempt to process boolean subtractions in 2D.";
static constexpr bool defaultvalue = true;
};
// These are the old IteratorSettings
struct WeldVertices : public SettingBase<WeldVertices, bool> {
static constexpr const char* const name = "weld-vertices";
static constexpr const char* const description = "Specifies whether vertices are welded, meaning that the coordinates "
"vector will only contain unique xyz-triplets. This results in a "
"manifold mesh which is useful for modelling applications, but might "
"result in unwanted shading artefacts in rendering applications.";
static constexpr bool defaultvalue = true;
};
struct UseWorldCoords : public SettingBase<UseWorldCoords, bool> {
static constexpr const char* const name = "use-world-coords";
static constexpr const char* const description = "Specifies whether to apply the local placements of building elements "
"directly to the coordinates of the representation mesh rather than "
"to represent the local placement in the 4x3 matrix, which will in that "
"case be the identity matrix.";
static constexpr bool defaultvalue = false;
};
struct ConvertBackUnits : public SettingBase<ConvertBackUnits, bool> {
static constexpr const char* const name = "convert-back-units";
static constexpr const char* const description = "Specifies whether to convert back geometrical output back to the "
"unit of measure in which it is defined in the IFC file. Default is "
"to use meters.";
static constexpr bool defaultvalue = false;
};
struct ContextIds : public SettingBase<ContextIds, std::set<int>> {
static constexpr const char* const name = "context-ids";
static constexpr const char* const description = "";
};
enum IteratorOutputOptions {
TRIANGULATED,
NATIVE,
SERIALIZED
};
std::istream& operator>>(std::istream& in, IteratorOutputOptions& ioo);
struct IteratorOutput : public SettingBase<IteratorOutput, IteratorOutputOptions> {
static constexpr const char* const name = "iterator-output";
static constexpr const char* const description = "";
static constexpr IteratorOutputOptions defaultvalue = TRIANGULATED;
};
struct DisableOpeningSubtractions : public SettingBase<DisableOpeningSubtractions, bool> {
static constexpr const char* const name = "disable-opening-subtractions";
static constexpr const char* const description = "Specifies whether to disable the boolean subtraction of "
"IfcOpeningElement Representations from their RelatingElements.";
static constexpr bool defaultvalue = false;
};
struct ApplyDefaultMaterials : public SettingBase<ApplyDefaultMaterials, bool> {
static constexpr const char* const name = "apply-default-materials";
static constexpr const char* const description = "";
static constexpr bool defaultvalue = true;
};
struct DontEmitNormals : public SettingBase<DontEmitNormals, bool> {
static constexpr const char* const name = "no-normals";
static constexpr const char* const description = "Disables computation of normals.Saves time and file size and is useful "
"in instances where you're going to recompute normals for the exported "
"model in other modelling application in any case.";
static constexpr bool defaultvalue = false;
};
struct GenerateUvs : public SettingBase<GenerateUvs, bool> {
static constexpr const char* const name = "generate-uvs";
static constexpr const char* const description = "Generates UVs (texture coordinates) by using simple box projection. Requires normals. "
"Not guaranteed to work properly if used with --weld-vertices.";
static constexpr bool defaultvalue = false;
};
struct ApplyLayerSets : public SettingBase<ApplyLayerSets, bool> {
static constexpr const char* const name = "enable-layerset-slicing";
static constexpr const char* const description = "Specifies whether to enable the slicing of products according "
"to their associated IfcMaterialLayerSet.";
static constexpr bool defaultvalue = false;
};
struct UseElementHierarchy : public SettingBase<UseElementHierarchy, bool> {
static constexpr const char* const name = "element-hierarchy";
static constexpr const char* const description = "Assign the elements using their e.g IfcBuildingStorey parent."
"Applicable to DAE output.";
static constexpr bool defaultvalue = false;
};
struct ValidateQuantities : public SettingBase<ValidateQuantities, bool> {
static constexpr const char* const name = "validate";
static constexpr const char* const description = "Checks whether geometrical output conforms to the included explicit quantities.";
static constexpr bool defaultvalue = false;
};
struct EdgeArrows : public SettingBase<EdgeArrows, bool> {
static constexpr const char* const name = "edge-arrows";
static constexpr const char* const description = "Adds arrow heads to edge segments to signify edge direction";
static constexpr bool defaultvalue = false;
};
struct SiteLocalPlacement : public SettingBase<SiteLocalPlacement, bool> {
static constexpr const char* const name = "site-local-placement";
static constexpr const char* const description = "Place elements locally in the IfcSite coordinate system, instead of placing "
"them in the IFC global coords. Applicable for OBJ, DAE, and STP output.";
static constexpr bool defaultvalue = false;
};
struct BuildingLocalPlacement : public SettingBase<BuildingLocalPlacement, bool> {
static constexpr const char* const name = "building-local-placement";
static constexpr const char* const description = "Similar to --site-local-placement, but placing elements in locally in the parent IfcBuilding coord system";
static constexpr bool defaultvalue = false;
};
struct ForceSpaceTransparency : public SettingBase<ForceSpaceTransparency, double> {
static constexpr const char* const name = "force-space-transparency";
static constexpr const char* const description = "Overrides transparency of spaces in geometry output.";
};
}
template <typename settings_t>
class IFC_GEOM_API SettingsContainer {
public:
// Tolerances and settings for various geometrical operations:
enum GeomValue {
// Specifies the deflection of the mesher
// Default: 0.001m / 1mm
GV_DEFLECTION_TOLERANCE,
// Specifies the minimal area of a face to be included in an IfcConnectedFaceset
// Read-only
GV_MINIMAL_FACE_AREA,
// Specifies the threshold distance under which cartesian points are deemed equal
// Read-only
GV_POINT_EQUALITY_TOLERANCE,
// Specifies maximum number of faces for a shell to be reoriented.
// Default: -1
GV_MAX_FACES_TO_ORIENT,
// The length unit used the creation of TopoDS_Shapes, primarily affects the
// interpretation of IfcCartesianPoints and IfcVector magnitudes
// DefaultL 1.0
GV_LENGTH_UNIT,
// The plane angle unit used for the creation of TopoDS_Shapes, primarily affects
// the interpretation of IfcParamaterValues of IfcTrimmedCurves
// Default: -1.0 (= not set, fist try degrees, then radians)
GV_PLANEANGLE_UNIT,
// The precision used in boolean operations, setting this value too low results
// in artefacts and potentially modelling failures
// Default: 0.00001 (obtained from IfcGeometricRepresentationContext if available)
GV_PRECISION,
// Whether to process shapes of type Face or higher (1) Wire or lower (-1) or all (0)
GV_DIMENSIONALITY,
GV_LAYERSET_FIRST,
GV_DISABLE_BOOLEAN_RESULT,
GV_NO_WIRE_INTERSECTION_CHECK,
GV_PRECISION_FACTOR,
GV_NO_WIRE_INTERSECTION_TOLERANCE,
GV_DEBUG_BOOLEAN,
GV_BOOLEAN_ATTEMPT_2D,
NUM_SETTINGS
};
void setValue(GeomValue var, double value);
double getValue(GeomValue var) const;
typedef boost::variant<bool, int, double, std::string, std::set<int>, IteratorOutputOptions> value_variant_t;
private:
std::array<double, NUM_SETTINGS> values_ = {
/* deflection_tolerance = */ 0.001,
// @todo make sure these 'read-only' variables work.
/* minimal_face_area = */ std::numeric_limits<double>::quiet_NaN(),
/* max_faces_to_orient = */ -1.0,
/* ifc_length_unit = */ 1.0,
/* ifc_planeangle_unit = */ -1.0,
/* modelling_precision = */ 0.00001,
/* dimensionality = */ 1.,
/* layerset_first = */ -1.,
/* disable_boolean_result = */ -1.
/* no_wire_intersection_check = */ -1.,
/* precision_factor = */ 10.,
/* no_wire_intersection_tolerance = */ -1.,
/* boolean_debug_setting = */ -1.,
/* boolean_attempt_2d = */ 1.
};
settings_t settings;
template <std::size_t Index>
void define_options_(po::options_description& desc) {
std::get<Index>(settings).defineOption(desc);
if constexpr (Index + 1 < std::tuple_size_v<settings_t>) {
define_options_<Index + 1>(desc);
}
}
template <std::size_t Index>
value_variant_t get_option_(const std::string& name) const {
if (std::tuple_element_t<Index, settings_t>::name == name) {
return std::get<Index>(settings).get();
}
if constexpr (Index + 1 < std::tuple_size_v<settings_t>) {
return get_option_<Index + 1>(name);
} else {
throw std::runtime_error("Setting not available");
}
}
template <std::size_t Index>
void set_option_(const std::string& name, const value_variant_t& val) {
if (std::tuple_element_t<Index, settings_t>::name == name) {
std::get<Index>(settings).value = boost::get<typename std::tuple_element_t<Index, settings_t>::base_type>(val);
} else if constexpr (Index + 1 < std::tuple_size_v<settings_t>) {
set_option_<Index + 1>(name, val);
} else {
throw std::runtime_error("Setting not available");
}
}
template <std::size_t Index>
void get_setting_names_(std::vector<std::string>& vec) const {
vec.push_back(std::tuple_element_t<Index, settings_t>::name);
if constexpr (Index + 1 < std::tuple_size_v<settings_t>) {
return get_setting_names_<Index + 1>(vec);
}
}
public:
typedef settings_t settings_tuple;
void define_options(po::options_description& desc) {
define_options_<0>(desc);
}
template <typename T>
const T& get() const {
return std::get<T>(settings);
}
template <typename T>
T& get() {
return std::get<T>(settings);
}
template <typename T>
void set(T& v) {
std::get<T>(settings) = v;
}
value_variant_t get(const std::string& name) const {
return get_option_<0>(name);
}
void set(const std::string& name, value_variant_t val) {
set_option_<0>(name, val);
}
std::vector<std::string> setting_names() const {
std::vector<std::string> r;
get_setting_names_<0>(r);
return r;
}
};
}
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>
>
{};
}
}
// namespace ifcopenshell {
// namespace geometry {
//
// class IFC_GEOM_API ConversionSettings {
// public:
// // Tolerances and settings for various geometrical operations:
// enum GeomValue {
// //
// // Default: 0.001m / 1mm
// GV_DEFLECTION_TOLERANCE,
//
// // The length unit used the creation of TopoDS_Shapes, primarily affects the
// // interpretation of IfcCartesianPoints and IfcVector magnitudes
// // DefaultL 1.0
// GV_LENGTH_UNIT,
// // The plane angle unit used for the creation of TopoDS_Shapes, primarily affects
// // the interpretation of IfcParamaterValues of IfcTrimmedCurves
// // Default: -1.0 (= not set, fist try degrees, then radians)
// GV_PLANEANGLE_UNIT,
// // The precision used in boolean operations, setting this value too low results
// // in artefacts and potentially modelling failures
// // Default: 0.00001 (obtained from IfcGeometricRepresentationContext if available)
// GV_PRECISION,
// // Whether to process shapes of type Face or higher (1) Wire or lower (-1) or all (0)
// GV_DIMENSIONALITY,
// GV_LAYERSET_FIRST,
// GV_DISABLE_BOOLEAN_RESULT,
// GV_NO_WIRE_INTERSECTION_CHECK,
// GV_PRECISION_FACTOR,
// GV_NO_WIRE_INTERSECTION_TOLERANCE,
// GV_DEBUG_BOOLEAN,
// GV_BOOLEAN_ATTEMPT_2D,
// NUM_SETTINGS
// };
//
// void setValue(GeomValue var, double value);
//
// double getValue(GeomValue var) const;
//
// private:
// std::array<double, NUM_SETTINGS> values_ = {
// /* deflection_tolerance = */ 0.001,
// // @todo make sure these 'read-only' variables work.
// /* minimal_face_area = */ std::numeric_limits<double>::quiet_NaN(),
// /* max_faces_to_orient = */ -1.0,
// /* ifc_length_unit = */ 1.0,
// /* ifc_planeangle_unit = */ -1.0,
// /* modelling_precision = */ 0.00001,
// /* dimensionality = */ 1.,
// /* layerset_first = */ -1.,
// /* disable_boolean_result = */ -1.
// /* no_wire_intersection_check = */ -1.,
// /* precision_factor = */ 10.,
// /* no_wire_intersection_tolerance = */ -1.,
// /* boolean_debug_setting = */ -1.,
// /* boolean_attempt_2d = */ 1.
// };
// };
// }
// }
// @todo find a place
namespace IfcGeom {
+11 -13
View File
@@ -4,12 +4,12 @@
using namespace ifcopenshell::geometry;
ifcopenshell::geometry::Converter::Converter(const std::string& geometry_library, IfcParse::IfcFile* file, IfcGeom::IteratorSettings& s)
ifcopenshell::geometry::Converter::Converter(const std::string& geometry_library, IfcParse::IfcFile* file, ifcopenshell::geometry::Settings& s)
: geometry_library_(boost::to_lower_copy(geometry_library))
, settings_(s)
{
mapping_ = impl::mapping_implementations().construct(file, settings_);
kernel_ = kernels::construct(geometry_library, mapping_->conversion_settings());
kernel_ = kernels::construct(geometry_library, mapping_->settings());
}
namespace {
@@ -44,7 +44,7 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_represe
return 0;
}
if (settings_.get(IfcGeom::IteratorSettings::APPLY_LAYERSETS)) {
if (settings_.get<ifcopenshell::geometry::settings::ApplyLayerSets>().get()) {
ifcopenshell::geometry::layerset_information layerinfo;
std::vector<ifcopenshell::geometry::endpoint_connection> neighbours;
std::map<IfcUtil::IfcBaseEntity*, ifcopenshell::geometry::layerset_information> neigbour_layers;
@@ -133,11 +133,11 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_represe
representation_id_builder << "-material-" << single_material->data().id();
}
if (settings_.force_space_transparency() >= 0. && product->declaration().is("IfcSpace")) {
if (settings_.get<ifcopenshell::geometry::settings::ForceSpaceTransparency>().has() && product->declaration().is("IfcSpace")) {
for (auto& s : shapes) {
if (s.hasStyle()) {
// @todo the uglyness
const_cast<taxonomy::style*>(&*s.StylePtr())->transparency = settings_.force_space_transparency();
const_cast<taxonomy::style*>(&*s.StylePtr())->transparency = settings_.get<ifcopenshell::geometry::settings::ForceSpaceTransparency>().get();
}
}
}
@@ -156,14 +156,12 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_represe
const std::string guid = product->get_value<std::string>("GlobalId", "");
const std::string product_type = product->declaration().name();
IfcGeom::ElementSettings element_settings(settings_, mapping_->get_length_unit(), product_type);
// Does the IfcElement have any IfcOpenings?
// Note that openings for IfcOpeningElements are not processed
auto openings = mapping_->find_openings(product);
if (!settings_.get(IfcGeom::IteratorSettings::DISABLE_OPENING_SUBTRACTIONS) && openings && openings->size()) {
if (!settings_.get<ifcopenshell::geometry::settings::DisableOpeningSubtractions>().get() && openings && openings->size()) {
representation_id_builder << "-openings";
for (auto it = openings->begin(); it != openings->end(); ++it) {
representation_id_builder << "-" << (*it)->data().id();
@@ -191,23 +189,23 @@ IfcGeom::BRepElement* ifcopenshell::geometry::Converter::create_brep_for_represe
opened_shapes = shapes;
}
if (settings_.get(IfcGeom::IteratorSettings::USE_WORLD_COORDS)) {
if (settings_.get<ifcopenshell::geometry::settings::UseWorldCoords>().get()) {
for (auto it = opened_shapes.begin(); it != opened_shapes.end(); ++it) {
it->prepend(place);
}
place = ifcopenshell::geometry::taxonomy::make<ifcopenshell::geometry::taxonomy::matrix4>();
representation_id_builder << "-world-coords";
}
shape = new IfcGeom::Representation::BRep(element_settings, representation_id_builder.str(), opened_shapes);
} else if (settings_.get(IfcGeom::IteratorSettings::USE_WORLD_COORDS)) {
shape = new IfcGeom::Representation::BRep(settings_, product_type, representation_id_builder.str(), opened_shapes);
} else if (settings_.get<ifcopenshell::geometry::settings::UseWorldCoords>().get()) {
for (auto it = shapes.begin(); it != shapes.end(); ++it) {
it->prepend(place);
}
place = ifcopenshell::geometry::taxonomy::make<ifcopenshell::geometry::taxonomy::matrix4>();
representation_id_builder << "-world-coords";
shape = new IfcGeom::Representation::BRep(element_settings, representation_id_builder.str(), shapes);
shape = new IfcGeom::Representation::BRep(settings_, product_type, representation_id_builder.str(), shapes);
} else {
shape = new IfcGeom::Representation::BRep(element_settings, representation_id_builder.str(), shapes);
shape = new IfcGeom::Representation::BRep(settings_, product_type, representation_id_builder.str(), shapes);
}
std::string context_string = "";
+8 -8
View File
@@ -18,19 +18,19 @@ namespace ifcopenshell { namespace geometry {
typedef boost::shared_ptr<IfcGeom::Representation::BRep> brep_ptr;
private:
std::string geometry_library_;
abstract_mapping* mapping_;
kernels::AbstractKernel* kernel_;
IfcGeom::IteratorSettings settings_;
ifcopenshell::geometry::abstract_mapping* mapping_;
ifcopenshell::geometry::kernels::AbstractKernel* kernel_;
ifcopenshell::geometry::Settings settings_;
std::map<ifcopenshell::geometry::taxonomy::ptr, brep_ptr, ifcopenshell::geometry::taxonomy::less_functor> cache_;
public:
kernels::AbstractKernel* kernel() { return kernel_; }
ifcopenshell::geometry::kernels::AbstractKernel* kernel() { return kernel_; }
Converter(const std::string& geometry_library, IfcParse::IfcFile* file, IfcGeom::IteratorSettings& settings);
Converter(const std::string& geometry_library, IfcParse::IfcFile* file, ifcopenshell::geometry::Settings& settings);
~Converter() {}
abstract_mapping* mapping() const { return mapping_; }
ifcopenshell::geometry::abstract_mapping* mapping() const { return mapping_; }
/*
virtual NativeElement<double, double>* convert(
@@ -49,8 +49,8 @@ namespace ifcopenshell { namespace geometry {
IfcGeom::BRepElement* create_brep_for_representation_and_product(const IfcUtil::IfcBaseEntity* representation, const IfcUtil::IfcBaseEntity* product);
// IfcGeom::BRepElement* create_brep_for_processed_representation(const IfcUtil::IfcBaseEntity* representation, const IfcUtil::IfcBaseEntity* product, IfcGeom::BRepElement* brep);
IfcGeom::BRepElement* create_brep_for_representation_and_product(taxonomy::ptr, const IfcUtil::IfcBaseEntity* product, const taxonomy::matrix4::ptr& place);
IfcGeom::BRepElement* create_brep_for_processed_representation(const IfcUtil::IfcBaseEntity* product, const taxonomy::matrix4::ptr& place, IfcGeom::BRepElement*);
IfcGeom::BRepElement* create_brep_for_representation_and_product(ifcopenshell::geometry::taxonomy::ptr, const IfcUtil::IfcBaseEntity* product, const ifcopenshell::geometry::taxonomy::matrix4::ptr& place);
IfcGeom::BRepElement* create_brep_for_processed_representation(const IfcUtil::IfcBaseEntity* product, const ifcopenshell::geometry::taxonomy::matrix4::ptr& place, IfcGeom::BRepElement*);
};
}}
+75 -44
View File
@@ -23,45 +23,69 @@
#include "../ifcgeom/Serializer.h"
#include "../ifcgeom/IfcGeomElement.h"
class SerializerSettings : public IfcGeom::IteratorSettings
{
public:
enum Setting : uint64_t
{
/// Use entity names instead of unique IDs for naming elements.
/// Applicable for OBJ, DAE, and SVG output.
USE_ELEMENT_NAMES = 1U << (IfcGeom::IteratorSettings::NUM_SETTINGS + 1U),
/// Use entity GUIDs instead of unique IDs for naming elements.
/// Applicable for OBJ, DAE, and SVG output.
USE_ELEMENT_GUIDS = 1U << (IfcGeom::IteratorSettings::NUM_SETTINGS + 2U),
/// Use material names instead of unique IDs for naming materials.
/// Applicable for OBJ and DAE output.
USE_MATERIAL_NAMES = 1U << (IfcGeom::IteratorSettings::NUM_SETTINGS + 3U),
/// Use element types instead of unique IDs for naming elements.
/// Applicable for DAE output.
USE_ELEMENT_TYPES = 1U << (IfcGeom::IteratorSettings::NUM_SETTINGS + 4U),
/// Order the elements using their IfcBuildingStorey parent
/// Applicable for DAE output
USE_ELEMENT_HIERARCHY = 1U << (IfcGeom::IteratorSettings::NUM_SETTINGS + 5U),
/// Use step ids for naming elements.
/// Applicable for OBJ, DAE, and SVG output.
USE_ELEMENT_STEPIDS = 1U << (IfcGeom::IteratorSettings::NUM_SETTINGS + 6U),
/// Use Y UP .
/// Applicable for OBJ output.
USE_Y_UP = 1ULL << (IfcGeom::IteratorSettings::NUM_SETTINGS + 7ULL),
/// Number of different setting flags.
NUM_SETTINGS = 7
};
namespace ifcopenshell {
namespace geometry {
inline namespace settings {
SerializerSettings()
: precision(DEFAULT_PRECISION) { }
struct UseElementNames : public SettingBase<UseElementNames, bool> {
static constexpr const char* const name = "use-element-names";
static constexpr const char* const description = "Use entity instance IfcRoot.Name instead of unique IDs for naming elements upon serialization. "
"Applicable for OBJ, DAE, STP, and SVG output.";
static constexpr bool defaultvalue = false;
};
/// Sets the precision used to format floating-point values, 15 by default.
/// Use a negative value to use the system's default precision (should be 6 typically).
short precision;
struct UseElementGuids : public SettingBase<UseElementGuids, bool> {
static constexpr const char* const name = "use-element-guids";
static constexpr const char* const description = "Use entity instance IfcRoot.GlobalId instead of unique IDs for naming elements upon serialization. "
"Applicable for OBJ, DAE, STP, and SVG output.";
static constexpr bool defaultvalue = false;
};
enum { DEFAULT_PRECISION = 15 };
};
struct UseElementStepIds : public SettingBase<UseElementStepIds, bool> {
static constexpr const char* const name = "use-element-step-ids";
static constexpr const char* const description = "Use the numeric step identifier (entity instance name) for naming elements upon serialization. "
"Applicable for OBJ, DAE, STP, and SVG output.";
static constexpr bool defaultvalue = false;
};
struct UseMaterialNames : public SettingBase<UseMaterialNames, bool> {
static constexpr const char* const name = "use-material-names";
static constexpr const char* const description = "Use material names instead of unique IDs for naming materials upon serialization. "
"Applicable for OBJ and DAE output.";
static constexpr bool defaultvalue = false;
};
struct UseElementTypes : public SettingBase<UseElementTypes, bool> {
static constexpr const char* const name = "use-element-types";
static constexpr const char* const description = "Use element types instead of unique IDs for naming elements upon serialization. "
"Applicable to DAE output.";
static constexpr bool defaultvalue = false;
};
struct UseYUp : public SettingBase<UseYUp, bool> {
static constexpr const char* const name = "y-up";
static constexpr const char* const description = "Change the 'up' axis to positive Y, default is Z UP. Applicable to OBJ output.";
static constexpr bool defaultvalue = false;
};
struct FloatingPointDigits : public SettingBase<FloatingPointDigits, int> {
static constexpr const char* const name = "digits";
static constexpr const char* const description = "Sets the precision to be used to format floating-point values, 15 by default. "
"Use a negative value to use the system's default precision (should be 6 typically). "
"Applicable for OBJ and DAE output. For DAE output, value >= 15 means that up to 16 decimals are used, "
" and any other value means that 6 or 7 decimals are used.";
static constexpr bool defaultvalue = 15;
};
}
class SerializerSettings : public SettingsContainer <
// @todo should we use tuple_cat here to unify the settings into a single class?
std::tuple<UseElementNames, UseElementGuids, UseElementStepIds, UseMaterialNames, UseElementTypes, UseYUp, FloatingPointDigits>
>
{};
}
}
class stream_or_filename {
private:
@@ -103,7 +127,10 @@ class GeometrySerializer : public Serializer {
public:
enum read_type { READ_BREP, READ_TRIANGULATION };
GeometrySerializer(const SerializerSettings& settings) : settings_(settings) {}
GeometrySerializer(const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings)
: geometry_settings_(geometry_settings)
, settings_(settings)
{}
virtual ~GeometrySerializer() {}
virtual bool isTesselated() const = 0;
@@ -112,25 +139,29 @@ public:
virtual void setUnitNameAndMagnitude(const std::string& name, float magnitude) = 0;
virtual IfcGeom::Element* read(IfcParse::IfcFile& f, const std::string& guid, const std::string& representation_id, read_type rt = READ_BREP) = 0;
const SerializerSettings& settings() const { return settings_; }
SerializerSettings& settings() { return settings_; }
const ifcopenshell::geometry::SerializerSettings& settings() const { return settings_; }
ifcopenshell::geometry::SerializerSettings& settings() { return settings_; }
const ifcopenshell::geometry::Settings& geometry_settings() const { return geometry_settings_; }
ifcopenshell::geometry::Settings& geometry_settings() { return geometry_settings_; }
/// Returns ID for the object depending on the used setting.
virtual std::string object_id(const IfcGeom::Element* o)
{
if (settings_.get(SerializerSettings::USE_ELEMENT_GUIDS)) return o->guid();
if (settings_.get(SerializerSettings::USE_ELEMENT_NAMES)) return o->name();
if (settings_.get(SerializerSettings::USE_ELEMENT_STEPIDS)) return "id-" + boost::lexical_cast<std::string>(o->id());
if (settings_.get<ifcopenshell::geometry::settings::UseElementGuids>().get()) return o->guid();
if (settings_.get<ifcopenshell::geometry::settings::UseElementNames>().get()) return o->name();
if (settings_.get<ifcopenshell::geometry::settings::UseElementStepIds>().get()) return "id-" + boost::lexical_cast<std::string>(o->id());
return o->unique_id();
}
protected:
SerializerSettings settings_;
ifcopenshell::geometry::Settings geometry_settings_;
ifcopenshell::geometry::SerializerSettings settings_;
};
class WriteOnlyGeometrySerializer : public GeometrySerializer {
public:
WriteOnlyGeometrySerializer(const SerializerSettings& settings) : GeometrySerializer(settings) {}
WriteOnlyGeometrySerializer(const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings) : GeometrySerializer(geometry_settings, settings) {}
virtual IfcGeom::Element* read(IfcParse::IfcFile&, const std::string&, const std::string&, read_type = READ_BREP) {
throw std::runtime_error("Not supported");
+4 -4
View File
@@ -35,10 +35,10 @@ namespace IfcGeom {
class Transformation {
private:
ElementSettings settings_;
ifcopenshell::geometry::Settings settings_;
ifcopenshell::geometry::taxonomy::matrix4::ptr matrix_;
public:
Transformation(const ElementSettings& settings, const ifcopenshell::geometry::taxonomy::matrix4::ptr& matrix)
Transformation(const ifcopenshell::geometry::Settings& settings, const ifcopenshell::geometry::taxonomy::matrix4::ptr& matrix)
: settings_(settings)
, matrix_(matrix)
{}
@@ -93,7 +93,7 @@ namespace IfcGeom {
const std::vector<const IfcGeom::Element*> parents() const { return _parents; }
void SetParents(std::vector<const IfcGeom::Element*> newparents) { _parents = newparents; }
Element(const ElementSettings& settings, int id, int parent_id, const std::string& name, const std::string& type,
Element(const ifcopenshell::geometry::Settings& settings, int id, int parent_id, const std::string& name, const std::string& type,
const std::string& guid, const std::string& context, const ifcopenshell::geometry::taxonomy::matrix4::ptr& trsf, const IfcUtil::IfcBaseEntity* product)
: _id(id), _parent_id(parent_id), _name(name), _type(type), _guid(guid), _context(context), _transformation(settings, trsf)
, product_(product)
@@ -132,7 +132,7 @@ namespace IfcGeom {
BRepElement(int id, int parent_id, const std::string& name, const std::string& type, const std::string& guid,
const std::string& context, const ifcopenshell::geometry::taxonomy::matrix4::ptr& trsf, const boost::shared_ptr<IfcGeom::Representation::BRep>& geometry,
const IfcUtil::IfcBaseEntity* product)
: Element(geometry->settings() ,id, parent_id, name, type, guid, context, trsf, product)
: Element(geometry->settings(), id, parent_id, name, type, guid, context, trsf, product)
, _geometry(geometry)
{}
+2 -2
View File
@@ -75,7 +75,7 @@ namespace IfcGeom {
// in IfcConvert so invocation is bound to a single file with a single
// schema.
// @todo pass settings
IfcGeom::IteratorSettings s;
ifcopenshell::geometry::Settings s;
static auto mapping = ifcopenshell::geometry::impl::mapping_implementations().construct(prod->data().file, s);
while ((parent = mapping->get_decomposing_entity(current, traverse_openings)) != nullptr) {
if (pred(parent)) {
@@ -183,7 +183,7 @@ namespace IfcGeom {
bool match(IfcUtil::IfcBaseEntity* prod) const {
// @todo
IfcGeom::IteratorSettings s;
ifcopenshell::geometry::Settings s;
static auto mapping = ifcopenshell::geometry::impl::mapping_implementations().construct(prod->data().file, s);
layer_map_t layers = mapping->get_layers(prod);
return std::find_if(layers.begin(), layers.end(), wildcards_match(values)) != layers.end();
+3
View File
@@ -2,6 +2,7 @@
#include "../ifcparse/IfcLogger.h"
/*
void IfcGeom::IteratorSettings::set_deflection_tolerance(double value)
{
deflection_tolerance_ = value;
@@ -10,3 +11,5 @@ void IfcGeom::IteratorSettings::set_deflection_tolerance(double value)
deflection_tolerance_ = 1e-3;
}
}
*/
+13 -12
View File
@@ -142,7 +142,7 @@ namespace {
#endif
IfcGeom::Representation::Serialization::Serialization(const BRep& brep)
: Representation(brep.settings())
: Representation(brep.settings(), brep.entity())
, id_(brep.id())
{
for (auto it = brep.begin(); it != brep.end(); ++it) {
@@ -213,9 +213,9 @@ IfcGeom::ConversionResultShape* IfcGeom::Representation::BRep::as_compound(bool
trsf = tr;
}
if (!force_meters && settings().get(IteratorSettings::CONVERT_BACK_UNITS)) {
if (!force_meters && settings().get<ifcopenshell::geometry::settings::ConvertBackUnits>().get()) {
gp_Trsf scale;
scale.SetScaleFactor(1.0 / settings().unit_magnitude());
scale.SetScaleFactor(1.0 / settings().get<ifcopenshell::geometry::settings::LengthUnit>().get());
trsf.PreMultiply(scale);
}
@@ -299,7 +299,7 @@ bool IfcGeom::Representation::BRep::calculate_projected_surface_area(const ifcop
for (IfcGeom::ConversionResults::const_iterator it = begin(); it != end(); ++it) {
double x, y, z;
surface_area_along_direction(settings().deflection_tolerance(), *std::static_pointer_cast<ifcopenshell::geometry::OpenCascadeShape>(it->Shape()), ax, x, y, z);
surface_area_along_direction(settings().get<ifcopenshell::geometry::settings::MesherLinearDeflection>().get(), *std::static_pointer_cast<ifcopenshell::geometry::OpenCascadeShape>(it->Shape()), ax, x, y, z);
if (util::is_manifold(*std::static_pointer_cast<ifcopenshell::geometry::OpenCascadeShape>(it->Shape()))) {
x /= 2.;
@@ -323,7 +323,7 @@ bool IfcGeom::Representation::BRep::calculate_projected_surface_area(const ifcop
}
IfcGeom::Representation::Triangulation::Triangulation(const BRep& shape_model)
: Representation(shape_model.settings())
: Representation(shape_model.settings(), shape_model.entity())
, id_(shape_model.id())
, weld_offset_(0)
{
@@ -343,8 +343,8 @@ IfcGeom::Representation::Triangulation::Triangulation(const BRep& shape_model)
}
}
if (settings().get(IteratorSettings::APPLY_DEFAULT_MATERIALS) && surface_style_id == -1) {
const auto& material = IfcGeom::get_default_style(settings().element_type());
if (settings().get<ifcopenshell::geometry::settings::ApplyDefaultMaterials>().get() && surface_style_id == -1) {
const auto& material = IfcGeom::get_default_style(shape_model.entity());
auto mit = std::find(_materials.begin(), _materials.end(), material);
if (mit == _materials.end()) {
surface_style_id = (int)_materials.size();
@@ -390,12 +390,13 @@ std::vector<double> IfcGeom::Representation::Triangulation::box_project_uvs(cons
}
int IfcGeom::Representation::Triangulation::addVertex(int material_index, double pX, double pY, double pZ) {
const bool convert = settings().get(IteratorSettings::CONVERT_BACK_UNITS);
const double X = convert ? (pX / settings().unit_magnitude()) : pX;
const double Y = convert ? (pY / settings().unit_magnitude()) : pY;
const double Z = convert ? (pZ / settings().unit_magnitude()) : pZ;
const bool convert = settings().get<ifcopenshell::geometry::settings::ConvertBackUnits>().get();
auto unit_magnitude = settings().get<ifcopenshell::geometry::settings::LengthUnit>().get();
const double X = convert ? (pX /unit_magnitude) : pX;
const double Y = convert ? (pY /unit_magnitude) : pY;
const double Z = convert ? (pZ /unit_magnitude) : pZ;
int i = (int)_verts.size() / 3;
if (settings().get(IteratorSettings::WELD_VERTICES)) {
if (settings().get<ifcopenshell::geometry::settings::WeldVertices>().get()) {
const VertexKey key = std::make_pair(material_index, std::make_pair(X, std::make_pair(Y, Z)));
typename VertexKeyMap::const_iterator it = welds.find(key);
if (it != welds.end()) return it->second;
+18 -12
View File
@@ -20,7 +20,7 @@
#ifndef IFCGEOMREPRESENTATION_H
#define IFCGEOMREPRESENTATION_H
#include "../ifcgeom/IteratorSettings.h"
#include "../ifcgeom/ConversionSettings.h"
#include "../ifcgeom/ConversionResult.h"
#include <map>
@@ -33,12 +33,17 @@ namespace IfcGeom {
Representation(const Representation&); //N/A
Representation& operator =(const Representation&); //N/A
protected:
const ElementSettings settings_;
const ifcopenshell::geometry::Settings settings_;
const std::string entity_;
public:
explicit Representation(const ElementSettings& settings)
: settings_(settings)
explicit Representation(const ifcopenshell::geometry::Settings& settings, const std::string& entity)
: settings_(settings)
, entity_(entity)
{}
const ElementSettings& settings() const { return settings_; }
const ifcopenshell::geometry::Settings& settings() const { return settings_; }
const std::string& entity() const {
return entity_;
}
virtual ~Representation() {}
};
@@ -49,8 +54,8 @@ namespace IfcGeom {
BRep(const BRep& other);
BRep& operator=(const BRep& other);
public:
BRep(const ElementSettings& settings, const std::string& id, const IfcGeom::ConversionResults& shapes)
: Representation(settings)
BRep(const ifcopenshell::geometry::Settings& settings, const std::string& entity, const std::string& id, const IfcGeom::ConversionResults& shapes)
: Representation(settings, entity)
, id_(id)
, shapes_(shapes)
{}
@@ -108,8 +113,8 @@ namespace IfcGeom {
size_t weld_offset_;
VertexKeyMap welds;
Triangulation(IfcGeom::IteratorSettings settings)
: Representation(IfcGeom::ElementSettings{ settings, 1., "" })
Triangulation(const ifcopenshell::geometry::Settings& settings, const std::string& entity)
: Representation(settings, entity)
, weld_offset_(0)
{}
@@ -127,7 +132,8 @@ namespace IfcGeom {
Triangulation(const BRep& shape_model);
Triangulation(
ElementSettings settings,
const ifcopenshell::geometry::Settings& settings,
const std::string& entity,
const std::string& id,
const std::vector<double>& verts,
const std::vector<int>& faces,
@@ -137,7 +143,7 @@ namespace IfcGeom {
const std::vector<int>& material_ids,
const std::vector<ifcopenshell::geometry::taxonomy::style>& materials
)
: Representation(settings)
: Representation(settings, entity)
, id_(id)
, _verts(verts)
, _faces(faces)
@@ -154,7 +160,7 @@ namespace IfcGeom {
/// @todo Very simple impl. Assumes that input vertices and normals match 1:1.
static std::vector<double> box_project_uvs(const std::vector<double> &vertices, const std::vector<double> &normals);
static Triangulation* empty(IfcGeom::IteratorSettings settings) { return new Triangulation(settings); }
static Triangulation* empty(const ifcopenshell::geometry::Settings& settings) { return new Triangulation(settings, ""); }
/// Welds vertices that belong to different faces
int addVertex(int material_index, double X, double Y, double Z);
+32 -37
View File
@@ -85,14 +85,11 @@
#include <chrono>
#include <atomic>
// @todo
using namespace ifcopenshell::geometry;
namespace {
struct geometry_conversion_result {
int index;
ifcopenshell::geometry::taxonomy::ptr item;
std::vector<std::pair<const IfcUtil::IfcBaseEntity*, taxonomy::matrix4::ptr>> products;
std::vector<std::pair<const IfcUtil::IfcBaseEntity*, ifcopenshell::geometry::taxonomy::matrix4::ptr>> products;
std::vector<IfcGeom::BRepElement*> breps;
std::vector<IfcGeom::Element*> elements;
};
@@ -124,17 +121,17 @@ namespace IfcGeom {
std::string geometry_library_;
IteratorSettings settings_;
ifcopenshell::geometry::Settings settings_;
IfcParse::IfcFile* ifc_file;
std::vector<filter_t> filters_;
bool owns_ifc_file;
int num_threads_;
// When single-threaded
Converter* converter_;
ifcopenshell::geometry::Converter* converter_;
// When multi-threaded
std::vector<Converter*> kernel_pool;
std::vector<ifcopenshell::geometry::Converter*> kernel_pool;
// The object is fetched beforehand to be sure that get() returns a valid element
TriangulationElement* current_triangulation;
@@ -151,8 +148,8 @@ namespace IfcGeom {
std::string unit_name_;
double unit_magnitude_;
taxonomy::point3 bounds_min_;
taxonomy::point3 bounds_max_;
ifcopenshell::geometry::taxonomy::point3 bounds_min_;
ifcopenshell::geometry::taxonomy::point3 bounds_max_;
// Should not be destructed because, destructor is blocking
std::future<void> init_future_;
@@ -171,8 +168,8 @@ namespace IfcGeom {
return *initialization_outcome_;
}
converter_ = new Converter(geometry_library_, ifc_file, settings_);
std::vector<geometry_conversion_task> reps;
converter_ = new ifcopenshell::geometry::Converter(geometry_library_, ifc_file, settings_);
std::vector<ifcopenshell::geometry::geometry_conversion_task> reps;
converter_->mapping()->get_representations(reps, filters_);
for (auto& task : reps) {
@@ -183,7 +180,7 @@ namespace IfcGeom {
}
std::transform(task.products->begin(), task.products->end(), std::back_inserter(res.products), [this, &res](IfcUtil::IfcBaseClass* prod) {
auto prod_item = converter_->mapping()->map(prod);
return std::make_pair(prod->as<IfcUtil::IfcBaseEntity>(), taxonomy::cast<taxonomy::geom_item>(prod_item)->matrix);
return std::make_pair(prod->as<IfcUtil::IfcBaseEntity>(), ifcopenshell::geometry::taxonomy::cast<ifcopenshell::geometry::taxonomy::geom_item>(prod_item)->matrix);
});
tasks_.push_back(res);
}
@@ -279,13 +276,13 @@ namespace IfcGeom {
kernel_pool.reserve(conc_threads);
for (unsigned i = 0; i < conc_threads; ++i) {
kernel_pool.push_back(new Converter(geometry_library_, ifc_file, settings_));
kernel_pool.push_back(new ifcopenshell::geometry::Converter(geometry_library_, ifc_file, settings_));
}
std::vector<std::future<geometry_conversion_result*>> threadpool;
for (auto& rep : tasks_) {
Converter* K = nullptr;
ifcopenshell::geometry::Converter* K = nullptr;
if (threadpool.size() < kernel_pool.size()) {
K = kernel_pool[threadpool.size()];
}
@@ -309,8 +306,8 @@ namespace IfcGeom {
std::future<geometry_conversion_result*> fu = std::async(
std::launch::async, [this](
Converter* kernel,
const IfcGeom::IteratorSettings& settings,
ifcopenshell::geometry::Converter* kernel,
ifcopenshell::geometry::Settings settings,
geometry_conversion_result* rep) {
this->create_element_(kernel, settings, rep);
return rep;
@@ -364,7 +361,7 @@ namespace IfcGeom {
}
} while (++num_created, next());
} else {
std::vector<geometry_conversion_task> reps;
std::vector<ifcopenshell::geometry::geometry_conversion_task> reps;
converter_->mapping()->get_representations(reps, filters_);
std::vector<IfcUtil::IfcBaseClass*> products;
@@ -374,7 +371,7 @@ namespace IfcGeom {
for (auto& product : products) {
auto prod_item = converter_->mapping()->map(product);
auto vec = taxonomy::cast<taxonomy::geom_item>(prod_item)->matrix->translation_part();
auto vec = ifcopenshell::geometry::taxonomy::cast<ifcopenshell::geometry::taxonomy::geom_item>(prod_item)->matrix->translation_part();
for (int i = 0; i < 3; ++i) {
bounds_min_.components()(i) = std::min(bounds_min_.components()(i), vec(i));
@@ -395,8 +392,8 @@ namespace IfcGeom {
const std::vector<IfcGeom::filter_t>& filters() const { return filters_; }
std::vector<IfcGeom::filter_t>& filters() { return filters_; }
const taxonomy::point3& bounds_min() const { return bounds_min_; }
const taxonomy::point3& bounds_max() const { return bounds_max_; }
const ifcopenshell::geometry::taxonomy::point3& bounds_min() const { return bounds_min_; }
const ifcopenshell::geometry::taxonomy::point3& bounds_max() const { return bounds_max_; }
private:
@@ -460,8 +457,8 @@ namespace IfcGeom {
}
void create_element_(
Converter* kernel,
const IfcGeom::IteratorSettings& settings,
ifcopenshell::geometry::Converter* kernel,
ifcopenshell::geometry::Settings settings,
geometry_conversion_result* rep)
{
auto representation = rep->item;
@@ -507,18 +504,18 @@ namespace IfcGeom {
}
IfcGeom::Element* process_based_on_settings(
const IfcGeom::IteratorSettings& settings,
ifcopenshell::geometry::Settings settings,
IfcGeom::BRepElement* elem,
IfcGeom::TriangulationElement* previous = nullptr)
{
if (settings.get(IfcGeom::IteratorSettings::USE_BREP_DATA)) {
if (settings.get<ifcopenshell::geometry::settings::IteratorOutput>().get() == ifcopenshell::geometry::settings::SERIALIZED) {
try {
return new IfcGeom::SerializedElement(*elem);
} catch (...) {
Logger::Message(Logger::LOG_ERROR, "Getting a serialized element from model failed.");
return nullptr;
}
} else if (!settings.get(IfcGeom::IteratorSettings::DISABLE_TRIANGULATION)) {
} else if (settings.get<ifcopenshell::geometry::settings::IteratorOutput>().get() == ifcopenshell::geometry::settings::TRIANGULATED) {
// the part before the hyphen is the representation id
auto gid2 = elem->geometry().id();
auto hyphen = gid2.find("-");
@@ -610,7 +607,7 @@ namespace IfcGeom {
auto ret = *task_result_iterator_;
// If we want to organize the element considering their hierarchy
if (settings_.get(IteratorSettings::ELEMENT_HIERARCHY))
if (settings_.get<ifcopenshell::geometry::settings::UseElementHierarchy>().get())
{
// We are going to build a vector with the element parents.
// First, create the parent vector
@@ -665,7 +662,7 @@ namespace IfcGeom {
}
const Element* get_object(int id) {
taxonomy::matrix4::ptr m4;
ifcopenshell::geometry::taxonomy::matrix4::ptr m4;
int parent_id = -1;
std::string instance_type, product_name, product_guid;
IfcUtil::IfcBaseEntity* ifc_product = 0;
@@ -684,7 +681,7 @@ namespace IfcGeom {
parent_id = parent_object->data().id();
}
m4 = taxonomy::cast<taxonomy::geom_item>(converter_->mapping()->map(ifc_product))->matrix;
m4 = ifcopenshell::geometry::taxonomy::cast<ifcopenshell::geometry::taxonomy::geom_item>(converter_->mapping()->map(ifc_product))->matrix;
} catch (const std::exception& e) {
Logger::Error(e);
}
@@ -701,9 +698,7 @@ namespace IfcGeom {
Logger::Error("Unknown error returning product");
}
ElementSettings element_settings(settings_, unit_magnitude_, instance_type);
Element* ifc_object = new Element(element_settings, id, parent_id, product_name, instance_type, product_guid, "", m4, ifc_product);
Element* ifc_object = new Element(settings_, id, parent_id, product_name, instance_type, product_guid, "", m4, ifc_product);
return ifc_object;
}
@@ -729,7 +724,7 @@ namespace IfcGeom {
return product;
}
Iterator(const std::string& geometry_library, const IteratorSettings& settings, IfcParse::IfcFile* file, const std::vector<IfcGeom::filter_t>& filters, int num_threads)
Iterator(const std::string& geometry_library, const ifcopenshell::geometry::Settings& settings, IfcParse::IfcFile* file, const std::vector<IfcGeom::filter_t>& filters, int num_threads)
: settings_(settings)
, ifc_file(file)
, filters_(filters)
@@ -739,7 +734,7 @@ namespace IfcGeom {
{
}
Iterator(const IteratorSettings& settings, IfcParse::IfcFile* file, const std::vector<IfcGeom::filter_t>& filters, int num_threads)
Iterator(const ifcopenshell::geometry::Settings& settings, IfcParse::IfcFile* file, const std::vector<IfcGeom::filter_t>& filters, int num_threads)
: settings_(settings)
, ifc_file(file)
, filters_(filters)
@@ -749,7 +744,7 @@ namespace IfcGeom {
{
}
Iterator(const IteratorSettings& settings, IfcParse::IfcFile* file)
Iterator(const ifcopenshell::geometry::Settings& settings, IfcParse::IfcFile* file)
: settings_(settings)
, ifc_file(file)
, owns_ifc_file(false)
@@ -758,7 +753,7 @@ namespace IfcGeom {
{
}
Iterator(const std::string& geometry_library, const IteratorSettings& settings, IfcParse::IfcFile* file)
Iterator(const std::string& geometry_library, const ifcopenshell::geometry::Settings& settings, IfcParse::IfcFile* file)
: settings_(settings)
, ifc_file(file)
, owns_ifc_file(false)
@@ -767,7 +762,7 @@ namespace IfcGeom {
{
}
Iterator(const std::string& geometry_library, const IteratorSettings& settings, IfcParse::IfcFile* file, int num_threads)
Iterator(const std::string& geometry_library, const ifcopenshell::geometry::Settings& settings, IfcParse::IfcFile* file, int num_threads)
: settings_(settings)
, ifc_file(file)
, owns_ifc_file(false)
@@ -781,7 +776,7 @@ namespace IfcGeom {
delete ifc_file;
}
if (!settings_.get(IfcGeom::IteratorSettings::DISABLE_TRIANGULATION)) {
if (!settings_.get<ifcopenshell::geometry::settings::IteratorOutput>().get() == ifcopenshell::geometry::settings::NATIVE) {
for (auto& p : all_processed_native_elements_) {
delete p;
}
+4
View File
@@ -20,6 +20,8 @@
#ifndef IFCGEOMITERATORSETTINGS_H
#define IFCGEOMITERATORSETTINGS_H
/*
#include "ifc_geom_api.h"
#include "../ifcparse/IfcException.h"
@@ -205,4 +207,6 @@ namespace IfcGeom
};
}
*/
#endif
+1 -1
View File
@@ -33,7 +33,7 @@ void ifcopenshell::geometry::impl::MappingFactoryImplementation::bind(const std:
this->insert(std::make_pair(schema_name_lower, fn));
}
ifcopenshell::geometry::abstract_mapping* ifcopenshell::geometry::impl::MappingFactoryImplementation::construct(IfcParse::IfcFile* file, IfcGeom::IteratorSettings& s) {
ifcopenshell::geometry::abstract_mapping* ifcopenshell::geometry::impl::MappingFactoryImplementation::construct(IfcParse::IfcFile* file, Settings& s) {
const std::string schema_name_lower = boost::to_lower_copy(file->schema()->name());
std::map<std::string, ifcopenshell::geometry::impl::mapping_fn>::const_iterator it;
it = this->find(schema_name_lower);
+5 -7
View File
@@ -27,10 +27,9 @@ namespace geometry {
class abstract_mapping {
protected:
IfcGeom::IteratorSettings settings_;
ConversionSettings conv_settings_;
Settings settings_;
public:
abstract_mapping(IfcGeom::IteratorSettings& s) : settings_(s) {}
abstract_mapping(Settings& s) : settings_(s) {}
virtual ifcopenshell::geometry::taxonomy::ptr map(const IfcUtil::IfcBaseInterface*) = 0;
virtual void get_representations(std::vector<geometry_conversion_task>& tasks, std::vector<filter_t>& filters) = 0;
@@ -44,18 +43,17 @@ namespace geometry {
virtual double get_length_unit() const = 0;
virtual IfcUtil::IfcBaseEntity* representation_of(const IfcUtil::IfcBaseEntity* product) = 0;
const IfcGeom::IteratorSettings& settings() const { return settings_; }
const ConversionSettings& conversion_settings() const { return conv_settings_; }
const Settings& settings() const { return settings_; }
};
namespace impl {
typedef boost::function2<abstract_mapping*, IfcParse::IfcFile*, IfcGeom::IteratorSettings&> mapping_fn;
typedef boost::function2<abstract_mapping*, IfcParse::IfcFile*, Settings&> mapping_fn;
class MappingFactoryImplementation : public std::map<std::string, mapping_fn> {
public:
MappingFactoryImplementation();
void bind(const std::string& schema_name, mapping_fn);
abstract_mapping* construct(IfcParse::IfcFile*, IfcGeom::IteratorSettings&);
abstract_mapping* construct(IfcParse::IfcFile*, Settings&);
};
MappingFactoryImplementation& mapping_implementations();
@@ -18,7 +18,7 @@ using ifcopenshell::geometry::NumberEpeck;
#define NumberType NumberEpeck
#endif
void ifcopenshell::geometry::CgalShape::Triangulate(const IfcGeom::IteratorSettings& settings, const ifcopenshell::geometry::taxonomy::matrix4& place, IfcGeom::Representation::Triangulation* t, int surface_style_id) const {
void ifcopenshell::geometry::CgalShape::Triangulate(ifcopenshell::geometry::Settings settings, const ifcopenshell::geometry::taxonomy::matrix4& place, IfcGeom::Representation::Triangulation* t, int surface_style_id) const {
// Copy is made because triangulate_faces() obviously does not accept a const argument
// ... also becuase of transforming the vertex positions, right?
cgal_shape_t s = *this;
@@ -372,7 +372,7 @@ void ifcopenshell::geometry::CgalShape::map(OpaqueCoordinate<4>& from, OpaqueCoo
#ifndef IFOPSH_SIMPLE_KERNEL
void ifcopenshell::geometry::CgalShapeHalfSpaceDecomposition::Triangulate(const IfcGeom::IteratorSettings& settings, const ifcopenshell::geometry::taxonomy::matrix4& place, IfcGeom::Representation::Triangulation* t, int surface_style_id) const {
void ifcopenshell::geometry::CgalShapeHalfSpaceDecomposition::Triangulate(ifcopenshell::geometry::Settings settings, const ifcopenshell::geometry::taxonomy::matrix4& place, IfcGeom::Representation::Triangulation* t, int surface_style_id) const {
throw std::runtime_error("Not implemented");
}
@@ -205,7 +205,7 @@ namespace ifcopenshell { namespace geometry {
operator const cgal_shape_t& () const { to_poly(); return *shape_; }
const cgal_shape_t& poly() const { to_poly(); return *shape_; }
virtual void Triangulate(const IfcGeom::IteratorSettings& settings, const ifcopenshell::geometry::taxonomy::matrix4& place, IfcGeom::Representation::Triangulation* t, int surface_style_id) const;
virtual void Triangulate(ifcopenshell::geometry::Settings settings, const ifcopenshell::geometry::taxonomy::matrix4& place, IfcGeom::Representation::Triangulation* t, int surface_style_id) const;
virtual void Serialize(const ifcopenshell::geometry::taxonomy::matrix4& place, std::string&) const;
virtual IfcGeom::ConversionResultShape* clone() const {
@@ -268,7 +268,7 @@ namespace ifcopenshell { namespace geometry {
planes_.push_back(shape);
}
virtual void Triangulate(const IfcGeom::IteratorSettings& settings, const ifcopenshell::geometry::taxonomy::matrix4& place, IfcGeom::Representation::Triangulation* t, int surface_style_id) const;
virtual void Triangulate(ifcopenshell::geometry::Settings settings, const ifcopenshell::geometry::taxonomy::matrix4& place, IfcGeom::Representation::Triangulation* t, int surface_style_id) const;
virtual void Serialize(const ifcopenshell::geometry::taxonomy::matrix4& place, std::string&) const;
virtual int surface_genus() const;
+1 -1
View File
@@ -1109,7 +1109,7 @@ bool CgalKernel::process_extrusion(const cgal_face_t& bottom_face, taxonomy::dir
bool CgalKernel::convert(const taxonomy::extrusion::ptr extrusion, cgal_shape_t &shape) {
const double& height = extrusion->depth;
if (height < conv_settings_.getValue(ConversionSettings::GV_PRECISION)) {
if (height < settings_.get<settings::Precision>().get()) {
Logger::Message(Logger::LOG_ERROR, "Non-positive extrusion height encountered for:", extrusion->instance);
return false;
}
+2 -2
View File
@@ -86,13 +86,13 @@ namespace ifcopenshell {
bool thin_solid(const CGAL::Nef_polyhedron_3<Kernel_>& a, CGAL::Nef_polyhedron_3<Kernel_>& result);
CGAL::Nef_polyhedron_3<Kernel_> create_precision_cube_() const {
auto cc = utils::create_cube(conv_settings_.getValue(ConversionSettings::GV_PRECISION));
auto cc = utils::create_cube(settings_.get<settings::Precision>().get());
return CGAL::Nef_polyhedron_3<Kernel_>(cc);
}
#endif
public:
CgalKernel(const ConversionSettings& settings)
CgalKernel(const Settings& settings)
: AbstractKernel("cgal", settings)
, circle_segments_(32)
{}
@@ -269,7 +269,7 @@ namespace IfcGeom {
std::vector<T> select(const IfcGeom::BRepElement* elem, bool completely_within = false, double extend = -1.e-5) const {
auto shp = elem->geometry().as_compound();
auto compound = ((OpenCascadeShape*)shp)->shape();
auto compound = ((ifcopenshell::geometry::OpenCascadeShape*)shp)->shape();
const auto& m = elem->transformation().data()->ccomponents();
gp_Trsf tr;
tr.SetValues(
@@ -369,10 +369,10 @@ namespace IfcGeom {
tree() {};
tree(IfcParse::IfcFile& f) {
add_file(f, IfcGeom::IteratorSettings());
add_file(f, ifcopenshell::geometry::Settings{});
}
tree(IfcParse::IfcFile& f, const IfcGeom::IteratorSettings& settings) {
tree(IfcParse::IfcFile& f, ifcopenshell::geometry::Settings settings) {
add_file(f, settings);
}
@@ -380,11 +380,11 @@ namespace IfcGeom {
add_file(it);
}
void add_file(IfcParse::IfcFile& f, const IfcGeom::IteratorSettings& settings) {
IfcGeom::IteratorSettings settings_ = settings;
settings_.set(IfcGeom::IteratorSettings::DISABLE_TRIANGULATION, true);
settings_.set(IfcGeom::IteratorSettings::USE_WORLD_COORDS, true);
settings_.set(IfcGeom::IteratorSettings::SEW_SHELLS, true);
void add_file(IfcParse::IfcFile& f, ifcopenshell::geometry::Settings settings) {
ifcopenshell::geometry::Settings settings_ = settings;
settings_.get<ifcopenshell::geometry::settings::IteratorOutput>().value = ifcopenshell::geometry::settings::NATIVE;
settings_.get<ifcopenshell::geometry::settings::UseWorldCoords>().value = true;
settings_.get<ifcopenshell::geometry::settings::ReorientShells>().value = true;
IfcGeom::Iterator it(settings_, &f, {}, 1);
@@ -31,7 +31,7 @@ namespace {
}
}
void ifcopenshell::geometry::OpenCascadeShape::Triangulate(const IfcGeom::IteratorSettings& settings, const ifcopenshell::geometry::taxonomy::matrix4& place, IfcGeom::Representation::Triangulation* t, int surface_style_id) const {
void ifcopenshell::geometry::OpenCascadeShape::Triangulate(ifcopenshell::geometry::Settings settings, const ifcopenshell::geometry::taxonomy::matrix4& place, IfcGeom::Representation::Triangulation* t, int surface_style_id) const {
// @todo remove duplication with OpenCascadeKernel::convert(const taxonomy::matrix4::ptr matrix, gp_GTrsf& trsf);
// above can be static?
@@ -50,7 +50,7 @@ void ifcopenshell::geometry::OpenCascadeShape::Triangulate(const IfcGeom::Iterat
// Triangulate the shape
try {
BRepMesh_IncrementalMesh(shape_, settings.deflection_tolerance(), false, settings.angular_tolerance());
BRepMesh_IncrementalMesh(shape_, settings.get<settings::MesherLinearDeflection>().get(), false, settings.get<settings::MesherAngularDeflection>().get());
} catch (...) {
Logger::Message(Logger::LOG_ERROR, "Failed to triangulate shape");
return;
@@ -77,8 +77,8 @@ void ifcopenshell::geometry::OpenCascadeShape::Triangulate(const IfcGeom::Iterat
std::map<int, int> dict;
// Vertex normals are only calculated if vertices are not welded and calculation is not disable explicitly.
const bool calculate_normals = !settings.get(IfcGeom::IteratorSettings::WELD_VERTICES) &&
!settings.get(IfcGeom::IteratorSettings::NO_NORMALS);
const bool calculate_normals = !settings.get<settings::WeldVertices>().get() &&
!settings.get<settings::DontEmitNormals>().get();
for (int i = 1; i <= tri->NbNodes(); ++i) {
coords.push_back(tri->Node(i).Transformed(loc).XYZ());
@@ -155,7 +155,7 @@ void ifcopenshell::geometry::OpenCascadeShape::Triangulate(const IfcGeom::Iterat
}
}
if (!t->normals().empty() && settings.get(IfcGeom::IteratorSettings::GENERATE_UVS)) {
if (!t->normals().empty() && settings.get<settings::GenerateUvs>().get()) {
t->uvs() = IfcGeom::Representation::Triangulation::box_project_uvs(t->verts(), t->normals());
}
@@ -166,7 +166,7 @@ void ifcopenshell::geometry::OpenCascadeShape::Triangulate(const IfcGeom::Iterat
// belong to any face.
for (TopExp_Explorer texp(shape_, TopAbs_EDGE); texp.More(); texp.Next()) {
BRepAdaptor_Curve crv(TopoDS::Edge(texp.Current()));
GCPnts_QuasiUniformDeflection tessellater(crv, settings.deflection_tolerance());
GCPnts_QuasiUniformDeflection tessellater(crv, settings.get<settings::MesherLinearDeflection>().get());
int n = tessellater.NbPoints();
int previous = -1;
@@ -182,7 +182,7 @@ void ifcopenshell::geometry::OpenCascadeShape::Triangulate(const IfcGeom::Iterat
segments.push_back(std::make_pair(previous, current));
}
if (settings.get(IfcGeom::IteratorSettings::EDGE_ARROWS)) {
if (settings.get<settings::EdgeArrows>().get()) {
// In case you want direction arrows on your edges
double u = tessellater.Parameter(i);
gp_XYZ p2, p3;
@@ -50,7 +50,7 @@ namespace ifcopenshell {
const TopoDS_Shape& shape() const { return shape_; }
operator const TopoDS_Shape& () { return shape_; }
virtual void Triangulate(const IfcGeom::IteratorSettings& settings, const ifcopenshell::geometry::taxonomy::matrix4& place, IfcGeom::Representation::Triangulation* t, int surface_style_id) const;
virtual void Triangulate(ifcopenshell::geometry::Settings settings, const ifcopenshell::geometry::taxonomy::matrix4& place, IfcGeom::Representation::Triangulation* t, int surface_style_id) const;
virtual void Serialize(const ifcopenshell::geometry::taxonomy::matrix4& place, std::string&) const;
virtual IfcGeom::ConversionResultShape* clone() const {
@@ -201,13 +201,15 @@ namespace {
};
}
using namespace ifcopenshell::geometry;
bool IfcGeom::OpenCascadeKernel::convert_openings(const IfcUtil::IfcBaseEntity* entity, const std::vector<std::pair<taxonomy::ptr, ifcopenshell::geometry::taxonomy::matrix4>>& openings,
const IfcGeom::ConversionResults& entity_shapes, const ifcopenshell::geometry::taxonomy::matrix4& entity_trsf, IfcGeom::ConversionResults& cut_shapes) {
util::boolean_settings bst;
bst.attempt_2d = conv_settings_.getValue(ConversionSettings::GV_BOOLEAN_ATTEMPT_2D) > 0.;
bst.debug = conv_settings_.getValue(ConversionSettings::GV_DEBUG_BOOLEAN) > 0.;
bst.precision = conv_settings_.getValue(ConversionSettings::GV_PRECISION);
bst.attempt_2d = settings_.get<settings::BooleanAttempt2d>().get();
bst.debug = settings_.get<settings::DebugBooleanOperations>().get();
bst.precision = settings_.get<settings::Precision>().get();
std::vector< std::pair<double, TopoDS_Shape> > opening_vector;
@@ -248,7 +250,7 @@ bool IfcGeom::OpenCascadeKernel::convert_openings(const IfcUtil::IfcBaseEntity*
for (unsigned int i = 0; i < opening_shapes.size(); ++i) {
TopoDS_Shape opening_shape_solid;
auto opening_shape_i = std::static_pointer_cast<OpenCascadeShape>(opening_shapes[i].Shape())->shape();
const TopoDS_Shape& opening_shape_unlocated = util::ensure_fit_for_subtraction(opening_shape_i, opening_shape_solid, conv_settings_.getValue(ConversionSettings::GV_PRECISION));
const TopoDS_Shape& opening_shape_unlocated = util::ensure_fit_for_subtraction(opening_shape_i, opening_shape_solid, settings_.get<settings::Precision>().get());
auto gtrsf = opening_shapes[i].Placement();
// @todo check
@@ -306,7 +308,7 @@ bool IfcGeom::OpenCascadeKernel::convert_openings(const IfcUtil::IfcBaseEntity*
if (as_shell) {
entity_shape_unlocated = entity_part;
} else {
entity_shape_unlocated = util::ensure_fit_for_subtraction(entity_part, entity_shape_solid, conv_settings_.getValue(ConversionSettings::GV_PRECISION));
entity_shape_unlocated = util::ensure_fit_for_subtraction(entity_part, entity_shape_solid, settings_.get<settings::Precision>().get());
}
const auto& m = it3->Placement()->ccomponents();
// @todo
@@ -56,12 +56,9 @@
#include "../../../ifcgeom/taxonomy.h"
#include "../../../ifcgeom/ConversionSettings.h"
// @todo remove once merged to same ns.
using namespace ifcopenshell::geometry;
namespace IfcGeom {
class IFC_GEOM_API OpenCascadeKernel : public kernels::AbstractKernel {
class IFC_GEOM_API OpenCascadeKernel : public ifcopenshell::geometry::kernels::AbstractKernel {
private:
/*
@@ -81,7 +78,7 @@ private:
double eps_;
bool non_manifold_;
void loop_(const taxonomy::loop::ptr ps, const std::function<void(int, int, bool)>& callback);
void loop_(const ifcopenshell::geometry::taxonomy::loop::ptr ps, const std::function<void(int, int, bool)>& callback);
/*
bool construct(const IfcSchema::IfcCartesianPoint* cp, gp_Pnt* l);
@@ -99,7 +96,7 @@ private:
std::vector<const void*> get_idxs(const std::vector<int>& it);
*/
public:
faceset_helper(OpenCascadeKernel* kernel, const taxonomy::shell::ptr l);
faceset_helper(OpenCascadeKernel* kernel, const ifcopenshell::geometry::taxonomy::shell::ptr l);
~faceset_helper();
bool non_manifold() const { return non_manifold_; }
@@ -108,8 +105,8 @@ private:
bool edge(int A, int B, TopoDS_Edge& e);
bool wire(const taxonomy::loop::ptr loop, TopoDS_Wire& wire);
bool wires(const taxonomy::loop::ptr loop, TopTools_ListOfShape& wires);
bool wire(const ifcopenshell::geometry::taxonomy::loop::ptr loop, TopoDS_Wire& wire);
bool wires(const ifcopenshell::geometry::taxonomy::loop::ptr loop, TopTools_ListOfShape& wires);
};
faceset_helper* faceset_helper_;
@@ -124,28 +121,28 @@ private:
double precision_;
public:
OpenCascadeKernel(const ConversionSettings& settings)
OpenCascadeKernel(const ifcopenshell::geometry::Settings& settings)
: AbstractKernel("opencascade", settings)
, faceset_helper_(nullptr)
, precision_(settings.getValue(ConversionSettings::GV_PRECISION))
, precision_(settings.get<ifcopenshell::geometry::settings::Precision>().get())
{}
bool convert(const taxonomy::extrusion::ptr, TopoDS_Shape&);
bool convert(const taxonomy::face::ptr, TopoDS_Shape&);
bool convert(const taxonomy::loop::ptr, TopoDS_Wire&);
bool convert(const taxonomy::matrix4::ptr, gp_GTrsf&);
bool convert(const taxonomy::shell::ptr, TopoDS_Shape&);
bool convert(const taxonomy::solid::ptr, TopoDS_Shape&);
bool convert(const taxonomy::bspline_surface::ptr bs, Handle(Geom_Surface) surf);
bool convert(const ifcopenshell::geometry::taxonomy::extrusion::ptr, TopoDS_Shape&);
bool convert(const ifcopenshell::geometry::taxonomy::face::ptr, TopoDS_Shape&);
bool convert(const ifcopenshell::geometry::taxonomy::loop::ptr, TopoDS_Wire&);
bool convert(const ifcopenshell::geometry::taxonomy::matrix4::ptr, gp_GTrsf&);
bool convert(const ifcopenshell::geometry::taxonomy::shell::ptr, TopoDS_Shape&);
bool convert(const ifcopenshell::geometry::taxonomy::solid::ptr, TopoDS_Shape&);
bool convert(const ifcopenshell::geometry::taxonomy::bspline_surface::ptr bs, Handle(Geom_Surface) surf);
virtual bool convert_impl(const taxonomy::loop::ptr, IfcGeom::ConversionResults&);
virtual bool convert_impl(const taxonomy::face::ptr, IfcGeom::ConversionResults&);
virtual bool convert_impl(const taxonomy::solid::ptr, IfcGeom::ConversionResults&);
virtual bool convert_impl(const taxonomy::shell::ptr, IfcGeom::ConversionResults&);
virtual bool convert_impl(const taxonomy::extrusion::ptr, IfcGeom::ConversionResults&);
virtual bool convert_impl(const taxonomy::boolean_result::ptr, IfcGeom::ConversionResults&);
virtual bool convert_impl(const ifcopenshell::geometry::taxonomy::loop::ptr, IfcGeom::ConversionResults&);
virtual bool convert_impl(const ifcopenshell::geometry::taxonomy::face::ptr, IfcGeom::ConversionResults&);
virtual bool convert_impl(const ifcopenshell::geometry::taxonomy::solid::ptr, IfcGeom::ConversionResults&);
virtual bool convert_impl(const ifcopenshell::geometry::taxonomy::shell::ptr, IfcGeom::ConversionResults&);
virtual bool convert_impl(const ifcopenshell::geometry::taxonomy::extrusion::ptr, IfcGeom::ConversionResults&);
virtual bool convert_impl(const ifcopenshell::geometry::taxonomy::boolean_result::ptr, IfcGeom::ConversionResults&);
virtual bool convert_openings(const IfcUtil::IfcBaseEntity* entity, const std::vector<std::pair<taxonomy::ptr, ifcopenshell::geometry::taxonomy::matrix4>>& openings,
virtual bool convert_openings(const IfcUtil::IfcBaseEntity* entity, const std::vector<std::pair<ifcopenshell::geometry::taxonomy::ptr, ifcopenshell::geometry::taxonomy::matrix4>>& openings,
const IfcGeom::ConversionResults& entity_shapes, const ifcopenshell::geometry::taxonomy::matrix4& entity_trsf, IfcGeom::ConversionResults& cut_shapes);
template <typename T, typename U>
@@ -46,7 +46,7 @@ namespace {
bool OpenCascadeKernel::convert_impl(const taxonomy::boolean_result::ptr br, ConversionResults& results) {
bool valid_result = false;
bool first = true;
const double tol = conv_settings_.getValue(ConversionSettings::GV_PRECISION);
const double tol = settings_.get<settings::Precision>().get();
TopoDS_Shape a;
TopTools_ListOfShape b;
@@ -58,14 +58,14 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::boolean_result::ptr br, Con
AbstractKernel::convert(c, cr);
if (first && br->operation == taxonomy::boolean_result::SUBTRACTION) {
// @todo A will be null on union/intersection, intended?
IfcGeom::util::flatten_shape_list(cr, a, false, conv_settings_.getValue(ifcopenshell::geometry::ConversionSettings::GV_PRECISION));
IfcGeom::util::flatten_shape_list(cr, a, false, settings_.get<settings::Precision>().get());
first_item_style = c->surface_style;
if (!first_item_style && c->kind() == taxonomy::COLLECTION) {
// @todo recursively right?
first_item_style = taxonomy::cast<taxonomy::geom_item>(taxonomy::cast<taxonomy::collection>(c)->children[0])->surface_style;
}
if (conv_settings_.getValue(ConversionSettings::GV_DISABLE_BOOLEAN_RESULT) > 0.0) {
if (settings_.get<settings::DisableBooleanResult>().get()) {
results.emplace_back(IfcGeom::ConversionResult(
(int)br->instance->data().id(),
br->matrix,
@@ -109,9 +109,9 @@ bool OpenCascadeKernel::convert_impl(const taxonomy::boolean_result::ptr br, Con
}
util::boolean_settings bst;
bst.attempt_2d = conv_settings_.getValue(ConversionSettings::GV_BOOLEAN_ATTEMPT_2D) > 0.;
bst.debug = conv_settings_.getValue(ConversionSettings::GV_DEBUG_BOOLEAN) > 0.;
bst.precision = conv_settings_.getValue(ConversionSettings::GV_PRECISION);
bst.attempt_2d = settings_.get<settings::BooleanAttempt2d>().get();
bst.debug = settings_.get<settings::DebugBooleanOperations>().get();
bst.precision = settings_.get<settings::Precision>().get();
TopoDS_Shape r;
@@ -9,7 +9,7 @@ using namespace IfcGeom;
bool OpenCascadeKernel::convert(const taxonomy::extrusion::ptr extrusion, TopoDS_Shape& shape) {
const double& height = extrusion->depth;
if (height < conv_settings_.getValue(ConversionSettings::GV_PRECISION)) {
if (height < settings_.get<settings::Precision>().get()) {
Logger::Error("Non-positive extrusion height encountered for:", extrusion->instance);
return false;
}
@@ -27,21 +27,21 @@ namespace {
IfcGeom::OpenCascadeKernel::faceset_helper::faceset_helper(
OpenCascadeKernel* kernel,
const taxonomy::shell::ptr shell
const ifcopenshell::geometry::taxonomy::shell::ptr shell
)
: kernel_(kernel)
, non_manifold_(false)
{
// @todo use pointers?
std::vector<taxonomy::point3::ptr> points;
std::vector<taxonomy::loop::ptr> loops;
std::vector<ifcopenshell::geometry::taxonomy::point3::ptr> points;
std::vector<ifcopenshell::geometry::taxonomy::loop::ptr> loops;
for (auto& f : shell->children) {
for (auto& l : f->children) {
loops.push_back(l);
for (auto& e : l->children) {
// @todo make sure only cartesian points are provided here
points.push_back(boost::get<taxonomy::point3::ptr>(e->start));
points.push_back(boost::get<ifcopenshell::geometry::taxonomy::point3::ptr>(e->start));
}
}
}
@@ -79,12 +79,12 @@ IfcGeom::OpenCascadeKernel::faceset_helper::faceset_helper(
double bdiff = std::numeric_limits<double>::infinity();
for (size_t i = 0; i < 3; ++i) {
const double d = bmax[i] - bmin[i];
if (d > kernel->settings().getValue(ConversionSettings::GV_PRECISION) * 10. && d < bdiff) {
if (d > kernel->settings().get<ifcopenshell::geometry::settings::Precision>().get() * 10. && d < bdiff) {
bdiff = d;
}
}
eps_ = kernel->settings().getValue(ConversionSettings::GV_PRECISION) * 10. * (std::min)(1.0, bdiff);
eps_ = kernel->settings().get<ifcopenshell::geometry::settings::Precision>().get() * 10. * (std::min)(1.0, bdiff);
size_t loops_removed, non_manifold, duplicate_faces;
@@ -192,15 +192,15 @@ IfcGeom::OpenCascadeKernel::faceset_helper::faceset_helper(
}
}
void IfcGeom::OpenCascadeKernel::faceset_helper::loop_(const taxonomy::loop::ptr ps, const std::function<void(int, int, bool)>& callback) {
void IfcGeom::OpenCascadeKernel::faceset_helper::loop_(const ifcopenshell::geometry::taxonomy::loop::ptr ps, const std::function<void(int, int, bool)>& callback) {
if (ps->children.size() < 3) {
return;
}
auto a = boost::get<taxonomy::point3::ptr>(ps->children.back()->start);
auto a = boost::get<ifcopenshell::geometry::taxonomy::point3::ptr>(ps->children.back()->start);
auto A = a->identity();
for (auto& b : ps->children) {
auto B = boost::get<taxonomy::point3::ptr>(b->start)->identity();
auto B = boost::get<ifcopenshell::geometry::taxonomy::point3::ptr>(b->start)->identity();
auto C = vertex_mapping_[A], D = vertex_mapping_[B];
bool fwd = C < D;
if (!fwd) {
@@ -222,7 +222,7 @@ bool IfcGeom::OpenCascadeKernel::faceset_helper::edge(int A, int B, TopoDS_Edge&
return true;
}
bool IfcGeom::OpenCascadeKernel::faceset_helper::wire(const taxonomy::loop::ptr loop, TopoDS_Wire& w) {
bool IfcGeom::OpenCascadeKernel::faceset_helper::wire(const ifcopenshell::geometry::taxonomy::loop::ptr loop, TopoDS_Wire& w) {
TopTools_ListOfShape ws;
if (!wires(loop, ws)) {
return false;
@@ -231,7 +231,7 @@ bool IfcGeom::OpenCascadeKernel::faceset_helper::wire(const taxonomy::loop::ptr
return true;
}
bool IfcGeom::OpenCascadeKernel::faceset_helper::wires(const taxonomy::loop::ptr loop, TopTools_ListOfShape& wires) {
bool IfcGeom::OpenCascadeKernel::faceset_helper::wires(const ifcopenshell::geometry::taxonomy::loop::ptr loop, TopTools_ListOfShape& wires) {
if (duplicates_.find(loop->identity()) != duplicates_.end()) {
return false;
}
@@ -253,7 +253,11 @@ bool IfcGeom::OpenCascadeKernel::faceset_helper::wires(const taxonomy::loop::ptr
wire.Closed(true);
TopTools_ListOfShape results;
if (kernel_->settings().getValue(ConversionSettings::GV_NO_WIRE_INTERSECTION_CHECK) < 0. && util::wire_intersections(wire, results, {kernel_->settings().getValue(ConversionSettings::GV_NO_WIRE_INTERSECTION_CHECK) < 0., kernel_->settings().getValue(ConversionSettings::GV_NO_WIRE_INTERSECTION_TOLERANCE) < 0., 0., kernel_->settings().getValue(ConversionSettings::GV_PRECISION)})) {
if (!kernel_->settings().get<ifcopenshell::geometry::settings::NoWireIntersectionCheck>().get() && util::wire_intersections(wire, results, {
!kernel_->settings().get<ifcopenshell::geometry::settings::NoWireIntersectionCheck>().get(),
!kernel_->settings().get<ifcopenshell::geometry::settings::NoWireIntersectionTolerance>().get(), 0.,
kernel_->settings().get<ifcopenshell::geometry::settings::Precision>().get()}))
{
Logger::Warning("Self-intersections with " + boost::lexical_cast<std::string>(results.Extent()) + " cycles detected");
non_manifold_ = true;
wires = results;
+1 -1
View File
@@ -72,7 +72,7 @@ bool OpenCascadeKernel::convert(const taxonomy::shell::ptr l, TopoDS_Shape& shap
// @todo
/* face_list.Extent() > getValue(GV_MAX_FACES_TO_ORIENT) || */
if (!create_solid_from_faces(face_list, shape, conv_settings_.getValue(ifcopenshell::geometry::ConversionSettings::GV_PRECISION))) {
if (!create_solid_from_faces(face_list, shape, settings_.get<settings::Precision>().get())) {
TopoDS_Compound compound;
BRep_Builder builder;
builder.MakeCompound(compound);
+1 -1
View File
@@ -40,7 +40,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCShapeProfileDef* inst) {
f2 = f1 + d1;
}
const double tol = conv_settings_.getValue(ConversionSettings::GV_PRECISION);
const double tol = settings_.get<settings::Precision>().get();
if ( x < tol || y < tol || d1 < tol || d2 < tol) {
Logger::Message(Logger::LOG_NOTICE," Skipping zero sized profile:", inst);
+1 -1
View File
@@ -25,7 +25,7 @@ using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCircle* inst) {
const double r = inst->Radius() * length_unit_;
if (r < conv_settings_.getValue(ConversionSettings::GV_PRECISION)) {
if (r < settings_.get<settings::Precision>().get()) {
Logger::Message(Logger::LOG_ERROR, "Radius not greater than zero for:", inst);
return nullptr;
}
+1 -1
View File
@@ -37,7 +37,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcCompositeCurve* inst) {
Logger::Notice("Infinite IfcLine used as ParentCurve of segment, treating as a segment", segment);
double u0 = 0.0;
double u1 = segment->as<IfcSchema::IfcCompositeCurveSegment>()->ParentCurve()->as<IfcSchema::IfcLine>()->Dir()->Magnitude() * length_unit_;
if (u1 < conv_settings_.getValue(ConversionSettings::GV_PRECISION)) {
if (u1 < settings_.get<settings::Precision>().get()) {
Logger::Warning("Segment length below tolerance", segment);
}
+1 -1
View File
@@ -632,7 +632,7 @@ class curve_segment_evaluator {
auto dy = p2y - p1y;
auto l = sqrt(dx * dx + dy * dy);
if (l < mapping_->conversion_settings().getValue(ConversionSettings::GV_PRECISION))
if (l < mapping_->settings().get<ifcopenshell::geometry::settings::Precision>().get())
{
std::ostringstream os;
os << "Coincident IfcPolyline.Points are not expected. Skipping point " << std::distance(iter, begin) << std::endl;
+1 -1
View File
@@ -24,7 +24,7 @@ using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcEllipse* inst) {
double x = inst->SemiAxis1() * length_unit_;
double y = inst->SemiAxis2() * length_unit_;
const double tol = conv_settings_.getValue(ConversionSettings::GV_PRECISION);
const double tol = settings_.get<settings::Precision>().get();
if (x < tol || y < tol) {
Logger::Message(Logger::LOG_ERROR, "Radius not greater than zero for:", inst);
return nullptr;
+1 -1
View File
@@ -24,7 +24,7 @@ using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcEllipseProfileDef* inst) {
double rx = inst->SemiAxis1() * length_unit_;
double ry = inst->SemiAxis2() * length_unit_;
const double tol = conv_settings_.getValue(ConversionSettings::GV_PRECISION);
const double tol = settings_.get<settings::Precision>().get();
if (rx < tol || ry < tol) {
Logger::Message(Logger::LOG_ERROR, "Radius not greater than zero for:", inst);
return nullptr;
+1 -1
View File
@@ -26,7 +26,7 @@ using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcExtrudedAreaSolid* inst) {
const double height = inst->Depth() * length_unit_;
if (height < conv_settings_.getValue(ConversionSettings::GV_PRECISION)) {
if (height < settings_.get<settings::Precision>().get()) {
Logger::Message(Logger::LOG_ERROR, "Non-positive extrusion height encountered for:", inst);
#ifndef PERMISSIVE_EXTRUSION
return nullptr;
@@ -26,7 +26,7 @@ using namespace ifcopenshell::geometry;
#define mapping POSTFIX_SCHEMA(mapping)
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcExtrudedAreaSolidTapered* inst) {
const double height = inst->Depth() * length_unit_;
if (height < conv_settings_.getValue(ConversionSettings::GV_PRECISION)) {
if (height < settings_.get<settings::Precision>().get()) {
Logger::Message(Logger::LOG_ERROR, "Non-positive extrusion height encountered for:", inst);
return nullptr;
}
+1 -1
View File
@@ -78,7 +78,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcIShapeProfileDef* inst) {
fe2 = fe1;
}
const double tol = conv_settings_.getValue(ConversionSettings::GV_PRECISION);
const double tol = settings_.get<settings::Precision>().get();
if (x1 < tol || x2 < tol || y < tol || d1 < tol || ft1 < tol || ft2 < tol) {
Logger::Message(Logger::LOG_NOTICE, "Skipping zero sized profile:", inst);
+1 -1
View File
@@ -42,7 +42,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcLShapeProfileDef* inst) {
f2 = *inst->EdgeRadius() * length_unit_;
}
const double tol = conv_settings_.getValue(ConversionSettings::GV_PRECISION);
const double tol = settings_.get<settings::Precision>().get();
if ( x < tol || y < tol || d < tol) {
Logger::Message(Logger::LOG_NOTICE, "Skipping zero sized profile:", inst);
+1 -1
View File
@@ -41,7 +41,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPolyLoop* inst) {
}
// @todo Remove points that are too close to one another
const double eps = conv_settings_.getValue(ConversionSettings::GV_PRECISION);
const double eps = settings_.get<settings::Precision>().get();
// util::remove_duplicate_points_from_loop(polygon, true, eps);
int count = polygon.size();
+1 -1
View File
@@ -33,7 +33,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcPolyline* inst) {
return taxonomy::cast<taxonomy::point3>(map(p));
});
const bool closed_by_proximity = polygon.size() >= 3 && (*polygon.front()->components_ - *polygon.back()->components_).norm() < conv_settings_.getValue(ConversionSettings::GV_PRECISION);
const bool closed_by_proximity = polygon.size() >= 3 && (*polygon.front()->components_ - *polygon.back()->components_).norm() < settings_.get<settings::Precision>().get();
if (closed_by_proximity) {
polygon.resize(polygon.size() - 1);
polygon.push_back(polygon.front());
@@ -34,7 +34,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRectangleHollowProfileDef* i
const double r1 = fr1 ? (*inst->OuterFilletRadius()) * length_unit_ : 0.;
const double r2 = fr2 ? (*inst->InnerFilletRadius()) * length_unit_ : 0.;
const double tol = conv_settings_.getValue(ConversionSettings::GV_PRECISION);
const double tol = settings_.get<settings::Precision>().get();
if (x < tol || y < tol) {
Logger::Message(Logger::LOG_NOTICE, "Skipping zero sized profile:", inst);
@@ -27,7 +27,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRectangleProfileDef* inst) {
const double x = inst->XDim() / 2.0f * length_unit_;
const double y = inst->YDim() / 2.0f * length_unit_;
const double tol = conv_settings_.getValue(ConversionSettings::GV_PRECISION);
const double tol = settings_.get<settings::Precision>().get();
if (x < tol || y < tol) {
Logger::Message(Logger::LOG_NOTICE, "Skipping zero sized profile:", inst);
+2 -1
View File
@@ -22,7 +22,8 @@
using namespace ifcopenshell::geometry;
taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRepresentation* inst) {
const bool use_body = !this->settings_.get(IfcGeom::IteratorSettings::INCLUDE_CURVES);
// @todo
const bool use_body = !this->settings_.get<settings::IncludeCurves>().get();
auto items = map_to_collection(this, inst->Items());
if (items == nullptr) {
@@ -28,7 +28,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcRoundedRectangleProfileDef*
const double y = inst->YDim() / 2.0f * length_unit_;
const double r = inst->RoundingRadius() * length_unit_;
const double tol = conv_settings_.getValue(ConversionSettings::GV_PRECISION);
const double tol = settings_.get<settings::Precision>().get();
if (x < tol || y < tol) {
Logger::Message(Logger::LOG_NOTICE, "Skipping zero sized profile:", inst);
+1 -1
View File
@@ -62,7 +62,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcSweptDiskSolid* inst) {
ep = inst->EndParam();
#endif
const double tol = conv_settings_.getValue(ConversionSettings::GV_PRECISION);
const double tol = settings_.get<settings::Precision>().get();
#ifdef SCHEMA_HAS_IfcSweptDiskSolidPolygonal
if (inst->as<IfcSchema::IfcSweptDiskSolidPolygonal>()) {
+1 -1
View File
@@ -37,7 +37,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcTShapeProfileDef* inst) {
const double flangeSlope = hasFlangeSlope ? (*inst->FlangeSlope() * angle_unit_) : 0.;
const double webSlope = hasWebSlope ? (*inst->WebSlope() * angle_unit_) : 0.;
const double tol = conv_settings_.getValue(ConversionSettings::GV_PRECISION);
const double tol = settings_.get<settings::Precision>().get();
if (x < tol || y < tol || d1 < tol || d2 < tol) {
Logger::Message(Logger::LOG_NOTICE, "Skipping zero sized profile:", inst);
@@ -33,7 +33,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcTrapeziumProfileDef* inst) {
// The trapezium x center should not be midway of BottomXDim but rather at the center of the overall bounding box.
const double x_offset = ((std::min(dx, 0.) + std::max(w + dx, x1 * 2.)) / 2.) - x1;
const double tol = conv_settings_.getValue(ConversionSettings::GV_PRECISION);
const double tol = settings_.get<settings::Precision>().get();
if (x1 < tol || w < tol || y < tol) {
Logger::Message(Logger::LOG_NOTICE, "Skipping zero sized profile:", inst);
+2 -2
View File
@@ -70,7 +70,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcTrimmedCurve* inst) {
}
}
const double tol = conv_settings_.getValue(ConversionSettings::GV_PRECISION);
const double tol = settings_.get<settings::Precision>().get();
trim_cartesian &= has_pnts[0] && has_pnts[1];
bool trim_cartesian_failed = !trim_cartesian;
@@ -126,7 +126,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcTrimmedCurve* inst) {
}
// @todo is 100. not too much? Check with the original issue.
const double precision_markup = conv_settings_.getValue(ConversionSettings::GV_PRECISION_FACTOR) == 1. ? 1. : 100.;
const double precision_markup = settings_.get<settings::PrecisionFactor>().get() == 1. ? 1. : 100.;
if (isConic && std::fabs(fmod(flts[1] - flts[0], pi * 2.)) < precision_markup * tol / (2 * pi * radius)) {
flts[0] = 0.;
+1 -1
View File
@@ -51,7 +51,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcUShapeProfileDef* inst) {
dy2 = x * tan(slope);
}
const double tol = conv_settings_.getValue(ConversionSettings::GV_PRECISION);
const double tol = settings_.get<settings::Precision>().get();
if (x < tol || y < tol || d1 < tol || d2 < tol) {
Logger::Message(Logger::LOG_NOTICE, "Skipping zero sized profile:", inst);
+1 -1
View File
@@ -42,7 +42,7 @@ taxonomy::ptr mapping::map_impl(const IfcSchema::IfcZShapeProfileDef* inst) {
f2 = *inst->EdgeRadius() * length_unit_;
}
const double tol = conv_settings_.getValue(ConversionSettings::GV_PRECISION);
const double tol = settings_.get<settings::Precision>().get();
if (x < tol || y < tol || dx < tol || dy < tol) {
Logger::Message(Logger::LOG_NOTICE, "Skipping zero sized profile:", inst);
+20 -75
View File
@@ -32,7 +32,7 @@ using namespace IfcGeom;
namespace {
struct POSTFIX_SCHEMA(factory_t) {
abstract_mapping* operator()(IfcParse::IfcFile* file, IteratorSettings& settings) const {
abstract_mapping* operator()(IfcParse::IfcFile* file, Settings& settings) const {
ifcopenshell::geometry::POSTFIX_SCHEMA(mapping)* m = new ifcopenshell::geometry::POSTFIX_SCHEMA(mapping)(file, settings);
return m;
}
@@ -114,7 +114,7 @@ namespace {
bool mapping::reuse_ok_(const IfcSchema::IfcProduct::list::ptr& products) {
// With world coords enabled, object transformations are directly applied to
// the BRep. There is no way to re-use the geometry for multiple products.
if (settings_.get(IfcGeom::IteratorSettings::USE_WORLD_COORDS)) {
if (settings_.get<settings::UseWorldCoords>().get()) {
return false;
}
@@ -127,11 +127,11 @@ bool mapping::reuse_ok_(const IfcSchema::IfcProduct::list::ptr& products) {
for (IfcSchema::IfcProduct::list::it it = products->begin(); it != products->end(); ++it) {
IfcSchema::IfcProduct* product = *it;
if (!settings_.get(IfcGeom::IteratorSettings::DISABLE_OPENING_SUBTRACTIONS) && find_openings(product)->size()) {
if (!settings_.get<settings::DisableOpeningSubtractions>().get() && find_openings(product)->size()) {
return false;
}
if (settings_.get(IfcGeom::IteratorSettings::APPLY_LAYERSETS)) {
if (settings_.get<settings::ApplyLayerSets>().get()) {
IfcSchema::IfcRelAssociates::list::ptr associations = product->HasAssociations();
for (IfcSchema::IfcRelAssociates::list::it jt = associations->begin(); jt != associations->end(); ++jt) {
IfcSchema::IfcRelAssociatesMaterial* assoc = (*jt)->as<IfcSchema::IfcRelAssociatesMaterial>();
@@ -188,7 +188,7 @@ aggregate_of_instance::ptr mapping::find_openings(const IfcUtil::IfcBaseEntity*
void mapping::get_representations(std::vector<geometry_conversion_task>& tasks, std::vector<filter_t>& filters) {
IfcSchema::IfcRepresentation::list::ptr representations(new IfcSchema::IfcRepresentation::list);
if (settings_.context_ids().empty()) {
if (!settings_.get<settings::ContextIds>().has()) {
addRepresentationsFromDefaultContexts(representations);
} else {
addRepresentationsFromContextIds(representations);
@@ -664,8 +664,8 @@ void mapping::initialize_units_() {
}
void mapping::initialize_settings() {
conv_settings_.setValue(ConversionSettings::GV_LENGTH_UNIT, length_unit_);
conv_settings_.setValue(ConversionSettings::GV_PLANEANGLE_UNIT, angle_unit_);
settings_.get<settings::LengthUnit>().value = length_unit_;
settings_.get<settings::PlaneUnit>().value = angle_unit_;
// Set precision from file
double lowest_precision_encountered = std::numeric_limits<double>::infinity();
@@ -679,12 +679,13 @@ void mapping::initialize_settings() {
IfcSchema::IfcGeometricRepresentationContext* context = *it;
// See if there is a context_id filter and whether the context is selected
if (!settings_.context_ids().empty()) {
if (settings_.context_ids().find(context->data().id()) == settings_.context_ids().end()) {
if (settings_.get<settings::ContextIds>().has()) {
auto cids = settings_.get<settings::ContextIds>().get();
if (cids.find(context->data().id()) == cids.end()) {
bool selected_sub_context = false;
auto subs = context->HasSubContexts();
for (auto& sub : *subs) {
if (settings_.context_ids().find(context->data().id()) != settings_.context_ids().end()) {
if (cids.find(context->data().id()) != cids.end()) {
selected_sub_context = true;
break;
}
@@ -695,9 +696,10 @@ void mapping::initialize_settings() {
}
}
if (context->Precision() && (*context->Precision() * length_unit_ * 10.) < lowest_precision_encountered) {
auto fp = settings_.get<settings::PrecisionFactor>().get();
if (context->Precision() && (*context->Precision() * length_unit_ * fp) < lowest_precision_encountered) {
// Some arbitrary factor that has proven to work better for the models in the set of test files.
lowest_precision_encountered = *context->Precision() * length_unit_ * 10.;
lowest_precision_encountered = *context->Precision() * length_unit_ * fp;
any_precision_encountered = true;
}
}
@@ -713,7 +715,7 @@ void mapping::initialize_settings() {
}
}
conv_settings_.setValue(ConversionSettings::GV_PRECISION, precision_to_set);
settings_.get<Precision>().value = precision_to_set;
}
bool mapping::get_layerset_information(const IfcUtil::IfcBaseInterface* p, layerset_information& info, int &)
@@ -920,7 +922,7 @@ IfcSchema::IfcRepresentation* mapping::find_representation(const IfcSchema::IfcP
}
void mapping::addRepresentationsFromContextIds(IfcSchema::IfcRepresentation::list::ptr& representations) {
for (auto context_id : settings_.context_ids()) {
for (auto context_id : settings_.get<settings::ContextIds>().get()) {
IfcSchema::IfcGeometricRepresentationContext* context;
try {
context = file_->instance_by_id(context_id)->as<IfcSchema::IfcGeometricRepresentationContext>();
@@ -944,7 +946,7 @@ void mapping::addRepresentationsFromDefaultContexts(IfcSchema::IfcRepresentation
allowed_context_types.insert("notdefined");
std::set<std::string> context_types;
if (!settings_.get(IfcGeom::IteratorSettings::EXCLUDE_SOLIDS_AND_SURFACES)) {
if (settings_.get<settings::IncludeSurfaces>().get()) {
// Really this should only be 'Model', as per
// the standard 'Design' is deprecated. So,
// just for backwards compatibility:
@@ -954,7 +956,7 @@ void mapping::addRepresentationsFromDefaultContexts(IfcSchema::IfcRepresentation
context_types.insert("model view");
context_types.insert("detail view");
}
if (settings_.get(IfcGeom::IteratorSettings::INCLUDE_CURVES)) {
if (settings_.get<settings::IncludeCurves>().get()) {
context_types.insert("plan");
}
@@ -1020,63 +1022,6 @@ void mapping::addRepresentationsFromDefaultContexts(IfcSchema::IfcRepresentation
}
}
void mapping::apply_settings() {
conv_settings_.setValue(ConversionSettings::GV_MAX_FACES_TO_ORIENT, settings_.get(IfcGeom::IteratorSettings::SEW_SHELLS) ? std::numeric_limits<double>::infinity() : -1);
conv_settings_.setValue(ConversionSettings::GV_DIMENSIONALITY, (settings_.get(IfcGeom::IteratorSettings::INCLUDE_CURVES)
? (settings_.get(IfcGeom::IteratorSettings::EXCLUDE_SOLIDS_AND_SURFACES) ? -1. : 0.) : +1.));
conv_settings_.setValue(ConversionSettings::GV_LAYERSET_FIRST,
settings_.get(IfcGeom::IteratorSettings::LAYERSET_FIRST)
? +1.0
: -1.0
);
conv_settings_.setValue(ConversionSettings::GV_NO_WIRE_INTERSECTION_CHECK,
settings_.get(IfcGeom::IteratorSettings::NO_WIRE_INTERSECTION_CHECK)
? +1.0
: -1.0
);
conv_settings_.setValue(ConversionSettings::GV_NO_WIRE_INTERSECTION_TOLERANCE,
settings_.get(IfcGeom::IteratorSettings::NO_WIRE_INTERSECTION_TOLERANCE)
? +1.0
: -1.0
);
conv_settings_.setValue(ConversionSettings::GV_PRECISION_FACTOR,
settings_.get(IfcGeom::IteratorSettings::STRICT_TOLERANCE)
? 1.0
: 10.0
);
conv_settings_.setValue(ConversionSettings::GV_DISABLE_BOOLEAN_RESULT,
settings_.get(IfcGeom::IteratorSettings::DISABLE_BOOLEAN_RESULT)
? +1.0
: -1.0
);
conv_settings_.setValue(ConversionSettings::GV_DEBUG_BOOLEAN,
settings_.get(IfcGeom::IteratorSettings::DEBUG_BOOLEAN)
? +1.0
: -1.0
);
conv_settings_.setValue(ConversionSettings::GV_BOOLEAN_ATTEMPT_2D,
settings_.get(IfcGeom::IteratorSettings::BOOLEAN_ATTEMPT_2D)
? +1.0
: -1.0
);
if (settings_.get(IfcGeom::IteratorSettings::BUILDING_LOCAL_PLACEMENT)) {
if (settings_.get(IfcGeom::IteratorSettings::SITE_LOCAL_PLACEMENT)) {
Logger::Message(Logger::LOG_WARNING, "building-local-placement takes precedence over site-local-placement");
}
placement_rel_to_type_ = &IfcSchema::IfcBuilding::Class();
} else if (settings_.get(IfcGeom::IteratorSettings::SITE_LOCAL_PLACEMENT)) {
placement_rel_to_type_ = &IfcSchema::IfcSite::Class();
}
// @todo
// conv_settings_.set_offset(settings_.offset);
// conv_settings_.set_rotation(settings_.rotation);
}
IfcUtil::IfcBaseEntity* mapping::representation_of(const IfcUtil::IfcBaseEntity* product) {
// @todo correct, but very inefficient
IfcSchema::IfcRepresentation::list::ptr representations(new IfcSchema::IfcRepresentation::list);
@@ -1084,7 +1029,7 @@ IfcUtil::IfcBaseEntity* mapping::representation_of(const IfcUtil::IfcBaseEntity*
IfcSchema::IfcRepresentation::list::ptr intersection(new IfcSchema::IfcRepresentation::list);
IfcSchema::IfcRepresentation::list::ptr intersection_no_box(new IfcSchema::IfcRepresentation::list);
if (settings_.context_ids().empty()) {
if (!settings_.get<settings::ContextIds>().has()) {
addRepresentationsFromDefaultContexts(representations);
} else {
addRepresentationsFromContextIds(representations);
@@ -1100,7 +1045,7 @@ IfcUtil::IfcBaseEntity* mapping::representation_of(const IfcUtil::IfcBaseEntity*
}
}
if (intersection->size() == 0 && settings_.context_ids().empty() && settings_.get(IfcGeom::IteratorSettings::INCLUDE_CURVES) && settings_.get(IfcGeom::IteratorSettings::EXCLUDE_SOLIDS_AND_SURFACES)) {
if (intersection->size() == 0 && settings_.get<settings::ContextIds>().has() && settings_.get<settings::IncludeCurves>().get() && !settings_.get<settings::IncludeSurfaces>().get()) {
for (auto& r : *of_product) {
if (r->RepresentationIdentifier() && *r->RepresentationIdentifier() == "Axis") {
intersection->push(r);
+1 -4
View File
@@ -31,9 +31,8 @@ namespace geometry {
void addRepresentationsFromContextIds(IfcSchema::IfcRepresentation::list::ptr&);
void addRepresentationsFromDefaultContexts(IfcSchema::IfcRepresentation::list::ptr&);
public:
POSTFIX_SCHEMA(mapping)(IfcParse::IfcFile* file, IfcGeom::IteratorSettings& settings) : abstract_mapping(settings), file_(file), placement_rel_to_type_(0), placement_rel_to_instance_(0) {
POSTFIX_SCHEMA(mapping)(IfcParse::IfcFile* file, Settings& settings) : abstract_mapping(settings), file_(file), placement_rel_to_type_(0), placement_rel_to_instance_(0) {
initialize_units_();
apply_settings();
}
virtual ifcopenshell::geometry::taxonomy::ptr map(const IfcUtil::IfcBaseInterface*);
virtual void get_representations(std::vector<geometry_conversion_task>& tasks, std::vector<filter_t>& filters);
@@ -42,8 +41,6 @@ namespace geometry {
virtual double get_length_unit() const { return length_unit_; }
virtual aggregate_of_instance::ptr find_openings(const IfcUtil::IfcBaseEntity*);
virtual IfcUtil::IfcBaseEntity* representation_of(const IfcUtil::IfcBaseEntity* product);
void apply_settings();
virtual const IfcUtil::IfcBaseEntity* get_single_material_association(const IfcUtil::IfcBaseEntity* product);
IfcSchema::IfcRepresentation* representation_mapped_to(const IfcSchema::IfcRepresentation* representation);