Fixed bug where IFC models with multiple IFCSite only loaded 1 site instead of the complete model

pull/1302/head
Leo Terziman 2017-06-01 09:47:50 +02:00
parent ea4dbb9e46
commit ca5ac0b532
1 changed files with 40 additions and 17 deletions

View File

@ -882,6 +882,7 @@ void ProcessSpatialStructures(ConversionData& conv)
}
}
std::vector<aiNode*> nodes;
for(const STEP::LazyObject* lz : *range) {
const IfcSpatialStructureElement* const prod = lz->ToPtr<IfcSpatialStructureElement>();
@ -890,20 +891,19 @@ void ProcessSpatialStructures(ConversionData& conv)
}
IFCImporter::LogDebug("looking at spatial structure `" + (prod->Name ? prod->Name.Get() : "unnamed") + "`" + (prod->ObjectType? " which is of type " + prod->ObjectType.Get():""));
// the primary site is referenced by an IFCRELAGGREGATES element which assigns it to the IFCPRODUCT
// the primary sites are referenced by an IFCRELAGGREGATES element which assigns them to the IFCPRODUCT
const STEP::DB::RefMap& refs = conv.db.GetRefs();
STEP::DB::RefMapRange range = refs.equal_range(conv.proj.GetID());
for(;range.first != range.second; ++range.first) {
if(const IfcRelAggregates* const aggr = conv.db.GetObject((*range.first).second)->ToPtr<IfcRelAggregates>()) {
STEP::DB::RefMapRange ref_range = refs.equal_range(conv.proj.GetID());
for(; ref_range.first != ref_range.second; ++ref_range.first) {
if(const IfcRelAggregates* const aggr = conv.db.GetObject((*ref_range.first).second)->ToPtr<IfcRelAggregates>()) {
for(const IfcObjectDefinition& def : aggr->RelatedObjects) {
// comparing pointer values is not sufficient, we would need to cast them to the same type first
// as there is multiple inheritance in the game.
if (def.GetID() == prod->GetID()) {
IFCImporter::LogDebug("selecting this spatial structure as root structure");
// got it, this is the primary site.
conv.out->mRootNode = ProcessSpatialStructure(NULL,*prod,conv,NULL);
return;
// got it, this is one primary site.
nodes.push_back(ProcessSpatialStructure(NULL, *prod, conv, NULL));
}
}
@ -911,19 +911,42 @@ void ProcessSpatialStructures(ConversionData& conv)
}
}
size_t nb_nodes = nodes.size();
IFCImporter::LogWarn("failed to determine primary site element, taking the first IfcSite");
for(const STEP::LazyObject* lz : *range) {
const IfcSpatialStructureElement* const prod = lz->ToPtr<IfcSpatialStructureElement>();
if(!prod) {
continue;
}
if (nb_nodes == 0) {
IFCImporter::LogWarn("failed to determine primary site element, taking all the IfcSite");
for (const STEP::LazyObject* lz : *range) {
const IfcSpatialStructureElement* const prod = lz->ToPtr<IfcSpatialStructureElement>();
if (!prod) {
continue;
}
conv.out->mRootNode = ProcessSpatialStructure(NULL,*prod,conv,NULL);
return;
}
nodes.push_back(ProcessSpatialStructure(NULL, *prod, conv, NULL));
}
IFCImporter::ThrowException("failed to determine primary site element");
nb_nodes = nodes.size();
}
if (nb_nodes == 1) {
conv.out->mRootNode = nodes[0];
}
else if (nb_nodes > 1) {
conv.out->mRootNode = new aiNode("Root");
conv.out->mRootNode->mParent = NULL;
conv.out->mRootNode->mNumChildren = static_cast<unsigned int>(nb_nodes);
conv.out->mRootNode->mChildren = new aiNode*[conv.out->mRootNode->mNumChildren];
for (size_t i = 0; i < nb_nodes; ++i) {
aiNode* node = nodes[i];
node->mParent = conv.out->mRootNode;
conv.out->mRootNode->mChildren[i] = node;
}
}
else {
IFCImporter::ThrowException("failed to determine primary site element");
}
}
// ------------------------------------------------------------------------------------------------