Collada: Added support for ngon export/import and added triangulate option to export
authorGaia Clary <gaia.clary@machinimatrix.org>
Sat, 2 Mar 2013 15:58:13 +0000 (15:58 +0000)
committerGaia Clary <gaia.clary@machinimatrix.org>
Sat, 2 Mar 2013 15:58:13 +0000 (15:58 +0000)
15 files changed:
release/scripts/presets/operator/wm.collada_export/second_life_rigged.py
release/scripts/presets/operator/wm.collada_export/second_life_static.py
source/blender/collada/CMakeLists.txt
source/blender/collada/ControllerExporter.cpp
source/blender/collada/DocumentImporter.cpp
source/blender/collada/ExportSettings.h
source/blender/collada/GeometryExporter.cpp
source/blender/collada/GeometryExporter.h
source/blender/collada/MeshImporter.cpp
source/blender/collada/MeshImporter.h
source/blender/collada/collada.cpp
source/blender/collada/collada.h
source/blender/collada/collada_utils.cpp
source/blender/collada/collada_utils.h
source/blender/editors/io/io_collada.c

index 40c3706..717e044 100644 (file)
@@ -12,7 +12,7 @@ op.deform_bones_only = True
 op.active_uv_only = True
 op.include_uv_textures = True
 op.use_texture_copies = True
-op.use_ngons = False
+op.triangulate = True
 op.use_object_instantiation = False
 op.sort_by_name = True
 op.second_life = True
index 2e8265c..9518fe5 100644 (file)
@@ -12,7 +12,7 @@ op.deform_bones_only = False
 op.active_uv_only = True
 op.include_uv_textures = True
 op.use_texture_copies = True
-op.use_ngons = False
+op.triangulate = True
 op.use_object_instantiation = False
 op.sort_by_name = True
 op.second_life = False
index 326ca2b..8747d29 100644 (file)
@@ -38,7 +38,7 @@ set(INC
        ../../../intern/guardedalloc
        ../ikplugin
        ../../../intern/iksolver/extern
-       
+       ../bmesh
 )
 
 set(INC_SYS
index 39ed033..6b367b9 100644 (file)
@@ -201,13 +201,12 @@ void ControllerExporter::export_skin_controller(Object *ob, Object *ob_arm)
        bool use_instantiation = this->export_settings->use_object_instantiation;
        Mesh *me;
 
-       if (this->export_settings->apply_modifiers) 
-               me = bc_to_mesh_apply_modifiers(scene, ob, this->export_settings->export_mesh_type);
-       else 
-               me = (Mesh *)ob->data;
+       me = bc_get_mesh_copy(scene,
+                               ob,
+                               this->export_settings->export_mesh_type,
+                               this->export_settings->apply_modifiers,
+                               this->export_settings->triangulate);
        
-       BKE_mesh_tessface_ensure(me);
-
        if (!me->dvert) return;
 
        std::string controller_name = id_name(ob_arm);
@@ -292,10 +291,8 @@ void ControllerExporter::export_skin_controller(Object *ob, Object *ob_arm)
        add_joints_element(&ob->defbase, joints_source_id, inv_bind_mat_source_id);
        add_vertex_weights_element(weights_source_id, joints_source_id, vcounts, joints);
 
-       if (this->export_settings->apply_modifiers)
-       {
-               BKE_libblock_free_us(&(G.main->mesh), me);
-       }
+       BKE_libblock_free_us(&(G.main->mesh), me);
+
        closeSkin();
        closeController();
 }
@@ -305,13 +302,11 @@ void ControllerExporter::export_morph_controller(Object *ob, Key *key)
        bool use_instantiation = this->export_settings->use_object_instantiation;
        Mesh *me;
 
-       if (this->export_settings->apply_modifiers) {
-               me = bc_to_mesh_apply_modifiers(scene, ob, this->export_settings->export_mesh_type);
-       } 
-       else {
-               me = (Mesh *)ob->data;
-       }
-       BKE_mesh_tessface_ensure(me);
+       me = bc_get_mesh_copy(scene,
+                               ob,
+                               this->export_settings->export_mesh_type,
+                               this->export_settings->apply_modifiers,
+                               this->export_settings->triangulate);
 
        std::string controller_name = id_name(ob) + "-morph";
        std::string controller_id = get_controller_id(key, ob);
@@ -332,10 +327,8 @@ void ControllerExporter::export_morph_controller(Object *ob, Key *key)
                                         COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, morph_weights_id)));
        targets.add();
 
-       if (this->export_settings->apply_modifiers)
-       {
-               BKE_libblock_free_us(&(G.main->mesh), me);
-       }
+       BKE_libblock_free_us(&(G.main->mesh), me);
+
 
        //support for animations
        //can also try the base element and param alternative
index b52a33b..49db6f0 100644 (file)
@@ -157,7 +157,8 @@ bool DocumentImporter::import()
        
        delete ehandler;
 
-       mesh_importer.bmeshConversion();
+       //XXX No longer needed (geometries are now created as bmesh)
+       //mesh_importer.bmeshConversion();
 
        return true;
 }
index 52a8adb..ec71fb2 100644 (file)
@@ -45,7 +45,7 @@ public:
        bool include_material_textures;
        bool use_texture_copies;
 
-       bool use_ngons;
+       bool triangulate;
        bool use_object_instantiation;
        bool sort_by_name;
        bool second_life;
index 8c86728..bb177cc 100644 (file)
@@ -57,7 +57,6 @@ GeometryExporter::GeometryExporter(COLLADASW::StreamWriter *sw, const ExportSett
 {
 }
 
-
 void GeometryExporter::exportGeom(Scene *sce)
 {
        openLibrary();
@@ -77,15 +76,12 @@ void GeometryExporter::operator()(Object *ob)
 #endif
 
        bool use_instantiation = this->export_settings->use_object_instantiation;
-       bool use_ngons         = this->export_settings->use_ngons;
-       Mesh *me;
-       if (this->export_settings->apply_modifiers) {
-               me = bc_to_mesh_apply_modifiers(mScene, ob, this->export_settings->export_mesh_type);
-       }
-       else {
-               me = (Mesh *)ob->data;
-       }
-       BKE_mesh_tessface_ensure(me);
+       bool triangulate       = this->export_settings->triangulate;
+       Mesh *me = bc_get_mesh_copy( mScene, 
+                                       ob,
+                                       this->export_settings->export_mesh_type,
+                                       this->export_settings->apply_modifiers,
+                                       this->export_settings->triangulate);
 
        std::string geom_id = get_geometry_id(ob, use_instantiation);
        std::vector<Normal> nor;
@@ -118,12 +114,13 @@ void GeometryExporter::operator()(Object *ob)
        bool has_uvs = (bool)CustomData_has_layer(&me->fdata, CD_MTFACE);
        
        // writes <source> for uv coords if mesh has uv coords
-       if (has_uvs)
+       if (has_uvs) {
                createTexcoordsSource(geom_id, me);
+       }
 
-       if (has_color)
+       if (has_color) {
                createVertexColorSource(geom_id, me);
-
+       }
        // <vertices>
 
        COLLADASW::Vertices verts(mSW);
@@ -140,11 +137,11 @@ void GeometryExporter::operator()(Object *ob)
                // XXX slow
                if (ob->totcol) {
                        for (int a = 0; a < ob->totcol; a++) {
-                               createPolylist(a, use_ngons, has_uvs, has_color, ob, me, geom_id, norind);
+                               createPolylist(a, has_uvs, has_color, ob, me, geom_id, norind);
                        }
                }
                else {
-                       createPolylist(0, use_ngons, has_uvs, has_color, ob, me, geom_id, norind);
+                       createPolylist(0, has_uvs, has_color, ob, me, geom_id, norind);
                }
        }
        
@@ -156,10 +153,6 @@ void GeometryExporter::operator()(Object *ob)
 
        closeGeometry();
 
-       if (this->export_settings->apply_modifiers) {
-               BKE_libblock_free_us(&(G.main->mesh), me);
-       }
-
        if (this->export_settings->include_shapekeys) {
                Key * key = BKE_key_from_object(ob);
                if (key) {
@@ -168,16 +161,16 @@ void GeometryExporter::operator()(Object *ob)
                        kb = kb->next;
                        for (; kb; kb = kb->next) {
                                BKE_key_convert_to_mesh(kb, me);
-                               export_key_mesh(ob, me, kb, use_ngons);
+                               export_key_mesh(ob, me, kb);
                        }
                }
        }
-#if 0
-       dm->release(dm);
-#endif
+
+       BKE_libblock_free_us(&(G.main->mesh), me);
+
 }
 
-void GeometryExporter::export_key_mesh(Object *ob, Mesh *me, KeyBlock *kb, bool use_ngons)
+void GeometryExporter::export_key_mesh(Object *ob, Mesh *me, KeyBlock *kb)
 {
        std::string geom_id = get_geometry_id(ob, false) + "_morph_" + translate_id(kb->name);
        std::vector<Normal> nor;
@@ -208,11 +201,13 @@ void GeometryExporter::export_key_mesh(Object *ob, Mesh *me, KeyBlock *kb, bool
        bool has_uvs = (bool)CustomData_has_layer(&me->fdata, CD_MTFACE);
        
        // writes <source> for uv coords if mesh has uv coords
-       if (has_uvs)
+       if (has_uvs) {
                createTexcoordsSource(geom_id, me);
+       }
 
-       if (has_color)
+       if (has_color) {
                createVertexColorSource(geom_id, me);
+       }
 
        // <vertices>
 
@@ -228,11 +223,11 @@ void GeometryExporter::export_key_mesh(Object *ob, Mesh *me, KeyBlock *kb, bool
        // XXX slow             
        if (ob->totcol) {
                for (int a = 0; a < ob->totcol; a++) {
-                       createPolylist(a, use_ngons, has_uvs, has_color, ob, me, geom_id, norind);
+                       createPolylist(a, has_uvs, has_color, ob, me, geom_id, norind);
                }
        }
        else {
-               createPolylist(0, use_ngons, has_uvs, has_color, ob, me, geom_id, norind);
+               createPolylist(0, has_uvs, has_color, ob, me, geom_id, norind);
        }
        
        closeMesh();
@@ -297,9 +292,7 @@ void GeometryExporter::createLooseEdgeList(Object *ob,
 }
 
 // powerful because it handles both cases when there is material and when there's not
-// Call this function when ngons shall be exported unchanged
 void GeometryExporter::createPolylist(short material_index,
-                                                                         bool use_ngons,
                                       bool has_uvs,
                                       bool has_color,
                                       Object *ob,
@@ -308,18 +301,6 @@ void GeometryExporter::createPolylist(short material_index,
                                       std::vector<Face>& norind)
 {
 
-       if (!use_ngons) {
-               createTriangulatedPolylist(
-                               material_index,
-                               has_uvs,
-                               has_color,
-                               ob,
-                               me,
-                               geom_id,
-                               norind);
-               return;
-       }
-
        MPoly *mpolys = me->mpoly;
        MLoop *mloops = me->mloop;
        int totpolys  = me->totpoly;
@@ -426,127 +407,6 @@ void GeometryExporter::createPolylist(short material_index,
        polylist.finish();
 }
 
-// powerful because it handles both cases when there is material and when there's not
-// Call this function when ngons shall be exported as Tris or Quads
-void GeometryExporter::createTriangulatedPolylist(short material_index,
-                                      bool has_uvs,
-                                      bool has_color,
-                                      Object *ob,
-                                      Mesh *me,
-                                      std::string& geom_id,
-                                      std::vector<Face>& norind)
-{
-       MFace *mfaces = me->mface;
-       int totfaces = me->totface;
-
-       // <vcount>
-       int i;
-       int faces_in_polylist = 0;
-       std::vector<unsigned long> vcount_list;
-
-       // count faces with this material
-       for (i = 0; i < totfaces; i++) {
-               MFace *f = &mfaces[i];
-               
-               if (f->mat_nr == material_index) {
-                       faces_in_polylist++;
-                       if (f->v4 == 0) {
-                               vcount_list.push_back(3);
-                       }
-                       else {
-                               vcount_list.push_back(4);
-                       }
-               }
-       }
-
-       // no faces using this material
-       if (faces_in_polylist == 0) {
-               fprintf(stderr, "%s: material with index %d is not used.\n", id_name(ob).c_str(), material_index);
-               return;
-       }
-               
-       Material *ma = ob->totcol ? give_current_material(ob, material_index + 1) : NULL;
-       COLLADASW::Polylist polylist(mSW);
-               
-       // sets count attribute in <polylist>
-       polylist.setCount(faces_in_polylist);
-               
-       // sets material name
-       if (ma) {
-               std::string material_id = get_material_id(ma);
-               std::ostringstream ostr;
-               ostr << translate_id(material_id);
-               polylist.setMaterial(ostr.str());
-       }
-                       
-       COLLADASW::InputList &til = polylist.getInputList();
-               
-       // creates <input> in <polylist> for vertices 
-       COLLADASW::Input input1(COLLADASW::InputSemantic::VERTEX, getUrlBySemantics(geom_id, COLLADASW::InputSemantic::VERTEX), 0);
-               
-       // creates <input> in <polylist> for normals
-       COLLADASW::Input input2(COLLADASW::InputSemantic::NORMAL, getUrlBySemantics(geom_id, COLLADASW::InputSemantic::NORMAL), 1);
-               
-       til.push_back(input1);
-       til.push_back(input2);
-               
-       // if mesh has uv coords writes <input> for TEXCOORD
-       int num_layers = CustomData_number_of_layers(&me->fdata, CD_MTFACE);
-       int active_uv_index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE)-1;
-       for (i = 0; i < num_layers; i++) {
-               if (!this->export_settings->active_uv_only || i == active_uv_index) {
-
-                       // char *name = CustomData_get_layer_name(&me->fdata, CD_MTFACE, i);
-                       COLLADASW::Input input3(COLLADASW::InputSemantic::TEXCOORD,
-                                                                       makeUrl(makeTexcoordSourceId(geom_id, i)),
-                                                                       2, // offset always 2, this is only until we have optimized UV sets
-                                                                       i  // set number equals UV map index
-                                                                       );
-                       til.push_back(input3);
-               }
-       }
-
-       if (has_color) {
-               COLLADASW::Input input4(COLLADASW::InputSemantic::COLOR, getUrlBySemantics(geom_id, COLLADASW::InputSemantic::COLOR), has_uvs ? 3 : 2);
-               til.push_back(input4);
-       }
-               
-       // sets <vcount>
-       polylist.setVCountList(vcount_list);
-               
-       // performs the actual writing
-       polylist.prepareToAppendValues();
-       
-
-               
-       // <p>
-       int texindex = 0;
-       for (i = 0; i < totfaces; i++) {
-               MFace *f = &mfaces[i];
-
-               if (f->mat_nr == material_index) {
-
-                       unsigned int *v = &f->v1;
-                       unsigned int *n = &norind[i].v1;
-                       for (int j = 0; j < (f->v4 == 0 ? 3 : 4); j++) {
-                               polylist.appendValues(v[j]);
-                               polylist.appendValues(n[j]);
-
-                               if (has_uvs)
-                                       polylist.appendValues(texindex + j);
-
-                               if (has_color)
-                                       polylist.appendValues(texindex + j);
-                       }
-               }
-
-               texindex += 3;
-               if (f->v4 != 0)
-                       texindex++;
-       }
-               
-       polylist.finish();
-}
 
 // creates <source> for positions
 void GeometryExporter::createVertsSource(std::string geom_id, Mesh *me)
@@ -617,6 +477,7 @@ void GeometryExporter::createVertexColorSource(std::string geom_id, Mesh *me)
        source.finish();
 }
 
+
 std::string GeometryExporter::makeTexcoordSourceId(std::string& geom_id, int layer_index)
 {
        char suffix[20];
@@ -627,38 +488,21 @@ std::string GeometryExporter::makeTexcoordSourceId(std::string& geom_id, int lay
 //creates <source> for texcoords
 void GeometryExporter::createTexcoordsSource(std::string geom_id, Mesh *me)
 {
-#if 0
-       int totfaces = dm->getNumTessFaces(dm);
-       MFace *mfaces = dm->getTessFaceArray(dm);
-#endif
-       int totfaces = me->totface;
-       MFace *mfaces = me->mface;
-
-       int totuv = 0;
-       int i;
 
-       // count totuv
-       for (i = 0; i < totfaces; i++) {
-               MFace *f = &mfaces[i];
-               if (f->v4 == 0) {
-                       totuv += 3;
-               }
-               else {
-                       totuv += 4;
-               }
-       }
+       int totpoly   = me->totpoly;
+       int totuv     = me->totloop;
+       MPoly *mpolys = me->mpoly;
 
-       int num_layers = CustomData_number_of_layers(&me->fdata, CD_MTFACE);
+       int num_layers = CustomData_number_of_layers(&me->ldata, CD_MLOOPUV);
 
        // write <source> for each layer
        // each <source> will get id like meshName + "map-channel-1"
        int map_index = 0;
-       int active_uv_index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE)-1;
+       int active_uv_index = CustomData_get_active_layer_index(&me->ldata, CD_MLOOPUV);
        for (int a = 0; a < num_layers; a++) {
 
                if (!this->export_settings->active_uv_only || a == active_uv_index) {
-                       MTFace *tface = (MTFace *)CustomData_get_layer_n(&me->fdata, CD_MTFACE, a);
-                       // char *name = CustomData_get_layer_name(&me->fdata, CD_MTFACE, a);
+                       MLoopUV *mloops = (MLoopUV *)CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, a);
                        
                        COLLADASW::FloatSourceF source(mSW);
                        std::string layer_id = makeTexcoordSourceId(geom_id, map_index++);
@@ -673,12 +517,12 @@ void GeometryExporter::createTexcoordsSource(std::string geom_id, Mesh *me)
                        
                        source.prepareToAppendValues();
                        
-                       for (i = 0; i < totfaces; i++) {
-                               MFace *f = &mfaces[i];
-                               
-                               for (int j = 0; j < (f->v4 == 0 ? 3 : 4); j++) {
-                                       source.appendValues(tface[i].uv[j][0],
-                                                                               tface[i].uv[j][1]);
+                       for (int index = 0; index < totpoly; index++) {
+                               MPoly   *mpoly = mpolys+index;
+                               MLoopUV *mloop = mloops+mpoly->loopstart;
+                               for (int j = 0; j < mpoly->totloop; j++) {
+                                       source.appendValues(mloop[j].uv[0],
+                                                                               mloop[j].uv[1]);
                                }
                        }
                        
index ce1dc78..c880dfd 100644 (file)
@@ -75,16 +75,7 @@ public:
                                                     std::vector<Face>& norind);
 
        // powerful because it handles both cases when there is material and when there's not
-       void createTriangulatedPolylist(short material_index,
-                                               bool has_uvs,
-                                               bool has_color,
-                                               Object *ob,
-                                               Mesh   *me,
-                                               std::string& geom_id,
-                                               std::vector<Face>& norind);
-       
        void createPolylist(short material_index,
-                                               bool use_ngons,
                                                bool has_uvs,
                                                bool has_color,
                                                Object *ob,
@@ -101,6 +92,7 @@ public:
 
        //creates <source> for texcoords
        void createTexcoordsSource(std::string geom_id, Mesh *me);
+       void createTesselatedTexcoordsSource(std::string geom_id, Mesh *me);
 
        //creates <source> for normals
        void createNormalsSource(std::string geom_id, Mesh *me, std::vector<Normal>& nor);
@@ -113,7 +105,7 @@ public:
 
        COLLADASW::URI makeUrl(std::string id);
 
-       void export_key_mesh(Object *ob, Mesh *me, KeyBlock *kb, bool use_ngons);
+       void export_key_mesh(Object *ob, Mesh *me, KeyBlock *kb);
        
        /* int getTriCount(MFace *faces, int totface);*/
 private:
index 26915f3..6994456 100644 (file)
@@ -173,83 +173,30 @@ void UVDataWrapper::getUV(int uv_index, float *uv)
        }
 }
 
-void MeshImporter::set_face_indices(MFace *mface, unsigned int *indices, bool quad)
-{
-       mface->v1 = indices[0];
-       mface->v2 = indices[1];
-       mface->v3 = indices[2];
-       if (quad) mface->v4 = indices[3];
-       else mface->v4 = 0;
-#ifdef COLLADA_DEBUG
-       // fprintf(stderr, "%u, %u, %u\n", indices[0], indices[1], indices[2]);
-#endif
-}
-
-// not used anymore, test_index_face from blenkernel is better
-#if 0
-// change face indices order so that v4 is not 0
-void MeshImporter::rotate_face_indices(MFace *mface)
-{
-       mface->v4 = mface->v1;
-       mface->v1 = mface->v2;
-       mface->v2 = mface->v3;
-       mface->v3 = 0;
+MeshImporter::MeshImporter(UnitConverter *unitconv, ArmatureImporter *arm, Scene *sce) : unitconverter(unitconv), scene(sce), armature_importer(arm) {
 }
-#endif
 
-void MeshImporter::set_face_uv(MTFace *mtface, UVDataWrapper &uvs,
-                               COLLADAFW::IndexList& index_list, unsigned int *tris_indices)
+void MeshImporter::set_poly_indices(MPoly *mpoly, MLoop *mloop, int loop_index, unsigned int *indices, int loop_count)
 {
-       // per face vertex indices, this means for quad we have 4 indices, not 8
-       COLLADAFW::UIntValuesArray& indices = index_list.getIndices();
+       mpoly->loopstart = loop_index;
+       mpoly->totloop   = loop_count;
 
-       uvs.getUV(indices[tris_indices[0]], mtface->uv[0]);
-       uvs.getUV(indices[tris_indices[1]], mtface->uv[1]);
-       uvs.getUV(indices[tris_indices[2]], mtface->uv[2]);
+       for (int index=0; index < loop_count; index++) {
+               mloop->v = indices[index];
+               mloop++;
+       }
 }
 
-void MeshImporter::set_face_uv(MTFace *mtface, UVDataWrapper &uvs,
-                               COLLADAFW::IndexList& index_list, int index, bool quad)
+void MeshImporter::set_face_uv(MLoopUV *mloopuv, UVDataWrapper &uvs,
+                               int start_index, COLLADAFW::IndexList& index_list, int count)
 {
        // per face vertex indices, this means for quad we have 4 indices, not 8
        COLLADAFW::UIntValuesArray& indices = index_list.getIndices();
 
-       uvs.getUV(indices[index + 0], mtface->uv[0]);
-       uvs.getUV(indices[index + 1], mtface->uv[1]);
-       uvs.getUV(indices[index + 2], mtface->uv[2]);
-
-       if (quad) uvs.getUV(indices[index + 3], mtface->uv[3]);
-
-#ifdef COLLADA_DEBUG
-       if (quad) {
-               fprintf(stderr, "face uv:\n"
-                       "((%d, %d, %d, %d))\n"
-                       "((%.1f, %.1f), (%.1f, %.1f), (%.1f, %.1f), (%.1f, %.1f))\n",
-
-                       indices[index + 0],
-                       indices[index + 1],
-                       indices[index + 2],
-                       indices[index + 3],
-
-                       mtface->uv[0][0], mtface->uv[0][1],
-                       mtface->uv[1][0], mtface->uv[1][1],
-                       mtface->uv[2][0], mtface->uv[2][1],
-                       mtface->uv[3][0], mtface->uv[3][1]);
+       for (int index = 0; index < count; index++) {
+               int uv_index = indices[index+start_index];
+               uvs.getUV(uv_index, mloopuv[index].uv);
        }
-       else {
-               fprintf(stderr, "face uv:\n"
-                       "((%d, %d, %d))\n"
-                       "((%.1f, %.1f), (%.1f, %.1f), (%.1f, %.1f))\n",
-
-                       indices[index + 0],
-                       indices[index + 1],
-                       indices[index + 2],
-
-                       mtface->uv[0][0], mtface->uv[0][1],
-                       mtface->uv[1][0], mtface->uv[1][1],
-                       mtface->uv[2][0], mtface->uv[2][1]);
-       }
-#endif
 }
 
 #ifdef COLLADA_DEBUG
@@ -329,91 +276,6 @@ void MeshImporter::read_vertices(COLLADAFW::Mesh *mesh, Mesh *me)
        }
 }
 
-int MeshImporter::triangulate_poly(unsigned int *indices, int totvert, MVert *verts, std::vector<unsigned int>& tri)
-{
-       ListBase dispbase;
-       DispList *dl;
-       float *vert;
-       int i = 0;
-       
-       dispbase.first = dispbase.last = NULL;
-       
-       dl = (DispList *)MEM_callocN(sizeof(DispList), "poly disp");
-       dl->nr = totvert;
-       dl->type = DL_POLY;
-       dl->parts = 1;
-       dl->verts = vert = (float *)MEM_callocN(totvert * 3 * sizeof(float), "poly verts");
-       dl->index = (int *)MEM_callocN(sizeof(int) * 3 * totvert, "dl index");
-
-       BLI_addtail(&dispbase, dl);
-       
-       for (i = 0; i < totvert; i++) {
-               copy_v3_v3(vert, verts[indices[i]].co);
-               vert += 3;
-       }
-       
-       BKE_displist_fill(&dispbase, &dispbase, 0);
-
-       int tottri = 0;
-       dl = (DispList *)dispbase.first;
-
-       if (dl->type == DL_INDEX3) {
-               tottri = dl->parts;
-
-               int *index = dl->index;
-               for (i = 0; i < tottri; i++) {
-                       int t[3] = {*index, *(index + 1), *(index + 2)};
-
-                       std::sort(t, t + 3);
-
-                       tri.push_back(t[0]);
-                       tri.push_back(t[1]);
-                       tri.push_back(t[2]);
-
-                       index += 3;
-               }
-       }
-
-       BKE_displist_free(&dispbase);
-
-       return tottri;
-}
-
-int MeshImporter::count_new_tris(COLLADAFW::Mesh *mesh, Mesh *me)
-{
-       COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives();
-       unsigned int i;
-       int tottri = 0;
-       
-       for (i = 0; i < prim_arr.getCount(); i++) {
-               
-               COLLADAFW::MeshPrimitive *mp = prim_arr[i];
-               int type = mp->getPrimitiveType();
-               size_t prim_totface = mp->getFaceCount();
-               unsigned int *indices = mp->getPositionIndices().getData();
-               
-               if (type == COLLADAFW::MeshPrimitive::POLYLIST ||
-                   type == COLLADAFW::MeshPrimitive::POLYGONS)
-               {
-                       COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons *)mp;
-                       COLLADAFW::Polygons::VertexCountArray& vcounta = mpvc->getGroupedVerticesVertexCountArray();
-                       
-                       for (unsigned int j = 0; j < prim_totface; j++) {
-                               int vcount = vcounta[j];
-                               
-                               if (vcount > 4) {
-                                       std::vector<unsigned int> tri;
-                                       
-                                       // tottri += triangulate_poly(indices, vcount, me->mvert, tri) - 1; // XXX why - 1?!
-                                       tottri += triangulate_poly(indices, vcount, me->mvert, tri);
-                               }
-
-                               indices += vcount;
-                       }
-               }
-       }
-       return tottri;
-}
 
 // =====================================================================
 // condition 1: The Primitive has normals
@@ -471,10 +333,11 @@ bool MeshImporter::primitive_has_faces(COLLADAFW::MeshPrimitive *mp) {
 // hint: This is done because mesh->getFacesCount() does
 // count loose edges as extra faces, which is not what we want here.
 // =================================================================
-void MeshImporter::allocate_face_data(COLLADAFW::Mesh *mesh, Mesh *me, int new_tris)
+void MeshImporter::allocate_poly_data(COLLADAFW::Mesh *collada_mesh, Mesh *me)
 {
-       COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives();
-       int total_facecount = 0;
+       COLLADAFW::MeshPrimitiveArray& prim_arr = collada_mesh->getMeshPrimitives();
+       int total_poly_count = 0;
+       int total_loop_count = 0;
 
        // collect edge_count and face_count from all parts
        for (int i = 0; i < prim_arr.getCount(); i++) {
@@ -485,21 +348,77 @@ void MeshImporter::allocate_face_data(COLLADAFW::Mesh *mesh, Mesh *me, int new_t
                        case COLLADAFW::MeshPrimitive::TRIANGLE_FANS:
                        case COLLADAFW::MeshPrimitive::POLYLIST:
                        case COLLADAFW::MeshPrimitive::POLYGONS: {
-                               size_t prim_totface = mp->getFaceCount();
-                               total_facecount += prim_totface;
+
+                               COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons *)mp;
+                               size_t prim_poly_count    = mpvc->getFaceCount();
+
+                               size_t prim_loop_count    = 0;
+                               for(int index=0; index < prim_poly_count; index++) {
+                                       prim_loop_count += get_vertex_count(mpvc, index);
+                               }
+
+                               total_poly_count += prim_poly_count;
+                               total_loop_count += prim_loop_count;
                                break;
                        }
                        default: break;
                }
        }
 
-       // allocate space for faces
-       if (total_facecount > 0) {
-               me->totface = total_facecount + new_tris;
-               me->mface   = (MFace *)CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, me->totface);
+       // Add the data containers
+       if (total_poly_count > 0) {
+               me->totpoly = total_poly_count;
+               me->totloop = total_loop_count;
+               me->mpoly   = (MPoly *)CustomData_add_layer(&me->pdata, CD_MPOLY, CD_CALLOC, NULL, me->totpoly);
+               me->mloop   = (MLoop *)CustomData_add_layer(&me->ldata, CD_MLOOP, CD_CALLOC, NULL, me->totloop);
+
+               unsigned int totuvset = collada_mesh->getUVCoords().getInputInfosArray().getCount();
+               for (int i = 0; i < totuvset; i++) {
+                       if (collada_mesh->getUVCoords().getLength(i) == 0) {
+                               totuvset = 0;
+                               break;
+                       }
+               }
+
+               if (totuvset > 0) {
+                       for (int i = 0; i < totuvset; i++) {
+                               COLLADAFW::MeshVertexData::InputInfos *info = collada_mesh->getUVCoords().getInputInfosArray()[i];
+                               COLLADAFW::String &uvname = info->mName;
+                               int x = 0;
+                               // Allocate space for UV_data
+                               CustomData_add_layer_named(&me->pdata, CD_MTEXPOLY, CD_DEFAULT, NULL, me->totpoly, uvname.c_str());
+                               CustomData_add_layer_named(&me->ldata, CD_MLOOPUV, CD_DEFAULT, NULL, me->totloop, uvname.c_str());
+                       }
+                       // activate the first uv map
+                       me->mtpoly  = (MTexPoly *)CustomData_get_layer_n(&me->pdata, CD_MTEXPOLY, 0);
+                       me->mloopuv = (MLoopUV *) CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, 0);
+               }
        }
 }
 
+unsigned int MeshImporter::get_vertex_count(COLLADAFW::Polygons *mp, int index) {
+       int type = mp->getPrimitiveType();
+       int result;
+       switch (type) {
+               case COLLADAFW::MeshPrimitive::TRIANGLES:
+               case COLLADAFW::MeshPrimitive::TRIANGLE_FANS: {
+                       result = 3;
+                       break;
+               }
+               case COLLADAFW::MeshPrimitive::POLYLIST:
+               case COLLADAFW::MeshPrimitive::POLYGONS: {
+                       result = mp->getGroupedVerticesVertexCountArray()[index];
+                       break;
+               }
+               default: {
+                       result = -1;
+                       break;
+               }
+       }
+       return result;
+}
+
+
 unsigned int MeshImporter::get_loose_edge_count(COLLADAFW::Mesh *mesh) {
        COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives();
        int loose_edge_count = 0;
@@ -606,256 +525,118 @@ void MeshImporter::read_lines(COLLADAFW::Mesh *mesh, Mesh *me)
 //
 // TODO: import uv set names
 // ========================================================================
-void MeshImporter::read_faces(COLLADAFW::Mesh *mesh, Mesh *me, int new_tris) //TODO:: Refactor. Possibly replace by iterators
+void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me)
 {
        unsigned int i;
        
-       allocate_face_data(mesh, me, new_tris);
-       
-       // allocate UV Maps
-       unsigned int totuvset = mesh->getUVCoords().getInputInfosArray().getCount();
+       allocate_poly_data(collada_mesh, me);
 
-       for (i = 0; i < totuvset; i++) {
-               if (mesh->getUVCoords().getLength(i) == 0) {
-                       totuvset = 0;
-                       break;
-               }
-       }
-
-       for (i = 0; i < totuvset; i++) {
-               COLLADAFW::MeshVertexData::InputInfos *info = mesh->getUVCoords().getInputInfosArray()[i];
-               CustomData_add_layer_named(&me->fdata, CD_MTFACE, CD_CALLOC, NULL, me->totface, info->mName.c_str());
-               //this->set_layername_map[i] = CustomData_get_layer_name(&me->fdata, CD_MTFACE, i);
-       }
-
-       // activate the first uv map
-       if (totuvset) me->mtface = (MTFace *)CustomData_get_layer_n(&me->fdata, CD_MTFACE, 0);
-
-       UVDataWrapper uvs(mesh->getUVCoords());
-
-#ifdef COLLADA_DEBUG
-       // uvs.print();
-#endif
+       UVDataWrapper uvs(collada_mesh->getUVCoords());
 
-       MFace *mface = me->mface;
+       MPoly *mpoly = me->mpoly;
+       MLoop *mloop = me->mloop;
+       int loop_index = 0;
 
        MaterialIdPrimitiveArrayMap mat_prim_map;
 
-       int face_index = 0;
-
-       COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives();
-
-       COLLADAFW::MeshVertexData& nor = mesh->getNormals();
+       COLLADAFW::MeshPrimitiveArray& prim_arr = collada_mesh->getMeshPrimitives();
+       COLLADAFW::MeshVertexData& nor = collada_mesh->getNormals();
 
        for (i = 0; i < prim_arr.getCount(); i++) {
                
                COLLADAFW::MeshPrimitive *mp = prim_arr[i];
 
                // faces
-               size_t prim_totface = mp->getFaceCount();
-               unsigned int *indices = mp->getPositionIndices().getData();
-               unsigned int *nind    = mp->getNormalIndices().getData();
+               size_t prim_totpoly            = mp->getFaceCount();
+               unsigned int *position_indices = mp->getPositionIndices().getData();
+               unsigned int *normal_indices   = mp->getNormalIndices().getData();
 
                bool mp_has_normals = primitive_has_useable_normals(mp);
                bool mp_has_faces   = primitive_has_faces(mp);
 
-               int type = mp->getPrimitiveType();
-               int index = 0;
+               int collada_meshtype = mp->getPrimitiveType();
                
-               // since we cannot set mface->mat_nr here, we store a portion of me->mface in Primitive
-               Primitive prim = {mface, 0};
+               // since we cannot set mpoly->mat_nr here, we store a portion of me->mface in Primitive
+               Primitive prim = {mpoly, 0};
                COLLADAFW::IndexListArray& index_list_array = mp->getUVCoordIndicesArray();
 
-#ifdef COLLADA_DEBUG
-               /*
-                  fprintf(stderr, "Primitive %d:\n", i);
-                  for (unsigned int j = 0; j < totuvset; j++) {
-                   print_index_list(*index_list_array[j]);
-                  }
-                */
-#endif
-               
-               if (type == COLLADAFW::MeshPrimitive::TRIANGLES) {
-                       for (unsigned int j = 0; j < prim_totface; j++) {
-                               
-                               set_face_indices(mface, indices, false);
-                               indices += 3;
-
-#if 0
-                               for (unsigned int k = 0; k < totuvset; k++) {
-                                       if (!index_list_array.empty() && index_list_array[k]) {
-                                               // get mtface by face index and uv set index
-                                               MTFace *mtface = (MTFace *)CustomData_get_layer_n(&me->fdata, CD_MTFACE, k);
-                                               set_face_uv(&mtface[face_index], uvs, k, *index_list_array[k], index, false);
-                                       }
-                               }
-#else
-                               for (unsigned int k = 0; k < index_list_array.getCount(); k++) {
-                                       // get mtface by face index and uv set index
-                                       MTFace *mtface = (MTFace *)CustomData_get_layer_n(&me->fdata, CD_MTFACE, k);
-                                       set_face_uv(&mtface[face_index], uvs, *index_list_array[k], index, false);
-                               }
-#endif
-
-                               test_index_face(mface, &me->fdata, face_index, 3);
-
-                               if (mp_has_normals) {
-                                       if (!flat_face(nind, nor, 3))
-                                               mface->flag |= ME_SMOOTH;
-
-                                       nind += 3;
-                               }
-                               
-                               index += 3;
-                               mface++;
-                               face_index++;
-                               prim.totface++;
-                       }
-               }
-
                // If MeshPrimitive is TRIANGLE_FANS we split it into triangles
                // The first trifan vertex will be the first vertex in every triangle
-               if (type == COLLADAFW::MeshPrimitive::TRIANGLE_FANS) {
+               // XXX The proper function of TRIANGLE_FANS is not tested!!!
+               // XXX In particular the handling of the normal_indices looks very wrong to me
+               if (collada_meshtype == COLLADAFW::MeshPrimitive::TRIANGLE_FANS) {
                        unsigned grouped_vertex_count = mp->getGroupedVertexElementsCount();
                        for (unsigned int group_index = 0; group_index < grouped_vertex_count; group_index++) {
-                               unsigned int first_vertex = indices[0]; // Store first trifan vertex
-                               unsigned int first_normal = nind[0]; // Store first trifan vertex normal
+                               unsigned int first_vertex = position_indices[0]; // Store first trifan vertex
+                               unsigned int first_normal = normal_indices[0]; // Store first trifan vertex normal
                                unsigned int vertex_count = mp->getGroupedVerticesVertexCount(group_index);
 
                                for (unsigned int vertex_index = 0; vertex_index < vertex_count - 2; vertex_index++) {
                                        // For each triangle store indeces of its 3 vertices
-                                       unsigned int triangle_vertex_indices[3] = {first_vertex, indices[1], indices[2]};
-                                       set_face_indices(mface, triangle_vertex_indices, false);
-                                       test_index_face(mface, &me->fdata, face_index, 3);
+                                       unsigned int triangle_vertex_indices[3] = {first_vertex, position_indices[1], position_indices[2]};
+                                       set_poly_indices(mpoly, mloop, loop_index, triangle_vertex_indices, 3);
 
                                        if (mp_has_normals) {  // vertex normals, same inplementation as for the triangles
                                                // the same for vertces normals
-                                               unsigned int vertex_normal_indices[3] = {first_normal, nind[1], nind[2]};
-                                               if (!flat_face(vertex_normal_indices, nor, 3))
-                                                       mface->flag |= ME_SMOOTH;
-                                               nind++;
+                                               unsigned int vertex_normal_indices[3] = {first_normal, normal_indices[1], normal_indices[2]};
+                                               if (!is_flat_face(vertex_normal_indices, nor, 3))
+                                                       mpoly->flag |= ME_SMOOTH;
+                                               normal_indices++;
                                        }
                                
-                                       mface++;  // same inplementation as for the triangles
-                                       indices++;
-                                       face_index++;
-                                       prim.totface++;
+                                       mpoly++;
+                                       mloop += 3;
+                                       loop_index += 3;
+                                       prim.totpoly++;
+
                                }
 
                                // Moving cursor  to the next triangle fan.
                                if (mp_has_normals)
-                                       nind += 2;
+                                       normal_indices += 2;
 
-                               indices +=  2;
+                               position_indices +=  2;
                        }
                }
-               else if (type == COLLADAFW::MeshPrimitive::POLYLIST || type == COLLADAFW::MeshPrimitive::POLYGONS) {
-                       COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons *)mp;
-                       COLLADAFW::Polygons::VertexCountArray& vcounta = mpvc->getGroupedVerticesVertexCountArray();
 
-                       for (unsigned int j = 0; j < prim_totface; j++) {
+               if (collada_meshtype == COLLADAFW::MeshPrimitive::POLYLIST ||
+                       collada_meshtype == COLLADAFW::MeshPrimitive::POLYGONS ||
+                       collada_meshtype == COLLADAFW::MeshPrimitive::TRIANGLES) {
+                       COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons *)mp;
+                       for (unsigned int j = 0; j < prim_totpoly; j++) {
                                
-                               // face
-                               int vcount = vcounta[j];
-                               if (vcount == 3 || vcount == 4) {
-                                       
-                                       set_face_indices(mface, indices, vcount == 4);
-                                       
-                                       // set mtface for each uv set
-                                       // it is assumed that all primitives have equal number of UV sets
-
-#if 0
-                                       for (unsigned int k = 0; k < totuvset; k++) {
-                                               if (!index_list_array.empty() && index_list_array[k]) {
-                                                       // get mtface by face index and uv set index
-                                                       MTFace *mtface = (MTFace *)CustomData_get_layer_n(&me->fdata, CD_MTFACE, k);
-                                                       set_face_uv(&mtface[face_index], uvs, k, *index_list_array[k], index, mface->v4 != 0);
-                                               }
-                                       }
-#else
-                                       for (unsigned int k = 0; k < index_list_array.getCount(); k++) {
-                                               // get mtface by face index and uv set index
-                                               MTFace *mtface = (MTFace *)CustomData_get_layer_n(&me->fdata, CD_MTFACE, k);
-                                               set_face_uv(&mtface[face_index], uvs, *index_list_array[k], index, vcount == 4);
-                                       }
-#endif
+                               // Vertices in polygon:
+                               int vcount = get_vertex_count(mpvc, j);
+                               set_poly_indices(mpoly, mloop, loop_index, position_indices, vcount);
 
-                                       test_index_face(mface, &me->fdata, face_index, vcount);
 
-                                       if (mp_has_normals) {
-                                               if (!flat_face(nind, nor, vcount))
-                                                       mface->flag |= ME_SMOOTH;
+                               for (unsigned int l = 0; l < index_list_array.getCount(); l++) {
+                                       int uvset_index = index_list_array[l]->getSetIndex();
 
-                                               nind += vcount;
-                                       }
-                                       
-                                       mface++;
-                                       face_index++;
-                                       prim.totface++;
-                                       
-                               }
-                               else {
-                                       std::vector<unsigned int> tri;
-                                       
-                                       triangulate_poly(indices, vcount, me->mvert, tri);
-
-                                       for (unsigned int k = 0; k < tri.size() / 3; k++) {
-                                               int v = k * 3;
-                                               unsigned int uv_indices[3] = {
-                                                       index + tri[v],
-                                                       index + tri[v + 1],
-                                                       index + tri[v + 2]
-                                               };
-                                               unsigned int tri_indices[3] = {
-                                                       indices[tri[v]],
-                                                       indices[tri[v + 1]],
-                                                       indices[tri[v + 2]]
-                                               };
-
-                                               set_face_indices(mface, tri_indices, false);
-                                               
-#if 0
-                                               for (unsigned int l = 0; l < totuvset; l++) {
-                                                       if (!index_list_array.empty() && index_list_array[l]) {
-                                                               // get mtface by face index and uv set index
-                                                               MTFace *mtface = (MTFace *)CustomData_get_layer_n(&me->fdata, CD_MTFACE, l);
-                                                               set_face_uv(&mtface[face_index], uvs, l, *index_list_array[l], uv_indices);
-                                                       }
-                                               }
-#else
-                                               for (unsigned int l = 0; l < index_list_array.getCount(); l++) {
-                                                       int uvset_index = index_list_array[l]->getSetIndex();
-
-                                                       // get mtface by face index and uv set index
-                                                       MTFace *mtface = (MTFace *)CustomData_get_layer_n(&me->fdata, CD_MTFACE, uvset_index);
-                                                       set_face_uv(&mtface[face_index], uvs, *index_list_array[l], uv_indices);
-                                               }
-#endif
-
-
-                                               test_index_face(mface, &me->fdata, face_index, 3);
-
-                                               if (mp_has_normals) {
-                                                       unsigned int ntri[3] = {nind[tri[v]], nind[tri[v + 1]], nind[tri[v + 2]]};
+                                       // get mtface by face index and uv set index
+                                       MLoopUV  *mloopuv = (MLoopUV  *)CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, uvset_index);
 
-                                                       if (!flat_face(ntri, nor, 3))
-                                                               mface->flag |= ME_SMOOTH;
-                                               }
-                                               
-                                               mface++;
-                                               face_index++;
-                                               prim.totface++;
-                                       }
+                                       set_face_uv(mloopuv+loop_index, uvs, loop_index, *index_list_array[l], vcount);
+                               }
 
-                                       if (mp_has_normals)
-                                               nind += vcount;
+                               if (mp_has_normals) {
+                                       if (!is_flat_face(normal_indices, nor, vcount))
+                                               mpoly->flag |= ME_SMOOTH;
                                }
+                               
+                               mpoly++;
+                               mloop += vcount;
+                               loop_index += vcount;
+                               prim.totpoly++;
+
+                               if (mp_has_normals)
+                                       normal_indices += vcount;
 
-                               index += vcount;
-                               indices += vcount;
+                               position_indices += vcount;
                        }
                }
-               else if (type == COLLADAFW::MeshPrimitive::LINES) {
+
+               else if (collada_meshtype == COLLADAFW::MeshPrimitive::LINES) {
                        continue; // read the lines later after all the rest is done
                }
 
@@ -863,7 +644,7 @@ void MeshImporter::read_faces(COLLADAFW::Mesh *mesh, Mesh *me, int new_tris) //T
                        mat_prim_map[mp->getMaterialId()].push_back(prim);
        }
 
-       geom_uid_mat_mapping_map[mesh->getUniqueId()] = mat_prim_map;
+       geom_uid_mat_mapping_map[collada_mesh->getUniqueId()] = mat_prim_map;
 }
 
 void MeshImporter::get_vector(float v[3], COLLADAFW::MeshVertexData& arr, int i, int stride)
@@ -896,8 +677,7 @@ void MeshImporter::get_vector(float v[3], COLLADAFW::MeshVertexData& arr, int i,
                        break;
        }
 }
-
-bool MeshImporter::flat_face(unsigned int *nind, COLLADAFW::MeshVertexData& nor, int count)
+bool MeshImporter::is_flat_face(unsigned int *nind, COLLADAFW::MeshVertexData& nor, int count)
 {
        float a[3], b[3];
 
@@ -919,8 +699,6 @@ bool MeshImporter::flat_face(unsigned int *nind, COLLADAFW::MeshVertexData& nor,
        return true;
 }
 
-MeshImporter::MeshImporter(UnitConverter *unitconv, ArmatureImporter *arm, Scene *sce) : unitconverter(unitconv), scene(sce), armature_importer(arm) {
-}
 
 void MeshImporter::bmeshConversion()
 {
@@ -929,10 +707,9 @@ void MeshImporter::bmeshConversion()
        {
                if ((*m).second) {
                        Mesh *me = (*m).second;
-                       BKE_mesh_convert_mfaces_to_mpolys(me);
                        BKE_mesh_tessface_clear(me);
-
                        BKE_mesh_calc_normals_mapping(me->mvert, me->totvert, me->mloop, me->mpoly, me->totloop, me->totpoly, NULL, NULL, 0, NULL, NULL);
+                       //BKE_mesh_validate(me, 1);
                }
        }
 }
@@ -1137,9 +914,10 @@ void MeshImporter::optimize_material_assignements()
 MTFace *MeshImporter::assign_material_to_geom(COLLADAFW::MaterialBinding cmaterial,
                                               std::map<COLLADAFW::UniqueId, Material *>& uid_material_map,
                                               Object *ob, const COLLADAFW::UniqueId *geom_uid,
-                                              MTex **color_texture, char *layername, MTFace *texture_face,
+                                              char *layername, MTFace *texture_face,
                                               std::map<Material *, TexIndexTextureArrayMap>& material_texture_mapping_map, short mat_index)
 {
+       MTex *color_texture = NULL;
        Mesh *me = (Mesh *)ob->data;
        const COLLADAFW::UniqueId& ma_uid = cmaterial.getReferencedMaterial();
        
@@ -1167,17 +945,17 @@ MTFace *MeshImporter::assign_material_to_geom(COLLADAFW::MaterialBinding cmateri
        // loop through <bind_vertex_inputs>
        for (i = 0; i < tex_array.getCount(); i++) {
                
-               *color_texture = assign_textures_to_uvlayer(tex_array[i], me, texindex_texarray_map,
-                                                           *color_texture);
+               color_texture = assign_textures_to_uvlayer(tex_array[i], me, texindex_texarray_map,
+                                                           color_texture);
        }
        
        // set texture face
-       if (*color_texture &&
-           strlen((*color_texture)->uvname) &&
-           strcmp(layername, (*color_texture)->uvname) != 0) {
+       if (color_texture &&
+           strlen((color_texture)->uvname) &&
+           strcmp(layername, color_texture->uvname) != 0) {
                texture_face = (MTFace *)CustomData_get_layer_named(&me->fdata, CD_MTFACE,
-                                                                   (*color_texture)->uvname);
-               strcpy(layername, (*color_texture)->uvname);
+                                                                   color_texture->uvname);
+               strcpy(layername, color_texture->uvname);
        }
        
        MaterialIdPrimitiveArrayMap& mat_prim_map = geom_uid_mat_mapping_map[*geom_uid];
@@ -1192,19 +970,18 @@ MTFace *MeshImporter::assign_material_to_geom(COLLADAFW::MaterialBinding cmateri
                
                for (it = prims.begin(); it != prims.end(); it++) {
                        Primitive& prim = *it;
-                       MFace *mface = prim.mface;
+                       MPoly *mpoly = prim.mpoly;
 
-                       for (i = 0; i < prim.totface; i++, mface++) {
-                               mface->mat_nr = mat_index;
+                       for (i = 0; i < prim.totpoly; i++, mpoly++) {
+                               mpoly->mat_nr = mat_index;
                                // bind texture images to faces
-                               if (texture_face && (*color_texture)) {
-                                       texture_face->tpage = (Image *)(*color_texture)->tex->ima;
+                               if (texture_face && color_texture) {
+                                       texture_face->tpage = (Image *)color_texture->tex->ima;
                                        texture_face++;
                                }
                        }
                }
-       }
-       
+       }       
        return texture_face;
 }
 
@@ -1251,15 +1028,15 @@ Object *MeshImporter::create_mesh_object(COLLADAFW::Node *node, COLLADAFW::Insta
        
        // replace ob->data freeing the old one
        Mesh *old_mesh = (Mesh *)ob->data;
+       Mesh *new_mesh = uid_mesh_map[*geom_uid];
 
-       set_mesh(ob, uid_mesh_map[*geom_uid]);
+       set_mesh(ob, new_mesh);
        
        if (old_mesh->id.us == 0) BKE_libblock_free(&G.main->mesh, old_mesh);
        
        char layername[100];
        layername[0] = '\0';
        MTFace *texture_face = NULL;
-       MTex *color_texture = NULL;
        
        COLLADAFW::MaterialBindingArray& mat_array =
            geom->getMaterialBindings();
@@ -1269,7 +1046,7 @@ Object *MeshImporter::create_mesh_object(COLLADAFW::Node *node, COLLADAFW::Insta
                
                if (mat_array[i].getReferencedMaterial().isValid()) {
                        texture_face = assign_material_to_geom(mat_array[i], uid_material_map, ob, geom_uid,
-                                                              &color_texture, layername, texture_face,
+                                                              layername, texture_face,
                                                               material_texture_mapping_map, i);
                }
                else {
@@ -1283,11 +1060,7 @@ Object *MeshImporter::create_mesh_object(COLLADAFW::Node *node, COLLADAFW::Insta
 // create a mesh storing a pointer in a map so it can be retrieved later by geometry UID
 bool MeshImporter::write_geometry(const COLLADAFW::Geometry *geom)
 {
-       // TODO: import also uvs, normals
-       // XXX what to do with normal indices?
-       // XXX num_normals may be != num verts, then what to do?
 
-       // check geometry->getType() first
        if (geom->getType() != COLLADAFW::Geometry::GEO_TYPE_MESH) {
                // TODO: report warning
                fprintf(stderr, "Mesh type %s is not supported\n", bc_geomTypeToStr(geom->getType()));
@@ -1306,23 +1079,16 @@ bool MeshImporter::write_geometry(const COLLADAFW::Geometry *geom)
        me->id.us--; // is already 1 here, but will be set later in set_mesh
 
        // store the Mesh pointer to link it later with an Object
+       // mesh_geom_map needed to map mesh to its geometry name (for shape key naming)
        this->uid_mesh_map[mesh->getUniqueId()] = me;
-       // needed to map mesh to its geometry name (needed for shape key naming)
        this->mesh_geom_map[std::string(me->id.name)] = str_geom_id;
-
-       int new_tris = 0;
        
        read_vertices(mesh, me);
-
-       new_tris = count_new_tris(mesh, me);
-       
-       read_faces(mesh, me, new_tris);
-
-       BKE_mesh_make_edges(me, 0);
+       read_polys(mesh, me);
+       BKE_mesh_calc_edges(me, 0);
 
        // read_lines() must be called after the face edges have been generated.
        // Oterwise the loose edges will be silently deleted again.
        read_lines(mesh, me);
-
        return true;
 }
index 8b0f5cd..751e6fa 100644 (file)
@@ -31,6 +31,7 @@
 #include <vector>
 
 #include "COLLADAFWIndexList.h"
+#include "COLLADAFWPolygons.h"
 #include "COLLADAFWInstanceGeometry.h"
 #include "COLLADAFWMaterialBinding.h"
 #include "COLLADAFWMesh.h"
@@ -89,30 +90,28 @@ private:
        std::map<COLLADAFW::UniqueId, Mesh*> uid_mesh_map; // geometry unique id-to-mesh map
        std::map<COLLADAFW::UniqueId, Object*> uid_object_map; // geom uid-to-object
        std::vector<Object*> imported_objects; // list of imported objects
-       // this structure is used to assign material indices to faces
+
+       // this structure is used to assign material indices to polygons
        // it holds a portion of Mesh faces and corresponds to a DAE primitive list (<triangles>, <polylist>, etc.)
        struct Primitive {
-               MFace *mface;
-               unsigned int totface;
+               MPoly *mpoly;
+               unsigned int totpoly;
        };
        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);
-
-       // not used anymore, test_index_face from blenkernel is better
-#if 0
-       // change face indices order so that v4 is not 0
-       void rotate_face_indices(MFace *mface);
-#endif
-       
-       void set_face_uv(MTFace *mtface, UVDataWrapper &uvs,
-                                        COLLADAFW::IndexList& index_list, unsigned int *tris_indices);
-
-       void set_face_uv(MTFace *mtface, UVDataWrapper &uvs,
-                                       COLLADAFW::IndexList& index_list, int index, bool quad);
+       void set_poly_indices(MPoly *mpoly,
+                                                 MLoop *mloop,
+                                                 int loop_index,
+                                                 unsigned int *indices,
+                                                 int loop_count);
+
+       void set_face_uv(MLoopUV *mloopuv,
+                                        UVDataWrapper &uvs,
+                                        int loop_index,
+                                        COLLADAFW::IndexList& index_list,
+                                        int count);
 
 #ifdef COLLADA_DEBUG
        void print_index_list(COLLADAFW::IndexList& index_list);
@@ -121,11 +120,7 @@ private:
        bool is_nice_mesh(COLLADAFW::Mesh *mesh);
 
        void read_vertices(COLLADAFW::Mesh *mesh, Mesh *me);
-       
-       int triangulate_poly(unsigned int *indices, int totvert, MVert *verts, std::vector<unsigned int>& tri);
-       
-       int count_new_tris(COLLADAFW::Mesh *mesh, Mesh *me);
-       
+                       
        bool primitive_has_useable_normals(COLLADAFW::MeshPrimitive *mp);
        bool primitive_has_faces(COLLADAFW::MeshPrimitive *mp);
 
@@ -135,15 +130,16 @@ private:
 
        CustomData create_edge_custom_data(EdgeHash *eh);
 
-       void allocate_face_data(COLLADAFW::Mesh *mesh, Mesh *me, int new_tris);
+       void allocate_poly_data(COLLADAFW::Mesh *collada_mesh, Mesh *me);
 
        // TODO: import uv set names
-       void read_faces(COLLADAFW::Mesh *mesh, Mesh *me, int new_tris);
+       void read_polys(COLLADAFW::Mesh *mesh, Mesh *me);
        void read_lines(COLLADAFW::Mesh *mesh, Mesh *me);
+       unsigned int get_vertex_count(COLLADAFW::Polygons *mp, int index);
 
        void get_vector(float v[3], COLLADAFW::MeshVertexData& arr, int i, int stride);
 
-       bool flat_face(unsigned int *nind, COLLADAFW::MeshVertexData& nor, int count);
+       bool is_flat_face(unsigned int *nind, COLLADAFW::MeshVertexData& nor, int count);
 
        std::vector<Object *> get_all_users_of(Mesh *reference_mesh);
 
@@ -166,7 +162,7 @@ public:
        MTFace *assign_material_to_geom(COLLADAFW::MaterialBinding cmaterial,
                                                                        std::map<COLLADAFW::UniqueId, Material*>& uid_material_map,
                                                                        Object *ob, const COLLADAFW::UniqueId *geom_uid, 
-                                                                       MTex **color_texture, char *layername, MTFace *texture_face,
+                                                                       char *layername, MTFace *texture_face,
                                                                        std::map<Material*, TexIndexTextureArrayMap>& material_texture_mapping_map, short mat_index);
        
        
index a868bf2..e75123c 100644 (file)
@@ -75,7 +75,7 @@ int collada_export(Scene *sce,
                                   int include_material_textures,
                                   int use_texture_copies,
 
-                   int use_ngons,
+                   int triangulate,
                    int use_object_instantiation,
                    int sort_by_name,
                    int second_life)
@@ -107,7 +107,7 @@ int collada_export(Scene *sce,
        export_settings.include_material_textures= include_material_textures != 0;
        export_settings.use_texture_copies       = use_texture_copies != 0;
 
-       export_settings.use_ngons                = use_ngons != 0;
+       export_settings.triangulate              = triangulate != 0;
        export_settings.use_object_instantiation = use_object_instantiation != 0;
        export_settings.sort_by_name             = sort_by_name != 0;
        export_settings.second_life              = second_life != 0;
index e7e8555..642259d 100644 (file)
@@ -67,7 +67,7 @@ int collada_export(Scene *sce,
                                   int include_material_textures,
                                   int use_texture_copies,
 
-                   int use_ngons,
+                   int triangulate,
                    int use_object_instantiation,
                    int sort_by_name,
                    int second_life);
index f438789..d8f1569 100644 (file)
@@ -56,6 +56,8 @@ extern "C" {
 
 #include "WM_api.h" // XXX hrm, see if we can do without this
 #include "WM_types.h"
+#include "bmesh.h"
+
 }
 
 float bc_get_float_value(const COLLADAFW::FloatOrDoubleArray& array, unsigned int index)
@@ -137,25 +139,38 @@ Object *bc_add_object(Scene *scene, int type, const char *name)
        return ob;
 }
 
-Mesh *bc_to_mesh_apply_modifiers(Scene *scene, Object *ob, BC_export_mesh_type export_mesh_type)
+Mesh *bc_get_mesh_copy(Scene *scene, Object *ob, BC_export_mesh_type export_mesh_type, bool apply_modifiers, bool triangulate)
 {
        Mesh *tmpmesh;
        CustomDataMask mask = CD_MASK_MESH;
        DerivedMesh *dm = NULL;
-       switch (export_mesh_type) {
-               case BC_MESH_TYPE_VIEW: {
-                       dm = mesh_create_derived_view(scene, ob, mask);
-                       break;
-               }
-               case BC_MESH_TYPE_RENDER: {
-                       dm = mesh_create_derived_render(scene, ob, mask);
-                       break;
+       if(apply_modifiers) {
+               switch (export_mesh_type) {
+                       case BC_MESH_TYPE_VIEW: {
+                               dm = mesh_create_derived_view(scene, ob, mask);
+                               break;
+                       }
+                       case BC_MESH_TYPE_RENDER: {
+                               dm = mesh_create_derived_render(scene, ob, mask);
+                               break;
+                       }
                }
        }
+       else {
+               dm = mesh_create_derived((Mesh *)ob->data, ob, NULL);
+       }
 
        tmpmesh = BKE_mesh_add(G.main, "ColladaMesh"); // name is not important here
        DM_to_mesh(dm, tmpmesh, ob);
        dm->release(dm);
+
+       if (triangulate) {
+               bc_triangulate_mesh(tmpmesh);
+       }
+
+       // XXX Not sure if we need that for ngon_export as well.
+       BKE_mesh_tessface_ensure(tmpmesh);
+
        return tmpmesh;
 }
 
@@ -366,3 +381,14 @@ void bc_match_scale(std::vector<Object *> *objects_done,
        }
 
 }
+
+void bc_triangulate_mesh(Mesh *me) {
+       bool use_beauty = false;
+       bool tag_only   = false;
+        
+       BMesh *bm = BM_mesh_create(&bm_mesh_allocsize_default);
+       BM_mesh_bm_from_me(bm, me, FALSE, 0);
+       BM_mesh_triangulate(bm, use_beauty, tag_only, NULL, NULL);
+       BM_mesh_bm_to_me(bm, me, FALSE);
+       BM_mesh_free(bm);
+}
index 892b57e..2b2c8c5 100644 (file)
@@ -62,7 +62,7 @@ extern float bc_get_float_value(const COLLADAFW::FloatOrDoubleArray& array, unsi
 extern int bc_test_parent_loop(Object *par, Object *ob);
 extern int bc_set_parent(Object *ob, Object *par, bContext *C, bool is_parent_space = true);
 extern Object *bc_add_object(Scene *scene, int type, const char *name);
-extern Mesh *bc_to_mesh_apply_modifiers(Scene *scene, Object *ob, BC_export_mesh_type export_mesh_type);
+extern Mesh *bc_get_mesh_copy(Scene *scene, Object *ob, BC_export_mesh_type export_mesh_type, bool apply_modifiers, bool triangulate);
 
 extern Object *bc_get_assigned_armature(Object *ob);
 extern Object *bc_get_highest_selected_ancestor_or_self(LinkNode *export_set, Object *ob);
@@ -84,4 +84,7 @@ extern int  bc_get_active_UVLayer(Object *ob);
 extern std::string bc_replace_string(std::string data, const std::string& pattern, const std::string& replacement); 
 extern std::string bc_url_encode(std::string data); 
 extern void bc_match_scale(std::vector<Object *> *objects_done, Scene &sce, UnitConverter &unit_converter);
+
+extern void bc_triangulate_mesh(Mesh *me);
+
 #endif
index 7eae20f..4908c10 100644 (file)
@@ -92,7 +92,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
        int use_texture_copies;
        int active_uv_only;
 
-       int use_ngons;
+       int triangulate;
        int use_object_instantiation;
        int sort_by_name;
        int second_life; 
@@ -119,7 +119,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
        use_texture_copies       = RNA_boolean_get(op->ptr, "use_texture_copies");
        active_uv_only           = RNA_boolean_get(op->ptr, "active_uv_only");
 
-       use_ngons                = RNA_boolean_get(op->ptr, "use_ngons");
+       triangulate              = RNA_boolean_get(op->ptr, "triangulate");
        use_object_instantiation = RNA_boolean_get(op->ptr, "use_object_instantiation");
        sort_by_name             = RNA_boolean_get(op->ptr, "sort_by_name");
        second_life              = RNA_boolean_get(op->ptr, "second_life");
@@ -142,7 +142,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
                           include_material_textures,
                           use_texture_copies,
 
-                          use_ngons,
+                          triangulate,
                           use_object_instantiation,
                           sort_by_name,
                           second_life))
@@ -221,7 +221,7 @@ static void uiCollada_exportSettings(uiLayout *layout, PointerRNA *imfptr)
        uiItemL(row, IFACE_("Collada Options:"), ICON_MODIFIER);
 
        row = uiLayoutRow(box, FALSE);
-       uiItemR(row, imfptr, "use_ngons", 0, NULL, ICON_NONE);
+       uiItemR(row, imfptr, "triangulate", 0, NULL, ICON_NONE);
        row = uiLayoutRow(box, FALSE);
        uiItemR(row, imfptr, "use_object_instantiation", 0, NULL, ICON_NONE);
        row = uiLayoutRow(box, FALSE);
@@ -299,8 +299,8 @@ void WM_OT_collada_export(wmOperatorType *ot)
                        "Copy textures to same folder where the .dae file is exported");
 
 
-       RNA_def_boolean(ot->srna, "use_ngons", 1, "Use NGons",
-                       "Export as NGons");
+       RNA_def_boolean(ot->srna, "triangulate", 1, "Triangulate",
+                       "Export Polygons (Quads & NGons) as Triangles");
 
        RNA_def_boolean(ot->srna, "use_object_instantiation", 1, "Use Object Instances",
                        "Instantiate multiple Objects from same Data");