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)
{
std::cout << "Usage: IfcConvert [options] <input.ifc> [<output>]" << "\n"
std::cout << "Usage: IfcConvert [options] <input.ifc> [<output>]\n"
<< "\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"
<< "Converts the geometry in an IFC file into one of the following formats:\n"
<< " .obj WaveFront OBJ (a .mtl file is also created)\n"
#ifdef WITH_OPENCOLLADA
<< " .dae Collada Digital Assets Exchange" << "\n"
<< " .dae Collada Digital Assets Exchange\n"
#endif
<< " .stp STEP Standard for the Exchange of Product Data" << "\n"
<< " .igs IGES Initial Graphics Exchange Specification" << "\n"
<< " .xml XML Property definitions and decomposition tree" << "\n"
<< " .svg SVG Scalable Vector Graphics (2D floor plan)" << "\n"
<< " .stp STEP Standard for the Exchange of Product Data\n"
<< " .igs IGES Initial Graphics Exchange Specification\n"
<< " .xml XML Property definitions and decomposition tree\n"
<< " .svg SVG Scalable Vector Graphics (2D floor plan)\n"
<< "\n"
<< "If no output filename given, <input>." + DEFAULT_EXTENSION + " will be used as the output file.\n";
if (suggest_help) {
@@ -81,6 +81,7 @@ void print_usage(bool suggest_help = true)
std::cout << std::endl;
}
/// @todo Add help for single option
void print_options(const po::options_description& 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;
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::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::arg_map_t tag_args; // IfcProxy.Tag & IfcElement.Tag
std::vector<IfcGeom::filter_t> filters;
IfcGeom::string_arg_filter tag_filter(IfcSchema::Type::IfcProxy, 8, IfcSchema::Type::IfcElement, 7); // IfcProxy.Tag & IfcElement.Tag
struct geom_filter
{
@@ -136,10 +136,10 @@ struct geom_filter
};
// 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.
struct inclusion_filter : public IfcGeom::filter, public geom_filter { inclusion_filter() : filter(true, false) {} };
struct exclusion_filter : public IfcGeom::filter, public geom_filter { exclusion_filter() : filter(false, false) {} };
struct inclusion_filter : public geom_filter {};
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)
{
@@ -158,10 +158,6 @@ int main(int argc, char** argv)
double deflection_tolerance;
inclusion_filter include_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");
geom_options.add_options()
@@ -284,7 +280,7 @@ int main(int argc, char** argv)
po::store(po::command_line_parser(argc, argv).
options(cmdline_options).positional(positional_options).run(), vmap);
} 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();
return EXIT_FAILURE;
} catch (const po::error_with_option_name& e) {
@@ -395,7 +391,9 @@ int main(int argc, char** argv)
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;
}
@@ -497,7 +495,7 @@ int main(int argc, char** argv)
time_t start,end;
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()) {
/// @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.
@@ -604,7 +602,7 @@ int main(int argc, char** argv)
void write_log() {
std::string log = log_stream.str();
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;
}
/// @todo Clean up this filter initialization code
/// @return The number of set up filters, if less than 1, an error occurred.
size_t setup_filters(
const inclusion_filter& include_filter,
const exclusion_filter& exclude_filter,
const std::string &output_extension,
/// @todo Clean up this filter initialization code further.
/// @return The used filters, if none an error occurred.
std::vector<IfcGeom::filter_t> setup_filters(
const geom_filter& include_filter,
const geom_filter& exclude_filter,
const std::string& output_extension,
bool traverse)
{
std::vector<IfcGeom::filter_t> filters;
entity_filter.traverse = traverse;
try {
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, ", "));
}
} catch (const IfcParse::IfcException& e) {
std::cout << "[Error] " << e.what() << std::endl;
return filters.size();
std::cerr << "[Error] " << e.what() << std::endl;
return filters;
}
if (!entity_filter.values.empty()) {
filters.push_back(boost::ref(entity_filter));
@@ -704,7 +703,7 @@ size_t setup_filters(
guid_filter.populate(include_filter.values);
} else if (exclude_filter.arg == GUID_ARG) {
guid_filter.include = false;
guid_filter.populate(include_filter.values);
guid_filter.populate(exclude_filter.values);
}
if (!guid_filter.values.empty()) {
filters.push_back(boost::ref(guid_filter));
@@ -734,9 +733,6 @@ size_t setup_filters(
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;
if (include_filter.arg == TAG_ARG) {
tag_filter.include = true;
@@ -748,7 +744,6 @@ size_t setup_filters(
if (!tag_filter.values.empty()) {
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.
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 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
void assert_arguments()
@@ -131,7 +139,7 @@ namespace IfcGeom
{
for (arg_map_t::const_iterator it = args.begin(); it != args.end(); ++it) {
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()) {
return *arg;
}