fix T48602: Changed The Collada validator to treat faces with < 3 verts as Warning...
[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) || defined(FREE_WINDOWS)
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
178 void VCOLDataWrapper::get_vcol(int v_index, MLoopCol *mloopcol)
179 {
180         int stride = mVData->getStride(0);
181         if (stride == 0) stride = 3;
182
183         switch (mVData->getType()) {
184                 case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT:
185                 {
186                         COLLADAFW::ArrayPrimitiveType<float> *values = mVData->getFloatValues();
187                         if (values->empty() || values->getCount() <= (v_index * stride + 2)) return;  // xxx need to create an eror instead
188
189                         mloopcol->r = FTOCHAR((*values)[v_index * stride]);
190                         mloopcol->g = FTOCHAR((*values)[v_index * stride + 1]);
191                         mloopcol->b = FTOCHAR((*values)[v_index * stride + 2]);
192                 }
193                 break;
194
195                 case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE:
196                 {
197                         COLLADAFW::ArrayPrimitiveType<double> *values = mVData->getDoubleValues();
198                         if (values->empty() || values->getCount() <= (v_index * stride + 2)) return; // xxx need to create an eror instead
199
200                         mloopcol->r = FTOCHAR((*values)[v_index * stride]);
201                         mloopcol->g = FTOCHAR((*values)[v_index * stride + 1]);
202                         mloopcol->b = FTOCHAR((*values)[v_index * stride + 2]);
203                 }
204                 break;
205                 default:
206                         fprintf(stderr, "VCOLDataWrapper.getvcol(): unknown data type\n");
207         }
208
209 }
210
211 MeshImporter::MeshImporter(UnitConverter *unitconv, ArmatureImporter *arm, Scene *sce) : unitconverter(unitconv), scene(sce), armature_importer(arm) {
212 }
213
214 bool MeshImporter::set_poly_indices(MPoly *mpoly, MLoop *mloop, int loop_index, unsigned int *indices, int loop_count)
215 {
216         mpoly->loopstart = loop_index;
217         mpoly->totloop   = loop_count;
218         bool broken_loop = false;
219         for (int index=0; index < loop_count; index++) {
220
221                 /* Test if loop defines a hole */
222                 if (!broken_loop) {
223                         for (int i = 0; i < index; i++) {
224                                 if (indices[i] == indices[index]) {
225                                         // duplicate index -> not good
226                                         broken_loop = true;
227                                 }
228                         }
229                 }
230
231                 mloop->v = indices[index];
232                 mloop++;
233         }
234         return broken_loop;
235 }
236
237 void MeshImporter::set_vcol(MLoopCol *mlc, VCOLDataWrapper &vob, int loop_index, COLLADAFW::IndexList &index_list, int count)
238 {
239         int index;
240         for (index = 0; index < count; index++, mlc++) {
241                 int v_index = index_list.getIndex(index + loop_index);
242                 vob.get_vcol(v_index,mlc);
243         }
244 }
245
246 void MeshImporter::set_face_uv(MLoopUV *mloopuv, UVDataWrapper &uvs,
247                                int start_index, COLLADAFW::IndexList& index_list, int count)
248 {
249         // per face vertex indices, this means for quad we have 4 indices, not 8
250         COLLADAFW::UIntValuesArray& indices = index_list.getIndices();
251
252         for (int index = 0; index < count; index++) {
253                 int uv_index = indices[index+start_index];
254                 uvs.getUV(uv_index, mloopuv[index].uv);
255         }
256 }
257
258 #ifdef COLLADA_DEBUG
259 void MeshImporter::print_index_list(COLLADAFW::IndexList& index_list)
260 {
261         fprintf(stderr, "Index list for \"%s\":\n", index_list.getName().c_str());
262         for (int i = 0; i < index_list.getIndicesCount(); i += 2) {
263                 fprintf(stderr, "%u, %u\n", index_list.getIndex(i), index_list.getIndex(i + 1));
264         }
265         fprintf(stderr, "\n");
266 }
267 #endif
268
269 bool MeshImporter::is_nice_mesh(COLLADAFW::Mesh *mesh)  // checks if mesh has supported primitive types: lines, polylist, triangles, triangle_fans
270 {
271         COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives();
272
273         const std::string &name = bc_get_dae_name(mesh);
274
275         for (unsigned i = 0; i < prim_arr.getCount(); i++) {
276
277                 COLLADAFW::MeshPrimitive *mp = prim_arr[i];
278                 COLLADAFW::MeshPrimitive::PrimitiveType type = mp->getPrimitiveType();
279
280                 const char *type_str = bc_primTypeToStr(type);
281
282                 // OpenCollada passes POLYGONS type for <polylist>
283                 if (type == COLLADAFW::MeshPrimitive::POLYLIST || type == COLLADAFW::MeshPrimitive::POLYGONS) {
284
285                         COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons *)mp;
286                         COLLADAFW::Polygons::VertexCountArray& vca = mpvc->getGroupedVerticesVertexCountArray();
287
288                         int hole_count = 0;
289                         int nonface_count = 0;
290
291                         for (unsigned int j = 0; j < vca.getCount(); j++) {
292                                 int count = vca[j];
293                                 if (abs(count) < 3) {
294                                         nonface_count++;
295                                 }
296
297                                 if (count < 0) {
298                                         hole_count ++;
299                                 }
300                         }
301
302                         if (hole_count > 0) {
303                                 fprintf(stderr, "WARNING: Primitive %s in %s: %d holes not imported (unsupported)\n", type_str, name.c_str(), hole_count);
304                         }
305
306                         if (nonface_count > 0) {
307                                 fprintf(stderr, "WARNING: Primitive %s in %s: %d faces with vertex count < 3 (rejected)\n", type_str, name.c_str(), nonface_count);
308                         }
309                 }
310
311                 else if (type == COLLADAFW::MeshPrimitive::LINES) {
312                         // TODO: Add Checker for line syntax here
313                 }
314
315                 else if (type != COLLADAFW::MeshPrimitive::TRIANGLES && type != COLLADAFW::MeshPrimitive::TRIANGLE_FANS) {
316                         fprintf(stderr, "ERROR: Primitive type %s is not supported.\n", type_str);
317                         return false;
318                 }
319         }
320         
321         if (mesh->getPositions().empty()) {
322                 fprintf(stderr, "ERROR: Mesh %s has no vertices.\n", name.c_str());
323                 return false;
324         }
325
326         return true;
327 }
328
329 void MeshImporter::read_vertices(COLLADAFW::Mesh *mesh, Mesh *me)
330 {
331         // vertices
332         COLLADAFW::MeshVertexData& pos = mesh->getPositions();
333         int stride = pos.getStride(0);
334         if (stride == 0) stride = 3;
335         
336         me->totvert = mesh->getPositions().getFloatValues()->getCount() / stride;
337         me->mvert = (MVert *)CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, me->totvert);
338
339         MVert *mvert;
340         int i;
341
342         for (i = 0, mvert = me->mvert; i < me->totvert; i++, mvert++) {
343                 get_vector(mvert->co, pos, i, stride);
344         }
345 }
346
347
348 // =====================================================================
349 // condition 1: The Primitive has normals
350 // condition 2: The number of normals equals the number of faces.
351 // return true if both conditions apply.
352 // return false otherwise.
353 // =====================================================================
354 bool MeshImporter::primitive_has_useable_normals(COLLADAFW::MeshPrimitive *mp) {
355
356         bool has_useable_normals = false;
357
358         int normals_count = mp->getNormalIndices().getCount();
359         if (normals_count > 0) {
360                 int index_count   = mp->getPositionIndices().getCount();
361                 if (index_count == normals_count) 
362                         has_useable_normals = true;
363                 else {
364                         fprintf(stderr,
365                                 "Warning: Number of normals %d is different from the number of vertices %d, skipping normals\n",
366                                 normals_count, index_count);
367                 }
368         }
369
370         return has_useable_normals;
371
372 }
373
374 // =====================================================================
375 // Assume that only TRIANGLES, TRIANGLE_FANS, POLYLIST and POLYGONS
376 // have faces. (to be verified)
377 // =====================================================================
378 bool MeshImporter::primitive_has_faces(COLLADAFW::MeshPrimitive *mp) {
379
380         bool has_faces = false;
381         int type = mp->getPrimitiveType();
382         switch (type) {
383                 case COLLADAFW::MeshPrimitive::TRIANGLES:
384                 case COLLADAFW::MeshPrimitive::TRIANGLE_FANS:
385                 case COLLADAFW::MeshPrimitive::POLYLIST:
386                 case COLLADAFW::MeshPrimitive::POLYGONS:
387                 {
388                         has_faces = true;
389                         break;
390                 }
391                 default: {
392                         has_faces = false; 
393                         break;
394                 }
395         }
396         return has_faces;
397 }
398
399
400 static std::string extract_vcolname(const COLLADAFW::String &collada_id) {
401         std::string colname =  collada_id;
402         int spos = colname.find("-mesh-colors-");
403         if (spos != std::string::npos) {
404                 colname = colname.substr(spos+13);
405         }
406         return colname;
407 }
408
409
410 // =================================================================
411 // Return the number of faces by summing up
412 // the facecounts of the parts.
413 // hint: This is done because mesh->getFacesCount() does
414 // count loose edges as extra faces, which is not what we want here.
415 // =================================================================
416 void MeshImporter::allocate_poly_data(COLLADAFW::Mesh *collada_mesh, Mesh *me)
417 {
418         COLLADAFW::MeshPrimitiveArray& prim_arr = collada_mesh->getMeshPrimitives();
419         int total_poly_count  = 0;
420         int total_loop_count  = 0;
421
422         // collect edge_count and face_count from all parts
423         for (int i = 0; i < prim_arr.getCount(); i++) {
424                 COLLADAFW::MeshPrimitive *mp = prim_arr[i];
425                 int type = mp->getPrimitiveType();
426                 switch (type) {
427                         case COLLADAFW::MeshPrimitive::TRIANGLES:
428                         case COLLADAFW::MeshPrimitive::TRIANGLE_FANS:
429                         case COLLADAFW::MeshPrimitive::POLYLIST:
430                         case COLLADAFW::MeshPrimitive::POLYGONS:
431                         {
432                                 COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons *)mp;
433                                 size_t prim_poly_count    = mpvc->getFaceCount();
434
435                                 size_t prim_loop_count    = 0;
436                                 for (int index=0; index < prim_poly_count; index++) 
437                                 {
438                                         int vcount = get_vertex_count(mpvc, index);
439                                         if (vcount > 0) {
440                                                 prim_loop_count += vcount;
441                                                 total_poly_count++;
442                                         }
443                                         else {
444                                                 // TODO: this is a hole and not another polygon!
445                                         }
446                                 }
447
448                                 total_loop_count += prim_loop_count;
449
450                                 break;
451                         }
452                         default:
453                                 break;
454                 }
455         }
456
457         // Add the data containers
458         if (total_poly_count > 0) {
459                 me->totpoly = total_poly_count;
460                 me->totloop = total_loop_count;
461                 me->mpoly   = (MPoly *)CustomData_add_layer(&me->pdata, CD_MPOLY, CD_CALLOC, NULL, me->totpoly);
462                 me->mloop   = (MLoop *)CustomData_add_layer(&me->ldata, CD_MLOOP, CD_CALLOC, NULL, me->totloop);
463
464                 unsigned int totuvset = collada_mesh->getUVCoords().getInputInfosArray().getCount();
465                 for (int i = 0; i < totuvset; i++) {
466                         if (collada_mesh->getUVCoords().getLength(i) == 0) {
467                                 totuvset = 0;
468                                 break;
469                         }
470                 }
471
472                 if (totuvset > 0) {
473                         for (int i = 0; i < totuvset; i++) {
474                                 COLLADAFW::MeshVertexData::InputInfos *info = collada_mesh->getUVCoords().getInputInfosArray()[i];
475                                 COLLADAFW::String &uvname = info->mName;
476                                 // Allocate space for UV_data
477                                 CustomData_add_layer_named(&me->pdata, CD_MTEXPOLY, CD_DEFAULT, NULL, me->totpoly, uvname.c_str());
478                                 CustomData_add_layer_named(&me->ldata, CD_MLOOPUV, CD_DEFAULT, NULL, me->totloop, uvname.c_str());
479                         }
480                         // activate the first uv map
481                         me->mtpoly  = (MTexPoly *)CustomData_get_layer_n(&me->pdata, CD_MTEXPOLY, 0);
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 i, 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 (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 i = 0; i < edge_count; i++, med++) {
612                                         med->bweight = 0;
613                                         med->crease  = 0;
614                                         med->flag   |= ME_LOOSEEDGE;
615                                         med->v1      = indices[2 * i];
616                                         med->v2      = indices[2 * i + 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                         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 MTex *MeshImporter::assign_textures_to_uvlayer(COLLADAFW::TextureCoordinateBinding &ctexture,
882                                                Mesh *me, TexIndexTextureArrayMap& texindex_texarray_map,
883                                                MTex *color_texture)
884 {
885         const COLLADAFW::TextureMapId texture_index = ctexture.getTextureMapId();
886         size_t setindex = ctexture.getSetIndex();
887         std::string uvname = ctexture.getSemantic();
888         
889         if (setindex == -1) return NULL;
890         
891         const CustomData *data = &me->fdata;
892         int layer_index = CustomData_get_layer_index(data, CD_MTFACE);
893
894         if (layer_index == -1) return NULL;
895
896         CustomDataLayer *cdl = &data->layers[layer_index + setindex];
897         
898         /* set uvname to bind_vertex_input semantic */
899         BLI_strncpy(cdl->name, uvname.c_str(), sizeof(cdl->name));
900
901         if (texindex_texarray_map.find(texture_index) == texindex_texarray_map.end()) {
902                 
903                 fprintf(stderr, "Cannot find texture array by texture index.\n");
904                 return color_texture;
905         }
906         
907         std::vector<MTex *> textures = texindex_texarray_map[texture_index];
908         
909         std::vector<MTex *>::iterator it;
910         
911         for (it = textures.begin(); it != textures.end(); it++) {
912                 
913                 MTex *texture = *it;
914                 
915                 if (texture) {
916                         BLI_strncpy(texture->uvname, uvname.c_str(), sizeof(texture->uvname));
917                         if (texture->mapto == MAP_COL) color_texture = texture;
918                 }
919         }
920         return color_texture;
921 }
922
923 /**
924  * this function checks if both objects have the same
925  * materials assigned to Object (in the same order)
926  * returns true if condition matches, otherwise false;
927  **/
928 static bool bc_has_same_material_configuration(Object *ob1, Object *ob2)
929 {
930         if (ob1->totcol != ob2->totcol) return false; // not same number of materials
931         if (ob1->totcol == 0) return false; // no material at all
932         
933         for (int index=0; index < ob1->totcol; index++) {
934                 if (ob1->matbits[index] != ob2->matbits[index]) return false; // shouldn't happen
935                 if (ob1->matbits[index] == 0) return false; // shouldn't happen
936                 if (ob1->mat[index] != ob2->mat[index]) return false; // different material assignment
937         }
938         return true;
939 }
940
941
942 /**
943  *
944  * Caution here: This code assumes tha all materials are assigned to Object
945  * and no material is assigned to Data.
946  * That is true right after the objects have been imported.
947  *
948  **/
949 static void bc_copy_materials_to_data(Object *ob, Mesh *me)
950 {
951         for (int index = 0; index < ob->totcol; index++) {
952                 ob->matbits[index] = 0;
953                 me->mat[index] = ob->mat[index];
954         }
955 }
956
957 /**
958  *
959  * Remove all references to materials from the object
960  *
961  **/
962 static void bc_remove_materials_from_object(Object *ob, Mesh *me)
963 {
964         for (int index = 0; index < ob->totcol; index++) {
965                 ob->matbits[index] = 0;
966                 ob->mat[index] = NULL;
967         }
968 }
969
970 /**
971  * Returns the list of Users of the given Mesh object.
972  * Note: This function uses the object user flag to control
973  * which objects have already been processed.
974  **/
975 std::vector<Object *> MeshImporter::get_all_users_of(Mesh *reference_mesh)
976 {
977         std::vector<Object *> mesh_users;
978         for (std::vector<Object *>::iterator it = imported_objects.begin();
979              it != imported_objects.end(); ++it)
980         {
981                 Object *ob = (*it);
982                 if (bc_is_marked(ob)) {
983                         bc_remove_mark(ob);
984                         Mesh *me = (Mesh *) ob->data;
985                         if (me == reference_mesh)
986                                 mesh_users.push_back(ob);
987                 }
988         }
989         return mesh_users;
990 }
991
992 /**
993  *
994  * During import all materials have been assigned to Object.
995  * Now we iterate over the imported objects and optimize
996  * the assignments as follows:
997  *
998  * for each imported geometry:
999  *     if number of users is 1:
1000  *         get the user (object)
1001  *         move the materials from Object to Data
1002  *     else:
1003  *         determine which materials are assigned to the first user
1004  *         check if all other users have the same materials in the same order
1005  *         if the check is positive:
1006  *             Add the materials of the first user to the geometry
1007  *             adjust all other users accordingly.
1008  *
1009  **/
1010 void MeshImporter::optimize_material_assignements()
1011 {
1012         for (std::vector<Object *>::iterator it = imported_objects.begin();
1013              it != imported_objects.end(); ++it)
1014         {
1015                 Object *ob = (*it);
1016                 Mesh *me = (Mesh *) ob->data;
1017                 if (me->id.us==1) {
1018                         bc_copy_materials_to_data(ob, me);
1019                         bc_remove_materials_from_object(ob, me);
1020                         bc_remove_mark(ob);
1021                 }
1022                 else if (me->id.us > 1)
1023                 {
1024                         bool can_move = true;
1025                         std::vector<Object *> mesh_users = get_all_users_of(me);
1026                         if (mesh_users.size() > 1)
1027                         {
1028                                 Object *ref_ob = mesh_users[0];
1029                                 for (int index = 1; index < mesh_users.size(); index++) {
1030                                         if (!bc_has_same_material_configuration(ref_ob, mesh_users[index])) {
1031                                                 can_move = false;
1032                                                 break;
1033                                         }
1034                                 }
1035                                 if (can_move) {
1036                                         bc_copy_materials_to_data(ref_ob, me);
1037                                         for (int index = 0; index < mesh_users.size(); index++) {
1038                                                 Object *object = mesh_users[index];
1039                                                 bc_remove_materials_from_object(object, me);
1040                                                 bc_remove_mark(object);
1041                                         }
1042                                 }
1043                         }
1044                 }
1045         }
1046 }
1047
1048 /**
1049  * We do not know in advance which objects will share geometries.
1050  * And we do not know either if the objects which share geometries
1051  * come along with different materials. So we first create the objects
1052  * and assign the materials to Object, then in a later cleanup we decide
1053  * which materials shall be moved to the created geometries. Also see
1054  * optimize_material_assignements() above.
1055  */
1056 MTFace *MeshImporter::assign_material_to_geom(COLLADAFW::MaterialBinding cmaterial,
1057                                               std::map<COLLADAFW::UniqueId, Material *>& uid_material_map,
1058                                               Object *ob, const COLLADAFW::UniqueId *geom_uid,
1059                                               char *layername, MTFace *texture_face,
1060                                               std::map<Material *, TexIndexTextureArrayMap>& material_texture_mapping_map, short mat_index)
1061 {
1062         MTex *color_texture = NULL;
1063         Mesh *me = (Mesh *)ob->data;
1064         const COLLADAFW::UniqueId& ma_uid = cmaterial.getReferencedMaterial();
1065         
1066         // do we know this material?
1067         if (uid_material_map.find(ma_uid) == uid_material_map.end()) {
1068                 
1069                 fprintf(stderr, "Cannot find material by UID.\n");
1070                 return NULL;
1071         }
1072
1073         // first time we get geom_uid, ma_uid pair. Save for later check.
1074         materials_mapped_to_geom.insert(std::pair<COLLADAFW::UniqueId, COLLADAFW::UniqueId>(*geom_uid, ma_uid));
1075         
1076         Material *ma = uid_material_map[ma_uid];
1077
1078         // Attention! This temporaly assigns material to object on purpose!
1079         // See note above.
1080         ob->actcol=0;
1081         assign_material(ob, ma, mat_index + 1, BKE_MAT_ASSIGN_OBJECT); 
1082         
1083         COLLADAFW::TextureCoordinateBindingArray& tex_array = 
1084             cmaterial.getTextureCoordinateBindingArray();
1085         TexIndexTextureArrayMap texindex_texarray_map = material_texture_mapping_map[ma];
1086         unsigned int i;
1087         // loop through <bind_vertex_inputs>
1088         for (i = 0; i < tex_array.getCount(); i++) {
1089                 
1090                 color_texture = assign_textures_to_uvlayer(tex_array[i], me, texindex_texarray_map,
1091                                                             color_texture);
1092         }
1093         
1094         // set texture face
1095         if (color_texture &&
1096             strlen((color_texture)->uvname) &&
1097             !STREQ(layername, color_texture->uvname)) {
1098                 texture_face = (MTFace *)CustomData_get_layer_named(&me->fdata, CD_MTFACE,
1099                                                                     color_texture->uvname);
1100                 strcpy(layername, color_texture->uvname);
1101         }
1102         
1103         MaterialIdPrimitiveArrayMap& mat_prim_map = geom_uid_mat_mapping_map[*geom_uid];
1104         COLLADAFW::MaterialId mat_id = cmaterial.getMaterialId();
1105         
1106         // assign material indices to mesh faces
1107         if (mat_prim_map.find(mat_id) != mat_prim_map.end()) {
1108                 
1109                 std::vector<Primitive>& prims = mat_prim_map[mat_id];
1110                 
1111                 std::vector<Primitive>::iterator it;
1112                 
1113                 for (it = prims.begin(); it != prims.end(); it++) {
1114                         Primitive& prim = *it;
1115                         MPoly *mpoly = prim.mpoly;
1116
1117                         for (i = 0; i < prim.totpoly; i++, mpoly++) {
1118                                 mpoly->mat_nr = mat_index;
1119                                 // bind texture images to faces
1120                                 if (texture_face && color_texture) {
1121                                         texture_face->tpage = (Image *)color_texture->tex->ima;
1122                                         texture_face++;
1123                                 }
1124                         }
1125                 }
1126         }       
1127         return texture_face;
1128 }
1129
1130 Object *MeshImporter::create_mesh_object(COLLADAFW::Node *node, COLLADAFW::InstanceGeometry *geom,
1131                                          bool isController,
1132                                          std::map<COLLADAFW::UniqueId, Material *>& uid_material_map,
1133                                          std::map<Material *, TexIndexTextureArrayMap>& material_texture_mapping_map)
1134 {
1135         const COLLADAFW::UniqueId *geom_uid = &geom->getInstanciatedObjectId();
1136         
1137         // check if node instanciates controller or geometry
1138         if (isController) {
1139                 
1140                 geom_uid = armature_importer->get_geometry_uid(*geom_uid);
1141                 
1142                 if (!geom_uid) {
1143                         fprintf(stderr, "Couldn't find a mesh UID by controller's UID.\n");
1144                         return NULL;
1145                 }
1146         }
1147         else {
1148                 
1149                 if (uid_mesh_map.find(*geom_uid) == uid_mesh_map.end()) {
1150                         // this could happen if a mesh was not created
1151                         // (e.g. if it contains unsupported geometry)
1152                         fprintf(stderr, "Couldn't find a mesh by UID.\n");
1153                         return NULL;
1154                 }
1155         }
1156         if (!uid_mesh_map[*geom_uid]) return NULL;
1157         
1158         // name Object
1159         const std::string& id = node->getName().size() ? node->getName() : node->getOriginalId();
1160         const char *name = (id.length()) ? id.c_str() : NULL;
1161         
1162         // add object
1163         Object *ob = bc_add_object(scene, OB_MESH, name);
1164         bc_set_mark(ob); // used later for material assignement optimization
1165
1166
1167         // store object pointer for ArmatureImporter
1168         uid_object_map[*geom_uid] = ob;
1169         imported_objects.push_back(ob);
1170         
1171         // replace ob->data freeing the old one
1172         Mesh *old_mesh = (Mesh *)ob->data;
1173         Mesh *new_mesh = uid_mesh_map[*geom_uid];
1174
1175         BKE_mesh_assign_object(ob, new_mesh);
1176         BKE_mesh_calc_normals(new_mesh);
1177
1178         if (old_mesh->id.us == 0) BKE_libblock_free(G.main, old_mesh);
1179         
1180         char layername[100];
1181         layername[0] = '\0';
1182         MTFace *texture_face = NULL;
1183         
1184         COLLADAFW::MaterialBindingArray& mat_array =
1185             geom->getMaterialBindings();
1186         
1187         // loop through geom's materials
1188         for (unsigned int i = 0; i < mat_array.getCount(); i++) {
1189                 
1190                 if (mat_array[i].getReferencedMaterial().isValid()) {
1191                         texture_face = assign_material_to_geom(mat_array[i], uid_material_map, ob, geom_uid,
1192                                                                layername, texture_face,
1193                                                                material_texture_mapping_map, i);
1194                 }
1195                 else {
1196                         fprintf(stderr, "invalid referenced material for %s\n", mat_array[i].getName().c_str());
1197                 }
1198         }
1199
1200         return ob;
1201 }
1202
1203 // create a mesh storing a pointer in a map so it can be retrieved later by geometry UID
1204 bool MeshImporter::write_geometry(const COLLADAFW::Geometry *geom)
1205 {
1206
1207         if (geom->getType() != COLLADAFW::Geometry::GEO_TYPE_MESH) {
1208                 // TODO: report warning
1209                 fprintf(stderr, "Mesh type %s is not supported\n", bc_geomTypeToStr(geom->getType()));
1210                 return true;
1211         }
1212         
1213         COLLADAFW::Mesh *mesh = (COLLADAFW::Mesh *)geom;
1214         
1215         if (!is_nice_mesh(mesh)) {
1216                 fprintf(stderr, "Ignoring mesh %s\n", bc_get_dae_name(mesh).c_str());
1217                 return true;
1218         }
1219         
1220         const std::string& str_geom_id = mesh->getName().size() ? mesh->getName() : mesh->getOriginalId();
1221         Mesh *me = BKE_mesh_add(G.main, (char *)str_geom_id.c_str());
1222         id_us_min(&me->id); // is already 1 here, but will be set later in BKE_mesh_assign_object
1223
1224         // store the Mesh pointer to link it later with an Object
1225         // mesh_geom_map needed to map mesh to its geometry name (for shape key naming)
1226         this->uid_mesh_map[mesh->getUniqueId()] = me;
1227         this->mesh_geom_map[std::string(me->id.name)] = str_geom_id;
1228         
1229         read_vertices(mesh, me);
1230         read_polys(mesh, me);
1231
1232         // must validate before calculating edges
1233         BKE_mesh_calc_normals(me);
1234         BKE_mesh_validate(me, false, false);
1235         // validation does this
1236         // BKE_mesh_calc_edges(me, false, false);
1237
1238         // read_lines() must be called after the face edges have been generated.
1239         // Oterwise the loose edges will be silently deleted again.
1240         read_lines(mesh, me);
1241
1242         return true;
1243 }