mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-12 10:33:20 +00:00
Drastic settings refactoring
This commit is contained in:
+47
-198
@@ -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>(§ion_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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,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;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
@@ -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 = "";
|
||||
|
||||
@@ -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*);
|
||||
};
|
||||
}}
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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)
|
||||
{}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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>()) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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):
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"
|
||||
%}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
%}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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() {}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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"));
|
||||
|
||||
@@ -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())
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user