svn merge ^/trunk/blender -r43530:43554
[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
56 #include "MEM_guardedalloc.h"
57 }
58
59 #include "ArmatureImporter.h"
60 #include "MeshImporter.h"
61 #include "collada_utils.h"
62
63 // get node name, or fall back to original id if not present (name is optional)
64 template<class T>
65 static const char *bc_get_dae_name(T *node)
66 {
67         const std::string& name = node->getName();
68         return name.size() ? name.c_str() : node->getOriginalId().c_str();
69 }
70
71 static const char *bc_primTypeToStr(COLLADAFW::MeshPrimitive::PrimitiveType type)
72 {
73         switch (type) {
74         case COLLADAFW::MeshPrimitive::LINES:
75                 return "LINES";
76         case COLLADAFW::MeshPrimitive::LINE_STRIPS:
77                 return "LINESTRIPS";
78         case COLLADAFW::MeshPrimitive::POLYGONS:
79                 return "POLYGONS";
80         case COLLADAFW::MeshPrimitive::POLYLIST:
81                 return "POLYLIST";
82         case COLLADAFW::MeshPrimitive::TRIANGLES:
83                 return "TRIANGLES";
84         case COLLADAFW::MeshPrimitive::TRIANGLE_FANS:
85                 return "TRIANGLE_FANS";
86         case COLLADAFW::MeshPrimitive::TRIANGLE_STRIPS:
87                 return "TRIANGLE_FANS";
88         case COLLADAFW::MeshPrimitive::POINTS:
89                 return "POINTS";
90         case COLLADAFW::MeshPrimitive::UNDEFINED_PRIMITIVE_TYPE:
91                 return "UNDEFINED_PRIMITIVE_TYPE";
92         }
93         return "UNKNOWN";
94 }
95
96 static const char *bc_geomTypeToStr(COLLADAFW::Geometry::GeometryType type)
97 {
98         switch (type) {
99         case COLLADAFW::Geometry::GEO_TYPE_MESH:
100                 return "MESH";
101         case COLLADAFW::Geometry::GEO_TYPE_SPLINE:
102                 return "SPLINE";
103         case COLLADAFW::Geometry::GEO_TYPE_CONVEX_MESH:
104                 return "CONVEX_MESH";
105         case COLLADAFW::Geometry::GEO_TYPE_UNKNOWN:
106         default:
107                 return "UNKNOWN";
108         }
109 }
110
111
112 UVDataWrapper::UVDataWrapper(COLLADAFW::MeshVertexData& vdata) : mVData(&vdata)
113 {}
114
115 #ifdef COLLADA_DEBUG
116 void WVDataWrapper::print()
117 {
118         fprintf(stderr, "UVs:\n");
119         switch(mVData->getType()) {
120         case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT:
121                 {
122                         COLLADAFW::ArrayPrimitiveType<float>* values = mVData->getFloatValues();
123                         if (values->getCount()) {
124                                 for (int i = 0; i < values->getCount(); i += 2) {
125                                         fprintf(stderr, "%.1f, %.1f\n", (*values)[i], (*values)[i+1]);
126                                 }
127                         }
128                 }
129                 break;
130         case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE:
131                 {
132                         COLLADAFW::ArrayPrimitiveType<double>* values = mVData->getDoubleValues();
133                         if (values->getCount()) {
134                                 for (int i = 0; i < values->getCount(); i += 2) {
135                                         fprintf(stderr, "%.1f, %.1f\n", (float)(*values)[i], (float)(*values)[i+1]);
136                                 }
137                         }
138                 }
139                 break;
140         }
141         fprintf(stderr, "\n");
142 }
143 #endif
144
145 void UVDataWrapper::getUV(int uv_index, float *uv)
146 {
147         int stride = mVData->getStride(0);
148         if(stride==0) stride = 2;
149
150         switch(mVData->getType()) {
151         case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT:
152                 {
153                         COLLADAFW::ArrayPrimitiveType<float>* values = mVData->getFloatValues();
154                         if (values->empty()) return;
155                         uv[0] = (*values)[uv_index*stride];
156                         uv[1] = (*values)[uv_index*stride + 1];
157                         
158                 }
159                 break;
160         case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE:
161                 {
162                         COLLADAFW::ArrayPrimitiveType<double>* values = mVData->getDoubleValues();
163                         if (values->empty()) return;
164                         uv[0] = (float)(*values)[uv_index*stride];
165                         uv[1] = (float)(*values)[uv_index*stride + 1];
166                         
167                 }
168                 break;
169         case COLLADAFW::MeshVertexData::DATA_TYPE_UNKNOWN:
170         default:
171                 fprintf(stderr, "MeshImporter.getUV(): unknown data type\n");
172         }
173 }
174
175 void MeshImporter::set_face_indices(MFace *mface, unsigned int *indices, bool quad)
176 {
177         mface->v1 = indices[0];
178         mface->v2 = indices[1];
179         mface->v3 = indices[2];
180         if (quad) mface->v4 = indices[3];
181         else mface->v4 = 0;
182 #ifdef COLLADA_DEBUG
183         // fprintf(stderr, "%u, %u, %u \n", indices[0], indices[1], indices[2]);
184 #endif
185 }
186
187 // not used anymore, test_index_face from blenkernel is better
188 #if 0
189 // change face indices order so that v4 is not 0
190 void MeshImporter::rotate_face_indices(MFace *mface)
191 {
192         mface->v4 = mface->v1;
193         mface->v1 = mface->v2;
194         mface->v2 = mface->v3;
195         mface->v3 = 0;
196 }
197 #endif
198
199 void MeshImporter::set_face_uv(MTFace *mtface, UVDataWrapper &uvs,
200                                  COLLADAFW::IndexList& index_list, unsigned int *tris_indices)
201 {
202         // per face vertex indices, this means for quad we have 4 indices, not 8
203         COLLADAFW::UIntValuesArray& indices = index_list.getIndices();
204
205         uvs.getUV(indices[tris_indices[0]], mtface->uv[0]);
206         uvs.getUV(indices[tris_indices[1]], mtface->uv[1]);
207         uvs.getUV(indices[tris_indices[2]], mtface->uv[2]);
208 }
209
210 void MeshImporter::set_face_uv(MTFace *mtface, UVDataWrapper &uvs,
211                                 COLLADAFW::IndexList& index_list, int index, bool quad)
212 {
213         // per face vertex indices, this means for quad we have 4 indices, not 8
214         COLLADAFW::UIntValuesArray& indices = index_list.getIndices();
215
216         uvs.getUV(indices[index + 0], mtface->uv[0]);
217         uvs.getUV(indices[index + 1], mtface->uv[1]);
218         uvs.getUV(indices[index + 2], mtface->uv[2]);
219
220         if (quad) uvs.getUV(indices[index + 3], mtface->uv[3]);
221
222 #ifdef COLLADA_DEBUG
223         if (quad) {
224                 fprintf(stderr, "face uv:\n"
225                                 "((%d, %d, %d, %d))\n"
226                                 "((%.1f, %.1f), (%.1f, %.1f), (%.1f, %.1f), (%.1f, %.1f))\n",
227
228                                 indices[index + 0],
229                                 indices[index + 1],
230                                 indices[index + 2],
231                                 indices[index + 3],
232
233                                 mtface->uv[0][0], mtface->uv[0][1],
234                                 mtface->uv[1][0], mtface->uv[1][1],
235                                 mtface->uv[2][0], mtface->uv[2][1],
236                                 mtface->uv[3][0], mtface->uv[3][1]);
237         }
238         else {
239                 fprintf(stderr, "face uv:\n"
240                                 "((%d, %d, %d))\n"
241                                 "((%.1f, %.1f), (%.1f, %.1f), (%.1f, %.1f))\n",
242
243                                 indices[index + 0],
244                                 indices[index + 1],
245                                 indices[index + 2],
246
247                                 mtface->uv[0][0], mtface->uv[0][1],
248                                 mtface->uv[1][0], mtface->uv[1][1],
249                                 mtface->uv[2][0], mtface->uv[2][1]);
250         }
251 #endif
252 }
253
254 #ifdef COLLADA_DEBUG
255 void MeshImporter::print_index_list(COLLADAFW::IndexList& index_list)
256 {
257         fprintf(stderr, "Index list for \"%s\":\n", index_list.getName().c_str());
258         for (int i = 0; i < index_list.getIndicesCount(); i += 2) {
259                 fprintf(stderr, "%u, %u\n", index_list.getIndex(i), index_list.getIndex(i + 1));
260         }
261         fprintf(stderr, "\n");
262 }
263 #endif
264
265 bool MeshImporter::is_nice_mesh(COLLADAFW::Mesh *mesh)  // checks if mesh has supported primitive types: polylist, triangles, triangle_fans
266 {
267         COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives();
268
269         const char *name = bc_get_dae_name(mesh);
270         
271         for (unsigned i = 0; i < prim_arr.getCount(); i++) {
272                 
273                 COLLADAFW::MeshPrimitive *mp = prim_arr[i];
274                 COLLADAFW::MeshPrimitive::PrimitiveType type = mp->getPrimitiveType();
275
276                 const char *type_str = bc_primTypeToStr(type);
277                 
278                 // OpenCollada passes POLYGONS type for <polylist>
279                 if (type == COLLADAFW::MeshPrimitive::POLYLIST || type == COLLADAFW::MeshPrimitive::POLYGONS) {
280
281                         COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons*)mp;
282                         COLLADAFW::Polygons::VertexCountArray& vca = mpvc->getGroupedVerticesVertexCountArray();
283                         
284                         for(unsigned int j = 0; j < vca.getCount(); j++){
285                                 int count = vca[j];
286                                 if (count < 3) {
287                                         fprintf(stderr, "Primitive %s in %s has at least one face with vertex count < 3\n",
288                                                         type_str, name);
289                                         return false;
290                                 }
291                         }
292                                 
293                 }
294                 else if(type != COLLADAFW::MeshPrimitive::TRIANGLES && type!= COLLADAFW::MeshPrimitive::TRIANGLE_FANS) {
295                         fprintf(stderr, "Primitive type %s is not supported.\n", type_str);
296                         return false;
297                 }
298         }
299         
300         if (mesh->getPositions().empty()) {
301                 fprintf(stderr, "Mesh %s has no vertices.\n", name);
302                 return false;
303         }
304
305         return true;
306 }
307
308 void MeshImporter::read_vertices(COLLADAFW::Mesh *mesh, Mesh *me)
309 {
310         // vertices
311         COLLADAFW::MeshVertexData& pos = mesh->getPositions();
312         int stride = pos.getStride(0);
313         if(stride==0) stride = 3;
314         
315         me->totvert = mesh->getPositions().getFloatValues()->getCount() / stride;
316         me->mvert = (MVert*)CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, me->totvert);
317
318         MVert *mvert;
319         int i;
320
321         for (i = 0, mvert = me->mvert; i < me->totvert; i++, mvert++) {
322                 get_vector(mvert->co, pos, i, stride);
323         }
324 }
325
326 int MeshImporter::triangulate_poly(unsigned int *indices, int totvert, MVert *verts, std::vector<unsigned int>& tri)
327 {
328         ListBase dispbase;
329         DispList *dl;
330         float *vert;
331         int i = 0;
332         
333         dispbase.first = dispbase.last = NULL;
334         
335         dl = (DispList*)MEM_callocN(sizeof(DispList), "poly disp");
336         dl->nr = totvert;
337         dl->type = DL_POLY;
338         dl->parts = 1;
339         dl->verts = vert = (float*)MEM_callocN(totvert * 3 * sizeof(float), "poly verts");
340         dl->index = (int*)MEM_callocN(sizeof(int) * 3 * totvert, "dl index");
341
342         BLI_addtail(&dispbase, dl);
343         
344         for (i = 0; i < totvert; i++) {
345                 copy_v3_v3(vert, verts[indices[i]].co);
346                 vert += 3;
347         }
348         
349         filldisplist(&dispbase, &dispbase, 0);
350
351         int tottri = 0;
352         dl= (DispList*)dispbase.first;
353
354         if (dl->type == DL_INDEX3) {
355                 tottri = dl->parts;
356
357                 int *index = dl->index;
358                 for (i= 0; i < tottri; i++) {
359                         int t[3]= {*index, *(index + 1), *(index + 2)};
360
361                         std::sort(t, t + 3);
362
363                         tri.push_back(t[0]);
364                         tri.push_back(t[1]);
365                         tri.push_back(t[2]);
366
367                         index += 3;
368                 }
369         }
370
371         freedisplist(&dispbase);
372
373         return tottri;
374 }
375
376 int MeshImporter::count_new_tris(COLLADAFW::Mesh *mesh, Mesh *me)
377 {
378         COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives();
379         unsigned int i;
380         int tottri = 0;
381         
382         for (i = 0; i < prim_arr.getCount(); i++) {
383                 
384                 COLLADAFW::MeshPrimitive *mp = prim_arr[i];
385                 int type = mp->getPrimitiveType();
386                 size_t prim_totface = mp->getFaceCount();
387                 unsigned int *indices = mp->getPositionIndices().getData();
388                 
389                 if (type == COLLADAFW::MeshPrimitive::POLYLIST ||
390                         type == COLLADAFW::MeshPrimitive::POLYGONS) {
391                         
392                         COLLADAFW::Polygons *mpvc =     (COLLADAFW::Polygons*)mp;
393                         COLLADAFW::Polygons::VertexCountArray& vcounta = mpvc->getGroupedVerticesVertexCountArray();
394                         
395                         for (unsigned int j = 0; j < prim_totface; j++) {
396                                 int vcount = vcounta[j];
397                                 
398                                 if (vcount > 4) {
399                                         std::vector<unsigned int> tri;
400                                         
401                                         // tottri += triangulate_poly(indices, vcount, me->mvert, tri) - 1; // XXX why - 1?!
402                                         tottri += triangulate_poly(indices, vcount, me->mvert, tri);
403                                 }
404
405                                 indices += vcount;
406                         }
407                 }
408         }
409         return tottri;
410 }
411
412 // TODO: import uv set names
413 void MeshImporter::read_faces(COLLADAFW::Mesh *mesh, Mesh *me, int new_tris) //TODO:: Refactor. Possibly replace by iterators
414 {
415         unsigned int i;
416         
417         // allocate faces
418         me->totface = mesh->getFacesCount() + new_tris;
419         me->mface = (MFace*)CustomData_add_layer(&me->fdata, CD_MFACE, CD_CALLOC, NULL, me->totface);
420         
421         // allocate UV Maps
422         unsigned int totuvset = mesh->getUVCoords().getInputInfosArray().getCount();
423
424         for (i = 0; i < totuvset; i++) {
425                 if (mesh->getUVCoords().getLength(i) == 0) {
426                         totuvset = 0;
427                         break;
428                 }
429         }
430
431         for (i = 0; i < totuvset; i++) {
432                 COLLADAFW::MeshVertexData::InputInfos *info = mesh->getUVCoords().getInputInfosArray()[i];
433                 CustomData_add_layer_named(&me->fdata, CD_MTFACE, CD_CALLOC, NULL, me->totface, info->mName.c_str());
434                 //this->set_layername_map[i] = CustomData_get_layer_name(&me->fdata, CD_MTFACE, i);
435         }
436
437         // activate the first uv map
438         if (totuvset) me->mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, 0);
439
440         UVDataWrapper uvs(mesh->getUVCoords());
441
442 #ifdef COLLADA_DEBUG
443         // uvs.print();
444 #endif
445
446         MFace *mface = me->mface;
447
448         MaterialIdPrimitiveArrayMap mat_prim_map;
449
450         int face_index = 0;
451
452         COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives();
453
454         bool has_normals = mesh->hasNormals();
455         COLLADAFW::MeshVertexData& nor = mesh->getNormals();
456
457         for (i = 0; i < prim_arr.getCount(); i++) {
458                 
459                 COLLADAFW::MeshPrimitive *mp = prim_arr[i];
460
461                 // faces
462                 size_t prim_totface = mp->getFaceCount();
463                 unsigned int *indices = mp->getPositionIndices().getData();
464                 unsigned int *nind = mp->getNormalIndices().getData();
465
466                 if (has_normals && mp->getPositionIndices().getCount() != mp->getNormalIndices().getCount()) {
467                         fprintf(stderr, "Warning: Number of normals is different from the number of vertcies, skipping normals\n");
468                         has_normals = false;
469                 }
470
471                 unsigned int j, k;
472                 int type = mp->getPrimitiveType();
473                 int index = 0;
474                 
475                 // since we cannot set mface->mat_nr here, we store a portion of me->mface in Primitive
476                 Primitive prim = {mface, 0};
477                 COLLADAFW::IndexListArray& index_list_array = mp->getUVCoordIndicesArray();
478
479 #ifdef COLLADA_DEBUG
480                 /*
481                 fprintf(stderr, "Primitive %d:\n", i);
482                 for (int j = 0; j < totuvset; j++) {
483                         print_index_list(*index_list_array[j]);
484                 }
485                 */
486 #endif
487                 
488                 if (type == COLLADAFW::MeshPrimitive::TRIANGLES) {
489                         for (j = 0; j < prim_totface; j++){
490                                 
491                                 set_face_indices(mface, indices, false);
492                                 indices += 3;
493
494 #if 0
495                                 for (k = 0; k < totuvset; k++) {
496                                         if (!index_list_array.empty() && index_list_array[k]) {
497                                                 // get mtface by face index and uv set index
498                                                 MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, k);
499                                                 set_face_uv(&mtface[face_index], uvs, k, *index_list_array[k], index, false);
500                                         }
501                                 }
502 #else
503                                 for (k = 0; k < index_list_array.getCount(); k++) {
504                                         // get mtface by face index and uv set index
505                                         MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, k);
506                                         set_face_uv(&mtface[face_index], uvs, *index_list_array[k], index, false);
507                                 }
508 #endif
509
510                                 test_index_face(mface, &me->fdata, face_index, 3);
511
512                                 if (has_normals) {
513                                         if (!flat_face(nind, nor, 3))
514                                                 mface->flag |= ME_SMOOTH;
515
516                                         nind += 3;
517                                 }
518                                 
519                                 index += 3;
520                                 mface++;
521                                 face_index++;
522                                 prim.totface++;
523                         }
524                 }
525
526                 // If MeshPrimitive is TRIANGLE_FANS we split it into triangles
527                 // The first trifan vertex will be the first vertex in every triangle
528                 if (type == COLLADAFW::MeshPrimitive::TRIANGLE_FANS) {
529                         unsigned grouped_vertex_count = mp->getGroupedVertexElementsCount();
530                         for (unsigned int group_index = 0; group_index < grouped_vertex_count; group_index++){
531                                 unsigned int first_vertex = indices[0]; // Store first trifan vertex
532                                 unsigned int first_normal = nind[0]; // Store first trifan vertex normal
533                                 unsigned int vertex_count = mp->getGroupedVerticesVertexCount(group_index);
534
535                                 for (unsigned int vertex_index = 0; vertex_index < vertex_count - 2; vertex_index++){
536                                         // For each triangle store indeces of its 3 vertices
537                                         unsigned int triangle_vertex_indices[3]={first_vertex, indices[1], indices[2]};
538                                         set_face_indices(mface, triangle_vertex_indices, false);
539                                         test_index_face(mface, &me->fdata, face_index, 3);
540
541                                         if (has_normals) {  // vertex normals, same inplementation as for the triangles
542                                                 // the same for vertces normals
543                                                 unsigned int vertex_normal_indices[3]={first_normal, nind[1], nind[2]};
544                                                 if (!flat_face(vertex_normal_indices, nor, 3))
545                                                         mface->flag |= ME_SMOOTH;
546                                                         nind++;
547                                                 }
548
549                                                 mface++;        // same inplementation as for the triangles
550                                                 indices++;
551                                                 face_index++;
552                                                 prim.totface++;
553                                         }
554                                 
555                                 // Moving cursor  to the next triangle fan.
556                                 if (has_normals)
557                                         nind += 2;
558
559                                 indices +=  2;
560                         }
561                 }
562                 else if (type == COLLADAFW::MeshPrimitive::POLYLIST || type == COLLADAFW::MeshPrimitive::POLYGONS) {
563                         COLLADAFW::Polygons *mpvc =     (COLLADAFW::Polygons*)mp;
564                         COLLADAFW::Polygons::VertexCountArray& vcounta = mpvc->getGroupedVerticesVertexCountArray();
565                         
566                         for (j = 0; j < prim_totface; j++) {
567                                 
568                                 // face
569                                 int vcount = vcounta[j];
570                                 if (vcount == 3 || vcount == 4) {
571                                         
572                                         set_face_indices(mface, indices, vcount == 4);
573                                         
574                                         // set mtface for each uv set
575                                         // it is assumed that all primitives have equal number of UV sets
576                                         
577 #if 0
578                                         for (k = 0; k < totuvset; k++) {
579                                                 if (!index_list_array.empty() && index_list_array[k]) {
580                                                         // get mtface by face index and uv set index
581                                                         MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, k);
582                                                         set_face_uv(&mtface[face_index], uvs, k, *index_list_array[k], index, mface->v4 != 0);
583                                                 }
584                                         }
585 #else
586                                         for (k = 0; k < index_list_array.getCount(); k++) {
587                                                 // get mtface by face index and uv set index
588                                                 MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, k);
589                                                 set_face_uv(&mtface[face_index], uvs, *index_list_array[k], index, vcount == 4);
590                                         }
591 #endif
592
593                                         test_index_face(mface, &me->fdata, face_index, vcount);
594
595                                         if (has_normals) {
596                                                 if (!flat_face(nind, nor, vcount))
597                                                         mface->flag |= ME_SMOOTH;
598
599                                                 nind += vcount;
600                                         }
601                                         
602                                         mface++;
603                                         face_index++;
604                                         prim.totface++;
605                                         
606                                 }
607                                 else {
608                                         std::vector<unsigned int> tri;
609                                         
610                                         triangulate_poly(indices, vcount, me->mvert, tri);
611                                         
612                                         for (k = 0; k < tri.size() / 3; k++) {
613                                                 int v = k * 3;
614                                                 unsigned int uv_indices[3] = {
615                                                         index + tri[v],
616                                                         index + tri[v + 1],
617                                                         index + tri[v + 2]
618                                                 };
619                                                 unsigned int tri_indices[3] = {
620                                                         indices[tri[v]],
621                                                         indices[tri[v + 1]],
622                                                         indices[tri[v + 2]]
623                                                 };
624
625                                                 set_face_indices(mface, tri_indices, false);
626                                                 
627 #if 0
628                                                 for (unsigned int l = 0; l < totuvset; l++) {
629                                                         if (!index_list_array.empty() && index_list_array[l]) {
630                                                                 // get mtface by face index and uv set index
631                                                                 MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, l);
632                                                                 set_face_uv(&mtface[face_index], uvs, l, *index_list_array[l], uv_indices);
633                                                         }
634                                                 }
635 #else
636                                                 for (unsigned int l = 0; l < index_list_array.getCount(); l++) {
637                                                         int uvset_index = index_list_array[l]->getSetIndex();
638
639                                                         // get mtface by face index and uv set index
640                                                         MTFace *mtface = (MTFace*)CustomData_get_layer_n(&me->fdata, CD_MTFACE, uvset_index);
641                                                         set_face_uv(&mtface[face_index], uvs, *index_list_array[l], uv_indices);
642                                                 }
643 #endif
644
645
646                                                 test_index_face(mface, &me->fdata, face_index, 3);
647
648                                                 if (has_normals) {
649                                                         unsigned int ntri[3] = {nind[tri[v]], nind[tri[v + 1]], nind[tri[v + 2]]};
650
651                                                         if (!flat_face(ntri, nor, 3))
652                                                                 mface->flag |= ME_SMOOTH;
653                                                 }
654                                                 
655                                                 mface++;
656                                                 face_index++;
657                                                 prim.totface++;
658                                         }
659
660                                         if (has_normals)
661                                                 nind += vcount;
662                                 }
663
664                                 index += vcount;
665                                 indices += vcount;
666                         }
667                 }
668                 
669                 mat_prim_map[mp->getMaterialId()].push_back(prim);
670         }
671
672         geom_uid_mat_mapping_map[mesh->getUniqueId()] = mat_prim_map;
673 }
674
675 void MeshImporter::get_vector(float v[3], COLLADAFW::MeshVertexData& arr, int i, int stride)
676 {
677         i *= stride;
678         
679         switch(arr.getType()) {
680         case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT:
681                 {
682                         COLLADAFW::ArrayPrimitiveType<float>* values = arr.getFloatValues();
683                         if (values->empty()) return;
684
685                         v[0] = (*values)[i++];
686                         v[1] = (*values)[i++];
687                         v[2] = (*values)[i];
688
689                 }
690                 break;
691         case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE:
692                 {
693                         COLLADAFW::ArrayPrimitiveType<double>* values = arr.getDoubleValues();
694                         if (values->empty()) return;
695
696                         v[0] = (float)(*values)[i++];
697                         v[1] = (float)(*values)[i++];
698                         v[2] = (float)(*values)[i];
699                 }
700                 break;
701         default:
702                 break;
703         }
704 }
705
706 bool MeshImporter::flat_face(unsigned int *nind, COLLADAFW::MeshVertexData& nor, int count)
707 {
708         float a[3], b[3];
709
710         get_vector(a, nor, *nind, 3);
711         normalize_v3(a);
712
713         nind++;
714
715         for (int i = 1; i < count; i++, nind++) {
716                 get_vector(b, nor, *nind, 3);
717                 normalize_v3(b);
718
719                 float dp = dot_v3v3(a, b);
720
721                 if (dp < 0.99999f || dp > 1.00001f)
722                         return false;
723         }
724
725         return true;
726 }
727
728 MeshImporter::MeshImporter(UnitConverter *unitconv, ArmatureImporter *arm, Scene *sce) : unitconverter(unitconv), scene(sce), armature_importer(arm) {}
729
730 Object *MeshImporter::get_object_by_geom_uid(const COLLADAFW::UniqueId& geom_uid)
731 {
732         if (uid_object_map.find(geom_uid) != uid_object_map.end())
733                 return uid_object_map[geom_uid];
734         return NULL;
735 }
736
737 MTex *MeshImporter::assign_textures_to_uvlayer(COLLADAFW::TextureCoordinateBinding &ctexture,
738                                                                  Mesh *me, TexIndexTextureArrayMap& texindex_texarray_map,
739                                                                  MTex *color_texture)
740 {
741         const COLLADAFW::TextureMapId texture_index = ctexture.getTextureMapId();
742         size_t setindex = ctexture.getSetIndex();
743         std::string uvname = ctexture.getSemantic();
744         
745         if(setindex==-1) return NULL;
746         
747         const CustomData *data = &me->fdata;
748         int layer_index = CustomData_get_layer_index(data, CD_MTFACE);
749         CustomDataLayer *cdl = &data->layers[layer_index+setindex];
750         
751         /* set uvname to bind_vertex_input semantic */
752         BLI_strncpy(cdl->name, uvname.c_str(), sizeof(cdl->name));
753
754         if (texindex_texarray_map.find(texture_index) == texindex_texarray_map.end()) {
755                 
756                 fprintf(stderr, "Cannot find texture array by texture index.\n");
757                 return color_texture;
758         }
759         
760         std::vector<MTex*> textures = texindex_texarray_map[texture_index];
761         
762         std::vector<MTex*>::iterator it;
763         
764         for (it = textures.begin(); it != textures.end(); it++) {
765                 
766                 MTex *texture = *it;
767                 
768                 if (texture) {
769                         BLI_strncpy(texture->uvname, uvname.c_str(), sizeof(texture->uvname));
770                         if (texture->mapto == MAP_COL) color_texture = texture;
771                 }
772         }
773         return color_texture;
774 }
775
776 MTFace *MeshImporter::assign_material_to_geom(COLLADAFW::MaterialBinding cmaterial,
777                                                                 std::map<COLLADAFW::UniqueId, Material*>& uid_material_map,
778                                                                 Object *ob, const COLLADAFW::UniqueId *geom_uid, 
779                                                                 MTex **color_texture, char *layername, MTFace *texture_face,
780                                                                 std::map<Material*, TexIndexTextureArrayMap>& material_texture_mapping_map, short mat_index)
781 {
782         Mesh *me = (Mesh*)ob->data;
783         const COLLADAFW::UniqueId& ma_uid = cmaterial.getReferencedMaterial();
784         
785         // do we know this material?
786         if (uid_material_map.find(ma_uid) == uid_material_map.end()) {
787                 
788                 fprintf(stderr, "Cannot find material by UID.\n");
789                 return NULL;
790         }
791         
792         // different nodes can point to same geometry, but still also specify the same materials
793         // again. Make sure we don't overwrite them on the next occurrences, so keep list of
794         // what we already have handled.
795         std::multimap<COLLADAFW::UniqueId, COLLADAFW::UniqueId>::iterator it;
796         it=materials_mapped_to_geom.find(*geom_uid);
797         while(it!=materials_mapped_to_geom.end()) {
798                 if(it->second == ma_uid && it->first == *geom_uid) return NULL; // do nothing if already found
799                 it++;
800         }
801         // first time we get geom_uid, ma_uid pair. Save for later check.
802         materials_mapped_to_geom.insert(std::pair<COLLADAFW::UniqueId, COLLADAFW::UniqueId>(*geom_uid, ma_uid));
803         
804         Material *ma = uid_material_map[ma_uid];
805         assign_material(ob, ma, ob->totcol + 1);
806         
807         COLLADAFW::TextureCoordinateBindingArray& tex_array = 
808                 cmaterial.getTextureCoordinateBindingArray();
809         TexIndexTextureArrayMap texindex_texarray_map = material_texture_mapping_map[ma];
810         unsigned int i;
811         // loop through <bind_vertex_inputs>
812         for (i = 0; i < tex_array.getCount(); i++) {
813                 
814                 *color_texture = assign_textures_to_uvlayer(tex_array[i], me, texindex_texarray_map,
815                                                                                                         *color_texture);
816         }
817         
818         // set texture face
819         if (*color_texture &&
820                 strlen((*color_texture)->uvname) &&
821                 strcmp(layername, (*color_texture)->uvname) != 0) {
822                 texture_face = (MTFace*)CustomData_get_layer_named(&me->fdata, CD_MTFACE,
823                                                                                                                    (*color_texture)->uvname);
824                 strcpy(layername, (*color_texture)->uvname);
825         }
826         
827         MaterialIdPrimitiveArrayMap& mat_prim_map = geom_uid_mat_mapping_map[*geom_uid];
828         COLLADAFW::MaterialId mat_id = cmaterial.getMaterialId();
829         
830         // assign material indices to mesh faces
831         if (mat_prim_map.find(mat_id) != mat_prim_map.end()) {
832                 
833                 std::vector<Primitive>& prims = mat_prim_map[mat_id];
834                 
835                 std::vector<Primitive>::iterator it;
836                 
837                 for (it = prims.begin(); it != prims.end(); it++) {
838                         Primitive& prim = *it;
839                         i = 0;
840                         while (i++ < prim.totface) {
841                                 prim.mface->mat_nr = mat_index;
842                                 prim.mface++;
843                                 // bind texture images to faces
844                                 if (texture_face && (*color_texture)) {
845                                         texture_face->mode = TF_TEX;
846                                         texture_face->tpage = (Image*)(*color_texture)->tex->ima;
847                                         texture_face++;
848                                 }
849                         }
850                 }
851         }
852         
853         return texture_face;
854 }
855
856
857 Object *MeshImporter::create_mesh_object(COLLADAFW::Node *node, COLLADAFW::InstanceGeometry *geom,
858                                                    bool isController,
859                                                    std::map<COLLADAFW::UniqueId, Material*>& uid_material_map,
860                                                    std::map<Material*, TexIndexTextureArrayMap>& material_texture_mapping_map)
861 {
862         const COLLADAFW::UniqueId *geom_uid = &geom->getInstanciatedObjectId();
863         
864         // check if node instanciates controller or geometry
865         if (isController) {
866                 
867                 geom_uid = armature_importer->get_geometry_uid(*geom_uid);
868                 
869                 if (!geom_uid) {
870                         fprintf(stderr, "Couldn't find a mesh UID by controller's UID.\n");
871                         return NULL;
872                 }
873         }
874         else {
875                 
876                 if (uid_mesh_map.find(*geom_uid) == uid_mesh_map.end()) {
877                         // this could happen if a mesh was not created
878                         // (e.g. if it contains unsupported geometry)
879                         fprintf(stderr, "Couldn't find a mesh by UID.\n");
880                         return NULL;
881                 }
882         }
883         if (!uid_mesh_map[*geom_uid]) return NULL;
884         
885         Object *ob = add_object(scene, OB_MESH);
886
887         // store object pointer for ArmatureImporter
888         uid_object_map[*geom_uid] = ob;
889         
890         // name Object
891         const std::string& id = node->getName().size() ? node->getName() : node->getOriginalId();
892         if (id.length())
893                 rename_id(&ob->id, (char*)id.c_str());
894         
895         // replace ob->data freeing the old one
896         Mesh *old_mesh = (Mesh*)ob->data;
897
898         set_mesh(ob, uid_mesh_map[*geom_uid]);
899         
900         if (old_mesh->id.us == 0) free_libblock(&G.main->mesh, old_mesh);
901         
902         char layername[100];
903         layername[0] = '\0';
904         MTFace *texture_face = NULL;
905         MTex *color_texture = NULL;
906         
907         COLLADAFW::MaterialBindingArray& mat_array =
908                 geom->getMaterialBindings();
909         
910         // loop through geom's materials
911         for (unsigned int i = 0; i < mat_array.getCount(); i++) {
912                 
913                 if(mat_array[i].getReferencedMaterial().isValid()) {
914                         texture_face = assign_material_to_geom(mat_array[i], uid_material_map, ob, geom_uid,
915                                                                                                    &color_texture, layername, texture_face,
916                                                                                                    material_texture_mapping_map, i);
917                 } else {
918                         fprintf(stderr, "invalid referenced material for %s\n", mat_array[i].getName().c_str());
919                 }
920         }
921                 
922         return ob;
923 }
924
925 // create a mesh storing a pointer in a map so it can be retrieved later by geometry UID
926 bool MeshImporter::write_geometry(const COLLADAFW::Geometry* geom) 
927 {
928         // TODO: import also uvs, normals
929         // XXX what to do with normal indices?
930         // XXX num_normals may be != num verts, then what to do?
931
932         // check geometry->getType() first
933         if (geom->getType() != COLLADAFW::Geometry::GEO_TYPE_MESH) {
934                 // TODO: report warning
935                 fprintf(stderr, "Mesh type %s is not supported\n", bc_geomTypeToStr(geom->getType()));
936                 return true;
937         }
938         
939         COLLADAFW::Mesh *mesh = (COLLADAFW::Mesh*)geom;
940         
941         if (!is_nice_mesh(mesh)) {
942                 fprintf(stderr, "Ignoring mesh %s\n", bc_get_dae_name(mesh));
943                 return true;
944         }
945         
946         const std::string& str_geom_id = mesh->getName().size() ? mesh->getName() : mesh->getOriginalId();
947         Mesh *me = add_mesh((char*)str_geom_id.c_str());
948
949         // store the Mesh pointer to link it later with an Object
950         this->uid_mesh_map[mesh->getUniqueId()] = me;
951         
952         int new_tris = 0;
953         
954         read_vertices(mesh, me);
955
956         new_tris = count_new_tris(mesh, me);
957         
958         read_faces(mesh, me, new_tris);
959
960         make_edges(me, 0);
961
962         mesh_calc_normals_mapping(me->mvert, me->totvert, me->mloop, me->mpoly, me->totloop, me->totpoly, NULL, NULL, 0, NULL, NULL);
963
964         return true;
965 }