Fix [#26037] Import Collada crashes Blender
authorNathan Letwory <nathan@letworyinteractive.com>
Wed, 9 Mar 2011 01:13:28 +0000 (01:13 +0000)
committerNathan Letwory <nathan@letworyinteractive.com>
Wed, 9 Mar 2011 01:13:28 +0000 (01:13 +0000)
Submitted by David Roy

Multiple nodes can reference the same geometry, and specify the same materials. This lead
to the import code overwriting material mappings of faces in a destructive way. Instead of
just writing the material bindings always we now keep book of what geometry+material mapping
we've already handled.

source/blender/collada/MeshImporter.cpp
source/blender/collada/MeshImporter.h

index 86dc1a44671937117547869d4242c36eab621a44..b6576858c51ab7dd8c1cea0757bf0f01181f7abf 100644 (file)
@@ -803,6 +803,18 @@ MTFace *MeshImporter::assign_material_to_geom(COLLADAFW::MaterialBinding cmateri
                return NULL;
        }
        
+       // different nodes can point to same geometry, but still also specify the same materials
+       // again. Make sure we don't overwrite them on the next occurrences, so keep list of
+       // what we already have handled.
+       std::multimap<COLLADAFW::UniqueId, COLLADAFW::UniqueId>::iterator it;
+       it=materials_mapped_to_geom.find(*geom_uid);
+       while(it!=materials_mapped_to_geom.end()) {
+               if(it->second == ma_uid) return NULL; // do nothing if already found
+               it++;
+       }
+       // first time we get geom_uid, ma_uid pair. Save for later check.
+       materials_mapped_to_geom.insert(std::pair<COLLADAFW::UniqueId, COLLADAFW::UniqueId>(*geom_uid, ma_uid));
+       
        Material *ma = uid_material_map[ma_uid];
        assign_material(ob, ma, ob->totcol + 1);
        
index 1a9f698a7ce0b36529421e0a31380472076d3c75..20fdb0dcc6e2ce35c07b7e4b86335deff7136300 100644 (file)
@@ -91,6 +91,7 @@ private:
        };
        typedef std::map<COLLADAFW::MaterialId, std::vector<Primitive> > MaterialIdPrimitiveArrayMap;
        std::map<COLLADAFW::UniqueId, MaterialIdPrimitiveArrayMap> geom_uid_mat_mapping_map; // crazy name!
+       std::multimap<COLLADAFW::UniqueId, COLLADAFW::UniqueId> materials_mapped_to_geom; //< materials that have already been mapped to a geometry. A pair of geom uid and mat uid, one geometry can have several materials
        
 
        void set_face_indices(MFace *mface, unsigned int *indices, bool quad);