# IFC: track references only for the types for which we actually need reverse indices. On average, this results in a 10% reduction in memory usage and a 5% speed improvement.

git-svn-id: https://assimp.svn.sourceforge.net/svnroot/assimp/trunk@1014 67173fc5-114c-0410-ac8e-9d2fd5bffc1f
pull/1/head
aramis_acg 2011-05-30 15:38:48 +00:00
parent af8533a0bf
commit bf7b1d3514
4 changed files with 50 additions and 14 deletions

View File

@ -416,8 +416,13 @@ void IFCImporter::InternReadFile( const std::string& pFile,
"ifcsite", "ifcbuilding", "ifcproject" "ifcsite", "ifcbuilding", "ifcproject"
}; };
// tell the reader for which types we need to simulate STEPs reverse indices
static const char* const inverse_indices_to_track[] = {
"ifcrelcontainedinspatialstructure", "ifcrelaggregates", "ifcrelvoidselement", "ifcstyleditem"
};
// feed the IFC schema into the reader and pre-parse all lines // feed the IFC schema into the reader and pre-parse all lines
STEP::ReadFile(*db, schema, types_to_track); STEP::ReadFile(*db, schema, types_to_track, inverse_indices_to_track);
const STEP::LazyObject* proj = db->GetObject("ifcproject"); const STEP::LazyObject* proj = db->GetObject("ifcproject");
if (!proj) { if (!proj) {
@ -1901,6 +1906,7 @@ void ProcessExtrudedAreaSolid(const IFC::IfcExtrudedAreaSolid& solid, TempMesh&
// add connection geometry to close the 'holes' for the openings // add connection geometry to close the 'holes' for the openings
if(conv.apply_openings) { if(conv.apply_openings) {
//result.infacing.resize(result.verts.size()+);
BOOST_FOREACH(const TempOpening& t,*conv.apply_openings) { BOOST_FOREACH(const TempOpening& t,*conv.apply_openings) {
const std::vector<aiVector3D>& in = t.profileMesh->verts; const std::vector<aiVector3D>& in = t.profileMesh->verts;
std::vector<aiVector3D>& out = result.verts; std::vector<aiVector3D>& out = result.verts;

View File

@ -371,6 +371,8 @@ namespace STEP {
ConvertObjectProc func; ConvertObjectProc func;
}; };
typedef std::map<std::string,ConvertObjectProc> ConverterMap;
public: public:
template <size_t N> template <size_t N>
@ -383,7 +385,7 @@ namespace STEP {
public: public:
ConvertObjectProc GetConverterProc(const std::string& name) const { ConvertObjectProc GetConverterProc(const std::string& name) const {
std::map<std::string,ConvertObjectProc>::const_iterator it = converters.find(name); ConverterMap::const_iterator it = converters.find(name);
return it == converters.end() ? NULL : (*it).second; return it == converters.end() ? NULL : (*it).second;
} }
@ -404,7 +406,7 @@ namespace STEP {
private: private:
std::map<std::string,ConvertObjectProc> converters; ConverterMap converters;
}; };
} }
@ -804,7 +806,11 @@ namespace STEP {
class DB class DB
{ {
friend DB* ReadFileHeader(boost::shared_ptr<IOStream> stream); friend DB* ReadFileHeader(boost::shared_ptr<IOStream> stream);
friend void ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme,const char* const* arr, size_t len); friend void ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme,
const char* const* types_to_track, size_t len,
const char* const* inverse_indices_to_track, size_t len2
);
friend class LazyObject; friend class LazyObject;
public: public:
@ -820,6 +826,10 @@ namespace STEP {
typedef std::step_unordered_multimap<uint64_t, uint64_t > RefMap; typedef std::step_unordered_multimap<uint64_t, uint64_t > RefMap;
typedef std::pair<RefMap::const_iterator,RefMap::const_iterator> RefMapRange; typedef std::pair<RefMap::const_iterator,RefMap::const_iterator> RefMapRange;
// list of types for which to keep inverse indices for all references
// the respective objects keep.
typedef std::set<std::string> InverseWhitelist;
private: private:
DB(boost::shared_ptr<StreamReaderLE> reader) DB(boost::shared_ptr<StreamReaderLE> reader)
@ -859,6 +869,11 @@ namespace STEP {
} }
bool KeepInverseIndicesForType(const std::string& type) const {
return inv_whitelist.find(type) != inv_whitelist.end();
}
// get the yet unevaluated object record with a given id // get the yet unevaluated object record with a given id
const LazyObject* GetObject(uint64_t id) const { const LazyObject* GetObject(uint64_t id) const {
const ObjectMap::const_iterator it = objects.find(id); const ObjectMap::const_iterator it = objects.find(id);
@ -937,6 +952,12 @@ namespace STEP {
} }
} }
void SetInverseIndicesToTrack( const char* const* types, size_t N ) {
for(size_t i = 0; i < N;++i) {
inv_whitelist.insert(types[i]);
}
}
HeaderInfo& GetHeader() { HeaderInfo& GetHeader() {
return header; return header;
} }
@ -945,12 +966,15 @@ namespace STEP {
refs.insert(std::make_pair(who,by_whom)); refs.insert(std::make_pair(who,by_whom));
} }
private: private:
HeaderInfo header; HeaderInfo header;
ObjectMap objects; ObjectMap objects;
ObjectMapByType objects_bytype; ObjectMapByType objects_bytype;
RefMap refs; RefMap refs;
InverseWhitelist inv_whitelist;
boost::shared_ptr<StreamReaderLE> reader; boost::shared_ptr<StreamReaderLE> reader;
LineSplitter splitter; LineSplitter splitter;

View File

@ -161,10 +161,13 @@ STEP::DB* STEP::ReadFileHeader(boost::shared_ptr<IOStream> stream)
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme,const char* const* arr, size_t len) void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme,
const char* const* types_to_track, size_t len,
const char* const* inverse_indices_to_track, size_t len2)
{ {
db.SetSchema(scheme); db.SetSchema(scheme);
db.SetTypesToTrack(arr,len); db.SetTypesToTrack(types_to_track,len);
db.SetInverseIndicesToTrack(inverse_indices_to_track,len2);
const DB::ObjectMap& map = db.GetObjects(); const DB::ObjectMap& map = db.GetObjects();
LineSplitter& splitter = db.GetSplitter(); LineSplitter& splitter = db.GetSplitter();
@ -228,7 +231,8 @@ void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme,const char* c
} }
if ( !DefaultLogger::isNullLogger() ){ if ( !DefaultLogger::isNullLogger() ){
DefaultLogger::get()->debug((Formatter::format(),"STEP: got ",map.size()," object records")); DefaultLogger::get()->debug((Formatter::format(),"STEP: got ",map.size()," object records with ",
db.GetRefs().size()," inverse index entries"));
} }
} }
@ -402,10 +406,12 @@ STEP::LazyObject::LazyObject(DB& db, uint64_t id,uint64_t line,const std::string
// find any external references and store them in the database. // find any external references and store them in the database.
// this helps us emulate STEPs INVERSE fields. // this helps us emulate STEPs INVERSE fields.
for (size_t i = 0; i < conv_args->GetSize(); ++i) { if (db.KeepInverseIndicesForType(type)) {
const EXPRESS::DataType* t = conv_args->operator [](i); for (size_t i = 0; i < conv_args->GetSize(); ++i) {
if (const EXPRESS::ENTITY* e = t->ToPtr<EXPRESS::ENTITY>()) { const EXPRESS::DataType* t = conv_args->operator [](i);
db.MarkRef(*e,id); if (const EXPRESS::ENTITY* e = t->ToPtr<EXPRESS::ENTITY>()) {
db.MarkRef(*e,id);
}
} }
} }
} }

View File

@ -56,9 +56,9 @@ namespace STEP {
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// 2) read the actual file contents using a user-supplied set of // 2) read the actual file contents using a user-supplied set of
// conversion functions to interpret the data. // conversion functions to interpret the data.
void ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme, const char* const* arr, size_t len); void ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme, const char* const* types_to_track, size_t len, const char* const* inverse_indices_to_track, size_t len2);
template <size_t N> inline void ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme, const char* const (&arr)[N]) { template <size_t N, size_t N2> inline void ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme, const char* const (&arr)[N], const char* const (&arr2)[N2]) {
return ReadFile(db,scheme,arr,N); return ReadFile(db,scheme,arr,N,arr2,N2);
} }