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