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