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
+47 -198
View File
@@ -217,7 +217,6 @@ int main(int argc, char** argv) {
typedef char char_t;
#endif
double deflection_tolerance, angular_tolerance, force_space_transparency;
inclusion_filter include_filter;
inclusion_traverse_filter include_traverse_filter;
exclusion_filter exclude_filter;
@@ -276,6 +275,8 @@ int main(int argc, char** argv) {
// none, convex-decomposition, minkowski-triangles or halfspace-snapping
std::string exterior_only_algo;
ifcopenshell::geometry::Settings geometry_settings;
po::options_description geom_options("Geometry options");
geom_options.add_options()
@@ -283,32 +284,6 @@ int main(int argc, char** argv) {
"Geometry kernel to use (opencascade, cgal, cgal-simple).")
("threads,j", po::value<int>(&num_threads)->default_value(1),
"Number of parallel processing threads for geometry interpretation.")
("plan",
"Specifies whether to include curves in the output result. Typically "
"these are representations of type Plan or Axis. Excluded by default.")
("model",
"Specifies whether to include surfaces and solids in the output result. "
"Typically these are representations of type Body or Facetation. "
"Included by default.")
("weld-vertices",
"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.")
("use-world-coords",
"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.")
("convert-back-units",
"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.")
("orient-shells",
"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.")
("center-model",
"Centers the elements by applying the center point of all placements as an offset."
"Can take several minutes on large models.")
@@ -318,30 +293,6 @@ int main(int argc, char** argv) {
"Applies an arbitrary offset of form 'x;y;z' to all placements.")
("model-rotation", po::value<std::string>(&rotation_str),
"Applies an arbitrary quaternion rotation of form 'x;y;z;w' to all placements.")
#if OCC_VERSION_HEX < 0x60900
// In Open CASCADE version prior to 6.9.0 boolean operations with multiple
// arguments where not introduced yet and a work-around was implemented to
// subtract multiple openings as a single compound. This hack is obsolete
// for newer versions of Open CASCADE.
("merge-boolean-operands",
"Specifies whether to merge all IfcOpeningElement operands into a single "
"operand before applying the subtraction operation. This may "
"introduce a performance improvement at the risk of failing, in "
"which case the subtraction is applied one-by-one.")
#endif
("disable-opening-subtractions",
"Specifies whether to disable the boolean subtraction of "
"IfcOpeningElement Representations from their RelatingElements.")
("disable-boolean-results",
"Specifies whether to disable the boolean operation within representations "
"such as clippings by means of IfcBooleanResult and subtypes")
("no-2d-boolean",
"Do not attempt to process boolean subtractions in 2D.")
("enable-layerset-slicing",
"Specifies whether to enable the slicing of products according "
"to their associated IfcMaterialLayerSet.")
("layerset-first", "Assigns the first layer material of the layerset "
"to the complete product.")
("include", po::value<inclusion_filter>(&include_filter)->multitoken(),
"Specifies that the instances that match a specific filtering criteria are to be included in the geometrical output:\n"
"1) 'entities': the following list of types should be included. SVG output defaults "
@@ -368,32 +319,15 @@ int main(int argc, char** argv) {
"are '--include=arg GlobalId ...' and 'include arg GlobalId ...'. Spaces and tabs can be used as delimiters."
"Multiple filters of same type with different values can be inserted on their own lines. "
"See --include, --include+, --exclude, and --exclude+ for more details.")
("no-normals",
"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.")
("deflection-tolerance", po::value<double>(&deflection_tolerance)->default_value(1e-3),
"Sets the deflection tolerance of the mesher, 1e-3 by default if not specified.")
("force-space-transparency", po::value<double>(&force_space_transparency),
"Overrides transparency of spaces in geometry output.")
("angular-tolerance", po::value<double>(&angular_tolerance)->default_value(0.5),
"Sets the angular tolerance of the mesher in radians 0.5 by default if not specified.")
("generate-uvs",
"Generates UVs (texture coordinates) by using simple box projection. Requires normals. "
"Not guaranteed to work properly if used with --weld-vertices.")
("default-material-file", new po::typed_value<path_t, char_t>(&default_material_filename),
"Specifies a material file that describes the material object types will have"
"if an object does not have any specified material in the IFC file.")
("validate", "Checks whether geometrical output conforms to the included explicit quantities.")
("no-wire-intersection-check", "Skip wire intersection check.")
("no-wire-intersection-tolerance", "Set wire intersection tolerance to 0.")
("exterior-only",
po::value<std::string>(&exterior_only_algo)->default_value("none")->implicit_value("minkowski-triangles"),
"Export only the exterior shell of the building found by geometric analysis. convex-decomposition, minkowski-triangles or halfspace-snapping")
("strict-tolerance", "Use exact tolerance from model. Default is a 10 "
"times increase 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.");
;
geometry_settings.define_options(geom_options);
std::string bounds;
#ifdef HAVE_ICU
@@ -409,6 +343,8 @@ int main(int argc, char** argv) {
SvgSerializer::storey_height_display_types svg_storey_height_display = SvgSerializer::SH_NONE;
#endif
ifcopenshell::geometry::SerializerSettings serializer_settings;
po::options_description serializer_options("Serialization options");
serializer_options.add_options()
#ifdef HAVE_ICU
@@ -454,41 +390,14 @@ int main(int argc, char** argv) {
("section-height", po::value<double>(&section_height),
"Specifies the cut section height for SVG 2D geometry.")
("section-height-from-storeys", "Derives section height from storey elevation. Use --section-height to override default offset of 1.2")
("use-element-names",
"Use entity instance IfcRoot.Name instead of unique IDs for naming elements upon serialization. "
"Applicable for OBJ, DAE, STP, and SVG output.")
("use-element-guids",
"Use entity instance IfcRoot.GlobalId instead of unique IDs for naming elements upon serialization. "
"Applicable for OBJ, DAE, STP, and SVG output.")
("use-element-numeric-ids", "Use the numeric step identifier (entity instance name) for naming elements upon serialization. "
"Applicable for OBJ, DAE, STP, and SVG output.")
("use-material-names",
"Use material names instead of unique IDs for naming materials upon serialization. "
"Applicable for OBJ and DAE output.")
("use-element-types",
"Use element types instead of unique IDs for naming elements upon serialization. "
"Applicable for DAE output.")
("use-element-hierarchy",
"Order the elements using their IfcBuildingStorey parent. "
"Applicable for DAE output.")
("site-local-placement",
"Place elements locally in the IfcSite coordinate system, instead of placing "
"them in the IFC global coords. Applicable for OBJ, DAE, and STP output.")
("y-up", "Change the 'up' axis to positive Y, default is Z UP, Applicable for OBJ output.")
("building-local-placement",
"Similar to --site-local-placement, but placing elements in locally in the parent IfcBuilding coord system")
("precision", po::value<short>(&precision)->default_value(SerializerSettings::DEFAULT_PRECISION),
"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.")
("print-space-names", "Prints IfcSpace LongName and Name in the geometry output. Applicable for SVG output")
("print-space-areas", "Prints calculated IfcSpace areas in square meters. Applicable for SVG output")
("space-name-transform", po::value<std::string>(),
"Additional transform to the space labels in SVG")
("edge-arrows", "Adds arrow heads to edge segments to signify edge direction")
;
serializer_settings.define_options(serializer_options);
po::options_description cmdline_options;
cmdline_options.add(generic_options).add(fileio_options).add(geom_options).add(ifc_options).add(serializer_options);
@@ -523,39 +432,11 @@ int main(int argc, char** argv) {
const bool no_progress = vmap.count("no-progress") != 0;
const bool quiet = vmap.count("quiet") != 0;
const bool stderr_progress = vmap.count("stderr-progress") != 0;
const bool weld_vertices = vmap.count("weld-vertices") != 0;
const bool use_world_coords = vmap.count("use-world-coords") != 0;
const bool convert_back_units = vmap.count("convert-back-units") != 0;
const bool orient_shells = vmap.count("orient-shells") != 0;
#if OCC_VERSION_HEX < 0x60900
const bool merge_boolean_operands = vmap.count("merge-boolean-operands") != 0;
#endif
const bool disable_opening_subtractions = vmap.count("disable-opening-subtractions") != 0;
const bool disable_boolean_results = vmap.count("disable-boolean-results") != 0;
const bool include_plan = vmap.count("plan") != 0;
const bool include_model = vmap.count("model") != 0 || (!include_plan);
const bool enable_layerset_slicing = vmap.count("enable-layerset-slicing") != 0;
const bool layerset_first = vmap.count("layerset-first") != 0;
const bool use_element_names = vmap.count("use-element-names") != 0;
const bool use_element_guids = vmap.count("use-element-guids") != 0;
const bool use_element_stepids = vmap.count("use-element-numeric-ids") != 0;
const bool use_material_names = vmap.count("use-material-names") != 0;
const bool use_element_types = vmap.count("use-element-types") != 0;
const bool use_element_hierarchy = vmap.count("use-element-hierarchy") != 0;
const bool use_y_up = vmap.count("y-up") != 0;
const bool no_normals = vmap.count("no-normals") != 0;
const bool center_model = vmap.count("center-model") != 0;
const bool center_model_geometry = vmap.count("center-model-geometry") != 0;
const bool model_offset = vmap.count("model-offset") != 0;
const bool model_rotation = vmap.count("model-rotation") != 0;
const bool site_local_placement = vmap.count("site-local-placement") != 0;
const bool building_local_placement = vmap.count("building-local-placement") != 0;
const bool generate_uvs = vmap.count("generate-uvs") != 0;
const bool validate = vmap.count("validate") != 0;
const bool edge_arrows = vmap.count("edge-arrows") != 0;
const bool no_wire_intersection_check = vmap.count("no-wire-intersection-check") != 0;
const bool no_wire_intersection_tolerance = vmap.count("no-wire-intersection-tolerance") != 0;
const bool strict_tolerance = vmap.count("strict-tolerance") != 0;
if (!quiet || vmap.count("version")) {
print_version();
@@ -849,12 +730,12 @@ int main(int argc, char** argv) {
settings.threads = num_threads;
}
settings.settings.set(IfcGeom::IteratorSettings::USE_WORLD_COORDS, false);
settings.settings.set(IfcGeom::IteratorSettings::WELD_VERTICES, false);
settings.settings.set(IfcGeom::IteratorSettings::SEW_SHELLS, true);
settings.settings.set(IfcGeom::IteratorSettings::CONVERT_BACK_UNITS, true);
settings.settings.set(IfcGeom::IteratorSettings::DISABLE_TRIANGULATION, true);
settings.settings.set(IfcGeom::IteratorSettings::DISABLE_OPENING_SUBTRACTIONS, !settings.apply_openings);
settings.settings.get<ifcopenshell::geometry::settings::UseWorldCoords>().value = false;
settings.settings.get<ifcopenshell::geometry::settings::WeldVertices>().value = false;
settings.settings.get<ifcopenshell::geometry::settings::ReorientShells>().value = true;
settings.settings.get<ifcopenshell::geometry::settings::ConvertBackUnits>().value = true;
settings.settings.get<ifcopenshell::geometry::settings::IteratorOutput>().value = ifcopenshell::geometry::settings::NATIVE;
settings.settings.get<ifcopenshell::geometry::settings::DisableOpeningSubtractions>().value = !settings.apply_openings;
if (include_filter.type != geom_filter::UNUSED) {
settings.entity_names = include_filter.values;
@@ -916,77 +797,43 @@ int main(int argc, char** argv) {
}
}
SerializerSettings settings;
/// @todo Make APPLY_DEFAULT_MATERIALS configurable? Quickly tested setting this to false and using obj exporter caused the program to crash and burn.
settings.set(IfcGeom::IteratorSettings::APPLY_DEFAULT_MATERIALS, true);
settings.set(IfcGeom::IteratorSettings::USE_WORLD_COORDS, use_world_coords || output_extension == OBJ || output_extension == STP || output_extension == IGS);
settings.set(IfcGeom::IteratorSettings::WELD_VERTICES, weld_vertices);
settings.set(IfcGeom::IteratorSettings::SEW_SHELLS, orient_shells || output_extension == SVG); // svg depends on correct solids for boolean subtractions for hlr
settings.set(IfcGeom::IteratorSettings::CONVERT_BACK_UNITS, convert_back_units);
settings.set(IfcGeom::IteratorSettings::DISABLE_OPENING_SUBTRACTIONS, disable_opening_subtractions);
settings.set(IfcGeom::IteratorSettings::DISABLE_BOOLEAN_RESULT, disable_boolean_results);
settings.set(IfcGeom::IteratorSettings::INCLUDE_CURVES, include_plan);
settings.set(IfcGeom::IteratorSettings::EXCLUDE_SOLIDS_AND_SURFACES, !include_model);
settings.set(IfcGeom::IteratorSettings::APPLY_LAYERSETS, enable_layerset_slicing);
settings.set(IfcGeom::IteratorSettings::LAYERSET_FIRST, layerset_first);
settings.set(IfcGeom::IteratorSettings::DEBUG_BOOLEAN, vmap.count("debug"));
settings.set(IfcGeom::IteratorSettings::NO_NORMALS, no_normals);
settings.set(IfcGeom::IteratorSettings::GENERATE_UVS, generate_uvs);
settings.set(IfcGeom::IteratorSettings::EDGE_ARROWS, edge_arrows);
settings.set(IfcGeom::IteratorSettings::ELEMENT_HIERARCHY, use_element_hierarchy || output_extension == SVG);
settings.set(IfcGeom::IteratorSettings::SITE_LOCAL_PLACEMENT, site_local_placement);
settings.set(IfcGeom::IteratorSettings::BUILDING_LOCAL_PLACEMENT, building_local_placement);
settings.set(IfcGeom::IteratorSettings::VALIDATE_QUANTITIES, validate);
settings.set(IfcGeom::IteratorSettings::NO_WIRE_INTERSECTION_CHECK, no_wire_intersection_check);
settings.set(IfcGeom::IteratorSettings::NO_WIRE_INTERSECTION_TOLERANCE, no_wire_intersection_tolerance);
settings.set(IfcGeom::IteratorSettings::STRICT_TOLERANCE, strict_tolerance);
settings.set(IfcGeom::IteratorSettings::BOOLEAN_ATTEMPT_2D, !vmap.count("no-2d-boolean"));
if (!geometry_settings.get<ifcopenshell::geometry::settings::WeldVertices>().has()) {
geometry_settings.get<ifcopenshell::geometry::settings::WeldVertices>().value = false;
}
settings.set(SerializerSettings::USE_ELEMENT_NAMES, use_element_names);
settings.set(SerializerSettings::USE_ELEMENT_GUIDS, use_element_guids);
settings.set(SerializerSettings::USE_Y_UP, use_y_up);
settings.set(SerializerSettings::USE_ELEMENT_STEPIDS, use_element_stepids);
settings.set(SerializerSettings::USE_MATERIAL_NAMES, use_material_names);
settings.set(SerializerSettings::USE_ELEMENT_TYPES, use_element_types);
settings.set(SerializerSettings::USE_ELEMENT_HIERARCHY, use_element_hierarchy);
settings.set_deflection_tolerance(deflection_tolerance);
settings.set_angular_tolerance(angular_tolerance);
settings.precision = precision;
if (vmap.count("force-space-transparency")) {
settings.force_space_transparency(force_space_transparency);
IfcGeom::update_default_style("IfcSpace").transparency = force_space_transparency;
if (geometry_settings.get<ifcopenshell::geometry::settings::ForceSpaceTransparency>().has()) {
IfcGeom::update_default_style("IfcSpace").transparency = geometry_settings.get<ifcopenshell::geometry::settings::ForceSpaceTransparency>().get();
}
boost::shared_ptr<GeometrySerializer> serializer; /**< @todo use std::unique_ptr when possible */
if (output_extension == OBJ) {
// Do not use temp file for MTL as it's such a small file.
const path_t mtl_filename = change_extension(output_filename, MTL);
serializer = boost::make_shared<WaveFrontOBJSerializer>(IfcUtil::path::to_utf8(output_temp_filename), IfcUtil::path::to_utf8(mtl_filename), settings);
serializer = boost::make_shared<WaveFrontOBJSerializer>(IfcUtil::path::to_utf8(output_temp_filename), IfcUtil::path::to_utf8(mtl_filename), geometry_settings, serializer_settings);
#ifdef WITH_OPENCOLLADA
} else if (output_extension == DAE) {
serializer = boost::make_shared<ColladaSerializer>(IfcUtil::path::to_utf8(output_temp_filename), settings);
serializer = boost::make_shared<ColladaSerializer>(IfcUtil::path::to_utf8(output_temp_filename), geometry_settings, serializer_settings);
#endif
#ifdef WITH_GLTF
} else if (output_extension == GLB) {
serializer = boost::make_shared<GltfSerializer>(IfcUtil::path::to_utf8(output_temp_filename), settings);
serializer = boost::make_shared<GltfSerializer>(IfcUtil::path::to_utf8(output_temp_filename), geometry_settings, serializer_settings);
#endif
#ifdef IFOPSH_WITH_OPENCASCADE
} else if (output_extension == STP) {
serializer = boost::make_shared<StepSerializer>(IfcUtil::path::to_utf8(output_temp_filename), settings);
serializer = boost::make_shared<StepSerializer>(IfcUtil::path::to_utf8(output_temp_filename), geometry_settings, serializer_settings);
} else if (output_extension == IGS) {
#if OCC_VERSION_HEX < 0x60900
// According to https://tracker.dev.opencascade.org/view.php?id=25689 something has been fixed in 6.9.0
IGESControl_Controller::Init(); // work around Open Cascade bug
#endif
serializer = boost::make_shared<IgesSerializer>(IfcUtil::path::to_utf8(output_temp_filename), settings);
serializer = boost::make_shared<IgesSerializer>(IfcUtil::path::to_utf8(output_temp_filename), geometry_settings, serializer_settings);
} else if (output_extension == SVG) {
settings.set(IfcGeom::IteratorSettings::DISABLE_TRIANGULATION, true);
serializer = boost::make_shared<SvgSerializer>(IfcUtil::path::to_utf8(output_temp_filename), settings);
geometry_settings.get<ifcopenshell::geometry::settings::IteratorOutput>().value = ifcopenshell::geometry::settings::NATIVE;
serializer = boost::make_shared<SvgSerializer>(IfcUtil::path::to_utf8(output_temp_filename), geometry_settings, serializer_settings);
#ifdef WITH_HDF5
} else if (output_extension == HDF) {
settings.set(IfcGeom::IteratorSettings::DISABLE_TRIANGULATION, true);
serializer = boost::make_shared<HdfSerializer>(IfcUtil::path::to_utf8(output_temp_filename), settings);
geometry_settings.get<ifcopenshell::geometry::settings::IteratorOutput>().value = ifcopenshell::geometry::settings::NATIVE;
serializer = boost::make_shared<HdfSerializer>(IfcUtil::path::to_utf8(output_temp_filename), geometry_settings, serializer_settings);
#endif
#endif
} else {
@@ -996,7 +843,7 @@ int main(int argc, char** argv) {
return EXIT_FAILURE;
}
if (use_element_hierarchy && output_extension != DAE) {
if (geometry_settings.get<ifcopenshell::geometry::settings::UseElementHierarchy>().get() && output_extension != DAE) {
cerr_ << "[Error] --use-element-hierarchy can be used only with .dae output.\n";
/// @todo Lots of duplicate error-and-exit code.
write_log(!quiet);
@@ -1007,17 +854,17 @@ int main(int argc, char** argv) {
const bool is_tesselated = serializer->isTesselated(); // isTesselated() doesn't change at run-time
if (!is_tesselated) {
if (weld_vertices) {
if (geometry_settings.get<ifcopenshell::geometry::settings::WeldVertices>().get()) {
Logger::Notice("Weld vertices setting ignored when writing non-tesselated output");
}
if (generate_uvs) {
if (geometry_settings.get<ifcopenshell::geometry::settings::GenerateUvs>().get()) {
Logger::Notice("Generate UVs setting ignored when writing non-tesselated output");
}
if (center_model || center_model_geometry || model_offset) {
Logger::Notice("Centering/offsetting model setting ignored when writing non-tesselated output");
}
settings.set(IfcGeom::IteratorSettings::DISABLE_TRIANGULATION, true);
geometry_settings.get<ifcopenshell::geometry::settings::IteratorOutput>().value = ifcopenshell::geometry::settings::NATIVE;
}
if (!serializer->ready()) {
@@ -1042,6 +889,8 @@ int main(int argc, char** argv) {
Logger::SetOutput(quiet ? nullptr : &cout_, vcounter.count > 1 ? &cout_ : &log_stream);
}
/*
// @todo
if (model_rotation) {
std::array<double, 4> &rotation = settings.rotation;
if (sscanf(rotation_str.c_str(), "%lf;%lf;%lf;%lf", &rotation[0], &rotation[1], &rotation[2], &rotation[3]) != 4) {
@@ -1104,10 +953,10 @@ int main(int argc, char** argv) {
msg << std::setprecision (std::numeric_limits< double >::max_digits10) << "Using model offset (" << offset[0] << "," << offset[1] << "," << offset[2] << ")";
Logger::Notice(msg.str());
}
*/
std::unique_ptr<IfcGeom::Iterator> context_iterator;
if (!elems_from_adaptor) {
context_iterator.reset(new IfcGeom::Iterator(geometry_kernel, settings, ifc_file, filter_funcs, num_threads));
context_iterator.reset(new IfcGeom::Iterator(geometry_kernel, geometry_settings, ifc_file, filter_funcs, num_threads));
}
#if defined(WITH_HDF5) && defined(IFOPSH_WITH_OPENCASCADE)
@@ -1116,7 +965,7 @@ int main(int argc, char** argv) {
if (!vmap.count("cache-file")) {
cache_file = input_filename + CACHE + HDF;
}
cache.reset(new HdfSerializer(IfcUtil::path::to_utf8(cache_file), settings));
cache.reset(new HdfSerializer(IfcUtil::path::to_utf8(cache_file), geometry_settings, serializer_settings));
context_iterator->set_cache(cache.get());
}
#endif
@@ -1209,7 +1058,7 @@ int main(int argc, char** argv) {
}
#endif
if (context_iterator && convert_back_units) {
if (context_iterator && geometry_settings.get<ifcopenshell::geometry::settings::ConvertBackUnits>().get()) {
serializer->setUnitNameAndMagnitude(context_iterator->unit_name(), static_cast<float>(context_iterator->unit_magnitude()));
} else {
serializer->setUnitNameAndMagnitude("METER", 1.0f);
@@ -1315,7 +1164,7 @@ int main(int argc, char** argv) {
output_temp_filename << "' for the conversion result.";
}
if (validate && Logger::MaxSeverity() >= Logger::LOG_ERROR) {
if (geometry_settings.get<ifcopenshell::geometry::settings::ValidateQuantities>().get() && Logger::MaxSeverity() >= Logger::LOG_ERROR) {
Logger::Error("Errors encountered during processing.");
successful = false;
}
@@ -1666,12 +1515,12 @@ void fix_quantities(IfcParse::IfcFile& f, bool no_progress, bool quiet, bool std
}
}
IfcGeom::IteratorSettings settings;
settings.set(IfcGeom::IteratorSettings::USE_WORLD_COORDS, false);
settings.set(IfcGeom::IteratorSettings::WELD_VERTICES, false);
settings.set(IfcGeom::IteratorSettings::SEW_SHELLS, true);
settings.set(IfcGeom::IteratorSettings::CONVERT_BACK_UNITS, true);
settings.set(IfcGeom::IteratorSettings::DISABLE_TRIANGULATION, true);
ifcopenshell::geometry::Settings settings;
settings.get<ifcopenshell::geometry::settings::UseWorldCoords>().value = false;
settings.get<ifcopenshell::geometry::settings::WeldVertices>().value = false;
settings.get<ifcopenshell::geometry::settings::ReorientShells>().value = true;
settings.get<ifcopenshell::geometry::settings::ConvertBackUnits>().value = true;
settings.get<ifcopenshell::geometry::settings::IteratorOutput>().value = ifcopenshell::geometry::settings::NATIVE;
IfcGeom::Iterator context_iterator(settings, &f, {}, 1);
+7 -7
View File
@@ -45,14 +45,14 @@ void fix_spaceboundaries(IfcParse::IfcFile& f, bool no_progress, bool quiet, boo
return;
}
IfcGeom::IteratorSettings settings;
ifcopenshell::geometry::Settings settings;
settings.set(IfcGeom::IteratorSettings::USE_WORLD_COORDS, false);
settings.set(IfcGeom::IteratorSettings::WELD_VERTICES, false);
settings.set(IfcGeom::IteratorSettings::SEW_SHELLS, true);
settings.set(IfcGeom::IteratorSettings::CONVERT_BACK_UNITS, true);
settings.set(IfcGeom::IteratorSettings::DISABLE_TRIANGULATION, true);
settings.set(IfcGeom::IteratorSettings::DISABLE_OPENING_SUBTRACTIONS, true);
settings.get<ifcopenshell::geometry::settings::UseWorldCoords>().value = false;
settings.get<ifcopenshell::geometry::settings::WeldVertices>().value = false;
settings.get<ifcopenshell::geometry::settings::ReorientShells>().value = true;
settings.get<ifcopenshell::geometry::settings::ConvertBackUnits>().value = true;
settings.get<ifcopenshell::geometry::settings::IteratorOutput>().value = ifcopenshell::geometry::settings::NATIVE;
settings.get<ifcopenshell::geometry::settings::DisableOpeningSubtractions>().value = true;
ifcopenshell::geometry::Converter c("cgal", &f2, settings);
@@ -10,13 +10,14 @@
#include <algorithm>
void fix_storeycontainment(IfcParse::IfcFile& f, bool no_progress, bool quiet, bool stderr_progress) {
IfcGeom::IteratorSettings settings;
settings.set(IfcGeom::IteratorSettings::USE_WORLD_COORDS, false);
settings.set(IfcGeom::IteratorSettings::WELD_VERTICES, false);
settings.set(IfcGeom::IteratorSettings::SEW_SHELLS, true);
settings.set(IfcGeom::IteratorSettings::CONVERT_BACK_UNITS, true);
settings.set(IfcGeom::IteratorSettings::DISABLE_TRIANGULATION, true);
settings.set(IfcGeom::IteratorSettings::DISABLE_OPENING_SUBTRACTIONS, true);
ifcopenshell::geometry::Settings settings;
settings.get<ifcopenshell::geometry::settings::UseWorldCoords>().value = false;
settings.get<ifcopenshell::geometry::settings::WeldVertices>().value = false;
settings.get<ifcopenshell::geometry::settings::ReorientShells>().value = true;
settings.get<ifcopenshell::geometry::settings::ConvertBackUnits>().value = true;
settings.get<ifcopenshell::geometry::settings::IteratorOutput>().value = ifcopenshell::geometry::settings::NATIVE;
settings.get<ifcopenshell::geometry::settings::DisableOpeningSubtractions>().value = true;
std::vector<ifcopenshell::geometry::filter_t> no_openings_and_spaces = {
IfcGeom::entity_filter(false, false, {"IfcOpeningElement", "IfcSpace"})
@@ -133,7 +134,7 @@ void fix_storeycontainment(IfcParse::IfcFile& f, bool no_progress, bool quiet, b
std::vector<double> intersection_volumes(nefs.size());
for (auto& g : geom_object->geometry()) {
auto s = ((ifcopenshell::geometry::CgalShape*) g.Shape())->shape();
auto s = std::static_pointer_cast<ifcopenshell::geometry::CgalShape>(g.Shape())->poly();
const auto& m = g.Placement()->ccomponents();
const auto& n = geom_object->transformation().data()->ccomponents();
@@ -12,17 +12,17 @@ using namespace ifcopenshell::geometry;
void fix_wallconnectivity(IfcParse::IfcFile& f, bool no_progress, bool quiet, bool stderr_progress) {
intersection_validator v(f, { "IfcWall" }, 1.e-3, no_progress, quiet, stderr_progress);
ifcopenshell::geometry::Settings settings;
IfcGeom::IteratorSettings settings;
settings.set(IfcGeom::IteratorSettings::USE_WORLD_COORDS, false);
settings.set(IfcGeom::IteratorSettings::WELD_VERTICES, false);
settings.set(IfcGeom::IteratorSettings::SEW_SHELLS, true);
settings.set(IfcGeom::IteratorSettings::CONVERT_BACK_UNITS, true);
settings.set(IfcGeom::IteratorSettings::DISABLE_TRIANGULATION, true);
settings.set(IfcGeom::IteratorSettings::DISABLE_OPENING_SUBTRACTIONS, true);
settings.get<ifcopenshell::geometry::settings::UseWorldCoords>().value = false;
settings.get<ifcopenshell::geometry::settings::WeldVertices>().value = false;
settings.get<ifcopenshell::geometry::settings::ReorientShells>().value = true;
settings.get<ifcopenshell::geometry::settings::ConvertBackUnits>().value = true;
settings.get<ifcopenshell::geometry::settings::IteratorOutput>().value = ifcopenshell::geometry::settings::NATIVE;
settings.get<ifcopenshell::geometry::settings::DisableOpeningSubtractions>().value = true;
settings.set(IfcGeom::IteratorSettings::INCLUDE_CURVES, true);
settings.set(IfcGeom::IteratorSettings::EXCLUDE_SOLIDS_AND_SURFACES, true);
settings.get<ifcopenshell::geometry::settings::IncludeCurves>().value = true;
settings.get<ifcopenshell::geometry::settings::IncludeSurfaces>().value = false;
ifcopenshell::geometry::Converter c("cgal", &f, settings);
+7 -7
View File
@@ -433,13 +433,13 @@ struct intersection_validator {
intersection_validator(IfcParse::IfcFile& f, std::initializer_list<std::string> entities, double eps, bool no_progress, bool quiet, bool stderr_progress) {
IfcGeom::IteratorSettings settings;
settings.set(IfcGeom::IteratorSettings::USE_WORLD_COORDS, false);
settings.set(IfcGeom::IteratorSettings::WELD_VERTICES, false);
settings.set(IfcGeom::IteratorSettings::SEW_SHELLS, true);
settings.set(IfcGeom::IteratorSettings::CONVERT_BACK_UNITS, true);
settings.set(IfcGeom::IteratorSettings::DISABLE_TRIANGULATION, true);
settings.set(IfcGeom::IteratorSettings::DISABLE_OPENING_SUBTRACTIONS, true);
ifcopenshell::geometry::Settings settings;
settings.get<ifcopenshell::geometry::settings::UseWorldCoords>().value = false;
settings.get<ifcopenshell::geometry::settings::WeldVertices>().value = false;
settings.get<ifcopenshell::geometry::settings::ReorientShells>().value = true;
settings.get<ifcopenshell::geometry::settings::ConvertBackUnits>().value = true;
settings.get<ifcopenshell::geometry::settings::IteratorOutput>().value = ifcopenshell::geometry::settings::NATIVE;
settings.get<ifcopenshell::geometry::settings::DisableOpeningSubtractions>().value = true;
std::vector<ifcopenshell::geometry::filter_t> spaces_and_walls = {
IfcGeom::entity_filter(true, false, entities)
+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);
+9 -6
View File
@@ -583,23 +583,26 @@ int main () {
char* data = new char[len];
memcpy(data, m.string().c_str(), len);
IfcGeom::IteratorSettings settings;
settings.set(IfcGeom::IteratorSettings::USE_WORLD_COORDS, false);
settings.set(IfcGeom::IteratorSettings::WELD_VERTICES, false);
settings.set(IfcGeom::IteratorSettings::CONVERT_BACK_UNITS, true);
ifcopenshell::geometry::Settings settings;
settings.get<ifcopenshell::geometry::settings::UseWorldCoords>().value = false;
settings.get<ifcopenshell::geometry::settings::WeldVertices>().value = false;
settings.get<ifcopenshell::geometry::settings::ConvertBackUnits>().value = true;
// settings.set(IfcGeom::IteratorSettings::INCLUDE_CURVES, true);
/*
// @todo
std::vector< std::pair<uint32_t, uint32_t> >::const_iterator it = setting_pairs.begin();
for (; it != setting_pairs.end(); ++it) {
settings.set(it->first, it->second != 0);
settings.get(it->first, it->second != 0);
if (it->first == IfcGeom::IteratorSettings::SEW_SHELLS && it->second) {
// Quantities (especially volume) can be emitted if there are proper
// topologically valid geometries being created.
emit_quantities = true;
}
}
*/
settings.set_deflection_tolerance(deflection);
settings.get<ifcopenshell::geometry::settings::MesherLinearDeflection>().value = deflection;
file = new IfcParse::IfcFile(data, (int)len);
iterator = new IfcGeom::Iterator(settings, file);
@@ -50,28 +50,59 @@ if has_occ:
else:
return shape
class missing_setting:
def __repr__(self): return '-'
# Subclass the settings module to provide an additional
# setting to enable pythonOCC when available
class settings_mixin:
"""
Pythonic interface mixin to the settings modules and
to provide an additional setting to enable pythonOCC
when available
"""
def __init__(self, **kwargs):
super(settings_mixin, self).__init__()
for k, v in kwargs.items():
self.set(getattr(self, k), v)
# nb: we just subclass serializer settings, so in python
# we do not differentiate between the two setting types
def __repr__(self):
def safe_get(x):
try: return self.get_(x)
except: return missing_setting()
fmt_pair = lambda x: "%s = %r" % (self.rname(x), safe_get(x))
return "%s(%s)" % (
type(self).__name__,
", ".join(map(fmt_pair, self.setting_names()))
)
@staticmethod
def name(k):
return k.lower().replace('_', '-')
@staticmethod
def rname(k):
return k.upper().replace('-', '_')
def set(self, k, v):
if k == "USE_PYTHON_OPENCASCADE":
if not has_occ:
raise ArgumentError("Python OpenCASCADE is not installed")
if v:
self.set_("iterator-output", ifcopenshell_wrapper.SERIALIZED)
self.set_("use-world-coords", True)
self.use_python_opencascade = True
else:
self.set_(self.name(k), v)
def get(self, k):
return self.get_(self.name(k))
class settings(ifcopenshell_wrapper.SerializerSettings):
if has_occ:
USE_PYTHON_OPENCASCADE = -1
def set(self, *args):
setting, value = args
if setting == settings.USE_PYTHON_OPENCASCADE:
self.set(settings.USE_BREP_DATA, value)
self.set(settings.USE_WORLD_COORDS, value)
self.set(settings.DISABLE_TRIANGULATION, value)
self.use_python_opencascade = value
else:
ifcopenshell_wrapper.SerializerSettings.set(self, *args)
class serializer_settings(settings_mixin, ifcopenshell_wrapper.SerializerSettings):
pass
class settings(settings_mixin, ifcopenshell_wrapper.Settings):
pass
# Make sure people are able to use python's platform agnostic paths
class iterator(ifcopenshell_wrapper.Iterator):
+65 -43
View File
@@ -30,7 +30,7 @@
}
// SWIG does not support bool references in a meaningful way, so the
// IfcGeom::IteratorSettings functions degrade to return a read only value
// ifcopenshell::geometry::Settings functions degrade to return a read only value
%typemap(out) double& {
$result = SWIG_From_double(*$1);
}
@@ -62,6 +62,7 @@
%include "../ifcgeom/Converter.h"
%include "../ifcgeom/ConversionResult.h"
%include "../ifcgeom/IteratorSettings.h"
%include "../ifcgeom/ConversionSettings.h"
%include "../ifcgeom/IfcGeomElement.h"
%include "../ifcgeom/IfcGeomRepresentation.h"
%include "../ifcgeom/Iterator.h"
@@ -74,6 +75,55 @@
%include "../serializers/XmlSerializer.h"
%include "../serializers/GltfSerializer.h"
%extend ifcopenshell::geometry::Settings {
void set_(const std::string& name, bool val) {
return $self->set(name, val);
}
void set_(const std::string& name, int val) {
return $self->set(name, val);
}
void set_(const std::string& name, double val) {
return $self->set(name, val);
}
void set_(const std::string& name, const std::string& val) {
return $self->set(name, val);
}
void set_(const std::string& name, const std::set<int>& val) {
return $self->set(name, val);
}
boost::variant<bool, int, double, std::string, std::set<int>> get_(const std::string& name) {
return $self->get(name);
}
std::vector<std::string> setting_names() {
return $self->setting_names();
}
}
%extend ifcopenshell::geometry::SerializerSettings {
void set_(const std::string& name, bool val) {
return $self->set(name, val);
}
void set_(const std::string& name, int val) {
return $self->set(name, val);
}
void set_(const std::string& name, double val) {
return $self->set(name, val);
}
void set_(const std::string& name, const std::string& val) {
return $self->set(name, val);
}
void set_(const std::string& name, const std::set<int>& val) {
return $self->set(name, val);
}
boost::variant<bool, int, double, std::string, std::set<int>> get_(const std::string& name) {
return $self->get(name);
}
std::vector<std::string> setting_names() {
return $self->setting_names();
}
}
#ifdef IFOPSH_WITH_OPENCASCADE
%template(ray_intersection_results) std::vector<IfcGeom::ray_intersection_result>;
@@ -184,33 +234,6 @@ struct ShapeRTTI : public boost::static_visitor<PyObject*>
$result = boost::apply_visitor(ShapeRTTI(), $1);
}
%extend SerializerSettings {
%pythoncode %{
old_init = __init__
def __init__(self, **kwargs):
self.old_init()
for k, v in kwargs.items():
self.set(getattr(self, k), v)
def __repr__(self):
def d():
import numbers
for x in dir(self):
if x.isupper() and x not in {"NUM_SETTINGS", "USE_PYTHON_OPENCASCADE", "DEFAULT_PRECISION"}:
v = getattr(self, x)
if isinstance(v, numbers.Integral):
yield x
return "%s(%s)" % (
type(self).__name__,
(", ".join(map(lambda x: "%s = %r" % (x, self.get(getattr(self, x))), d())))
)
%}
}
%newobject construct_iterator_with_include_exclude;
%newobject construct_iterator_with_include_exclude_globalid;
%newobject construct_iterator_with_include_exclude_id;
@@ -218,13 +241,13 @@ struct ShapeRTTI : public boost::static_visitor<PyObject*>
// I couldn't get the vector<string> typemap to be applied when %extending Iterator constructor.
// anyway it does not matter as SWIG generates C code without actual constructors
%inline %{
IfcGeom::Iterator* construct_iterator_with_include_exclude(const std::string& geometry_library, IfcGeom::IteratorSettings settings, IfcParse::IfcFile* file, std::vector<std::string> elems, bool include, int num_threads) {
IfcGeom::Iterator* construct_iterator_with_include_exclude(const std::string& geometry_library, ifcopenshell::geometry::Settings settings, IfcParse::IfcFile* file, std::vector<std::string> elems, bool include, int num_threads) {
std::set<std::string> elems_set(elems.begin(), elems.end());
IfcGeom::entity_filter ef{ include, false, elems_set };
return new IfcGeom::Iterator(geometry_library, settings, file, {ef}, num_threads);
}
IfcGeom::Iterator* construct_iterator_with_include_exclude_globalid(const std::string& geometry_library, IfcGeom::IteratorSettings settings, IfcParse::IfcFile* file, std::vector<std::string> elems, bool include, int num_threads) {
IfcGeom::Iterator* construct_iterator_with_include_exclude_globalid(const std::string& geometry_library, ifcopenshell::geometry::Settings settings, IfcParse::IfcFile* file, std::vector<std::string> elems, bool include, int num_threads) {
std::set<std::string> elems_set(elems.begin(), elems.end());
IfcGeom::attribute_filter af;
af.attribute_name = "GlobalId";
@@ -233,7 +256,7 @@ struct ShapeRTTI : public boost::static_visitor<PyObject*>
return new IfcGeom::Iterator(geometry_library, settings, file, {af}, num_threads);
}
IfcGeom::Iterator* construct_iterator_with_include_exclude_id(const std::string& geometry_library, IfcGeom::IteratorSettings settings, IfcParse::IfcFile* file, std::vector<int> elems, bool include, int num_threads) {
IfcGeom::Iterator* construct_iterator_with_include_exclude_id(const std::string& geometry_library, ifcopenshell::geometry::Settings settings, IfcParse::IfcFile* file, std::vector<int> elems, bool include, int num_threads) {
std::set<int> elems_set(elems.begin(), elems.end());
IfcGeom::instance_id_filter af(include, false, elems_set);
return new IfcGeom::Iterator(geometry_library, settings, file, {af}, num_threads);
@@ -374,7 +397,7 @@ struct ShapeRTTI : public boost::static_visitor<PyObject*>
}
template <typename Schema>
static boost::variant<IfcGeom::Element*, IfcGeom::Representation::Representation*> helper_fn_create_shape(const std::string& geometry_library, IfcGeom::IteratorSettings& settings, IfcUtil::IfcBaseClass* instance, IfcUtil::IfcBaseClass* representation = 0) {
static boost::variant<IfcGeom::Element*, IfcGeom::Representation::Representation*> helper_fn_create_shape(const std::string& geometry_library, ifcopenshell::geometry::Settings& settings, IfcUtil::IfcBaseClass* instance, IfcUtil::IfcBaseClass* representation = 0) {
IfcParse::IfcFile* file = instance->data().file;
ifcopenshell::geometry::Converter kernel(geometry_library, file, settings);
@@ -403,13 +426,13 @@ struct ShapeRTTI : public boost::static_visitor<PyObject*>
if (!rep->RepresentationIdentifier()) {
continue;
}
if (!settings.get(IfcGeom::IteratorSettings::EXCLUDE_SOLIDS_AND_SURFACES)) {
if (settings.get<ifcopenshell::geometry::settings::IncludeSurfaces>().get()) {
if (*rep->RepresentationIdentifier() == "Body") {
ifc_representation = rep;
break;
}
}
if (settings.get(IfcGeom::IteratorSettings::INCLUDE_CURVES)) {
if (settings.get<ifcopenshell::geometry::settings::IncludeCurves>().get()) {
if (*rep->RepresentationIdentifier() == "Plan" || *rep->RepresentationIdentifier() == "Axis") {
ifc_representation = rep;
break;
@@ -427,13 +450,13 @@ struct ShapeRTTI : public boost::static_visitor<PyObject*>
// TODO: Remove redundancy with IfcGeomIterator.h
if (context->ContextType()) {
std::set<std::string> context_types;
if (!settings.get(IfcGeom::IteratorSettings::EXCLUDE_SOLIDS_AND_SURFACES)) {
if (settings.get<ifcopenshell::geometry::settings::IncludeSurfaces>().get()) {
context_types.insert("model");
context_types.insert("design");
context_types.insert("model view");
context_types.insert("detail view");
}
if (settings.get(IfcGeom::IteratorSettings::INCLUDE_CURVES)) {
if (settings.get<ifcopenshell::geometry::settings::IncludeCurves>().get()) {
context_types.insert("plan");
}
@@ -461,11 +484,11 @@ struct ShapeRTTI : public boost::static_visitor<PyObject*>
if (!brep) {
throw IfcParse::IfcException("Failed to process shape");
}
if (settings.get(IfcGeom::IteratorSettings::USE_BREP_DATA)) {
if (settings.get<ifcopenshell::geometry::settings::IteratorOutput>().get() == ifcopenshell::geometry::settings::SERIALIZED) {
IfcGeom::SerializedElement* serialization = new IfcGeom::SerializedElement(*brep);
delete brep;
return serialization;
} else if (!settings.get(IfcGeom::IteratorSettings::DISABLE_TRIANGULATION)) {
} else if (settings.get<ifcopenshell::geometry::settings::IteratorOutput>().get() == ifcopenshell::geometry::settings::TRIANGULATED) {
IfcGeom::TriangulationElement* triangulation = new IfcGeom::TriangulationElement(*brep);
delete brep;
return triangulation;
@@ -481,12 +504,11 @@ struct ShapeRTTI : public boost::static_visitor<PyObject*>
) {
IfcGeom::ConversionResults shapes = kernel.convert(instance);
IfcGeom::ElementSettings element_settings(settings, kernel.mapping()->get_length_unit(), instance->declaration().name());
IfcGeom::Representation::BRep brep(element_settings, to_locale_invariant_string(instance->data().id()), shapes);
IfcGeom::Representation::BRep brep(settings, instance->declaration().name(), to_locale_invariant_string(instance->data().id()), shapes);
try {
if (settings.get(IfcGeom::IteratorSettings::USE_BREP_DATA)) {
if (settings.get<ifcopenshell::geometry::settings::IteratorOutput>().get() == ifcopenshell::geometry::settings::SERIALIZED) {
return new IfcGeom::Representation::Serialization(brep);
} else if (!settings.get(IfcGeom::IteratorSettings::DISABLE_TRIANGULATION)) {
} else if (settings.get<ifcopenshell::geometry::settings::IteratorOutput>().get() == ifcopenshell::geometry::settings::TRIANGULATED) {
return new IfcGeom::Representation::Triangulation(brep);
}
} catch (...) {
@@ -502,7 +524,7 @@ struct ShapeRTTI : public boost::static_visitor<PyObject*>
%}
%inline %{
static boost::variant<IfcGeom::Element*, IfcGeom::Representation::Representation*> create_shape(IfcGeom::IteratorSettings& settings, IfcUtil::IfcBaseClass* instance, IfcUtil::IfcBaseClass* representation = 0, const char* const geometry_library="opencascade") {
static boost::variant<IfcGeom::Element*, IfcGeom::Representation::Representation*> create_shape(ifcopenshell::geometry::Settings& settings, IfcUtil::IfcBaseClass* instance, IfcUtil::IfcBaseClass* representation = 0, const char* const geometry_library="opencascade") {
const std::string& schema_name = instance->declaration().schema()->name();
#ifdef HAS_SCHEMA_2x3
+5
View File
@@ -56,6 +56,7 @@
%shared_ptr(IfcGeom::OpaqueNumber);
%ignore IfcGeom::NumberNativeDouble;
%ignore ifcopenshell::geometry::Converter;
// General python-specific rename rules for comparison operators.
// Mostly to silence warnings, but might be of use some time.
@@ -134,6 +135,7 @@
#include "../ifcparse/IfcSchema.h"
#include "../ifcparse/utils.h"
#include "../ifcgeom/ConversionSettings.h"
#include "../ifcgeom/ConversionResult.h"
#include "../svgfill/src/svgfill.h"
@@ -204,6 +206,9 @@
#include "../ifcparse/IfcFile.h"
#include "../ifcparse/IfcSchema.h"
#include "../ifcparse/utils.h"
#include "../ifcgeom/ConversionSettings.h"
#include "../ifcgeom/ConversionResult.h"
#include "../svgfill/src/svgfill.h"
%}
+16
View File
@@ -185,4 +185,20 @@
}
return pyobj;
}
struct pythonizing_visitor {
typedef PyObject* result_type;
template <typename T>
PyObject* operator()(const T& t) {
return pythonize(t);
}
template <>
PyObject* operator()(const std::set<int>& t) {
std::vector<int> vs(t.begin(), t.end());
return pythonize_vector(vs);
}
};
%}
+5
View File
@@ -147,3 +147,8 @@ CREATE_VECTOR_TYPEMAP_OUT(IfcParse::inverse_attribute const *)
CREATE_VECTOR_TYPEMAP_OUT(IfcParse::entity const *)
CREATE_VECTOR_TYPEMAP_OUT(IfcParse::declaration const *)
CREATE_VECTOR_TYPEMAP_OUT(IfcGeom::ConversionResultShape *)
%typemap(out) boost::variant<bool, int, double, std::string, std::set<int>> {
pythonizing_visitor vis;
$result = $1.apply_visitor(vis);
}
+3 -3
View File
@@ -409,7 +409,7 @@ void ColladaSerializer::ColladaExporter::write(const IfcGeom::TriangulationEleme
DeferredObject deferred(name, representation_id, o->type(), o->transformation(), mesh.verts(), mesh.normals(),
mesh.faces(), mesh.edges(), mesh.material_ids(), mesh.materials(), material_references, mesh.uvs());
if (serializer->settings().get(SerializerSettings::USE_ELEMENT_HIERARCHY)) {
if (serializer->geometry_settings().get<ifcopenshell::geometry::settings::UseElementHierarchy>().get()) {
deferred.parents() = o->parents();
}
@@ -451,7 +451,7 @@ std::string ColladaSerializer::differentiateSlabTypes(const IfcUtil::IfcBaseEnti
std::string ColladaSerializer::object_id(const IfcGeom::Element* o) /*override*/
{
if (settings_.get(SerializerSettings::USE_ELEMENT_TYPES)) {
if (settings_.get<ifcopenshell::geometry::settings::UseElementTypes>().get()) {
const std::string slabSuffix = (o->product() && o->product()->declaration().name() == "IfcSlab")
? differentiateSlabTypes(o->product())
: "";
@@ -464,7 +464,7 @@ void ColladaSerializer::ColladaExporter::endDocument() {
// In fact due the XML based nature of Collada and its dependency on library nodes,
// only at this point all objects are written to the stream.
materials.write();
bool use_hierarchy = serializer->settings().get(SerializerSettings::USE_ELEMENT_HIERARCHY);
bool use_hierarchy = serializer->geometry_settings().get<ifcopenshell::geometry::settings::UseElementHierarchy>().get();
std::set<std::string> geometries_written;
+3 -3
View File
@@ -219,9 +219,9 @@ private:
std::string unit_name;
float unit_magnitude;
public:
ColladaSerializer(const std::string& dae_filename, const SerializerSettings& settings)
: WriteOnlyGeometrySerializer(settings)
, exporter("IfcOpenShell", dae_filename, this, settings.precision >= 15)
ColladaSerializer(const std::string& dae_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings)
: WriteOnlyGeometrySerializer(geometry_settings, settings)
, exporter("IfcOpenShell", dae_filename, this, settings.get<ifcopenshell::geometry::settings::FloatingPointDigits>().get() >= 15)
{
exporter.serializer = this;
exporter.materials.serializer = this;
+2 -2
View File
@@ -44,8 +44,8 @@ static const uint32_t PRIM_TRIANGLES = 4;
static const uint32_t PRIM_TRIANGLE_STRIP = 5;
static const uint32_t PRIM_TRIANGLE_FAN = 6;
GltfSerializer::GltfSerializer(const std::string& filename, const SerializerSettings& settings)
: WriteOnlyGeometrySerializer(settings)
GltfSerializer::GltfSerializer(const std::string& filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings)
: WriteOnlyGeometrySerializer(geometry_settings, settings)
, filename_(filename)
, tmp_filename1_(filename + ".indices.tmp")
, tmp_filename2_(filename + ".vertices.tmp")
+1 -1
View File
@@ -39,7 +39,7 @@ private:
int writeMaterial(const ifcopenshell::geometry::taxonomy::style& style);
public:
GltfSerializer(const std::string& filename, const SerializerSettings& settings);
GltfSerializer(const std::string& filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings);
virtual ~GltfSerializer();
bool ready();
void writeHeader();
+21 -7
View File
@@ -53,8 +53,8 @@ herr_t print_stack(hid_t /*estack*/, void*) {
return 0;
}
HdfSerializer::HdfSerializer(const std::string& hdf_filename, const SerializerSettings& settings, bool read_only)
: GeometrySerializer(settings)
HdfSerializer::HdfSerializer(const std::string& hdf_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, bool read_only)
: GeometrySerializer(geometry_settings, settings)
, hdf_filename(hdf_filename)
, settings_(settings)
{
@@ -284,7 +284,6 @@ IfcGeom::Element* HdfSerializer::read(IfcParse::IfcFile& f, const std::string& g
auto representation_group = element_group.openGroup(representation_id_str);
std::string geom_id = read_scalar_attribute<std::string>(representation_group, "geom_id");
IfcGeom::ElementSettings element_settings(settings_, f.getUnit("LENGTHUNIT").second, type);
auto inst = f.instance_by_id(id)->as<IfcUtil::IfcBaseEntity>();
boost::shared_ptr<IfcGeom::Representation::BRep> brep_geometry;
@@ -305,6 +304,9 @@ IfcGeom::Element* HdfSerializer::read(IfcParse::IfcFile& f, const std::string& g
if (rt == READ_BREP && !brep_geometry) {
auto brepDataset = representation_group.openDataSet(DATASET_NAME_OCCT);
/*
// @todo
static const auto ignored_settings =
// Settings that do not affect storage of brep data
IfcGeom::IteratorSettings::DISABLE_TRIANGULATION | IfcGeom::IteratorSettings::USE_BREP_DATA |
@@ -325,6 +327,7 @@ IfcGeom::Element* HdfSerializer::read(IfcParse::IfcFile& f, const std::string& g
if (stored_settings != requested_settings && (stored_settings | IfcGeom::IteratorSettings::USE_WORLD_COORDS) != requested_settings) {
throw std::runtime_error("Settings mismatch");
}
*/
std::vector<brep_element> parts;
{
@@ -357,6 +360,9 @@ IfcGeom::Element* HdfSerializer::read(IfcParse::IfcFile& f, const std::string& g
shapes.push_back(IfcGeom::ConversionResult(part.id, matrix, new ifcopenshell::geometry::OpenCascadeShape(shp), style_ptr));
}
/*
// @todo
// World coordinates can be applied post-hoc
if (settings_.get(IfcGeom::IteratorSettings::USE_WORLD_COORDS) && !(stored_settings & IfcGeom::IteratorSettings::USE_WORLD_COORDS)) {
for (IfcGeom::ConversionResults::iterator it = shapes.begin(); it != shapes.end(); ++it) {
@@ -364,13 +370,16 @@ IfcGeom::Element* HdfSerializer::read(IfcParse::IfcFile& f, const std::string& g
}
trsf = ifcopenshell::geometry::taxonomy::make<ifcopenshell::geometry::taxonomy::matrix4>();
}
*/
brep_geometry = boost::shared_ptr<IfcGeom::Representation::BRep>(new IfcGeom::Representation::BRep(element_settings, geom_id, shapes));
brep_geometry = boost::shared_ptr<IfcGeom::Representation::BRep>(new IfcGeom::Representation::BRep(geometry_settings(), type, geom_id, shapes));
/*
// @todo
if (!settings_.get(IfcGeom::IteratorSettings::USE_WORLD_COORDS)) {
brep_cache_.insert({ representation_id_str, brep_geometry });
}
*/
}
if (rt == READ_TRIANGULATION && !triangulation_geometry) {
@@ -413,7 +422,8 @@ IfcGeom::Element* HdfSerializer::read(IfcParse::IfcFile& f, const std::string& g
}
triangulation_geometry = boost::shared_ptr<IfcGeom::Representation::Triangulation>(new IfcGeom::Representation::Triangulation(
element_settings,
geometry_settings_,
type,
geom_id,
verts,
faces,
@@ -432,7 +442,7 @@ IfcGeom::Element* HdfSerializer::read(IfcParse::IfcFile& f, const std::string& g
} else {
return new IfcGeom::TriangulationElement(
IfcGeom::Element(
element_settings,
geometry_settings_,
id,
parent_id,
name,
@@ -619,7 +629,11 @@ void HdfSerializer::write(const IfcGeom::BRepElement* o) {
H5::DataSpace attrdspace(H5S_SCALAR);
H5::Attribute att = brepDataset.createAttribute("settings", H5::PredType::NATIVE_UINT64, attrdspace);
/*
// @todo
uint64_t value = o->geometry().settings().get_raw();
*/
uint64_t value = 0;
att.write(H5::PredType::NATIVE_UINT64, &value);
}
+2 -2
View File
@@ -38,7 +38,7 @@ private:
const std::string hdf_filename;
unsigned int vcount_total;
H5::H5File file;
SerializerSettings settings_;
ifcopenshell::geometry::SerializerSettings settings_;
static const H5std_string DATASET_NAME_POSITIONS;
static const H5std_string DATASET_NAME_UVCOORDS;
@@ -92,7 +92,7 @@ private:
void write_style(surface_style_serialization& data, const ifcopenshell::geometry::taxonomy::style& s);
public:
HdfSerializer(const std::string& hdf_filename, const SerializerSettings& settings, bool read_only=false);
HdfSerializer(const std::string& hdf_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings, bool read_only=false);
virtual ~HdfSerializer() {}
bool ready();
void writeHeader();
+2 -2
View File
@@ -40,8 +40,8 @@ private:
public:
/// @note IGESControl_Controller::Init() must be called prior to instantiating IgesSerializer.
/// See http://tracker.dev.opencascade.org/view.php?id=23679 for more information.
IgesSerializer(const std::string& out_filename, const SerializerSettings& settings)
: OpenCascadeBasedSerializer(out_filename, settings)
IgesSerializer(const std::string& out_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings)
: OpenCascadeBasedSerializer(out_filename, geometry_settings, settings)
{}
virtual ~IgesSerializer() {}
void writeShape(const std::string&, const TopoDS_Shape& shape) {
+2 -2
View File
@@ -36,8 +36,8 @@ protected:
const std::string out_filename;
const char* getSymbolForUnitMagnitude(float mag);
public:
explicit OpenCascadeBasedSerializer(const std::string& out_filename, const SerializerSettings& settings)
: WriteOnlyGeometrySerializer(settings)
explicit OpenCascadeBasedSerializer(const std::string& out_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings)
: WriteOnlyGeometrySerializer(geometry_settings, settings)
, out_filename(out_filename)
{}
virtual ~OpenCascadeBasedSerializer() {}
+2 -2
View File
@@ -34,8 +34,8 @@ class StepSerializer : public OpenCascadeBasedSerializer
private:
STEPControl_Writer writer;
public:
explicit StepSerializer(const std::string& out_filename, const SerializerSettings& settings)
: OpenCascadeBasedSerializer(out_filename, settings)
explicit StepSerializer(const std::string& out_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& serializer_settings)
: OpenCascadeBasedSerializer(out_filename, geometry_settings, serializer_settings)
{}
virtual ~StepSerializer() {}
void writeShape(const std::string& name, const TopoDS_Shape& shape) {
+7 -8
View File
@@ -311,7 +311,7 @@ void SvgSerializer::write(path_object& p, const TopoDS_Shape& comp_or_wire, boos
ycoords.push_back(path.add(p2.Y()));
} else if (ty != STANDARD_TYPE(Geom_Line)) {
BRepAdaptor_Curve crv(edge);
GCPnts_QuasiUniformDeflection tessellater(crv, settings().deflection_tolerance());
GCPnts_QuasiUniformDeflection tessellater(crv, geometry_settings().get<ifcopenshell::geometry::settings::MesherLinearDeflection>().get());
// NB: Start at 2: 1-based and skip the first point, assume it coincides with p1.
for (int i = 2; i <= tessellater.NbPoints(); ++i) {
gp_Pnt pi = tessellater.Value(i);
@@ -379,9 +379,8 @@ namespace {
for (const auto& p : o->parents()) {
if (p->type() == "IfcBuildingStorey") {
try {
const IfcGeom::ElementSettings& settings = o->geometry().settings();
double e = *p->product()->get("Elevation");
double storey_elevation = e * settings.unit_magnitude();
double storey_elevation = e * o->geometry().settings().get<ifcopenshell::geometry::settings::LengthUnit>().get();
return std::make_pair(p->product(), storey_elevation);
} catch (...) {
continue;
@@ -1883,7 +1882,7 @@ void SvgSerializer::addTextAnnotations(const drawing_key& k) {
auto desc = (std::string) *ds;
if (object_type == "Text") {
auto mapping = ifcopenshell::geometry::impl::mapping_implementations().construct(file, settings_);
auto mapping = ifcopenshell::geometry::impl::mapping_implementations().construct(file, geometry_settings_);
auto item = mapping->map(*pl);
auto matrix = ifcopenshell::geometry::taxonomy::cast<ifcopenshell::geometry::taxonomy::matrix4>(item);
delete mapping;
@@ -2307,11 +2306,11 @@ std::string SvgSerializer::nameElement(const IfcUtil::IfcBaseEntity* storey, con
std::string SvgSerializer::idElement(const IfcUtil::IfcBaseEntity* elem) {
const std::string type = elem->declaration().is("IfcBuildingStorey") ? "storey" : "product";
const std::string name =
(settings().get(SerializerSettings::USE_ELEMENT_GUIDS)
(settings().get<ifcopenshell::geometry::settings::UseElementGuids>().get()
? static_cast<std::string>(*elem->get("GlobalId"))
: ((settings().get(SerializerSettings::USE_ELEMENT_NAMES) && !elem->get("Name")->isNull()))
: ((settings().get<ifcopenshell::geometry::settings::UseElementNames>().get() && !elem->get("Name")->isNull()))
? static_cast<std::string>(*elem->get("Name"))
: (settings().get(SerializerSettings::USE_ELEMENT_STEPIDS))
: (settings().get<ifcopenshell::geometry::settings::UseElementStepIds>().get())
? ("id-" + boost::lexical_cast<std::string>(elem->data().id()))
: IfcParse::IfcGlobalId(*elem->get("GlobalId")).formatted());
return type + "-" + name;
@@ -2340,7 +2339,7 @@ void SvgSerializer::setFile(IfcParse::IfcFile* f) {
auto storeys = f->instances_by_type("IfcBuildingStorey");
if (!storeys || storeys->size() == 0) {
auto mapping = ifcopenshell::geometry::impl::mapping_implementations().construct(file, settings_);
auto mapping = ifcopenshell::geometry::impl::mapping_implementations().construct(file, geometry_settings_);
std::vector<const IfcParse::declaration*> to_derive_from;
to_derive_from.push_back(f->schema()->declaration_by_name("IfcBuilding"));
+2 -2
View File
@@ -196,8 +196,8 @@ protected:
subtract_before_project subtraction_settings_;
public:
SvgSerializer(const stream_or_filename& out_filename, const SerializerSettings& settings)
: WriteOnlyGeometrySerializer(settings)
SvgSerializer(const stream_or_filename& out_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings)
: WriteOnlyGeometrySerializer(geometry_settings, settings)
, svg_file(out_filename)
, xmin(+std::numeric_limits<double>::infinity())
, ymin(+std::numeric_limits<double>::infinity())
+5 -5
View File
@@ -27,14 +27,14 @@
#include <boost/lexical_cast.hpp>
#include <iomanip>
WaveFrontOBJSerializer::WaveFrontOBJSerializer(const stream_or_filename& obj_filename, const stream_or_filename& mtl_filename, const SerializerSettings& settings)
: WriteOnlyGeometrySerializer(settings)
WaveFrontOBJSerializer::WaveFrontOBJSerializer(const stream_or_filename& obj_filename, const stream_or_filename& mtl_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings)
: WriteOnlyGeometrySerializer(geometry_settings, settings)
, obj_stream(obj_filename)
, mtl_stream(mtl_filename)
, vcount_total(1)
{
obj_stream.stream << std::setprecision(settings.precision);
mtl_stream.stream << std::setprecision(settings.precision);
obj_stream.stream << std::setprecision(settings.get<ifcopenshell::geometry::settings::FloatingPointDigits>().get());
mtl_stream.stream << std::setprecision(settings.get<ifcopenshell::geometry::settings::FloatingPointDigits>().get());
}
bool WaveFrontOBJSerializer::ready() {
@@ -91,7 +91,7 @@ void WaveFrontOBJSerializer::write(const IfcGeom::TriangulationElement* o)
{
obj_stream.stream << "g " << object_id(o) << "\n";
obj_stream.stream << "s 1" << "\n";
const bool isyup = settings().get(SerializerSettings::USE_Y_UP);
const bool isyup = settings().get<ifcopenshell::geometry::settings::UseYUp>().get();
const IfcGeom::Representation::Triangulation& mesh = o->geometry();
+1 -1
View File
@@ -35,7 +35,7 @@ private:
unsigned int vcount_total;
std::set<std::string> materials;
public:
WaveFrontOBJSerializer(const stream_or_filename& obj_filename, const stream_or_filename& mtl_filename, const SerializerSettings& settings);
WaveFrontOBJSerializer(const stream_or_filename& obj_filename, const stream_or_filename& mtl_filename, const ifcopenshell::geometry::Settings& geometry_settings, const ifcopenshell::geometry::SerializerSettings& settings);
virtual ~WaveFrontOBJSerializer() {}
bool ready();
void writeHeader();
@@ -35,7 +35,7 @@ private:
IfcParse::IfcFile* file;
// @todo
IfcGeom::IteratorSettings settings_;
ifcopenshell::geometry::Settings settings_;
ifcopenshell::geometry::abstract_mapping* mapping_;
public: