support for IfcConvert -include=arg <Description|Tag> (for IfcElement.Tag, not yet for IfcProxy.Tag).

This commit is contained in:
Stinkfist0
2017-02-16 19:49:46 +02:00
committed by Thomas Krijnen
parent de5864fc72
commit 1b7d38a56d
3 changed files with 96 additions and 47 deletions
+74 -40
View File
@@ -122,7 +122,7 @@ void write_log();
struct geom_filter
{
geom_filter() : type(UNUSED) {}
enum filter_type { UNUSED, ENTITY_TYPE, ENTITY_ARG, LAYER_NAME };
enum filter_type { UNUSED, ENTITY_TYPE, LAYER_NAME, ENTITY_ARG };
filter_type type;
std::string arg;
std::set<std::string> values;
@@ -151,9 +151,8 @@ int main(int argc, char** argv)
exclusion_filter exclude_filter;
supported_args.push_back(NAME_ARG);
supported_args.push_back(GUID_ARG);
/// @todo
//supported_args.push_back(DESC_ARG);
//supported_args.push_back(TAG_ARG);
supported_args.push_back(DESC_ARG);
supported_args.push_back(TAG_ARG);
po::options_description geom_options("Geometry options");
geom_options.add_options()
@@ -207,7 +206,7 @@ int main(int argc, char** argv)
"2) 'layers': the entities 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. "
"Currently supported arguments are GlobalId and Name.\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)."
"--include and --exclude cannot be placed right before input file argument and "
"only single of each argument supported for now. See also --exclude and --traverse.")
@@ -389,6 +388,7 @@ int main(int argc, char** argv)
// Set up filters. Entity filter is used always by default.
std::vector<IfcGeom::filter_t> filters;
/// @todo Clean up this filter initialization code
IfcGeom::entity_filter entity_filter;
entity_filter.traverse = traverse;
@@ -418,25 +418,8 @@ int main(int argc, char** argv)
std::cout << "[Error] " << e.what() << std::endl;
return 1;
}
IfcGeom::arg_filter<IfcSchema::IfcRoot, 2, std::string> name_filter;
name_filter.traverse = traverse;
if (include_filter.arg == NAME_ARG) {
name_filter.include = true;
name_filter.populate(include_filter.values);
} else if (exclude_filter.arg == NAME_ARG) {
name_filter.include = false;
name_filter.populate(exclude_filter.values);
}
IfcGeom::arg_filter<IfcSchema::IfcRoot, 0, std::string> guid_filter;
guid_filter.traverse = traverse;
if (include_filter.arg == GUID_ARG) {
guid_filter.include = true;
guid_filter.populate(include_filter.values);
} else if (exclude_filter.arg == GUID_ARG) {
guid_filter.include = false;
guid_filter.populate(include_filter.values);
if (!entity_filter.values.empty()) {
filters.push_back(boost::ref(entity_filter));
}
IfcGeom::layer_filter layer_filter;
@@ -448,6 +431,71 @@ int main(int argc, char** argv)
layer_filter.include = false;
layer_filter.populate(exclude_filter.values);
}
if (!layer_filter.values.empty()) {
filters.push_back(boost::ref(layer_filter));
}
// IfcRoot.GlobalId
IfcGeom::arg_filter<IfcSchema::IfcRoot, 0, std::string> guid_filter;
guid_filter.traverse = traverse;
if (include_filter.arg == GUID_ARG) {
guid_filter.include = true;
guid_filter.populate(include_filter.values);
} else if (exclude_filter.arg == GUID_ARG) {
guid_filter.include = false;
guid_filter.populate(include_filter.values);
}
if (!guid_filter.values.empty()) {
filters.push_back(boost::ref(guid_filter));
}
// Note: skipping IfcRoot OwnerHistory, argument index 1
// IfcRoot.Name
IfcGeom::arg_filter<IfcSchema::IfcRoot, 2, std::string> name_filter;
name_filter.traverse = traverse;
if (include_filter.arg == NAME_ARG) {
name_filter.include = true;
name_filter.populate(include_filter.values);
} else if (exclude_filter.arg == NAME_ARG) {
name_filter.include = false;
name_filter.populate(exclude_filter.values);
}
if (!name_filter.values.empty()) {
filters.push_back(boost::ref(name_filter));
}
// IfcRoot.Description
IfcGeom::arg_filter<IfcSchema::IfcRoot, 3, std::string> desc_filter;
desc_filter.traverse = traverse;
if (include_filter.arg == DESC_ARG) {
desc_filter.include = true;
desc_filter.populate(include_filter.values);
} else if (exclude_filter.arg == DESC_ARG) {
desc_filter.include = false;
desc_filter.populate(exclude_filter.values);
}
if (!desc_filter.values.empty()) {
filters.push_back(boost::ref(desc_filter));
}
/// @todo IfcProxy.Tag
//IfcGeom::arg_filter<IfcSchema::IfcProxy, 8, std::string> tag_filter;
// IfcElement.Tag
IfcGeom::arg_filter<IfcSchema::IfcElement, 7, std::string> tag_filter;
tag_filter.traverse = traverse;
if (include_filter.arg == TAG_ARG) {
tag_filter.include = true;
tag_filter.populate(include_filter.values);
} else if (exclude_filter.arg == TAG_ARG) {
tag_filter.include = false;
tag_filter.populate(exclude_filter.values);
}
if (!tag_filter.values.empty()) {
filters.push_back(boost::ref(tag_filter));
}
///@ todo Logger::Message(Logger::LOG_NOTICE, "Filtering by X, Y and Z.")
if (output_extension == ".xml") {
int exit_code = 1;
@@ -537,21 +585,6 @@ int main(int argc, char** argv)
settings.set(IfcGeom::IteratorSettings::DISABLE_TRIANGULATION, true);
}
IfcGeom::Iterator<real_t> context_iterator(settings, input_filename);
if (!guid_filter.values.empty()) {
context_iterator.filters().push_back(boost::ref(guid_filter));
}
if (!name_filter.values.empty()) {
context_iterator.filters().push_back(boost::ref(name_filter));
}
if (!entity_filter.values.empty()) {
context_iterator.filters().push_back(boost::ref(entity_filter));
}
if (!layer_filter.values.empty()) {
context_iterator.filters().push_back(boost::ref(layer_filter));
}
if (!serializer->ready()) {
write_log();
return 1;
@@ -559,7 +592,8 @@ int main(int argc, char** argv)
time_t start,end;
time(&start);
IfcGeom::Iterator<real_t> context_iterator(settings, input_filename, filters);
if (!context_iterator.initialize()) {
/// @todo It would be nice to know and print separate error prints for a case where we failed to parse
/// the file and for a case where we found no entities that satisfy our filtering criteria.
+9 -5
View File
@@ -24,7 +24,11 @@
#define IFCGEOMFILTER_H
#include "IfcGeom.h"
#include <boost/function.hpp>
#include <boost/regex.hpp>
#include <boost/algorithm/string/replace.hpp>
#include <boost/algorithm/string/case_conv.hpp>
namespace IfcGeom
{
@@ -100,13 +104,13 @@ namespace IfcGeom
/// @todo Maybe not use template class for this after all. Attribute name would be better
/// than index, but IfcBaseClass doesn't have getArgument(name) (IfcLateBoundEntity would have though).
template<class ClassType, unsigned short ArgIndex, typename ArgType>
template<class IfcType, unsigned short ArgIndex, typename ArgType>
struct arg_filter : public wildcard_filter
{
arg_filter()
{
#ifndef NDEBUG
ClassType dummy(0);
IfcType dummy(0);
assert(ArgIndex < dummy.getArgumentCount());
#endif
}
@@ -114,7 +118,7 @@ namespace IfcGeom
: wildcard_filter(include, traverse, patterns)
{
#ifndef NDEBUG
ClassType dummy(0);
IfcType dummy(0);
assert(ArgIndex < dummy.getArgumentCount());
#endif
populate(patterns);
@@ -122,8 +126,8 @@ namespace IfcGeom
ArgType value(IfcSchema::IfcProduct* prod) const
{
Argument *arg = prod->entity->getArgument(ArgIndex);
return !arg->isNull() ? *arg : ArgType();
Argument *arg = prod->is(IfcType::Class()) ? prod->entity->getArgument(ArgIndex) : 0;
return arg && !arg->isNull() ? *arg : ArgType();
}
bool operator()(IfcSchema::IfcProduct* prod) const
+13 -2
View File
@@ -145,7 +145,18 @@ namespace IfcGeom {
}
}
/// @todo public/private sections all over the place: move all public to the beginning of the class
public:
Iterator(const IteratorSettings& settings, const std::string& filename, std::vector<filter_t>& filters)
: settings(settings)
, ifc_file(new IfcParse::IfcFile)
, owns_ifc_file(true)
, filters_(filters)
{
ifc_file->Init(filename);
_initialize();
}
bool initialize() {
try {
initUnits();
@@ -307,8 +318,8 @@ namespace IfcGeom {
IfcParse::IfcFile* getFile() const { return ifc_file; }
const std::vector<filter_t> &filters() const { return filters_; }
std::vector<filter_t> &filters() { return filters_; }
const std::vector<filter_t>& filters() const { return filters_; }
std::vector<filter_t>& filters() { return filters_; }
const gp_XYZ& bounds_min() const { return bounds_min_; }
const gp_XYZ& bounds_max() const { return bounds_max_; }