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