mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-10 17:58:20 +00:00
Revive some temporarily disabled features in de 0.6 branch
This commit is contained in:
@@ -33,6 +33,7 @@
|
||||
#include "../serializers/XmlSerializer.h"
|
||||
#include "../serializers/SvgSerializer.h"
|
||||
|
||||
#include "../ifcgeom_schema_agnostic/IfcGeomFilter.h"
|
||||
#include "../ifcgeom_schema_agnostic/IfcGeomIterator.h"
|
||||
|
||||
#include <Standard_Version.hxx>
|
||||
@@ -119,16 +120,9 @@ static std::stringstream log_stream;
|
||||
void write_log(bool);
|
||||
|
||||
/// @todo make the filters non-global
|
||||
/*
|
||||
IfcGeom::entity_filter entity_filter; // Entity filter is used always by default.
|
||||
IfcGeom::layer_filter layer_filter;
|
||||
const std::string NAME_ARG = "Name", GUID_ARG = "GlobalId", DESC_ARG = "Description", TAG_ARG = "Tag";
|
||||
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
|
||||
IfcGeom::attribute_filter attribute_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&);
|
||||
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&);
|
||||
*/
|
||||
|
||||
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;
|
||||
/*
|
||||
inclusion_filter include_filter;
|
||||
inclusion_traverse_filter include_traverse_filter;
|
||||
exclusion_filter exclude_filter;
|
||||
exclusion_traverse_filter exclude_traverse_filter;
|
||||
std::string filter_filename;
|
||||
*/
|
||||
|
||||
po::options_description geom_options("Geometry options");
|
||||
geom_options.add_options()
|
||||
@@ -232,14 +223,13 @@ int main(int argc, char** argv)
|
||||
("enable-layerset-slicing",
|
||||
"Specifies whether to enable the slicing of products according "
|
||||
"to their associated IfcMaterialLayerSet.")
|
||||
/*
|
||||
("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 "
|
||||
"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"
|
||||
"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"
|
||||
"The values for 'layers' and 'arg' are handled case-sensitively (wildcards supported)."
|
||||
"--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 "
|
||||
"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. "
|
||||
"See --include, --include+, --exclude, and --exclude+ for more details.");
|
||||
*/
|
||||
"See --include, --include+, --exclude, and --exclude+ for more details.")
|
||||
("no-normals",
|
||||
"Disables computation of normals. Saves time and file size and is useful "
|
||||
"in instances where you're going to recompute normals for the exported "
|
||||
@@ -490,7 +479,6 @@ int main(int argc, char** argv)
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
/*
|
||||
if (!filter_filename.empty()) {
|
||||
size_t num_filters = read_filters_from_file(filter_filename, include_filter, include_traverse_filter, exclude_filter, exclude_traverse_filter);
|
||||
if (num_filters) {
|
||||
@@ -514,14 +502,10 @@ int main(int argc, char** argv)
|
||||
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 (!guid_filter.values.empty()) { guid_filter.update_description(); Logger::Notice(guid_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); }
|
||||
*/
|
||||
|
||||
if (!attribute_filter.attribute_name.empty()) { attribute_filter.update_description(); Logger::Notice(layer_filter.description); }
|
||||
|
||||
SerializerSettings settings;
|
||||
/// @todo Make APPLY_DEFAULT_MATERIALS configurable? Quickly tested setting this to false and using obj exporter caused the program to crash and burn.
|
||||
settings.set(IfcGeom::IteratorSettings::APPLY_DEFAULT_MATERIALS, true);
|
||||
@@ -629,7 +613,7 @@ int main(int argc, char** argv)
|
||||
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()) {
|
||||
/// @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.
|
||||
@@ -663,7 +647,6 @@ int main(int argc, char** argv)
|
||||
|
||||
throw std::runtime_error("needs more work");
|
||||
|
||||
/*
|
||||
if (!quiet) Logger::Status("Computing bounds...");
|
||||
context_iterator.compute_bounds();
|
||||
if (!quiet) Logger::Status("Done!");
|
||||
@@ -672,7 +655,6 @@ int main(int argc, char** argv)
|
||||
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) {
|
||||
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)
|
||||
{
|
||||
geom_filter temp;
|
||||
@@ -910,9 +891,6 @@ void parse_filter(geom_filter &filter, const std::vector<std::string>& values)
|
||||
} 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);
|
||||
}
|
||||
@@ -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> filter_funcs;
|
||||
BOOST_FOREACH(const geom_filter& f, filters) {
|
||||
for(auto& 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) {
|
||||
std::cerr << "[Error] " << e.what() << std::endl;
|
||||
return std::vector<IfcGeom::filter_t>();
|
||||
}
|
||||
entity_filter.entity_names = f.values;
|
||||
} 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);
|
||||
}
|
||||
attribute_filter.include = f.include;
|
||||
attribute_filter.traverse = f.traverse;
|
||||
attribute_filter.attribute_name = f.arg;
|
||||
attribute_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<std::string> 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) {
|
||||
std::cerr << "[Error] " << e.what() << std::endl;
|
||||
return std::vector<IfcGeom::filter_t>();
|
||||
if (entity_filter.entity_names.empty()) {
|
||||
std::set<std::string> entities;
|
||||
entities.insert("IfcSpace");
|
||||
if (output_extension == ".svg") {
|
||||
entity_filter.include = true;
|
||||
} else {
|
||||
entities.insert("IfcOpeningElement");
|
||||
}
|
||||
entity_filter.entity_names = entities;
|
||||
}
|
||||
|
||||
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)); }
|
||||
if (!entity_filter.entity_names.empty()) { filter_funcs.push_back(boost::ref(entity_filter)); }
|
||||
if (!attribute_filter.values.empty()) { filter_funcs.push_back(boost::ref(attribute_filter)); }
|
||||
|
||||
return filter_funcs;
|
||||
}
|
||||
*/
|
||||
|
||||
@@ -221,8 +221,6 @@ public:
|
||||
|
||||
std::pair<std::string, double> initializeUnits(IfcSchema::IfcUnitAssignment*);
|
||||
|
||||
static IfcSchema::IfcObjectDefinition* get_decomposing_entity(IfcSchema::IfcProduct*);
|
||||
|
||||
template <typename P, typename PP>
|
||||
IfcGeom::BRepElement<P, PP>* create_brep_for_representation_and_product(
|
||||
const IteratorSettings&, IfcSchema::IfcRepresentation*, IfcSchema::IfcProduct*);
|
||||
|
||||
@@ -1332,7 +1332,7 @@ IfcGeom::BRepElement<P, PP>* IfcGeom::Kernel::create_brep_for_representation_and
|
||||
|
||||
int parent_id = -1;
|
||||
try {
|
||||
IfcSchema::IfcObjectDefinition* parent_object = get_decomposing_entity(product);
|
||||
IfcSchema::IfcObjectDefinition* parent_object = get_decomposing_entity(product)->as<IfcSchema::IfcObjectDefinition>();
|
||||
if (parent_object) {
|
||||
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;
|
||||
try {
|
||||
IfcSchema::IfcObjectDefinition* parent_object = get_decomposing_entity(product);
|
||||
IfcSchema::IfcObjectDefinition* parent_object = get_decomposing_entity(product)->as<IfcSchema::IfcObjectDefinition>();
|
||||
if (parent_object) {
|
||||
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>(
|
||||
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>(
|
||||
|
||||
@@ -14,8 +14,8 @@ namespace IfcGeom {
|
||||
namespace {
|
||||
template <typename P, typename PP>
|
||||
struct MAKE_TYPE_NAME(factory_t) {
|
||||
IfcGeom::IteratorImplementation<P, PP>* operator()(const IfcGeom::IteratorSettings& settings, IfcParse::IfcFile* file) const {
|
||||
return new IfcGeom::MAKE_TYPE_NAME(IteratorImplementation_)<P, PP>(settings, file);
|
||||
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, filters);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -80,8 +80,8 @@
|
||||
#include "../ifcgeom_schema_agnostic/IfcGeomMaterial.h"
|
||||
#include "../ifcgeom/IfcGeomIteratorSettings.h"
|
||||
#include "../ifcgeom/IfcRepresentationShapeItem.h"
|
||||
#include "../ifcgeom/IfcGeomFilter.h"
|
||||
|
||||
#include "../ifcgeom_schema_agnostic/IfcGeomFilter.h"
|
||||
#include "../ifcgeom_schema_agnostic/IteratorImplementation.h"
|
||||
|
||||
// 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 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() {
|
||||
try {
|
||||
initUnits();
|
||||
@@ -614,7 +605,7 @@ namespace IfcGeom {
|
||||
ifc_product = ifc_entity->as<IfcSchema::IfcProduct>();
|
||||
parent_id = -1;
|
||||
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) {
|
||||
parent_id = parent_object->data().id();
|
||||
}
|
||||
@@ -721,31 +712,11 @@ namespace IfcGeom {
|
||||
|
||||
bool owns_ifc_file;
|
||||
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)
|
||||
, ifc_file(file)
|
||||
, owns_ifc_file(false)
|
||||
{
|
||||
_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)
|
||||
, filters_(filters)
|
||||
{
|
||||
_initialize();
|
||||
}
|
||||
|
||||
@@ -23,7 +23,8 @@
|
||||
#ifndef IFCGEOMFILTER_H
|
||||
#define IFCGEOMFILTER_H
|
||||
|
||||
#include "IfcGeom.h"
|
||||
#include "Kernel.h"
|
||||
#include "../ifcparse/IfcFile.h"
|
||||
|
||||
#include <boost/foreach.hpp>
|
||||
#include <boost/function.hpp>
|
||||
@@ -33,15 +34,13 @@
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace IfcGeom
|
||||
{
|
||||
namespace IfcGeom {
|
||||
/// 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.
|
||||
/// 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(bool incl, bool trav) : include(incl), traverse(trav) {}
|
||||
/// Should the product be included (true) or excluded (false).
|
||||
@@ -52,8 +51,7 @@ namespace IfcGeom
|
||||
/// Optional description for the filtering criteria of this filter.
|
||||
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);
|
||||
if (!is_match && traverse) {
|
||||
is_match = traverse_match(prod, pred);
|
||||
@@ -61,46 +59,38 @@ namespace IfcGeom
|
||||
return is_match == include;
|
||||
}
|
||||
|
||||
static bool traverse_match(IfcSchema::IfcProduct* prod, const filter_t& pred)
|
||||
{
|
||||
throw std::runtime_error("todo");
|
||||
/*
|
||||
IfcSchema::IfcProduct* parent, *current = prod;
|
||||
while ((parent = dynamic_cast<IfcSchema::IfcProduct*>(IfcGeom::Kernel::get_decomposing_entity(current))) != 0) {
|
||||
static bool traverse_match(IfcUtil::IfcBaseEntity* prod, const filter_t& pred) {
|
||||
IfcUtil::IfcBaseEntity* parent, *current = prod;
|
||||
while ((parent = IfcGeom::Kernel::get_decomposing_entity(current)) != nullptr) {
|
||||
if (pred(parent)) {
|
||||
return true;
|
||||
}
|
||||
current = parent;
|
||||
}
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
struct wildcard_filter : public filter
|
||||
{
|
||||
struct wildcard_filter : public filter {
|
||||
wildcard_filter() : filter(false, false) {}
|
||||
wildcard_filter(bool include, bool traverse, const std::set<std::string>& patterns)
|
||||
: filter(include, traverse)
|
||||
{
|
||||
: filter(include, traverse) {
|
||||
populate(patterns);
|
||||
}
|
||||
|
||||
std::set<boost::regex> values;
|
||||
|
||||
void populate(const std::set<std::string>& patterns)
|
||||
{
|
||||
void populate(const std::set<std::string>& patterns) {
|
||||
values.clear();
|
||||
BOOST_FOREACH(const std::string &pattern, patterns) {
|
||||
for(auto& pattern: patterns) {
|
||||
values.insert(wildcard_string_to_regex(pattern));
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
BOOST_FOREACH(const boost::regex& r, values) {
|
||||
static bool match_values(const std::set<boost::regex>& values, const std::string &str) {
|
||||
for(auto& r: values) {
|
||||
if (boost::regex_match(str, r)) {
|
||||
return true;
|
||||
}
|
||||
@@ -108,11 +98,10 @@ namespace IfcGeom
|
||||
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
|
||||
static const std::string special_chars = "\\^.$|()[]+/";
|
||||
BOOST_FOREACH(char c, special_chars) {
|
||||
for(auto c: special_chars) {
|
||||
std::string char_str(1, c);
|
||||
boost::replace_all(str, char_str, "\\" + char_str);
|
||||
}
|
||||
@@ -124,127 +113,78 @@ namespace IfcGeom
|
||||
};
|
||||
|
||||
/// @note supports only string arguments for now
|
||||
struct string_arg_filter : public wildcard_filter
|
||||
{
|
||||
// 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;
|
||||
struct attribute_filter : public wildcard_filter {
|
||||
std::string attribute_name;
|
||||
|
||||
/// @todo Take only attribute name when IfcBaseClass and IfcLateBoundEntity are merged.
|
||||
string_arg_filter(arg_map_t args) : args(args) { assert_arguments(); }
|
||||
string_arg_filter(const IfcParse::declaration* type, unsigned short index) { args[type] = index; assert_arguments(); }
|
||||
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();
|
||||
}
|
||||
attribute_filter() {}
|
||||
attribute_filter(const std::string& attribute_name)
|
||||
: attribute_name(attribute_name) {}
|
||||
|
||||
/// @todo this won't be needed when we have the generic argument name access
|
||||
void assert_arguments()
|
||||
{
|
||||
// TODO
|
||||
#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);
|
||||
assert(it->second < base->getArgumentCount() && "Argument index out of bounds");
|
||||
assert(base->getArgumentType(it->second) == IfcUtil::Argument_STRING && "Argument type not string");
|
||||
delete base;
|
||||
std::string value(IfcUtil::IfcBaseEntity* prod) const {
|
||||
try {
|
||||
return (std::string) *prod->get(attribute_name);
|
||||
} catch (...) {
|
||||
// Either
|
||||
// (a) not an attribute name for this entity instance
|
||||
// (b) not a string attribute
|
||||
// (c) null for this entity instance
|
||||
// @todo: validate the filters with a reference to the schema
|
||||
// probably in IfcGeomIteratorImplementation
|
||||
return "<invalid>";
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
std::string value(IfcSchema::IfcProduct* prod) const
|
||||
{
|
||||
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(IfcUtil::IfcBaseEntity* prod) const {
|
||||
return wildcard_filter::match(value(prod));
|
||||
}
|
||||
|
||||
bool match(IfcSchema::IfcProduct* prod) const { return wildcard_filter::match(value(prod)); }
|
||||
|
||||
bool operator()(IfcSchema::IfcProduct* prod) const
|
||||
{
|
||||
bool operator()(IfcUtil::IfcBaseEntity* prod) const {
|
||||
// @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;
|
||||
|
||||
ss << (traverse ? "traverse " : "") << (include ? "include" : "exclude");
|
||||
std::vector<std::string> patterns;
|
||||
BOOST_FOREACH(const boost::regex& r, values) {
|
||||
for (auto& r : values) {
|
||||
patterns.push_back("\"" + r.str() + "\"");
|
||||
}
|
||||
|
||||
// TODO
|
||||
#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 << " " << attribute_name;
|
||||
ss << " values " << boost::algorithm::join(patterns, " ");
|
||||
|
||||
description = ss.str();
|
||||
}
|
||||
};
|
||||
|
||||
struct layer_filter : public wildcard_filter
|
||||
{
|
||||
typedef std::map<std::string, IfcSchema::IfcPresentationLayerAssignment*> layer_map_t;
|
||||
struct layer_filter : public wildcard_filter {
|
||||
typedef std::map<std::string, IfcUtil::IfcBaseEntity*> layer_map_t;
|
||||
|
||||
layer_filter() {}
|
||||
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
|
||||
{
|
||||
throw std::runtime_error("todo");
|
||||
/*
|
||||
bool match(IfcUtil::IfcBaseEntity* prod) const {
|
||||
layer_map_t layers = IfcGeom::Kernel::get_layers(prod);
|
||||
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));
|
||||
}
|
||||
|
||||
struct wildcards_match
|
||||
{
|
||||
struct wildcards_match {
|
||||
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);
|
||||
}
|
||||
|
||||
std::set<boost::regex> patterns;
|
||||
};
|
||||
|
||||
void update_description()
|
||||
{
|
||||
void update_description() {
|
||||
std::stringstream ss;
|
||||
ss << (traverse ? "traverse " : "") << (include ? "include" : "exclude") << " layers";
|
||||
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(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)
|
||||
{
|
||||
//populate(types);
|
||||
}
|
||||
, entity_names(entity_names) {}
|
||||
|
||||
std::set<const IfcParse::declaration*> values;
|
||||
|
||||
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
|
||||
{
|
||||
bool match(IfcUtil::IfcBaseEntity* prod) const {
|
||||
// The set is iterated over to able to filter on subtypes.
|
||||
BOOST_FOREACH(const IfcParse::declaration* type, values) {
|
||||
if (prod->declaration().is(*type)) {
|
||||
for (auto& name : entity_names) {
|
||||
if (prod->declaration().is(name)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
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));
|
||||
}
|
||||
|
||||
void update_description()
|
||||
{
|
||||
// TODO
|
||||
#if 0
|
||||
void update_description() {
|
||||
std::stringstream ss;
|
||||
ss << (traverse ? "traverse " : "") << (include ? "include" : "exclude") << " entities";
|
||||
BOOST_FOREACH(IfcSchema::Enum::Class() type, values) {
|
||||
ss << " " << IfcSchema::ToString::Class()(type);
|
||||
for (auto& name : entity_names) {
|
||||
ss << " " << name;
|
||||
}
|
||||
description = ss.str();
|
||||
#endif
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -78,6 +78,8 @@ namespace IfcGeom {
|
||||
|
||||
IfcParse::IfcFile* file_;
|
||||
IfcGeom::IteratorSettings settings_;
|
||||
std::vector<IfcGeom::filter_t> filters_;
|
||||
|
||||
IteratorImplementation<P, PP>* implementation_;
|
||||
|
||||
public:
|
||||
@@ -85,7 +87,15 @@ namespace IfcGeom {
|
||||
: file_(file)
|
||||
, 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() {
|
||||
@@ -94,6 +104,11 @@ namespace IfcGeom {
|
||||
|
||||
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(); }
|
||||
|
||||
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>
|
||||
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);
|
||||
typename std::map<std::string, typename get_factory_type<P, PP>::type>::const_iterator it;
|
||||
it = this->find(schema_name_lower);
|
||||
if (it == this->end()) {
|
||||
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
|
||||
#define ITERATOR_IMPLEMENTATION_H
|
||||
|
||||
#include "../ifcgeom_schema_agnostic/IfcGeomFilter.h"
|
||||
#include "../ifcparse/IfcFile.h"
|
||||
#include "../ifcgeom/IfcGeomIteratorSettings.h"
|
||||
|
||||
#include <gp_XYZ.hxx>
|
||||
|
||||
#include <boost/function.hpp>
|
||||
|
||||
#include <map>
|
||||
@@ -20,9 +23,9 @@ namespace IfcGeom {
|
||||
class BRepElement;
|
||||
}
|
||||
|
||||
typedef boost::function2<IfcGeom::IteratorImplementation<float, float>*, const IfcGeom::IteratorSettings&, IfcParse::IfcFile*> iterator_float_float_fn;
|
||||
typedef boost::function2<IfcGeom::IteratorImplementation<float, double>*, const IfcGeom::IteratorSettings&, IfcParse::IfcFile*> 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<float, float>*, const IfcGeom::IteratorSettings&, IfcParse::IfcFile*, const std::vector<IfcGeom::filter_t>&> iterator_float_float_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::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>
|
||||
struct get_factory_type {};
|
||||
@@ -47,7 +50,7 @@ class IteratorFactoryImplementation : public std::map<std::string, typename get_
|
||||
public:
|
||||
IteratorFactoryImplementation();
|
||||
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>
|
||||
@@ -59,6 +62,9 @@ namespace IfcGeom {
|
||||
class IteratorImplementation {
|
||||
public:
|
||||
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 const std::string& getUnitName() const = 0;
|
||||
virtual double getUnitMagnitude() const = 0;
|
||||
|
||||
@@ -47,3 +47,119 @@ IfcGeom::Kernel* IfcGeom::impl::KernelFactoryImplementation::construct(const std
|
||||
}
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -95,30 +95,8 @@ namespace IfcGeom {
|
||||
|
||||
static int count(const TopoDS_Shape&, TopAbs_ShapeEnum);
|
||||
|
||||
template <typename Schema>
|
||||
static std::map<std::string, typename Schema::IfcPresentationLayerAssignment*> get_layers(typename Schema::IfcProduct* prod) {
|
||||
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;
|
||||
}
|
||||
|
||||
static IfcUtil::IfcBaseEntity* get_decomposing_entity(IfcUtil::IfcBaseEntity*);
|
||||
static std::map<std::string, IfcUtil::IfcBaseEntity*> get_layers(IfcUtil::IfcBaseEntity*);
|
||||
};
|
||||
|
||||
namespace impl {
|
||||
|
||||
@@ -308,8 +308,8 @@ ptree& descend(IfcSchema::IfcObjectDefinition* product, ptree& tree) {
|
||||
}
|
||||
|
||||
if (product->declaration().is(IfcSchema::IfcProduct::Class())) {
|
||||
std::map<std::string, IfcSchema::IfcPresentationLayerAssignment*> layers = IfcGeom::Kernel::get_layers<IfcSchema>(product->as<IfcSchema::IfcProduct>());
|
||||
for (std::map<std::string, IfcSchema::IfcPresentationLayerAssignment*>::const_iterator it = layers.begin(); it != layers.end(); ++it) {
|
||||
std::map<std::string, IfcUtil::IfcBaseEntity*> layers = IfcGeom::Kernel::get_layers(product);
|
||||
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.
|
||||
// Note that the IfcPresentationLayerAssignment passed here doesn't really matter as as_link is true
|
||||
// for the format_entity_instance() call.
|
||||
|
||||
Reference in New Issue
Block a user