context_iterator(settings, &ifc_file,
+ // filter_funcs);
+
+ IfcGeom::Kernel kernel;
+ std::string unit_name = "METER";
+ double unit_magnitude = 1.f;
+ IfcSchema::IfcRepresentation::list::ptr ok_mapped_representations;
+ IfcSchema::IfcRepresentation::list::ptr representations =
+ IfcSchema::IfcRepresentation::list::ptr(
+ new IfcSchema::IfcRepresentation::list);
+ IfcSchema::IfcRepresentation::list::it representation_iterator;
+
+ try
+ {
+
+ // constructor
+ // TriangulationElement* current_triangulation =0 ;
+ // BRepElement
* current_shape_model = 0;
+ // SerializedElement
* current_serialization = 0;
+ 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.));
+ 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");
+ }
+ kernel.set_conversion_placement_rel_to(IfcSchema::Type::IfcBuilding);
+ }
+ else if (settings.get(IfcGeom::IteratorSettings::SITE_LOCAL_PLACEMENT))
+ {
+ kernel.set_conversion_placement_rel_to(IfcSchema::Type::IfcSite);
}
- const bool is_tesselated = serializer->isTesselated(); // isTesselated() doesn't change at run-time
- if (!is_tesselated) {
- if (weld_vertices) {
- Logger::Notice("Weld vertices setting ignored when writing non-tesselated output");
- }
- if (generate_uvs) {
- Logger::Notice("Generate UVs setting ignored when writing non-tesselated output");
- }
- if (center_model || model_offset) {
- Logger::Notice("Centering/offsetting model setting ignored when writing non-tesselated output");
- }
+ // initialize()
+ // initunits()
+ IfcSchema::IfcProject::list::ptr projects =
+ ifc_file.entitiesByType();
+ std::set allowed_context_types;
+ std::set context_types;
+ double lowest_precision_encountered =
+ std::numeric_limits::infinity();
+ bool any_precision_encountered = false;
- settings.set(IfcGeom::IteratorSettings::DISABLE_TRIANGULATION, true);
+ if (projects->size() == 1)
+ {
+ IfcSchema::IfcProject *project = *projects->begin();
+ std::pair length_unit =
+ kernel.initializeUnits(project->UnitsInContext());
+ unit_name = length_unit.first;
+ unit_magnitude = length_unit.second;
+ }
+ else
+ {
+ Logger::Error("A single IfcProject is expected (encountered " +
+ boost::lexical_cast(projects->size()) +
+ "); unable to read unit information.");
}
- if (!serializer->ready()) {
- IfcUtil::path::delete_file(IfcUtil::path::to_utf8(output_temp_filename));
- write_log(!quiet);
- return EXIT_FAILURE;
+ allowed_context_types.insert("model");
+ allowed_context_types.insert("plan");
+ allowed_context_types.insert("notdefined");
+ if (!settings.get(IfcGeom::IteratorSettings::EXCLUDE_SOLIDS_AND_SURFACES))
+ {
+ // Really this should only be 'Model', as per
+ // the standard 'Design' is deprecated. So,
+ // just for backwards compatibility:
+ context_types.insert("model");
+ context_types.insert("design");
+ // Some earlier (?) versions DDS-CAD output their own ContextTypes
+ context_types.insert("model view");
+ context_types.insert("detail view");
+ }
+ if (settings.get(IfcGeom::IteratorSettings::INCLUDE_CURVES))
+ {
+ context_types.insert("plan");
}
- time_t start,end;
- time(&start);
-
- if (!init_input_file(IfcUtil::path::to_utf8(input_filename), ifc_file, no_progress || quiet, mmap)) {
- write_log(!quiet);
- IfcUtil::path::delete_file(IfcUtil::path::to_utf8(output_temp_filename)); /**< @todo Windows Unicode support */
- return EXIT_FAILURE;
- }
+ representations = IfcSchema::IfcRepresentation::list::ptr(
+ new IfcSchema::IfcRepresentation::list);
+ ok_mapped_representations = IfcSchema::IfcRepresentation::list::ptr(
+ new IfcSchema::IfcRepresentation::list);
+ IfcSchema::IfcGeometricRepresentationContext::list::it it;
+ IfcSchema::IfcGeometricRepresentationSubContext::list::it jt;
+ IfcSchema::IfcGeometricRepresentationContext::list::ptr contexts =
+ ifc_file.entitiesByType();
- ////////////////////////////////////////////////////////////
- // initialize geometry
- ////////////////////////////////////////////////////////////
-
- serializer->setFile(&ifc_file);
-
- IfcGeom::Iterator context_iterator(settings, &ifc_file, filter_funcs);
- IfcGeom::Kernel kernel;
- std::string unit_name = "METER" ;
- double unit_magnitude = 1.f;
- IfcSchema::IfcRepresentation::list::ptr ok_mapped_representations;
- IfcSchema::IfcRepresentation::list::ptr representations =
- IfcSchema::IfcRepresentation::list::ptr(new IfcSchema::IfcRepresentation::list);
- IfcSchema::IfcRepresentation::list::it representation_iterator;
+ IfcSchema::IfcGeometricRepresentationContext::list::ptr filtered_contexts(
+ new IfcSchema::IfcGeometricRepresentationContext::list);
-
- try {
-
- // constructor
- // TriangulationElement* current_triangulation =0 ;
- // BRepElement
* current_shape_model = 0;
- // SerializedElement
* current_serialization = 0;
- 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.));
- 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");
- }
- kernel.set_conversion_placement_rel_to(IfcSchema::Type::IfcBuilding);
- } else if (settings.get(IfcGeom::IteratorSettings::SITE_LOCAL_PLACEMENT)) {
- kernel.set_conversion_placement_rel_to(IfcSchema::Type::IfcSite);
+ for (it = contexts->begin(); it != contexts->end(); ++it)
+ {
+ IfcSchema::IfcGeometricRepresentationContext *context = *it;
+ if (context->is(IfcSchema::Type::IfcGeometricRepresentationSubContext))
+ {
+ // Continue, as the list of subcontexts will be considered
+ // by the parent's context inverse attributes.
+ continue;
}
-
- // initialize()
- // initunits()
- IfcSchema::IfcProject::list::ptr projects = ifc_file.entitiesByType();
- std::set allowed_context_types;
- std::set context_types;
- double lowest_precision_encountered = std::numeric_limits::infinity();
- bool any_precision_encountered = false;
-
- if (projects->size() == 1) {
- IfcSchema::IfcProject* project = *projects->begin();
- std::pair length_unit = kernel.initializeUnits(project->UnitsInContext());
- unit_name = length_unit.first;
- unit_magnitude = length_unit.second;
- } else {
- Logger::Error("A single IfcProject is expected (encountered " + boost::lexical_cast(projects->size()) + "); unable to read unit information.");
- }
-
- allowed_context_types.insert("model");
- allowed_context_types.insert("plan");
- allowed_context_types.insert("notdefined");
- if (!settings.get(IfcGeom::IteratorSettings::EXCLUDE_SOLIDS_AND_SURFACES)) {
- // Really this should only be 'Model', as per
- // the standard 'Design' is deprecated. So,
- // just for backwards compatibility:
- context_types.insert("model");
- context_types.insert("design");
- // Some earlier (?) versions DDS-CAD output their own ContextTypes
- context_types.insert("model view");
- context_types.insert("detail view");
- }
- if (settings.get(IfcGeom::IteratorSettings::INCLUDE_CURVES)) {
- context_types.insert("plan");
- }
-
- representations = IfcSchema::IfcRepresentation::list::ptr(new IfcSchema::IfcRepresentation::list);
- ok_mapped_representations = IfcSchema::IfcRepresentation::list::ptr(new IfcSchema::IfcRepresentation::list);
-
- IfcSchema::IfcGeometricRepresentationContext::list::it it;
- IfcSchema::IfcGeometricRepresentationSubContext::list::it jt;
- IfcSchema::IfcGeometricRepresentationContext::list::ptr contexts =
- ifc_file.entitiesByType();
-
- IfcSchema::IfcGeometricRepresentationContext::list::ptr filtered_contexts (new IfcSchema::IfcGeometricRepresentationContext::list);
-
- for (it = contexts->begin(); it != contexts->end(); ++it) {
- IfcSchema::IfcGeometricRepresentationContext* context = *it;
- if (context->is(IfcSchema::Type::IfcGeometricRepresentationSubContext)) {
- // Continue, as the list of subcontexts will be considered
- // by the parent's context inverse attributes.
- continue;
- }
- try {
- if (context->hasContextType()) {
- std::string context_type = context->ContextType();
- boost::to_lower(context_type);
- if (allowed_context_types.find(context_type) == allowed_context_types.end()) {
- Logger::Message(Logger::LOG_ERROR, std::string("ContextType '") + context->ContextType() + "' not allowed:", context->entity);
- } // == allowed_context_types.end()
- if (context_types.find(context_type) != context_types.end()) {
- filtered_contexts->push(context);
- } // != context_types.end()
- } // hasContextType()
- } catch (const std::exception& e) {
- Logger::Error(e);
- }
- } // end iterating contexts
-
- // In case no contexts are identified based on their ContextType, all contexts are
- // considered. Note that sub contexts are excluded as they are considered later on.
- if (filtered_contexts->size() == 0) {
- for (it = contexts->begin(); it != contexts->end(); ++it) {
- IfcSchema::IfcGeometricRepresentationContext* context = *it;
- if (!context->is(IfcSchema::Type::IfcGeometricRepresentationSubContext)) {
+ try
+ {
+ if (context->hasContextType())
+ {
+ std::string context_type = context->ContextType();
+ boost::to_lower(context_type);
+ if (allowed_context_types.find(context_type) ==
+ allowed_context_types.end())
+ {
+ Logger::Message(Logger::LOG_ERROR,
+ std::string("ContextType '") +
+ context->ContextType() + "' not allowed:",
+ context->entity);
+ } // == allowed_context_types.end()
+ if (context_types.find(context_type) != context_types.end())
+ {
filtered_contexts->push(context);
- }
+ } // != context_types.end()
+ } // hasContextType()
+ }
+ catch (const std::exception &e)
+ {
+ Logger::Error(e);
+ }
+ } // end iterating contexts
+
+ // In case no contexts are identified based on their ContextType, all
+ // contexts are considered. Note that sub contexts are excluded as they
+ // are considered later on.
+ if (filtered_contexts->size() == 0)
+ {
+ for (it = contexts->begin(); it != contexts->end(); ++it)
+ {
+ IfcSchema::IfcGeometricRepresentationContext *context = *it;
+ if (!context->is(IfcSchema::Type::IfcGeometricRepresentationSubContext))
+ {
+ filtered_contexts->push(context);
}
}
-
- for (it = filtered_contexts->begin(); it != filtered_contexts->end(); ++it) {
- IfcSchema::IfcGeometricRepresentationContext* context = *it;
-
- representations->push(context->RepresentationsInContext());
- try {
- if (context->hasPrecision() && context->Precision() < lowest_precision_encountered) {
- lowest_precision_encountered = context->Precision();
- any_precision_encountered = true;
- }
- } catch (const std::exception& e) {
- Logger::Error(e);
- }
-
- IfcSchema::IfcGeometricRepresentationSubContext::list::ptr sub_contexts = context->HasSubContexts();
- for (jt = sub_contexts->begin(); jt != sub_contexts->end(); ++jt) {
- representations->push((*jt)->RepresentationsInContext());
- }
- // There is no need for full recursion as the following is governed by the schema:
- // WR31: The parent context shall not be another geometric representation sub context.
- } // end iterating filtered_contexts
-
- if (any_precision_encountered) {
- // Some arbitrary factor that has proven to work better for the models in the set of test files.
- lowest_precision_encountered *= 10.;
- lowest_precision_encountered *= unit_magnitude;
- if (lowest_precision_encountered < 1.e-7) {
- Logger::Message(Logger::LOG_WARNING, "Precision lower than 0.0000001 meter not enforced");
- kernel.setValue(IfcGeom::Kernel::GV_PRECISION, 1.e-7);
- } else {
- kernel.setValue(IfcGeom::Kernel::GV_PRECISION, lowest_precision_encountered);
- }
- } else {
- kernel.setValue(IfcGeom::Kernel::GV_PRECISION, 1.e-5);
- }
-
- if (representations->size() == 0) {
- Logger::Message(Logger::LOG_ERROR, "No representations encountered in relevant contexts, using all");
- representations = ifc_file.entitiesByType();
- }
-
- if (representations->size() == 0) {
- Logger::Message(Logger::LOG_ERROR, "No representations encountered, aborting");
- return 0;
- }
-
- // representation_iterator = representations->begin();
- // ifcproducts.reset();
-
- // if (!create()) {
- // return false;
- // }
-
- // done = 0;
- // total = representations->size();
-
- // return true;
- } catch (const std::exception& e) {
- Logger::Error(e);
- Logger::Error("No geometrical entities found");
- IfcUtil::path::delete_file(IfcUtil::path::to_utf8(output_temp_filename));
- write_log(!quiet);
- return EXIT_FAILURE;
}
-
- //replaces:
- // if (!context_iterator.initialize()) {
- // /// @todo It would be nice to know and print separate error prints for a case where we found no entities
- // /// and for a case we found no entities that satisfy our filtering criteria.
- // Logger::Error("No geometrical entities found");
- // IfcUtil::path::delete_file(IfcUtil::path::to_utf8(output_temp_filename));
- // write_log(!quiet);
- // return EXIT_FAILURE;
+
+ for (it = filtered_contexts->begin(); it != filtered_contexts->end(); ++it)
+ {
+ IfcSchema::IfcGeometricRepresentationContext *context = *it;
+
+ representations->push(context->RepresentationsInContext());
+ try
+ {
+ if (context->hasPrecision() &&
+ context->Precision() < lowest_precision_encountered)
+ {
+ lowest_precision_encountered = context->Precision();
+ any_precision_encountered = true;
+ }
+ }
+ catch (const std::exception &e)
+ {
+ Logger::Error(e);
+ }
+
+ IfcSchema::IfcGeometricRepresentationSubContext::list::ptr sub_contexts =
+ context->HasSubContexts();
+ for (jt = sub_contexts->begin(); jt != sub_contexts->end(); ++jt)
+ {
+ representations->push((*jt)->RepresentationsInContext());
+ }
+ // There is no need for full recursion as the following is governed
+ // by the schema: WR31: The parent context shall not be another
+ // geometric representation sub context.
+ } // end iterating filtered_contexts
+
+ if (any_precision_encountered)
+ {
+ // Some arbitrary factor that has proven to work better for the
+ // models in the set of test files.
+ lowest_precision_encountered *= 10.;
+ lowest_precision_encountered *= unit_magnitude;
+ if (lowest_precision_encountered < 1.e-7)
+ {
+ Logger::Message(Logger::LOG_WARNING,
+ "Precision lower than 0.0000001 meter not enforced");
+ kernel.setValue(IfcGeom::Kernel::GV_PRECISION, 1.e-7);
+ }
+ else
+ {
+ kernel.setValue(IfcGeom::Kernel::GV_PRECISION,
+ lowest_precision_encountered);
+ }
+ }
+ else
+ {
+ kernel.setValue(IfcGeom::Kernel::GV_PRECISION, 1.e-5);
+ }
+
+ if (representations->size() == 0)
+ {
+ Logger::Message(Logger::LOG_ERROR,
+ "No representations encountered in relevant "
+ "contexts, using all");
+ representations = ifc_file.entitiesByType();
+ }
+
+ if (representations->size() == 0)
+ {
+ Logger::Message(Logger::LOG_ERROR,
+ "No representations encountered, aborting");
+ return 0;
+ }
+
+ // representation_iterator = representations->begin();
+ // ifcproducts.reset();
+
+ // if (!create()) {
+ // return false;
// }
-
- if (convert_back_units) {
- // serializer->setUnitNameAndMagnitude(context_iterator.getUnitName(), static_cast(context_iterator.getUnitMagnitude()));
- serializer->setUnitNameAndMagnitude(unit_name, static_cast(unit_magnitude));
- } else {
- serializer->setUnitNameAndMagnitude("METER", 1.0f);
- }
- serializer->writeHeader();
+ // done = 0;
+ // total = representations->size();
- int old_progress = quiet ? 0 : -1;
- Bounds model_bounds;
- if (is_tesselated && (center_model || model_offset)) {
- double* offset = serializer->settings().offset;
- if (center_model) {
- if (site_local_placement || building_local_placement) {
- Logger::Error("Cannot use --center-model together with --{site,building}-local-placement");
- return EXIT_FAILURE;
- }
+ // return true;
+ }
+ catch (const std::exception &e)
+ {
+ Logger::Error(e);
+ Logger::Error("No geometrical entities found");
+ IfcUtil::path::delete_file(IfcUtil::path::to_utf8(output_temp_filename));
+ write_log(!quiet);
+ return EXIT_FAILURE;
+ }
- if (!quiet) Logger::Status("Computing bounds...");
- model_bounds = compute_bounds( &ifc_file, kernel );
- if (!quiet) Logger::Status("Done!");
+ // above try block replaces:
+ // if (!context_iterator.initialize()) {
+ // /// @todo It would be nice to know and print separate error prints
+ // for a case where we found no entities
+ // /// and for a case we found no entities that satisfy our filtering
+ // criteria. Logger::Error("No geometrical entities found");
+ // IfcUtil::path::delete_file(IfcUtil::path::to_utf8(output_temp_filename));
+ // write_log(!quiet);
+ // return EXIT_FAILURE;
+ // }
- gp_XYZ center = (model_bounds.min + model_bounds.max) * 0.5;
- offset[0] = -center.X();
- offset[1] = -center.Y();
- offset[2] = -center.Z();
- } else {
- if (sscanf(offset_str.c_str(), "%lf;%lf;%lf", &offset[0], &offset[1], &offset[2]) != 3) {
- cerr_ << "[Error] Invalid use of --model-offset\n";
- IfcUtil::path::delete_file(IfcUtil::path::to_utf8(output_temp_filename));
- print_options(serializer_options);
- return EXIT_FAILURE;
- }
+ if (convert_back_units)
+ {
+ // serializer->setUnitNameAndMagnitude(context_iterator.getUnitName(),
+ // static_cast(context_iterator.getUnitMagnitude()));
+ serializer->setUnitNameAndMagnitude(unit_name,
+ static_cast(unit_magnitude));
+ }
+ else
+ {
+ serializer->setUnitNameAndMagnitude("METER", 1.0f);
+ }
+
+ serializer->writeHeader();
+
+ ////////////////////////////////////////////////////////////
+ // with serializer ready to receive data,
+ // let's get to the geometry:
+ ////////////////////////////////////////////////////////////
+
+ // int old_progress = quiet ? 0 : -1;
+ Bounds model_bounds;
+ if (is_tesselated && (center_model || model_offset))
+ {
+ double *offset = serializer->settings().offset;
+ if (center_model)
+ {
+ if (site_local_placement || building_local_placement)
+ {
+ Logger::Error("Cannot use --center-model together with "
+ "--{site,building}-local-placement");
+ return EXIT_FAILURE;
}
- std::stringstream msg;
- msg << "Using model offset (" << offset[0] << "," << offset[1] << "," << offset[2] << ")";
- Logger::Notice(msg.str());
+ if (!quiet)
+ Logger::Status("Computing bounds...");
+ model_bounds = compute_bounds(&ifc_file, kernel);
+ if (!quiet)
+ Logger::Status("Done!");
+
+ gp_XYZ center = (model_bounds.min + model_bounds.max) * 0.5;
+ offset[0] = -center.X();
+ offset[1] = -center.Y();
+ offset[2] = -center.Z();
+ }
+ else
+ {
+ if (sscanf(offset_str.c_str(), "%lf;%lf;%lf", &offset[0], &offset[1],
+ &offset[2]) != 3)
+ {
+ cerr_ << "[Error] Invalid use of --model-offset\n";
+ IfcUtil::path::delete_file(
+ IfcUtil::path::to_utf8(output_temp_filename));
+ print_options(serializer_options);
+ return EXIT_FAILURE;
+ }
}
- if (!quiet) {
- Logger::Status("Creating geometry...");
- }
+ std::stringstream msg;
+ msg << "Using model offset (" << offset[0] << "," << offset[1] << ","
+ << offset[2] << ")";
+ Logger::Notice(msg.str());
+ }
- // 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
- // -BRepElement pointer, based on current settings. (see IfcGeomIterator.h
- // for definition) IfcGeom::Iterator::next() is used to poll whether more
- // geometrical entities are available. None of these functions throw
- // exceptions, neither for parsing errors or geometrical errors. Upon
- // calling next() the entity to be returned has already been processed, a
- // non-null return value guarantees that a successfully processed product is
- // available.
- size_t num_created = 0;
+ if (!quiet)
+ {
+ Logger::Status("Creating geometry...");
+ }
+ // 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
+ // -BRepElement pointer, based on current settings. (see IfcGeomIterator.h
+ // for definition) IfcGeom::Iterator::next() is used to poll whether more
+ // geometrical entities are available. None of these functions throw
+ // exceptions, neither for parsing errors or geometrical errors. Upon
+ // calling next() the entity to be returned has already been processed, a
+ // non-null return value guarantees that a successfully processed product is
+ // available.
- ////////////////////////////////////////////////////////////
- // start initializing elements for threading
- ////////////////////////////////////////////////////////////
-
- std::vector IfcproductRepresentations;
-
- // do {
- // IfcGeom::Element *geom_object = context_iterator.get();
+ ////////////////////////////////////////////////////////////
+ // start initializing elements for threading
+ ////////////////////////////////////////////////////////////
- // if (is_tesselated)
- // {
- // serializer->write(static_cast*>(geom_object));
- // }
- // else
- // {
- // serializer->write(static_cast*>(geom_object));
- // }
+ // size_t num_created = 0;
- // if (!no_progress) {
- // if (quiet) {
- // const int progress = context_iterator.progress();
- // for (; old_progress < progress; ++old_progress) {
- // std::cout << ".";
- // if (stderr_progress)
- // std::cerr << ".";
- // }
- // std::cout << std::flush;
- // if (stderr_progress)
- // std::cerr << std::flush;
- // } else {
- // const int progress = context_iterator.progress() / 2;
- // if (old_progress != progress) Logger::ProgressBar(progress);
- // old_progress = progress;
- // }
- // }
- // } while (++num_created, context_iterator.next());
+ // do {
+ // IfcGeom::Element *geom_object = context_iterator.get();
- // if (!no_progress && quiet) {
- // for (; old_progress < 100; ++old_progress) {
- // std::cout << ".";
- // if (stderr_progress)
- // std::cerr << ".";
- // }
- // std::cout << std::flush;
- // if (stderr_progress)
- // std::cerr << std::flush;
- // } else {
- // Logger::Status("\rDone creating geometry (" + boost::lexical_cast(num_created) +
- // " objects) ");
- // }
+ // if (is_tesselated)
+ // {
+ // serializer->write(static_cast*>(geom_object));
+ // }
+ // else
+ // {
+ // serializer->write(static_cast*>(geom_object));
+ // }
+ // if (!no_progress) {
+ // if (quiet) {
+ // const int progress =
+ // context_iterator.progress(); for (; old_progress
+ // < progress;
+ // ++old_progress) { std::cout << ".";
+ // if (stderr_progress) std::cerr
+ // <<
+ // ".";
+ // }
+ // std::cout << std::flush;
+ // if (stderr_progress)
+ // std::cerr << std::flush;
+ // } else {
+ // const int progress = context_iterator.progress()
+ // / 2; if (old_progress != progress)
+ // Logger::ProgressBar(progress); old_progress =
+ // progress;
+ // }
+ // }
+ // } while (++num_created, context_iterator.next());
- ////////////////////////////////////////////////////////////
- // Copy/Paste from IfcInfo, fine-tooth comb over vars
- ////////////////////////////////////////////////////////////
-
-////////////////////////////////////////////////////////////
+ // if (!no_progress && quiet) {
+ // for (; old_progress < 100; ++old_progress) {
+ // std::cout << ".";
+ // if (stderr_progress)
+ // std::cerr << ".";
+ // }
+ // std::cout << std::flush;
+ // if (stderr_progress)
+ // std::cerr << std::flush;
+ // } else {
+ // Logger::Status("\rDone creating geometry (" +
+ // boost::lexical_cast(num_created) + "
+ // objects) ");
+ // }
+
+ ////////////////////////////////////////////////////////////
+ // Copy/Paste from IfcInfo, fine-tooth comb over vars
+ ////////////////////////////////////////////////////////////
+
+ ////////////////////////////////////////////////////////////
/////// find products associated with representations (... ?)
////////////////////////////////////////////////////////////
+ std::vector IfcproductRepresentations;
IfcSchema::IfcProduct::list::ptr ifcproducts;
IfcSchema::IfcProduct::list::it ifcproduct_iterator;
std::vector filters_;
-
IfcGeom::layer_filter layer_filter;
IfcGeom::entity_filter entity_filter;
IfcGeom::string_arg_filter guid_filter(IfcSchema::Type::IfcRoot, 0);
IfcGeom::string_arg_filter name_filter(IfcSchema::Type::IfcRoot, 2);
IfcGeom::string_arg_filter desc_filter(IfcSchema::Type::IfcRoot, 3);
IfcGeom::string_arg_filter tag_filter(IfcSchema::Type::IfcProxy, 8,
- IfcSchema::Type::IfcElement,
- 7);
+ IfcSchema::Type::IfcElement, 7);
filters_.emplace_back(boost::ref(layer_filter));
filters_.emplace_back(boost::ref(entity_filter));
filters_.emplace_back(boost::ref(guid_filter));
@@ -1052,33 +1422,41 @@ int wmain(int argc, wchar_t** argv) {
struct filter_match
{
filter_match(IfcSchema::IfcProduct *prod) : product(prod) {}
- bool operator()(const IfcGeom::filter_t &filter) const { return filter(product); }
+ bool operator()(const IfcGeom::filter_t &filter) const
+ {
+ return filter(product);
+ }
IfcSchema::IfcProduct *product;
};
Logger::Status("starting to iterate over representations ");
- start = std::chrono::system_clock::now();
int index_count = 0;
for (representation_iterator = representations->begin();
- representation_iterator != representations->end(); representation_iterator++)
+ representation_iterator != representations->end();
+ representation_iterator++)
{
IfcSchema::IfcRepresentation *representation = *representation_iterator;
ifcproducts.reset();
- ifcproducts = IfcSchema::IfcProduct::list::ptr(new IfcSchema::IfcProduct::list);
+ ifcproducts =
+ IfcSchema::IfcProduct::list::ptr(new IfcSchema::IfcProduct::list);
IfcSchema::IfcProduct::list::ptr unfiltered_products =
kernel.products_represented_by(representation);
- geometry_reuse_ok_for_current_representation_ = reuse_ok_(settings, unfiltered_products);
- IfcSchema::IfcRepresentationMap::list::ptr maps = representation->RepresentationMap();
+ geometry_reuse_ok_for_current_representation_ =
+ reuse_ok_(settings, unfiltered_products, kernel);
+ IfcSchema::IfcRepresentationMap::list::ptr maps =
+ representation->RepresentationMap();
if (!geometry_reuse_ok_for_current_representation_ && maps->size() == 1)
{
- // unfiltered_products contains products represented by this representation by means of
- // mapped items. For example because of openings applied to products, reuse might not be
- // acceptable and then the products will be processed by means of their immediate
+ // unfiltered_products contains products represented by this
+ // representation by means of mapped items. For example because of
+ // openings applied to products, reuse might not be acceptable and
+ // then the products will be processed by means of their immediate
// representation and not the mapped representation.
- // IfcRepresentationMaps are also used for IfcTypeProducts, so an additional check is
- // performed whether the map is indeed used by IfcMappedItems.
+ // IfcRepresentationMaps are also used for IfcTypeProducts, so an
+ // additional check is performed whether the map is indeed used by
+ // IfcMappedItems.
IfcSchema::IfcRepresentationMap *map = *maps->begin();
if (map->MapUsage()->size() > 0)
{
@@ -1094,10 +1472,13 @@ int wmain(int argc, wchar_t** argv) {
kernel.representation_mapped_to(representation);
if (representation_mapped_to)
{
- // Check if this representation has (or will be) processed as part its mapped
- // representation
- bool contains = ok_mapped_representations->contains(representation_mapped_to);
- bool reuse = reuse_ok_(settings, kernel.products_represented_by(representation_mapped_to));
+ // Check if this representation has (or will be) processed as part
+ // its mapped representation
+ bool contains =
+ ok_mapped_representations->contains(representation_mapped_to);
+ bool reuse = reuse_ok_(
+ settings, kernel.products_represented_by(representation_mapped_to),
+ kernel);
representation_processed_as_mapped_item = contains || reuse;
}
if (representation_processed_as_mapped_item)
@@ -1107,8 +1488,8 @@ int wmain(int argc, wchar_t** argv) {
// continue;
continue;
}
- // Filter the products based on the set of entities and/or names being included or excluded
- // for processing.
+ // Filter the products based on the set of entities and/or names being
+ // included or excluded for processing.
for (IfcSchema::IfcProduct::list::it jt = unfiltered_products->begin();
jt != unfiltered_products->end(); ++jt)
{
@@ -1119,8 +1500,8 @@ int wmain(int argc, wchar_t** argv) {
}
} // end for unfiltered_products
- for (ifcproduct_iterator = ifcproducts->begin(); ifcproduct_iterator != ifcproducts->end();
- ifcproduct_iterator++)
+ for (ifcproduct_iterator = ifcproducts->begin();
+ ifcproduct_iterator != ifcproducts->end(); ifcproduct_iterator++)
{
IfcproductRepresentation ir;
ir.index = index_count;
@@ -1131,328 +1512,484 @@ int wmain(int argc, wchar_t** argv) {
} // end for ifcproducts
} // for representation in representations
- end = std::chrono::system_clock::now();
- elapsed_seconds = end - start;
- Logger::Status("iterated over representations: " + std::to_string(elapsed_seconds.count()));
- Logger::Status("count: " + std::to_string(index_count));
- const unsigned int conc_threads = std::thread::hardware_concurrency();
- std::cout << "amount of threads available for use on this machine: " << conc_threads << std::endl;
+ // int count = 0;
+ unsigned int conc_threads = std::thread::hardware_concurrency();
+ if (conc_threads > (unsigned int)IfcproductRepresentations.size())
+ {
+ conc_threads = (unsigned int)IfcproductRepresentations.size();
+ }
std::vector> threadpool;
- count = 0;
- for (int j = 0; j < (int)IfcproductRepresentations.size();)
+
+ cout_ << "threads available: " << conc_threads << "\n";
+
+ cout_ << "ready to process " << IfcproductRepresentations.size()
+ << " items.\n";
+
+ for (int j = 0; j < (int)IfcproductRepresentations.size(); j++)
{
IfcproductRepresentation &r = IfcproductRepresentations[j];
- if (threadpool.size() < conc_threads)
- {
- std::future fu = std::async(std::launch::async, create_element, std::ref(settings), std::ref(r));
- threadpool.emplace_back(std::move(fu));
- j++;
- }
+ create_element(settings, r, kernel);
+ // if (threadpool.size() < conc_threads)
+ // {
+ // std::future fu = std::async(std::launch::async, create_element,
+ // std::ref(settings), std::ref(r));
+ // threadpool.emplace_back(std::move(fu));
+ // j++;
+ // }
+ // else
+ // {
+ // bool waiting = true;
+ // while (waiting)
+ // {
+ // for (int i = 0; i < (int)threadpool.size(); i++)
+ // {
+ // std::future &fu = threadpool[i];
+ // std::future_status status;
+ // status = fu.wait_for(std::chrono::seconds(0));
+ // if (status == std::future_status::ready)
+ // {
+ // fu.get();
+ // threadpool.erase(threadpool.begin() + i);
+ // waiting = false;
+ // } // if
+ // } // for
+ // } // while
+ // }
+ // else
+ }
+
+ // for (std::future &fu : threadpool)
+ // {
+ // fu.get();
+ // }
+
+
+ for (int j = 0; j < (int)IfcproductRepresentations.size(); j++)
+ {
+ IfcproductRepresentation *rep = &IfcproductRepresentations[j];
+ //write_element(serializer, rep, is_tesselated);
+ cout_ << "writing to file, element #: " << rep->index << "\n";
+ IfcGeom::Element *geom_object = rep->element;
+ if (is_tesselated)
+ {
+ serializer->write(
+ static_cast *>(
+ geom_object));
+ }
else
{
- bool waiting = true;
- while (waiting)
- {
- for (int i = 0; i < (int)threadpool.size(); i++)
- {
- std::future &fu = threadpool[i];
- std::future_status status;
- status = fu.wait_for(std::chrono::seconds(0));
- if (status == std::future_status::ready)
- {
- fu.get();
- threadpool.erase(threadpool.begin() + i);
- waiting = false;
- } // if
- } // for
- } // while
- } // else
+ serializer->write(
+ static_cast *>(geom_object));
+ }
+
}
-
- for (std::future &fu : threadpool)
+ ////////////////////////////////////////////////////////////
+ // Elements are generated and in memory (...)
+ // Time to write it out.
+ ////////////////////////////////////////////////////////////
+
+ serializer->finalize();
+ // Make sure the dtor is explicitly run here (e.g. output files are closed
+ // before renaming them).
+ serializer.reset();
+
+ // Renaming might fail (e.g. maybe the existing file was open in a viewer
+ // application) Do not remove the temp file as user can salvage the
+ // conversion result from it.
+ bool successful =
+ IfcUtil::path::rename_file(IfcUtil::path::to_utf8(output_temp_filename),
+ IfcUtil::path::to_utf8(output_filename));
+ if (!successful)
{
- fu.get();
+ cerr_ << "Unable to write output file '" << output_filename << "', see '"
+ << output_temp_filename << "' for the conversion result.";
}
+ write_log(!quiet);
+ time(&end);
- ////////////////////////////////////////////////////////////
- //
- ////////////////////////////////////////////////////////////
-
- serializer->finalize();
- // Make sure the dtor is explicitly run here (e.g. output files are closed before renaming them).
- serializer.reset();
-
- // Renaming might fail (e.g. maybe the existing file was open in a viewer application)
- // Do not remove the temp file as user can salvage the conversion result from it.
- bool successful = IfcUtil::path::rename_file(IfcUtil::path::to_utf8(output_temp_filename), IfcUtil::path::to_utf8(output_filename));
- if (!successful) {
- cerr_ << "Unable to write output file '" << output_filename << "', see '" <<
- output_temp_filename << "' for the conversion result.";
- }
-
- write_log(!quiet);
-
- time(&end);
-
- if (!quiet) {
- Logger::Status("\nConversion took " + format_duration(start, end));
- }
-
- return successful ? EXIT_SUCCESS : EXIT_FAILURE;
- }
-
- std::string format_duration(time_t start, time_t end)
+ if (!quiet)
{
- int seconds = (int)difftime(end, start);
- std::stringstream ss;
- int minutes = seconds / 60;
- seconds = seconds % 60;
- if (minutes > 0) {
- ss << minutes << " minute";
- if (minutes == 0 || minutes > 1) {
- ss << "s";
- }
- ss << " ";
- }
- ss << seconds << " second";
- if (seconds == 0 || seconds > 1) {
+ Logger::Status("\nConversion took " + format_duration(start, end));
+ }
+
+ return successful ? EXIT_SUCCESS : EXIT_FAILURE;
+}
+
+std::string format_duration(time_t start, time_t end)
+{
+ int seconds = (int)difftime(end, start);
+ std::stringstream ss;
+ int minutes = seconds / 60;
+ seconds = seconds % 60;
+ if (minutes > 0)
+ {
+ ss << minutes << " minute";
+ if (minutes == 0 || minutes > 1)
+ {
ss << "s";
}
- return ss.str();
+ ss << " ";
}
-
- void write_log(bool header) {
- path_t log = log_stream.str();
- if (!log.empty()) {
- if (header) {
- cout_ << "\nLog:\n";
- }
- cout_ << log << std::endl;
- }
- }
-
- bool init_input_file(const std::string &filename, IfcParse::IfcFile &ifc_file, bool no_progress, bool mmap)
+ ss << seconds << " second";
+ if (seconds == 0 || seconds > 1)
{
- time_t start, end;
+ ss << "s";
+ }
+ return ss.str();
+}
- // Prevent IfcFile::Init() prints by setting output to null temporarily
- if (no_progress) { Logger::SetOutput(NULL, &log_stream); }
+void write_log(bool header)
+{
+ path_t log = log_stream.str();
+ if (!log.empty())
+ {
+ if (header)
+ {
+ cout_ << "\nLog:\n";
+ }
+ cout_ << log << std::endl;
+ }
+}
- time(&start);
+bool init_input_file(const std::string &filename, IfcParse::IfcFile &ifc_file,
+ bool no_progress, bool mmap)
+{
+ time_t start, end;
+ // Prevent IfcFile::Init() prints by setting output to null temporarily
+ if (no_progress)
+ {
+ Logger::SetOutput(NULL, &log_stream);
+ }
+
+ time(&start);
#ifdef USE_MMAP
- if (!ifc_file.Init(filename, mmap)) {
+ if (!ifc_file.Init(filename, mmap))
+ {
#else
- (void)mmap;
- if (!ifc_file.Init(filename)) {
+ (void)mmap;
+ if (!ifc_file.Init(filename))
+ {
#endif
- Logger::Error("Unable to parse input file '" + filename + "'");
- return false;
- }
- time(&end);
+ Logger::Error("Unable to parse input file '" + filename + "'");
+ return false;
+ }
+ time(&end);
- if (no_progress) { Logger::SetOutput(&cout_, &log_stream); }
- else { Logger::Status("Parsing input file took " + format_duration(start, end)); }
+ if (no_progress)
+ {
+ Logger::SetOutput(&cout_, &log_stream);
+ }
+ else
+ {
+ Logger::Status("Parsing input file took " + format_duration(start, end));
+ }
- return true;
+ return true;
+}
+
+bool append_filter(const std::string &type,
+ const std::vector &values, geom_filter &filter)
+{
+ geom_filter temp;
+ parse_filter(temp, values);
+ // Merge values only if type and arg match.
+ if ((filter.type != geom_filter::UNUSED && filter.type != temp.type) ||
+ (!filter.arg.empty() && filter.arg != temp.arg))
+ {
+ cerr_ << "[Error] Multiple '" << type.c_str()
+ << "' filters specified with different criteria\n";
+ return false;
+ }
+ filter.type = temp.type;
+ filter.values.insert(temp.values.begin(), temp.values.end());
+ filter.arg = temp.arg;
+ return true;
+}
+
+size_t
+read_filters_from_file(const std::string &filename,
+ inclusion_filter &include_filter,
+ inclusion_traverse_filter &include_traverse_filter,
+ exclusion_filter &exclude_filter,
+ exclusion_traverse_filter &exclude_traverse_filter)
+{
+ std::ifstream filter_file(IfcUtil::path::from_utf8(filename).c_str());
+
+ if (!filter_file.is_open())
+ {
+ cerr_ << "[Error] Unable to open filter file '"
+ << IfcUtil::path::from_utf8(filename)
+ << "' or the file does not exist.\n";
+ return 0;
+ }
+
+ size_t line_number = 1, num_filters = 0;
+ for (std::string line; std::getline(filter_file, line); ++line_number)
+ {
+ boost::trim(line);
+ if (line.empty())
+ {
+ continue;
}
- bool append_filter(const std::string& type, const std::vector& values, geom_filter& filter)
+ std::vector values;
+ boost::split(values, line, boost::is_any_of("\t "),
+ boost::token_compress_on);
+ if (values.empty())
{
- geom_filter temp;
- parse_filter(temp, values);
- // Merge values only if type and arg match.
- if ((filter.type != geom_filter::UNUSED && filter.type != temp.type) || (!filter.arg.empty() && filter.arg != temp.arg)) {
- cerr_ << "[Error] Multiple '" << type.c_str() << "' filters specified with different criteria\n";
- return false;
- }
- filter.type = temp.type;
- filter.values.insert(temp.values.begin(), temp.values.end());
- filter.arg = temp.arg;
- return true;
+ continue;
}
- size_t read_filters_from_file(
- const std::string& filename,
- inclusion_filter& include_filter,
- inclusion_traverse_filter& include_traverse_filter,
- exclusion_filter& exclude_filter,
- exclusion_traverse_filter& exclude_traverse_filter)
+ std::string type = values.front();
+ values.erase(values.begin());
+ // Support both "--include=arg GlobalId 1VQ5n5$RrEbPk8le4ZCI81" and
+ // "include arg GlobalId 1VQ5n5$RrEbPk8le4ZCI81" and tolerate extraneous
+ // whitespace.
+ boost::trim_left_if(type, boost::is_any_of("-"));
+ size_t equal_pos = type.find('=');
+ if (equal_pos != std::string::npos)
{
- std::ifstream filter_file(IfcUtil::path::from_utf8(filename).c_str());
+ std::string value = type.substr(equal_pos + 1);
+ type = type.substr(0, equal_pos);
+ values.insert(values.begin(), value);
+ }
- if (!filter_file.is_open()) {
- cerr_ << "[Error] Unable to open filter file '" << IfcUtil::path::from_utf8(filename) << "' or the file does not exist.\n";
+ try
+ {
+ if (type == "include")
+ {
+ if (append_filter("include", values, include_filter))
+ {
+ ++num_filters;
+ }
+ }
+ else if (type == "include+")
+ {
+ if (append_filter("include+", values, include_traverse_filter))
+ {
+ ++num_filters;
+ }
+ }
+ else if (type == "exclude")
+ {
+ if (append_filter("exclude", values, exclude_filter))
+ {
+ ++num_filters;
+ }
+ }
+ else if (type == "exclude+")
+ {
+ if (append_filter("exclude+", values, exclude_traverse_filter))
+ {
+ ++num_filters;
+ }
+ }
+ else
+ {
+ cerr_ << "[Error] Invalid filtering type at line "
+ << boost::lexical_cast(line_number) << "\n";
return 0;
}
+ }
+ catch (...)
+ {
+ cerr_ << "[Error] Unable to parse filter at line "
+ << boost::lexical_cast(line_number) << ".\n";
+ return 0;
+ }
+ }
+ return num_filters;
+}
- size_t line_number = 1, num_filters = 0;
- for (std::string line; std::getline(filter_file, line); ++line_number) {
- boost::trim(line);
- if (line.empty()) {
- continue;
- }
+void parse_filter(geom_filter &filter, const std::vector &values)
+{
+ if (values.size() == 0)
+ {
+ throw po::validation_error(
+ po::validation_error::at_least_one_value_required);
+ }
+ std::string type = *values.begin();
+ if (type == "entities")
+ {
+ filter.type = geom_filter::ENTITY_TYPE;
+ }
+ else if (type == "layers")
+ {
+ filter.type = geom_filter::LAYER_NAME;
+ }
+ else if (type == "arg")
+ {
+ filter.type = geom_filter::ENTITY_ARG;
+ filter.arg = *(values.begin() + 1);
+ if (std::find(supported_args.begin(), supported_args.end(), filter.arg) ==
+ supported_args.end())
+ {
+ throw po::validation_error(po::validation_error::invalid_option_value);
+ }
+ }
+ else
+ {
+ throw po::validation_error(po::validation_error::invalid_option_value);
+ }
+ filter.values.insert(values.begin() +
+ (filter.type == geom_filter::ENTITY_ARG ? 2 : 1),
+ values.end());
+}
- std::vector values;
- boost::split(values, line, boost::is_any_of("\t "), boost::token_compress_on);
- if (values.empty()) {
- continue;
- }
+void validate(boost::any &v, const std::vector &values,
+ inclusion_filter *, int)
+{
+ /// @todo For now only single --include, --include+, --exclude, or
+ /// --exclude+ supported. Support having multiple.
+ po::validators::check_first_occurrence(v);
+ inclusion_filter filter;
+ parse_filter(filter, values);
+ v = filter;
+}
- std::string type = values.front();
- values.erase(values.begin());
- // Support both "--include=arg GlobalId 1VQ5n5$RrEbPk8le4ZCI81" and "include arg GlobalId 1VQ5n5$RrEbPk8le4ZCI81"
- // and tolerate extraneous whitespace.
- boost::trim_left_if(type, boost::is_any_of("-"));
- size_t equal_pos = type.find('=');
- if (equal_pos != std::string::npos) {
- std::string value = type.substr(equal_pos + 1);
- type = type.substr(0, equal_pos);
- values.insert(values.begin(), value);
- }
+void validate(boost::any &v, const std::vector &values,
+ inclusion_traverse_filter *, int)
+{
+ po::validators::check_first_occurrence(v);
+ inclusion_traverse_filter filter;
+ parse_filter(filter, values);
+ v = filter;
+}
- try {
- if (type == "include") { if (append_filter("include", values, include_filter)) { ++num_filters; } }
- else if (type == "include+") { if (append_filter("include+", values, include_traverse_filter)) { ++num_filters; } }
- else if (type == "exclude") { if (append_filter("exclude", values, exclude_filter)) { ++num_filters; } }
- else if (type == "exclude+") { if (append_filter("exclude+", values, exclude_traverse_filter)) { ++num_filters; } }
- else {
- cerr_ << "[Error] Invalid filtering type at line " << boost::lexical_cast(line_number) << "\n";
- return 0;
- }
- } catch(...) {
- cerr_ << "[Error] Unable to parse filter at line " << boost::lexical_cast(line_number) << ".\n";
- return 0;
- }
+void validate(boost::any &v, const std::vector &values,
+ exclusion_filter *, int)
+{
+ po::validators::check_first_occurrence(v);
+ exclusion_filter filter;
+ parse_filter(filter, values);
+ v = filter;
+}
+
+void validate(boost::any &v, const std::vector &values,
+ exclusion_traverse_filter *, int)
+{
+ po::validators::check_first_occurrence(v);
+ exclusion_traverse_filter filter;
+ parse_filter(filter, values);
+ v = filter;
+}
+
+/// @todo Clean up this filter initialization code further.
+/// @return References to the used filter functors, if none an error occurred.
+std::vector
+setup_filters(const std::vector &filters,
+ const std::string &output_extension)
+{
+ std::vector filter_funcs;
+ BOOST_FOREACH (const geom_filter &f, filters)
+ {
+ if (f.type == geom_filter::ENTITY_TYPE)
+ {
+ entity_filter.include = f.include;
+ entity_filter.traverse = f.traverse;
+ try
+ {
+ entity_filter.populate(f.values);
}
- return num_filters;
- }
-
- void parse_filter(geom_filter &filter, const std::vector& values)
- {
- if (values.size() == 0) {
- throw po::validation_error(po::validation_error::at_least_one_value_required);
+ catch (const IfcParse::IfcException &e)
+ {
+ cerr_ << "[Error] " << e.what() << std::endl;
+ return std::vector();
}
- std::string type = *values.begin();
- if (type == "entities") {
- filter.type = geom_filter::ENTITY_TYPE;
- } else if (type == "layers") {
- filter.type = geom_filter::LAYER_NAME;
- } else if (type == "arg") {
- filter.type = geom_filter::ENTITY_ARG;
- filter.arg = *(values.begin() + 1);
- if (std::find(supported_args.begin(), supported_args.end(), filter.arg) == supported_args.end()) {
- throw po::validation_error(po::validation_error::invalid_option_value);
- }
- } else {
- throw po::validation_error(po::validation_error::invalid_option_value);
+ }
+ else if (f.type == geom_filter::LAYER_NAME)
+ {
+ layer_filter.include = f.include;
+ layer_filter.traverse = f.traverse;
+ layer_filter.populate(f.values);
+ }
+ else if (f.type == geom_filter::ENTITY_ARG)
+ {
+ if (f.arg == GUID_ARG)
+ {
+ guid_filter.include = f.include;
+ guid_filter.traverse = f.traverse;
+ guid_filter.populate(f.values);
}
- filter.values.insert(values.begin() + (filter.type == geom_filter::ENTITY_ARG ? 2 : 1), values.end());
- }
-
- void validate(boost::any& v, const std::vector& values, inclusion_filter*, int)
- {
- /// @todo For now only single --include, --include+, --exclude, or --exclude+ supported. Support having multiple.
- po::validators::check_first_occurrence(v);
- inclusion_filter filter;
- parse_filter(filter, values);
- v = filter;
- }
-
- void validate(boost::any& v, const std::vector& values, inclusion_traverse_filter*, int)
- {
- po::validators::check_first_occurrence(v);
- inclusion_traverse_filter filter;
- parse_filter(filter, values);
- v = filter;
- }
-
- void validate(boost::any& v, const std::vector& values, exclusion_filter*, int)
- {
- po::validators::check_first_occurrence(v);
- exclusion_filter filter;
- parse_filter(filter, values);
- v = filter;
- }
-
- void validate(boost::any& v, const std::vector& values, exclusion_traverse_filter*, int)
- {
- po::validators::check_first_occurrence(v);
- exclusion_traverse_filter filter;
- parse_filter(filter, values);
- v = filter;
- }
-
-
- /// @todo Clean up this filter initialization code further.
- /// @return References to the used filter functors, if none an error occurred.
- std::vector setup_filters(const std::vector& filters, const std::string& output_extension)
- {
- std::vector filter_funcs;
- BOOST_FOREACH(const geom_filter& f, filters) {
- if (f.type == geom_filter::ENTITY_TYPE) {
- entity_filter.include = f.include;
- entity_filter.traverse = f.traverse;
- try {
- entity_filter.populate(f.values);
- } catch (const IfcParse::IfcException& e) {
- cerr_ << "[Error] " << e.what() << std::endl;
- return std::vector();
- }
- } else if (f.type == geom_filter::LAYER_NAME) {
- layer_filter.include = f.include;
- layer_filter.traverse = f.traverse;
- layer_filter.populate(f.values);
- } else if (f.type == geom_filter::ENTITY_ARG) {
- if (f.arg == GUID_ARG) {
- guid_filter.include = f.include;
- guid_filter.traverse = f.traverse;
- guid_filter.populate(f.values);
- } else if (f.arg == NAME_ARG) {
- name_filter.include = f.include;
- name_filter.traverse = f.traverse;
- name_filter.populate(f.values);
- } else if (f.arg == DESC_ARG) {
- desc_filter.include = f.include;
- desc_filter.traverse = f.traverse;
- desc_filter.populate(f.values);
- } else if (f.arg == TAG_ARG) {
- tag_filter.include = f.include;
- tag_filter.traverse = f.traverse;
- tag_filter.populate(f.values);
- }
- }
+ else if (f.arg == NAME_ARG)
+ {
+ name_filter.include = f.include;
+ name_filter.traverse = f.traverse;
+ name_filter.populate(f.values);
}
-
- // If no entity names are specified these are the defaults to skip from output
- if (entity_filter.values.empty()) {
- try {
- std::set entities;
- entities.insert("IfcSpace");
- if (output_extension == ".svg") {
- entity_filter.include = true;
- } else {
- entities.insert("IfcOpeningElement");
- }
- entity_filter.populate(entities);
- } catch (const IfcParse::IfcException& e) {
- cerr_ << "[Error] " << e.what() << std::endl;
- return std::vector();
- }
+ else if (f.arg == DESC_ARG)
+ {
+ desc_filter.include = f.include;
+ desc_filter.traverse = f.traverse;
+ desc_filter.populate(f.values);
+ }
+ else if (f.arg == TAG_ARG)
+ {
+ tag_filter.include = f.include;
+ tag_filter.traverse = f.traverse;
+ tag_filter.populate(f.values);
}
-
- if (!layer_filter.values.empty()) { filter_funcs.push_back(boost::ref(layer_filter)); }
- if (!entity_filter.values.empty()) { filter_funcs.push_back(boost::ref(entity_filter)); }
- if (!guid_filter.values.empty()) { filter_funcs.push_back(boost::ref(guid_filter)); }
- if (!name_filter.values.empty()) { filter_funcs.push_back(boost::ref(name_filter)); }
- if (!desc_filter.values.empty()) { filter_funcs.push_back(boost::ref(desc_filter)); }
- if (!tag_filter.values.empty()) { filter_funcs.push_back(boost::ref(tag_filter)); }
-
- return filter_funcs;
}
-bool reuse_ok_(SerializerSettings settings, const IfcSchema::IfcProduct::list::ptr &products, IfcGeom::Kernel kernel)
+ }
+
+ // If no entity names are specified these are the defaults to skip from
+ // output
+ if (entity_filter.values.empty())
+ {
+ try
+ {
+ std::set entities;
+ entities.insert("IfcSpace");
+ if (output_extension == ".svg")
+ {
+ entity_filter.include = true;
+ }
+ else
+ {
+ entities.insert("IfcOpeningElement");
+ }
+ entity_filter.populate(entities);
+ }
+ catch (const IfcParse::IfcException &e)
+ {
+ cerr_ << "[Error] " << e.what() << std::endl;
+ return std::vector();
+ }
+ }
+
+ if (!layer_filter.values.empty())
+ {
+ filter_funcs.push_back(boost::ref(layer_filter));
+ }
+ if (!entity_filter.values.empty())
+ {
+ filter_funcs.push_back(boost::ref(entity_filter));
+ }
+ if (!guid_filter.values.empty())
+ {
+ filter_funcs.push_back(boost::ref(guid_filter));
+ }
+ if (!name_filter.values.empty())
+ {
+ filter_funcs.push_back(boost::ref(name_filter));
+ }
+ if (!desc_filter.values.empty())
+ {
+ filter_funcs.push_back(boost::ref(desc_filter));
+ }
+ if (!tag_filter.values.empty())
+ {
+ filter_funcs.push_back(boost::ref(tag_filter));
+ }
+
+ return filter_funcs;
+}
+bool reuse_ok_(SerializerSettings settings,
+ const IfcSchema::IfcProduct::list::ptr &products,
+ IfcGeom::Kernel kernel)
{
// IfcGeom::Kernel kernel;
@@ -1465,17 +2002,20 @@ bool reuse_ok_(SerializerSettings settings, const IfcSchema::IfcProduct::list::p
std::set associated_single_materials;
- for (IfcSchema::IfcProduct::list::it it = products->begin(); it != products->end(); ++it)
+ for (IfcSchema::IfcProduct::list::it it = products->begin();
+ it != products->end(); ++it)
{
IfcSchema::IfcProduct *product = *it;
- if (!settings.get(IfcGeom::IteratorSettings::DISABLE_OPENING_SUBTRACTIONS) &&
+ if (!settings.get(
+ IfcGeom::IteratorSettings::DISABLE_OPENING_SUBTRACTIONS) &&
kernel.find_openings(product)->size())
{
return false;
}
if (settings.get(IfcGeom::IteratorSettings::APPLY_LAYERSETS))
{
- IfcSchema::IfcRelAssociates::list::ptr associations = product->HasAssociations();
+ IfcSchema::IfcRelAssociates::list::ptr associations =
+ product->HasAssociations();
for (IfcSchema::IfcRelAssociates::list::it jt = associations->begin();
jt != associations->end(); ++jt)
{
@@ -1483,7 +2023,8 @@ bool reuse_ok_(SerializerSettings settings, const IfcSchema::IfcProduct::list::p
(*jt)->as();
if (assoc)
{
- if (assoc->RelatingMaterial()->is(IfcSchema::Type::IfcMaterialLayerSetUsage))
+ if (assoc->RelatingMaterial()->is(
+ IfcSchema::Type::IfcMaterialLayerSetUsage))
{
// TODO: Check whether single layer?
return false;
@@ -1491,30 +2032,59 @@ bool reuse_ok_(SerializerSettings settings, const IfcSchema::IfcProduct::list::p
}
}
}
- // Note that this can be a nullptr (!), but the fact that set size should be one still holds
- associated_single_materials.insert(kernel.get_single_material_association(product));
+ // Note that this can be a nullptr (!), but the fact that set size
+ // should be one still holds
+ associated_single_materials.insert(
+ kernel.get_single_material_association(product));
if (associated_single_materials.size() > 1)
return false;
}
return associated_single_materials.size() == 1;
}
-void create_element(SerializerSettings &settings, IfcproductRepresentation &rep)
+void write_element(boost::shared_ptr serializer,
+ IfcproductRepresentation *rep, bool is_tesselated)
{
+ // IfcGeom::Element *geom_object = context_iterator.get();
+
+ IfcGeom::Element *geom_object = rep->element;
+ if (is_tesselated)
+ {
+ serializer->write(
+ static_cast *>(
+ geom_object));
+ }
+ else
+ {
+ serializer->write(
+ static_cast *>(geom_object));
+ }
+}
+
+void create_element(SerializerSettings &settings, IfcproductRepresentation &rep,
+ IfcGeom::Kernel kernel)
+{
+
+
+ ////////////////////////////////////////////////////////////
+ // is kernel thread-safe (-ish) ?
+ ////////////////////////////////////////////////////////////
+
Logger::Status("processing item #: " + std::to_string(rep.index));
- IfcGeom::Kernel kernel;
- IfcSchema::IfcRepresentation *representation= rep.representation;
+ // IfcGeom::Kernel kernel;
+ IfcSchema::IfcRepresentation *representation = rep.representation;
IfcSchema::IfcProduct *product = rep.product;
// IfcGeom::BRepElement *element;
- rep.element =
- kernel.create_brep_for_representation_and_product(settings, representation, product);
- //if(geometry_reuse_ok_for_current_representation_)
+ rep.element = kernel.create_brep_for_representation_and_product(
+ settings, representation, product);
+ // if(geometry_reuse_ok_for_current_representation_)
// {
- // // element = kernel.create_brep_for_processed_representation(settings, representation,
- // // product,
- // // current_shape_model);
- // }
-
+ // // element =
+ // kernel.create_brep_for_processed_representation(settings,
+ // representation,
+ // // product,
+ // // current_shape_model);
+ // }
return;
}
@@ -1522,48 +2092,59 @@ void create_element(SerializerSettings &settings, IfcproductRepresentation &rep)
//@todo MOVE this include
#include
-Bounds compute_bounds(IfcParse::IfcFile* ifc_file, IfcGeom::Kernel kernel)
+Bounds compute_bounds(IfcParse::IfcFile *ifc_file, IfcGeom::Kernel kernel)
+{
+ gp_XYZ bounds_min_;
+ gp_XYZ bounds_max_;
+ Bounds bounds;
+
+ for (int i = 1; i < 4; ++i)
{
- gp_XYZ bounds_min_;
- gp_XYZ bounds_max_;
- Bounds bounds;
-
- for (int i = 1; i < 4; ++i) {
- bounds_min_.SetCoord(i, std::numeric_limits::infinity());
- bounds_max_.SetCoord(i, -std::numeric_limits::infinity());
- }
-
- IfcSchema::IfcProduct::list::ptr products = ifc_file->entitiesByType();
- for (IfcSchema::IfcProduct::list::it iter = products->begin(); iter != products->end(); ++iter) {
- IfcSchema::IfcProduct* product = *iter;
- if (product->hasObjectPlacement()) {
- // Use a fresh trsf every time in order to prevent the result to be concatenated
- gp_Trsf trsf;
- bool success = false;
-
- try {
- success = kernel.convert(product->ObjectPlacement(), trsf);
- } catch (const std::exception& e) {
- Logger::Error(e);
- } catch (...) {
- Logger::Error("Failed to construct placement");
- }
-
- if (!success) {
- continue;
- }
-
- const gp_XYZ& pos = trsf.TranslationPart();
- bounds_min_.SetX(std::min(bounds_min_.X(), pos.X()));
- bounds_min_.SetY(std::min(bounds_min_.Y(), pos.Y()));
- bounds_min_.SetZ(std::min(bounds_min_.Z(), pos.Z()));
- bounds_max_.SetX(std::max(bounds_max_.X(), pos.X()));
- bounds_max_.SetY(std::max(bounds_max_.Y(), pos.Y()));
- bounds_max_.SetZ(std::max(bounds_max_.Z(), pos.Z()));
- }
- }
- bounds.min = bounds_min_;
- bounds.max = bounds_max_;
- return bounds;
+ bounds_min_.SetCoord(i, std::numeric_limits::infinity());
+ bounds_max_.SetCoord(i, -std::numeric_limits::infinity());
}
+ IfcSchema::IfcProduct::list::ptr products =
+ ifc_file->entitiesByType();
+ for (IfcSchema::IfcProduct::list::it iter = products->begin();
+ iter != products->end(); ++iter)
+ {
+ IfcSchema::IfcProduct *product = *iter;
+ if (product->hasObjectPlacement())
+ {
+ // Use a fresh trsf every time in order to prevent the
+ // result to be concatenated
+ gp_Trsf trsf;
+ bool success = false;
+
+ try
+ {
+ success = kernel.convert(product->ObjectPlacement(), trsf);
+ }
+ catch (const std::exception &e)
+ {
+ Logger::Error(e);
+ }
+ catch (...)
+ {
+ Logger::Error("Failed to construct placement");
+ }
+
+ if (!success)
+ {
+ continue;
+ }
+
+ const gp_XYZ &pos = trsf.TranslationPart();
+ bounds_min_.SetX(std::min(bounds_min_.X(), pos.X()));
+ bounds_min_.SetY(std::min(bounds_min_.Y(), pos.Y()));
+ bounds_min_.SetZ(std::min(bounds_min_.Z(), pos.Z()));
+ bounds_max_.SetX(std::max(bounds_max_.X(), pos.X()));
+ bounds_max_.SetY(std::max(bounds_max_.Y(), pos.Y()));
+ bounds_max_.SetZ(std::max(bounds_max_.Z(), pos.Z()));
+ }
+ }
+ bounds.min = bounds_min_;
+ bounds.max = bounds_max_;
+ return bounds;
+}
diff --git a/test/input b/test/input
index 2abd02c2a3..e3d6488df2 160000
--- a/test/input
+++ b/test/input
@@ -1 +1 @@
-Subproject commit 2abd02c2a3078fa52601dd8d5c9630c982a0e25c
+Subproject commit e3d6488df2dcc55308dc8810b1f9d911117dcbee