2023-03-21 20:15:01 +01:00
# ifndef CONVERSIONSETTINGS_H
# define CONVERSIONSETTINGS_H
2017-12-20 16:38:55 +01:00
2023-03-21 20:15:01 +01:00
# include <array>
2023-03-30 14:28:25 +02:00
# include <limits>
2023-03-30 14:29:06 +02:00
# include <string>
2023-11-15 10:32:20 +01:00
# 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>
2023-03-30 14:28:25 +02:00
2023-03-21 20:15:01 +01:00
# include "ifc_geom_api.h"
2017-12-22 13:51:11 +01:00
2023-11-15 10:32:20 +01:00
# ifndef SWIG
namespace po = boost : : program_options ;
namespace std {
2025-09-26 14:24:49 +02:00
IFC_GEOM_API istream & operator > > ( istream & in , set < int > & ints ) ;
IFC_GEOM_API istream & operator > > ( istream & in , set < string > & ints ) ;
IFC_GEOM_API istream & operator > > ( istream & in , vector < double > & vs ) ;
2023-11-15 10:32:20 +01:00
}
# endif
2023-03-21 20:15:01 +01:00
namespace ifcopenshell {
namespace geometry {
2023-11-15 10:32:20 +01:00
inline namespace settings {
2022-07-18 13:51:45 +02:00
2023-11-15 10:32:20 +01:00
# ifndef SWIG
template < typename T , typename U = int >
struct HasDefault : std : : false_type { } ;
2023-03-21 20:15:01 +01:00
2023-11-15 10:32:20 +01:00
template < typename T >
struct HasDefault < T , decltype ( ( void ) T : : defaultvalue , 0 ) > : std : : true_type { } ;
# endif
2025-04-29 10:52:27 +02:00
template < typename Derived , typename T , bool Internal = false >
2023-11-15 10:32:20 +01:00
struct SettingBase {
typedef T base_type ;
2024-09-13 11:37:05 +02:00
// boost program options does not seem to handle optional<vector> types, so in case
// of vector settings we need to strip away the optional and detect argument presence
// with !vector::empty()
2025-03-19 11:42:11 +01:00
// tfk: we no longer do this because negative values can not be passed like this as boost confuses them with options
// std::conditional_t<std::is_same_v<T, std::vector<double>>, T, boost::optional<T>> value;
boost : : optional < T > value ;
2023-11-15 10:32:20 +01:00
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 ;
}
} ;
2025-04-29 10:52:27 +02:00
if constexpr ( Internal ) {
// do nothing, this is an internal setting and not supposed to be set from the command line
} else if constexpr ( std : : is_same_v < T , bool > ) {
2023-11-15 10:32:20 +01:00
// @todo bool_switch doesn't work with optional unfortunately...
value . emplace ( ) ;
desc . add_options ( ) ( Derived : : name , apply_default ( po : : bool_switch ( & * value ) ) , Derived : : description ) ;
2024-09-13 11:37:05 +02:00
} else if constexpr ( std : : is_same_v < T , std : : vector < double > > ) {
2025-03-19 11:42:11 +01:00
// these options have to be supplied manually in IfcConvert.cpp
// desc.add_options()(Derived::name, apply_default(po::value(&value)->multitoken()), Derived::description);
2023-11-15 10:32:20 +01:00
} else {
desc . add_options ( ) ( Derived : : name , apply_default ( po : : value ( & value ) ) , Derived : : description ) ;
}
}
T get ( ) const {
2025-03-19 11:42:11 +01:00
if constexpr ( false & & std : : is_same_v < T , std : : vector < double > > ) {
2024-09-13 11:37:05 +02:00
return value ;
} else {
if ( value ) {
return value . get ( ) ;
}
if constexpr ( HasDefault < Derived > ( ) ) {
return Derived : : defaultvalue ;
2025-10-03 14:10:07 +03:00
} else {
throw std : : runtime_error ( " Setting not set " ) ;
2024-09-13 11:37:05 +02:00
}
2023-11-15 10:32:20 +01:00
}
}
bool has ( ) const {
2025-03-19 11:42:11 +01:00
if constexpr ( false & & std : : is_same_v < T , std : : vector < double > > ) {
2024-09-13 11:37:05 +02:00
return ! value . empty ( ) ;
} else {
// @todo this is not reliable, better use vmap[...].defaulted()
return ! ! value ;
}
2023-11-15 10:32:20 +01:00
}
} ;
// 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 ;
} ;
2025-04-29 10:52:27 +02:00
struct LengthUnit : public SettingBase < LengthUnit , double , true > {
2023-11-15 10:32:20 +01:00
static constexpr const char * const name = " length-unit " ;
static constexpr const char * const description = " " ;
static constexpr double defaultvalue = 1.0 ;
} ;
2025-04-29 10:52:27 +02:00
struct PlaneUnit : public SettingBase < PlaneUnit , double , true > {
2023-11-15 10:32:20 +01:00
static constexpr const char * const name = " angle-unit " ;
static constexpr const char * const description = " " ;
static constexpr double defaultvalue = 1.0 ;
} ;
2025-04-29 10:52:27 +02:00
struct Precision : public SettingBase < Precision , double , true > {
2023-11-15 10:32:20 +01:00
static constexpr const char * const name = " precision " ;
static constexpr const char * const description = " " ;
static constexpr double defaultvalue = 0.00001 ;
} ;
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 ;
} ;
2024-12-10 21:17:37 +01:00
struct DebugBooleanOperations : public SettingBase < DebugBooleanOperations , bool > {
static constexpr const char * const name = " debug " ;
static constexpr const char * const description = " write boolean operands to file in current directory for debugging purposes " ;
2023-11-15 10:32:20 +01:00
static constexpr bool defaultvalue = false ;
} ;
2024-12-10 21:17:37 +01:00
struct BooleanAttempt2d : public SettingBase < BooleanAttempt2d , bool > {
2023-11-15 10:32:20 +01:00
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 ;
2023-03-21 20:15:01 +01:00
} ;
2023-11-15 10:32:20 +01:00
2024-10-07 20:47:01 +02:00
struct UnifyShapes : public SettingBase < UnifyShapes , bool > {
static constexpr const char * const name = " unify-shapes " ;
static constexpr const char * const description = " Unify adjacent co-planar and co-linear subshapes (topological entities "
" sharing the same geometric domain) before triangulation or further processing " ;
static constexpr bool defaultvalue = false ;
} ;
2024-04-29 21:00:59 +02:00
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 ;
} ;
2023-11-15 10:32:20 +01:00
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 " ;
2025-07-11 17:48:37 +05:00
static constexpr const char * const description = " List of comma separated context ids to process - e.g. '15,29' (no quotes needed). " ;
2023-11-15 10:32:20 +01:00
} ;
2025-07-11 16:30:41 +05:00
struct ContextTypes : public SettingBase < ContextTypes , std : : set < std : : string > > {
2024-04-18 21:04:02 +02:00
static constexpr const char * const name = " context-types " ;
2025-07-11 17:48:37 +05:00
static constexpr const char * const description = " Currently option has no effect. " ;
2024-04-18 21:04:02 +02:00
} ;
2025-07-11 16:30:41 +05:00
struct ContextIdentifiers : public SettingBase < ContextIdentifiers , std : : set < std : : string > > {
2024-04-18 21:04:02 +02:00
static constexpr const char * const name = " context-identifiers " ;
2025-07-11 17:48:37 +05:00
static constexpr const char * const description = " Currently option has no effect. " ;
2024-04-18 21:04:02 +02:00
} ;
enum OutputDimensionalityTypes {
CURVES ,
SURFACES_AND_SOLIDS ,
CURVES_SURFACES_AND_SOLIDS
} ;
2025-09-26 14:24:49 +02:00
IFC_GEOM_API std : : istream & operator > > ( std : : istream & in , OutputDimensionalityTypes & ioo ) ;
2024-04-18 21:04:02 +02:00
struct OutputDimensionality : public SettingBase < OutputDimensionality , OutputDimensionalityTypes > {
static constexpr const char * const name = " dimensionality " ;
2025-07-11 17:48:57 +05:00
static constexpr const char * const description =
" Specifies whether to include curves and/or surfaces and solids in the output result. "
" Defaults to only surfaces and solids (SURFACES_AND_SOLIDS). "
" Other possible values are CURVES, CURVES_SURFACES_AND_SOLIDS. " ;
2024-04-18 21:36:45 +02:00
static constexpr OutputDimensionalityTypes defaultvalue = SURFACES_AND_SOLIDS ;
2024-04-18 21:04:02 +02:00
} ;
2023-11-15 10:32:20 +01:00
enum IteratorOutputOptions {
TRIANGULATED ,
NATIVE ,
SERIALIZED
} ;
2025-09-26 14:24:49 +02:00
IFC_GEOM_API std : : istream & operator > > ( std : : istream & in , IteratorOutputOptions & ioo ) ;
2023-11-15 10:32:20 +01:00
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 ;
} ;
2024-08-24 20:02:34 +02:00
struct NoParallelMapping : public SettingBase < NoParallelMapping , bool > {
static constexpr const char * const name = " no-parallel-mapping " ;
static constexpr const char * const description = " Perform mapping upfront (single-threaded) as opposed to in parallel. May decrease performance, but also decrease output size (in the future) " ;
static constexpr bool defaultvalue = false ;
} ;
2025-05-18 22:14:22 +02:00
struct PermissiveShapeReuse : public SettingBase < PermissiveShapeReuse , bool > {
static constexpr const char * const name = " permissive-shape-reuse " ;
static constexpr const char * const description = " Traverse geometry-level transformations and apply to product-level placement in order to increase reuse of geometries " ;
static constexpr bool defaultvalue = false ;
} ;
2023-11-15 10:32:20 +01:00
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. " ;
} ;
2023-12-15 13:41:37 +01:00
struct CircleSegments : public SettingBase < CircleSegments , int > {
static constexpr const char * const name = " circle-segments " ;
static constexpr const char * const description = " Number of segments to approximate full circles in CGAL kernel. " ;
static constexpr int defaultvalue = 16 ;
} ;
2025-08-06 05:46:07 +02:00
struct CgalSmoothAngleDegrees : public SettingBase < CgalSmoothAngleDegrees , double > {
static constexpr const char * const name = " cgal-smooth-angle-degrees " ;
static constexpr const char * const description = " Angle in degrees under which adjacent facets will have averaged vertex normals in CGAL output. NB irrespective of original IFC geometry types. Defaults to -1 to disable smoothing. " ;
2025-08-21 14:06:54 +02:00
static constexpr double defaultvalue = - 1. ;
2025-08-06 05:46:07 +02:00
} ;
2024-02-18 13:59:55 +01:00
struct KeepBoundingBoxes : public SettingBase < KeepBoundingBoxes , bool > {
static constexpr const char * const name = " keep-bounding-boxes " ;
static constexpr const char * const description =
" Default is to removes IfcBoundingBox from model prior to converting geometry. "
" Setting this option disables that behaviour " ;
static constexpr bool defaultvalue = false ;
} ;
2024-08-15 13:56:31 -03:00
struct SurfaceColour : public SettingBase < SurfaceColour , bool > {
static constexpr const char * const name = " surface-colour " ;
static constexpr const char * const description =
" Prioritizes the surface color instead of using diffuse. " ;
static constexpr bool defaultvalue = false ;
} ;
2025-03-14 07:31:50 -07:00
struct ComputeCurvature : public SettingBase < ComputeCurvature , bool > {
static constexpr const char * const name = " compute-curvature " ;
static constexpr const char * const description = " Specifies whether function_item_evaluator.evaluate() computes curvature. " ;
static constexpr bool defaultvalue = false ;
} ;
2025-01-02 11:10:56 -08:00
enum FunctionStepMethod {
2023-11-22 15:49:24 -08:00
MAXSTEPSIZE ,
MINSTEPS } ;
2025-09-26 14:24:49 +02:00
IFC_GEOM_API std : : istream & operator > > ( std : : istream & in , FunctionStepMethod & ioo ) ;
2023-11-22 15:49:24 -08:00
2025-01-02 11:10:56 -08:00
struct FunctionStepType : public SettingBase < FunctionStepType , FunctionStepMethod > {
static constexpr const char * const name = " function-step-type " ;
static constexpr const char * const description = " Indicates the method used for defining step size when evaluating function-based curves. Provides interpretation of function-step-param " ;
static constexpr FunctionStepMethod defaultvalue = MAXSTEPSIZE ;
2023-11-22 15:49:24 -08:00
} ;
2025-01-02 11:10:56 -08:00
struct FunctionStepParam : public SettingBase < FunctionStepParam , double > {
static constexpr const char * const name = " function-step-param " ;
static constexpr const char * const description = " Indicates the parameter value for defining step size when evaluating function-based curves. " ;
static constexpr double defaultvalue = 0.5 ; // ceiling of this value is used when FunctionStepMethod is MinSteps
2023-11-22 15:49:24 -08:00
} ;
2024-09-13 11:37:05 +02:00
struct ModelOffset : public SettingBase < ModelOffset , std : : vector < double > > {
static constexpr const char * const name = " model-offset " ;
2025-03-19 11:42:11 +01:00
static constexpr const char * const description = " Applies an arbitrary offset of form x,y,z to all placements. " ;
2024-09-13 11:37:05 +02:00
} ;
struct ModelRotation : public SettingBase < ModelRotation , std : : vector < double > > {
static constexpr const char * const name = " model-rotation " ;
2025-03-19 11:42:11 +01:00
static constexpr const char * const description = " Applies an arbitrary quaternion rotation of form x,y,z,w to all placements. " ;
2024-09-13 11:37:05 +02:00
} ;
2024-09-18 19:25:37 +02:00
enum TriangulationMethod {
TRIANGLE_MESH ,
POLYHEDRON_WITHOUT_HOLES ,
POLYHEDRON_WITH_HOLES
} ;
2025-09-26 14:24:49 +02:00
IFC_GEOM_API std : : istream & operator > > ( std : : istream & in , TriangulationMethod & ioo ) ;
2024-09-18 19:25:37 +02:00
struct TriangulationType : public SettingBase < TriangulationType , TriangulationMethod > {
static constexpr const char * const name = " triangulation-type " ;
static constexpr const char * const description = " Type of planar facet to be emitted " ;
static constexpr TriangulationMethod defaultvalue = TRIANGLE_MESH ;
} ;
2025-02-23 14:46:10 +01:00
struct CgalEmitOriginalEdges : public SettingBase < CgalEmitOriginalEdges , bool > {
static constexpr const char * const name = " cgal-original-edges " ;
static constexpr const char * const description = " Try to emit original edge face boundary edges instead of recomputed ones based on face normal. Falls back to triangulated data in case of boolean operands and faces with holes. " ;
static constexpr bool defaultvalue = false ;
} ;
2025-05-18 22:14:22 +02:00
struct OcctNoCleanTriangulation : public SettingBase < OcctNoCleanTriangulation , bool , true > {
static constexpr const char * const name = " no-clean-triangulation " ;
static constexpr const char * const description = " Don't clean triangulations, might cause memory leaks " ;
static constexpr bool defaultvalue = false ;
} ;
struct CacheShapes : public SettingBase < CacheShapes , bool > {
static constexpr const char * const name = " cache-shapes " ;
static constexpr const char * const description = " Experimental as not all topology hash functions fully implemented " ;
static constexpr bool defaultvalue = false ;
} ;
2025-07-01 21:10:24 +02:00
2026-02-01 21:08:11 +01:00
struct MakeVolume : public SettingBase < MakeVolume , bool > {
static constexpr const char * const name = " make-volume " ;
static constexpr const char * const description = " Try to isolate and fix a valid volume from non-manifold elements prior to opening subtraction " ;
static constexpr bool defaultvalue = false ;
} ;
2025-07-01 21:10:24 +02:00
struct DeferProcessingFirstElement : public SettingBase < DeferProcessingFirstElement , bool , true > {
static constexpr const char * const name = " defer-processing-first-element " ;
static constexpr const char * const description = " Don't process first element in Iterator::initialize call() " ;
static constexpr bool defaultvalue = false ;
} ;
struct MaxOffset : public SettingBase < MaxOffset , double > {
static constexpr const char * const name = " max-offset " ;
static constexpr const char * const description = " Maximum translation offset to be observed after which median offset in model gets removed and logged. Requires --no-parallel-mapping. " ;
} ;
struct MaxOffsetDeviation : public SettingBase < MaxOffsetDeviation , double > {
static constexpr const char * const name = " max-offset-deviation " ;
static constexpr const char * const description = " To retain field of view, completely remove elements outside of the median offset. Requires --no-parallel-mapping. " ;
} ;
struct ApplyOffset : public SettingBase < ApplyOffset , std : : vector < double > > {
static constexpr const char * const name = " apply-offset " ;
static constexpr const char * const description = " Slight variation of --model-offset where large offsets are applied by negating existing large offsets to retain maximum precision. Requires --no-parallel-mapping. " ;
} ;
2023-11-15 10:32:20 +01:00
}
2025-03-19 11:42:43 +01:00
namespace impl {
template < typename T >
struct readable_name {
static constexpr const char * name = " Unknown Type " ;
} ;
template < >
struct readable_name < bool > {
static constexpr const char * name = " bool " ;
} ;
template < >
struct readable_name < int > {
static constexpr const char * name = " int " ;
} ;
template < >
struct readable_name < double > {
static constexpr const char * name = " double " ;
} ;
template < >
struct readable_name < std : : string > {
static constexpr const char * name = " std::string " ;
} ;
template < >
struct readable_name < std : : set < int > > {
static constexpr const char * name = " std::set<int> " ;
} ;
template < >
struct readable_name < std : : set < std : : string > > {
static constexpr const char * name = " std::set<std::string> " ;
} ;
template < >
struct readable_name < std : : vector < double > > {
static constexpr const char * name = " std::vector<double> " ;
} ;
template < >
struct readable_name < IteratorOutputOptions > {
static constexpr const char * name = " IteratorOutputOptions " ;
} ;
template < >
struct readable_name < FunctionStepMethod > {
static constexpr const char * name = " FunctionStepMethod " ;
} ;
template < >
struct readable_name < OutputDimensionalityTypes > {
static constexpr const char * name = " OutputDimensionalityTypes " ;
} ;
template < >
struct readable_name < TriangulationMethod > {
static constexpr const char * name = " TriangulationMethod " ;
} ;
}
2023-11-15 10:32:20 +01:00
template < typename settings_t >
2025-09-26 14:24:49 +02:00
class SettingsContainer {
2023-11-15 10:32:20 +01:00
public :
2025-01-02 11:10:56 -08:00
typedef boost : : variant < bool , int , double , std : : string , std : : set < int > , std : : set < std : : string > , std : : vector < double > , IteratorOutputOptions , FunctionStepMethod , OutputDimensionalityTypes , TriangulationMethod > value_variant_t ;
2023-11-15 10:32:20 +01:00
private :
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 " ) ;
}
}
2025-03-19 11:42:43 +01:00
template < std : : size_t Index >
std : : string get_type_ ( const std : : string & name ) const {
if ( std : : tuple_element_t < Index , settings_t > : : name = = name ) {
return impl : : readable_name < typename std : : tuple_element_t < Index , settings_t > : : base_type > : : name ;
}
if constexpr ( Index + 1 < std : : tuple_size_v < settings_t > ) {
return get_type_ < Index + 1 > ( name ) ;
} else {
throw std : : runtime_error ( " Setting not available " ) ;
}
}
2023-11-15 10:32:20 +01:00
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 ) {
2024-04-21 10:19:17 +02:00
if constexpr ( std : : is_enum_v < typename std : : tuple_element_t < Index , settings_t > : : base_type > ) {
2025-03-19 11:42:43 +01:00
if ( auto * val_ptr = boost : : get < int > ( & val ) ) {
auto val_as_enum = ( typename std : : tuple_element_t < Index , settings_t > : : base_type ) * val_ptr ;
2024-04-21 10:19:17 +02:00
std : : get < Index > ( settings ) . value = val_as_enum ;
return ;
}
}
2025-03-19 11:42:43 +01:00
try {
std : : get < Index > ( settings ) . value = boost : : get < typename std : : tuple_element_t < Index , settings_t > : : base_type > ( val ) ;
} catch ( const boost : : bad_get & ) {
std : : string ty = impl : : readable_name < typename std : : tuple_element_t < Index , settings_t > : : base_type > : : name ;
throw std : : runtime_error ( " Expected a value of type < " + ty + " > for setting ' " + name + " ' " ) ;
}
2023-11-15 10:32:20 +01:00
} 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 ) ;
}
2025-03-19 11:42:43 +01:00
std : : string get_type ( const std : : string & name ) {
return get_type_ < 0 > ( name ) ;
}
2023-11-15 10:32:20 +01:00
std : : vector < std : : string > setting_names ( ) const {
std : : vector < std : : string > r ;
get_setting_names_ < 0 > ( r ) ;
return r ;
}
2017-12-22 13:51:11 +01:00
} ;
2023-11-15 10:32:20 +01:00
2025-09-26 14:24:49 +02:00
class Settings : public SettingsContainer <
2026-02-01 21:08:11 +01:00
std : : tuple < MesherLinearDeflection , MesherAngularDeflection , ReorientShells , LengthUnit , PlaneUnit , Precision , OutputDimensionality , LayersetFirst , DisableBooleanResult , NoWireIntersectionCheck , NoWireIntersectionTolerance , PrecisionFactor , DebugBooleanOperations , BooleanAttempt2d , SurfaceColour , WeldVertices , UseWorldCoords , UnifyShapes , UseMaterialNames , ConvertBackUnits , ContextIds , ContextTypes , ContextIdentifiers , IteratorOutput , DisableOpeningSubtractions , ApplyDefaultMaterials , DontEmitNormals , GenerateUvs , ApplyLayerSets , UseElementHierarchy , ValidateQuantities , EdgeArrows , BuildingLocalPlacement , SiteLocalPlacement , ForceSpaceTransparency , CircleSegments , CgalSmoothAngleDegrees , KeepBoundingBoxes , ComputeCurvature , FunctionStepType , FunctionStepParam , NoParallelMapping , PermissiveShapeReuse , ModelOffset , ModelRotation , TriangulationType , CgalEmitOriginalEdges , OcctNoCleanTriangulation , CacheShapes , DeferProcessingFirstElement , MaxOffset , MaxOffsetDeviation , ApplyOffset , MakeVolume >
2023-11-15 10:32:20 +01:00
>
{ } ;
}
2023-03-21 20:15:01 +01:00
}
2022-06-11 15:48:04 +02:00
2023-03-21 20:15:01 +01:00
// @todo find a place
namespace IfcGeom {
2025-10-03 14:00:20 +00:00
# if defined(_MSC_VER)
# pragma warning(push)
# pragma warning(disable: 4275)
# endif
2025-09-26 14:24:49 +02:00
class IFC_GEOM_API geometry_exception : public std : : runtime_error {
2022-06-14 15:02:54 +02:00
protected :
std : : string message ;
public :
geometry_exception ( const std : : string & m )
2025-09-26 14:24:49 +02:00
: std : : runtime_error ( m )
{ }
2025-10-03 14:00:20 +00:00
~ geometry_exception ( ) override ;
2022-06-14 15:02:54 +02:00
} ;
class IFC_GEOM_API too_many_faces_exception : public geometry_exception {
public :
too_many_faces_exception ( )
: geometry_exception ( " Too many faces for operation " ) { }
2025-10-03 14:00:20 +00:00
~ too_many_faces_exception ( ) override ;
2022-06-14 15:02:54 +02:00
} ;
2017-12-20 16:38:55 +01:00
}
2025-10-03 14:00:20 +00:00
# if defined(_MSC_VER)
# pragma warning(pop)
# endif
2023-03-21 20:15:01 +01:00
# endif