Cleaning up geom filters.

This commit is contained in:
Stinkfist0
2017-02-20 19:41:52 +02:00
committed by Thomas Krijnen
parent 7101ac22c8
commit d88c93a150
2 changed files with 189 additions and 176 deletions
+57 -54
View File
@@ -24,6 +24,9 @@
#define IFCGEOMFILTER_H
#include "IfcGeom.h"
#ifndef NDEBUG
#include "../ifcparse/IfcWritableEntity.h"
#endif
#include <boost/function.hpp>
#include <boost/regex.hpp>
@@ -44,18 +47,17 @@ namespace IfcGeom
/// children of a storey named "Level 20", or children of entities that have no representation, e.g. IfcCurtainWall.
bool traverse;
//static bool traverse_match(IfcSchema::IfcProduct* prod, filter_t pred)
//{
// bool is_match = false;
// IfcSchema::IfcProduct* parent, *current = prod;
// while ((parent = static_cast<IfcSchema::IfcProduct*>(IfcGeom::Kernel::get_decomposing_entity(current))) != 0) {
// if (pred(parent)) {
// is_match = true;
// break;
// }
// current = parent;
// }
//}
static bool traverse_match(IfcSchema::IfcProduct* prod, const filter_t& pred)
{
IfcSchema::IfcProduct* parent, *current = prod;
while ((parent = static_cast<IfcSchema::IfcProduct*>(IfcGeom::Kernel::get_decomposing_entity(current))) != 0) {
if (pred(parent)) {
return true;
}
current = parent;
}
return false;
}
};
struct wildcard_filter : public filter
@@ -109,8 +111,21 @@ namespace IfcGeom
arg_map_t args;
/// @todo Take only attribute name when IfcBaseClass and IfcLateBoundEntity are merged.
string_arg_filter(arg_map_t args) : args(args) {}
string_arg_filter(IfcSchema::Type::Enum type, unsigned short index) { args[type] = index; }
string_arg_filter(arg_map_t args) : args(args) { assert_arguments(); }
string_arg_filter(IfcSchema::Type::Enum type, unsigned short index) { args[type] = index; assert_arguments(); }
/// @todo this won't be needed when we have the generic argument name access
void assert_arguments()
{
#ifndef NDEBUG
for (arg_map_t::const_iterator it = args.begin(); it != args.end(); ++it) {
IfcWrite::IfcWritableEntity dummy(it->first);
IfcUtil::IfcBaseClass* base = IfcSchema::SchemaEntity(&dummy);
assert(it->second < base->getArgumentCount() && "Invalid argument index");
delete base;
}
#endif
}
std::string value(IfcSchema::IfcProduct* prod) const
{
@@ -129,14 +144,7 @@ namespace IfcGeom
{
bool is_match = match(value(prod));
if (is_match != include && traverse) {
IfcSchema::IfcProduct* parent, *current = prod;
while ((parent = static_cast<IfcSchema::IfcProduct*>(IfcGeom::Kernel::get_decomposing_entity(current))) != 0) {
if (match(value(parent))) {
is_match = true;
break;
}
current = parent;
}
is_match = traverse_match(prod, boost::ref(*this));
}
return is_match == include;
}
@@ -144,42 +152,44 @@ namespace IfcGeom
struct layer_filter : public wildcard_filter
{
typedef std::map<std::string, IfcSchema::IfcPresentationLayerAssignment*> layer_map_t;
layer_filter() {}
layer_filter(bool include, bool traverse, const std::set<std::string>& patterns)
: wildcard_filter(include, traverse, patterns)
{
}
bool match(IfcSchema::IfcProduct* 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 is_match = false;
std::map<std::string, IfcSchema::IfcPresentationLayerAssignment*> layers = IfcGeom::Kernel::get_layers(prod);
std::map<std::string, IfcSchema::IfcPresentationLayerAssignment*>::const_iterator lit;
for (lit = layers.begin(); lit != layers.end(); ++lit) {
if (match(lit->first)) {
is_match = true;
break;
}
}
bool is_match = match(prod);
if (is_match != include && traverse) {
for (lit = layers.begin(); lit != layers.end(); ++lit) {
IfcSchema::IfcProduct* parent, *current = prod;
while ((parent = static_cast<IfcSchema::IfcProduct*>(IfcGeom::Kernel::get_decomposing_entity(current))) != 0) {
if (match(lit->first)) {
is_match = true;
break;
}
current = parent;
}
if (is_match) {
break;
}
}
is_match = traverse_match(prod, boost::ref(*this));
}
return is_match == include;
}
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
{
foreach(const boost::regex& r, patterns) {
if (boost::regex_match(layer_map_value.first, r)) {
return true;
}
}
return false;
}
std::set<boost::regex> patterns;
};
};
struct entity_filter : public filter
@@ -223,14 +233,7 @@ namespace IfcGeom
{
bool is_match = match(prod);
if (is_match != include && traverse) {
IfcSchema::IfcProduct* parent, *current = prod;
while ((parent = static_cast<IfcSchema::IfcProduct*>(IfcGeom::Kernel::get_decomposing_entity(current))) != 0) {
if (match(parent)) {
is_match = true;
break;
}
current = parent;
}
is_match = traverse_match(prod, boost::ref(*this));
}
return is_match == include;
}