# 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"
};
// 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
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");
if (!proj) {
@ -1901,6 +1906,7 @@ void ProcessExtrudedAreaSolid(const IFC::IfcExtrudedAreaSolid& solid, TempMesh&
// add connection geometry to close the 'holes' for the openings
if(conv.apply_openings) {
//result.infacing.resize(result.verts.size()+);
BOOST_FOREACH(const TempOpening& t,*conv.apply_openings) {
const std::vector<aiVector3D>& in = t.profileMesh->verts;
std::vector<aiVector3D>& out = result.verts;

View File

@ -371,6 +371,8 @@ namespace STEP {
ConvertObjectProc func;
};
typedef std::map<std::string,ConvertObjectProc> ConverterMap;
public:
template <size_t N>
@ -383,7 +385,7 @@ namespace STEP {
public:
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;
}
@ -404,7 +406,7 @@ namespace STEP {
private:
std::map<std::string,ConvertObjectProc> converters;
ConverterMap converters;
};
}
@ -804,7 +806,11 @@ namespace STEP {
class DB
{
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;
public:
@ -820,6 +826,10 @@ namespace STEP {
typedef std::step_unordered_multimap<uint64_t, uint64_t > RefMap;
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:
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
const LazyObject* GetObject(uint64_t id) const {
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() {
return header;
}
@ -945,12 +966,15 @@ namespace STEP {
refs.insert(std::make_pair(who,by_whom));
}
private:
HeaderInfo header;
ObjectMap objects;
ObjectMapByType objects_bytype;
RefMap refs;
InverseWhitelist inv_whitelist;
boost::shared_ptr<StreamReaderLE> reader;
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.SetTypesToTrack(arr,len);
db.SetTypesToTrack(types_to_track,len);
db.SetInverseIndicesToTrack(inverse_indices_to_track,len2);
const DB::ObjectMap& map = db.GetObjects();
LineSplitter& splitter = db.GetSplitter();
@ -228,7 +231,8 @@ void STEP::ReadFile(DB& db,const EXPRESS::ConversionSchema& scheme,const char* c
}
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,6 +406,7 @@ STEP::LazyObject::LazyObject(DB& db, uint64_t id,uint64_t line,const std::string
// find any external references and store them in the database.
// this helps us emulate STEPs INVERSE fields.
if (db.KeepInverseIndicesForType(type)) {
for (size_t i = 0; i < conv_args->GetSize(); ++i) {
const EXPRESS::DataType* t = conv_args->operator [](i);
if (const EXPRESS::ENTITY* e = t->ToPtr<EXPRESS::ENTITY>()) {
@ -409,6 +414,7 @@ STEP::LazyObject::LazyObject(DB& db, uint64_t id,uint64_t line,const std::string
}
}
}
}
// ------------------------------------------------------------------------------------------------
STEP::LazyObject::~LazyObject()

View File

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