Merge branch 'blender2.7'
[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, Trevor Glauz.
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_material.h"
47         #include "BKE_mesh.h"
48         #include "BKE_object.h"
49
50         #include "BLI_listbase.h"
51         #include "BLI_math.h"
52         #include "BLI_string.h"
53         #include "BLI_edgehash.h"
54
55         #include "MEM_guardedalloc.h"
56 }
57
58 #include "ArmatureImporter.h"
59 #include "MeshImporter.h"
60 #include "collada_utils.h"
61
62 // get node name, or fall back to original id if not present (name is optional)
63 template<class T>
64 static const std::string bc_get_dae_name(T *node)
65 {
66         return node->getName().size() ? node->getName(): node->getOriginalId();
67 }
68
69 static const char *bc_primTypeToStr(COLLADAFW::MeshPrimitive::PrimitiveType type)
70 {
71         switch (type) {
72                 case COLLADAFW::MeshPrimitive::LINES:
73                         return "LINES";
74                 case COLLADAFW::MeshPrimitive::LINE_STRIPS:
75                         return "LINESTRIPS";
76                 case COLLADAFW::MeshPrimitive::POLYGONS:
77                         return "POLYGONS";
78                 case COLLADAFW::MeshPrimitive::POLYLIST:
79                         return "POLYLIST";
80                 case COLLADAFW::MeshPrimitive::TRIANGLES:
81                         return "TRIANGLES";
82                 case COLLADAFW::MeshPrimitive::TRIANGLE_FANS:
83                         return "TRIANGLE_FANS";
84                 case COLLADAFW::MeshPrimitive::TRIANGLE_STRIPS:
85                         return "TRIANGLE_STRIPS";
86                 case COLLADAFW::MeshPrimitive::POINTS:
87                         return "POINTS";
88                 case COLLADAFW::MeshPrimitive::UNDEFINED_PRIMITIVE_TYPE:
89                         return "UNDEFINED_PRIMITIVE_TYPE";
90         }
91         return "UNKNOWN";
92 }
93
94 static const char *bc_geomTypeToStr(COLLADAFW::Geometry::GeometryType type)
95 {
96         switch (type) {
97                 case COLLADAFW::Geometry::GEO_TYPE_MESH:
98                         return "MESH";
99                 case COLLADAFW::Geometry::GEO_TYPE_SPLINE:
100                         return "SPLINE";
101                 case COLLADAFW::Geometry::GEO_TYPE_CONVEX_MESH:
102                         return "CONVEX_MESH";
103                 case COLLADAFW::Geometry::GEO_TYPE_UNKNOWN:
104                 default:
105                         return "UNKNOWN";
106         }
107 }
108
109
110 UVDataWrapper::UVDataWrapper(COLLADAFW::MeshVertexData& vdata) : mVData(&vdata)
111 {
112 }
113
114 #ifdef COLLADA_DEBUG
115 void WVDataWrapper::print()
116 {
117         fprintf(stderr, "UVs:\n");
118         switch (mVData->getType()) {
119                 case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT:
120                 {
121                         COLLADAFW::ArrayPrimitiveType<float> *values = mVData->getFloatValues();
122                         if (values->getCount()) {
123                                 for (int i = 0; i < values->getCount(); i += 2) {
124                                         fprintf(stderr, "%.1f, %.1f\n", (*values)[i], (*values)[i + 1]);
125                                 }
126                         }
127                 }
128                 break;
129                 case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE:
130                 {
131                         COLLADAFW::ArrayPrimitiveType<double> *values = mVData->getDoubleValues();
132                         if (values->getCount()) {
133                                 for (int i = 0; i < values->getCount(); i += 2) {
134                                         fprintf(stderr, "%.1f, %.1f\n", (float)(*values)[i], (float)(*values)[i + 1]);
135                                 }
136                         }
137                 }
138                 break;
139         }
140         fprintf(stderr, "\n");
141 }
142 #endif
143
144 void UVDataWrapper::getUV(int uv_index, float *uv)
145 {
146         int stride = mVData->getStride(0);
147         if (stride == 0) stride = 2;
148
149         switch (mVData->getType()) {
150                 case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT:
151                 {
152                         COLLADAFW::ArrayPrimitiveType<float> *values = mVData->getFloatValues();
153                         if (values->empty()) return;
154                         uv[0] = (*values)[uv_index * stride];
155                         uv[1] = (*values)[uv_index * stride + 1];
156
157                 }
158                 break;
159                 case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE:
160                 {
161                         COLLADAFW::ArrayPrimitiveType<double> *values = mVData->getDoubleValues();
162                         if (values->empty()) return;
163                         uv[0] = (float)(*values)[uv_index * stride];
164                         uv[1] = (float)(*values)[uv_index * stride + 1];
165
166                 }
167                 break;
168                 case COLLADAFW::MeshVertexData::DATA_TYPE_UNKNOWN:
169                 default:
170                         fprintf(stderr, "MeshImporter.getUV(): unknown data type\n");
171         }
172 }
173
174 VCOLDataWrapper::VCOLDataWrapper(COLLADAFW::MeshVertexData& vdata) : mVData(&vdata) {}
175
176 void VCOLDataWrapper::get_vcol(int v_index, MLoopCol *mloopcol)
177 {
178         int stride = mVData->getStride(0);
179         if (stride == 0) stride = 3;
180
181         switch (mVData->getType()) {
182                 case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT:
183                 {
184                         COLLADAFW::ArrayPrimitiveType<float> *values = mVData->getFloatValues();
185                         if (values->empty() || values->getCount() <= (v_index * stride + 2)) return;  // xxx need to create an error instead
186
187                         mloopcol->r = unit_float_to_uchar_clamp((*values)[v_index * stride]);
188                         mloopcol->g = unit_float_to_uchar_clamp((*values)[v_index * stride + 1]);
189                         mloopcol->b = unit_float_to_uchar_clamp((*values)[v_index * stride + 2]);
190                 }
191                 break;
192
193                 case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE:
194                 {
195                         COLLADAFW::ArrayPrimitiveType<double> *values = mVData->getDoubleValues();
196                         if (values->empty() || values->getCount() <= (v_index * stride + 2)) return; // xxx need to create an error instead
197
198                         mloopcol->r = unit_float_to_uchar_clamp((*values)[v_index * stride]);
199                         mloopcol->g = unit_float_to_uchar_clamp((*values)[v_index * stride + 1]);
200                         mloopcol->b = unit_float_to_uchar_clamp((*values)[v_index * stride + 2]);
201                 }
202                 break;
203                 default:
204                         fprintf(stderr, "VCOLDataWrapper.getvcol(): unknown data type\n");
205         }
206
207 }
208
209 MeshImporter::MeshImporter(UnitConverter *unitconv, ArmatureImporter *arm, Main *bmain, Scene *sce, ViewLayer *view_layer):
210         unitconverter(unitconv),
211         m_bmain(bmain),
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 function 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 already 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 index = 0; index < prim_arr.getCount(); index++) {
603                         COLLADAFW::MeshPrimitive *mp = prim_arr[index];
604
605                         int type = mp->getPrimitiveType();
606                         if (type == COLLADAFW::MeshPrimitive::LINES) {
607                                 unsigned int edge_count  = mp->getFaceCount();
608                                 unsigned int *indices    = mp->getPositionIndices().getData();
609
610                                 for (int j = 0; j < edge_count; j++, med++) {
611                                         med->bweight = 0;
612                                         med->crease  = 0;
613                                         med->flag   |= ME_LOOSEEDGE;
614                                         med->v1      = indices[2 * j];
615                                         med->v2      = indices[2 * j + 1];
616                                 }
617                         }
618                 }
619
620         }
621 }
622
623
624 // =======================================================================
625 // Read all faces from TRIANGLES, TRIANGLE_FANS, POLYLIST, POLYGON
626 // Important: This function MUST be called before read_lines()
627 // Otherwise we will loose all edges from faces (see read_lines() above)
628 //
629 // TODO: import uv set names
630 // ========================================================================
631 void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me)
632 {
633         unsigned int i;
634
635         allocate_poly_data(collada_mesh, me);
636
637         UVDataWrapper uvs(collada_mesh->getUVCoords());
638         VCOLDataWrapper vcol(collada_mesh->getColors());
639
640         MPoly *mpoly = me->mpoly;
641         MLoop *mloop = me->mloop;
642         int loop_index = 0;
643
644         MaterialIdPrimitiveArrayMap mat_prim_map;
645
646         COLLADAFW::MeshPrimitiveArray& prim_arr = collada_mesh->getMeshPrimitives();
647         COLLADAFW::MeshVertexData& nor = collada_mesh->getNormals();
648
649         for (i = 0; i < prim_arr.getCount(); i++) {
650
651                 COLLADAFW::MeshPrimitive *mp = prim_arr[i];
652
653                 // faces
654                 size_t prim_totpoly                           = mp->getFaceCount();
655                 unsigned int *position_indices                = mp->getPositionIndices().getData();
656                 unsigned int *normal_indices                  = mp->getNormalIndices().getData();
657
658
659                 bool mp_has_normals = primitive_has_useable_normals(mp);
660                 bool mp_has_faces   = primitive_has_faces(mp);
661
662                 int collada_meshtype = mp->getPrimitiveType();
663
664                 // since we cannot set mpoly->mat_nr here, we store a portion of me->mpoly in Primitive
665                 Primitive prim = {mpoly, 0};
666
667                 // If MeshPrimitive is TRIANGLE_FANS we split it into triangles
668                 // The first trifan vertex will be the first vertex in every triangle
669                 // XXX The proper function of TRIANGLE_FANS is not tested!!!
670                 // XXX In particular the handling of the normal_indices looks very wrong to me
671                 if (collada_meshtype == COLLADAFW::MeshPrimitive::TRIANGLE_FANS) {
672                         unsigned grouped_vertex_count = mp->getGroupedVertexElementsCount();
673                         for (unsigned int group_index = 0; group_index < grouped_vertex_count; group_index++) {
674                                 unsigned int first_vertex = position_indices[0]; // Store first trifan vertex
675                                 unsigned int first_normal = normal_indices[0]; // Store first trifan vertex normal
676                                 unsigned int vertex_count = mp->getGroupedVerticesVertexCount(group_index);
677
678                                 for (unsigned int vertex_index = 0; vertex_index < vertex_count - 2; vertex_index++) {
679                                         // For each triangle store indices of its 3 vertices
680                                         unsigned int triangle_vertex_indices[3] = {first_vertex, position_indices[1], position_indices[2]};
681                                         set_poly_indices(mpoly, mloop, loop_index, triangle_vertex_indices, 3);
682
683                                         if (mp_has_normals) {  // vertex normals, same inplementation as for the triangles
684                                                 // the same for vertces normals
685                                                 unsigned int vertex_normal_indices[3] = {first_normal, normal_indices[1], normal_indices[2]};
686                                                 if (!is_flat_face(vertex_normal_indices, nor, 3))
687                                                         mpoly->flag |= ME_SMOOTH;
688                                                 normal_indices++;
689                                         }
690
691                                         mpoly++;
692                                         mloop += 3;
693                                         loop_index += 3;
694                                         prim.totpoly++;
695
696                                 }
697
698                                 // Moving cursor  to the next triangle fan.
699                                 if (mp_has_normals)
700                                         normal_indices += 2;
701
702                                 position_indices +=  2;
703                         }
704                 }
705
706                 if (collada_meshtype == COLLADAFW::MeshPrimitive::POLYLIST ||
707                     collada_meshtype == COLLADAFW::MeshPrimitive::POLYGONS ||
708                     collada_meshtype == COLLADAFW::MeshPrimitive::TRIANGLES)
709                 {
710                         COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons *)mp;
711                         unsigned int start_index = 0;
712
713                         COLLADAFW::IndexListArray& index_list_array_uvcoord = mp->getUVCoordIndicesArray();
714                         COLLADAFW::IndexListArray& index_list_array_vcolor  = mp->getColorIndicesArray();
715
716                         int invalid_loop_holes = 0;
717                         for (unsigned int j = 0; j < prim_totpoly; j++) {
718
719                                 // Vertices in polygon:
720                                 int vcount = get_vertex_count(mpvc, j);
721                                 if (vcount < 0) {
722                                         continue; // TODO: add support for holes
723                                 }
724
725                                 bool broken_loop = set_poly_indices(mpoly, mloop, loop_index, position_indices, vcount);
726                                 if (broken_loop)
727                                 {
728                                         invalid_loop_holes += 1;
729                                 }
730
731                                 for (unsigned int uvset_index = 0; uvset_index < index_list_array_uvcoord.getCount(); uvset_index++) {
732                                         // get mtface by face index and uv set index
733                                         COLLADAFW::IndexList& index_list = *index_list_array_uvcoord[uvset_index];
734                                         MLoopUV  *mloopuv = (MLoopUV  *)CustomData_get_layer_named(&me->ldata, CD_MLOOPUV, index_list.getName().c_str());
735                                         if (mloopuv == NULL) {
736                                                 fprintf(stderr, "Collada import: Mesh [%s] : Unknown reference to TEXCOORD [#%s].\n", me->id.name, index_list.getName().c_str() );
737                                         }
738                                         else {
739                                                 set_face_uv(mloopuv+loop_index, uvs, start_index, *index_list_array_uvcoord[uvset_index], vcount);
740                                         }
741                                 }
742
743                                 if (mp_has_normals) {
744                                         if (!is_flat_face(normal_indices, nor, vcount))
745                                                 mpoly->flag |= ME_SMOOTH;
746                                 }
747
748
749                                 if (mp->hasColorIndices()) {
750                                         int vcolor_count = index_list_array_vcolor.getCount();
751
752                                         for (unsigned int vcolor_index = 0; vcolor_index < vcolor_count; vcolor_index++) {
753
754                                                 COLLADAFW::IndexList& color_index_list = *mp->getColorIndices(vcolor_index);
755                                                 COLLADAFW::String colname = extract_vcolname(color_index_list.getName());
756                                                 MLoopCol *mloopcol = (MLoopCol  *)CustomData_get_layer_named(&me->ldata, CD_MLOOPCOL, colname.c_str());
757                                                 if (mloopcol == NULL) {
758                                                         fprintf(stderr, "Collada import: Mesh [%s] : Unknown reference to VCOLOR [#%s].\n", me->id.name, color_index_list.getName().c_str());
759                                                 }
760                                                 else {
761                                                         set_vcol(mloopcol + loop_index, vcol, start_index, color_index_list, vcount);
762                                                 }
763                                         }
764                                 }
765
766                                 mpoly++;
767                                 mloop       += vcount;
768                                 loop_index  += vcount;
769                                 start_index += vcount;
770                                 prim.totpoly++;
771
772                                 if (mp_has_normals)
773                                         normal_indices += vcount;
774
775                                 position_indices += vcount;
776                         }
777
778                         if (invalid_loop_holes > 0)
779                         {
780                                 fprintf(stderr, "Collada import: Mesh [%s] : contains %d unsupported loops (holes).\n", me->id.name, invalid_loop_holes);
781                         }
782                 }
783
784                 else if (collada_meshtype == COLLADAFW::MeshPrimitive::LINES) {
785                         continue; // read the lines later after all the rest is done
786                 }
787
788                 if (mp_has_faces)
789                         mat_prim_map[mp->getMaterialId()].push_back(prim);
790
791
792         }
793
794         geom_uid_mat_mapping_map[collada_mesh->getUniqueId()] = mat_prim_map;
795 }
796
797 void MeshImporter::get_vector(float v[3], COLLADAFW::MeshVertexData& arr, int i, int stride)
798 {
799         i *= stride;
800
801         switch (arr.getType()) {
802                 case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT:
803                 {
804                         COLLADAFW::ArrayPrimitiveType<float> *values = arr.getFloatValues();
805                         if (values->empty()) return;
806
807                         v[0] = (*values)[i++];
808                         v[1] = (*values)[i++];
809                         if (stride>=3) {
810                                 v[2] = (*values)[i];
811                         }
812                         else {
813                                 v[2] = 0.0f;
814                         }
815
816                 }
817                 break;
818                 case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE:
819                 {
820                         COLLADAFW::ArrayPrimitiveType<double> *values = arr.getDoubleValues();
821                         if (values->empty()) return;
822
823                         v[0] = (float)(*values)[i++];
824                         v[1] = (float)(*values)[i++];
825                         if (stride >= 3) {
826                                 v[2] = (float)(*values)[i];
827                         }
828                         else {
829                                 v[2] = 0.0f;
830                         }
831                 }
832                 break;
833                 default:
834                         break;
835         }
836 }
837
838 bool MeshImporter::is_flat_face(unsigned int *nind, COLLADAFW::MeshVertexData& nor, int count)
839 {
840         float a[3], b[3];
841
842         get_vector(a, nor, *nind, 3);
843         normalize_v3(a);
844
845         nind++;
846
847         for (int i = 1; i < count; i++, nind++) {
848                 get_vector(b, nor, *nind, 3);
849                 normalize_v3(b);
850
851                 float dp = dot_v3v3(a, b);
852
853                 if (dp < 0.99999f || dp > 1.00001f)
854                         return false;
855         }
856
857         return true;
858 }
859
860 Object *MeshImporter::get_object_by_geom_uid(const COLLADAFW::UniqueId& geom_uid)
861 {
862         if (uid_object_map.find(geom_uid) != uid_object_map.end())
863                 return uid_object_map[geom_uid];
864         return NULL;
865 }
866
867 Mesh *MeshImporter::get_mesh_by_geom_uid(const COLLADAFW::UniqueId& mesh_uid)
868 {
869         if (uid_mesh_map.find(mesh_uid) != uid_mesh_map.end())
870                 return uid_mesh_map[mesh_uid];
871         return NULL;
872 }
873
874 std::string *MeshImporter::get_geometry_name(const std::string &mesh_name)
875 {
876         if (this->mesh_geom_map.find(mesh_name) != this->mesh_geom_map.end())
877                 return &this->mesh_geom_map[mesh_name];
878         return NULL;
879 }
880
881 /**
882  * this function checks if both objects have the same
883  * materials assigned to Object (in the same order)
884  * returns true if condition matches, otherwise false;
885  **/
886 static bool bc_has_same_material_configuration(Object *ob1, Object *ob2)
887 {
888         if (ob1->totcol != ob2->totcol) return false; // not same number of materials
889         if (ob1->totcol == 0) return false; // no material at all
890
891         for (int index=0; index < ob1->totcol; index++) {
892                 if (ob1->matbits[index] != ob2->matbits[index]) return false; // shouldn't happen
893                 if (ob1->matbits[index] == 0) return false; // shouldn't happen
894                 if (ob1->mat[index] != ob2->mat[index]) return false; // different material assignment
895         }
896         return true;
897 }
898
899
900 /**
901  *
902  * Caution here: This code assumes that all materials are assigned to Object
903  * and no material is assigned to Data.
904  * That is true right after the objects have been imported.
905  *
906  **/
907 static void bc_copy_materials_to_data(Object *ob, Mesh *me)
908 {
909         for (int index = 0; index < ob->totcol; index++) {
910                 ob->matbits[index] = 0;
911                 me->mat[index] = ob->mat[index];
912         }
913 }
914
915 /**
916  *
917  * Remove all references to materials from the object
918  *
919  **/
920 static void bc_remove_materials_from_object(Object *ob, Mesh *me)
921 {
922         for (int index = 0; index < ob->totcol; index++) {
923                 ob->matbits[index] = 0;
924                 ob->mat[index] = NULL;
925         }
926 }
927
928 /**
929  * Returns the list of Users of the given Mesh object.
930  * Note: This function uses the object user flag to control
931  * which objects have already been processed.
932  **/
933 std::vector<Object *> MeshImporter::get_all_users_of(Mesh *reference_mesh)
934 {
935         std::vector<Object *> mesh_users;
936         for (std::vector<Object *>::iterator it = imported_objects.begin();
937              it != imported_objects.end(); ++it)
938         {
939                 Object *ob = (*it);
940                 if (bc_is_marked(ob)) {
941                         bc_remove_mark(ob);
942                         Mesh *me = (Mesh *) ob->data;
943                         if (me == reference_mesh)
944                                 mesh_users.push_back(ob);
945                 }
946         }
947         return mesh_users;
948 }
949
950 /**
951  *
952  * During import all materials have been assigned to Object.
953  * Now we iterate over the imported objects and optimize
954  * the assignments as follows:
955  *
956  * for each imported geometry:
957  *     if number of users is 1:
958  *         get the user (object)
959  *         move the materials from Object to Data
960  *     else:
961  *         determine which materials are assigned to the first user
962  *         check if all other users have the same materials in the same order
963  *         if the check is positive:
964  *             Add the materials of the first user to the geometry
965  *             adjust all other users accordingly.
966  *
967  **/
968 void MeshImporter::optimize_material_assignements()
969 {
970         for (std::vector<Object *>::iterator it = imported_objects.begin();
971              it != imported_objects.end(); ++it)
972         {
973                 Object *ob = (*it);
974                 Mesh *me = (Mesh *) ob->data;
975                 if (me->id.us==1) {
976                         bc_copy_materials_to_data(ob, me);
977                         bc_remove_materials_from_object(ob, me);
978                         bc_remove_mark(ob);
979                 }
980                 else if (me->id.us > 1)
981                 {
982                         bool can_move = true;
983                         std::vector<Object *> mesh_users = get_all_users_of(me);
984                         if (mesh_users.size() > 1)
985                         {
986                                 Object *ref_ob = mesh_users[0];
987                                 for (int index = 1; index < mesh_users.size(); index++) {
988                                         if (!bc_has_same_material_configuration(ref_ob, mesh_users[index])) {
989                                                 can_move = false;
990                                                 break;
991                                         }
992                                 }
993                                 if (can_move) {
994                                         bc_copy_materials_to_data(ref_ob, me);
995                                         for (int index = 0; index < mesh_users.size(); index++) {
996                                                 Object *object = mesh_users[index];
997                                                 bc_remove_materials_from_object(object, me);
998                                                 bc_remove_mark(object);
999                                         }
1000                                 }
1001                         }
1002                 }
1003         }
1004 }
1005
1006 /**
1007  * We do not know in advance which objects will share geometries.
1008  * And we do not know either if the objects which share geometries
1009  * come along with different materials. So we first create the objects
1010  * and assign the materials to Object, then in a later cleanup we decide
1011  * which materials shall be moved to the created geometries. Also see
1012  * optimize_material_assignements() above.
1013  */
1014 void MeshImporter::assign_material_to_geom(
1015         COLLADAFW::MaterialBinding cmaterial,
1016         std::map<COLLADAFW::UniqueId, Material *>& uid_material_map,
1017         Object *ob, const COLLADAFW::UniqueId *geom_uid,
1018         short mat_index)
1019 {
1020         const COLLADAFW::UniqueId& ma_uid = cmaterial.getReferencedMaterial();
1021
1022         // do we know this material?
1023         if (uid_material_map.find(ma_uid) == uid_material_map.end()) {
1024
1025                 fprintf(stderr, "Cannot find material by UID.\n");
1026                 return;
1027         }
1028
1029         // first time we get geom_uid, ma_uid pair. Save for later check.
1030         materials_mapped_to_geom.insert(std::pair<COLLADAFW::UniqueId, COLLADAFW::UniqueId>(*geom_uid, ma_uid));
1031
1032         Material *ma = uid_material_map[ma_uid];
1033
1034         // Attention! This temporarily assigns material to object on purpose!
1035         // See note above.
1036         ob->actcol=0;
1037         assign_material(m_bmain, ob, ma, mat_index + 1, BKE_MAT_ASSIGN_OBJECT);
1038
1039         MaterialIdPrimitiveArrayMap& mat_prim_map = geom_uid_mat_mapping_map[*geom_uid];
1040         COLLADAFW::MaterialId mat_id = cmaterial.getMaterialId();
1041
1042         // assign material indices to mesh faces
1043         if (mat_prim_map.find(mat_id) != mat_prim_map.end()) {
1044
1045                 std::vector<Primitive>& prims = mat_prim_map[mat_id];
1046
1047                 std::vector<Primitive>::iterator it;
1048
1049                 for (it = prims.begin(); it != prims.end(); it++) {
1050                         Primitive& prim = *it;
1051                         MPoly *mpoly = prim.mpoly;
1052
1053                         for (int i = 0; i < prim.totpoly; i++, mpoly++) {
1054                                 mpoly->mat_nr = mat_index;
1055                         }
1056                 }
1057         }
1058 }
1059
1060 Object *MeshImporter::create_mesh_object(COLLADAFW::Node *node, COLLADAFW::InstanceGeometry *geom,
1061                                          bool isController,
1062                                          std::map<COLLADAFW::UniqueId, Material *>& uid_material_map)
1063 {
1064         const COLLADAFW::UniqueId *geom_uid = &geom->getInstanciatedObjectId();
1065
1066         // check if node instantiates controller or geometry
1067         if (isController) {
1068
1069                 geom_uid = armature_importer->get_geometry_uid(*geom_uid);
1070
1071                 if (!geom_uid) {
1072                         fprintf(stderr, "Couldn't find a mesh UID by controller's UID.\n");
1073                         return NULL;
1074                 }
1075         }
1076         else {
1077
1078                 if (uid_mesh_map.find(*geom_uid) == uid_mesh_map.end()) {
1079                         // this could happen if a mesh was not created
1080                         // (e.g. if it contains unsupported geometry)
1081                         fprintf(stderr, "Couldn't find a mesh by UID.\n");
1082                         return NULL;
1083                 }
1084         }
1085         if (!uid_mesh_map[*geom_uid]) return NULL;
1086
1087         // name Object
1088         const std::string& id = node->getName().size() ? node->getName() : node->getOriginalId();
1089         const char *name = (id.length()) ? id.c_str() : NULL;
1090
1091         // add object
1092         Object *ob = bc_add_object(m_bmain, scene, view_layer, OB_MESH, name);
1093         bc_set_mark(ob); // used later for material assignment optimization
1094
1095
1096         // store object pointer for ArmatureImporter
1097         uid_object_map[*geom_uid] = ob;
1098         imported_objects.push_back(ob);
1099
1100         // replace ob->data freeing the old one
1101         Mesh *old_mesh = (Mesh *)ob->data;
1102         Mesh *new_mesh = uid_mesh_map[*geom_uid];
1103
1104         BKE_mesh_assign_object(m_bmain, ob, new_mesh);
1105         BKE_mesh_calc_normals(new_mesh);
1106
1107         id_us_plus(&old_mesh->id);  /* Because BKE_mesh_assign_object would have already decreased it... */
1108         BKE_libblock_free_us(m_bmain, old_mesh);
1109
1110         COLLADAFW::MaterialBindingArray& mat_array =
1111             geom->getMaterialBindings();
1112
1113         // loop through geom's materials
1114         for (unsigned int i = 0; i < mat_array.getCount(); i++) {
1115
1116                 if (mat_array[i].getReferencedMaterial().isValid()) {
1117                         assign_material_to_geom(
1118                                 mat_array[i], uid_material_map, ob, geom_uid,
1119                                 i);
1120                 }
1121                 else {
1122                         fprintf(stderr, "invalid referenced material for %s\n", mat_array[i].getName().c_str());
1123                 }
1124         }
1125
1126         // clean up the mesh
1127         BKE_mesh_validate((Mesh *)ob->data, false, false);
1128
1129         return ob;
1130 }
1131
1132 // create a mesh storing a pointer in a map so it can be retrieved later by geometry UID
1133 bool MeshImporter::write_geometry(const COLLADAFW::Geometry *geom)
1134 {
1135
1136         if (geom->getType() != COLLADAFW::Geometry::GEO_TYPE_MESH) {
1137                 // TODO: report warning
1138                 fprintf(stderr, "Mesh type %s is not supported\n", bc_geomTypeToStr(geom->getType()));
1139                 return true;
1140         }
1141
1142         COLLADAFW::Mesh *mesh = (COLLADAFW::Mesh *)geom;
1143
1144         if (!is_nice_mesh(mesh)) {
1145                 fprintf(stderr, "Ignoring mesh %s\n", bc_get_dae_name(mesh).c_str());
1146                 return true;
1147         }
1148
1149         const std::string& str_geom_id = mesh->getName().size() ? mesh->getName() : mesh->getOriginalId();
1150         Mesh *me = BKE_mesh_add(m_bmain, (char *)str_geom_id.c_str());
1151         id_us_min(&me->id); // is already 1 here, but will be set later in BKE_mesh_assign_object
1152
1153         // store the Mesh pointer to link it later with an Object
1154         // mesh_geom_map needed to map mesh to its geometry name (for shape key naming)
1155         this->uid_mesh_map[mesh->getUniqueId()] = me;
1156         this->mesh_geom_map[std::string(me->id.name)] = str_geom_id;
1157
1158         read_vertices(mesh, me);
1159         read_polys(mesh, me);
1160         BKE_mesh_calc_edges(me, false, false);
1161         // read_lines() must be called after the face edges have been generated.
1162         // Otherwise the loose edges will be silently deleted again.
1163         read_lines(mesh, me);
1164
1165         return true;
1166 }