Cleanup: remove last G.main's from Collada code.
[blender.git] / source / blender / collada / MeshImporter.cpp
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor(s): Chingiz Dyussenov, Arystanbek Dyussenov, Nathan Letwory.
19  *
20  * ***** END GPL LICENSE BLOCK *****
21  */
22
23 /** \file blender/collada/MeshImporter.cpp
24  *  \ingroup collada
25  */
26
27
28 #include <algorithm>
29
30 #if !defined(WIN32)
31 #include <iostream>
32 #endif
33
34 /* COLLADABU_ASSERT, may be able to remove later */
35 #include "COLLADABUPlatform.h"
36
37 #include "COLLADAFWMeshPrimitive.h"
38 #include "COLLADAFWMeshVertexData.h"
39 #include "COLLADAFWPolygons.h"
40
41 extern "C" {
42         #include "BKE_customdata.h"
43         #include "BKE_displist.h"
44         #include "BKE_global.h"
45         #include "BKE_library.h"
46         #include "BKE_main.h"
47         #include "BKE_material.h"
48         #include "BKE_mesh.h"
49         #include "BKE_object.h"
50
51         #include "BLI_listbase.h"
52         #include "BLI_math.h"
53         #include "BLI_string.h"
54         #include "BLI_edgehash.h"
55
56         #include "MEM_guardedalloc.h"
57 }
58
59 #include "ArmatureImporter.h"
60 #include "MeshImporter.h"
61 #include "collada_utils.h"
62
63 // get node name, or fall back to original id if not present (name is optional)
64 template<class T>
65 static const std::string bc_get_dae_name(T *node)
66 {
67         return node->getName().size() ? node->getName(): node->getOriginalId();
68 }
69
70 static const char *bc_primTypeToStr(COLLADAFW::MeshPrimitive::PrimitiveType type)
71 {
72         switch (type) {
73                 case COLLADAFW::MeshPrimitive::LINES:
74                         return "LINES";
75                 case COLLADAFW::MeshPrimitive::LINE_STRIPS:
76                         return "LINESTRIPS";
77                 case COLLADAFW::MeshPrimitive::POLYGONS:
78                         return "POLYGONS";
79                 case COLLADAFW::MeshPrimitive::POLYLIST:
80                         return "POLYLIST";
81                 case COLLADAFW::MeshPrimitive::TRIANGLES:
82                         return "TRIANGLES";
83                 case COLLADAFW::MeshPrimitive::TRIANGLE_FANS:
84                         return "TRIANGLE_FANS";
85                 case COLLADAFW::MeshPrimitive::TRIANGLE_STRIPS:
86                         return "TRIANGLE_STRIPS";
87                 case COLLADAFW::MeshPrimitive::POINTS:
88                         return "POINTS";
89                 case COLLADAFW::MeshPrimitive::UNDEFINED_PRIMITIVE_TYPE:
90                         return "UNDEFINED_PRIMITIVE_TYPE";
91         }
92         return "UNKNOWN";
93 }
94
95 static const char *bc_geomTypeToStr(COLLADAFW::Geometry::GeometryType type)
96 {
97         switch (type) {
98                 case COLLADAFW::Geometry::GEO_TYPE_MESH:
99                         return "MESH";
100                 case COLLADAFW::Geometry::GEO_TYPE_SPLINE:
101                         return "SPLINE";
102                 case COLLADAFW::Geometry::GEO_TYPE_CONVEX_MESH:
103                         return "CONVEX_MESH";
104                 case COLLADAFW::Geometry::GEO_TYPE_UNKNOWN:
105                 default:
106                         return "UNKNOWN";
107         }
108 }
109
110
111 UVDataWrapper::UVDataWrapper(COLLADAFW::MeshVertexData& vdata) : mVData(&vdata)
112 {
113 }
114
115 #ifdef COLLADA_DEBUG
116 void WVDataWrapper::print()
117 {
118         fprintf(stderr, "UVs:\n");
119         switch (mVData->getType()) {
120                 case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT:
121                 {
122                         COLLADAFW::ArrayPrimitiveType<float> *values = mVData->getFloatValues();
123                         if (values->getCount()) {
124                                 for (int i = 0; i < values->getCount(); i += 2) {
125                                         fprintf(stderr, "%.1f, %.1f\n", (*values)[i], (*values)[i + 1]);
126                                 }
127                         }
128                 }
129                 break;
130                 case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE:
131                 {
132                         COLLADAFW::ArrayPrimitiveType<double> *values = mVData->getDoubleValues();
133                         if (values->getCount()) {
134                                 for (int i = 0; i < values->getCount(); i += 2) {
135                                         fprintf(stderr, "%.1f, %.1f\n", (float)(*values)[i], (float)(*values)[i + 1]);
136                                 }
137                         }
138                 }
139                 break;
140         }
141         fprintf(stderr, "\n");
142 }
143 #endif
144
145 void UVDataWrapper::getUV(int uv_index, float *uv)
146 {
147         int stride = mVData->getStride(0);
148         if (stride == 0) stride = 2;
149
150         switch (mVData->getType()) {
151                 case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT:
152                 {
153                         COLLADAFW::ArrayPrimitiveType<float> *values = mVData->getFloatValues();
154                         if (values->empty()) return;
155                         uv[0] = (*values)[uv_index * stride];
156                         uv[1] = (*values)[uv_index * stride + 1];
157
158                 }
159                 break;
160                 case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE:
161                 {
162                         COLLADAFW::ArrayPrimitiveType<double> *values = mVData->getDoubleValues();
163                         if (values->empty()) return;
164                         uv[0] = (float)(*values)[uv_index * stride];
165                         uv[1] = (float)(*values)[uv_index * stride + 1];
166
167                 }
168                 break;
169                 case COLLADAFW::MeshVertexData::DATA_TYPE_UNKNOWN:
170                 default:
171                         fprintf(stderr, "MeshImporter.getUV(): unknown data type\n");
172         }
173 }
174
175 VCOLDataWrapper::VCOLDataWrapper(COLLADAFW::MeshVertexData& vdata) : mVData(&vdata) {}
176
177 void VCOLDataWrapper::get_vcol(int v_index, MLoopCol *mloopcol)
178 {
179         int stride = mVData->getStride(0);
180         if (stride == 0) stride = 3;
181
182         switch (mVData->getType()) {
183                 case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT:
184                 {
185                         COLLADAFW::ArrayPrimitiveType<float> *values = mVData->getFloatValues();
186                         if (values->empty() || values->getCount() <= (v_index * stride + 2)) return;  // xxx need to create an eror instead
187
188                         mloopcol->r = unit_float_to_uchar_clamp((*values)[v_index * stride]);
189                         mloopcol->g = unit_float_to_uchar_clamp((*values)[v_index * stride + 1]);
190                         mloopcol->b = unit_float_to_uchar_clamp((*values)[v_index * stride + 2]);
191                 }
192                 break;
193
194                 case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE:
195                 {
196                         COLLADAFW::ArrayPrimitiveType<double> *values = mVData->getDoubleValues();
197                         if (values->empty() || values->getCount() <= (v_index * stride + 2)) return; // xxx need to create an eror instead
198
199                         mloopcol->r = unit_float_to_uchar_clamp((*values)[v_index * stride]);
200                         mloopcol->g = unit_float_to_uchar_clamp((*values)[v_index * stride + 1]);
201                         mloopcol->b = unit_float_to_uchar_clamp((*values)[v_index * stride + 2]);
202                 }
203                 break;
204                 default:
205                         fprintf(stderr, "VCOLDataWrapper.getvcol(): unknown data type\n");
206         }
207
208 }
209
210 MeshImporter::MeshImporter(UnitConverter *unitconv, ArmatureImporter *arm, Main *bmain, Scene *sce) :
211     unitconverter(unitconv),
212     m_bmain(bmain),
213     scene(sce),
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->pdata, CD_MTEXPOLY, CD_DEFAULT, NULL, me->totpoly, uvname.c_str());
480                                 CustomData_add_layer_named(&me->ldata, CD_MLOOPUV, CD_DEFAULT, NULL, me->totloop, uvname.c_str());
481                         }
482                         // activate the first uv map
483                         me->mtpoly  = (MTexPoly *)CustomData_get_layer_n(&me->pdata, CD_MTEXPOLY, 0);
484                         me->mloopuv = (MLoopUV *) CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, 0);
485                 }
486
487                 int totcolset = collada_mesh->getColors().getInputInfosArray().getCount();
488                 if (totcolset > 0) {
489                         for (int i = 0; i < totcolset; i++) {
490                                 COLLADAFW::MeshVertexData::InputInfos *info = collada_mesh->getColors().getInputInfosArray()[i];
491                                 COLLADAFW::String colname = extract_vcolname(info->mName);
492                                 CustomData_add_layer_named(&me->ldata,CD_MLOOPCOL,CD_DEFAULT,NULL,me->totloop, colname.c_str());
493                         }
494                         me->mloopcol = (MLoopCol *) CustomData_get_layer_n(&me->ldata, CD_MLOOPCOL, 0);
495                 }
496
497         }
498 }
499
500 unsigned int MeshImporter::get_vertex_count(COLLADAFW::Polygons *mp, int index) {
501         int type = mp->getPrimitiveType();
502         int result;
503         switch (type) {
504                 case COLLADAFW::MeshPrimitive::TRIANGLES:
505                 case COLLADAFW::MeshPrimitive::TRIANGLE_FANS:
506                 {
507                         result = 3;
508                         break;
509                 }
510                 case COLLADAFW::MeshPrimitive::POLYLIST:
511                 case COLLADAFW::MeshPrimitive::POLYGONS:
512                 {
513                         result = mp->getGroupedVerticesVertexCountArray()[index];
514                         break;
515                 }
516                 default:
517                 {
518                         result = -1;
519                         break;
520                 }
521         }
522         return result;
523 }
524
525
526 unsigned int MeshImporter::get_loose_edge_count(COLLADAFW::Mesh *mesh) {
527         COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives();
528         int loose_edge_count = 0;
529
530         // collect edge_count and face_count from all parts
531         for (int i = 0; i < prim_arr.getCount(); i++) {
532                 COLLADAFW::MeshPrimitive *mp = prim_arr[i];
533                 int type = mp->getPrimitiveType();
534                 switch (type) {
535                         case COLLADAFW::MeshPrimitive::LINES:
536                         {
537                                 size_t prim_totface = mp->getFaceCount();
538                                 loose_edge_count += prim_totface;
539                                 break;
540                         }
541                         default:
542                                 break;
543                 }
544         }
545         return loose_edge_count;
546 }
547
548 // =================================================================
549 // This functin is copied from source/blender/editors/mesh/mesh_data.c
550 //
551 // TODO: (As discussed with sergey-) :
552 // Maybe move this function to blenderkernel/intern/mesh.c
553 // and add definition to BKE_mesh.c
554 // =================================================================
555 void MeshImporter::mesh_add_edges(Mesh *mesh, int len)
556 {
557         CustomData edata;
558         MEdge *medge;
559         int totedge;
560
561         if (len == 0)
562                 return;
563
564         totedge = mesh->totedge + len;
565
566         /* update customdata  */
567         CustomData_copy(&mesh->edata, &edata, CD_MASK_MESH, CD_DEFAULT, totedge);
568         CustomData_copy_data(&mesh->edata, &edata, 0, 0, mesh->totedge);
569
570         if (!CustomData_has_layer(&edata, CD_MEDGE))
571                 CustomData_add_layer(&edata, CD_MEDGE, CD_CALLOC, NULL, totedge);
572
573         CustomData_free(&mesh->edata, mesh->totedge);
574         mesh->edata = edata;
575         BKE_mesh_update_customdata_pointers(mesh, false); /* new edges don't change tessellation */
576
577         /* set default flags */
578         medge = &mesh->medge[mesh->totedge];
579         for (int i = 0; i < len; i++, medge++)
580                 medge->flag = ME_EDGEDRAW | ME_EDGERENDER | SELECT;
581
582         mesh->totedge = totedge;
583 }
584
585 // =================================================================
586 // Read all loose edges.
587 // Important: This function assumes that all edges from existing
588 // faces have allready been generated and added to me->medge
589 // So this function MUST be called after read_faces() (see below)
590 // =================================================================
591 void MeshImporter::read_lines(COLLADAFW::Mesh *mesh, Mesh *me)
592 {
593         unsigned int loose_edge_count = get_loose_edge_count(mesh);
594         if (loose_edge_count > 0) {
595
596                 unsigned int face_edge_count  = me->totedge;
597                 /* unsigned int total_edge_count = loose_edge_count + face_edge_count; */ /* UNUSED */
598
599                 mesh_add_edges(me, loose_edge_count);
600                 MEdge *med = me->medge + face_edge_count;
601
602                 COLLADAFW::MeshPrimitiveArray& prim_arr = mesh->getMeshPrimitives();
603
604                 for (int i = 0; i < prim_arr.getCount(); i++) {
605
606                         COLLADAFW::MeshPrimitive *mp = prim_arr[i];
607
608                         int type = mp->getPrimitiveType();
609                         if (type == COLLADAFW::MeshPrimitive::LINES) {
610                                 unsigned int edge_count  = mp->getFaceCount();
611                                 unsigned int *indices    = mp->getPositionIndices().getData();
612
613                                 for (int j = 0; j < edge_count; j++, med++) {
614                                         med->bweight = 0;
615                                         med->crease  = 0;
616                                         med->flag   |= ME_LOOSEEDGE;
617                                         med->v1      = indices[2 * j];
618                                         med->v2      = indices[2 * j + 1];
619                                 }
620                         }
621                 }
622
623         }
624 }
625
626
627 // =======================================================================
628 // Read all faces from TRIANGLES, TRIANGLE_FANS, POLYLIST, POLYGON
629 // Important: This function MUST be called before read_lines()
630 // Otherwise we will loose all edges from faces (see read_lines() above)
631 //
632 // TODO: import uv set names
633 // ========================================================================
634 void MeshImporter::read_polys(COLLADAFW::Mesh *collada_mesh, Mesh *me)
635 {
636         unsigned int i;
637
638         allocate_poly_data(collada_mesh, me);
639
640         UVDataWrapper uvs(collada_mesh->getUVCoords());
641         VCOLDataWrapper vcol(collada_mesh->getColors());
642
643         MPoly *mpoly = me->mpoly;
644         MLoop *mloop = me->mloop;
645         int loop_index = 0;
646
647         MaterialIdPrimitiveArrayMap mat_prim_map;
648
649         COLLADAFW::MeshPrimitiveArray& prim_arr = collada_mesh->getMeshPrimitives();
650         COLLADAFW::MeshVertexData& nor = collada_mesh->getNormals();
651
652         for (i = 0; i < prim_arr.getCount(); i++) {
653
654                 COLLADAFW::MeshPrimitive *mp = prim_arr[i];
655
656                 // faces
657                 size_t prim_totpoly                           = mp->getFaceCount();
658                 unsigned int *position_indices                = mp->getPositionIndices().getData();
659                 unsigned int *normal_indices                  = mp->getNormalIndices().getData();
660
661
662                 bool mp_has_normals = primitive_has_useable_normals(mp);
663                 bool mp_has_faces   = primitive_has_faces(mp);
664
665                 int collada_meshtype = mp->getPrimitiveType();
666
667                 // since we cannot set mpoly->mat_nr here, we store a portion of me->mpoly in Primitive
668                 Primitive prim = {mpoly, 0};
669
670                 // If MeshPrimitive is TRIANGLE_FANS we split it into triangles
671                 // The first trifan vertex will be the first vertex in every triangle
672                 // XXX The proper function of TRIANGLE_FANS is not tested!!!
673                 // XXX In particular the handling of the normal_indices looks very wrong to me
674                 if (collada_meshtype == COLLADAFW::MeshPrimitive::TRIANGLE_FANS) {
675                         unsigned grouped_vertex_count = mp->getGroupedVertexElementsCount();
676                         for (unsigned int group_index = 0; group_index < grouped_vertex_count; group_index++) {
677                                 unsigned int first_vertex = position_indices[0]; // Store first trifan vertex
678                                 unsigned int first_normal = normal_indices[0]; // Store first trifan vertex normal
679                                 unsigned int vertex_count = mp->getGroupedVerticesVertexCount(group_index);
680
681                                 for (unsigned int vertex_index = 0; vertex_index < vertex_count - 2; vertex_index++) {
682                                         // For each triangle store indeces of its 3 vertices
683                                         unsigned int triangle_vertex_indices[3] = {first_vertex, position_indices[1], position_indices[2]};
684                                         set_poly_indices(mpoly, mloop, loop_index, triangle_vertex_indices, 3);
685
686                                         if (mp_has_normals) {  // vertex normals, same inplementation as for the triangles
687                                                 // the same for vertces normals
688                                                 unsigned int vertex_normal_indices[3] = {first_normal, normal_indices[1], normal_indices[2]};
689                                                 if (!is_flat_face(vertex_normal_indices, nor, 3))
690                                                         mpoly->flag |= ME_SMOOTH;
691                                                 normal_indices++;
692                                         }
693
694                                         mpoly++;
695                                         mloop += 3;
696                                         loop_index += 3;
697                                         prim.totpoly++;
698
699                                 }
700
701                                 // Moving cursor  to the next triangle fan.
702                                 if (mp_has_normals)
703                                         normal_indices += 2;
704
705                                 position_indices +=  2;
706                         }
707                 }
708
709                 if (collada_meshtype == COLLADAFW::MeshPrimitive::POLYLIST ||
710                     collada_meshtype == COLLADAFW::MeshPrimitive::POLYGONS ||
711                     collada_meshtype == COLLADAFW::MeshPrimitive::TRIANGLES)
712                 {
713                         COLLADAFW::Polygons *mpvc = (COLLADAFW::Polygons *)mp;
714                         unsigned int start_index = 0;
715
716                         COLLADAFW::IndexListArray& index_list_array_uvcoord = mp->getUVCoordIndicesArray();
717                         COLLADAFW::IndexListArray& index_list_array_vcolor  = mp->getColorIndicesArray();
718
719                         int invalid_loop_holes = 0;
720                         for (unsigned int j = 0; j < prim_totpoly; j++) {
721
722                                 // Vertices in polygon:
723                                 int vcount = get_vertex_count(mpvc, j);
724                                 if (vcount < 0) {
725                                         continue; // TODO: add support for holes
726                                 }
727
728                                 bool broken_loop = set_poly_indices(mpoly, mloop, loop_index, position_indices, vcount);
729                                 if (broken_loop)
730                                 {
731                                         invalid_loop_holes += 1;
732                                 }
733
734                                 for (unsigned int uvset_index = 0; uvset_index < index_list_array_uvcoord.getCount(); uvset_index++) {
735                                         // get mtface by face index and uv set index
736                                         COLLADAFW::IndexList& index_list = *index_list_array_uvcoord[uvset_index];
737                                         MLoopUV  *mloopuv = (MLoopUV  *)CustomData_get_layer_named(&me->ldata, CD_MLOOPUV, index_list.getName().c_str());
738                                         if (mloopuv == NULL) {
739                                                 fprintf(stderr, "Collada import: Mesh [%s] : Unknown reference to TEXCOORD [#%s].\n", me->id.name, index_list.getName().c_str() );
740                                         }
741                                         else {
742                                                 set_face_uv(mloopuv+loop_index, uvs, start_index, *index_list_array_uvcoord[uvset_index], vcount);
743                                         }
744                                 }
745
746                                 if (mp_has_normals) {
747                                         if (!is_flat_face(normal_indices, nor, vcount))
748                                                 mpoly->flag |= ME_SMOOTH;
749                                 }
750
751
752                                 if (mp->hasColorIndices()) {
753                                         int vcolor_count = index_list_array_vcolor.getCount();
754
755                                         for (unsigned int vcolor_index = 0; vcolor_index < vcolor_count; vcolor_index++) {
756
757                                                 COLLADAFW::IndexList& color_index_list = *mp->getColorIndices(vcolor_index);
758                                                 COLLADAFW::String colname = extract_vcolname(color_index_list.getName());
759                                                 MLoopCol *mloopcol = (MLoopCol  *)CustomData_get_layer_named(&me->ldata, CD_MLOOPCOL, colname.c_str());
760                                                 if (mloopcol == NULL) {
761                                                         fprintf(stderr, "Collada import: Mesh [%s] : Unknown reference to VCOLOR [#%s].\n", me->id.name, color_index_list.getName().c_str());
762                                                 }
763                                                 else {
764                                                         set_vcol(mloopcol + loop_index, vcol, start_index, color_index_list, vcount);
765                                                 }
766                                         }
767                                 }
768
769                                 mpoly++;
770                                 mloop       += vcount;
771                                 loop_index  += vcount;
772                                 start_index += vcount;
773                                 prim.totpoly++;
774
775                                 if (mp_has_normals)
776                                         normal_indices += vcount;
777
778                                 position_indices += vcount;
779                         }
780
781                         if (invalid_loop_holes > 0)
782                         {
783                                 fprintf(stderr, "Collada import: Mesh [%s] : contains %d unsupported loops (holes).\n", me->id.name, invalid_loop_holes);
784                         }
785                 }
786
787                 else if (collada_meshtype == COLLADAFW::MeshPrimitive::LINES) {
788                         continue; // read the lines later after all the rest is done
789                 }
790
791                 if (mp_has_faces)
792                         mat_prim_map[mp->getMaterialId()].push_back(prim);
793
794
795         }
796
797         geom_uid_mat_mapping_map[collada_mesh->getUniqueId()] = mat_prim_map;
798 }
799
800 void MeshImporter::get_vector(float v[3], COLLADAFW::MeshVertexData& arr, int i, int stride)
801 {
802         i *= stride;
803
804         switch (arr.getType()) {
805                 case COLLADAFW::MeshVertexData::DATA_TYPE_FLOAT:
806                 {
807                         COLLADAFW::ArrayPrimitiveType<float> *values = arr.getFloatValues();
808                         if (values->empty()) return;
809
810                         v[0] = (*values)[i++];
811                         v[1] = (*values)[i++];
812                         if (stride>=3) {
813                                 v[2] = (*values)[i];
814                         }
815                         else {
816                                 v[2] = 0.0f;
817                         }
818
819                 }
820                 break;
821                 case COLLADAFW::MeshVertexData::DATA_TYPE_DOUBLE:
822                 {
823                         COLLADAFW::ArrayPrimitiveType<double> *values = arr.getDoubleValues();
824                         if (values->empty()) return;
825
826                         v[0] = (float)(*values)[i++];
827                         v[1] = (float)(*values)[i++];
828                         if (stride >= 3) {
829                                 v[2] = (float)(*values)[i];
830                         }
831                         else {
832                                 v[2] = 0.0f;
833                         }
834                 }
835                 break;
836                 default:
837                         break;
838         }
839 }
840
841 bool MeshImporter::is_flat_face(unsigned int *nind, COLLADAFW::MeshVertexData& nor, int count)
842 {
843         float a[3], b[3];
844
845         get_vector(a, nor, *nind, 3);
846         normalize_v3(a);
847
848         nind++;
849
850         for (int i = 1; i < count; i++, nind++) {
851                 get_vector(b, nor, *nind, 3);
852                 normalize_v3(b);
853
854                 float dp = dot_v3v3(a, b);
855
856                 if (dp < 0.99999f || dp > 1.00001f)
857                         return false;
858         }
859
860         return true;
861 }
862
863 Object *MeshImporter::get_object_by_geom_uid(const COLLADAFW::UniqueId& geom_uid)
864 {
865         if (uid_object_map.find(geom_uid) != uid_object_map.end())
866                 return uid_object_map[geom_uid];
867         return NULL;
868 }
869
870 Mesh *MeshImporter::get_mesh_by_geom_uid(const COLLADAFW::UniqueId& mesh_uid)
871 {
872         if (uid_mesh_map.find(mesh_uid) != uid_mesh_map.end())
873                 return uid_mesh_map[mesh_uid];
874         return NULL;
875 }
876
877 std::string *MeshImporter::get_geometry_name(const std::string &mesh_name)
878 {
879         if (this->mesh_geom_map.find(mesh_name) != this->mesh_geom_map.end())
880                 return &this->mesh_geom_map[mesh_name];
881         return NULL;
882 }
883
884 MTex *MeshImporter::assign_textures_to_uvlayer(COLLADAFW::TextureCoordinateBinding &ctexture,
885                                                Mesh *me, TexIndexTextureArrayMap& texindex_texarray_map,
886                                                MTex *color_texture)
887 {
888         const COLLADAFW::TextureMapId texture_index = ctexture.getTextureMapId();
889         size_t setindex = ctexture.getSetIndex();
890         std::string uvname = ctexture.getSemantic();
891
892         if (setindex == -1) return NULL;
893
894         const CustomData *data = &me->fdata;
895         int layer_index = CustomData_get_layer_index(data, CD_MTFACE);
896
897         if (layer_index == -1) return NULL;
898
899         CustomDataLayer *cdl = &data->layers[layer_index + setindex];
900
901         /* set uvname to bind_vertex_input semantic */
902         BLI_strncpy(cdl->name, uvname.c_str(), sizeof(cdl->name));
903
904         if (texindex_texarray_map.find(texture_index) == texindex_texarray_map.end()) {
905
906                 fprintf(stderr, "Cannot find texture array by texture index.\n");
907                 return color_texture;
908         }
909
910         std::vector<MTex *> textures = texindex_texarray_map[texture_index];
911
912         std::vector<MTex *>::iterator it;
913
914         for (it = textures.begin(); it != textures.end(); it++) {
915
916                 MTex *texture = *it;
917
918                 if (texture) {
919                         BLI_strncpy(texture->uvname, uvname.c_str(), sizeof(texture->uvname));
920                         if (texture->mapto == MAP_COL) color_texture = texture;
921                 }
922         }
923         return color_texture;
924 }
925
926 /**
927  * this function checks if both objects have the same
928  * materials assigned to Object (in the same order)
929  * returns true if condition matches, otherwise false;
930  **/
931 static bool bc_has_same_material_configuration(Object *ob1, Object *ob2)
932 {
933         if (ob1->totcol != ob2->totcol) return false; // not same number of materials
934         if (ob1->totcol == 0) return false; // no material at all
935
936         for (int index=0; index < ob1->totcol; index++) {
937                 if (ob1->matbits[index] != ob2->matbits[index]) return false; // shouldn't happen
938                 if (ob1->matbits[index] == 0) return false; // shouldn't happen
939                 if (ob1->mat[index] != ob2->mat[index]) return false; // different material assignment
940         }
941         return true;
942 }
943
944
945 /**
946  *
947  * Caution here: This code assumes tha all materials are assigned to Object
948  * and no material is assigned to Data.
949  * That is true right after the objects have been imported.
950  *
951  **/
952 static void bc_copy_materials_to_data(Object *ob, Mesh *me)
953 {
954         for (int index = 0; index < ob->totcol; index++) {
955                 ob->matbits[index] = 0;
956                 me->mat[index] = ob->mat[index];
957         }
958 }
959
960 /**
961  *
962  * Remove all references to materials from the object
963  *
964  **/
965 static void bc_remove_materials_from_object(Object *ob, Mesh *me)
966 {
967         for (int index = 0; index < ob->totcol; index++) {
968                 ob->matbits[index] = 0;
969                 ob->mat[index] = NULL;
970         }
971 }
972
973 /**
974  * Returns the list of Users of the given Mesh object.
975  * Note: This function uses the object user flag to control
976  * which objects have already been processed.
977  **/
978 std::vector<Object *> MeshImporter::get_all_users_of(Mesh *reference_mesh)
979 {
980         std::vector<Object *> mesh_users;
981         for (std::vector<Object *>::iterator it = imported_objects.begin();
982              it != imported_objects.end(); ++it)
983         {
984                 Object *ob = (*it);
985                 if (bc_is_marked(ob)) {
986                         bc_remove_mark(ob);
987                         Mesh *me = (Mesh *) ob->data;
988                         if (me == reference_mesh)
989                                 mesh_users.push_back(ob);
990                 }
991         }
992         return mesh_users;
993 }
994
995 /**
996  *
997  * During import all materials have been assigned to Object.
998  * Now we iterate over the imported objects and optimize
999  * the assignments as follows:
1000  *
1001  * for each imported geometry:
1002  *     if number of users is 1:
1003  *         get the user (object)
1004  *         move the materials from Object to Data
1005  *     else:
1006  *         determine which materials are assigned to the first user
1007  *         check if all other users have the same materials in the same order
1008  *         if the check is positive:
1009  *             Add the materials of the first user to the geometry
1010  *             adjust all other users accordingly.
1011  *
1012  **/
1013 void MeshImporter::optimize_material_assignements()
1014 {
1015         for (std::vector<Object *>::iterator it = imported_objects.begin();
1016              it != imported_objects.end(); ++it)
1017         {
1018                 Object *ob = (*it);
1019                 Mesh *me = (Mesh *) ob->data;
1020                 if (me->id.us==1) {
1021                         bc_copy_materials_to_data(ob, me);
1022                         bc_remove_materials_from_object(ob, me);
1023                         bc_remove_mark(ob);
1024                 }
1025                 else if (me->id.us > 1)
1026                 {
1027                         bool can_move = true;
1028                         std::vector<Object *> mesh_users = get_all_users_of(me);
1029                         if (mesh_users.size() > 1)
1030                         {
1031                                 Object *ref_ob = mesh_users[0];
1032                                 for (int index = 1; index < mesh_users.size(); index++) {
1033                                         if (!bc_has_same_material_configuration(ref_ob, mesh_users[index])) {
1034                                                 can_move = false;
1035                                                 break;
1036                                         }
1037                                 }
1038                                 if (can_move) {
1039                                         bc_copy_materials_to_data(ref_ob, me);
1040                                         for (int index = 0; index < mesh_users.size(); index++) {
1041                                                 Object *object = mesh_users[index];
1042                                                 bc_remove_materials_from_object(object, me);
1043                                                 bc_remove_mark(object);
1044                                         }
1045                                 }
1046                         }
1047                 }
1048         }
1049 }
1050
1051 /**
1052  * We do not know in advance which objects will share geometries.
1053  * And we do not know either if the objects which share geometries
1054  * come along with different materials. So we first create the objects
1055  * and assign the materials to Object, then in a later cleanup we decide
1056  * which materials shall be moved to the created geometries. Also see
1057  * optimize_material_assignements() above.
1058  */
1059 MTFace *MeshImporter::assign_material_to_geom(COLLADAFW::MaterialBinding cmaterial,
1060                                               std::map<COLLADAFW::UniqueId, Material *>& uid_material_map,
1061                                               Object *ob, const COLLADAFW::UniqueId *geom_uid,
1062                                               char *layername, MTFace *texture_face,
1063                                               std::map<Material *, TexIndexTextureArrayMap>& material_texture_mapping_map, short mat_index)
1064 {
1065         MTex *color_texture = NULL;
1066         Mesh *me = (Mesh *)ob->data;
1067         const COLLADAFW::UniqueId& ma_uid = cmaterial.getReferencedMaterial();
1068
1069         // do we know this material?
1070         if (uid_material_map.find(ma_uid) == uid_material_map.end()) {
1071
1072                 fprintf(stderr, "Cannot find material by UID.\n");
1073                 return NULL;
1074         }
1075
1076         // first time we get geom_uid, ma_uid pair. Save for later check.
1077         materials_mapped_to_geom.insert(std::pair<COLLADAFW::UniqueId, COLLADAFW::UniqueId>(*geom_uid, ma_uid));
1078
1079         Material *ma = uid_material_map[ma_uid];
1080
1081         // Attention! This temporaly assigns material to object on purpose!
1082         // See note above.
1083         ob->actcol=0;
1084         assign_material(m_bmain, ob, ma, mat_index + 1, BKE_MAT_ASSIGN_OBJECT);
1085
1086         COLLADAFW::TextureCoordinateBindingArray& tex_array =
1087             cmaterial.getTextureCoordinateBindingArray();
1088         TexIndexTextureArrayMap texindex_texarray_map = material_texture_mapping_map[ma];
1089         unsigned int i;
1090         // loop through <bind_vertex_inputs>
1091         for (i = 0; i < tex_array.getCount(); i++) {
1092
1093                 color_texture = assign_textures_to_uvlayer(tex_array[i], me, texindex_texarray_map,
1094                                                             color_texture);
1095         }
1096
1097         // set texture face
1098         if (color_texture &&
1099             strlen((color_texture)->uvname) &&
1100             !STREQ(layername, color_texture->uvname))
1101         {
1102                 texture_face = (MTFace *)CustomData_get_layer_named(&me->fdata, CD_MTFACE,
1103                                                                     color_texture->uvname);
1104                 strcpy(layername, color_texture->uvname);
1105         }
1106
1107         MaterialIdPrimitiveArrayMap& mat_prim_map = geom_uid_mat_mapping_map[*geom_uid];
1108         COLLADAFW::MaterialId mat_id = cmaterial.getMaterialId();
1109
1110         // assign material indices to mesh faces
1111         if (mat_prim_map.find(mat_id) != mat_prim_map.end()) {
1112
1113                 std::vector<Primitive>& prims = mat_prim_map[mat_id];
1114
1115                 std::vector<Primitive>::iterator it;
1116
1117                 for (it = prims.begin(); it != prims.end(); it++) {
1118                         Primitive& prim = *it;
1119                         MPoly *mpoly = prim.mpoly;
1120
1121                         for (i = 0; i < prim.totpoly; i++, mpoly++) {
1122                                 mpoly->mat_nr = mat_index;
1123                                 // bind texture images to faces
1124                                 if (texture_face && color_texture) {
1125                                         texture_face->tpage = (Image *)color_texture->tex->ima;
1126                                         texture_face++;
1127                                 }
1128                         }
1129                 }
1130         }
1131         return texture_face;
1132 }
1133
1134 Object *MeshImporter::create_mesh_object(COLLADAFW::Node *node, COLLADAFW::InstanceGeometry *geom,
1135                                          bool isController,
1136                                          std::map<COLLADAFW::UniqueId, Material *>& uid_material_map,
1137                                          std::map<Material *, TexIndexTextureArrayMap>& material_texture_mapping_map)
1138 {
1139         const COLLADAFW::UniqueId *geom_uid = &geom->getInstanciatedObjectId();
1140
1141         // check if node instanciates controller or geometry
1142         if (isController) {
1143
1144                 geom_uid = armature_importer->get_geometry_uid(*geom_uid);
1145
1146                 if (!geom_uid) {
1147                         fprintf(stderr, "Couldn't find a mesh UID by controller's UID.\n");
1148                         return NULL;
1149                 }
1150         }
1151         else {
1152
1153                 if (uid_mesh_map.find(*geom_uid) == uid_mesh_map.end()) {
1154                         // this could happen if a mesh was not created
1155                         // (e.g. if it contains unsupported geometry)
1156                         fprintf(stderr, "Couldn't find a mesh by UID.\n");
1157                         return NULL;
1158                 }
1159         }
1160         if (!uid_mesh_map[*geom_uid]) return NULL;
1161
1162         // name Object
1163         const std::string& id = node->getName().size() ? node->getName() : node->getOriginalId();
1164         const char *name = (id.length()) ? id.c_str() : NULL;
1165
1166         // add object
1167         Object *ob = bc_add_object(m_bmain, scene, OB_MESH, name);
1168         bc_set_mark(ob); // used later for material assignement optimization
1169
1170
1171         // store object pointer for ArmatureImporter
1172         uid_object_map[*geom_uid] = ob;
1173         imported_objects.push_back(ob);
1174
1175         // replace ob->data freeing the old one
1176         Mesh *old_mesh = (Mesh *)ob->data;
1177         Mesh *new_mesh = uid_mesh_map[*geom_uid];
1178
1179         BKE_mesh_assign_object(m_bmain, ob, new_mesh);
1180         BKE_mesh_calc_normals(new_mesh);
1181
1182         id_us_plus(&old_mesh->id);  /* Because BKE_mesh_assign_object would have already decreased it... */
1183         BKE_libblock_free_us(m_bmain, old_mesh);
1184
1185         char layername[100];
1186         layername[0] = '\0';
1187         MTFace *texture_face = NULL;
1188
1189         COLLADAFW::MaterialBindingArray& mat_array =
1190             geom->getMaterialBindings();
1191
1192         // loop through geom's materials
1193         for (unsigned int i = 0; i < mat_array.getCount(); i++) {
1194
1195                 if (mat_array[i].getReferencedMaterial().isValid()) {
1196                         texture_face = assign_material_to_geom(mat_array[i], uid_material_map, ob, geom_uid,
1197                                                                layername, texture_face,
1198                                                                material_texture_mapping_map, i);
1199                 }
1200                 else {
1201                         fprintf(stderr, "invalid referenced material for %s\n", mat_array[i].getName().c_str());
1202                 }
1203         }
1204
1205         return ob;
1206 }
1207
1208 // create a mesh storing a pointer in a map so it can be retrieved later by geometry UID
1209 bool MeshImporter::write_geometry(const COLLADAFW::Geometry *geom)
1210 {
1211
1212         if (geom->getType() != COLLADAFW::Geometry::GEO_TYPE_MESH) {
1213                 // TODO: report warning
1214                 fprintf(stderr, "Mesh type %s is not supported\n", bc_geomTypeToStr(geom->getType()));
1215                 return true;
1216         }
1217
1218         COLLADAFW::Mesh *mesh = (COLLADAFW::Mesh *)geom;
1219
1220         if (!is_nice_mesh(mesh)) {
1221                 fprintf(stderr, "Ignoring mesh %s\n", bc_get_dae_name(mesh).c_str());
1222                 return true;
1223         }
1224
1225         const std::string& str_geom_id = mesh->getName().size() ? mesh->getName() : mesh->getOriginalId();
1226         Mesh *me = BKE_mesh_add(m_bmain, (char *)str_geom_id.c_str());
1227         id_us_min(&me->id); // is already 1 here, but will be set later in BKE_mesh_assign_object
1228
1229         // store the Mesh pointer to link it later with an Object
1230         // mesh_geom_map needed to map mesh to its geometry name (for shape key naming)
1231         this->uid_mesh_map[mesh->getUniqueId()] = me;
1232         this->mesh_geom_map[std::string(me->id.name)] = str_geom_id;
1233
1234         read_vertices(mesh, me);
1235         read_polys(mesh, me);
1236
1237         // must validate before calculating edges
1238         BKE_mesh_calc_normals(me);
1239         BKE_mesh_validate(me, false, false);
1240         // validation does this
1241         // BKE_mesh_calc_edges(me, false, false);
1242
1243         // read_lines() must be called after the face edges have been generated.
1244         // Oterwise the loose edges will be silently deleted again.
1245         read_lines(mesh, me);
1246
1247         return true;
1248 }