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