IfcConvert: minor cleanup + fix guid exclusion filter's value population.

This commit is contained in:
Stinkfist0
2017-02-21 16:04:05 +02:00
committed by Thomas Krijnen
parent 470b08cd04
commit 4b5790e83a
2 changed files with 41 additions and 38 deletions
+32 -37
View File
@@ -62,17 +62,17 @@ void print_version()
void print_usage(bool suggest_help = true) void print_usage(bool suggest_help = true)
{ {
std::cout << "Usage: IfcConvert [options] <input.ifc> [<output>]" << "\n" std::cout << "Usage: IfcConvert [options] <input.ifc> [<output>]\n"
<< "\n" << "\n"
<< "Converts the geometry in an IFC file into one of the following formats:" << "\n" << "Converts the geometry in an IFC file into one of the following formats:\n"
<< " .obj WaveFront OBJ (a .mtl file is also created)" << "\n" << " .obj WaveFront OBJ (a .mtl file is also created)\n"
#ifdef WITH_OPENCOLLADA #ifdef WITH_OPENCOLLADA
<< " .dae Collada Digital Assets Exchange" << "\n" << " .dae Collada Digital Assets Exchange\n"
#endif #endif
<< " .stp STEP Standard for the Exchange of Product Data" << "\n" << " .stp STEP Standard for the Exchange of Product Data\n"
<< " .igs IGES Initial Graphics Exchange Specification" << "\n" << " .igs IGES Initial Graphics Exchange Specification\n"
<< " .xml XML Property definitions and decomposition tree" << "\n" << " .xml XML Property definitions and decomposition tree\n"
<< " .svg SVG Scalable Vector Graphics (2D floor plan)" << "\n" << " .svg SVG Scalable Vector Graphics (2D floor plan)\n"
<< "\n" << "\n"
<< "If no output filename given, <input>." + DEFAULT_EXTENSION + " will be used as the output file.\n"; << "If no output filename given, <input>." + DEFAULT_EXTENSION + " will be used as the output file.\n";
if (suggest_help) { if (suggest_help) {
@@ -81,6 +81,7 @@ void print_usage(bool suggest_help = true)
std::cout << std::endl; std::cout << std::endl;
} }
/// @todo Add help for single option
void print_options(const po::options_description& options) void print_options(const po::options_description& options)
{ {
std::cout << "\n" << options; std::cout << "\n" << options;
@@ -115,16 +116,15 @@ bool rename_file(const std::string& old_filename, const std::string& new_filenam
static std::stringstream log_stream; static std::stringstream log_stream;
void write_log(); void write_log();
const std::string NAME_ARG = "Name", GUID_ARG = "GlobalId", DESC_ARG = "Description", TAG_ARG = "Tag";
std::vector<std::string> supported_args;
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";
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 IfcGeom::string_arg_filter guid_filter(IfcSchema::Type::IfcRoot, 0); // IfcRoot.GlobalId
// Note: skipping IfcRoot OwnerHistory, argument index 1 // Note: skipping IfcRoot OwnerHistory, argument index 1
IfcGeom::string_arg_filter name_filter(IfcSchema::Type::IfcRoot, 2); // IfcRoot.Name 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 desc_filter(IfcSchema::Type::IfcRoot, 3); // IfcRoot.Description
IfcGeom::string_arg_filter::arg_map_t tag_args; // IfcProxy.Tag & IfcElement.Tag IfcGeom::string_arg_filter tag_filter(IfcSchema::Type::IfcProxy, 8, IfcSchema::Type::IfcElement, 7); // IfcProxy.Tag & IfcElement.Tag
std::vector<IfcGeom::filter_t> filters;
struct geom_filter struct geom_filter
{ {
@@ -136,10 +136,10 @@ struct geom_filter
}; };
// Specialized classes for knowing which type of filter we are validating within validate(). // Specialized classes for knowing which type of filter we are validating within validate().
// Could not figure out easily how else to know it if using single type for both. // Could not figure out easily how else to know it if using single type for both.
struct inclusion_filter : public IfcGeom::filter, public geom_filter { inclusion_filter() : filter(true, false) {} }; struct inclusion_filter : public geom_filter {};
struct exclusion_filter : public IfcGeom::filter, public geom_filter { exclusion_filter() : filter(false, false) {} }; struct exclusion_filter : public geom_filter {};
size_t setup_filters(const inclusion_filter&, const exclusion_filter&, const std::string&, bool); std::vector<IfcGeom::filter_t> setup_filters(const geom_filter&, const geom_filter&, const std::string&, bool);
int main(int argc, char** argv) int main(int argc, char** argv)
{ {
@@ -158,10 +158,6 @@ int main(int argc, char** argv)
double deflection_tolerance; double deflection_tolerance;
inclusion_filter include_filter; inclusion_filter include_filter;
exclusion_filter exclude_filter; exclusion_filter exclude_filter;
supported_args.push_back(NAME_ARG);
supported_args.push_back(GUID_ARG);
supported_args.push_back(DESC_ARG);
supported_args.push_back(TAG_ARG);
po::options_description geom_options("Geometry options"); po::options_description geom_options("Geometry options");
geom_options.add_options() geom_options.add_options()
@@ -284,7 +280,7 @@ int main(int argc, char** argv)
po::store(po::command_line_parser(argc, argv). po::store(po::command_line_parser(argc, argv).
options(cmdline_options).positional(positional_options).run(), vmap); options(cmdline_options).positional(positional_options).run(), vmap);
} catch (const po::unknown_option& e) { } catch (const po::unknown_option& e) {
std::cerr << "[Error] Unknown option '" << e.get_option_name() << "'" << "\n\n"; std::cerr << "[Error] Unknown option '" << e.get_option_name() << "'\n\n";
print_usage(); print_usage();
return EXIT_FAILURE; return EXIT_FAILURE;
} catch (const po::error_with_option_name& e) { } catch (const po::error_with_option_name& e) {
@@ -395,7 +391,9 @@ int main(int argc, char** argv)
boost::to_lower(output_extension); boost::to_lower(output_extension);
if (!setup_filters(include_filter, exclude_filter, output_extension, traverse)) { std::vector<IfcGeom::filter_t> used_filters = setup_filters(include_filter, exclude_filter, output_extension, traverse);
if (used_filters.empty()) {
std::cerr << "[Error] Failed to set up geometry filters\n";
return EXIT_FAILURE; return EXIT_FAILURE;
} }
@@ -497,7 +495,7 @@ int main(int argc, char** argv)
time_t start,end; time_t start,end;
time(&start); time(&start);
IfcGeom::Iterator<real_t> context_iterator(settings, input_filename, filters); IfcGeom::Iterator<real_t> context_iterator(settings, input_filename, used_filters);
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 failed to parse /// @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. /// the file and for a case where we found no entities that satisfy our filtering criteria.
@@ -604,7 +602,7 @@ int main(int argc, char** argv)
void write_log() { void write_log() {
std::string log = log_stream.str(); std::string log = log_stream.str();
if (!log.empty()) { if (!log.empty()) {
std::cout << "\n" << "Log:\n" << log << std::endl; std::cout << "\nLog:\n" << log << std::endl;
} }
} }
@@ -647,14 +645,15 @@ void validate(boost::any& v, const std::vector<std::string>& values, exclusion_f
v = filter; v = filter;
} }
/// @todo Clean up this filter initialization code /// @todo Clean up this filter initialization code further.
/// @return The number of set up filters, if less than 1, an error occurred. /// @return The used filters, if none an error occurred.
size_t setup_filters( std::vector<IfcGeom::filter_t> setup_filters(
const inclusion_filter& include_filter, const geom_filter& include_filter,
const exclusion_filter& exclude_filter, const geom_filter& exclude_filter,
const std::string &output_extension, const std::string& output_extension,
bool traverse) bool traverse)
{ {
std::vector<IfcGeom::filter_t> filters;
entity_filter.traverse = traverse; entity_filter.traverse = traverse;
try { try {
if (include_filter.type == geom_filter::ENTITY_TYPE) { if (include_filter.type == geom_filter::ENTITY_TYPE) {
@@ -679,8 +678,8 @@ size_t setup_filters(
std::string(" by default entities ") + boost::algorithm::join(entities, ", ")); std::string(" by default entities ") + boost::algorithm::join(entities, ", "));
} }
} catch (const IfcParse::IfcException& e) { } catch (const IfcParse::IfcException& e) {
std::cout << "[Error] " << e.what() << std::endl; std::cerr << "[Error] " << e.what() << std::endl;
return filters.size(); return filters;
} }
if (!entity_filter.values.empty()) { if (!entity_filter.values.empty()) {
filters.push_back(boost::ref(entity_filter)); filters.push_back(boost::ref(entity_filter));
@@ -704,7 +703,7 @@ size_t setup_filters(
guid_filter.populate(include_filter.values); guid_filter.populate(include_filter.values);
} else if (exclude_filter.arg == GUID_ARG) { } else if (exclude_filter.arg == GUID_ARG) {
guid_filter.include = false; guid_filter.include = false;
guid_filter.populate(include_filter.values); guid_filter.populate(exclude_filter.values);
} }
if (!guid_filter.values.empty()) { if (!guid_filter.values.empty()) {
filters.push_back(boost::ref(guid_filter)); filters.push_back(boost::ref(guid_filter));
@@ -734,9 +733,6 @@ size_t setup_filters(
filters.push_back(boost::ref(desc_filter)); filters.push_back(boost::ref(desc_filter));
} }
tag_args[IfcSchema::Type::IfcProxy] = 8;
tag_args[IfcSchema::Type::IfcElement] = 7;
IfcGeom::string_arg_filter tag_filter(tag_args);
tag_filter.traverse = traverse; tag_filter.traverse = traverse;
if (include_filter.arg == TAG_ARG) { if (include_filter.arg == TAG_ARG) {
tag_filter.include = true; tag_filter.include = true;
@@ -748,7 +744,6 @@ size_t setup_filters(
if (!tag_filter.values.empty()) { if (!tag_filter.values.empty()) {
filters.push_back(boost::ref(tag_filter)); filters.push_back(boost::ref(tag_filter));
} }
return true;
return filters.size(); return filters;
} }
+9 -1
View File
@@ -113,6 +113,14 @@ namespace IfcGeom
/// @todo Take only attribute name when IfcBaseClass and IfcLateBoundEntity are merged. /// @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(arg_map_t args) : args(args) { assert_arguments(); }
string_arg_filter(IfcSchema::Type::Enum type, unsigned short index) { args[type] = index; assert_arguments(); } string_arg_filter(IfcSchema::Type::Enum type, unsigned short index) { args[type] = index; assert_arguments(); }
string_arg_filter(
IfcSchema::Type::Enum type1, unsigned short index1,
IfcSchema::Type::Enum 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 /// @todo this won't be needed when we have the generic argument name access
void assert_arguments() void assert_arguments()
@@ -131,7 +139,7 @@ namespace IfcGeom
{ {
for (arg_map_t::const_iterator it = args.begin(); it != args.end(); ++it) { for (arg_map_t::const_iterator it = args.begin(); it != args.end(); ++it) {
if (prod->is(it->first)) { if (prod->is(it->first)) {
Argument *arg = (it->second <= prod->entity->getArgumentCount() ? prod->entity->getArgument(it->second) : 0); Argument *arg = (it->second < prod->entity->getArgumentCount() ? prod->entity->getArgument(it->second) : 0);
if (arg && !arg->isNull()) { if (arg && !arg->isNull()) {
return *arg; return *arg;
} }