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