Revive some temporarily disabled features in de 0.6 branch

This commit is contained in:
Thomas Krijnen
2018-09-07 14:08:56 +02:00
parent 03da7bc6e4
commit 0df4edff01
12 changed files with 244 additions and 351 deletions
+26 -75
View File
@@ -33,6 +33,7 @@
#include "../serializers/XmlSerializer.h" #include "../serializers/XmlSerializer.h"
#include "../serializers/SvgSerializer.h" #include "../serializers/SvgSerializer.h"
#include "../ifcgeom_schema_agnostic/IfcGeomFilter.h"
#include "../ifcgeom_schema_agnostic/IfcGeomIterator.h" #include "../ifcgeom_schema_agnostic/IfcGeomIterator.h"
#include <Standard_Version.hxx> #include <Standard_Version.hxx>
@@ -119,16 +120,9 @@ static std::stringstream log_stream;
void write_log(bool); void write_log(bool);
/// @todo make the filters non-global /// @todo make the filters non-global
/*
IfcGeom::entity_filter entity_filter; // Entity filter is used always by default. IfcGeom::entity_filter entity_filter; // Entity filter is used always by default.
IfcGeom::layer_filter layer_filter; IfcGeom::layer_filter layer_filter;
const std::string NAME_ARG = "Name", GUID_ARG = "GlobalId", DESC_ARG = "Description", TAG_ARG = "Tag"; IfcGeom::attribute_filter attribute_filter;
boost::array<std::string, 4> supported_args = { { NAME_ARG, GUID_ARG, DESC_ARG, TAG_ARG } };
IfcGeom::string_arg_filter guid_filter(IfcSchema::Type::IfcRoot, 0); // IfcRoot.GlobalId
// Note: skipping IfcRoot OwnerHistory, argument index 1
IfcGeom::string_arg_filter name_filter(IfcSchema::Type::IfcRoot, 2); // IfcRoot.Name
IfcGeom::string_arg_filter desc_filter(IfcSchema::Type::IfcRoot, 3); // IfcRoot.Description
IfcGeom::string_arg_filter tag_filter(IfcSchema::Type::IfcProxy, 8, IfcSchema::Type::IfcElement, 7); // IfcProxy.Tag & IfcElement.Tag
struct geom_filter struct geom_filter
{ {
@@ -151,7 +145,6 @@ struct exclusion_traverse_filter : public geom_filter { exclusion_traverse_filte
size_t read_filters_from_file(const std::string&, inclusion_filter&, inclusion_traverse_filter&, exclusion_filter&, exclusion_traverse_filter&); size_t read_filters_from_file(const std::string&, inclusion_filter&, inclusion_traverse_filter&, exclusion_filter&, exclusion_traverse_filter&);
void parse_filter(geom_filter &, const std::vector<std::string>&); void parse_filter(geom_filter &, const std::vector<std::string>&);
std::vector<IfcGeom::filter_t> setup_filters(const std::vector<geom_filter>&, const std::string&); std::vector<IfcGeom::filter_t> setup_filters(const std::vector<geom_filter>&, const std::string&);
*/
bool init_input_file(const std::string& filename, IfcParse::IfcFile*& ifc_file, bool no_progress, bool mmap); bool init_input_file(const std::string& filename, IfcParse::IfcFile*& ifc_file, bool no_progress, bool mmap);
@@ -179,13 +172,11 @@ int main(int argc, char** argv)
double deflection_tolerance; double deflection_tolerance;
/*
inclusion_filter include_filter; inclusion_filter include_filter;
inclusion_traverse_filter include_traverse_filter; inclusion_traverse_filter include_traverse_filter;
exclusion_filter exclude_filter; exclusion_filter exclude_filter;
exclusion_traverse_filter exclude_traverse_filter; exclusion_traverse_filter exclude_traverse_filter;
std::string filter_filename; std::string filter_filename;
*/
po::options_description geom_options("Geometry options"); po::options_description geom_options("Geometry options");
geom_options.add_options() geom_options.add_options()
@@ -232,14 +223,13 @@ int main(int argc, char** argv)
("enable-layerset-slicing", ("enable-layerset-slicing",
"Specifies whether to enable the slicing of products according " "Specifies whether to enable the slicing of products according "
"to their associated IfcMaterialLayerSet.") "to their associated IfcMaterialLayerSet.")
/*
("include", po::value<inclusion_filter>(&include_filter)->multitoken(), ("include", po::value<inclusion_filter>(&include_filter)->multitoken(),
"Specifies that the entities that match a specific filtering criteria are to be included in the geometrical output:\n" "Specifies that the instances that match a specific filtering criteria are to be included in the geometrical output:\n"
"1) 'entities': the following list of types should be included. SVG output defaults " "1) 'entities': the following list of types should be included. SVG output defaults "
"to IfcSpace to be included. The entity names are handled case-insensitively.\n" "to IfcSpace to be included. The entity names are handled case-insensitively.\n"
"2) 'layers': the entities that are assigned to presentation layers of which names " "2) 'layers': the instances that are assigned to presentation layers of which names "
"match the given values should be included.\n" "match the given values should be included.\n"
"3) 'arg <ArgumentName>': the following list of values for that specific argument should be included. " "3) 'attribute <AttributeName>': products whose value for <AttributeName> should be included\n. "
"Currently supported arguments are GlobalId, Name, Description, and Tag.\n\n" "Currently supported arguments are GlobalId, Name, Description, and Tag.\n\n"
"The values for 'layers' and 'arg' are handled case-sensitively (wildcards supported)." "The values for 'layers' and 'arg' are handled case-sensitively (wildcards supported)."
"--include and --exclude cannot be placed right before input file argument and " "--include and --exclude cannot be placed right before input file argument and "
@@ -258,8 +248,7 @@ int main(int argc, char** argv)
"Specifies a filter file that describes the used filtering criteria. Supported formats " "Specifies a filter file that describes the used filtering criteria. Supported formats "
"are '--include=arg GlobalId ...' and 'include arg GlobalId ...'. Spaces and tabs can be used as delimeters." "are '--include=arg GlobalId ...' and 'include arg GlobalId ...'. Spaces and tabs can be used as delimeters."
"Multiple filters of same type with different values can be inserted on their own lines. " "Multiple filters of same type with different values can be inserted on their own lines. "
"See --include, --include+, --exclude, and --exclude+ for more details."); "See --include, --include+, --exclude, and --exclude+ for more details.")
*/
("no-normals", ("no-normals",
"Disables computation of normals. Saves time and file size and is useful " "Disables computation of normals. Saves time and file size and is useful "
"in instances where you're going to recompute normals for the exported " "in instances where you're going to recompute normals for the exported "
@@ -490,7 +479,6 @@ int main(int argc, char** argv)
return exit_code; return exit_code;
} }
/*
if (!filter_filename.empty()) { if (!filter_filename.empty()) {
size_t num_filters = read_filters_from_file(filter_filename, include_filter, include_traverse_filter, exclude_filter, exclude_traverse_filter); size_t num_filters = read_filters_from_file(filter_filename, include_filter, include_traverse_filter, exclude_filter, exclude_traverse_filter);
if (num_filters) { if (num_filters) {
@@ -514,14 +502,10 @@ int main(int argc, char** argv)
return EXIT_FAILURE; return EXIT_FAILURE;
} }
if (!entity_filter.values.empty()) { entity_filter.update_description(); Logger::Notice(entity_filter.description); } if (!entity_filter.entity_names.empty()) { entity_filter.update_description(); Logger::Notice(entity_filter.description); }
if (!layer_filter.values.empty()) { layer_filter.update_description(); Logger::Notice(layer_filter.description); } if (!layer_filter.values.empty()) { layer_filter.update_description(); Logger::Notice(layer_filter.description); }
if (!guid_filter.values.empty()) { guid_filter.update_description(); Logger::Notice(guid_filter.description); } if (!attribute_filter.attribute_name.empty()) { attribute_filter.update_description(); Logger::Notice(layer_filter.description); }
if (!name_filter.values.empty()) { name_filter.update_description(); Logger::Notice(name_filter.description); }
if (!desc_filter.values.empty()) { desc_filter.update_description(); Logger::Notice(desc_filter.description); }
if (!tag_filter.values.empty()) { tag_filter.update_description(); Logger::Notice(tag_filter.description); }
*/
SerializerSettings settings; SerializerSettings settings;
/// @todo Make APPLY_DEFAULT_MATERIALS configurable? Quickly tested setting this to false and using obj exporter caused the program to crash and burn. /// @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::APPLY_DEFAULT_MATERIALS, true);
@@ -629,7 +613,7 @@ int main(int argc, char** argv)
return EXIT_FAILURE; return EXIT_FAILURE;
} }
IfcGeom::Iterator<real_t> context_iterator(settings, ifc_file); IfcGeom::Iterator<real_t> context_iterator(settings, ifc_file, filter_funcs);
if (!context_iterator.initialize()) { if (!context_iterator.initialize()) {
/// @todo It would be nice to know and print separate error prints for a case where we found no entities /// @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. /// and for a case we found no entities that satisfy our filtering criteria.
@@ -663,7 +647,6 @@ int main(int argc, char** argv)
throw std::runtime_error("needs more work"); throw std::runtime_error("needs more work");
/*
if (!quiet) Logger::Status("Computing bounds..."); if (!quiet) Logger::Status("Computing bounds...");
context_iterator.compute_bounds(); context_iterator.compute_bounds();
if (!quiet) Logger::Status("Done!"); if (!quiet) Logger::Status("Done!");
@@ -672,7 +655,6 @@ int main(int argc, char** argv)
offset[0] = -center.X(); offset[0] = -center.X();
offset[1] = -center.Y(); offset[1] = -center.Y();
offset[2] = -center.Z(); offset[2] = -center.Z();
*/
} else { } else {
if (sscanf(offset_str.c_str(), "%lf;%lf;%lf", &offset[0], &offset[1], &offset[2]) != 3) { if (sscanf(offset_str.c_str(), "%lf;%lf;%lf", &offset[0], &offset[1], &offset[2]) != 3) {
std::cerr << "[Error] Invalid use of --model-offset\n"; std::cerr << "[Error] Invalid use of --model-offset\n";
@@ -826,7 +808,6 @@ bool init_input_file(const std::string& filename, IfcParse::IfcFile*& ifc_file,
} }
/*
bool append_filter(const std::string& type, const std::vector<std::string>& values, geom_filter& filter) bool append_filter(const std::string& type, const std::vector<std::string>& values, geom_filter& filter)
{ {
geom_filter temp; geom_filter temp;
@@ -910,9 +891,6 @@ void parse_filter(geom_filter &filter, const std::vector<std::string>& values)
} else if (type == "arg") { } else if (type == "arg") {
filter.type = geom_filter::ENTITY_ARG; filter.type = geom_filter::ENTITY_ARG;
filter.arg = *(values.begin() + 1); 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 { } else {
throw po::validation_error(po::validation_error::invalid_option_value); throw po::validation_error(po::validation_error::invalid_option_value);
} }
@@ -958,65 +936,38 @@ void validate(boost::any& v, const std::vector<std::string>& values, exclusion_t
std::vector<IfcGeom::filter_t> setup_filters(const std::vector<geom_filter>& filters, const std::string& output_extension) std::vector<IfcGeom::filter_t> setup_filters(const std::vector<geom_filter>& filters, const std::string& output_extension)
{ {
std::vector<IfcGeom::filter_t> filter_funcs; std::vector<IfcGeom::filter_t> filter_funcs;
BOOST_FOREACH(const geom_filter& f, filters) { for(auto& f: filters) {
if (f.type == geom_filter::ENTITY_TYPE) { if (f.type == geom_filter::ENTITY_TYPE) {
entity_filter.include = f.include; entity_filter.include = f.include;
entity_filter.traverse = f.traverse; entity_filter.traverse = f.traverse;
try { entity_filter.entity_names = f.values;
entity_filter.populate(f.values);
} catch (const IfcParse::IfcException& e) {
std::cerr << "[Error] " << e.what() << std::endl;
return std::vector<IfcGeom::filter_t>();
}
} else if (f.type == geom_filter::LAYER_NAME) { } else if (f.type == geom_filter::LAYER_NAME) {
layer_filter.include = f.include; layer_filter.include = f.include;
layer_filter.traverse = f.traverse; layer_filter.traverse = f.traverse;
layer_filter.populate(f.values); layer_filter.populate(f.values);
} else if (f.type == geom_filter::ENTITY_ARG) { } else if (f.type == geom_filter::ENTITY_ARG) {
if (f.arg == GUID_ARG) { attribute_filter.include = f.include;
guid_filter.include = f.include; attribute_filter.traverse = f.traverse;
guid_filter.traverse = f.traverse; attribute_filter.attribute_name = f.arg;
guid_filter.populate(f.values); attribute_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);
}
} }
} }
// If no entity names are specified these are the defaults to skip from output // If no entity names are specified these are the defaults to skip from output
if (entity_filter.values.empty()) { if (entity_filter.entity_names.empty()) {
try { std::set<std::string> entities;
std::set<std::string> entities; entities.insert("IfcSpace");
entities.insert("IfcSpace"); if (output_extension == ".svg") {
if (output_extension == ".svg") { entity_filter.include = true;
entity_filter.include = true; } else {
} else { entities.insert("IfcOpeningElement");
entities.insert("IfcOpeningElement");
}
entity_filter.populate(entities);
} catch (const IfcParse::IfcException& e) {
std::cerr << "[Error] " << e.what() << std::endl;
return std::vector<IfcGeom::filter_t>();
} }
entity_filter.entity_names = entities;
} }
if (!layer_filter.values.empty()) { filter_funcs.push_back(boost::ref(layer_filter)); } 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 (!entity_filter.entity_names.empty()) { filter_funcs.push_back(boost::ref(entity_filter)); }
if (!guid_filter.values.empty()) { filter_funcs.push_back(boost::ref(guid_filter)); } if (!attribute_filter.values.empty()) { filter_funcs.push_back(boost::ref(attribute_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; return filter_funcs;
} }
*/
-2
View File
@@ -221,8 +221,6 @@ public:
std::pair<std::string, double> initializeUnits(IfcSchema::IfcUnitAssignment*); std::pair<std::string, double> initializeUnits(IfcSchema::IfcUnitAssignment*);
static IfcSchema::IfcObjectDefinition* get_decomposing_entity(IfcSchema::IfcProduct*);
template <typename P, typename PP> template <typename P, typename PP>
IfcGeom::BRepElement<P, PP>* create_brep_for_representation_and_product( IfcGeom::BRepElement<P, PP>* create_brep_for_representation_and_product(
const IteratorSettings&, IfcSchema::IfcRepresentation*, IfcSchema::IfcProduct*); const IteratorSettings&, IfcSchema::IfcRepresentation*, IfcSchema::IfcProduct*);
+2 -57
View File
@@ -1332,7 +1332,7 @@ IfcGeom::BRepElement<P, PP>* IfcGeom::Kernel::create_brep_for_representation_and
int parent_id = -1; int parent_id = -1;
try { try {
IfcSchema::IfcObjectDefinition* parent_object = get_decomposing_entity(product); IfcSchema::IfcObjectDefinition* parent_object = get_decomposing_entity(product)->as<IfcSchema::IfcObjectDefinition>();
if (parent_object) { if (parent_object) {
parent_id = parent_object->data().id(); parent_id = parent_object->data().id();
} }
@@ -1499,7 +1499,7 @@ IfcGeom::BRepElement<P, PP>* IfcGeom::Kernel::create_brep_for_processed_represen
{ {
int parent_id = -1; int parent_id = -1;
try { try {
IfcSchema::IfcObjectDefinition* parent_object = get_decomposing_entity(product); IfcSchema::IfcObjectDefinition* parent_object = get_decomposing_entity(product)->as<IfcSchema::IfcObjectDefinition>();
if (parent_object) { if (parent_object) {
parent_id = parent_object->data().id(); parent_id = parent_object->data().id();
} }
@@ -1541,61 +1541,6 @@ IfcGeom::BRepElement<P, PP>* IfcGeom::Kernel::create_brep_for_processed_represen
); );
} }
IfcSchema::IfcObjectDefinition* IfcGeom::Kernel::get_decomposing_entity(IfcSchema::IfcProduct* product) {
IfcSchema::IfcObjectDefinition* parent = 0;
// In case of an opening element, parent to the RelatingBuildingElement
if ( product->declaration().is(IfcSchema::IfcOpeningElement::Class() ) ) {
IfcSchema::IfcOpeningElement* opening = (IfcSchema::IfcOpeningElement*)product;
IfcSchema::IfcRelVoidsElement::list::ptr voids = opening->VoidsElements();
if ( voids->size() ) {
IfcSchema::IfcRelVoidsElement* ifc_void = *voids->begin();
parent = ifc_void->RelatingBuildingElement();
}
} else if ( product->declaration().is(IfcSchema::IfcElement::Class() ) ) {
IfcSchema::IfcElement* element = (IfcSchema::IfcElement*)product;
IfcSchema::IfcRelFillsElement::list::ptr fills = element->FillsVoids();
// In case of a RelatedBuildingElement parent to the opening element
if ( fills->size() ) {
for ( IfcSchema::IfcRelFillsElement::list::it it = fills->begin(); it != fills->end(); ++ it ) {
IfcSchema::IfcRelFillsElement* fill = *it;
IfcSchema::IfcObjectDefinition* ifc_objectdef = fill->RelatingOpeningElement();
if ( product == ifc_objectdef ) continue;
parent = ifc_objectdef;
}
}
// Else simply parent to the containing structure
if (!parent) {
IfcSchema::IfcRelContainedInSpatialStructure::list::ptr parents = element->ContainedInStructure();
if ( parents->size() ) {
IfcSchema::IfcRelContainedInSpatialStructure* container = *parents->begin();
parent = container->RelatingStructure();
}
}
}
// Parent decompositions to the RelatingObject
if (!parent) {
IfcEntityList::ptr parents = product->data().getInverse((&IfcSchema::IfcRelAggregates::Class()), -1);
parents->push(product->data().getInverse((&IfcSchema::IfcRelNests::Class()), -1));
for ( IfcEntityList::it it = parents->begin(); it != parents->end(); ++ it ) {
IfcSchema::IfcRelDecomposes* decompose = (IfcSchema::IfcRelDecomposes*)*it;
IfcSchema::IfcObjectDefinition* ifc_objectdef;
#ifdef USE_IFC4
if (decompose->declaration().is(IfcSchema::IfcRelAggregates::Class())) {
ifc_objectdef = ((IfcSchema::IfcRelAggregates*)decompose)->RelatingObject();
} else {
continue;
}
#else
ifc_objectdef = decompose->RelatingObject();
#endif
if ( product == ifc_objectdef ) continue;
parent = ifc_objectdef;
}
}
return parent;
}
template IFC_GEOM_API IfcGeom::BRepElement<float, float>* IfcGeom::Kernel::create_brep_for_representation_and_product<float, float>( template IFC_GEOM_API IfcGeom::BRepElement<float, float>* IfcGeom::Kernel::create_brep_for_representation_and_product<float, float>(
const IteratorSettings& settings, IfcSchema::IfcRepresentation* representation, IfcSchema::IfcProduct* product); const IteratorSettings& settings, IfcSchema::IfcRepresentation* representation, IfcSchema::IfcProduct* product);
template IFC_GEOM_API IfcGeom::BRepElement<float, double>* IfcGeom::Kernel::create_brep_for_representation_and_product<float, double>( template IFC_GEOM_API IfcGeom::BRepElement<float, double>* IfcGeom::Kernel::create_brep_for_representation_and_product<float, double>(
@@ -14,8 +14,8 @@ namespace IfcGeom {
namespace { namespace {
template <typename P, typename PP> template <typename P, typename PP>
struct MAKE_TYPE_NAME(factory_t) { struct MAKE_TYPE_NAME(factory_t) {
IfcGeom::IteratorImplementation<P, PP>* operator()(const IfcGeom::IteratorSettings& settings, IfcParse::IfcFile* file) const { IfcGeom::IteratorImplementation<P, PP>* operator()(const IfcGeom::IteratorSettings& settings, IfcParse::IfcFile* file, const std::vector<IfcGeom::filter_t>& filters) const {
return new IfcGeom::MAKE_TYPE_NAME(IteratorImplementation_)<P, PP>(settings, file); return new IfcGeom::MAKE_TYPE_NAME(IteratorImplementation_)<P, PP>(settings, file, filters);
} }
}; };
} }
+4 -33
View File
@@ -80,8 +80,8 @@
#include "../ifcgeom_schema_agnostic/IfcGeomMaterial.h" #include "../ifcgeom_schema_agnostic/IfcGeomMaterial.h"
#include "../ifcgeom/IfcGeomIteratorSettings.h" #include "../ifcgeom/IfcGeomIteratorSettings.h"
#include "../ifcgeom/IfcRepresentationShapeItem.h" #include "../ifcgeom/IfcRepresentationShapeItem.h"
#include "../ifcgeom/IfcGeomFilter.h"
#include "../ifcgeom_schema_agnostic/IfcGeomFilter.h"
#include "../ifcgeom_schema_agnostic/IteratorImplementation.h" #include "../ifcgeom_schema_agnostic/IteratorImplementation.h"
// The infamous min & max Win32 #defines can leak here from OCE depending on the build configuration // The infamous min & max Win32 #defines can leak here from OCE depending on the build configuration
@@ -156,15 +156,6 @@ namespace IfcGeom {
typedef P Precision; typedef P Precision;
typedef PP PlacementPrecision; typedef PP PlacementPrecision;
MAKE_TYPE_NAME(IteratorImplementation_)(const IteratorSettings& settings, IfcParse::IfcFile* file, std::vector<IfcGeom::filter_t>& filters)
: settings(settings)
, ifc_file(file)
, owns_ifc_file(false)
, filters_(filters)
{
_initialize();
}
bool initialize() { bool initialize() {
try { try {
initUnits(); initUnits();
@@ -614,7 +605,7 @@ namespace IfcGeom {
ifc_product = ifc_entity->as<IfcSchema::IfcProduct>(); ifc_product = ifc_entity->as<IfcSchema::IfcProduct>();
parent_id = -1; parent_id = -1;
try { try {
IfcSchema::IfcObjectDefinition* parent_object = kernel.get_decomposing_entity(ifc_product); IfcSchema::IfcObjectDefinition* parent_object = kernel.get_decomposing_entity(ifc_product)->as<IfcSchema::IfcObjectDefinition>();
if (parent_object) { if (parent_object) {
parent_id = parent_object->data().id(); parent_id = parent_object->data().id();
} }
@@ -721,31 +712,11 @@ namespace IfcGeom {
bool owns_ifc_file; bool owns_ifc_file;
public: public:
MAKE_TYPE_NAME(IteratorImplementation_)(const IteratorSettings& settings, IfcParse::IfcFile* file) MAKE_TYPE_NAME(IteratorImplementation_)(const IteratorSettings& settings, IfcParse::IfcFile* file, const std::vector<IfcGeom::filter_t>& filters)
: settings(settings) : settings(settings)
, ifc_file(file) , ifc_file(file)
, owns_ifc_file(false) , owns_ifc_file(false)
{ , filters_(filters)
_initialize();
}
MAKE_TYPE_NAME(IteratorImplementation_)(const IteratorSettings& settings, const std::string& filename)
: settings(settings)
, ifc_file(new IfcParse::IfcFile(filename))
, owns_ifc_file(true)
{
_initialize();
}
MAKE_TYPE_NAME(IteratorImplementation_)(const IteratorSettings& settings, void* data, int length)
: settings(settings)
, ifc_file(new IfcParse::IfcFile(data, length))
, owns_ifc_file(true)
{
_initialize();
}
MAKE_TYPE_NAME(IteratorImplementation_)(const IteratorSettings& settings, std::istream& filestream, int length)
: settings(settings)
, ifc_file(new IfcParse::IfcFile(filestream, length))
, owns_ifc_file(true)
{ {
_initialize(); _initialize();
} }
@@ -23,7 +23,8 @@
#ifndef IFCGEOMFILTER_H #ifndef IFCGEOMFILTER_H
#define IFCGEOMFILTER_H #define IFCGEOMFILTER_H
#include "IfcGeom.h" #include "Kernel.h"
#include "../ifcparse/IfcFile.h"
#include <boost/foreach.hpp> #include <boost/foreach.hpp>
#include <boost/function.hpp> #include <boost/function.hpp>
@@ -33,15 +34,13 @@
#include <functional> #include <functional>
namespace IfcGeom namespace IfcGeom {
{
/// The filter function (free or member function) or function object (use boost::ref() to reference to it) /// The filter function (free or member function) or function object (use boost::ref() to reference to it)
/// should return true if the geometry for the product is wanted to be included in the output. /// should return true if the geometry for the product is wanted to be included in the output.
/// http://www.boost.org/doc/libs/1_62_0/doc/html/function/tutorial.html /// http://www.boost.org/doc/libs/1_62_0/doc/html/function/tutorial.html
typedef boost::function<bool(IfcSchema::IfcProduct*)> filter_t; typedef boost::function<bool(IfcUtil::IfcBaseEntity*)> filter_t;
struct filter struct filter {
{
filter() : include(false), traverse(false) {} filter() : include(false), traverse(false) {}
filter(bool incl, bool trav) : include(incl), traverse(trav) {} filter(bool incl, bool trav) : include(incl), traverse(trav) {}
/// Should the product be included (true) or excluded (false). /// Should the product be included (true) or excluded (false).
@@ -52,8 +51,7 @@ namespace IfcGeom
/// Optional description for the filtering criteria of this filter. /// Optional description for the filtering criteria of this filter.
std::string description; std::string description;
bool match(IfcSchema::IfcProduct* prod, const filter_t& pred) const bool match(IfcUtil::IfcBaseEntity* prod, const filter_t& pred) const {
{
bool is_match = pred(prod); bool is_match = pred(prod);
if (!is_match && traverse) { if (!is_match && traverse) {
is_match = traverse_match(prod, pred); is_match = traverse_match(prod, pred);
@@ -61,46 +59,38 @@ namespace IfcGeom
return is_match == include; return is_match == include;
} }
static bool traverse_match(IfcSchema::IfcProduct* prod, const filter_t& pred) static bool traverse_match(IfcUtil::IfcBaseEntity* prod, const filter_t& pred) {
{ IfcUtil::IfcBaseEntity* parent, *current = prod;
throw std::runtime_error("todo"); while ((parent = IfcGeom::Kernel::get_decomposing_entity(current)) != nullptr) {
/*
IfcSchema::IfcProduct* parent, *current = prod;
while ((parent = dynamic_cast<IfcSchema::IfcProduct*>(IfcGeom::Kernel::get_decomposing_entity(current))) != 0) {
if (pred(parent)) { if (pred(parent)) {
return true; return true;
} }
current = parent; current = parent;
} }
*/
return false; return false;
} }
}; };
struct wildcard_filter : public filter struct wildcard_filter : public filter {
{
wildcard_filter() : filter(false, false) {} wildcard_filter() : filter(false, false) {}
wildcard_filter(bool include, bool traverse, const std::set<std::string>& patterns) wildcard_filter(bool include, bool traverse, const std::set<std::string>& patterns)
: filter(include, traverse) : filter(include, traverse) {
{
populate(patterns); populate(patterns);
} }
std::set<boost::regex> values; std::set<boost::regex> values;
void populate(const std::set<std::string>& patterns) void populate(const std::set<std::string>& patterns) {
{
values.clear(); values.clear();
BOOST_FOREACH(const std::string &pattern, patterns) { for(auto& pattern: patterns) {
values.insert(wildcard_string_to_regex(pattern)); values.insert(wildcard_string_to_regex(pattern));
} }
} }
bool match(const std::string &str) const { return match_values(values, str); } bool match(const std::string &str) const { return match_values(values, str); }
static bool match_values(const std::set<boost::regex>& values, const std::string &str) static bool match_values(const std::set<boost::regex>& values, const std::string &str) {
{ for(auto& r: values) {
BOOST_FOREACH(const boost::regex& r, values) {
if (boost::regex_match(str, r)) { if (boost::regex_match(str, r)) {
return true; return true;
} }
@@ -108,11 +98,10 @@ namespace IfcGeom
return false; return false;
} }
static boost::regex wildcard_string_to_regex(std::string str) static boost::regex wildcard_string_to_regex(std::string str) {
{
// Escape all non-"*?" regex special chars // Escape all non-"*?" regex special chars
static const std::string special_chars = "\\^.$|()[]+/"; static const std::string special_chars = "\\^.$|()[]+/";
BOOST_FOREACH(char c, special_chars) { for(auto c: special_chars) {
std::string char_str(1, c); std::string char_str(1, c);
boost::replace_all(str, char_str, "\\" + char_str); boost::replace_all(str, char_str, "\\" + char_str);
} }
@@ -124,127 +113,78 @@ namespace IfcGeom
}; };
/// @note supports only string arguments for now /// @note supports only string arguments for now
struct string_arg_filter : public wildcard_filter struct attribute_filter : public wildcard_filter {
{ std::string attribute_name;
// Using this for now in order to overcome the fact that different classes have the argument at different indices.
typedef std::map<const IfcParse::declaration*, unsigned short> arg_map_t;
arg_map_t args;
/// @todo Take only attribute name when IfcBaseClass and IfcLateBoundEntity are merged. attribute_filter() {}
string_arg_filter(arg_map_t args) : args(args) { assert_arguments(); } attribute_filter(const std::string& attribute_name)
string_arg_filter(const IfcParse::declaration* type, unsigned short index) { args[type] = index; assert_arguments(); } : attribute_name(attribute_name) {}
string_arg_filter(
const IfcParse::declaration* type1, unsigned short index1,
const IfcParse::declaration* type2, unsigned short index2)
{
args[type1] = index1;
args[type2] = index2;
assert_arguments();
}
/// @todo this won't be needed when we have the generic argument name access std::string value(IfcUtil::IfcBaseEntity* prod) const {
void assert_arguments() try {
{ return (std::string) *prod->get(attribute_name);
// TODO } catch (...) {
#if 0 // Either
for (arg_map_t::const_iterator it = args.begin(); it != args.end(); ++it) { // (a) not an attribute name for this entity instance
IfcEntityInstanceData dummy(it->first); // (b) not a string attribute
IfcUtil::IfcBaseClass* base = IfcSchema::SchemaEntity(&dummy); // (c) null for this entity instance
assert(it->second < base->getArgumentCount() && "Argument index out of bounds"); // @todo: validate the filters with a reference to the schema
assert(base->getArgumentType(it->second) == IfcUtil::Argument_STRING && "Argument type not string"); // probably in IfcGeomIteratorImplementation
delete base; return "<invalid>";
} }
#endif
} }
std::string value(IfcSchema::IfcProduct* prod) const bool match(IfcUtil::IfcBaseEntity* prod) const {
{ return wildcard_filter::match(value(prod));
for (arg_map_t::const_iterator it = args.begin(); it != args.end(); ++it) { }
if (prod->declaration().is(*it->first) && it->second < prod->data().getArgumentCount() &&
prod->data().getArgument(it->second)->type() == IfcUtil::Argument_STRING) {
Argument *arg = prod->data().getArgument(it->second);
if (!arg->isNull()) {
return *arg;
}
}
}
return "";
}
bool match(IfcSchema::IfcProduct* prod) const { return wildcard_filter::match(value(prod)); } bool operator()(IfcUtil::IfcBaseEntity* prod) const {
bool operator()(IfcSchema::IfcProduct* prod) const
{
// @note bind1st() and mem_fun() deprecated in C++11, use bind() and mem_fn() when migrating to C++11. // @note bind1st() and mem_fun() deprecated in C++11, use bind() and mem_fn() when migrating to C++11.
return filter::match(prod, std::bind1st(std::mem_fun(&string_arg_filter::match), this)); return filter::match(prod, std::bind1st(std::mem_fun(&attribute_filter::match), this));
} }
void update_description() void update_description() {
{
std::stringstream ss; std::stringstream ss;
ss << (traverse ? "traverse " : "") << (include ? "include" : "exclude"); ss << (traverse ? "traverse " : "") << (include ? "include" : "exclude");
std::vector<std::string> patterns; std::vector<std::string> patterns;
BOOST_FOREACH(const boost::regex& r, values) { for (auto& r : values) {
patterns.push_back("\"" + r.str() + "\""); patterns.push_back("\"" + r.str() + "\"");
} }
// TODO ss << " " << attribute_name;
#if 0
for (arg_map_t::const_iterator it = args.begin(); it != args.end(); ++it) {
IfcEntityInstanceData dummy(it->first);
IfcUtil::IfcBaseClass* base = IfcSchema::SchemaEntity(&dummy);
try {
ss << " " << IfcSchema::ToString::Class()(it->first) << "." << base->declaration().as_entity()->all_attributes()[it->second]->name();
} catch (const std::exception& e) {
Logger::Error(e);
}
delete base;
}
#endif
ss << " values " << boost::algorithm::join(patterns, " "); ss << " values " << boost::algorithm::join(patterns, " ");
description = ss.str(); description = ss.str();
} }
}; };
struct layer_filter : public wildcard_filter struct layer_filter : public wildcard_filter {
{ typedef std::map<std::string, IfcUtil::IfcBaseEntity*> layer_map_t;
typedef std::map<std::string, IfcSchema::IfcPresentationLayerAssignment*> layer_map_t;
layer_filter() {} layer_filter() {}
layer_filter(bool include, bool traverse, const std::set<std::string>& patterns) layer_filter(bool include, bool traverse, const std::set<std::string>& patterns)
: wildcard_filter(include, traverse, patterns) : wildcard_filter(include, traverse, patterns) {}
{
}
bool match(IfcSchema::IfcProduct* prod) const bool match(IfcUtil::IfcBaseEntity* prod) const {
{
throw std::runtime_error("todo");
/*
layer_map_t layers = IfcGeom::Kernel::get_layers(prod); layer_map_t layers = IfcGeom::Kernel::get_layers(prod);
return std::find_if(layers.begin(), layers.end(), wildcards_match(values)) != layers.end(); return std::find_if(layers.begin(), layers.end(), wildcards_match(values)) != layers.end();
*/
} }
bool operator()(IfcSchema::IfcProduct* prod) const bool operator()(IfcUtil::IfcBaseEntity* prod) const {
{
return filter::match(prod, std::bind1st(std::mem_fun(&layer_filter::match), this)); return filter::match(prod, std::bind1st(std::mem_fun(&layer_filter::match), this));
} }
struct wildcards_match struct wildcards_match {
{
wildcards_match(const std::set<boost::regex>& patterns) : patterns(patterns) {} wildcards_match(const std::set<boost::regex>& patterns) : patterns(patterns) {}
bool operator()(const layer_map_t::value_type& layer_map_value) const bool operator()(const layer_map_t::value_type& layer_map_value) const {
{
return wildcard_filter::match_values(patterns, layer_map_value.first); return wildcard_filter::match_values(patterns, layer_map_value.first);
} }
std::set<boost::regex> patterns; std::set<boost::regex> patterns;
}; };
void update_description() void update_description() {
{
std::stringstream ss; std::stringstream ss;
ss << (traverse ? "traverse " : "") << (include ? "include" : "exclude") << " layers"; ss << (traverse ? "traverse " : "") << (include ? "include" : "exclude") << " layers";
std::vector<std::string> str_values; std::vector<std::string> str_values;
@@ -256,62 +196,35 @@ namespace IfcGeom
} }
}; };
struct entity_filter : public filter struct entity_filter : public filter {
{ std::set<std::string> entity_names;
entity_filter() {} entity_filter() {}
entity_filter(bool include, bool traverse/*, const std::set<std::string>& types*/) entity_filter(bool include, bool traverse, const std::set<std::string>& entity_names)
: filter(include, traverse) : filter(include, traverse)
{ , entity_names(entity_names) {}
//populate(types);
}
std::set<const IfcParse::declaration*> values; bool match(IfcUtil::IfcBaseEntity* prod) const {
void populate(const std::set<std::string>&)
{
// TODO
#if 0
values.clear();
BOOST_FOREACH(const std::string& type, types) {
const IfcParse::declaration* ty;
try {
ty = IfcSchema::FromString::Class()(boost::to_upper_copy(type));
} catch (const IfcParse::IfcException&) {
throw IfcParse::IfcException("'" + type + "' does not name a valid IFC entity");
}
values.insert(ty);
/// @todo Add child classes so that containment in set can be in O(log n)
}
#endif
}
bool match(IfcSchema::IfcProduct* prod) const
{
// The set is iterated over to able to filter on subtypes. // The set is iterated over to able to filter on subtypes.
BOOST_FOREACH(const IfcParse::declaration* type, values) { for (auto& name : entity_names) {
if (prod->declaration().is(*type)) { if (prod->declaration().is(name)) {
return true; return true;
} }
} }
return false; return false;
} }
bool operator()(IfcSchema::IfcProduct* prod) const bool operator()(IfcUtil::IfcBaseEntity* prod) const {
{
return filter::match(prod, std::bind1st(std::mem_fun(&entity_filter::match), this)); return filter::match(prod, std::bind1st(std::mem_fun(&entity_filter::match), this));
} }
void update_description() void update_description() {
{
// TODO
#if 0
std::stringstream ss; std::stringstream ss;
ss << (traverse ? "traverse " : "") << (include ? "include" : "exclude") << " entities"; ss << (traverse ? "traverse " : "") << (include ? "include" : "exclude") << " entities";
BOOST_FOREACH(IfcSchema::Enum::Class() type, values) { for (auto& name : entity_names) {
ss << " " << IfcSchema::ToString::Class()(type); ss << " " << name;
} }
description = ss.str(); description = ss.str();
#endif
} }
}; };
} }
+16 -1
View File
@@ -78,6 +78,8 @@ namespace IfcGeom {
IfcParse::IfcFile* file_; IfcParse::IfcFile* file_;
IfcGeom::IteratorSettings settings_; IfcGeom::IteratorSettings settings_;
std::vector<IfcGeom::filter_t> filters_;
IteratorImplementation<P, PP>* implementation_; IteratorImplementation<P, PP>* implementation_;
public: public:
@@ -85,7 +87,15 @@ namespace IfcGeom {
: file_(file) : file_(file)
, settings_(settings) , settings_(settings)
{ {
implementation_ = iterator_implementations<P, PP>().construct(file_->schema()->name(), settings, file); implementation_ = iterator_implementations<P, PP>().construct(file_->schema()->name(), settings, file, filters_);
}
Iterator(const IfcGeom::IteratorSettings& settings, IfcParse::IfcFile* file, const std::vector<IfcGeom::filter_t>& filters)
: file_(file)
, settings_(settings)
, filters_(filters)
{
implementation_ = iterator_implementations<P, PP>().construct(file_->schema()->name(), settings, file, filters_);
} }
bool initialize() { bool initialize() {
@@ -94,6 +104,11 @@ namespace IfcGeom {
int progress() const { return implementation_->progress(); } int progress() const { return implementation_->progress(); }
void compute_bounds() { implementation_->compute_bounds(); }
const gp_XYZ& bounds_min() const { return implementation_->bounds_min(); }
const gp_XYZ& bounds_max() const { return implementation_->bounds_max(); }
const std::string& unit_name() const { return implementation_->getUnitName(); } const std::string& unit_name() const { return implementation_->getUnitName(); }
double unit_magnitude() const { return implementation_->getUnitMagnitude(); } double unit_magnitude() const { return implementation_->getUnitMagnitude(); }
@@ -31,14 +31,14 @@ void IteratorFactoryImplementation<P, PP>::bind(const std::string& schema_name,
} }
template <typename P, typename PP> template <typename P, typename PP>
IfcGeom::IteratorImplementation<P, PP>* IteratorFactoryImplementation<P, PP>::construct(const std::string& schema_name, const IfcGeom::IteratorSettings& settings, IfcParse::IfcFile* file) { IfcGeom::IteratorImplementation<P, PP>* IteratorFactoryImplementation<P, PP>::construct(const std::string& schema_name, const IfcGeom::IteratorSettings& settings, IfcParse::IfcFile* file, const std::vector<IfcGeom::filter_t>& filters) {
const std::string schema_name_lower = boost::to_lower_copy(schema_name); const std::string schema_name_lower = boost::to_lower_copy(schema_name);
typename std::map<std::string, typename get_factory_type<P, PP>::type>::const_iterator it; typename std::map<std::string, typename get_factory_type<P, PP>::type>::const_iterator it;
it = this->find(schema_name_lower); it = this->find(schema_name_lower);
if (it == this->end()) { if (it == this->end()) {
throw IfcParse::IfcException("No geometry iterator registered for " + schema_name); throw IfcParse::IfcException("No geometry iterator registered for " + schema_name);
} }
return it->second(settings, file); return it->second(settings, file, filters);
} }
@@ -1,9 +1,12 @@
#ifndef ITERATOR_IMPLEMENTATION_H #ifndef ITERATOR_IMPLEMENTATION_H
#define ITERATOR_IMPLEMENTATION_H #define ITERATOR_IMPLEMENTATION_H
#include "../ifcgeom_schema_agnostic/IfcGeomFilter.h"
#include "../ifcparse/IfcFile.h" #include "../ifcparse/IfcFile.h"
#include "../ifcgeom/IfcGeomIteratorSettings.h" #include "../ifcgeom/IfcGeomIteratorSettings.h"
#include <gp_XYZ.hxx>
#include <boost/function.hpp> #include <boost/function.hpp>
#include <map> #include <map>
@@ -20,9 +23,9 @@ namespace IfcGeom {
class BRepElement; class BRepElement;
} }
typedef boost::function2<IfcGeom::IteratorImplementation<float, float>*, const IfcGeom::IteratorSettings&, IfcParse::IfcFile*> iterator_float_float_fn; typedef boost::function3<IfcGeom::IteratorImplementation<float, float>*, const IfcGeom::IteratorSettings&, IfcParse::IfcFile*, const std::vector<IfcGeom::filter_t>&> iterator_float_float_fn;
typedef boost::function2<IfcGeom::IteratorImplementation<float, double>*, const IfcGeom::IteratorSettings&, IfcParse::IfcFile*> iterator_float_double_fn; typedef boost::function3<IfcGeom::IteratorImplementation<float, double>*, const IfcGeom::IteratorSettings&, IfcParse::IfcFile*, const std::vector<IfcGeom::filter_t>&> iterator_float_double_fn;
typedef boost::function2<IfcGeom::IteratorImplementation<double, double>*, const IfcGeom::IteratorSettings&, IfcParse::IfcFile*> iterator_double_double_fn; typedef boost::function3<IfcGeom::IteratorImplementation<double, double>*, const IfcGeom::IteratorSettings&, IfcParse::IfcFile*, const std::vector<IfcGeom::filter_t>&> iterator_double_double_fn;
template <typename P, typename PP> template <typename P, typename PP>
struct get_factory_type {}; struct get_factory_type {};
@@ -47,7 +50,7 @@ class IteratorFactoryImplementation : public std::map<std::string, typename get_
public: public:
IteratorFactoryImplementation(); IteratorFactoryImplementation();
void bind(const std::string& schema_name, typename get_factory_type<P, PP>::type fn); void bind(const std::string& schema_name, typename get_factory_type<P, PP>::type fn);
IfcGeom::IteratorImplementation<P, PP>* construct(const std::string& schema_name, const IfcGeom::IteratorSettings&, IfcParse::IfcFile*); IfcGeom::IteratorImplementation<P, PP>* construct(const std::string& schema_name, const IfcGeom::IteratorSettings&, IfcParse::IfcFile*, const std::vector<IfcGeom::filter_t>&);
}; };
template <typename P, typename PP> template <typename P, typename PP>
@@ -59,6 +62,9 @@ namespace IfcGeom {
class IteratorImplementation { class IteratorImplementation {
public: public:
virtual bool initialize() = 0; virtual bool initialize() = 0;
virtual void compute_bounds() = 0;
virtual const gp_XYZ& bounds_min() const = 0;
virtual const gp_XYZ& bounds_max() const = 0;
virtual int progress() const = 0; virtual int progress() const = 0;
virtual const std::string& getUnitName() const = 0; virtual const std::string& getUnitName() const = 0;
virtual double getUnitMagnitude() const = 0; virtual double getUnitMagnitude() const = 0;
+116
View File
@@ -47,3 +47,119 @@ IfcGeom::Kernel* IfcGeom::impl::KernelFactoryImplementation::construct(const std
} }
return it->second(file); return it->second(file);
} }
#define CREATE_GET_DECOMPOSING_ENTITY(IfcSchema) \
\
IfcSchema::IfcObjectDefinition* get_decomposing_entity_impl(IfcSchema::IfcProduct* product) { \
IfcSchema::IfcObjectDefinition* parent = 0; \
\
/* In case of an opening element, parent to the RelatingBuildingElement */ \
if (product->declaration().is(IfcSchema::IfcOpeningElement::Class())) { \
IfcSchema::IfcOpeningElement* opening = (IfcSchema::IfcOpeningElement*)product; \
IfcSchema::IfcRelVoidsElement::list::ptr voids = opening->VoidsElements(); \
if (voids->size()) { \
IfcSchema::IfcRelVoidsElement* ifc_void = *voids->begin(); \
parent = ifc_void->RelatingBuildingElement(); \
} \
} else if (product->declaration().is(IfcSchema::IfcElement::Class())) { \
IfcSchema::IfcElement* element = (IfcSchema::IfcElement*)product; \
IfcSchema::IfcRelFillsElement::list::ptr fills = element->FillsVoids(); \
/* In case of a RelatedBuildingElement parent to the opening element */ \
if (fills->size()) { \
for (IfcSchema::IfcRelFillsElement::list::it it = fills->begin(); it != fills->end(); ++it) { \
IfcSchema::IfcRelFillsElement* fill = *it; \
IfcSchema::IfcObjectDefinition* ifc_objectdef = fill->RelatingOpeningElement(); \
if (product == ifc_objectdef) continue; \
parent = ifc_objectdef; \
} \
} \
/* Else simply parent to the containing structure */ \
if (!parent) { \
IfcSchema::IfcRelContainedInSpatialStructure::list::ptr parents = element->ContainedInStructure(); \
if (parents->size()) { \
IfcSchema::IfcRelContainedInSpatialStructure* container = *parents->begin(); \
parent = container->RelatingStructure(); \
} \
} \
} \
\
/* Parent decompositions to the RelatingObject */ \
if (!parent) { \
IfcEntityList::ptr parents = product->data().getInverse((&IfcSchema::IfcRelAggregates::Class()), -1); \
parents->push(product->data().getInverse((&IfcSchema::IfcRelNests::Class()), -1)); \
for (IfcEntityList::it it = parents->begin(); it != parents->end(); ++it) { \
IfcSchema::IfcRelDecomposes* decompose = (IfcSchema::IfcRelDecomposes*)*it; \
IfcUtil::IfcBaseEntity* ifc_objectdef; \
\
ifc_objectdef = get_RelatingObject(decompose); \
\
if (product == ifc_objectdef) continue; \
parent = ifc_objectdef->as<IfcSchema::IfcObjectDefinition>(); \
} \
} \
return parent; \
}
namespace {
IfcUtil::IfcBaseEntity* get_RelatingObject(Ifc4::IfcRelDecomposes* decompose) {
Ifc4::IfcRelAggregates* aggr = decompose->as<Ifc4::IfcRelAggregates>();
if (aggr != nullptr) {
return aggr->RelatingObject();
}
return nullptr;
}
IfcUtil::IfcBaseEntity* get_RelatingObject(Ifc2x3::IfcRelDecomposes* decompose) {
return decompose->RelatingObject();
}
CREATE_GET_DECOMPOSING_ENTITY(Ifc2x3);
CREATE_GET_DECOMPOSING_ENTITY(Ifc4);
}
IfcUtil::IfcBaseEntity* IfcGeom::Kernel::get_decomposing_entity(IfcUtil::IfcBaseEntity* inst) {
if (inst->as<Ifc2x3::IfcProduct>()) {
return get_decomposing_entity_impl(inst->as<Ifc2x3::IfcProduct>());
} else if (inst->as<Ifc4::IfcProduct>()) {
return get_decomposing_entity_impl(inst->as<Ifc4::IfcProduct>());
} else {
throw IfcParse::IfcException("Unexpected entity " + inst->declaration().name());
}
}
namespace {
template <typename Schema>
static std::map<std::string, IfcUtil::IfcBaseEntity*> get_layers_impl(typename Schema::IfcProduct* prod) {
std::map<std::string, IfcUtil::IfcBaseEntity*> layers;
if (prod->hasRepresentation()) {
IfcEntityList::ptr r = IfcParse::traverse(prod->Representation());
typename Schema::IfcRepresentation::list::ptr representations = r->as<typename Schema::IfcRepresentation>();
for (typename Schema::IfcRepresentation::list::it it = representations->begin(); it != representations->end(); ++it) {
typename Schema::IfcPresentationLayerAssignment::list::ptr a = (*it)->LayerAssignments();
for (typename Schema::IfcPresentationLayerAssignment::list::it jt = a->begin(); jt != a->end(); ++jt) {
layers[(*jt)->Name()] = *jt;
}
}
typename Schema::IfcRepresentationItem::list::ptr items = r->as<typename Schema::IfcRepresentationItem>();
for (typename Schema::IfcRepresentationItem::list::it it = items->begin(); it != items->end(); ++it) {
typename Schema::IfcPresentationLayerAssignment::list::ptr a = getLayerAssignments(*it)->template as<typename Schema::IfcPresentationLayerAssignment>();
for (typename Schema::IfcPresentationLayerAssignment::list::it jt = a->begin(); jt != a->end(); ++jt) {
layers[(*jt)->Name()] = *jt;
}
}
}
return layers;
}
}
std::map<std::string, IfcUtil::IfcBaseEntity*> IfcGeom::Kernel::get_layers(IfcUtil::IfcBaseEntity* inst) {
if (inst->as<Ifc2x3::IfcProduct>()) {
return get_layers_impl<Ifc2x3>(inst->as<Ifc2x3::IfcProduct>());
} else if (inst->as<Ifc4::IfcProduct>()) {
return get_layers_impl<Ifc4>(inst->as<Ifc4::IfcProduct>());
} else {
throw IfcParse::IfcException("Unexpected entity " + inst->declaration().name());
}
}
+2 -24
View File
@@ -95,30 +95,8 @@ namespace IfcGeom {
static int count(const TopoDS_Shape&, TopAbs_ShapeEnum); static int count(const TopoDS_Shape&, TopAbs_ShapeEnum);
template <typename Schema> static IfcUtil::IfcBaseEntity* get_decomposing_entity(IfcUtil::IfcBaseEntity*);
static std::map<std::string, typename Schema::IfcPresentationLayerAssignment*> get_layers(typename Schema::IfcProduct* prod) { static std::map<std::string, IfcUtil::IfcBaseEntity*> get_layers(IfcUtil::IfcBaseEntity*);
std::map<std::string, typename Schema::IfcPresentationLayerAssignment*> layers;
if (prod->hasRepresentation()) {
IfcEntityList::ptr r = IfcParse::traverse(prod->Representation());
typename Schema::IfcRepresentation::list::ptr representations = r->as<typename Schema::IfcRepresentation>();
for (typename Schema::IfcRepresentation::list::it it = representations->begin(); it != representations->end(); ++it) {
typename Schema::IfcPresentationLayerAssignment::list::ptr a = (*it)->LayerAssignments();
for (typename Schema::IfcPresentationLayerAssignment::list::it jt = a->begin(); jt != a->end(); ++jt) {
layers[(*jt)->Name()] = *jt;
}
}
typename Schema::IfcRepresentationItem::list::ptr items = r->as<typename Schema::IfcRepresentationItem>();
for (typename Schema::IfcRepresentationItem::list::it it = items->begin(); it != items->end(); ++it) {
typename Schema::IfcPresentationLayerAssignment::list::ptr a = getLayerAssignments(*it)->template as<typename Schema::IfcPresentationLayerAssignment>();
for (typename Schema::IfcPresentationLayerAssignment::list::it jt = a->begin(); jt != a->end(); ++jt) {
layers[(*jt)->Name()] = *jt;
}
}
}
return layers;
}
}; };
namespace impl { namespace impl {
@@ -308,8 +308,8 @@ ptree& descend(IfcSchema::IfcObjectDefinition* product, ptree& tree) {
} }
if (product->declaration().is(IfcSchema::IfcProduct::Class())) { if (product->declaration().is(IfcSchema::IfcProduct::Class())) {
std::map<std::string, IfcSchema::IfcPresentationLayerAssignment*> layers = IfcGeom::Kernel::get_layers<IfcSchema>(product->as<IfcSchema::IfcProduct>()); std::map<std::string, IfcUtil::IfcBaseEntity*> layers = IfcGeom::Kernel::get_layers(product);
for (std::map<std::string, IfcSchema::IfcPresentationLayerAssignment*>::const_iterator it = layers.begin(); it != layers.end(); ++it) { for (std::map<std::string, IfcUtil::IfcBaseEntity*>::const_iterator it = layers.begin(); it != layers.end(); ++it) {
// IfcPresentationLayerAssignments don't have GUIDs (only optional Identifier) so use name as the ID. // IfcPresentationLayerAssignments don't have GUIDs (only optional Identifier) so use name as the ID.
// Note that the IfcPresentationLayerAssignment passed here doesn't really matter as as_link is true // Note that the IfcPresentationLayerAssignment passed here doesn't really matter as as_link is true
// for the format_entity_instance() call. // for the format_entity_instance() call.