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