Merge branch 'master' into v0.6.0

This commit is contained in:
Thomas Krijnen
2019-02-06 15:39:43 +01:00
6 changed files with 66 additions and 46 deletions
+33 -19
View File
@@ -122,6 +122,7 @@ 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(bool); void write_log(bool);
void fix_quantities(IfcParse::IfcFile&, bool, bool, bool); void fix_quantities(IfcParse::IfcFile&, bool, bool, bool);
std::string format_duration(time_t start, time_t end);
/// @todo make the filters non-global /// @todo make the filters non-global
IfcGeom::entity_filter entity_filter; // Entity filter is used always by default. IfcGeom::entity_filter entity_filter; // Entity filter is used always by default.
@@ -475,10 +476,14 @@ int main(int argc, char** argv)
int exit_code = EXIT_FAILURE; int exit_code = EXIT_FAILURE;
try { try {
if (init_input_file(input_filename, ifc_file, no_progress || quiet, mmap)) { if (init_input_file(input_filename, ifc_file, no_progress || quiet, mmap)) {
time_t start, end;
time(&start);
XmlSerializer s(ifc_file, output_temp_filename); XmlSerializer s(ifc_file, output_temp_filename);
Logger::Status("Writing XML output..."); Logger::Status("Writing XML output...");
s.finalize(); s.finalize();
Logger::Status("Done!"); time(&end);
Logger::Status("Done! Conversion took " + format_duration(start, end));
rename_file(output_temp_filename, output_filename); rename_file(output_temp_filename, output_filename);
exit_code = EXIT_SUCCESS; exit_code = EXIT_SUCCESS;
} }
@@ -786,28 +791,33 @@ int main(int argc, char** argv)
time(&end); time(&end);
if (!quiet) { if (!quiet) {
int seconds = (int)difftime(end, start); Logger::Status("\nConversion took " + format_duration(start, end));
std::stringstream msg; }
int minutes = seconds / 60;
seconds = seconds % 60;
msg << "\nConversion took";
if (minutes > 0) {
msg << " " << minutes << " minute";
if (minutes > 1) {
msg << "s";
}
}
msg << " " << seconds << " second";
if (seconds > 1) {
msg << "s";
}
Logger::Status(msg.str());
}
return successful ? EXIT_SUCCESS : EXIT_FAILURE; return successful ? EXIT_SUCCESS : EXIT_FAILURE;
} }
std::string format_duration(time_t start, time_t end)
{
int seconds = (int)difftime(end, start);
std::stringstream ss;
int minutes = seconds / 60;
seconds = seconds % 60;
if (minutes > 0) {
ss << minutes << " minute";
if (minutes == 0 || minutes > 1) {
ss << "s";
}
ss << " ";
}
ss << seconds << " second";
if (seconds == 0 || seconds > 1) {
ss << "s";
}
return ss.str();
}
void write_log(bool header) { void write_log(bool header) {
std::string log = log_stream.str(); std::string log = log_stream.str();
if (!log.empty()) { if (!log.empty()) {
@@ -821,10 +831,12 @@ void write_log(bool header) {
#include <boost/algorithm/string/predicate.hpp> #include <boost/algorithm/string/predicate.hpp>
bool init_input_file(const std::string& filename, IfcParse::IfcFile*& ifc_file, bool no_progress, bool mmap) { bool init_input_file(const std::string& filename, IfcParse::IfcFile*& ifc_file, bool no_progress, bool mmap) {
time_t start, end;
// Prevent IfcFile::Init() prints by setting output to null temporarily // Prevent IfcFile::Init() prints by setting output to null temporarily
if (no_progress) { Logger::SetOutput(NULL, &log_stream); } if (no_progress) { Logger::SetOutput(NULL, &log_stream); }
time(&start);
#ifdef USE_MMAP #ifdef USE_MMAP
ifc_file = new IfcParse::IfcFile(filename, mmap); ifc_file = new IfcParse::IfcFile(filename, mmap);
#else #else
@@ -841,8 +853,10 @@ bool init_input_file(const std::string& filename, IfcParse::IfcFile*& ifc_file,
Logger::Error("Unable to parse input file '" + filename + "'"); Logger::Error("Unable to parse input file '" + filename + "'");
return false; return false;
} }
time(&end);
if (no_progress) { Logger::SetOutput(&std::cout, &log_stream); } if (no_progress) { Logger::SetOutput(&std::cout, &log_stream); }
else { Logger::Status("Parsing input file took " + format_duration(start, end)); }
return true; return true;
-17
View File
@@ -151,15 +151,6 @@ IfcUtil::IfcBaseEntity* IfcGeom::Kernel::get_decomposing_entity(IfcUtil::IfcBase
} }
namespace { namespace {
// LayerAssignments renamed from plural to singular, LayerAssignment, so work around that
IfcEntityList::ptr getLayerAssignments(Ifc2x3::IfcRepresentationItem* item) {
return item->LayerAssignments()->generalize();
}
IfcEntityList::ptr getLayerAssignments(Ifc4::IfcRepresentationItem* item) {
return item->LayerAssignment()->generalize();
}
template <typename Schema> template <typename Schema>
static std::map<std::string, IfcUtil::IfcBaseEntity*> get_layers_impl(typename Schema::IfcProduct* prod) { static std::map<std::string, IfcUtil::IfcBaseEntity*> get_layers_impl(typename Schema::IfcProduct* prod) {
std::map<std::string, IfcUtil::IfcBaseEntity*> layers; std::map<std::string, IfcUtil::IfcBaseEntity*> layers;
@@ -172,14 +163,6 @@ namespace {
layers[(*jt)->Name()] = *jt; layers[(*jt)->Name()] = *jt;
} }
} }
typename Schema::IfcRepresentationItem::list::ptr items = r->as<typename Schema::IfcRepresentationItem>();
for (typename Schema::IfcRepresentationItem::list::it it = items->begin(); it != items->end(); ++it) {
typename Schema::IfcPresentationLayerAssignment::list::ptr a = getLayerAssignments(*it)->template as<typename Schema::IfcPresentationLayerAssignment>();
for (typename Schema::IfcPresentationLayerAssignment::list::it jt = a->begin(); jt != a->end(); ++jt) {
layers[(*jt)->Name()] = *jt;
}
}
} }
return layers; return layers;
} }
+1
View File
@@ -40,6 +40,7 @@ public:
it end(); it end();
IfcUtil::IfcBaseClass* operator[] (int i); IfcUtil::IfcBaseClass* operator[] (int i);
unsigned int size() const; unsigned int size() const;
void reserve(unsigned capacity);
bool contains(IfcUtil::IfcBaseClass*) const; bool contains(IfcUtil::IfcBaseClass*) const;
template <class U> template <class U>
typename U::list::ptr as() { typename U::list::ptr as() {
+6
View File
@@ -41,6 +41,7 @@ public:
typedef boost::unordered_map<unsigned int, IfcUtil::IfcBaseClass*> entity_by_id_t; typedef boost::unordered_map<unsigned int, IfcUtil::IfcBaseClass*> entity_by_id_t;
typedef std::map<std::string, IfcUtil::IfcBaseClass*> entity_by_guid_t; typedef std::map<std::string, IfcUtil::IfcBaseClass*> entity_by_guid_t;
typedef std::map<unsigned int, std::vector<unsigned int> > entities_by_ref_t; typedef std::map<unsigned int, std::vector<unsigned int> > entities_by_ref_t;
typedef std::map<unsigned int, IfcEntityList::ptr> ref_map_t;
typedef entity_by_id_t::const_iterator const_iterator; typedef entity_by_id_t::const_iterator const_iterator;
class type_iterator : private entities_by_type_t::const_iterator { class type_iterator : private entities_by_type_t::const_iterator {
@@ -86,6 +87,7 @@ private:
entities_by_type_t bytype; entities_by_type_t bytype;
entities_by_type_t bytype_excl; entities_by_type_t bytype_excl;
entities_by_ref_t byref; entities_by_ref_t byref;
ref_map_t by_ref_cached_;
entity_by_guid_t byguid; entity_by_guid_t byguid;
entity_entity_map_t entity_file_map; entity_entity_map_t entity_file_map;
@@ -181,6 +183,10 @@ public:
IfcEntityList::ptr getInverse(int instance_id, const IfcParse::declaration* type, int attribute_index); IfcEntityList::ptr getInverse(int instance_id, const IfcParse::declaration* type, int attribute_index);
/// Marks entity as modified so that potential cache for it is invalidated.
/// @todo Currently the whole cache is invalidated. Implement more fine-grained invalidation.
void mark_entity_as_modified(int id);
unsigned int FreshId() { return ++MaxId; } unsigned int FreshId() { return ++MaxId; }
IfcUtil::IfcBaseClass* addEntity(IfcUtil::IfcBaseClass* entity); IfcUtil::IfcBaseClass* addEntity(IfcUtil::IfcBaseClass* entity);
+25 -10
View File
@@ -1257,7 +1257,9 @@ void IfcEntityInstanceData::setArgument(unsigned int i, Argument* a, IfcUtil::Ar
if (this->file) { if (this->file) {
register_inverse_visitor visitor(*this->file, *this); register_inverse_visitor visitor(*this->file, *this);
apply_individual_instance_visitor(copy).apply(visitor); apply_individual_instance_visitor(copy).apply(visitor);
}
this->file->mark_entity_as_modified(id_);
}
attributes_[i] = copy; attributes_[i] = copy;
} }
@@ -1504,6 +1506,11 @@ IfcEntityList::ptr IfcFile::traverse(IfcUtil::IfcBaseClass* instance, int max_le
return IfcParse::traverse(instance, max_level); return IfcParse::traverse(instance, max_level);
} }
void IfcFile::mark_entity_as_modified(int /*id*/)
{
by_ref_cached_.clear();
}
void IfcFile::addEntities(IfcEntityList::ptr es) { void IfcFile::addEntities(IfcEntityList::ptr es) {
for( IfcEntityList::it i = es->begin(); i != es->end(); ++ i ) { for( IfcEntityList::it i = es->begin(); i != es->end(); ++ i ) {
addEntity(*i); addEntity(*i);
@@ -1868,17 +1875,25 @@ IfcEntityList::ptr IfcFile::instances_by_type(const std::string& t) {
IfcEntityList::ptr IfcFile::instances_by_reference(int t) { IfcEntityList::ptr IfcFile::instances_by_reference(int t) {
entities_by_ref_t::const_iterator it = byref.find(t); entities_by_ref_t::const_iterator it = byref.find(t);
IfcEntityList::ptr return_value; IfcEntityList::ptr ret;
if (it != byref.end()) { if (it != byref.end()) {
const std::vector<unsigned>& ids = it->second; ref_map_t::const_iterator cached_it = by_ref_cached_.find(t);
for (std::vector<unsigned>::const_iterator jt = ids.begin(); jt != ids.end(); ++jt) { if (cached_it != by_ref_cached_.end()) {
if (!return_value) { ret = cached_it->second;
return_value.reset(new IfcEntityList); }
} else {
return_value->push(instance_by_id(*jt)); if (it->second.size()) {
} ret.reset(new IfcEntityList);
ret->reserve((unsigned)it->second.size());
const std::vector<unsigned>& ids = it->second;
for (std::vector<unsigned>::const_iterator jt = ids.begin(); jt != ids.end(); ++jt) {
ret->push(instance_by_id(*jt));
}
}
by_ref_cached_[t] = ret;
}
} }
return return_value; return ret;
} }
IfcUtil::IfcBaseClass* IfcFile::instance_by_id(int id) { IfcUtil::IfcBaseClass* IfcFile::instance_by_id(int id) {
+1
View File
@@ -42,6 +42,7 @@ void IfcEntityList::push(const IfcEntityList::ptr& l) {
} }
} }
unsigned int IfcEntityList::size() const { return (unsigned int) ls.size(); } unsigned int IfcEntityList::size() const { return (unsigned int) ls.size(); }
void IfcEntityList::reserve(unsigned capacity) { ls.reserve((size_t)capacity); }
IfcEntityList::it IfcEntityList::begin() { return ls.begin(); } IfcEntityList::it IfcEntityList::begin() { return ls.begin(); }
IfcEntityList::it IfcEntityList::end() { return ls.end(); } IfcEntityList::it IfcEntityList::end() { return ls.end(); }
IfcUtil::IfcBaseClass* IfcEntityList::operator[] (int i) { IfcUtil::IfcBaseClass* IfcEntityList::operator[] (int i) {