mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
Implement filtering created geometry by layer assignments.
This commit is contained in:
committed by
Thomas Krijnen
parent
3abee03b9b
commit
63b0488909
@@ -200,8 +200,8 @@ int main(int argc, char** argv)
|
||||
"geometrical output. The name patterns are handled case-sensitively. Cannot be placed right before input file argument. "
|
||||
"Only single option supported for now.")
|
||||
("exclude", po::value<exclusion_filter>(&exclude_filter)->multitoken(),
|
||||
"Specifies that the 'entities', 'names', or 'guids' provided are to be excluded. Defaults to IfcOpeningElement and IfcSpace "
|
||||
"to be excluded. See --include for syntax and more details.")
|
||||
"Specifies that the 'entities', 'names', 'guids', or 'layers' provided are to be excluded. "
|
||||
"The default value is '--exclude=entities IfcOpeningElement IfcSpace'. See --include for syntax and 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 "
|
||||
@@ -647,8 +647,8 @@ void validate(boost::any& v, const std::vector<std::string>& values, inclusion_f
|
||||
filter.type = geom_filter::ENTITY_NAME;
|
||||
} else if (type == "guids") {
|
||||
filter.type = geom_filter::ENTITY_GUID;
|
||||
//} else if (type == "layers") {
|
||||
// filter.type = geom_filter::LAYER_NAME;
|
||||
} else if (type == "layers") {
|
||||
filter.type = geom_filter::LAYER_NAME;
|
||||
} else {
|
||||
throw po::validation_error(po::validation_error::invalid_option_value);
|
||||
}
|
||||
@@ -671,8 +671,8 @@ void validate(boost::any& v, const std::vector<std::string>& values, exclusion_f
|
||||
filter.type = geom_filter::ENTITY_NAME;
|
||||
} else if (type == "guids") {
|
||||
filter.type = geom_filter::ENTITY_GUID;
|
||||
//} else if (type == "layers") {
|
||||
// filter.type = geom_filter::LAYER_NAME;
|
||||
} else if (type == "layers") {
|
||||
filter.type = geom_filter::LAYER_NAME;
|
||||
} else {
|
||||
throw po::validation_error(po::validation_error::invalid_option_value);
|
||||
}
|
||||
|
||||
@@ -270,41 +270,14 @@ ptree& descend(IfcObjectDefinition* product, ptree& tree) {
|
||||
}
|
||||
|
||||
if (product->is(Type::IfcProduct)) {
|
||||
IfcProduct* prod = product->as<IfcProduct>();
|
||||
if (prod->hasRepresentation()) {
|
||||
IfcEntityList::ptr r = prod->entity->file->traverse(prod->Representation());
|
||||
|
||||
std::map<std::string, IfcPresentationLayerAssignment*> layers;
|
||||
IfcRepresentation::list::ptr representations = r->as<IfcRepresentation>();
|
||||
for (IfcRepresentation::list::it it = representations->begin(); it != representations->end(); ++it) {
|
||||
IfcPresentationLayerAssignment::list::ptr a = (*it)->LayerAssignments();
|
||||
for (IfcPresentationLayerAssignment::list::it jt = a->begin(); jt != a->end(); ++jt) {
|
||||
layers[(*jt)->Name()] = *jt;
|
||||
}
|
||||
}
|
||||
|
||||
IfcRepresentationItem::list::ptr items = r->as<IfcRepresentationItem>();
|
||||
for (IfcRepresentationItem::list::it it = items->begin(); it != items->end(); ++it) {
|
||||
IfcPresentationLayerAssignment::list::ptr a = (*it)->
|
||||
// LayerAssignments renamed from plural to singular, LayerAssignment, so work around that
|
||||
#ifdef USE_IFC4
|
||||
LayerAssignment();
|
||||
#else
|
||||
LayerAssignments();
|
||||
#endif
|
||||
for (IfcPresentationLayerAssignment::list::it jt = a->begin(); jt != a->end(); ++jt) {
|
||||
layers[(*jt)->Name()] = *jt;
|
||||
}
|
||||
}
|
||||
|
||||
for (std::map<std::string, IfcPresentationLayerAssignment*>::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.
|
||||
ptree node;
|
||||
node.put("<xmlattr>.xlink:href", "#" + it->first);
|
||||
format_entity_instance(it->second, node, child, true);
|
||||
}
|
||||
std::map<std::string, IfcPresentationLayerAssignment*> layers = IfcGeom::Kernel::get_layers(product->as<IfcProduct>());
|
||||
for (std::map<std::string, IfcPresentationLayerAssignment*>::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.
|
||||
ptree node;
|
||||
node.put("<xmlattr>.xlink:href", "#" + it->first);
|
||||
format_entity_instance(it->second, node, child, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -241,6 +241,8 @@ public:
|
||||
|
||||
IfcSchema::IfcObjectDefinition* get_decomposing_entity(IfcSchema::IfcProduct*);
|
||||
|
||||
static std::map<std::string, IfcSchema::IfcPresentationLayerAssignment*> get_layers(IfcSchema::IfcProduct* prod);
|
||||
|
||||
template <typename P>
|
||||
IfcGeom::BRepElement<P>* create_brep_for_representation_and_product(
|
||||
const IteratorSettings&, IfcSchema::IfcRepresentation*, IfcSchema::IfcProduct*);
|
||||
|
||||
@@ -1275,6 +1275,37 @@ IfcSchema::IfcObjectDefinition* IfcGeom::Kernel::get_decomposing_entity(IfcSchem
|
||||
return parent;
|
||||
}
|
||||
|
||||
std::map<std::string, IfcSchema::IfcPresentationLayerAssignment*> IfcGeom::Kernel::get_layers(IfcSchema::IfcProduct* prod)
|
||||
{
|
||||
using namespace IfcSchema;
|
||||
std::map<std::string, IfcPresentationLayerAssignment*> layers;
|
||||
if (prod->hasRepresentation()) {
|
||||
IfcEntityList::ptr r = prod->entity->file->traverse(prod->Representation());
|
||||
IfcRepresentation::list::ptr representations = r->as<IfcRepresentation>();
|
||||
for (IfcRepresentation::list::it it = representations->begin(); it != representations->end(); ++it) {
|
||||
IfcPresentationLayerAssignment::list::ptr a = (*it)->LayerAssignments();
|
||||
for (IfcPresentationLayerAssignment::list::it jt = a->begin(); jt != a->end(); ++jt) {
|
||||
layers[(*jt)->Name()] = *jt;
|
||||
}
|
||||
}
|
||||
|
||||
IfcRepresentationItem::list::ptr items = r->as<IfcRepresentationItem>();
|
||||
for (IfcRepresentationItem::list::it it = items->begin(); it != items->end(); ++it) {
|
||||
IfcPresentationLayerAssignment::list::ptr a = (*it)->
|
||||
// LayerAssignments renamed from plural to singular, LayerAssignment, so work around that
|
||||
#ifdef USE_IFC4
|
||||
LayerAssignment();
|
||||
#else
|
||||
LayerAssignments();
|
||||
#endif
|
||||
for (IfcPresentationLayerAssignment::list::it jt = a->begin(); jt != a->end(); ++jt) {
|
||||
layers[(*jt)->Name()] = *jt;
|
||||
}
|
||||
}
|
||||
}
|
||||
return layers;
|
||||
}
|
||||
|
||||
template IFC_GEOM_API IfcGeom::BRepElement<float>* IfcGeom::Kernel::create_brep_for_representation_and_product<float>(
|
||||
const IteratorSettings& settings, IfcSchema::IfcRepresentation* representation, IfcSchema::IfcProduct* product);
|
||||
template IFC_GEOM_API IfcGeom::BRepElement<double>* IfcGeom::Kernel::create_brep_for_representation_and_product<double>(
|
||||
|
||||
@@ -583,83 +583,127 @@ namespace IfcGeom {
|
||||
const bool traverse = settings.get(IteratorSettings::TRAVERSE);
|
||||
for (IfcSchema::IfcProduct::list::it jt = unfiltered_products->begin(); jt != unfiltered_products->end(); ++jt) {
|
||||
IfcSchema::IfcProduct* prod = *jt;
|
||||
/// @todo Horrible copy-pasta, refactor.
|
||||
bool type_found = false;
|
||||
// The set is iterated over to able to filter on subtypes.
|
||||
foreach(IfcSchema::Type::Enum type, entity_filter_.values) {
|
||||
if (prod->is(type)) {
|
||||
type_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (type_found != entity_filter_.include && traverse) {
|
||||
if (!entity_filter_.values.empty()) {
|
||||
// The set is iterated over to able to filter on subtypes.
|
||||
foreach(IfcSchema::Type::Enum type, entity_filter_.values) {
|
||||
IfcSchema::IfcProduct* parent, * current = prod;
|
||||
while ((parent = static_cast<IfcSchema::IfcProduct*>(kernel.get_decomposing_entity(current))) != 0) {
|
||||
if (parent->is(type)) {
|
||||
type_found = true;
|
||||
if (prod->is(type)) {
|
||||
type_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (type_found != entity_filter_.include && traverse) {
|
||||
foreach(IfcSchema::Type::Enum type, entity_filter_.values) {
|
||||
IfcSchema::IfcProduct* parent, *current = prod;
|
||||
while ((parent = static_cast<IfcSchema::IfcProduct*>(kernel.get_decomposing_entity(current))) != 0) {
|
||||
if (parent->is(type)) {
|
||||
type_found = true;
|
||||
break;
|
||||
}
|
||||
current = parent;
|
||||
}
|
||||
if (type_found) {
|
||||
break;
|
||||
}
|
||||
current = parent;
|
||||
}
|
||||
if (type_found) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool name_found = false;
|
||||
foreach(const boost::regex& r, name_filter_.values) {
|
||||
if (prod->hasName() && boost::regex_match(prod->Name(), r)) {
|
||||
name_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (name_found != name_filter_.include && traverse) {
|
||||
if (!name_filter_.values.empty()) {
|
||||
foreach(const boost::regex& r, name_filter_.values) {
|
||||
IfcSchema::IfcProduct* parent, *current = prod;
|
||||
while ((parent = static_cast<IfcSchema::IfcProduct*>(kernel.get_decomposing_entity(current))) != 0) {
|
||||
if (parent->hasName() && boost::regex_match(parent->Name(), r)) {
|
||||
name_found = true;
|
||||
if (prod->hasName() && boost::regex_match(prod->Name(), r)) {
|
||||
name_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (name_found != name_filter_.include && traverse) {
|
||||
foreach(const boost::regex& r, name_filter_.values) {
|
||||
IfcSchema::IfcProduct* parent, *current = prod;
|
||||
while ((parent = static_cast<IfcSchema::IfcProduct*>(kernel.get_decomposing_entity(current))) != 0) {
|
||||
if (parent->hasName() && boost::regex_match(parent->Name(), r)) {
|
||||
name_found = true;
|
||||
break;
|
||||
}
|
||||
current = parent;
|
||||
}
|
||||
if (name_found) {
|
||||
break;
|
||||
}
|
||||
current = parent;
|
||||
}
|
||||
if (name_found) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool guid_found = false;
|
||||
foreach(const boost::regex& r, guid_filter_.values) {
|
||||
if (boost::regex_match(prod->GlobalId(), r)) {
|
||||
guid_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (guid_found != guid_filter_.include && traverse) {
|
||||
if (!guid_filter_.values.empty()) {
|
||||
foreach(const boost::regex& r, guid_filter_.values) {
|
||||
IfcSchema::IfcProduct* parent, *current = prod;
|
||||
while ((parent = static_cast<IfcSchema::IfcProduct*>(kernel.get_decomposing_entity(current))) != 0) {
|
||||
if (boost::regex_match(parent->GlobalId(), r)) {
|
||||
guid_found = true;
|
||||
break;
|
||||
}
|
||||
current = parent;
|
||||
}
|
||||
if (guid_found) {
|
||||
if (boost::regex_match(prod->GlobalId(), r)) {
|
||||
std::cout << prod->GlobalId() << std::endl;
|
||||
guid_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (guid_found != guid_filter_.include && traverse) {
|
||||
foreach(const boost::regex& r, guid_filter_.values) {
|
||||
IfcSchema::IfcProduct* parent, *current = prod;
|
||||
while ((parent = static_cast<IfcSchema::IfcProduct*>(kernel.get_decomposing_entity(current))) != 0) {
|
||||
if (boost::regex_match(parent->GlobalId(), r)) {
|
||||
guid_found = true;
|
||||
break;
|
||||
}
|
||||
current = parent;
|
||||
}
|
||||
if (guid_found) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (type_found == entity_filter_.include && name_found == name_filter_.include && guid_found == guid_filter_.include) {
|
||||
bool layer_found = false;
|
||||
if (!layer_filter_.values.empty()) {
|
||||
std::map<std::string, IfcSchema::IfcPresentationLayerAssignment*> layers = IfcGeom::Kernel::get_layers(prod);
|
||||
std::map<std::string, IfcSchema::IfcPresentationLayerAssignment*>::const_iterator lit;
|
||||
foreach(const boost::regex& r, layer_filter_.values) {
|
||||
for (lit = layers.begin(); lit != layers.end(); ++lit) {
|
||||
if (boost::regex_match(lit->first, r)) {
|
||||
layer_found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (layer_found) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (layer_found != layer_filter_.include && traverse) {
|
||||
foreach(const boost::regex& r, layer_filter_.values) {
|
||||
for (lit = layers.begin(); lit != layers.end(); ++lit) {
|
||||
IfcSchema::IfcProduct* parent, *current = prod;
|
||||
while ((parent = static_cast<IfcSchema::IfcProduct*>(kernel.get_decomposing_entity(current))) != 0) {
|
||||
if (boost::regex_match(lit->first, r)) {
|
||||
layer_found = true;
|
||||
break;
|
||||
}
|
||||
current = parent;
|
||||
}
|
||||
if (layer_found) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (type_found == entity_filter_.include && name_found == name_filter_.include &&
|
||||
guid_found == guid_filter_.include && layer_found == layer_filter_.include) {
|
||||
ifcproducts->push(prod);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ifcproduct_iterator = ifcproducts->begin();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user