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