diff --git a/src/ifcconvert/IfcConvert.cpp b/src/ifcconvert/IfcConvert.cpp index 8f1e285ea8..e0483f75df 100644 --- a/src/ifcconvert/IfcConvert.cpp +++ b/src/ifcconvert/IfcConvert.cpp @@ -26,16 +26,6 @@ * * ********************************************************************************/ -#include -#include -#include -#include - -#include -#include - -#include "../ifcgeom/IfcGeomIterator.h" - #include "../ifcconvert/ColladaSerializer.h" #include "../ifcconvert/IgesSerializer.h" #include "../ifcconvert/StepSerializer.h" @@ -43,35 +33,68 @@ #include "../ifcconvert/XmlSerializer.h" #include "../ifcconvert/SvgSerializer.h" +#include "../ifcgeom/IfcGeomIterator.h" + #include #include +#include +#include +#include + +#include +#include +#include +#include + +typedef double real_t; /**< @todo Will be configurable */ +#define INF std::numeric_limits::infinity() +real_t bounds_min[3] = { INF, INF, INF }; +real_t bounds_max[3] = { -INF, -INF, -INF }; + #if USE_VLD #include #endif -static std::string DEFAULT_EXTENSION = "obj"; +const std::string DEFAULT_EXTENSION = "obj"; -void printVersion() { - std::cerr << "IfcOpenShell IfcConvert " << IFCOPENSHELL_VERSION << std::endl; +void print_version() +{ + /// @todo Why cerr used for info prints? Change to cout. + std::cerr << "IfcOpenShell " << IfcSchema::Identifier << " IfcConvert " << IFCOPENSHELL_VERSION << std::endl; } -void printUsage(const boost::program_options::options_description& generic_options, const boost::program_options::options_description& geom_options) { - printVersion(); - std::cerr << "Usage: IfcConvert [options] []" << std::endl - << std::endl - << "Converts the geometry in an IFC file into one of the following formats:" << std::endl - << " .obj WaveFront OBJ (a .mtl file is also created)" << std::endl; -#ifdef WITH_OPENCOLLADA - std::cerr << " .dae Collada Digital Asset Exchange" << std::endl; +void print_usage() +{ + std::cerr << "Usage: IfcConvert [options] []" << "\n" + << "\n" + << "Converts the geometry in an IFC file into one of the following formats:" << "\n" + << " .obj WaveFront OBJ (a .mtl file is also created)" << "\n" +#ifdef WITH_OPENCOLLADA + << " .dae Collada Digital Assets Exchange" << "\n" #endif - std::cerr << " .stp STEP Standard for the Exchange of Product Data" << std::endl - << " .igs IGES Initial Graphics Exchange Specification" << std::endl - << " .xml XML Property definitions and decomposition tree" << std::endl - << " .svg SVG Scalable Vector Graphics (2d floor plan)" << std::endl - << std::endl - << "Command line options" << std::endl << generic_options << std::endl - << "Advanced options" << std::endl << geom_options << std::endl; + << " .stp STEP Standard for the Exchange of Product Data" << "\n" + << " .igs IGES Initial Graphics Exchange Specification" << "\n" + << " .xml XML Property definitions and decomposition tree" << "\n" + << " .svg SVG Scalable Vector Graphics (2D floor plan)" << "\n" + << "\n" + << "If no output filename given, ." + DEFAULT_EXTENSION + " will be used as the output file.\n" + << "\n" + << "Run 'IfcConvert --help' for more information." << std::endl; +} + +void print_options( + const boost::optional& generic_options, + const boost::optional& geom_options, + const boost::optional& serialization_options) +{ + if (generic_options) + std::cerr << "\nCommand line options\n" << generic_options; + if (geom_options) + std::cerr << "\nGeometry options\n" << geom_options; + if (serialization_options) + std::cerr << "\nSerialization options\n" << serialization_options; + std::cerr << std::endl; } std::string change_extension(const std::string& fn, const std::string& ext) { @@ -89,7 +112,7 @@ void write_log(); int main(int argc, char** argv) { boost::program_options::options_description generic_options; generic_options.add_options() - ("help", "display usage information") + ("help,h", "display usage information") ("version", "display version information") ("verbose,v", "more verbose output"); @@ -98,8 +121,8 @@ int main(int argc, char** argv) { ("input-file", boost::program_options::value(), "input IFC file") ("output-file", boost::program_options::value(), "output geometry file"); - std::string bounds; - std::vector entity_vector; + std::vector entity_vector/*, names*/; + //double deflection_tolerance; boost::program_options::options_description geom_options; geom_options.add_options() ("plan", @@ -142,20 +165,48 @@ int main(int argc, char** argv) { ("disable-opening-subtractions", "Specifies whether to disable the boolean subtraction of " "IfcOpeningElement Representations from their RelatingElements.") - ("bounds", boost::program_options::value(&bounds), - "Specifies the bounding rectangle, for example 512x512, to which the " - "output will be scaled. Only used when converting to SVG.") ("include", - "Specifies that the entities listed after --entities are to be included") + "Specifies that the entities listed after --entities or --names are to be included") ("exclude", - "Specifies that the entities listed after --entities are to be excluded") - ("entities", boost::program_options::value< std::vector >(&entity_vector)->multitoken(), + "Specifies that the entities listed after --entities or --names are to be excluded") + ("entities", boost::program_options::value< std::vector >(&entity_vector)->multitoken(), "A list of entities that should be included in or excluded from the " - "geometrical output, depending on whether --ignore or --include is " - "specified. Defaults to IfcOpeningElement and IfcSpace to be excluded."); - + "geometrical output, depending on whether --exclude or --include is specified. " + " Defaults to IfcOpeningElement and IfcSpace to be excluded. " + "The names are handled case-insensitively. Cannot be placed right before input file argument.") + /*("names", boost::program_options::value< std::vector >(&names)->multitoken(), + "A list of names or wildcard patterns that should be included in or excluded from the " + "geometrical output, depending on whether --exclude or --include is specified. " + "The names are handled case-sensitively. Cannot be placed right before input file argument.") + ("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", boost::program_options::value(&deflection_tolerance), + "Sets the deflection tolerance of the mesher, 1e-3 by default if not specified.")*/; + + std::string bounds; + boost::program_options::options_description serializer_options; + serializer_options.add_options() + ("bounds", boost::program_options::value(&bounds), + "Specifies the bounding rectangle, for example 512x512, to which the " + "output will be scaled. Only used when converting to SVG.") + /*("use-names", + "Use entity names instead of unique IDs for naming objects and materials " + "upon serialization. Applicable for .obj and .dae output.") + ("use-guids", + "Use entity GUIDs instead of unique IDs for naming objects upon serialization. " + "Overrides possible usage of --use-names for objects but not for materials." + "Applicable for .obj and .dae output.") + ("center-model", + "Centers the models upon serialization by applying the center point of " + "the scene bounds as an offset. Applicable only for .dae output currently.") + ("generate-uvs", + "Generates UVs (texture coordinates) by using simple box projection. Requires normals. Not guaranteed to work " + "properly if used with --weld-vertices. Applicable only for .dae output currently.")*/; + boost::program_options::options_description cmdline_options; - cmdline_options.add(generic_options).add(fileio_options).add(geom_options); + cmdline_options.add(generic_options).add(fileio_options).add(geom_options).add(serializer_options); boost::program_options::positional_options_description positional_options; positional_options.add("input-file", 1); @@ -167,21 +218,30 @@ int main(int argc, char** argv) { options(cmdline_options).positional(positional_options).run(), vmap); } catch (const boost::program_options::unknown_option& e) { std::cerr << "[Error] Unknown option '" << e.get_option_name() << "'" << std::endl << std::endl; - // Usage information will be emitted below + print_usage(); + return 1; } catch (...) { // Catch other errors such as invalid command line syntax + print_usage(); + return 1; } boost::program_options::notify(vmap); - if (vmap.count("version")) { - printVersion(); - return 0; - } else if (vmap.count("help") || !vmap.count("input-file")) { - printUsage(generic_options, geom_options); - return vmap.count("help") ? 0 : 1; + print_version(); + + if (vmap.count("version")) { + return 0; + } else if (vmap.count("help")) { + print_usage(); + print_options(generic_options, geom_options, serializer_options); + return 0; + } else if (!vmap.count("input-file")) { + std::cerr << "[Error] Input file not specified" << std::endl; + print_usage(); + return 1; } else if (vmap.count("include") && vmap.count("exclude")) { - std::cerr << "[Error] --include and --ignore can not be specified together" << std::endl; - printUsage(generic_options, geom_options); + std::cerr << "[Error] --include and --exclude can not be specified together" << std::endl; + print_options(boost::none, geom_options, boost::none); return 1; } @@ -197,6 +257,12 @@ int main(int argc, char** argv) { bool include_entities = vmap.count("include") != 0; const bool include_plan = vmap.count("plan") != 0; const bool include_model = vmap.count("model") != 0 || (!include_plan); + //const bool use_names = vmap.count("use-names") != 0; + //const bool use_guids = vmap.count("use-guids") != 0 ; + //const bool no_normals = vmap.count("no-normals") != 0 ; + //const bool center_model = vmap.count("center-model") != 0 ; + //const bool generate_uvs = vmap.count("generate-uvs") != 0 ; + //const bool deflection_tolerance_specified = vmap.count("deflection-tolerance") != 0 ; boost::optional bounding_width, bounding_height; if (vmap.count("bounds") == 1) { int w, h; @@ -205,18 +271,14 @@ int main(int argc, char** argv) { bounding_height = h; } else { std::cerr << "[Error] Invalid use of --bounds" << std::endl; - printUsage(generic_options, geom_options); + print_options(boost::none, boost::none, serializer_options); return 1; } } // Gets the set ifc types to be ignored from the command line. - std::set entities; - for (std::vector::const_iterator it = entity_vector.begin(); it != entity_vector.end(); ++it) { - const std::string& mixed_case_type = *it; - entities.insert(boost::to_lower_copy(mixed_case_type)); - } - + std::set entities(entity_vector.begin(), entity_vector.end()); + const std::string input_filename = vmap["input-file"].as(); // If no output filename is specified a Wavefront OBJ file will be output // to maintain backwards compatibility with the obsolete IfcObj executable. @@ -225,7 +287,8 @@ int main(int argc, char** argv) { : change_extension(input_filename, DEFAULT_EXTENSION); if (output_filename.size() < 5) { - printUsage(generic_options, geom_options); + std::cerr << "[Error] Invalid or unsupported output file given " << output_filename << std::endl; + print_usage(); return 1; } @@ -234,12 +297,12 @@ int main(int argc, char** argv) { // If no entities are specified these are the defaults to skip from output if (entity_vector.empty()) { + entities.insert("IfcSpace"); + /// @todo Document in --help that SVG uses "--include --entities IfcSpace" by default. if (output_extension == ".svg") { - entities.insert("ifcspace"); include_entities = true; } else { - entities.insert("ifcopeningelement"); - entities.insert("ifcspace"); + entities.insert("IfcOpeningElement"); } } @@ -264,7 +327,7 @@ int main(int argc, char** argv) { } IfcGeom::IteratorSettings 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); settings.set(IfcGeom::IteratorSettings::WELD_VERTICES, weld_vertices); @@ -276,6 +339,13 @@ int main(int argc, char** argv) { settings.set(IfcGeom::IteratorSettings::DISABLE_OPENING_SUBTRACTIONS, disable_opening_subtractions); settings.set(IfcGeom::IteratorSettings::INCLUDE_CURVES, include_plan); settings.set(IfcGeom::IteratorSettings::EXCLUDE_SOLIDS_AND_SURFACES, !include_model); + //settings.set(IfcConvertSettings::USE_NAMES, use_names); + //settings.set(IfcConvertSettings::USE_GUIDS, use_guids); + //settings.set(IfcGeom::IteratorSettings::NO_NORMALS, no_normals); + //settings.set(IfcConvertSettings::CENTER_MODEL, center_model); + //settings.set(IfcConvertSettings::GENERATE_UVS, generate_uvs); + //if (deflection_tolerance_specified) + // settings.set_deflection_tolerance(deflection_tolerance); GeometrySerializer* serializer; if (output_extension == ".obj") { @@ -300,15 +370,12 @@ int main(int argc, char** argv) { settings.set(IfcGeom::IteratorSettings::DISABLE_TRIANGULATION, true); serializer = new SvgSerializer(output_filename); if (bounding_width && bounding_height) { - ((SvgSerializer*) serializer)->setBoundingRectangle( - static_cast(*bounding_width), - static_cast(*bounding_height) - ); + static_cast(serializer)->setBoundingRectangle(*bounding_width, *bounding_height); } } else { Logger::Message(Logger::LOG_ERROR, "Unknown output filename extension"); write_log(); - printUsage(generic_options, geom_options); + print_usage(); return 1; } @@ -316,16 +383,18 @@ int main(int argc, char** argv) { if (weld_vertices) { Logger::Message(Logger::LOG_NOTICE, "Weld vertices setting ignored when writing STEP or IGES files"); } - settings.disable_triangulation() = true; + settings.set(IfcGeom::IteratorSettings::DISABLE_TRIANGULATION, true); } - IfcGeom::Iterator context_iterator(settings, input_filename); + IfcGeom::Iterator context_iterator(settings, input_filename); try { if (include_entities) { context_iterator.includeEntities(entities); + //context_iterator.include_entity_names(names); } else { context_iterator.excludeEntities(entities); + //context_iterator.exclude_entity_names(names); } } catch (const IfcParse::IfcException& e) { std::cout << "[Error] " << e.what() << std::endl; @@ -347,21 +416,18 @@ int main(int argc, char** argv) { return 1; } - serializer->setFile(context_iterator.getFile()); - if (convert_back_units) { - serializer->setUnitNameAndMagnitude(context_iterator.getUnitName(), static_cast(context_iterator.getUnitMagnitude())); + serializer->setUnitNameAndMagnitude(context_iterator.getUnitName(), static_cast(context_iterator.getUnitMagnitude())); } else { serializer->setUnitNameAndMagnitude("METER", 1.0f); } serializer->writeHeader(); - std::set materials; - int old_progress = -1; Logger::Status("Creating geometry..."); + std::vector* > geometries; // The functions IfcGeom::Iterator::get() and IfcGeom::Iterator::next() // wrap an iterator of all geometrical products in the Ifc file. // IfcGeom::Iterator::get() returns an IfcGeom::TriangulationElement or @@ -373,30 +439,65 @@ int main(int argc, char** argv) { // true return value guarantees that a successfully processed product is // available. do { - const IfcGeom::Element* geom_object = context_iterator.get(); - - if (serializer->isTesselated()) { - serializer->write(static_cast*>(geom_object)); - } else { - serializer->write(static_cast*>(geom_object)); - } - - const int progress = context_iterator.progress() / 2; - if (old_progress!= progress) Logger::ProgressBar(progress); - old_progress = progress; - - } while (context_iterator.next()); + IfcGeom::Element *geom_object = context_iterator.get(true); // true == take ownership, we will clean up ourselves + geometries.push_back(geom_object); + const int progress = context_iterator.progress() / 2; + if (old_progress != progress) Logger::ProgressBar(progress); + old_progress = progress; + + //if (center_model) { + // const std::vector& pos = geom_object->transformation().matrix().data(); + // bounds_min[0] = std::min(bounds_min[0], pos[9]); + // bounds_min[1] = std::min(bounds_min[1], pos[10]); + // bounds_min[2] = std::min(bounds_min[2], pos[11]); + // bounds_max[0] = std::max(bounds_max[0], pos[9]); + // bounds_max[1] = std::max(bounds_max[1], pos[10]); + // bounds_max[2] = std::max(bounds_max[2], pos[11]); + //} + } while (context_iterator.next()); + + Logger::Status("\rDone creating geometry (" + boost::lexical_cast(geometries.size()) + + " objects) "); + + //if (center_model) { + // settings.offset[0] = -(bounds_min[0] + bounds_max[0]) * real_t(0.5); + // settings.offset[1] = -(bounds_min[1] + bounds_max[1]) * real_t(0.5); + // settings.offset[2] = -(bounds_min[2] + bounds_max[2]) * real_t(0.5); + // //printf("Bounds min. (%g, %g, %g)\n", bounds_min[0], bounds_min[1], bounds_min[2]); + // //printf("Bounds max. (%g, %g, %g)\n", bounds_max[0], bounds_max[1], bounds_max[2]); + // printf("Using model offset (%g, %g, %g)\n", settings.offset[0], settings.offset[1], settings.offset[2]); //TODO Logger::Message(Logger::LOG_NOTICE, ...); + //} + + Logger::Status("Serializing geometry..."); + + //serializer->setSettings(settings); + + if (serializer->isTesselated()) { // isTesselated() doesn't change at run-time + foreach(const IfcGeom::Element* geom, geometries) { + serializer->write(static_cast*>(geom)); + delete geom; + } + } else { + foreach(const IfcGeom::Element* geom, geometries) { + serializer->write(static_cast*>(geom)); + delete geom; + } + } serializer->finalize(); - delete serializer; - Logger::Status("\rDone creating geometry "); + Logger::Status("\rDone serializing geometry "); + + delete serializer; write_log(); time(&end); - int dif = (int) difftime (end,start); - printf ("\nConversion took %d seconds\n", dif ); + int seconds = (int)difftime(end, start); + if (seconds < 60) + printf("\nConversion took %d seconds\n", seconds); // TODO Logger::Message(Logger::LOG_NOTICE, ...); + else + printf("\nConversion took %d minute(s) %d seconds\n", seconds/60, seconds%60); // TODO Logger::Message(Logger::LOG_NOTICE, ...); return 0; } @@ -404,7 +505,6 @@ int main(int argc, char** argv) { void write_log() { std::string log = log_stream.str(); if (!log.empty()) { - std::cerr << std::endl << "Log:" << std::endl; - std::cerr << log << std::endl; + std::cerr << "\n" << "Log:\n" << log << std::endl; } -} \ No newline at end of file +} diff --git a/src/ifcconvert/OpenCascadeBasedSerializer.cpp b/src/ifcconvert/OpenCascadeBasedSerializer.cpp index 2dbb642c3d..2f9ea54839 100644 --- a/src/ifcconvert/OpenCascadeBasedSerializer.cpp +++ b/src/ifcconvert/OpenCascadeBasedSerializer.cpp @@ -43,7 +43,7 @@ void OpenCascadeBasedSerializer::write(const IfcGeom::BRepElement* o) { const gp_Trsf& o_trsf = o->transformation().data(); gtrsf.PreMultiply(o_trsf); - if (o->geometry().settings().convert_back_units()) { + if (o->geometry().settings().get(IfcGeom::IteratorSettings::CONVERT_BACK_UNITS)) { gp_Trsf scale; scale.SetScaleFactor(1.0 / o->geometry().settings().unit_magnitude()); gtrsf.PreMultiply(scale); diff --git a/src/ifcconvert/XmlSerializer.cpp b/src/ifcconvert/XmlSerializer.cpp index 83be2a66e5..fbec20e6c8 100644 --- a/src/ifcconvert/XmlSerializer.cpp +++ b/src/ifcconvert/XmlSerializer.cpp @@ -21,7 +21,6 @@ #include #include -#include #include #include "XmlSerializer.h" @@ -256,16 +255,16 @@ void XmlSerializer::finalize() { ptree root, header, decomposition, properties; // Write the SPF header as XML nodes. - BOOST_FOREACH(const std::string& s, file->header().file_description().description()) { + foreach(const std::string& s, file->header().file_description().description()) { header.add_child("file_description.description", ptree(s)); } - BOOST_FOREACH(const std::string& s, file->header().file_name().author()) { + foreach(const std::string& s, file->header().file_name().author()) { header.add_child("file_name.author", ptree(s)); } - BOOST_FOREACH(const std::string& s, file->header().file_name().organization()) { + foreach(const std::string& s, file->header().file_name().organization()) { header.add_child("file_name.organization", ptree(s)); } - BOOST_FOREACH(const std::string& s, file->header().file_schema().schema_identifiers()) { + foreach(const std::string& s, file->header().file_schema().schema_identifiers()) { header.add_child("file_schema.schema_identifiers", ptree(s)); } header.put("file_description.implementation_level", file->header().file_description().implementation_level()); @@ -298,4 +297,4 @@ void XmlSerializer::finalize() { boost::property_tree::xml_writer_settings settings('\t', 1); #endif boost::property_tree::write_xml(xml_filename, root, std::locale(), settings); -} \ No newline at end of file +} diff --git a/src/ifcgeom/IfcGeomElement.h b/src/ifcgeom/IfcGeomElement.h index c65d890a94..f5e1cf6eeb 100644 --- a/src/ifcgeom/IfcGeomElement.h +++ b/src/ifcgeom/IfcGeomElement.h @@ -44,7 +44,7 @@ namespace IfcGeom { for(int i = 1; i < 5; ++i) { for (int j = 1; j < 4; ++j) { const double trsf_value = trsf.Value(j,i); - const double matrix_value = i == 4 && settings.convert_back_units() + const double matrix_value = i == 4 && settings.get(IteratorSettings::CONVERT_BACK_UNITS) ? trsf_value / settings.unit_magnitude() : trsf_value; _data.push_back(static_cast

(matrix_value)); diff --git a/src/ifcgeom/IfcGeomFunctions.cpp b/src/ifcgeom/IfcGeomFunctions.cpp index 14dd47230f..8123bcb041 100644 --- a/src/ifcgeom/IfcGeomFunctions.cpp +++ b/src/ifcgeom/IfcGeomFunctions.cpp @@ -1103,11 +1103,11 @@ IfcGeom::BRepElement

* IfcGeom::Kernel::create_brep_for_representation_and_pro const std::string product_type = IfcSchema::Type::ToString(product->type()); ElementSettings element_settings(settings, getValue(GV_LENGTH_UNIT), product_type); - if ( !settings.disable_opening_subtractions() && openings && openings->size() ) { + if (!settings.get(IfcGeom::IteratorSettings::DISABLE_OPENING_SUBTRACTIONS) && openings && openings->size()) { IfcGeom::IfcRepresentationShapeItems opened_shapes; try { #if OCC_VERSION_HEX < 0x60900 - const bool faster_booleans = settings.faster_booleans(); + const bool faster_booleans = settings.get(IteratorSettings::FASTER_BOOLEANS); #else const bool faster_booleans = true; #endif @@ -1123,14 +1123,14 @@ IfcGeom::BRepElement

* IfcGeom::Kernel::create_brep_for_representation_and_pro } catch(...) { Logger::Message(Logger::LOG_ERROR,"Error processing openings for:",product->entity); } - if ( settings.use_world_coords() ) { + if (settings.get(IteratorSettings::USE_WORLD_COORDS)) { for ( IfcGeom::IfcRepresentationShapeItems::iterator it = opened_shapes.begin(); it != opened_shapes.end(); ++ it ) { it->prepend(trsf); } trsf = gp_Trsf(); } shape = new IfcGeom::Representation::BRep(element_settings, representation->entity->id(), opened_shapes); - } else if ( settings.use_world_coords() ) { + } else if (settings.get(IteratorSettings::USE_WORLD_COORDS)) { for ( IfcGeom::IfcRepresentationShapeItems::iterator it = shapes.begin(); it != shapes.end(); ++ it ) { it->prepend(trsf); } diff --git a/src/ifcgeom/IfcGeomIterator.h b/src/ifcgeom/IfcGeomIterator.h index 30bf6fe9cb..36bda5e5dd 100644 --- a/src/ifcgeom/IfcGeomIterator.h +++ b/src/ifcgeom/IfcGeomIterator.h @@ -86,6 +86,9 @@ namespace IfcGeom { template class Iterator { private: + Iterator(const Iterator&); // N/I + Iterator& operator=(const Iterator&); // N/I + Kernel kernel; IteratorSettings settings; @@ -121,6 +124,7 @@ namespace IfcGeom { } } + std::set names_to_include_or_exclude; // regex containing a name or a wildcard expression std::set entities_to_include_or_exclude; bool include_entities_in_processing; @@ -148,7 +152,7 @@ namespace IfcGeom { } catch (...) {} std::set context_types; - if (!settings.exclude_solids_and_surfaces()) { + if (!settings.get(IteratorSettings::EXCLUDE_SOLIDS_AND_SURFACES)) { // Really this should only be 'Model', as per // the standard 'Design' is deprecated. So, // just for backwards compatibility: @@ -157,7 +161,7 @@ namespace IfcGeom { // DDS likes to output 'model view' context_types.insert("model view"); } - if (settings.include_curves()) { + if (settings.get(IteratorSettings::INCLUDE_CURVES)) { context_types.insert("plan"); } @@ -250,36 +254,46 @@ namespace IfcGeom { return true; } - int progress() { - return 100 * done / total; - } + int progress() const { return 100 * done / total; } - const std::string& getUnitName() { - return unit_name; - } + const std::string& getUnitName() const { return unit_name; } - const P getUnitMagnitude() { - return unit_magnitude; - } + P getUnitMagnitude() const { return unit_magnitude; } - const std::string getLog() { - return Logger::GetLog(); - } + std::string getLog() const { return Logger::GetLog(); } - IfcParse::IfcFile* getFile() { - return ifc_file; - } + IfcParse::IfcFile* getFile() const { return ifc_file; } + /// @note Entity names are handled case-insensitively. void includeEntities(const std::set& entities) { populate_set(entities); include_entities_in_processing = true; } + /// @note Entity names are handled case-insensitively. void excludeEntities(const std::set& entities) { populate_set(entities); include_entities_in_processing = false; } + // Arbitrary names or wildcard expressions are handled case-sensitively. + void include_entity_names(const std::vector& names) + { + names_to_include_or_exclude.clear(); + foreach(const std::string &name, names) + names_to_include_or_exclude.insert(IfcUtil::wildcard_string_to_regex(name)); + include_entities_in_processing = true; + } + + // Arbitrary names or wildcard expressions are handled case-sensitively. + void exclude_entity_names(const std::vector& names) + { + names_to_include_or_exclude.clear(); + foreach(const std::string &name, names) + names_to_include_or_exclude.insert(IfcUtil::wildcard_string_to_regex(name)); + include_entities_in_processing = false; + } + private: // Move to the next IfcRepresentation void _nextShape() { @@ -330,6 +344,14 @@ namespace IfcGeom { break; } } + + foreach(const boost::regex& r, names_to_include_or_exclude) { + if (boost::regex_match((*it)->Name(), r)) { + found = true; + break; + } + } + if (found == include_entities_in_processing) { ifcproducts->push(*jt); } @@ -382,13 +404,17 @@ namespace IfcGeom { return create(); } - Element

* get() { - // TODO: Test settings and throw - if (current_triangulation) return current_triangulation; - else if (current_serialization) return current_serialization; - else if (current_shape_model) return current_shape_model; - else return 0; - } + /// Gets or takes the representation of the current geometrical entity. + /// @param take_ownership Pass in 'true' as if wishing to maintain the element lifetime yourself. + Element

* get(bool take_ownership = false) + { + // TODO: Test settings and throw + Element

* ret = 0; + if (current_triangulation) { ret = current_triangulation; if (take_ownership) current_triangulation = 0; } + else if (current_serialization) { ret = current_serialization; if (take_ownership) current_serialization = 0; } + else if (current_shape_model) { ret = current_shape_model; if (take_ownership) current_shape_model = 0; } + return ret; + } const Element

* getObject(int id) { @@ -430,12 +456,12 @@ namespace IfcGeom { current_shape_model = create_shape_model_for_next_entity(); } catch (...) {} if (!current_shape_model) return false; - if (settings.use_brep_data()) { + if (settings.get(IteratorSettings::USE_BREP_DATA)) { try { current_serialization = new SerializedElement

(*current_shape_model); } catch (...) {} return !!current_serialization; - } else if (!settings.disable_triangulation()) { + } else if (!settings.get(IteratorSettings::DISABLE_TRIANGULATION)) { try { current_triangulation = new TriangulationElement

(*current_shape_model); } catch (...) {} @@ -457,8 +483,8 @@ namespace IfcGeom { unit_name = "METER"; unit_magnitude = 1.f; - kernel.setValue(IfcGeom::Kernel::GV_MAX_FACES_TO_SEW, settings.sew_shells() ? 1000 : -1); - kernel.setValue(IfcGeom::Kernel::GV_DIMENSIONALITY, (settings.include_curves() ? (settings.exclude_solids_and_surfaces() ? -1. : 0.) : +1.)); + kernel.setValue(IfcGeom::Kernel::GV_MAX_FACES_TO_SEW, settings.get(IteratorSettings::SEW_SHELLS) ? 1000 : -1); + kernel.setValue(IfcGeom::Kernel::GV_DIMENSIONALITY, (settings.get(IteratorSettings::INCLUDE_CURVES) ? (settings.get(IteratorSettings::EXCLUDE_SOLIDS_AND_SURFACES) ? -1. : 0.) : +1.)); } bool owns_ifc_file; diff --git a/src/ifcgeom/IfcGeomIteratorSettings.h b/src/ifcgeom/IfcGeomIteratorSettings.h index 7adc5e9463..3d65fc3d8f 100644 --- a/src/ifcgeom/IfcGeomIteratorSettings.h +++ b/src/ifcgeom/IfcGeomIteratorSettings.h @@ -20,160 +20,130 @@ #ifndef IFCGEOMITERATORSETTINGS_H #define IFCGEOMITERATORSETTINGS_H -#include - #include "../ifcparse/IfcException.h" -namespace IfcGeom { +namespace IfcGeom +{ + class IteratorSettings + { + public: + /// Enumeration of setting identifiers. These settings define the + /// behaviour of various aspects of IfcOpenShell. + enum Setting + { + /// 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 artifacts in rendering applications. + WELD_VERTICES = 1, + /// 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. + USE_WORLD_COORDS = 1 << 1, + /// Internally IfcOpenShell measures everything in meters. This settings + /// specifies whether to convert IfcGeomObjects back to the units in which + /// the geometry in the IFC file is specified. + CONVERT_BACK_UNITS = 1 << 2, + /// Specifies whether to use the Open Cascade BREP format for representation + /// items rather than to create triangle meshes. This is useful is IfcOpenShell + /// is used as a library in an application that is also built on Open Cascade. + USE_BREP_DATA = 1 << 3, + /// Specifies whether to sew IfcConnectedFaceSets (open and closed shells) to + /// TopoDS_Shells or whether to keep them as a loose collection of faces. + SEW_SHELLS = 1 << 4, + /// Specifies whether to compose IfcOpeningElements into a single compound + /// in order to speed up the processing of opening subtractions. + FASTER_BOOLEANS = 1 << 5, + /// Disables the subtraction of IfcOpeningElement representations from + /// the related building element representations. + DISABLE_OPENING_SUBTRACTIONS = 1 << 6, + /// Disables the triangulation of the topological representations. Useful if + /// the client application understands Open Cascade's native format. + DISABLE_TRIANGULATION = 1 << 7, + /// Applies default materials to entity instances without a surface style. + APPLY_DEFAULT_MATERIALS = 1 << 8, + /// Specifies whether to include subtypes of IfcCurve. + INCLUDE_CURVES = 1 << 9, + /// Specifies whether to exclude subtypes of IfcSolidModel and IfcSurface. + EXCLUDE_SOLIDS_AND_SURFACES = 1 << 10, + /// 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. + //NO_NORMALS = 1 << 11, + /// Use entity names instead of unique IDs for naming objects and materials. + /// Applicable for .obj and .dae output. + //USE_NAMES = 1 << 12, + /// Use entity GUIDs instead of unique IDs for naming objects. + /// Overrides possible usage of --use-names for objects but not for materials. + /// Applicable for .obj and .dae output. + //USE_GUIDS = 1 << 13, + /// Centers the models upon serialization by the applying the center point of + /// the scene bounds as an offset. Applicable only for .dae output currently. + //CENTER_MODEL = 1 << 14, + /// Generates UVs by using simple box projection. Requires normals. + /// Applicable only for .dae output currently. + //GENERATE_UVS = 1 << 15, + //NUM_SETTINGS = 15 + }; + /// Used to store logical OR combination of setting flags. + typedef unsigned SettingField; - class IteratorSettings { - public: - // Enumeration of setting identifiers. These settings define the - // behaviour of various aspects of IfcOpenShell. + IteratorSettings() + : settings_(WELD_VERTICES) // OR options that default to true here + , deflection_tolerance_(1.e-3) + { + memset(offset, 0, sizeof(offset)); + } - // 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 artifacts in rendering applications. - static const int WELD_VERTICES = 1; - // 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 const int USE_WORLD_COORDS = 2; - // Internally IfcOpenShell measures everything in meters. This settings - // specifies whether to convert IfcGeomObjects back to the units in which - // the geometry in the IFC file is specified. - static const int CONVERT_BACK_UNITS = 3; - // Specifies whether to use the Open Cascade BREP format for representation - // items rather than to create triangle meshes. This is useful is IfcOpenShell - // is used as a library in an application that is also built on Open Cascade. - static const int USE_BREP_DATA = 4; - // Specifies whether to sew IfcConnectedFaceSets (open and closed shells) to - // TopoDS_Shells or whether to keep them as a loose collection of faces. - static const int SEW_SHELLS = 5; - // Specifies whether to compose IfcOpeningElements into a single compound - // in order to speed up the processing of opening subtractions. - static const int FASTER_BOOLEANS = 6; - // Disables the subtraction of IfcOpeningElement representations from - // the related building element representations. - static const int DISABLE_OPENING_SUBTRACTIONS = 8; - // Disables the triangulation of the topological representations. Useful if - // the client application understands Open Cascade's native format. - static const int DISABLE_TRIANGULATION = 9; - // Applies default materials to entity instances without a surface style. - static const int APPLY_DEFAULT_MATERIALS = 10; - // Specifies whether to include subtypes of IfcCurve. - static const int INCLUDE_CURVES = 11; - // Specifies whether to exclude subtypes of IfcSolidModel and IfcSurface. - static const int EXCLUDE_SOLIDS_AND_SURFACES = 12; + /// Optional offset that is applied to serialized objects, (0,0,0) by default. + double offset[3]; - // End of settings enumeration. + /// Note that this is independent of the IFC length unit, one millimeter by default. + double deflection_tolerance() const { return deflection_tolerance_; } + /// @todo Sanity check for the value + void set_deflection_tolerance(double value) { deflection_tolerance_ = value; } - private: - bool _weld_vertices, _use_world_coords, _convert_back_units, _use_brep_data, _sew_shells, _faster_booleans, _disable_opening_subtractions, _disable_triangulation, _apply_default_materials, _include_curves, _exclude_solids_and_surfaces; - double _deflection_tolerance; - public: - IteratorSettings() - : _weld_vertices(true) - , _use_world_coords(false) - , _convert_back_units(false) - , _use_brep_data(false) - , _sew_shells(false) - , _faster_booleans(false) - , _disable_opening_subtractions(false) - , _disable_triangulation(false) - , _apply_default_materials(false) - , _include_curves(false) - , _exclude_solids_and_surfaces(false) - // TODO: Make deflection tolerance into a command line argument - // For now, stick to one millimeter. Note that this is independent of the IFC length unit. - , _deflection_tolerance(1.e-3) - {} + bool get(SettingField setting) const + { + /// @todo If unknown setting value/combination: throw IfcParse::IfcException("Invalid IteratorSetting")? + return (settings_ & setting) != 0; + } - const bool& weld_vertices() const { return _weld_vertices; } - bool& weld_vertices() { return _weld_vertices; } - const bool& use_world_coords() const { return _use_world_coords; } - bool& use_world_coords() { return _use_world_coords; } - const bool& convert_back_units() const { return _convert_back_units; } - bool& convert_back_units() { return _convert_back_units; } - const bool& use_brep_data() const { return _use_brep_data; } - bool& use_brep_data() { return _use_brep_data; } - const bool& sew_shells() const { return _sew_shells; } - bool& sew_shells() { return _sew_shells; } - const bool& faster_booleans() const { return _faster_booleans; } - bool& faster_booleans() { return _faster_booleans; } - const bool& disable_opening_subtractions() const { return _disable_opening_subtractions; } - bool& disable_opening_subtractions() { return _disable_opening_subtractions; } - const bool& disable_triangulation() const { return _disable_triangulation; } - bool& disable_triangulation() { return _disable_triangulation; } - const bool& apply_default_materials() const { return _apply_default_materials; } - bool& apply_default_materials() { return _apply_default_materials; } - const bool& include_curves() const { return _include_curves; } - bool& include_curves() { return _include_curves; } - const bool& exclude_solids_and_surfaces() const { return _exclude_solids_and_surfaces; } - bool& exclude_solids_and_surfaces() { return _exclude_solids_and_surfaces; } - - const double& deflection_tolerance() const { return _deflection_tolerance; } - double& deflection_tolerance() { return _deflection_tolerance; } - - void set(int setting, bool value) { - switch (setting) { - case USE_WORLD_COORDS: - _use_world_coords = value; - break; - case WELD_VERTICES: - _weld_vertices = value; - break; - case CONVERT_BACK_UNITS: - _convert_back_units = value; - break; - case USE_BREP_DATA: - _use_brep_data = value; - break; - case FASTER_BOOLEANS: - _faster_booleans = value; - break; - case SEW_SHELLS: - _sew_shells = value; - break; - case DISABLE_OPENING_SUBTRACTIONS: - _disable_opening_subtractions = value; - break; - case DISABLE_TRIANGULATION: - _disable_triangulation = value; - break; - case APPLY_DEFAULT_MATERIALS: - _apply_default_materials = value; - break; - case INCLUDE_CURVES: - _include_curves = value; - break; - case EXCLUDE_SOLIDS_AND_SURFACES: - _exclude_solids_and_surfaces = value; - break; - default: throw IfcParse::IfcException("Invalid IteratorSetting"); - } - } - }; - - class ElementSettings : public IteratorSettings { - private: - double _unit_magnitude; - std::string _element_type; - public: - ElementSettings(const IteratorSettings& settings, - double unit_magnitude, - const std::string& element_type) - : IteratorSettings(settings) - , _unit_magnitude(unit_magnitude) - , _element_type(element_type) - {} + void set(SettingField setting, bool value) + { + /// @todo If unknown setting value/combination: throw IfcParse::IfcException("Invalid IteratorSetting")? + if (value) { + settings_ |= setting; + } else { + settings_ &= ~setting; + } + } - const double& unit_magnitude() const { return _unit_magnitude; } - const std::string& element_type() const { return _element_type; } - }; + protected: + SettingField settings_; + double deflection_tolerance_; + }; + class ElementSettings : public IteratorSettings + { + public: + ElementSettings(const IteratorSettings& settings, + double unit_magnitude, + const std::string& element_type) + : IteratorSettings(settings) + , unit_magnitude_(unit_magnitude) + , element_type_(element_type) + { + } + + double unit_magnitude() const { return unit_magnitude_; } + const std::string& element_type() const { return element_type_; } + + private: + double unit_magnitude_; + std::string element_type_; + }; } -#endif \ No newline at end of file +#endif diff --git a/src/ifcgeom/IfcGeomRepresentation.cpp b/src/ifcgeom/IfcGeomRepresentation.cpp index 15801265ae..abd17a15d9 100644 --- a/src/ifcgeom/IfcGeomRepresentation.cpp +++ b/src/ifcgeom/IfcGeomRepresentation.cpp @@ -38,7 +38,7 @@ IfcGeom::Representation::Serialization::Serialization(const BRep& brep) for (IfcGeom::IfcRepresentationShapeItems::const_iterator it = brep.begin(); it != brep.end(); ++ it) { const TopoDS_Shape& s = it->Shape(); gp_GTrsf trsf = it->Placement(); - if (settings().convert_back_units()) { + if (settings().get(IteratorSettings::CONVERT_BACK_UNITS)) { gp_Trsf scale; scale.SetScaleFactor(1.0 / settings().unit_magnitude()); trsf.PreMultiply(scale); diff --git a/src/ifcgeom/IfcGeomRepresentation.h b/src/ifcgeom/IfcGeomRepresentation.h index 501ff68733..802444edf8 100644 --- a/src/ifcgeom/IfcGeomRepresentation.h +++ b/src/ifcgeom/IfcGeomRepresentation.h @@ -132,7 +132,7 @@ namespace IfcGeom { } } - if (settings().apply_default_materials() && surface_style_id == -1) { + if (settings().get(IteratorSettings::APPLY_DEFAULT_MATERIALS) && surface_style_id == -1) { Material material(IfcGeom::get_default_style(settings().element_type())); std::vector::const_iterator mit = std::find(_materials.begin(), _materials.end(), material); if (mit == _materials.end()) { @@ -182,7 +182,7 @@ namespace IfcGeom { std::map dict; // Vertex normals are only calculated if vertices are not welded - const bool calculate_normals = !settings().weld_vertices(); + const bool calculate_normals = !settings().get(IteratorSettings::WELD_VERTICES); for( int i = 1; i <= nodes.Length(); ++ i ) { coords.push_back(nodes(i).Transformed(loc).XYZ()); @@ -278,11 +278,12 @@ namespace IfcGeom { private: // Welds vertices that belong to different faces int addVertex(int material_index, const gp_XYZ& p) { - const P X = static_cast

(settings().convert_back_units() ? (p.X() / settings().unit_magnitude()) : p.X()); - const P Y = static_cast

(settings().convert_back_units() ? (p.Y() / settings().unit_magnitude()) : p.Y()); - const P Z = static_cast

(settings().convert_back_units() ? (p.Z() / settings().unit_magnitude()) : p.Z()); + const bool convert = settings().get(IteratorSettings::CONVERT_BACK_UNITS); + const P X = static_cast

(convert ? (p.X() / settings().unit_magnitude()) : p.X()); + const P Y = static_cast

(convert ? (p.Y() / settings().unit_magnitude()) : p.Y()); + const P Z = static_cast

(convert ? (p.Z() / settings().unit_magnitude()) : p.Z()); int i = (int) _verts.size() / 3; - if (settings().weld_vertices()) { + if (settings().get(IteratorSettings::WELD_VERTICES)) { 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; diff --git a/src/ifcgeomserver/IfcGeomServer.cpp b/src/ifcgeomserver/IfcGeomServer.cpp index 975c3c471e..0b37b739aa 100644 --- a/src/ifcgeomserver/IfcGeomServer.cpp +++ b/src/ifcgeomserver/IfcGeomServer.cpp @@ -318,10 +318,10 @@ int main () { memcpy(data, m.string().c_str(), len); IfcGeom::IteratorSettings settings; - settings.use_world_coords() = false; - settings.weld_vertices() = false; - settings.convert_back_units() = true; - settings.include_curves() = true; + settings.set(IfcGeom::IteratorSettings::USE_WORLD_COORDS, false); + settings.set(IfcGeom::IteratorSettings::WELD_VERTICES, false); + settings.set(IfcGeom::IteratorSettings::CONVERT_BACK_UNITS, true); + settings.set(IfcGeom::IteratorSettings::INCLUDE_CURVES, true); iterator = new IfcGeom::Iterator(settings, data, (int)len); has_more = iterator->initialize(); diff --git a/src/ifcmax/IfcMax.cpp b/src/ifcmax/IfcMax.cpp index 46bf0f39f8..28ab422882 100644 --- a/src/ifcmax/IfcMax.cpp +++ b/src/ifcmax/IfcMax.cpp @@ -214,9 +214,9 @@ static Mtl* ComposeMultiMaterial(std::map, Mtl*>& multi int IFCImp::DoImport(const TCHAR *name, ImpInterface *impitfc, Interface *itfc, BOOL /*suppressPrompts*/) { IfcGeom::IteratorSettings settings; - settings.use_world_coords() = false; - settings.weld_vertices() = true; - settings.sew_shells() = true; + settings.set(IfcGeom::IteratorSettings::USE_WORLD_COORDS, false); + settings.set(IfcGeom::IteratorSettings::WELD_VERTICES, true); + settings.set(IfcGeom::IteratorSettings::SEW_SHELLS, true); #ifdef _UNICODE int fn_buffer_size = WideCharToMultiByte(CP_UTF8, 0, name, -1, 0, 0, 0, 0); diff --git a/src/ifcparse/IfcUtil.cpp b/src/ifcparse/IfcUtil.cpp index 0f4bc13734..efd0e8f64e 100644 --- a/src/ifcparse/IfcUtil.cpp +++ b/src/ifcparse/IfcUtil.cpp @@ -17,12 +17,14 @@ * * ********************************************************************************/ +#include "IfcUtil.h" +#include "../ifcparse/IfcException.h" + +#include + #include #include -#include "../ifcparse/IfcException.h" - -#include "IfcUtil.h" void IfcEntityList::push(IfcUtil::IfcBaseClass* l) { if (l) { @@ -143,4 +145,14 @@ bool IfcUtil::valid_binary_string(const std::string& s) { if (*it != '0' && *it != '1') return false; } return true; -} \ No newline at end of file +} + +boost::regex IfcUtil::wildcard_string_to_regex(std::string str) +{ + std::string special_chars = "\\^.$|()[]*+"; + foreach(char c, special_chars) { + std::string char_str(1, c); + boost::replace_all(str, char_str, "\\"+ char_str); + } + return boost::regex(str); +} diff --git a/src/ifcparse/IfcUtil.h b/src/ifcparse/IfcUtil.h index 19ffead06c..553c483d35 100644 --- a/src/ifcparse/IfcUtil.h +++ b/src/ifcparse/IfcUtil.h @@ -26,15 +26,20 @@ #include #include -#include -#include - #ifdef USE_IFC4 #include "../ifcparse/Ifc4enum.h" #else #include "../ifcparse/Ifc2x3enum.h" #endif +#include +#include +#include +#include + +#define foreach BOOST_FOREACH +#define rforeach BOOST_REVERSE_FOREACH + class Argument; class IfcEntityList; class IfcEntityListList; @@ -110,6 +115,8 @@ namespace IfcUtil { }; bool valid_binary_string(const std::string& s); + + boost::regex wildcard_string_to_regex(std::string str); } template diff --git a/src/ifcwrap/IfcGeomWrapper.i b/src/ifcwrap/IfcGeomWrapper.i index 84a435b69e..e0db875565 100644 --- a/src/ifcwrap/IfcGeomWrapper.i +++ b/src/ifcwrap/IfcGeomWrapper.i @@ -244,8 +244,8 @@ struct ShapeRTTI : public boost::static_visitor IfcSchema::IfcProject* project = *projects->begin(); IfcGeom::Kernel kernel; - kernel.setValue(IfcGeom::Kernel::GV_MAX_FACES_TO_SEW, settings.sew_shells() ? 1000 : -1); - kernel.setValue(IfcGeom::Kernel::GV_DIMENSIONALITY, (settings.include_curves() ? (settings.exclude_solids_and_surfaces() ? -1. : 0.) : +1.)); + kernel.setValue(IfcGeom::Kernel::GV_MAX_FACES_TO_SEW, settings.get(IfcGeom::IteratorSettings::SEW_SHELLS) ? 1000 : -1); + kernel.setValue(IfcGeom::Kernel::GV_DIMENSIONALITY, (settings.get(IfcGeom::IteratorSettings::INCLUDE_CURVES) ? (settings.get(IfcGeom::IteratorSettings::EXCLUDE_SOLIDS_AND_SURFACES) ? -1. : 0.) : +1.)); std::pair length_unit = kernel.initializeUnits(project->UnitsInContext()); if (instance->is(IfcSchema::Type::IfcProduct)) { @@ -269,13 +269,13 @@ struct ShapeRTTI : public boost::static_visitor // First, try to find a representation based on the settings for (IfcSchema::IfcRepresentation::list::it it = reps->begin(); it != reps->end(); ++it) { IfcSchema::IfcRepresentation* rep = *it; - if (!settings.exclude_solids_and_surfaces()) { + if (!settings.get(IfcGeom::IteratorSettings::EXCLUDE_SOLIDS_AND_SURFACES)) { if (rep->RepresentationIdentifier() == "Body") { ifc_representation = rep; break; } } - if (settings.include_curves()) { + if (settings.get(IfcGeom::IteratorSettings::INCLUDE_CURVES)) { if (rep->RepresentationIdentifier() == "Plan" || rep->RepresentationIdentifier() == "Axis") { ifc_representation = rep; break; @@ -293,12 +293,12 @@ struct ShapeRTTI : public boost::static_visitor // TODO: Remove redundancy with IfcGeomIterator.h if (context->hasContextType()) { std::set context_types; - if (!settings.exclude_solids_and_surfaces()) { + if (!settings.get(IfcGeom::IteratorSettings::EXCLUDE_SOLIDS_AND_SURFACES)) { context_types.insert("model"); context_types.insert("design"); context_types.insert("model view"); } - if (settings.include_curves()) { + if (settings.get(IfcGeom::IteratorSettings::INCLUDE_CURVES)) { context_types.insert("plan"); } @@ -347,11 +347,11 @@ struct ShapeRTTI : public boost::static_visitor if (!brep) { throw IfcParse::IfcException("Failed to process shape"); } - if (settings.use_brep_data()) { + if (settings.get(IfcGeom::IteratorSettings::USE_BREP_DATA)) { IfcGeom::SerializedElement* serialization = new IfcGeom::SerializedElement(*brep); delete brep; return serialization; - } else if (!settings.disable_triangulation()) { + } else if (!settings.get(IfcGeom::IteratorSettings::DISABLE_TRIANGULATION)) { IfcGeom::TriangulationElement* triangulation = new IfcGeom::TriangulationElement(*brep); delete brep; return triangulation; @@ -366,9 +366,9 @@ struct ShapeRTTI : public boost::static_visitor IfcGeom::ElementSettings element_settings(settings, kernel.getValue(IfcGeom::Kernel::GV_LENGTH_UNIT), IfcSchema::Type::ToString(instance->type())); IfcGeom::Representation::BRep brep(element_settings, instance->entity->id(), shapes); try { - if (settings.use_brep_data()) { + if (settings.get(IfcGeom::IteratorSettings::USE_BREP_DATA)) { return new IfcGeom::Representation::Serialization(brep); - } else if (!settings.disable_triangulation()) { + } else if (!settings.get(IfcGeom::IteratorSettings::DISABLE_TRIANGULATION)) { return new IfcGeom::Representation::Triangulation(brep); } } catch (...) {