Fix #33421: collada import of a mesh with loose edges did not draw the edges in the...
[blender.git] / source / blender / collada / MeshImporter.cpp
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Nathan Letwory.
19  *
20  * ***** END GPL LICENSE BLOCK *****
21  */
22
23 /** \file blender/collada/MeshImporter.cpp
24  *  \ingroup collada
25  */
26
27
28 #include <algorithm>
29
30 #if !defined(WIN32) || defined(FREE_WINDOWS)
31 #include <iostream>
32 #endif
33
34 /* COLLADABU_ASSERT, may be able to remove later */
35 #include "COLLADABUPlatform.h"
36
37 #include "COLLADAFWMeshPrimitive.h"
38 #include "COLLADAFWMeshVertexData.h"
39 #include "COLLADAFWPolygons.h"
40
41 extern "C" {
42         #include "BKE_blender.h"
43         #include "BKE_customdata.h"
44         #include "BKE_displist.h"
45         #include "BKE_global.h"
46         #include "BKE_library.h"
47         #include "BKE_main.h"
48         #include "BKE_material.h"
49         #include "BKE_mesh.h"
50         #include "BKE_object.h"
51
52         #include "BLI_listbase.h"
53         #include "BLI_math.h"
54         #include "BLI_string.h"
55         #include "BLI_edgehash.h"
56
57         #include "MEM_guardedalloc.h"
58 }
59
60 #include "ArmatureImporter.h"
61 #include "MeshImporter.h"
62 #include "collada_utils.h"
63
64 // get node name, or fall back to original id if not present (name is optional)
65 template<class T>
66 static const char *bc_get_dae_name(T *node)
67 {
68         const std::string& name = node->getName();
69         return name.size() ? name.c_str() : node->getOriginalId().c_str();
70 }
71
72 static const char *bc_primTypeToStr(COLLADAFW::MeshPrimitive::PrimitiveType type)
73 {
74         switch (type) {
75                 case COLLADAFW::MeshPrimitive::LINES:
76                         return "LINES";
77                 case COLLADAFW::MeshPrimitive::LINE_STRIPS:
78                         return "LINESTRIPS";
79                 case COLLADAFW::MeshPrimitive::POLYGONS:
80                         return "POLYGONS";
81                 case COLLADAFW::MeshPrimitive::POLYLIST:
82                         return "POLYLIST";
83                 case COLLADAFW::MeshPrimitive::TRIANGLES:
84                         return "TRIANGLES";
85                 case COLLADAFW::MeshPrimitive::TRIANGLE_FANS:
86                         return "TRIANGLE_FANS";
87                 case COLLADAFW::MeshPrimitive::TRIANGLE_STRIPS:
88                         return "TRIANGLE_FANS";
89                 case COLLADAFW::MeshPrimitive::POINTS:
90                         return "POINTS";
91                 case COLLADAFW::MeshPrimitive::UNDEFINED_PRIMITIVE_TYPE:
92                         return "UNDEFINED_PRIMITIVE_TYPE";
93         }
94         return "UNKNOWN";
95 }
96
97 static const char *bc_geomTypeToStr(COLLADAFW::Geometry::GeometryType type)
98 {
99         switch (type) {
100                 case COLLADAFW::Geometry::GEO_TYPE_MESH:
101                         return "MESH";
102                 case COLLADAFW::Geometry::GEO_TYPE_SPLINE:
103                         return "SPLINE";
104                 case COLLADAFW::Geometry::GEO_TYPE_CONVEX_MESH:
105                         return "CONVEX_MESH";
106                 case COLLADAFW::Geometry::GEO_TYPE_UNKNOWN:
107                 default:
108                         return "UNKNOWN";
109         }
110 }
111
112
113 UVDataWrapper::UVDataWrapper(COLLADAFW::MeshVertexData& vdata) : mVData(&vdata)
114 {
115 }
116
117 #ifdef COLLADA_DEBUG
118 void WVDataWrapper::print()
119 {
120         fprintf(stderr, "UVs:\n");
121         switch (mVData->getType()) {
122                 case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT:
123                 {
124                         COLLADAFW::ArrayPrimitiveType<float> *values = mVData->getFloatValues();
125                         if (values->getCount()) {
126                                 for (int i = 0; i < values->getCount(); i += 2) {
127                                         fprintf(stderr, "%.1f, %.1f\n", (*values)[i], (*values)[i + 1]);
128                                 }
129                         }
130                 }
131                 break;
132                 case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE:
133                 {
134                         COLLADAFW::ArrayPrimitiveType<double> *values = mVData->getDoubleValues();
135                         if (values->getCount()) {
136                                 for (int i = 0; i < values->getCount(); i += 2) {
137                                         fprintf(stderr, "%.1f, %.1f\n", (float)(*values)[i], (float)(*values)[i + 1]);
138                                 }
139                         }
140                 }
141                 break;
142         }
143         fprintf(stderr, "\n");
144 }
145 #endif
146
147 void UVDataWrapper::getUV(int uv_index, float *uv)
148 {
149         int stride = mVData->getStride(0);
150         if (stride == 0) stride = 2;
151
152         switch (mVData->getType()) {
153                 case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT:
154                 {
155                         COLLADAFW::ArrayPrimitiveType<float> *values = mVData->getFloatValues();
156                         if (values->empty()) return;
157                         uv[0] = (*values)[uv_index * stride];
158                         uv[1] = (*values)[uv_index * stride + 1];
159                         
160                 }
161                 break;
162                 case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE:
163                 {
164                         COLLADAFW::ArrayPrimitiveType<double> *values = mVData->getDoubleValues();
165                         if (values->empty()) return;
166                         uv[0] = (float)(*values)[uv_index * stride];
167                         uv[1] = (float)(*values)[uv_index * stride + 1];
168                         
169                 }
170                 break;
171                 case COLLADAFW::MeshVertexData::DATA_TYPE_UNKNOWN:
172                 default:
173                         fprintf(stderr, "MeshImporter.getUV(): unknown data type\n");
174         }
175 }
176
177 void MeshImporter::set_face_indices(MFace *mface, unsigned int *indices, bool quad)
178 {
179         mface->v1 = indices[0];
180         mface->v2 = indices[1];
181         mface->v3 = indices[2];
182         if (quad) mface->v4 = indices[3];
183         else mface->v4 = 0;
184 #ifdef COLLADA_DEBUG
185         // fprintf(stderr, "%u, %u, %u\n", indices[0], indices[1], indices[2]);
186 #endif
187 }
188
189 // not used anymore, test_index_face from blenkernel is better
190 #if 0
191 // change face indices order so that v4 is not 0
192 void MeshImporter::rotate_face_indices(MFace *mface)
193 {
194         mface->v4 = mface->v1;
195         mface->v1 = mface->v2;
196         mface->v2 = mface->v3;
197         mface->v3 = 0;
198 }
199 #endif
200
201 void MeshImporter::set_face_uv(MTFace *mtface, UVDataWrapper &uvs,
202                                COLLADAFW::IndexList& index_list, unsigned int *tris_indices)
203 {
204         // per face vertex indices, this means for quad we have 4 indices, not 8
205         COLLADAFW::UIntValuesArray& indices = index_list.getIndices();
206
207         uvs.getUV(indices[tris_indices[0]], mtface->uv[0]);
208         uvs.getUV(indices[tris_indices[1]], mtface->uv[1]);
209         uvs.getUV(indices[tris_indices[2]], mtface->uv[2]);
210 }
211
212 void MeshImporter::set_face_uv(MTFace *mtface, UVDataWrapper &uvs,
213                                COLLADAFW::IndexList& index_list, int index, bool quad)
214 {
215         // per face vertex indices, this means for quad we have 4 indices, not 8
216         COLLADAFW::UIntValuesArray& indices = index_list.getIndices();
217
218         uvs.getUV(indices[index + 0], mtface->uv[0]);
219         uvs.getUV(indices[index + 1], mtface->uv[1]);
220         uvs.getUV(indices[index + 2], mtface->uv[2]);
221
222         if (quad) uvs.getUV(indices[index + 3], mtface->uv[3]);
223
224 #ifdef COLLADA_DEBUG
225         if (quad) {
226                 fprintf(stderr, "face uv:\n"
227                         "((%d, %d, %d, %d))\n"
228                         "((%.1f, %.1f), (%.1f, %.1f), (%.1f, %.1f), (%.1f, %.1f))\n",
229
230                         indices[index + 0],
231                         indices[index + 1],
232                         indices[index + 2],
233                         indices[index + 3],
234
235                         mtface->uv[0][0], mtface->uv[0][1],
236                         mtface->uv[1][0], mtface->uv[1][1],
237                         mtface->uv[2][0], mtface->uv[2][1],
238                         mtface->uv[3][0], mtface->uv[3][1]);
239         }
240         else {
241                 fprintf(stderr, "face uv:\n"
242                         "((%d, %d, %d))\n"
243                         "((%.1f, %.1f), (%.1f, %.1f), (%.1f, %.1f))\n",
244
245                         indices[index + 0],
246                         indices[index + 1],
247                         indices[index + 2],
248
249                         mtface->uv[0][0], mtface->uv[0][1],
250                         mtface->uv[1][0], mtface->uv[1][1],
251                         mtface->uv[2][0], mtface->uv[2][1]);
252         }
253 #endif
254 }
255
256 #ifdef COLLADA_DEBUG
257 void MeshImporter::print_index_list(COLLADAFW::IndexList& index_list)
258 {
259         fprintf(stderr, "Index list for \"%s\":\n", index_list.getName().c_str());
260         for (int i = 0; i < index_list.getIndicesCount(); i += 2) {
261                 fprintf(stderr, "%u, %u\n", index_list.getIndex(i), index_list.getIndex(i + 1));
262         }
263         fprintf(stderr, "\n");
264 }
265 #endif
266
267 bool MeshImporter::is_nice_mesh(COLLADAFW::Mesh *mesh)  // checks if mesh has supported primitive types: lines, polylist, triangles, triangle_fans
268 {
269         COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives();
270
271         const char *name = bc_get_dae_name(mesh);
272         
273         for (unsigned i = 0; i < prim_arr.getCount(); i++) {
274                 
275                 COLLADAFW::MeshPrimitive *mp = prim_arr[i];
276                 COLLADAFW::MeshPrimitive::PrimitiveType type = mp->getPrimitiveType();
277
278                 const char *type_str = bc_primTypeToStr(type);
279                 
280                 // OpenCollada passes POLYGONS type for <polylist>
281                 if (type == COLLADAFW::MeshPrimitive::POLYLIST || type == COLLADAFW::MeshPrimitive::POLYGONS) {
282
283                         COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons *)mp;
284                         COLLADAFW::Polygons::VertexCountArray& vca = mpvc->getGroupedVerticesVertexCountArray();
285                         
286                         for (unsigned int j = 0; j < vca.getCount(); j++) {
287                                 int count = vca[j];
288                                 if (count < 3) {
289                                         fprintf(stderr, "Primitive %s in %s has at least one face with vertex count < 3\n",
290                                                 type_str, name);
291                                         return false;
292                                 }
293                         }
294                                 
295                 }
296
297                 else if (type == COLLADAFW::MeshPrimitive::LINES) {
298                         // TODO: Add Checker for line syntax here
299                 }
300
301                 else if (type != COLLADAFW::MeshPrimitive::TRIANGLES && type != COLLADAFW::MeshPrimitive::TRIANGLE_FANS) {
302                         fprintf(stderr, "Primitive type %s is not supported.\n", type_str);
303                         return false;
304                 }
305         }
306         
307         if (mesh->getPositions().empty()) {
308                 fprintf(stderr, "Mesh %s has no vertices.\n", name);
309                 return false;
310         }
311
312         return true;
313 }
314
315 void MeshImporter::read_vertices(COLLADAFW::Mesh *mesh, Mesh *me)
316 {
317         // vertices
318         COLLADAFW::MeshVertexData& pos = mesh->getPositions();
319         int stride = pos.getStride(0);
320         if (stride == 0) stride = 3;
321         
322         me->totvert = mesh->getPositions().getFloatValues()->getCount() / stride;
323         me->mvert = (MVert *)CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, me->totvert);
324
325         MVert *mvert;
326         int i;
327
328         for (i = 0, mvert = me->mvert; i < me->totvert; i++, mvert++) {
329                 get_vector(mvert->co, pos, i, stride);
330         }
331 }
332
333 int MeshImporter::triangulate_poly(unsigned int *indices, int totvert, MVert *verts, std::vector<unsigned int>& tri)
334 {
335         ListBase dispbase;
336         DispList *dl;
337         float *vert;
338         int i = 0;
339         
340         dispbase.first = dispbase.last = NULL;
341         
342         dl = (DispList *)MEM_callocN(sizeof(DispList), "poly disp");
343         dl->nr = totvert;
344         dl->type = DL_POLY;
345         dl->parts = 1;
346         dl->verts = vert = (float *)MEM_callocN(totvert * 3 * sizeof(float), "poly verts");
347         dl->index = (int *)MEM_callocN(sizeof(int) * 3 * totvert, "dl index");
348
349         BLI_addtail(&dispbase, dl);
350         
351         for (i = 0; i < totvert; i++) {
352                 copy_v3_v3(vert, verts[indices[i]].co);
353                 vert += 3;
354         }
355         
356         BKE_displist_fill(&dispbase, &dispbase, 0);
357
358         int tottri = 0;
359         dl = (DispList *)dispbase.first;
360
361         if (dl->type == DL_INDEX3) {
362                 tottri = dl->parts;
363
364                 int *index = dl->index;
365                 for (i = 0; i < tottri; i++) {
366                         int t[3] = {*index, *(index + 1), *(index + 2)};
367
368                         std::sort(t, t + 3);
369
370                         tri.push_back(t[0]);
371                         tri.push_back(t[1]);
372                         tri.push_back(t[2]);
373
374                         index += 3;
375                 }
376         }
377
378         BKE_displist_free(&dispbase);
379
380         return tottri;
381 }
382
383 int MeshImporter::count_new_tris(COLLADAFW::Mesh *mesh, Mesh *me)
384 {
385         COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives();
386         unsigned int i;
387         int tottri = 0;
388         
389         for (i = 0; i < prim_arr.getCount(); i++) {
390                 
391                 COLLADAFW::MeshPrimitive *mp = prim_arr[i];
392                 int type = mp->getPrimitiveType();
393                 size_t prim_totface = mp->getFaceCount();
394                 unsigned int *indices = mp->getPositionIndices().getData();
395                 
396                 if (type == COLLADAFW::MeshPrimitive::POLYLIST ||
397                     type == COLLADAFW::MeshPrimitive::POLYGONS)
398                 {
399                         COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons *)mp;
400                         COLLADAFW::Polygons::VertexCountArray& vcounta = mpvc->getGroupedVerticesVertexCountArray();
401                         
402                         for (unsigned int j = 0; j < prim_totface; j++) {
403                                 int vcount = vcounta[j];
404                                 
405                                 if (vcount > 4) {
406                                         std::vector<unsigned int> tri;
407                                         
408                                         // tottri += triangulate_poly(indices, vcount, me->mvert, tri) - 1; // XXX why - 1?!
409                                         tottri += triangulate_poly(indices, vcount, me->mvert, tri);
410                                 }
411
412                                 indices += vcount;
413                         }
414                 }
415         }
416         return tottri;
417 }
418
419 // =====================================================================
420 // condition 1: The Primitive has normals
421 // condition 2: The number of normals equals the number of faces.
422 // return true if both conditions apply.
423 // return false otherwise.
424 // =====================================================================
425 bool MeshImporter::primitive_has_useable_normals(COLLADAFW::MeshPrimitive *mp) {
426
427         bool has_useable_normals = false;
428
429         int normals_count = mp->getNormalIndices().getCount();
430         if (normals_count > 0) {
431                 int index_count   = mp->getPositionIndices().getCount();
432                 if (index_count == normals_count) 
433                         has_useable_normals = true;
434                 else {
435                         fprintf(stderr,
436                                 "Warning: Number of normals %d is different from the number of vertices %d, skipping normals\n",
437                                 normals_count, index_count);
438                 }
439         }
440
441         return has_useable_normals;
442
443 }
444
445 // =====================================================================
446 // Assume that only TRIANGLES, TRIANGLE_FANS, POLYLIST and POLYGONS
447 // have faces. (to be verified)
448 // =====================================================================
449 bool MeshImporter::primitive_has_faces(COLLADAFW::MeshPrimitive *mp) {
450
451         bool has_faces = false;
452         int type = mp->getPrimitiveType();
453         switch (type) {
454                 case COLLADAFW::MeshPrimitive::TRIANGLES:
455                 case COLLADAFW::MeshPrimitive::TRIANGLE_FANS:
456                 case COLLADAFW::MeshPrimitive::POLYLIST:
457                 case COLLADAFW::MeshPrimitive::POLYGONS: {
458                         has_faces = true;
459                         break;
460                 }
461                 default: {
462                         has_faces = false; 
463                         break;
464                 }
465         }
466         return has_faces;
467 }
468
469 // =================================================================
470 // Return the number of faces by summing up
471 // the facecounts of the parts.
472 // hint: This is done because mesh->getFacesCount() does
473 // count loose edges as extra faces, which is not what we want here.
474 // =================================================================
475 void MeshImporter::allocate_face_data(COLLADAFW::Mesh *mesh, Mesh *me, int new_tris)
476 {
477         COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives();
478         int total_facecount = 0;
479
480         // collect edge_count and face_count from all parts
481         for (int i = 0; i < prim_arr.getCount(); i++) {
482                 COLLADAFW::MeshPrimitive *mp = prim_arr[i];
483                 int type = mp->getPrimitiveType();
484                 switch (type) {
485                         case COLLADAFW::MeshPrimitive::TRIANGLES:
486                         case COLLADAFW::MeshPrimitive::TRIANGLE_FANS:
487                         case COLLADAFW::MeshPrimitive::POLYLIST:
488                         case COLLADAFW::MeshPrimitive::POLYGONS: {
489                                 size_t prim_totface = mp->getFaceCount();
490                                 total_facecount += prim_totface;
491                                 break;
492                         }
493                         default: break;
494                 }
495         }
496
497         // allocate space for faces
498         if (total_facecount > 0) {
499                 me->totface = total_facecount + new_tris;
500                 me->mface   = (MFace *)CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, me->totface);
501         }
502 }
503
504 unsigned int MeshImporter::get_loose_edge_count(COLLADAFW::Mesh *mesh) {
505         COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives();
506         int loose_edge_count = 0;
507
508         // collect edge_count and face_count from all parts
509         for (int i = 0; i < prim_arr.getCount(); i++) {
510                 COLLADAFW::MeshPrimitive *mp = prim_arr[i];
511                 int type = mp->getPrimitiveType();
512                 switch (type) {
513                         case COLLADAFW::MeshPrimitive::LINES: {
514                                 size_t prim_totface = mp->getFaceCount();
515                                 loose_edge_count += prim_totface;
516                                 break;
517                         }
518                         default: break;
519                 }
520         }
521         return loose_edge_count;
522 }
523
524 // =================================================================
525 // This functin is copied from source/blender/editors/mesh/mesh_data.c
526 //
527 // TODO: (As discussed with sergey-) :
528 // Maybe move this function to blenderkernel/intern/mesh.c 
529 // and add definition to BKE_mesh.c
530 // =================================================================
531 void MeshImporter::mesh_add_edges(Mesh *mesh, int len)
532 {
533         CustomData edata;
534         MEdge *medge;
535         int i, totedge;
536
537         if (len == 0)
538                 return;
539
540         totedge = mesh->totedge + len;
541
542         /* update customdata  */
543         CustomData_copy(&mesh->edata, &edata, CD_MASK_MESH, CD_DEFAULT, totedge);
544         CustomData_copy_data(&mesh->edata, &edata, 0, 0, mesh->totedge);
545
546         if (!CustomData_has_layer(&edata, CD_MEDGE))
547                 CustomData_add_layer(&edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
548
549         CustomData_free(&mesh->edata, mesh->totedge);
550         mesh->edata = edata;
551         mesh_update_customdata_pointers(mesh, FALSE); /* new edges don't change tessellation */
552
553         /* set default flags */
554         medge = &mesh->medge[mesh->totedge];
555         for (i = 0; i < len; i++, medge++)
556                 medge->flag = ME_EDGEDRAW | ME_EDGERENDER | SELECT;
557
558         mesh->totedge = totedge;
559 }
560
561 // =================================================================
562 // Read all loose edges.
563 // Important: This function assumes that all edges from existing 
564 // faces have allready been generated and added to me->medge
565 // So this function MUST be called after read_faces() (see below)
566 // =================================================================
567 void MeshImporter::read_lines(COLLADAFW::Mesh *mesh, Mesh *me)
568 {
569         unsigned int loose_edge_count = get_loose_edge_count(mesh);
570         if (loose_edge_count > 0) {
571
572                 unsigned int face_edge_count  = me->totedge;
573                 /* unsigned int total_edge_count = loose_edge_count + face_edge_count; */ /* UNUSED */
574                 
575                 mesh_add_edges(me, loose_edge_count);
576                 MEdge *med = me->medge + face_edge_count;
577
578                 COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives();
579
580                 for (int i = 0; i < prim_arr.getCount(); i++) {
581                         
582                         COLLADAFW::MeshPrimitive *mp = prim_arr[i];
583
584                         int type = mp->getPrimitiveType();
585                         if (type == COLLADAFW::MeshPrimitive::LINES) {
586                                 unsigned int edge_count  = mp->getFaceCount();
587                                 unsigned int *indices    = mp->getPositionIndices().getData();
588                                 
589                                 for (int i = 0; i < edge_count; i++, med++) {
590                                         med->bweight = 0;
591                                         med->crease  = 0;
592                                         med->flag   |= ME_LOOSEEDGE;
593                                         med->v1      = indices[2 * i];
594                                         med->v2      = indices[2 * i + 1];
595                                 }
596                         }
597                 }
598
599         }
600 }
601
602
603 // =======================================================================
604 // Read all faces from TRIANGLES, TRIANGLE_FANS, POLYLIST, POLYGON
605 // Important: This function MUST be called before read_lines() 
606 // Otherwise we will loose all edges from faces (see read_lines() above)
607 //
608 // TODO: import uv set names
609 // ========================================================================
610 void MeshImporter::read_faces(COLLADAFW::Mesh *mesh, Mesh *me, int new_tris) //TODO:: Refactor. Possibly replace by iterators
611 {
612         unsigned int i;
613         
614         allocate_face_data(mesh, me, new_tris);
615         
616         // allocate UV Maps
617         unsigned int totuvset = mesh->getUVCoords().getInputInfosArray().getCount();
618
619         for (i = 0; i < totuvset; i++) {
620                 if (mesh->getUVCoords().getLength(i) == 0) {
621                         totuvset = 0;
622                         break;
623                 }
624         }
625
626         for (i = 0; i < totuvset; i++) {
627                 COLLADAFW::MeshVertexData::InputInfos *info = mesh->getUVCoords().getInputInfosArray()[i];
628                 CustomData_add_layer_named(&me->fdata, CD_MTFACE, CD_CALLOC, NULL, me->totface, info->mName.c_str());
629                 //this->set_layername_map[i] = CustomData_get_layer_name(&me->fdata, CD_MTFACE, i);
630         }
631
632         // activate the first uv map
633         if (totuvset) me->mtface = (MTFace *)CustomData_get_layer_n(&me->fdata, CD_MTFACE, 0);
634
635         UVDataWrapper uvs(mesh->getUVCoords());
636
637 #ifdef COLLADA_DEBUG
638         // uvs.print();
639 #endif
640
641         MFace *mface = me->mface;
642
643         MaterialIdPrimitiveArrayMap mat_prim_map;
644
645         int face_index = 0;
646
647         COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives();
648
649         COLLADAFW::MeshVertexData& nor = mesh->getNormals();
650
651         for (i = 0; i < prim_arr.getCount(); i++) {
652                 
653                 COLLADAFW::MeshPrimitive *mp = prim_arr[i];
654
655                 // faces
656                 size_t prim_totface = mp->getFaceCount();
657                 unsigned int *indices = mp->getPositionIndices().getData();
658                 unsigned int *nind    = mp->getNormalIndices().getData();
659
660                 bool mp_has_normals = primitive_has_useable_normals(mp);
661                 bool mp_has_faces   = primitive_has_faces(mp);
662
663                 int type = mp->getPrimitiveType();
664                 int index = 0;
665                 
666                 // since we cannot set mface->mat_nr here, we store a portion of me->mface in Primitive
667                 Primitive prim = {mface, 0};
668                 COLLADAFW::IndexListArray& index_list_array = mp->getUVCoordIndicesArray();
669
670 #ifdef COLLADA_DEBUG
671                 /*
672                    fprintf(stderr, "Primitive %d:\n", i);
673                    for (unsigned int j = 0; j < totuvset; j++) {
674                     print_index_list(*index_list_array[j]);
675                    }
676                  */
677 #endif
678                 
679                 if (type == COLLADAFW::MeshPrimitive::TRIANGLES) {
680                         for (unsigned int j = 0; j < prim_totface; j++) {
681                                 
682                                 set_face_indices(mface, indices, false);
683                                 indices += 3;
684
685 #if 0
686                                 for (unsigned int k = 0; k < totuvset; k++) {
687                                         if (!index_list_array.empty() && index_list_array[k]) {
688                                                 // get mtface by face index and uv set index
689                                                 MTFace *mtface = (MTFace *)CustomData_get_layer_n(&me->fdata, CD_MTFACE, k);
690                                                 set_face_uv(&mtface[face_index], uvs, k, *index_list_array[k], index, false);
691                                         }
692                                 }
693 #else
694                                 for (unsigned int k = 0; k < index_list_array.getCount(); k++) {
695                                         // get mtface by face index and uv set index
696                                         MTFace *mtface = (MTFace *)CustomData_get_layer_n(&me->fdata, CD_MTFACE, k);
697                                         set_face_uv(&mtface[face_index], uvs, *index_list_array[k], index, false);
698                                 }
699 #endif
700
701                                 test_index_face(mface, &me->fdata, face_index, 3);
702
703                                 if (mp_has_normals) {
704                                         if (!flat_face(nind, nor, 3))
705                                                 mface->flag |= ME_SMOOTH;
706
707                                         nind += 3;
708                                 }
709                                 
710                                 index += 3;
711                                 mface++;
712                                 face_index++;
713                                 prim.totface++;
714                         }
715                 }
716
717                 // If MeshPrimitive is TRIANGLE_FANS we split it into triangles
718                 // The first trifan vertex will be the first vertex in every triangle
719                 if (type == COLLADAFW::MeshPrimitive::TRIANGLE_FANS) {
720                         unsigned grouped_vertex_count = mp->getGroupedVertexElementsCount();
721                         for (unsigned int group_index = 0; group_index < grouped_vertex_count; group_index++) {
722                                 unsigned int first_vertex = indices[0]; // Store first trifan vertex
723                                 unsigned int first_normal = nind[0]; // Store first trifan vertex normal
724                                 unsigned int vertex_count = mp->getGroupedVerticesVertexCount(group_index);
725
726                                 for (unsigned int vertex_index = 0; vertex_index < vertex_count - 2; vertex_index++) {
727                                         // For each triangle store indeces of its 3 vertices
728                                         unsigned int triangle_vertex_indices[3] = {first_vertex, indices[1], indices[2]};
729                                         set_face_indices(mface, triangle_vertex_indices, false);
730                                         test_index_face(mface, &me->fdata, face_index, 3);
731
732                                         if (mp_has_normals) {  // vertex normals, same inplementation as for the triangles
733                                                 // the same for vertces normals
734                                                 unsigned int vertex_normal_indices[3] = {first_normal, nind[1], nind[2]};
735                                                 if (!flat_face(vertex_normal_indices, nor, 3))
736                                                         mface->flag |= ME_SMOOTH;
737                                                 nind++;
738                                         }
739                                 
740                                         mface++;  // same inplementation as for the triangles
741                                         indices++;
742                                         face_index++;
743                                         prim.totface++;
744                                 }
745
746                                 // Moving cursor  to the next triangle fan.
747                                 if (mp_has_normals)
748                                         nind += 2;
749
750                                 indices +=  2;
751                         }
752                 }
753                 else if (type == COLLADAFW::MeshPrimitive::POLYLIST || type == COLLADAFW::MeshPrimitive::POLYGONS) {
754                         COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons *)mp;
755                         COLLADAFW::Polygons::VertexCountArray& vcounta = mpvc->getGroupedVerticesVertexCountArray();
756
757                         for (unsigned int j = 0; j < prim_totface; j++) {
758                                 
759                                 // face
760                                 int vcount = vcounta[j];
761                                 if (vcount == 3 || vcount == 4) {
762                                         
763                                         set_face_indices(mface, indices, vcount == 4);
764                                         
765                                         // set mtface for each uv set
766                                         // it is assumed that all primitives have equal number of UV sets
767
768 #if 0
769                                         for (unsigned int k = 0; k < totuvset; k++) {
770                                                 if (!index_list_array.empty() && index_list_array[k]) {
771                                                         // get mtface by face index and uv set index
772                                                         MTFace *mtface = (MTFace *)CustomData_get_layer_n(&me->fdata, CD_MTFACE, k);
773                                                         set_face_uv(&mtface[face_index], uvs, k, *index_list_array[k], index, mface->v4 != 0);
774                                                 }
775                                         }
776 #else
777                                         for (unsigned int k = 0; k < index_list_array.getCount(); k++) {
778                                                 // get mtface by face index and uv set index
779                                                 MTFace *mtface = (MTFace *)CustomData_get_layer_n(&me->fdata, CD_MTFACE, k);
780                                                 set_face_uv(&mtface[face_index], uvs, *index_list_array[k], index, vcount == 4);
781                                         }
782 #endif
783
784                                         test_index_face(mface, &me->fdata, face_index, vcount);
785
786                                         if (mp_has_normals) {
787                                                 if (!flat_face(nind, nor, vcount))
788                                                         mface->flag |= ME_SMOOTH;
789
790                                                 nind += vcount;
791                                         }
792                                         
793                                         mface++;
794                                         face_index++;
795                                         prim.totface++;
796                                         
797                                 }
798                                 else {
799                                         std::vector<unsigned int> tri;
800                                         
801                                         triangulate_poly(indices, vcount, me->mvert, tri);
802
803                                         for (unsigned int k = 0; k < tri.size() / 3; k++) {
804                                                 int v = k * 3;
805                                                 unsigned int uv_indices[3] = {
806                                                         index + tri[v],
807                                                         index + tri[v + 1],
808                                                         index + tri[v + 2]
809                                                 };
810                                                 unsigned int tri_indices[3] = {
811                                                         indices[tri[v]],
812                                                         indices[tri[v + 1]],
813                                                         indices[tri[v + 2]]
814                                                 };
815
816                                                 set_face_indices(mface, tri_indices, false);
817                                                 
818 #if 0
819                                                 for (unsigned int l = 0; l < totuvset; l++) {
820                                                         if (!index_list_array.empty() && index_list_array[l]) {
821                                                                 // get mtface by face index and uv set index
822                                                                 MTFace *mtface = (MTFace *)CustomData_get_layer_n(&me->fdata, CD_MTFACE, l);
823                                                                 set_face_uv(&mtface[face_index], uvs, l, *index_list_array[l], uv_indices);
824                                                         }
825                                                 }
826 #else
827                                                 for (unsigned int l = 0; l < index_list_array.getCount(); l++) {
828                                                         int uvset_index = index_list_array[l]->getSetIndex();
829
830                                                         // get mtface by face index and uv set index
831                                                         MTFace *mtface = (MTFace *)CustomData_get_layer_n(&me->fdata, CD_MTFACE, uvset_index);
832                                                         set_face_uv(&mtface[face_index], uvs, *index_list_array[l], uv_indices);
833                                                 }
834 #endif
835
836
837                                                 test_index_face(mface, &me->fdata, face_index, 3);
838
839                                                 if (mp_has_normals) {
840                                                         unsigned int ntri[3] = {nind[tri[v]], nind[tri[v + 1]], nind[tri[v + 2]]};
841
842                                                         if (!flat_face(ntri, nor, 3))
843                                                                 mface->flag |= ME_SMOOTH;
844                                                 }
845                                                 
846                                                 mface++;
847                                                 face_index++;
848                                                 prim.totface++;
849                                         }
850
851                                         if (mp_has_normals)
852                                                 nind += vcount;
853                                 }
854
855                                 index += vcount;
856                                 indices += vcount;
857                         }
858                 }
859                 else if (type == COLLADAFW::MeshPrimitive::LINES) {
860                         continue; // read the lines later after all the rest is done
861                 }
862
863                 if (mp_has_faces)
864                         mat_prim_map[mp->getMaterialId()].push_back(prim);
865         }
866
867         geom_uid_mat_mapping_map[mesh->getUniqueId()] = mat_prim_map;
868 }
869
870 void MeshImporter::get_vector(float v[3], COLLADAFW::MeshVertexData& arr, int i, int stride)
871 {
872         i *= stride;
873         
874         switch (arr.getType()) {
875                 case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT:
876                 {
877                         COLLADAFW::ArrayPrimitiveType<float> *values = arr.getFloatValues();
878                         if (values->empty()) return;
879
880                         v[0] = (*values)[i++];
881                         v[1] = (*values)[i++];
882                         v[2] = (*values)[i];
883
884                 }
885                 break;
886                 case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE:
887                 {
888                         COLLADAFW::ArrayPrimitiveType<double> *values = arr.getDoubleValues();
889                         if (values->empty()) return;
890
891                         v[0] = (float)(*values)[i++];
892                         v[1] = (float)(*values)[i++];
893                         v[2] = (float)(*values)[i];
894                 }
895                 break;
896                 default:
897                         break;
898         }
899 }
900
901 bool MeshImporter::flat_face(unsigned int *nind, COLLADAFW::MeshVertexData& nor, int count)
902 {
903         float a[3], b[3];
904
905         get_vector(a, nor, *nind, 3);
906         normalize_v3(a);
907
908         nind++;
909
910         for (int i = 1; i < count; i++, nind++) {
911                 get_vector(b, nor, *nind, 3);
912                 normalize_v3(b);
913
914                 float dp = dot_v3v3(a, b);
915
916                 if (dp < 0.99999f || dp > 1.00001f)
917                         return false;
918         }
919
920         return true;
921 }
922
923 MeshImporter::MeshImporter(UnitConverter *unitconv, ArmatureImporter *arm, Scene *sce) : unitconverter(unitconv), scene(sce), armature_importer(arm) {
924 }
925
926 void MeshImporter::bmeshConversion()
927 {
928         for (std::map<COLLADAFW::UniqueId, Mesh *>::iterator m = uid_mesh_map.begin();
929              m != uid_mesh_map.end(); ++m)
930         {
931                 if ((*m).second) {
932                         Mesh *me = (*m).second;
933                         BKE_mesh_convert_mfaces_to_mpolys(me);
934                         BKE_mesh_tessface_clear(me);
935
936                         BKE_mesh_calc_normals_mapping(me->mvert, me->totvert, me->mloop, me->mpoly, me->totloop, me->totpoly, NULL, NULL, 0, NULL, NULL);
937                 }
938         }
939 }
940
941
942 Object *MeshImporter::get_object_by_geom_uid(const COLLADAFW::UniqueId& geom_uid)
943 {
944         if (uid_object_map.find(geom_uid) != uid_object_map.end())
945                 return uid_object_map[geom_uid];
946         return NULL;
947 }
948
949 MTex *MeshImporter::assign_textures_to_uvlayer(COLLADAFW::TextureCoordinateBinding &ctexture,
950                                                Mesh *me, TexIndexTextureArrayMap& texindex_texarray_map,
951                                                MTex *color_texture)
952 {
953         const COLLADAFW::TextureMapId texture_index = ctexture.getTextureMapId();
954         size_t setindex = ctexture.getSetIndex();
955         std::string uvname = ctexture.getSemantic();
956         
957         if (setindex == -1) return NULL;
958         
959         const CustomData *data = &me->fdata;
960         int layer_index = CustomData_get_layer_index(data, CD_MTFACE);
961
962         if (layer_index == -1) return NULL;
963
964         CustomDataLayer *cdl = &data->layers[layer_index + setindex];
965         
966         /* set uvname to bind_vertex_input semantic */
967         BLI_strncpy(cdl->name, uvname.c_str(), sizeof(cdl->name));
968
969         if (texindex_texarray_map.find(texture_index) == texindex_texarray_map.end()) {
970                 
971                 fprintf(stderr, "Cannot find texture array by texture index.\n");
972                 return color_texture;
973         }
974         
975         std::vector<MTex *> textures = texindex_texarray_map[texture_index];
976         
977         std::vector<MTex *>::iterator it;
978         
979         for (it = textures.begin(); it != textures.end(); it++) {
980                 
981                 MTex *texture = *it;
982                 
983                 if (texture) {
984                         BLI_strncpy(texture->uvname, uvname.c_str(), sizeof(texture->uvname));
985                         if (texture->mapto == MAP_COL) color_texture = texture;
986                 }
987         }
988         return color_texture;
989 }
990
991 /**
992  * this function checks if both objects have the same
993  * materials assigned to Object (in the same order)
994  * returns true if condition matches, otherwise false;
995  **/
996 static bool bc_has_same_material_configuration(Object *ob1, Object *ob2)
997 {
998         if (ob1->totcol != ob2->totcol) return false; // not same number of materials
999         if (ob1->totcol == 0) return false; // no material at all
1000         
1001         for (int index=0; index < ob1->totcol; index++) {
1002                 if (ob1->matbits[index] != ob2->matbits[index]) return false; // shouldn't happen
1003                 if (ob1->matbits[index] == 0) return false; // shouldn't happen
1004                 if (ob1->mat[index] != ob2->mat[index]) return false; // different material assignment
1005         }
1006         return true;
1007 }
1008
1009
1010 /**
1011  *
1012  * Caution here: This code assumes tha all materials are assigned to Object
1013  * and no material is assigned to Data.
1014  * That is true right after the objects have been imported.
1015  *
1016  **/
1017 static void bc_copy_materials_to_data(Object *ob, Mesh *me)
1018 {
1019         for (int index = 0; index < ob->totcol; index++) {
1020                 ob->matbits[index] = 0;
1021                 me->mat[index] = ob->mat[index];
1022         }
1023 }
1024
1025 /**
1026  *
1027  * Remove all references to materials from the object
1028  *
1029  **/
1030 static void bc_remove_materials_from_object(Object *ob, Mesh *me)
1031 {
1032         for (int index = 0; index < ob->totcol; index++) {
1033                 ob->matbits[index] = 0;
1034                 ob->mat[index] = NULL;
1035         }
1036 }
1037
1038 /**
1039  * Returns the list of Users of the given Mesh object.
1040  * Note: This function uses the object user flag to control
1041  * which objects have already been processed.
1042  **/
1043 std::vector<Object *> MeshImporter::get_all_users_of(Mesh *reference_mesh)
1044 {
1045         std::vector<Object *> mesh_users;
1046         for (std::vector<Object *>::iterator it = imported_objects.begin();
1047              it != imported_objects.end(); ++it)
1048         {
1049                 Object *ob = (*it);
1050                 if (bc_is_marked(ob)) {
1051                         bc_remove_mark(ob);
1052                         Mesh *me = (Mesh *) ob->data;
1053                         if (me == reference_mesh)
1054                                 mesh_users.push_back(ob);
1055                 }
1056         }
1057         return mesh_users;
1058 }
1059
1060 /**
1061  *
1062  * During import all materials have been assigned to Object.
1063  * Now we iterate over the imported objects and optimize
1064  * the assignments as follows:
1065  *
1066  * for each imported geometry:
1067  *     if number of users is 1:
1068  *         get the user (object)
1069  *         move the materials from Object to Data
1070  *     else:
1071  *         determine which materials are assigned to the first user
1072  *         check if all other users have the same materials in the same order
1073  *         if the check is positive:
1074  *             Add the materials of the first user to the geometry
1075  *             adjust all other users accordingly.
1076  *
1077  **/
1078 void MeshImporter::optimize_material_assignments()
1079 {
1080         for (std::vector<Object *>::iterator it = imported_objects.begin();
1081              it != imported_objects.end(); ++it)
1082         {
1083                 Object *ob = (*it);
1084                 Mesh *me = (Mesh *) ob->data;
1085                 if (me->id.us==1) {
1086                         bc_copy_materials_to_data(ob,me);
1087                         bc_remove_materials_from_object(ob,me);
1088                         bc_remove_mark(ob);
1089                 }
1090                 else if (me->id.us > 1)
1091                 {
1092                         bool can_move = true;
1093                         std::vector<Object *> mesh_users = get_all_users_of(me);
1094                         if (mesh_users.size() > 1)
1095                         {
1096                                 Object *ref_ob = mesh_users[0];
1097                                 for (int index = 1; index < mesh_users.size(); index++) {
1098                                         if (!bc_has_same_material_configuration(ref_ob, mesh_users[index])) {
1099                                                 can_move = false;
1100                                                 break;
1101                                         }
1102                                 }
1103                                 if (can_move) {
1104                                         bc_copy_materials_to_data(ref_ob,me);
1105                                         for (int index = 0; index < mesh_users.size(); index++) {
1106                                                 Object *object = mesh_users[index];
1107                                                 bc_remove_materials_from_object(object,me);
1108                                                 bc_remove_mark(object);
1109                                         }
1110                                 }
1111                         }
1112                 }
1113         }
1114 }
1115
1116 /**
1117  * We do not know in advance which objects will share geometries.
1118  * And we do not know either if the objects which share geometries
1119  * come along with different materials. So we first create the objects
1120  * and assign the materials to Object, then in a later cleanup we decide
1121  * which materials shall be moved to the created geometries. Also see
1122  * optimize_material_assignments() above.
1123  */
1124 MTFace *MeshImporter::assign_material_to_geom(COLLADAFW::MaterialBinding cmaterial,
1125                                               std::map<COLLADAFW::UniqueId, Material *>& uid_material_map,
1126                                               Object *ob, const COLLADAFW::UniqueId *geom_uid,
1127                                               MTex **color_texture, char *layername, MTFace *texture_face,
1128                                               std::map<Material *, TexIndexTextureArrayMap>& material_texture_mapping_map, short mat_index)
1129 {
1130         Mesh *me = (Mesh *)ob->data;
1131         const COLLADAFW::UniqueId& ma_uid = cmaterial.getReferencedMaterial();
1132         
1133         // do we know this material?
1134         if (uid_material_map.find(ma_uid) == uid_material_map.end()) {
1135                 
1136                 fprintf(stderr, "Cannot find material by UID.\n");
1137                 return NULL;
1138         }
1139
1140         // first time we get geom_uid, ma_uid pair. Save for later check.
1141         materials_mapped_to_geom.insert(std::pair<COLLADAFW::UniqueId, COLLADAFW::UniqueId>(*geom_uid, ma_uid));
1142         
1143         Material *ma = uid_material_map[ma_uid];
1144
1145         // Attention! This temporaly assigns material to object on purpose!
1146         // See note above.
1147         ob->actcol=0;
1148         assign_material(ob, ma, mat_index + 1, BKE_MAT_ASSIGN_OBJECT); 
1149         
1150         COLLADAFW::TextureCoordinateBindingArray& tex_array = 
1151             cmaterial.getTextureCoordinateBindingArray();
1152         TexIndexTextureArrayMap texindex_texarray_map = material_texture_mapping_map[ma];
1153         unsigned int i;
1154         // loop through <bind_vertex_inputs>
1155         for (i = 0; i < tex_array.getCount(); i++) {
1156                 
1157                 *color_texture = assign_textures_to_uvlayer(tex_array[i], me, texindex_texarray_map,
1158                                                             *color_texture);
1159         }
1160         
1161         // set texture face
1162         if (*color_texture &&
1163             strlen((*color_texture)->uvname) &&
1164             strcmp(layername, (*color_texture)->uvname) != 0) {
1165                 texture_face = (MTFace *)CustomData_get_layer_named(&me->fdata, CD_MTFACE,
1166                                                                     (*color_texture)->uvname);
1167                 strcpy(layername, (*color_texture)->uvname);
1168         }
1169         
1170         MaterialIdPrimitiveArrayMap& mat_prim_map = geom_uid_mat_mapping_map[*geom_uid];
1171         COLLADAFW::MaterialId mat_id = cmaterial.getMaterialId();
1172         
1173         // assign material indices to mesh faces
1174         if (mat_prim_map.find(mat_id) != mat_prim_map.end()) {
1175                 
1176                 std::vector<Primitive>& prims = mat_prim_map[mat_id];
1177                 
1178                 std::vector<Primitive>::iterator it;
1179                 
1180                 for (it = prims.begin(); it != prims.end(); it++) {
1181                         Primitive& prim = *it;
1182                         MFace *mface = prim.mface;
1183
1184                         for (i = 0; i < prim.totface; i++, mface++) {
1185                                 mface->mat_nr = mat_index;
1186                                 // bind texture images to faces
1187                                 if (texture_face && (*color_texture)) {
1188                                         texture_face->tpage = (Image *)(*color_texture)->tex->ima;
1189                                         texture_face++;
1190                                 }
1191                         }
1192                 }
1193         }
1194         
1195         return texture_face;
1196 }
1197
1198 Object *MeshImporter::create_mesh_object(COLLADAFW::Node *node, COLLADAFW::InstanceGeometry *geom,
1199                                          bool isController,
1200                                          std::map<COLLADAFW::UniqueId, Material *>& uid_material_map,
1201                                          std::map<Material *, TexIndexTextureArrayMap>& material_texture_mapping_map)
1202 {
1203         const COLLADAFW::UniqueId *geom_uid = &geom->getInstanciatedObjectId();
1204         
1205         // check if node instanciates controller or geometry
1206         if (isController) {
1207                 
1208                 geom_uid = armature_importer->get_geometry_uid(*geom_uid);
1209                 
1210                 if (!geom_uid) {
1211                         fprintf(stderr, "Couldn't find a mesh UID by controller's UID.\n");
1212                         return NULL;
1213                 }
1214         }
1215         else {
1216                 
1217                 if (uid_mesh_map.find(*geom_uid) == uid_mesh_map.end()) {
1218                         // this could happen if a mesh was not created
1219                         // (e.g. if it contains unsupported geometry)
1220                         fprintf(stderr, "Couldn't find a mesh by UID.\n");
1221                         return NULL;
1222                 }
1223         }
1224         if (!uid_mesh_map[*geom_uid]) return NULL;
1225         
1226         // name Object
1227         const std::string& id = node->getName().size() ? node->getName() : node->getOriginalId();
1228         const char *name = (id.length()) ? id.c_str() : NULL;
1229         
1230         // add object
1231         Object *ob = bc_add_object(scene, OB_MESH, name);
1232         bc_set_mark(ob); // used later for material assignement optimization
1233
1234
1235         // store object pointer for ArmatureImporter
1236         uid_object_map[*geom_uid] = ob;
1237         imported_objects.push_back(ob);
1238         
1239         // replace ob->data freeing the old one
1240         Mesh *old_mesh = (Mesh *)ob->data;
1241
1242         set_mesh(ob, uid_mesh_map[*geom_uid]);
1243         
1244         if (old_mesh->id.us == 0) BKE_libblock_free(&G.main->mesh, old_mesh);
1245         
1246         char layername[100];
1247         layername[0] = '\0';
1248         MTFace *texture_face = NULL;
1249         MTex *color_texture = NULL;
1250         
1251         COLLADAFW::MaterialBindingArray& mat_array =
1252             geom->getMaterialBindings();
1253         
1254         // loop through geom's materials
1255         for (unsigned int i = 0; i < mat_array.getCount(); i++) {
1256                 
1257                 if (mat_array[i].getReferencedMaterial().isValid()) {
1258                         texture_face = assign_material_to_geom(mat_array[i], uid_material_map, ob, geom_uid,
1259                                                                &color_texture, layername, texture_face,
1260                                                                material_texture_mapping_map, i);
1261                 }
1262                 else {
1263                         fprintf(stderr, "invalid referenced material for %s\n", mat_array[i].getName().c_str());
1264                 }
1265         }
1266
1267         return ob;
1268 }
1269
1270 // create a mesh storing a pointer in a map so it can be retrieved later by geometry UID
1271 bool MeshImporter::write_geometry(const COLLADAFW::Geometry *geom)
1272 {
1273         // TODO: import also uvs, normals
1274         // XXX what to do with normal indices?
1275         // XXX num_normals may be != num verts, then what to do?
1276
1277         // check geometry->getType() first
1278         if (geom->getType() != COLLADAFW::Geometry::GEO_TYPE_MESH) {
1279                 // TODO: report warning
1280                 fprintf(stderr, "Mesh type %s is not supported\n", bc_geomTypeToStr(geom->getType()));
1281                 return true;
1282         }
1283         
1284         COLLADAFW::Mesh *mesh = (COLLADAFW::Mesh *)geom;
1285         
1286         if (!is_nice_mesh(mesh)) {
1287                 fprintf(stderr, "Ignoring mesh %s\n", bc_get_dae_name(mesh));
1288                 return true;
1289         }
1290         
1291         const std::string& str_geom_id = mesh->getName().size() ? mesh->getName() : mesh->getOriginalId();
1292         Mesh *me = BKE_mesh_add((char *)str_geom_id.c_str());
1293         me->id.us--; // is already 1 here, but will be set later in set_mesh
1294
1295         // store the Mesh pointer to link it later with an Object
1296         this->uid_mesh_map[mesh->getUniqueId()] = me;
1297         
1298         int new_tris = 0;
1299         
1300         read_vertices(mesh, me);
1301
1302         new_tris = count_new_tris(mesh, me);
1303         
1304         read_faces(mesh, me, new_tris);
1305
1306         BKE_mesh_make_edges(me, 0);
1307
1308         // read_lines() must be called after the face edges have been generated.
1309         // Oterwise the loose edges will be silently deleted again.
1310         read_lines(mesh, me);
1311
1312         return true;
1313 }