Skip to content

Commit 4df526f

Browse files
committed
Merge branch 'master' into v0.6.0
2 parents 42e0058 + 6bac067 commit 4df526f

6 files changed

Lines changed: 66 additions & 46 deletions

File tree

src/ifcconvert/IfcConvert.cpp

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ bool rename_file(const std::string& old_filename, const std::string& new_filenam
122122
static std::stringstream log_stream;
123123
void write_log(bool);
124124
void fix_quantities(IfcParse::IfcFile&, bool, bool, bool);
125+
std::string format_duration(time_t start, time_t end);
125126

126127
/// @todo make the filters non-global
127128
IfcGeom::entity_filter entity_filter; // Entity filter is used always by default.
@@ -475,10 +476,14 @@ int main(int argc, char** argv)
475476
int exit_code = EXIT_FAILURE;
476477
try {
477478
if (init_input_file(input_filename, ifc_file, no_progress || quiet, mmap)) {
479+
time_t start, end;
480+
time(&start);
478481
XmlSerializer s(ifc_file, output_temp_filename);
479482
Logger::Status("Writing XML output...");
480483
s.finalize();
481-
Logger::Status("Done!");
484+
time(&end);
485+
Logger::Status("Done! Conversion took " + format_duration(start, end));
486+
482487
rename_file(output_temp_filename, output_filename);
483488
exit_code = EXIT_SUCCESS;
484489
}
@@ -786,28 +791,33 @@ int main(int argc, char** argv)
786791

787792
time(&end);
788793

789-
if (!quiet) {
790-
int seconds = (int)difftime(end, start);
791-
std::stringstream msg;
792-
int minutes = seconds / 60;
793-
seconds = seconds % 60;
794-
msg << "\nConversion took";
795-
if (minutes > 0) {
796-
msg << " " << minutes << " minute";
797-
if (minutes > 1) {
798-
msg << "s";
799-
}
800-
}
801-
msg << " " << seconds << " second";
802-
if (seconds > 1) {
803-
msg << "s";
804-
}
805-
Logger::Status(msg.str());
806-
}
794+
if (!quiet) {
795+
Logger::Status("\nConversion took " + format_duration(start, end));
796+
}
807797

808798
return successful ? EXIT_SUCCESS : EXIT_FAILURE;
809799
}
810800

801+
std::string format_duration(time_t start, time_t end)
802+
{
803+
int seconds = (int)difftime(end, start);
804+
std::stringstream ss;
805+
int minutes = seconds / 60;
806+
seconds = seconds % 60;
807+
if (minutes > 0) {
808+
ss << minutes << " minute";
809+
if (minutes == 0 || minutes > 1) {
810+
ss << "s";
811+
}
812+
ss << " ";
813+
}
814+
ss << seconds << " second";
815+
if (seconds == 0 || seconds > 1) {
816+
ss << "s";
817+
}
818+
return ss.str();
819+
}
820+
811821
void write_log(bool header) {
812822
std::string log = log_stream.str();
813823
if (!log.empty()) {
@@ -821,10 +831,12 @@ void write_log(bool header) {
821831
#include <boost/algorithm/string/predicate.hpp>
822832

823833
bool init_input_file(const std::string& filename, IfcParse::IfcFile*& ifc_file, bool no_progress, bool mmap) {
834+
time_t start, end;
824835

825836
// Prevent IfcFile::Init() prints by setting output to null temporarily
826837
if (no_progress) { Logger::SetOutput(NULL, &log_stream); }
827838

839+
time(&start);
828840
#ifdef USE_MMAP
829841
ifc_file = new IfcParse::IfcFile(filename, mmap);
830842
#else
@@ -841,8 +853,10 @@ bool init_input_file(const std::string& filename, IfcParse::IfcFile*& ifc_file,
841853
Logger::Error("Unable to parse input file '" + filename + "'");
842854
return false;
843855
}
856+
time(&end);
844857

845858
if (no_progress) { Logger::SetOutput(&std::cout, &log_stream); }
859+
else { Logger::Status("Parsing input file took " + format_duration(start, end)); }
846860

847861
return true;
848862

src/ifcgeom_schema_agnostic/Kernel.cpp

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -151,15 +151,6 @@ IfcUtil::IfcBaseEntity* IfcGeom::Kernel::get_decomposing_entity(IfcUtil::IfcBase
151151
}
152152

153153
namespace {
154-
155-
// LayerAssignments renamed from plural to singular, LayerAssignment, so work around that
156-
IfcEntityList::ptr getLayerAssignments(Ifc2x3::IfcRepresentationItem* item) {
157-
return item->LayerAssignments()->generalize();
158-
}
159-
IfcEntityList::ptr getLayerAssignments(Ifc4::IfcRepresentationItem* item) {
160-
return item->LayerAssignment()->generalize();
161-
}
162-
163154
template <typename Schema>
164155
static std::map<std::string, IfcUtil::IfcBaseEntity*> get_layers_impl(typename Schema::IfcProduct* prod) {
165156
std::map<std::string, IfcUtil::IfcBaseEntity*> layers;
@@ -172,14 +163,6 @@ namespace {
172163
layers[(*jt)->Name()] = *jt;
173164
}
174165
}
175-
176-
typename Schema::IfcRepresentationItem::list::ptr items = r->as<typename Schema::IfcRepresentationItem>();
177-
for (typename Schema::IfcRepresentationItem::list::it it = items->begin(); it != items->end(); ++it) {
178-
typename Schema::IfcPresentationLayerAssignment::list::ptr a = getLayerAssignments(*it)->template as<typename Schema::IfcPresentationLayerAssignment>();
179-
for (typename Schema::IfcPresentationLayerAssignment::list::it jt = a->begin(); jt != a->end(); ++jt) {
180-
layers[(*jt)->Name()] = *jt;
181-
}
182-
}
183166
}
184167
return layers;
185168
}

src/ifcparse/IfcEntityList.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class IFC_PARSE_API IfcEntityList {
4040
it end();
4141
IfcUtil::IfcBaseClass* operator[] (int i);
4242
unsigned int size() const;
43+
void reserve(unsigned capacity);
4344
bool contains(IfcUtil::IfcBaseClass*) const;
4445
template <class U>
4546
typename U::list::ptr as() {

src/ifcparse/IfcFile.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ class IFC_PARSE_API IfcFile {
4141
typedef boost::unordered_map<unsigned int, IfcUtil::IfcBaseClass*> entity_by_id_t;
4242
typedef std::map<std::string, IfcUtil::IfcBaseClass*> entity_by_guid_t;
4343
typedef std::map<unsigned int, std::vector<unsigned int> > entities_by_ref_t;
44+
typedef std::map<unsigned int, IfcEntityList::ptr> ref_map_t;
4445
typedef entity_by_id_t::const_iterator const_iterator;
4546

4647
class type_iterator : private entities_by_type_t::const_iterator {
@@ -86,6 +87,7 @@ class IFC_PARSE_API IfcFile {
8687
entities_by_type_t bytype;
8788
entities_by_type_t bytype_excl;
8889
entities_by_ref_t byref;
90+
ref_map_t by_ref_cached_;
8991
entity_by_guid_t byguid;
9092
entity_entity_map_t entity_file_map;
9193

@@ -181,6 +183,10 @@ class IFC_PARSE_API IfcFile {
181183

182184
IfcEntityList::ptr getInverse(int instance_id, const IfcParse::declaration* type, int attribute_index);
183185

186+
/// Marks entity as modified so that potential cache for it is invalidated.
187+
/// @todo Currently the whole cache is invalidated. Implement more fine-grained invalidation.
188+
void mark_entity_as_modified(int id);
189+
184190
unsigned int FreshId() { return ++MaxId; }
185191

186192
IfcUtil::IfcBaseClass* addEntity(IfcUtil::IfcBaseClass* entity);

src/ifcparse/IfcParse.cpp

Lines changed: 25 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1257,7 +1257,9 @@ void IfcEntityInstanceData::setArgument(unsigned int i, Argument* a, IfcUtil::Ar
12571257
if (this->file) {
12581258
register_inverse_visitor visitor(*this->file, *this);
12591259
apply_individual_instance_visitor(copy).apply(visitor);
1260-
}
1260+
1261+
this->file->mark_entity_as_modified(id_);
1262+
}
12611263

12621264
attributes_[i] = copy;
12631265
}
@@ -1504,6 +1506,11 @@ IfcEntityList::ptr IfcFile::traverse(IfcUtil::IfcBaseClass* instance, int max_le
15041506
return IfcParse::traverse(instance, max_level);
15051507
}
15061508

1509+
void IfcFile::mark_entity_as_modified(int /*id*/)
1510+
{
1511+
by_ref_cached_.clear();
1512+
}
1513+
15071514
void IfcFile::addEntities(IfcEntityList::ptr es) {
15081515
for( IfcEntityList::it i = es->begin(); i != es->end(); ++ i ) {
15091516
addEntity(*i);
@@ -1868,17 +1875,25 @@ IfcEntityList::ptr IfcFile::instances_by_type(const std::string& t) {
18681875

18691876
IfcEntityList::ptr IfcFile::instances_by_reference(int t) {
18701877
entities_by_ref_t::const_iterator it = byref.find(t);
1871-
IfcEntityList::ptr return_value;
1878+
IfcEntityList::ptr ret;
18721879
if (it != byref.end()) {
1873-
const std::vector<unsigned>& ids = it->second;
1874-
for (std::vector<unsigned>::const_iterator jt = ids.begin(); jt != ids.end(); ++jt) {
1875-
if (!return_value) {
1876-
return_value.reset(new IfcEntityList);
1877-
}
1878-
return_value->push(instance_by_id(*jt));
1879-
}
1880+
ref_map_t::const_iterator cached_it = by_ref_cached_.find(t);
1881+
if (cached_it != by_ref_cached_.end()) {
1882+
ret = cached_it->second;
1883+
}
1884+
else {
1885+
if (it->second.size()) {
1886+
ret.reset(new IfcEntityList);
1887+
ret->reserve((unsigned)it->second.size());
1888+
const std::vector<unsigned>& ids = it->second;
1889+
for (std::vector<unsigned>::const_iterator jt = ids.begin(); jt != ids.end(); ++jt) {
1890+
ret->push(instance_by_id(*jt));
1891+
}
1892+
}
1893+
by_ref_cached_[t] = ret;
1894+
}
18801895
}
1881-
return return_value;
1896+
return ret;
18821897
}
18831898

18841899
IfcUtil::IfcBaseClass* IfcFile::instance_by_id(int id) {

src/ifcparse/IfcUtil.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ void IfcEntityList::push(const IfcEntityList::ptr& l) {
4242
}
4343
}
4444
unsigned int IfcEntityList::size() const { return (unsigned int) ls.size(); }
45+
void IfcEntityList::reserve(unsigned capacity) { ls.reserve((size_t)capacity); }
4546
IfcEntityList::it IfcEntityList::begin() { return ls.begin(); }
4647
IfcEntityList::it IfcEntityList::end() { return ls.end(); }
4748
IfcUtil::IfcBaseClass* IfcEntityList::operator[] (int i) {

0 commit comments

Comments
 (0)