Revert to master - those changes are globally valid, but remain incomplete,
[blender.git] / source / blender / blenkernel / intern / mesh.c
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  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * Contributor(s): Blender Foundation
22  *
23  * ***** END GPL LICENSE BLOCK *****
24  */
25
26 /** \file blender/blenkernel/intern/mesh.c
27  *  \ingroup bke
28  */
29
30 #include "MEM_guardedalloc.h"
31
32 #include "DNA_scene_types.h"
33 #include "DNA_material_types.h"
34 #include "DNA_object_types.h"
35 #include "DNA_key_types.h"
36 #include "DNA_mesh_types.h"
37 #include "DNA_ipo_types.h"
38
39 #include "BLI_utildefines.h"
40 #include "BLI_math.h"
41 #include "BLI_listbase.h"
42 #include "BLI_edgehash.h"
43 #include "BLI_string.h"
44
45 #include "BKE_animsys.h"
46 #include "BKE_main.h"
47 #include "BKE_DerivedMesh.h"
48 #include "BKE_global.h"
49 #include "BKE_mesh.h"
50 #include "BKE_displist.h"
51 #include "BKE_library.h"
52 #include "BKE_material.h"
53 #include "BKE_modifier.h"
54 #include "BKE_multires.h"
55 #include "BKE_key.h"
56 #include "BKE_mball.h"
57 #include "BKE_depsgraph.h"
58 /* these 2 are only used by conversion functions */
59 #include "BKE_curve.h"
60 /* -- */
61 #include "BKE_object.h"
62 #include "BKE_editmesh.h"
63
64 #include "DEG_depsgraph.h"
65
66 enum {
67         MESHCMP_DVERT_WEIGHTMISMATCH = 1,
68         MESHCMP_DVERT_GROUPMISMATCH,
69         MESHCMP_DVERT_TOTGROUPMISMATCH,
70         MESHCMP_LOOPCOLMISMATCH,
71         MESHCMP_LOOPUVMISMATCH,
72         MESHCMP_LOOPMISMATCH,
73         MESHCMP_POLYVERTMISMATCH,
74         MESHCMP_POLYMISMATCH,
75         MESHCMP_EDGEUNKNOWN,
76         MESHCMP_VERTCOMISMATCH,
77         MESHCMP_CDLAYERS_MISMATCH
78 };
79
80 static const char *cmpcode_to_str(int code)
81 {
82         switch (code) {
83                 case MESHCMP_DVERT_WEIGHTMISMATCH:
84                         return "Vertex Weight Mismatch";
85                 case MESHCMP_DVERT_GROUPMISMATCH:
86                         return "Vertex Group Mismatch";
87                 case MESHCMP_DVERT_TOTGROUPMISMATCH:
88                         return "Vertex Doesn't Belong To Same Number Of Groups";
89                 case MESHCMP_LOOPCOLMISMATCH:
90                         return "Vertex Color Mismatch";
91                 case MESHCMP_LOOPUVMISMATCH:
92                         return "UV Mismatch";
93                 case MESHCMP_LOOPMISMATCH:
94                         return "Loop Mismatch";
95                 case MESHCMP_POLYVERTMISMATCH:
96                         return "Loop Vert Mismatch In Poly Test";
97                 case MESHCMP_POLYMISMATCH:
98                         return "Loop Vert Mismatch";
99                 case MESHCMP_EDGEUNKNOWN:
100                         return "Edge Mismatch";
101                 case MESHCMP_VERTCOMISMATCH:
102                         return "Vertex Coordinate Mismatch";
103                 case MESHCMP_CDLAYERS_MISMATCH:
104                         return "CustomData Layer Count Mismatch";
105                 default:
106                         return "Mesh Comparison Code Unknown";
107         }
108 }
109
110 /* thresh is threshold for comparing vertices, uvs, vertex colors,
111  * weights, etc.*/
112 static int customdata_compare(CustomData *c1, CustomData *c2, Mesh *m1, Mesh *m2, const float thresh)
113 {
114         const float thresh_sq = thresh * thresh;
115         CustomDataLayer *l1, *l2;
116         int i, i1 = 0, i2 = 0, tot, j;
117         
118         for (i = 0; i < c1->totlayer; i++) {
119                 if (ELEM(c1->layers[i].type, CD_MVERT, CD_MEDGE, CD_MPOLY,
120                          CD_MLOOPUV, CD_MLOOPCOL, CD_MTEXPOLY, CD_MDEFORMVERT))
121                 {
122                         i1++;
123                 }
124         }
125
126         for (i = 0; i < c2->totlayer; i++) {
127                 if (ELEM(c2->layers[i].type, CD_MVERT, CD_MEDGE, CD_MPOLY,
128                          CD_MLOOPUV, CD_MLOOPCOL, CD_MTEXPOLY, CD_MDEFORMVERT))
129                 {
130                         i2++;
131                 }
132         }
133
134         if (i1 != i2)
135                 return MESHCMP_CDLAYERS_MISMATCH;
136         
137         l1 = c1->layers; l2 = c2->layers;
138         tot = i1;
139         i1 = 0; i2 = 0;
140         for (i = 0; i < tot; i++) {
141                 while (i1 < c1->totlayer && !ELEM(l1->type, CD_MVERT, CD_MEDGE, CD_MPOLY,
142                                                   CD_MLOOPUV, CD_MLOOPCOL, CD_MTEXPOLY, CD_MDEFORMVERT))
143                 {
144                         i1++, l1++;
145                 }
146
147                 while (i2 < c2->totlayer && !ELEM(l2->type, CD_MVERT, CD_MEDGE, CD_MPOLY,
148                                                   CD_MLOOPUV, CD_MLOOPCOL, CD_MTEXPOLY, CD_MDEFORMVERT))
149                 {
150                         i2++, l2++;
151                 }
152                 
153                 if (l1->type == CD_MVERT) {
154                         MVert *v1 = l1->data;
155                         MVert *v2 = l2->data;
156                         int vtot = m1->totvert;
157                         
158                         for (j = 0; j < vtot; j++, v1++, v2++) {
159                                 if (len_squared_v3v3(v1->co, v2->co) > thresh_sq)
160                                         return MESHCMP_VERTCOMISMATCH;
161                                 /* I don't care about normals, let's just do coodinates */
162                         }
163                 }
164                 
165                 /*we're order-agnostic for edges here*/
166                 if (l1->type == CD_MEDGE) {
167                         MEdge *e1 = l1->data;
168                         MEdge *e2 = l2->data;
169                         int etot = m1->totedge;
170                         EdgeHash *eh = BLI_edgehash_new_ex(__func__, etot);
171                 
172                         for (j = 0; j < etot; j++, e1++) {
173                                 BLI_edgehash_insert(eh, e1->v1, e1->v2, e1);
174                         }
175                         
176                         for (j = 0; j < etot; j++, e2++) {
177                                 if (!BLI_edgehash_lookup(eh, e2->v1, e2->v2))
178                                         return MESHCMP_EDGEUNKNOWN;
179                         }
180                         BLI_edgehash_free(eh, NULL);
181                 }
182                 
183                 if (l1->type == CD_MPOLY) {
184                         MPoly *p1 = l1->data;
185                         MPoly *p2 = l2->data;
186                         int ptot = m1->totpoly;
187                 
188                         for (j = 0; j < ptot; j++, p1++, p2++) {
189                                 MLoop *lp1, *lp2;
190                                 int k;
191                                 
192                                 if (p1->totloop != p2->totloop)
193                                         return MESHCMP_POLYMISMATCH;
194                                 
195                                 lp1 = m1->mloop + p1->loopstart;
196                                 lp2 = m2->mloop + p2->loopstart;
197                                 
198                                 for (k = 0; k < p1->totloop; k++, lp1++, lp2++) {
199                                         if (lp1->v != lp2->v)
200                                                 return MESHCMP_POLYVERTMISMATCH;
201                                 }
202                         }
203                 }
204                 if (l1->type == CD_MLOOP) {
205                         MLoop *lp1 = l1->data;
206                         MLoop *lp2 = l2->data;
207                         int ltot = m1->totloop;
208                 
209                         for (j = 0; j < ltot; j++, lp1++, lp2++) {
210                                 if (lp1->v != lp2->v)
211                                         return MESHCMP_LOOPMISMATCH;
212                         }
213                 }
214                 if (l1->type == CD_MLOOPUV) {
215                         MLoopUV *lp1 = l1->data;
216                         MLoopUV *lp2 = l2->data;
217                         int ltot = m1->totloop;
218                 
219                         for (j = 0; j < ltot; j++, lp1++, lp2++) {
220                                 if (len_squared_v2v2(lp1->uv, lp2->uv) > thresh_sq)
221                                         return MESHCMP_LOOPUVMISMATCH;
222                         }
223                 }
224                 
225                 if (l1->type == CD_MLOOPCOL) {
226                         MLoopCol *lp1 = l1->data;
227                         MLoopCol *lp2 = l2->data;
228                         int ltot = m1->totloop;
229                 
230                         for (j = 0; j < ltot; j++, lp1++, lp2++) {
231                                 if (ABS(lp1->r - lp2->r) > thresh || 
232                                     ABS(lp1->g - lp2->g) > thresh || 
233                                     ABS(lp1->b - lp2->b) > thresh || 
234                                     ABS(lp1->a - lp2->a) > thresh)
235                                 {
236                                         return MESHCMP_LOOPCOLMISMATCH;
237                                 }
238                         }
239                 }
240
241                 if (l1->type == CD_MDEFORMVERT) {
242                         MDeformVert *dv1 = l1->data;
243                         MDeformVert *dv2 = l2->data;
244                         int dvtot = m1->totvert;
245                 
246                         for (j = 0; j < dvtot; j++, dv1++, dv2++) {
247                                 int k;
248                                 MDeformWeight *dw1 = dv1->dw, *dw2 = dv2->dw;
249                                 
250                                 if (dv1->totweight != dv2->totweight)
251                                         return MESHCMP_DVERT_TOTGROUPMISMATCH;
252                                 
253                                 for (k = 0; k < dv1->totweight; k++, dw1++, dw2++) {
254                                         if (dw1->def_nr != dw2->def_nr)
255                                                 return MESHCMP_DVERT_GROUPMISMATCH;
256                                         if (fabsf(dw1->weight - dw2->weight) > thresh)
257                                                 return MESHCMP_DVERT_WEIGHTMISMATCH;
258                                 }
259                         }
260                 }
261         }
262         
263         return 0;
264 }
265
266 /**
267  * Used for unit testing; compares two meshes, checking only
268  * differences we care about.  should be usable with leaf's
269  * testing framework I get RNA work done, will use hackish
270  * testing code for now.
271  */
272 const char *BKE_mesh_cmp(Mesh *me1, Mesh *me2, float thresh)
273 {
274         int c;
275         
276         if (!me1 || !me2)
277                 return "Requires two input meshes";
278         
279         if (me1->totvert != me2->totvert) 
280                 return "Number of verts don't match";
281         
282         if (me1->totedge != me2->totedge)
283                 return "Number of edges don't match";
284         
285         if (me1->totpoly != me2->totpoly)
286                 return "Number of faces don't match";
287                                 
288         if (me1->totloop != me2->totloop)
289                 return "Number of loops don't match";
290         
291         if ((c = customdata_compare(&me1->vdata, &me2->vdata, me1, me2, thresh)))
292                 return cmpcode_to_str(c);
293
294         if ((c = customdata_compare(&me1->edata, &me2->edata, me1, me2, thresh)))
295                 return cmpcode_to_str(c);
296
297         if ((c = customdata_compare(&me1->ldata, &me2->ldata, me1, me2, thresh)))
298                 return cmpcode_to_str(c);
299
300         if ((c = customdata_compare(&me1->pdata, &me2->pdata, me1, me2, thresh)))
301                 return cmpcode_to_str(c);
302         
303         return NULL;
304 }
305
306 static void mesh_ensure_tessellation_customdata(Mesh *me)
307 {
308         if (UNLIKELY((me->totface != 0) && (me->totpoly == 0))) {
309                 /* Pass, otherwise this function  clears 'mface' before
310                  * versioning 'mface -> mpoly' code kicks in [#30583]
311                  *
312                  * Callers could also check but safer to do here - campbell */
313         }
314         else {
315                 const int tottex_original = CustomData_number_of_layers(&me->pdata, CD_MTEXPOLY);
316                 const int totcol_original = CustomData_number_of_layers(&me->ldata, CD_MLOOPCOL);
317
318                 const int tottex_tessface = CustomData_number_of_layers(&me->fdata, CD_MTFACE);
319                 const int totcol_tessface = CustomData_number_of_layers(&me->fdata, CD_MCOL);
320
321                 if (tottex_tessface != tottex_original ||
322                     totcol_tessface != totcol_original)
323                 {
324                         BKE_mesh_tessface_clear(me);
325
326                         CustomData_from_bmeshpoly(&me->fdata, &me->pdata, &me->ldata, me->totface);
327
328                         /* TODO - add some --debug-mesh option */
329                         if (G.debug & G_DEBUG) {
330                                 /* note: this warning may be un-called for if we are initializing the mesh for the
331                                  * first time from bmesh, rather then giving a warning about this we could be smarter
332                                  * and check if there was any data to begin with, for now just print the warning with
333                                  * some info to help troubleshoot whats going on - campbell */
334                                 printf("%s: warning! Tessellation uvs or vcol data got out of sync, "
335                                        "had to reset!\n    CD_MTFACE: %d != CD_MTEXPOLY: %d || CD_MCOL: %d != CD_MLOOPCOL: %d\n",
336                                        __func__, tottex_tessface, tottex_original, totcol_tessface, totcol_original);
337                         }
338                 }
339         }
340 }
341
342 void BKE_mesh_ensure_skin_customdata(Mesh *me)
343 {
344         BMesh *bm = me->edit_btmesh ? me->edit_btmesh->bm : NULL;
345         MVertSkin *vs;
346
347         if (bm) {
348                 if (!CustomData_has_layer(&bm->vdata, CD_MVERT_SKIN)) {
349                         BMVert *v;
350                         BMIter iter;
351
352                         BM_data_layer_add(bm, &bm->vdata, CD_MVERT_SKIN);
353
354                         /* Mark an arbitrary vertex as root */
355                         BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
356                                 vs = CustomData_bmesh_get(&bm->vdata, v->head.data,
357                                                           CD_MVERT_SKIN);
358                                 vs->flag |= MVERT_SKIN_ROOT;
359                                 break;
360                         }
361                 }
362         }
363         else {
364                 if (!CustomData_has_layer(&me->vdata, CD_MVERT_SKIN)) {
365                         vs = CustomData_add_layer(&me->vdata,
366                                                   CD_MVERT_SKIN,
367                                                   CD_DEFAULT,
368                                                   NULL,
369                                                   me->totvert);
370
371                         /* Mark an arbitrary vertex as root */
372                         if (vs) {
373                                 vs->flag |= MVERT_SKIN_ROOT;
374                         }
375                 }
376         }
377 }
378
379 /* this ensures grouped customdata (e.g. mtexpoly and mloopuv and mtface, or
380  * mloopcol and mcol) have the same relative active/render/clone/mask indices.
381  *
382  * note that for undo mesh data we want to skip 'ensure_tess_cd' call since
383  * we don't want to store memory for tessface when its only used for older
384  * versions of the mesh. - campbell*/
385 static void mesh_update_linked_customdata(Mesh *me, const bool do_ensure_tess_cd)
386 {
387         if (me->edit_btmesh)
388                 BKE_editmesh_update_linked_customdata(me->edit_btmesh);
389
390         if (do_ensure_tess_cd) {
391                 mesh_ensure_tessellation_customdata(me);
392         }
393
394         CustomData_bmesh_update_active_layers(&me->fdata, &me->pdata, &me->ldata);
395 }
396
397 void BKE_mesh_update_customdata_pointers(Mesh *me, const bool do_ensure_tess_cd)
398 {
399         mesh_update_linked_customdata(me, do_ensure_tess_cd);
400
401         me->mvert = CustomData_get_layer(&me->vdata, CD_MVERT);
402         me->dvert = CustomData_get_layer(&me->vdata, CD_MDEFORMVERT);
403
404         me->medge = CustomData_get_layer(&me->edata, CD_MEDGE);
405
406         me->mface = CustomData_get_layer(&me->fdata, CD_MFACE);
407         me->mcol = CustomData_get_layer(&me->fdata, CD_MCOL);
408         me->mtface = CustomData_get_layer(&me->fdata, CD_MTFACE);
409         
410         me->mpoly = CustomData_get_layer(&me->pdata, CD_MPOLY);
411         me->mloop = CustomData_get_layer(&me->ldata, CD_MLOOP);
412
413         me->mtpoly = CustomData_get_layer(&me->pdata, CD_MTEXPOLY);
414         me->mloopcol = CustomData_get_layer(&me->ldata, CD_MLOOPCOL);
415         me->mloopuv = CustomData_get_layer(&me->ldata, CD_MLOOPUV);
416 }
417
418 bool BKE_mesh_has_custom_loop_normals(Mesh *me)
419 {
420         if (me->edit_btmesh) {
421                 return CustomData_has_layer(&me->edit_btmesh->bm->ldata, CD_CUSTOMLOOPNORMAL);
422         }
423         else {
424                 return CustomData_has_layer(&me->ldata, CD_CUSTOMLOOPNORMAL);
425         }
426 }
427
428 /* Note: unlinking is called when me->id.us is 0, question remains how
429  * much unlinking of Library data in Mesh should be done... probably
430  * we need a more generic method, like the expand() functions in
431  * readfile.c */
432
433 void BKE_mesh_unlink(Mesh *me)
434 {
435         int a;
436         
437         if (me == NULL) return;
438
439         if (me->mat) {
440                 for (a = 0; a < me->totcol; a++) {
441                         if (me->mat[a]) me->mat[a]->id.us--;
442                         me->mat[a] = NULL;
443                 }
444         }
445
446         if (me->key) {
447                 me->key->id.us--;
448         }
449         me->key = NULL;
450         
451         if (me->texcomesh) me->texcomesh = NULL;
452 }
453
454 /* do not free mesh itself */
455 void BKE_mesh_free(Mesh *me, int unlink)
456 {
457         if (unlink)
458                 BKE_mesh_unlink(me);
459
460         CustomData_free(&me->vdata, me->totvert);
461         CustomData_free(&me->edata, me->totedge);
462         CustomData_free(&me->fdata, me->totface);
463         CustomData_free(&me->ldata, me->totloop);
464         CustomData_free(&me->pdata, me->totpoly);
465
466         if (me->adt) {
467                 BKE_animdata_free(&me->id);
468                 me->adt = NULL;
469         }
470         
471         if (me->mat) MEM_freeN(me->mat);
472         
473         if (me->bb) MEM_freeN(me->bb);
474         if (me->mselect) MEM_freeN(me->mselect);
475         if (me->edit_btmesh) MEM_freeN(me->edit_btmesh);
476 }
477
478 static void mesh_tessface_clear_intern(Mesh *mesh, int free_customdata)
479 {
480         if (free_customdata) {
481                 CustomData_free(&mesh->fdata, mesh->totface);
482         }
483         else {
484                 CustomData_reset(&mesh->fdata);
485         }
486
487         mesh->mface = NULL;
488         mesh->mtface = NULL;
489         mesh->mcol = NULL;
490         mesh->totface = 0;
491 }
492
493 Mesh *BKE_mesh_add(Main *bmain, const char *name)
494 {
495         Mesh *me;
496         
497         me = BKE_libblock_alloc(bmain, ID_ME, name);
498         
499         me->size[0] = me->size[1] = me->size[2] = 1.0;
500         me->smoothresh = 30;
501         me->texflag = ME_AUTOSPACE;
502
503         /* disable because its slow on many GPU's, see [#37518] */
504 #if 0
505         me->flag = ME_TWOSIDED;
506 #endif
507         me->drawflag = ME_DRAWEDGES | ME_DRAWFACES | ME_DRAWCREASES;
508
509         CustomData_reset(&me->vdata);
510         CustomData_reset(&me->edata);
511         CustomData_reset(&me->fdata);
512         CustomData_reset(&me->pdata);
513         CustomData_reset(&me->ldata);
514
515         return me;
516 }
517
518 Mesh *BKE_mesh_copy_ex(Main *bmain, Mesh *me)
519 {
520         Mesh *men;
521         MTFace *tface;
522         MTexPoly *txface;
523         int a, i;
524         const int do_tessface = ((me->totface != 0) && (me->totpoly == 0)); /* only do tessface if we have no polys */
525         
526         men = BKE_libblock_copy_ex(bmain, &me->id);
527         
528         men->mat = MEM_dupallocN(me->mat);
529         for (a = 0; a < men->totcol; a++) {
530                 id_us_plus((ID *)men->mat[a]);
531         }
532         id_us_plus((ID *)men->texcomesh);
533
534         CustomData_copy(&me->vdata, &men->vdata, CD_MASK_MESH, CD_DUPLICATE, men->totvert);
535         CustomData_copy(&me->edata, &men->edata, CD_MASK_MESH, CD_DUPLICATE, men->totedge);
536         CustomData_copy(&me->ldata, &men->ldata, CD_MASK_MESH, CD_DUPLICATE, men->totloop);
537         CustomData_copy(&me->pdata, &men->pdata, CD_MASK_MESH, CD_DUPLICATE, men->totpoly);
538         if (do_tessface) {
539                 CustomData_copy(&me->fdata, &men->fdata, CD_MASK_MESH, CD_DUPLICATE, men->totface);
540         }
541         else {
542                 mesh_tessface_clear_intern(men, false);
543         }
544
545         BKE_mesh_update_customdata_pointers(men, do_tessface);
546
547         /* ensure indirect linked data becomes lib-extern */
548         for (i = 0; i < me->fdata.totlayer; i++) {
549                 if (me->fdata.layers[i].type == CD_MTFACE) {
550                         tface = (MTFace *)me->fdata.layers[i].data;
551
552                         for (a = 0; a < me->totface; a++, tface++)
553                                 if (tface->tpage)
554                                         id_lib_extern((ID *)tface->tpage);
555                 }
556         }
557         
558         for (i = 0; i < me->pdata.totlayer; i++) {
559                 if (me->pdata.layers[i].type == CD_MTEXPOLY) {
560                         txface = (MTexPoly *)me->pdata.layers[i].data;
561
562                         for (a = 0; a < me->totpoly; a++, txface++)
563                                 if (txface->tpage)
564                                         id_lib_extern((ID *)txface->tpage);
565                 }
566         }
567
568         men->edit_btmesh = NULL;
569
570         men->mselect = MEM_dupallocN(men->mselect);
571         men->bb = MEM_dupallocN(men->bb);
572         
573         men->key = BKE_key_copy(me->key);
574         if (men->key) men->key->from = (ID *)men;
575
576         if (me->id.lib) {
577                 BKE_id_lib_local_paths(bmain, me->id.lib, &men->id);
578         }
579
580         return men;
581 }
582
583 Mesh *BKE_mesh_copy(Mesh *me)
584 {
585         return BKE_mesh_copy_ex(G.main, me);
586 }
587
588 BMesh *BKE_mesh_to_bmesh(Mesh *me, Object *ob)
589 {
590         BMesh *bm;
591         const BMAllocTemplate allocsize = BMALLOC_TEMPLATE_FROM_ME(me);
592
593         bm = BM_mesh_create(&allocsize);
594
595         BM_mesh_bm_from_me(bm, me, false, true, ob->shapenr);
596
597         return bm;
598 }
599
600 static void expand_local_mesh(Mesh *me)
601 {
602         id_lib_extern((ID *)me->texcomesh);
603
604         if (me->mtface || me->mtpoly) {
605                 int a, i;
606
607                 for (i = 0; i < me->pdata.totlayer; i++) {
608                         if (me->pdata.layers[i].type == CD_MTEXPOLY) {
609                                 MTexPoly *txface = (MTexPoly *)me->pdata.layers[i].data;
610
611                                 for (a = 0; a < me->totpoly; a++, txface++) {
612                                         /* special case: ima always local immediately */
613                                         if (txface->tpage) {
614                                                 id_lib_extern((ID *)txface->tpage);
615                                         }
616                                 }
617                         }
618                 }
619
620                 for (i = 0; i < me->fdata.totlayer; i++) {
621                         if (me->fdata.layers[i].type == CD_MTFACE) {
622                                 MTFace *tface = (MTFace *)me->fdata.layers[i].data;
623
624                                 for (a = 0; a < me->totface; a++, tface++) {
625                                         /* special case: ima always local immediately */
626                                         if (tface->tpage) {
627                                                 id_lib_extern((ID *)tface->tpage);
628                                         }
629                                 }
630                         }
631                 }
632         }
633
634         if (me->mat) {
635                 extern_local_matarar(me->mat, me->totcol);
636         }
637 }
638
639 void BKE_mesh_make_local(Mesh *me)
640 {
641         Main *bmain = G.main;
642         Object *ob;
643         bool is_local = false, is_lib = false;
644
645         /* - only lib users: do nothing
646          * - only local users: set flag
647          * - mixed: make copy
648          */
649
650         if (me->id.lib == NULL) return;
651         if (me->id.us == 1) {
652                 id_clear_lib_data(bmain, &me->id);
653                 expand_local_mesh(me);
654                 return;
655         }
656
657         for (ob = bmain->object.first; ob && ELEM(0, is_lib, is_local); ob = ob->id.next) {
658                 if (me == ob->data) {
659                         if (ob->id.lib) is_lib = true;
660                         else is_local = true;
661                 }
662         }
663
664         if (is_local && is_lib == false) {
665                 id_clear_lib_data(bmain, &me->id);
666                 expand_local_mesh(me);
667         }
668         else if (is_local && is_lib) {
669                 Mesh *me_new = BKE_mesh_copy(me);
670                 me_new->id.us = 0;
671
672
673                 /* Remap paths of new ID using old library as base. */
674                 BKE_id_lib_local_paths(bmain, me->id.lib, &me_new->id);
675
676                 for (ob = bmain->object.first; ob; ob = ob->id.next) {
677                         if (me == ob->data) {
678                                 if (ob->id.lib == NULL) {
679                                         BKE_mesh_assign_object(ob, me_new);
680                                 }
681                         }
682                 }
683         }
684 }
685
686 bool BKE_mesh_uv_cdlayer_rename_index(Mesh *me, const int poly_index, const int loop_index, const int face_index,
687                                       const char *new_name, const bool do_tessface)
688 {
689         CustomData *pdata, *ldata, *fdata;
690         CustomDataLayer *cdlp, *cdlu, *cdlf;
691         const int step = do_tessface ? 3 : 2;
692         int i;
693
694         if (me->edit_btmesh) {
695                 pdata = &me->edit_btmesh->bm->pdata;
696                 ldata = &me->edit_btmesh->bm->ldata;
697                 fdata = NULL;  /* No tessellated data in BMesh! */
698         }
699         else {
700                 pdata = &me->pdata;
701                 ldata = &me->ldata;
702                 fdata = &me->fdata;
703         }
704         cdlp = &pdata->layers[poly_index];
705         cdlu = &ldata->layers[loop_index];
706         cdlf = fdata && do_tessface ? &fdata->layers[face_index] : NULL;
707
708         if (cdlp->name != new_name) {
709                 /* Mesh validate passes a name from the CD layer as the new name,
710                  * Avoid memcpy from self to self in this case.
711                  */
712                 BLI_strncpy(cdlp->name, new_name, sizeof(cdlp->name));
713                 CustomData_set_layer_unique_name(pdata, cdlp - pdata->layers);
714         }
715
716         /* Loop until we do have exactly the same name for all layers! */
717         for (i = 1; !STREQ(cdlp->name, cdlu->name) || (cdlf && !STREQ(cdlp->name, cdlf->name)); i++) {
718                 switch (i % step) {
719                         case 0:
720                                 BLI_strncpy(cdlp->name, cdlu->name, sizeof(cdlp->name));
721                                 CustomData_set_layer_unique_name(pdata, cdlp - pdata->layers);
722                                 break;
723                         case 1:
724                                 BLI_strncpy(cdlu->name, cdlp->name, sizeof(cdlu->name));
725                                 CustomData_set_layer_unique_name(ldata, cdlu - ldata->layers);
726                                 break;
727                         case 2:
728                                 if (cdlf) {
729                                         BLI_strncpy(cdlf->name, cdlp->name, sizeof(cdlf->name));
730                                         CustomData_set_layer_unique_name(fdata, cdlf - fdata->layers);
731                                 }
732                                 break;
733                 }
734         }
735
736         return true;
737 }
738
739 bool BKE_mesh_uv_cdlayer_rename(Mesh *me, const char *old_name, const char *new_name, bool do_tessface)
740 {
741         CustomData *pdata, *ldata, *fdata;
742         if (me->edit_btmesh) {
743                 pdata = &me->edit_btmesh->bm->pdata;
744                 ldata = &me->edit_btmesh->bm->ldata;
745                 /* No tessellated data in BMesh! */
746                 fdata = NULL;
747                 do_tessface = false;
748         }
749         else {
750                 pdata = &me->pdata;
751                 ldata = &me->ldata;
752                 fdata = &me->fdata;
753                 do_tessface = (do_tessface && fdata->totlayer);
754         }
755
756         {
757                 const int pidx_start = CustomData_get_layer_index(pdata, CD_MTEXPOLY);
758                 const int lidx_start = CustomData_get_layer_index(ldata, CD_MLOOPUV);
759                 const int fidx_start = do_tessface ? CustomData_get_layer_index(fdata, CD_MTFACE) : -1;
760                 int pidx = CustomData_get_named_layer(pdata, CD_MTEXPOLY, old_name);
761                 int lidx = CustomData_get_named_layer(ldata, CD_MLOOPUV, old_name);
762                 int fidx = do_tessface ? CustomData_get_named_layer(fdata, CD_MTFACE, old_name) : -1;
763
764                 /* None of those cases should happen, in theory!
765                  * Note this assume we have the same number of mtexpoly, mloopuv and mtface layers!
766                  */
767                 if (pidx == -1) {
768                         if (lidx == -1) {
769                                 if (fidx == -1) {
770                                         /* No layer found with this name! */
771                                         return false;
772                                 }
773                                 else {
774                                         lidx = fidx;
775                                 }
776                         }
777                         pidx = lidx;
778                 }
779                 else {
780                         if (lidx == -1) {
781                                 lidx = pidx;
782                         }
783                         if (fidx == -1 && do_tessface) {
784                                 fidx = pidx;
785                         }
786                 }
787 #if 0
788                 /* For now, we do not consider mismatch in indices (i.e. same name leading to (relative) different indices). */
789                 else if (pidx != lidx) {
790                         lidx = pidx;
791                 }
792 #endif
793
794                 /* Go back to absolute indices! */
795                 pidx += pidx_start;
796                 lidx += lidx_start;
797                 if (fidx != -1)
798                         fidx += fidx_start;
799
800                 return BKE_mesh_uv_cdlayer_rename_index(me, pidx, lidx, fidx, new_name, do_tessface);
801         }
802 }
803
804 void BKE_mesh_boundbox_calc(Mesh *me, float r_loc[3], float r_size[3])
805 {
806         BoundBox *bb;
807         float min[3], max[3];
808         float mloc[3], msize[3];
809         
810         if (me->bb == NULL) me->bb = MEM_callocN(sizeof(BoundBox), "boundbox");
811         bb = me->bb;
812
813         if (!r_loc) r_loc = mloc;
814         if (!r_size) r_size = msize;
815         
816         INIT_MINMAX(min, max);
817         if (!BKE_mesh_minmax(me, min, max)) {
818                 min[0] = min[1] = min[2] = -1.0f;
819                 max[0] = max[1] = max[2] = 1.0f;
820         }
821
822         mid_v3_v3v3(r_loc, min, max);
823                 
824         r_size[0] = (max[0] - min[0]) / 2.0f;
825         r_size[1] = (max[1] - min[1]) / 2.0f;
826         r_size[2] = (max[2] - min[2]) / 2.0f;
827         
828         BKE_boundbox_init_from_minmax(bb, min, max);
829
830         bb->flag &= ~BOUNDBOX_DIRTY;
831 }
832
833 void BKE_mesh_texspace_calc(Mesh *me)
834 {
835         float loc[3], size[3];
836         int a;
837
838         BKE_mesh_boundbox_calc(me, loc, size);
839
840         if (me->texflag & ME_AUTOSPACE) {
841                 for (a = 0; a < 3; a++) {
842                         if (size[a] == 0.0f) size[a] = 1.0f;
843                         else if (size[a] > 0.0f && size[a] < 0.00001f) size[a] = 0.00001f;
844                         else if (size[a] < 0.0f && size[a] > -0.00001f) size[a] = -0.00001f;
845                 }
846
847                 copy_v3_v3(me->loc, loc);
848                 copy_v3_v3(me->size, size);
849                 zero_v3(me->rot);
850         }
851 }
852
853 BoundBox *BKE_mesh_boundbox_get(Object *ob)
854 {
855         Mesh *me = ob->data;
856
857         if (ob->bb)
858                 return ob->bb;
859
860         if (me->bb == NULL || (me->bb->flag & BOUNDBOX_DIRTY)) {
861                 BKE_mesh_texspace_calc(me);
862         }
863
864         return me->bb;
865 }
866
867 void BKE_mesh_texspace_get(Mesh *me, float r_loc[3], float r_rot[3], float r_size[3])
868 {
869         if (me->bb == NULL || (me->bb->flag & BOUNDBOX_DIRTY)) {
870                 BKE_mesh_texspace_calc(me);
871         }
872
873         if (r_loc) copy_v3_v3(r_loc,  me->loc);
874         if (r_rot) copy_v3_v3(r_rot,  me->rot);
875         if (r_size) copy_v3_v3(r_size, me->size);
876 }
877
878 void BKE_mesh_texspace_copy_from_object(Mesh *me, Object *ob)
879 {
880         float *texloc, *texrot, *texsize;
881         short *texflag;
882
883         if (BKE_object_obdata_texspace_get(ob, &texflag, &texloc, &texsize, &texrot)) {
884                 me->texflag = *texflag;
885                 copy_v3_v3(me->loc, texloc);
886                 copy_v3_v3(me->size, texsize);
887                 copy_v3_v3(me->rot, texrot);
888         }
889 }
890
891 float (*BKE_mesh_orco_verts_get(Object *ob))[3]
892 {
893         Mesh *me = ob->data;
894         MVert *mvert = NULL;
895         Mesh *tme = me->texcomesh ? me->texcomesh : me;
896         int a, totvert;
897         float (*vcos)[3] = NULL;
898
899         /* Get appropriate vertex coordinates */
900         vcos = MEM_callocN(sizeof(*vcos) * me->totvert, "orco mesh");
901         mvert = tme->mvert;
902         totvert = min_ii(tme->totvert, me->totvert);
903
904         for (a = 0; a < totvert; a++, mvert++) {
905                 copy_v3_v3(vcos[a], mvert->co);
906         }
907
908         return vcos;
909 }
910
911 void BKE_mesh_orco_verts_transform(Mesh *me, float (*orco)[3], int totvert, int invert)
912 {
913         float loc[3], size[3];
914         int a;
915
916         BKE_mesh_texspace_get(me->texcomesh ? me->texcomesh : me, loc, NULL, size);
917
918         if (invert) {
919                 for (a = 0; a < totvert; a++) {
920                         float *co = orco[a];
921                         madd_v3_v3v3v3(co, loc, co, size);
922                 }
923         }
924         else {
925                 for (a = 0; a < totvert; a++) {
926                         float *co = orco[a];
927                         co[0] = (co[0] - loc[0]) / size[0];
928                         co[1] = (co[1] - loc[1]) / size[1];
929                         co[2] = (co[2] - loc[2]) / size[2];
930                 }
931         }
932 }
933
934 /* rotates the vertices of a face in case v[2] or v[3] (vertex index) is = 0.
935  * this is necessary to make the if (mface->v4) check for quads work */
936 int test_index_face(MFace *mface, CustomData *fdata, int mfindex, int nr)
937 {
938         /* first test if the face is legal */
939         if ((mface->v3 || nr == 4) && mface->v3 == mface->v4) {
940                 mface->v4 = 0;
941                 nr--;
942         }
943         if ((mface->v2 || mface->v4) && mface->v2 == mface->v3) {
944                 mface->v3 = mface->v4;
945                 mface->v4 = 0;
946                 nr--;
947         }
948         if (mface->v1 == mface->v2) {
949                 mface->v2 = mface->v3;
950                 mface->v3 = mface->v4;
951                 mface->v4 = 0;
952                 nr--;
953         }
954
955         /* check corrupt cases, bow-tie geometry, cant handle these because edge data wont exist so just return 0 */
956         if (nr == 3) {
957                 if (
958                     /* real edges */
959                     mface->v1 == mface->v2 ||
960                     mface->v2 == mface->v3 ||
961                     mface->v3 == mface->v1)
962                 {
963                         return 0;
964                 }
965         }
966         else if (nr == 4) {
967                 if (
968                     /* real edges */
969                     mface->v1 == mface->v2 ||
970                     mface->v2 == mface->v3 ||
971                     mface->v3 == mface->v4 ||
972                     mface->v4 == mface->v1 ||
973                     /* across the face */
974                     mface->v1 == mface->v3 ||
975                     mface->v2 == mface->v4)
976                 {
977                         return 0;
978                 }
979         }
980
981         /* prevent a zero at wrong index location */
982         if (nr == 3) {
983                 if (mface->v3 == 0) {
984                         static int corner_indices[4] = {1, 2, 0, 3};
985
986                         SWAP(unsigned int, mface->v1, mface->v2);
987                         SWAP(unsigned int, mface->v2, mface->v3);
988
989                         if (fdata)
990                                 CustomData_swap(fdata, mfindex, corner_indices);
991                 }
992         }
993         else if (nr == 4) {
994                 if (mface->v3 == 0 || mface->v4 == 0) {
995                         static int corner_indices[4] = {2, 3, 0, 1};
996
997                         SWAP(unsigned int, mface->v1, mface->v3);
998                         SWAP(unsigned int, mface->v2, mface->v4);
999
1000                         if (fdata)
1001                                 CustomData_swap(fdata, mfindex, corner_indices);
1002                 }
1003         }
1004
1005         return nr;
1006 }
1007
1008 Mesh *BKE_mesh_from_object(Object *ob)
1009 {
1010         
1011         if (ob == NULL) return NULL;
1012         if (ob->type == OB_MESH) return ob->data;
1013         else return NULL;
1014 }
1015
1016 void BKE_mesh_assign_object(Object *ob, Mesh *me)
1017 {
1018         Mesh *old = NULL;
1019
1020         multires_force_update(ob);
1021         
1022         if (ob == NULL) return;
1023         
1024         if (ob->type == OB_MESH) {
1025                 old = ob->data;
1026                 if (old)
1027                         old->id.us--;
1028                 ob->data = me;
1029                 id_us_plus((ID *)me);
1030         }
1031         
1032         test_object_materials(G.main, (ID *)me);
1033
1034         test_object_modifiers(ob);
1035 }
1036
1037 void BKE_mesh_from_metaball(ListBase *lb, Mesh *me)
1038 {
1039         DispList *dl;
1040         MVert *mvert;
1041         MLoop *mloop, *allloop;
1042         MPoly *mpoly;
1043         const float *nors, *verts;
1044         int a, *index;
1045         
1046         dl = lb->first;
1047         if (dl == NULL) return;
1048
1049         if (dl->type == DL_INDEX4) {
1050                 mvert = CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, dl->nr);
1051                 allloop = mloop = CustomData_add_layer(&me->ldata, CD_MLOOP, CD_CALLOC, NULL, dl->parts * 4);
1052                 mpoly = CustomData_add_layer(&me->pdata, CD_MPOLY, CD_CALLOC, NULL, dl->parts);
1053                 me->mvert = mvert;
1054                 me->mloop = mloop;
1055                 me->mpoly = mpoly;
1056                 me->totvert = dl->nr;
1057                 me->totpoly = dl->parts;
1058
1059                 a = dl->nr;
1060                 nors = dl->nors;
1061                 verts = dl->verts;
1062                 while (a--) {
1063                         copy_v3_v3(mvert->co, verts);
1064                         normal_float_to_short_v3(mvert->no, nors);
1065                         mvert++;
1066                         nors += 3;
1067                         verts += 3;
1068                 }
1069                 
1070                 a = dl->parts;
1071                 index = dl->index;
1072                 while (a--) {
1073                         int count = index[2] != index[3] ? 4 : 3;
1074
1075                         mloop[0].v = index[0];
1076                         mloop[1].v = index[1];
1077                         mloop[2].v = index[2];
1078                         if (count == 4)
1079                                 mloop[3].v = index[3];
1080
1081                         mpoly->totloop = count;
1082                         mpoly->loopstart = (int)(mloop - allloop);
1083                         mpoly->flag = ME_SMOOTH;
1084
1085
1086                         mpoly++;
1087                         mloop += count;
1088                         me->totloop += count;
1089                         index += 4;
1090                 }
1091
1092                 BKE_mesh_update_customdata_pointers(me, true);
1093
1094                 BKE_mesh_calc_normals(me);
1095
1096                 BKE_mesh_calc_edges(me, true, false);
1097         }
1098 }
1099
1100 /**
1101  * Specialized function to use when we _know_ existing edges don't overlap with poly edges.
1102  */
1103 static void make_edges_mdata_extend(MEdge **r_alledge, int *r_totedge,
1104                                     const MPoly *mpoly, MLoop *mloop,
1105                                     const int totpoly)
1106 {
1107         int totedge = *r_totedge;
1108         int totedge_new;
1109         EdgeHash *eh;
1110         unsigned int eh_reserve;
1111         const MPoly *mp;
1112         int i;
1113
1114         eh_reserve = max_ii(totedge, BLI_EDGEHASH_SIZE_GUESS_FROM_POLYS(totpoly));
1115         eh = BLI_edgehash_new_ex(__func__, eh_reserve);
1116
1117         for (i = 0, mp = mpoly; i < totpoly; i++, mp++) {
1118                 BKE_mesh_poly_edgehash_insert(eh, mp, mloop + mp->loopstart);
1119         }
1120
1121         totedge_new = BLI_edgehash_size(eh);
1122
1123 #ifdef DEBUG
1124         /* ensure that theres no overlap! */
1125         if (totedge_new) {
1126                 MEdge *medge = *r_alledge;
1127                 for (i = 0; i < totedge; i++, medge++) {
1128                         BLI_assert(BLI_edgehash_haskey(eh, medge->v1, medge->v2) == false);
1129                 }
1130         }
1131 #endif
1132
1133         if (totedge_new) {
1134                 EdgeHashIterator *ehi;
1135                 MEdge *medge;
1136                 unsigned int e_index = totedge;
1137
1138                 *r_alledge = medge = (*r_alledge ? MEM_reallocN(*r_alledge, sizeof(MEdge) * (totedge + totedge_new)) :
1139                                                    MEM_callocN(sizeof(MEdge) * totedge_new, __func__));
1140                 medge += totedge;
1141
1142                 totedge += totedge_new;
1143
1144                 /* --- */
1145                 for (ehi = BLI_edgehashIterator_new(eh);
1146                      BLI_edgehashIterator_isDone(ehi) == false;
1147                      BLI_edgehashIterator_step(ehi), ++medge, e_index++)
1148                 {
1149                         BLI_edgehashIterator_getKey(ehi, &medge->v1, &medge->v2);
1150                         BLI_edgehashIterator_setValue(ehi, SET_UINT_IN_POINTER(e_index));
1151
1152                         medge->crease = medge->bweight = 0;
1153                         medge->flag = ME_EDGEDRAW | ME_EDGERENDER;
1154                 }
1155                 BLI_edgehashIterator_free(ehi);
1156
1157                 *r_totedge = totedge;
1158
1159
1160                 for (i = 0, mp = mpoly; i < totpoly; i++, mp++) {
1161                         MLoop *l = &mloop[mp->loopstart];
1162                         MLoop *l_prev = (l + (mp->totloop - 1));
1163                         int j;
1164                         for (j = 0; j < mp->totloop; j++, l++) {
1165                                 /* lookup hashed edge index */
1166                                 l_prev->e = GET_UINT_FROM_POINTER(BLI_edgehash_lookup(eh, l_prev->v, l->v));
1167                                 l_prev = l;
1168                         }
1169                 }
1170         }
1171
1172         BLI_edgehash_free(eh, NULL);
1173 }
1174
1175
1176 /* Initialize mverts, medges and, faces for converting nurbs to mesh and derived mesh */
1177 /* return non-zero on error */
1178 int BKE_mesh_nurbs_to_mdata(
1179         Object *ob, MVert **r_allvert, int *r_totvert,
1180         MEdge **r_alledge, int *r_totedge, MLoop **r_allloop, MPoly **r_allpoly,
1181         int *r_totloop, int *r_totpoly)
1182 {
1183         ListBase disp = {NULL, NULL};
1184
1185         if (ob->curve_cache) {
1186                 disp = ob->curve_cache->disp;
1187         }
1188
1189         return BKE_mesh_nurbs_displist_to_mdata(
1190                 ob, &disp,
1191                 r_allvert, r_totvert,
1192                 r_alledge, r_totedge,
1193                 r_allloop, r_allpoly, NULL,
1194                 r_totloop, r_totpoly);
1195 }
1196
1197 /* BMESH: this doesn't calculate all edges from polygons,
1198  * only free standing edges are calculated */
1199
1200 /* Initialize mverts, medges and, faces for converting nurbs to mesh and derived mesh */
1201 /* use specified dispbase */
1202 int BKE_mesh_nurbs_displist_to_mdata(
1203         Object *ob, const ListBase *dispbase,
1204         MVert **r_allvert, int *r_totvert,
1205         MEdge **r_alledge, int *r_totedge,
1206         MLoop **r_allloop, MPoly **r_allpoly,
1207         MLoopUV **r_alluv,
1208         int *r_totloop, int *r_totpoly)
1209 {
1210         Curve *cu = ob->data;
1211         DispList *dl;
1212         MVert *mvert;
1213         MPoly *mpoly;
1214         MLoop *mloop;
1215         MLoopUV *mloopuv = NULL;
1216         MEdge *medge;
1217         const float *data;
1218         int a, b, ofs, vertcount, startvert, totvert = 0, totedge = 0, totloop = 0, totvlak = 0;
1219         int p1, p2, p3, p4, *index;
1220         const bool conv_polys = ((CU_DO_2DFILL(cu) == false) ||  /* 2d polys are filled with DL_INDEX3 displists */
1221                                  (ob->type == OB_SURF));  /* surf polys are never filled */
1222
1223         /* count */
1224         dl = dispbase->first;
1225         while (dl) {
1226                 if (dl->type == DL_SEGM) {
1227                         totvert += dl->parts * dl->nr;
1228                         totedge += dl->parts * (dl->nr - 1);
1229                 }
1230                 else if (dl->type == DL_POLY) {
1231                         if (conv_polys) {
1232                                 totvert += dl->parts * dl->nr;
1233                                 totedge += dl->parts * dl->nr;
1234                         }
1235                 }
1236                 else if (dl->type == DL_SURF) {
1237                         int tot;
1238                         totvert += dl->parts * dl->nr;
1239                         tot = (dl->parts - 1 + ((dl->flag & DL_CYCL_V) == 2)) * (dl->nr - 1 + (dl->flag & DL_CYCL_U));
1240                         totvlak += tot;
1241                         totloop += tot * 4;
1242                 }
1243                 else if (dl->type == DL_INDEX3) {
1244                         int tot;
1245                         totvert += dl->nr;
1246                         tot = dl->parts;
1247                         totvlak += tot;
1248                         totloop += tot * 3;
1249                 }
1250                 dl = dl->next;
1251         }
1252
1253         if (totvert == 0) {
1254                 /* error("can't convert"); */
1255                 /* Make Sure you check ob->data is a curve */
1256                 return -1;
1257         }
1258
1259         *r_allvert = mvert = MEM_callocN(sizeof(MVert) * totvert, "nurbs_init mvert");
1260         *r_alledge = medge = MEM_callocN(sizeof(MEdge) * totedge, "nurbs_init medge");
1261         *r_allloop = mloop = MEM_callocN(sizeof(MLoop) * totvlak * 4, "nurbs_init mloop"); // totloop
1262         *r_allpoly = mpoly = MEM_callocN(sizeof(MPoly) * totvlak, "nurbs_init mloop");
1263
1264         if (r_alluv)
1265                 *r_alluv = mloopuv = MEM_callocN(sizeof(MLoopUV) * totvlak * 4, "nurbs_init mloopuv");
1266         
1267         /* verts and faces */
1268         vertcount = 0;
1269
1270         dl = dispbase->first;
1271         while (dl) {
1272                 const bool is_smooth = (dl->rt & CU_SMOOTH) != 0;
1273
1274                 if (dl->type == DL_SEGM) {
1275                         startvert = vertcount;
1276                         a = dl->parts * dl->nr;
1277                         data = dl->verts;
1278                         while (a--) {
1279                                 copy_v3_v3(mvert->co, data);
1280                                 data += 3;
1281                                 vertcount++;
1282                                 mvert++;
1283                         }
1284
1285                         for (a = 0; a < dl->parts; a++) {
1286                                 ofs = a * dl->nr;
1287                                 for (b = 1; b < dl->nr; b++) {
1288                                         medge->v1 = startvert + ofs + b - 1;
1289                                         medge->v2 = startvert + ofs + b;
1290                                         medge->flag = ME_LOOSEEDGE | ME_EDGERENDER | ME_EDGEDRAW;
1291
1292                                         medge++;
1293                                 }
1294                         }
1295
1296                 }
1297                 else if (dl->type == DL_POLY) {
1298                         if (conv_polys) {
1299                                 startvert = vertcount;
1300                                 a = dl->parts * dl->nr;
1301                                 data = dl->verts;
1302                                 while (a--) {
1303                                         copy_v3_v3(mvert->co, data);
1304                                         data += 3;
1305                                         vertcount++;
1306                                         mvert++;
1307                                 }
1308
1309                                 for (a = 0; a < dl->parts; a++) {
1310                                         ofs = a * dl->nr;
1311                                         for (b = 0; b < dl->nr; b++) {
1312                                                 medge->v1 = startvert + ofs + b;
1313                                                 if (b == dl->nr - 1) medge->v2 = startvert + ofs;
1314                                                 else medge->v2 = startvert + ofs + b + 1;
1315                                                 medge->flag = ME_LOOSEEDGE | ME_EDGERENDER | ME_EDGEDRAW;
1316                                                 medge++;
1317                                         }
1318                                 }
1319                         }
1320                 }
1321                 else if (dl->type == DL_INDEX3) {
1322                         startvert = vertcount;
1323                         a = dl->nr;
1324                         data = dl->verts;
1325                         while (a--) {
1326                                 copy_v3_v3(mvert->co, data);
1327                                 data += 3;
1328                                 vertcount++;
1329                                 mvert++;
1330                         }
1331
1332                         a = dl->parts;
1333                         index = dl->index;
1334                         while (a--) {
1335                                 mloop[0].v = startvert + index[0];
1336                                 mloop[1].v = startvert + index[2];
1337                                 mloop[2].v = startvert + index[1];
1338                                 mpoly->loopstart = (int)(mloop - (*r_allloop));
1339                                 mpoly->totloop = 3;
1340                                 mpoly->mat_nr = dl->col;
1341
1342                                 if (mloopuv) {
1343                                         int i;
1344
1345                                         for (i = 0; i < 3; i++, mloopuv++) {
1346                                                 mloopuv->uv[0] = (mloop[i].v - startvert) / (float)(dl->nr - 1);
1347                                                 mloopuv->uv[1] = 0.0f;
1348                                         }
1349                                 }
1350
1351                                 if (is_smooth) mpoly->flag |= ME_SMOOTH;
1352                                 mpoly++;
1353                                 mloop += 3;
1354                                 index += 3;
1355                         }
1356                 }
1357                 else if (dl->type == DL_SURF) {
1358                         startvert = vertcount;
1359                         a = dl->parts * dl->nr;
1360                         data = dl->verts;
1361                         while (a--) {
1362                                 copy_v3_v3(mvert->co, data);
1363                                 data += 3;
1364                                 vertcount++;
1365                                 mvert++;
1366                         }
1367
1368                         for (a = 0; a < dl->parts; a++) {
1369
1370                                 if ( (dl->flag & DL_CYCL_V) == 0 && a == dl->parts - 1) break;
1371
1372                                 if (dl->flag & DL_CYCL_U) {         /* p2 -> p1 -> */
1373                                         p1 = startvert + dl->nr * a;    /* p4 -> p3 -> */
1374                                         p2 = p1 + dl->nr - 1;       /* -----> next row */
1375                                         p3 = p1 + dl->nr;
1376                                         p4 = p2 + dl->nr;
1377                                         b = 0;
1378                                 }
1379                                 else {
1380                                         p2 = startvert + dl->nr * a;
1381                                         p1 = p2 + 1;
1382                                         p4 = p2 + dl->nr;
1383                                         p3 = p1 + dl->nr;
1384                                         b = 1;
1385                                 }
1386                                 if ( (dl->flag & DL_CYCL_V) && a == dl->parts - 1) {
1387                                         p3 -= dl->parts * dl->nr;
1388                                         p4 -= dl->parts * dl->nr;
1389                                 }
1390
1391                                 for (; b < dl->nr; b++) {
1392                                         mloop[0].v = p1;
1393                                         mloop[1].v = p3;
1394                                         mloop[2].v = p4;
1395                                         mloop[3].v = p2;
1396                                         mpoly->loopstart = (int)(mloop - (*r_allloop));
1397                                         mpoly->totloop = 4;
1398                                         mpoly->mat_nr = dl->col;
1399
1400                                         if (mloopuv) {
1401                                                 int orco_sizeu = dl->nr - 1;
1402                                                 int orco_sizev = dl->parts - 1;
1403                                                 int i;
1404
1405                                                 /* exception as handled in convertblender.c too */
1406                                                 if (dl->flag & DL_CYCL_U) {
1407                                                         orco_sizeu++;
1408                                                         if (dl->flag & DL_CYCL_V)
1409                                                                 orco_sizev++;
1410                                                 }
1411                                                 else if (dl->flag & DL_CYCL_V) {
1412                                                         orco_sizev++;
1413                                                 }
1414
1415                                                 for (i = 0; i < 4; i++, mloopuv++) {
1416                                                         /* find uv based on vertex index into grid array */
1417                                                         int v = mloop[i].v - startvert;
1418
1419                                                         mloopuv->uv[0] = (v / dl->nr) / (float)orco_sizev;
1420                                                         mloopuv->uv[1] = (v % dl->nr) / (float)orco_sizeu;
1421
1422                                                         /* cyclic correction */
1423                                                         if ((i == 1 || i == 2) && mloopuv->uv[0] == 0.0f)
1424                                                                 mloopuv->uv[0] = 1.0f;
1425                                                         if ((i == 0 || i == 1) && mloopuv->uv[1] == 0.0f)
1426                                                                 mloopuv->uv[1] = 1.0f;
1427                                                 }
1428                                         }
1429
1430                                         if (is_smooth) mpoly->flag |= ME_SMOOTH;
1431                                         mpoly++;
1432                                         mloop += 4;
1433
1434                                         p4 = p3;
1435                                         p3++;
1436                                         p2 = p1;
1437                                         p1++;
1438                                 }
1439                         }
1440                 }
1441
1442                 dl = dl->next;
1443         }
1444         
1445         if (totvlak) {
1446                 make_edges_mdata_extend(r_alledge, &totedge,
1447                                         *r_allpoly, *r_allloop, totvlak);
1448         }
1449
1450         *r_totpoly = totvlak;
1451         *r_totloop = totloop;
1452         *r_totedge = totedge;
1453         *r_totvert = totvert;
1454
1455         return 0;
1456 }
1457
1458
1459 /* this may fail replacing ob->data, be sure to check ob->type */
1460 void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, const bool use_orco_uv)
1461 {
1462         Main *bmain = G.main;
1463         Object *ob1;
1464         DerivedMesh *dm = ob->derivedFinal;
1465         Mesh *me;
1466         Curve *cu;
1467         MVert *allvert = NULL;
1468         MEdge *alledge = NULL;
1469         MLoop *allloop = NULL;
1470         MLoopUV *alluv = NULL;
1471         MPoly *allpoly = NULL;
1472         int totvert, totedge, totloop, totpoly;
1473
1474         cu = ob->data;
1475
1476         if (dm == NULL) {
1477                 if (BKE_mesh_nurbs_displist_to_mdata(ob, dispbase, &allvert, &totvert,
1478                                                      &alledge, &totedge, &allloop,
1479                                                      &allpoly, (use_orco_uv) ? &alluv : NULL,
1480                                                      &totloop, &totpoly) != 0)
1481                 {
1482                         /* Error initializing */
1483                         return;
1484                 }
1485
1486                 /* make mesh */
1487                 me = BKE_mesh_add(G.main, "Mesh");
1488                 me->totvert = totvert;
1489                 me->totedge = totedge;
1490                 me->totloop = totloop;
1491                 me->totpoly = totpoly;
1492
1493                 me->mvert = CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN, allvert, me->totvert);
1494                 me->medge = CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, alledge, me->totedge);
1495                 me->mloop = CustomData_add_layer(&me->ldata, CD_MLOOP, CD_ASSIGN, allloop, me->totloop);
1496                 me->mpoly = CustomData_add_layer(&me->pdata, CD_MPOLY, CD_ASSIGN, allpoly, me->totpoly);
1497
1498                 if (alluv) {
1499                         const char *uvname = "Orco";
1500                         me->mtpoly = CustomData_add_layer_named(&me->pdata, CD_MTEXPOLY, CD_DEFAULT, NULL, me->totpoly, uvname);
1501                         me->mloopuv = CustomData_add_layer_named(&me->ldata, CD_MLOOPUV, CD_ASSIGN, alluv, me->totloop, uvname);
1502                 }
1503
1504                 BKE_mesh_calc_normals(me);
1505         }
1506         else {
1507                 me = BKE_mesh_add(G.main, "Mesh");
1508                 DM_to_mesh(dm, me, ob, CD_MASK_MESH, false);
1509         }
1510
1511         me->totcol = cu->totcol;
1512         me->mat = cu->mat;
1513
1514         BKE_mesh_texspace_calc(me);
1515
1516         cu->mat = NULL;
1517         cu->totcol = 0;
1518
1519         if (ob->data) {
1520                 BKE_libblock_free(bmain, ob->data);
1521         }
1522         ob->data = me;
1523         ob->type = OB_MESH;
1524
1525         /* other users */
1526         ob1 = bmain->object.first;
1527         while (ob1) {
1528                 if (ob1->data == cu) {
1529                         ob1->type = OB_MESH;
1530                 
1531                         ob1->data = ob->data;
1532                         id_us_plus((ID *)ob->data);
1533                 }
1534                 ob1 = ob1->id.next;
1535         }
1536 }
1537
1538 void BKE_mesh_from_nurbs(Object *ob)
1539 {
1540         Curve *cu = (Curve *) ob->data;
1541         bool use_orco_uv = (cu->flag & CU_UV_ORCO) != 0;
1542         ListBase disp = {NULL, NULL};
1543
1544         if (ob->curve_cache) {
1545                 disp = ob->curve_cache->disp;
1546         }
1547
1548         BKE_mesh_from_nurbs_displist(ob, &disp, use_orco_uv);
1549 }
1550
1551 typedef struct EdgeLink {
1552         struct EdgeLink *next, *prev;
1553         void *edge;
1554 } EdgeLink;
1555
1556 typedef struct VertLink {
1557         Link *next, *prev;
1558         unsigned int index;
1559 } VertLink;
1560
1561 static void prependPolyLineVert(ListBase *lb, unsigned int index)
1562 {
1563         VertLink *vl = MEM_callocN(sizeof(VertLink), "VertLink");
1564         vl->index = index;
1565         BLI_addhead(lb, vl);
1566 }
1567
1568 static void appendPolyLineVert(ListBase *lb, unsigned int index)
1569 {
1570         VertLink *vl = MEM_callocN(sizeof(VertLink), "VertLink");
1571         vl->index = index;
1572         BLI_addtail(lb, vl);
1573 }
1574
1575 void BKE_mesh_to_curve_nurblist(DerivedMesh *dm, ListBase *nurblist, const int edge_users_test)
1576 {
1577         MVert       *mvert = dm->getVertArray(dm);
1578         MEdge *med, *medge = dm->getEdgeArray(dm);
1579         MPoly *mp,  *mpoly = dm->getPolyArray(dm);
1580         MLoop       *mloop = dm->getLoopArray(dm);
1581
1582         int dm_totedge = dm->getNumEdges(dm);
1583         int dm_totpoly = dm->getNumPolys(dm);
1584         int totedges = 0;
1585         int i;
1586
1587         /* only to detect edge polylines */
1588         int *edge_users;
1589
1590         ListBase edges = {NULL, NULL};
1591
1592         /* get boundary edges */
1593         edge_users = MEM_callocN(sizeof(int) * dm_totedge, __func__);
1594         for (i = 0, mp = mpoly; i < dm_totpoly; i++, mp++) {
1595                 MLoop *ml = &mloop[mp->loopstart];
1596                 int j;
1597                 for (j = 0; j < mp->totloop; j++, ml++) {
1598                         edge_users[ml->e]++;
1599                 }
1600         }
1601
1602         /* create edges from all faces (so as to find edges not in any faces) */
1603         med = medge;
1604         for (i = 0; i < dm_totedge; i++, med++) {
1605                 if (edge_users[i] == edge_users_test) {
1606                         EdgeLink *edl = MEM_callocN(sizeof(EdgeLink), "EdgeLink");
1607                         edl->edge = med;
1608
1609                         BLI_addtail(&edges, edl);   totedges++;
1610                 }
1611         }
1612         MEM_freeN(edge_users);
1613
1614         if (edges.first) {
1615                 while (edges.first) {
1616                         /* each iteration find a polyline and add this as a nurbs poly spline */
1617
1618                         ListBase polyline = {NULL, NULL}; /* store a list of VertLink's */
1619                         bool closed = false;
1620                         int totpoly = 0;
1621                         MEdge *med_current = ((EdgeLink *)edges.last)->edge;
1622                         unsigned int startVert = med_current->v1;
1623                         unsigned int endVert = med_current->v2;
1624                         bool ok = true;
1625
1626                         appendPolyLineVert(&polyline, startVert);   totpoly++;
1627                         appendPolyLineVert(&polyline, endVert);     totpoly++;
1628                         BLI_freelinkN(&edges, edges.last);          totedges--;
1629
1630                         while (ok) { /* while connected edges are found... */
1631                                 EdgeLink *edl = edges.last;
1632                                 ok = false;
1633                                 while (edl) {
1634                                         EdgeLink *edl_prev = edl->prev;
1635
1636                                         med = edl->edge;
1637
1638                                         if (med->v1 == endVert) {
1639                                                 endVert = med->v2;
1640                                                 appendPolyLineVert(&polyline, med->v2); totpoly++;
1641                                                 BLI_freelinkN(&edges, edl);             totedges--;
1642                                                 ok = true;
1643                                         }
1644                                         else if (med->v2 == endVert) {
1645                                                 endVert = med->v1;
1646                                                 appendPolyLineVert(&polyline, endVert); totpoly++;
1647                                                 BLI_freelinkN(&edges, edl);             totedges--;
1648                                                 ok = true;
1649                                         }
1650                                         else if (med->v1 == startVert) {
1651                                                 startVert = med->v2;
1652                                                 prependPolyLineVert(&polyline, startVert);  totpoly++;
1653                                                 BLI_freelinkN(&edges, edl);                 totedges--;
1654                                                 ok = true;
1655                                         }
1656                                         else if (med->v2 == startVert) {
1657                                                 startVert = med->v1;
1658                                                 prependPolyLineVert(&polyline, startVert);  totpoly++;
1659                                                 BLI_freelinkN(&edges, edl);                 totedges--;
1660                                                 ok = true;
1661                                         }
1662
1663                                         edl = edl_prev;
1664                                 }
1665                         }
1666
1667                         /* Now we have a polyline, make into a curve */
1668                         if (startVert == endVert) {
1669                                 BLI_freelinkN(&polyline, polyline.last);
1670                                 totpoly--;
1671                                 closed = true;
1672                         }
1673
1674                         /* --- nurbs --- */
1675                         {
1676                                 Nurb *nu;
1677                                 BPoint *bp;
1678                                 VertLink *vl;
1679
1680                                 /* create new 'nurb' within the curve */
1681                                 nu = (Nurb *)MEM_callocN(sizeof(Nurb), "MeshNurb");
1682
1683                                 nu->pntsu = totpoly;
1684                                 nu->pntsv = 1;
1685                                 nu->orderu = 4;
1686                                 nu->flagu = CU_NURB_ENDPOINT | (closed ? CU_NURB_CYCLIC : 0);  /* endpoint */
1687                                 nu->resolu = 12;
1688
1689                                 nu->bp = (BPoint *)MEM_callocN(sizeof(BPoint) * totpoly, "bpoints");
1690
1691                                 /* add points */
1692                                 vl = polyline.first;
1693                                 for (i = 0, bp = nu->bp; i < totpoly; i++, bp++, vl = (VertLink *)vl->next) {
1694                                         copy_v3_v3(bp->vec, mvert[vl->index].co);
1695                                         bp->f1 = SELECT;
1696                                         bp->radius = bp->weight = 1.0;
1697                                 }
1698                                 BLI_freelistN(&polyline);
1699
1700                                 /* add nurb to curve */
1701                                 BLI_addtail(nurblist, nu);
1702                         }
1703                         /* --- done with nurbs --- */
1704                 }
1705         }
1706 }
1707
1708 void BKE_mesh_to_curve(Scene *scene, Object *ob)
1709 {
1710         /* make new mesh data from the original copy */
1711         DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_MESH);
1712         ListBase nurblist = {NULL, NULL};
1713         bool needsFree = false;
1714
1715         BKE_mesh_to_curve_nurblist(dm, &nurblist, 0);
1716         BKE_mesh_to_curve_nurblist(dm, &nurblist, 1);
1717
1718         if (nurblist.first) {
1719                 Curve *cu = BKE_curve_add(G.main, ob->id.name + 2, OB_CURVE);
1720                 cu->flag |= CU_3D;
1721
1722                 cu->nurb = nurblist;
1723
1724                 ((Mesh *)ob->data)->id.us--;
1725                 ob->data = cu;
1726                 ob->type = OB_CURVE;
1727
1728                 /* curve objects can't contain DM in usual cases, we could free memory */
1729                 needsFree = true;
1730         }
1731
1732         dm->needsFree = needsFree;
1733         dm->release(dm);
1734
1735         if (needsFree) {
1736                 ob->derivedFinal = NULL;
1737
1738                 /* curve object could have got bounding box only in special cases */
1739                 if (ob->bb) {
1740                         MEM_freeN(ob->bb);
1741                         ob->bb = NULL;
1742                 }
1743         }
1744 }
1745
1746 void BKE_mesh_material_index_remove(Mesh *me, short index)
1747 {
1748         MPoly *mp;
1749         MFace *mf;
1750         int i;
1751
1752         for (mp = me->mpoly, i = 0; i < me->totpoly; i++, mp++) {
1753                 if (mp->mat_nr && mp->mat_nr >= index) {
1754                         mp->mat_nr--;
1755                 }
1756         }
1757
1758         for (mf = me->mface, i = 0; i < me->totface; i++, mf++) {
1759                 if (mf->mat_nr && mf->mat_nr >= index) {
1760                         mf->mat_nr--;
1761                 }
1762         }
1763 }
1764
1765 void BKE_mesh_material_index_clear(Mesh *me)
1766 {
1767         MPoly *mp;
1768         MFace *mf;
1769         int i;
1770
1771         for (mp = me->mpoly, i = 0; i < me->totpoly; i++, mp++) {
1772                 mp->mat_nr = 0;
1773         }
1774
1775         for (mf = me->mface, i = 0; i < me->totface; i++, mf++) {
1776                 mf->mat_nr = 0;
1777         }
1778 }
1779
1780 void BKE_mesh_material_remap(Mesh *me, const unsigned int *remap, unsigned int remap_len)
1781 {
1782         const short remap_len_short = (short)remap_len;
1783
1784 #define MAT_NR_REMAP(n) \
1785         if (n < remap_len_short) { \
1786                 BLI_assert(n >= 0 && remap[n] < remap_len_short); \
1787                 n = remap[n]; \
1788         } ((void)0)
1789
1790         if (me->edit_btmesh) {
1791                 BMEditMesh *em = me->edit_btmesh;
1792                 BMIter iter;
1793                 BMFace *efa;
1794
1795                 BM_ITER_MESH(efa, &iter, em->bm, BM_FACES_OF_MESH) {
1796                         MAT_NR_REMAP(efa->mat_nr);
1797                 }
1798         }
1799         else {
1800                 int i;
1801                 for (i = 0; i < me->totpoly; i++) {
1802                         MAT_NR_REMAP(me->mpoly[i].mat_nr);
1803                 }
1804         }
1805
1806 #undef MAT_NR_REMAP
1807
1808 }
1809
1810 void BKE_mesh_smooth_flag_set(Object *meshOb, int enableSmooth) 
1811 {
1812         Mesh *me = meshOb->data;
1813         int i;
1814
1815         for (i = 0; i < me->totpoly; i++) {
1816                 MPoly *mp = &me->mpoly[i];
1817
1818                 if (enableSmooth) {
1819                         mp->flag |= ME_SMOOTH;
1820                 }
1821                 else {
1822                         mp->flag &= ~ME_SMOOTH;
1823                 }
1824         }
1825         
1826         for (i = 0; i < me->totface; i++) {
1827                 MFace *mf = &me->mface[i];
1828
1829                 if (enableSmooth) {
1830                         mf->flag |= ME_SMOOTH;
1831                 }
1832                 else {
1833                         mf->flag &= ~ME_SMOOTH;
1834                 }
1835         }
1836 }
1837
1838 /**
1839  * Return a newly MEM_malloc'd array of all the mesh vertex locations
1840  * \note \a r_numVerts may be NULL
1841  */
1842 float (*BKE_mesh_vertexCos_get(const Mesh *me, int *r_numVerts))[3]
1843 {
1844         int i, numVerts = me->totvert;
1845         float (*cos)[3] = MEM_mallocN(sizeof(*cos) * numVerts, "vertexcos1");
1846
1847         if (r_numVerts) *r_numVerts = numVerts;
1848         for (i = 0; i < numVerts; i++)
1849                 copy_v3_v3(cos[i], me->mvert[i].co);
1850
1851         return cos;
1852 }
1853
1854 /**
1855  * Find the index of the loop in 'poly' which references vertex,
1856  * returns -1 if not found
1857  */
1858 int poly_find_loop_from_vert(
1859         const MPoly *poly, const MLoop *loopstart,
1860         unsigned vert)
1861 {
1862         int j;
1863         for (j = 0; j < poly->totloop; j++, loopstart++) {
1864                 if (loopstart->v == vert)
1865                         return j;
1866         }
1867         
1868         return -1;
1869 }
1870
1871 /**
1872  * Fill \a r_adj with the loop indices in \a poly adjacent to the
1873  * vertex. Returns the index of the loop matching vertex, or -1 if the
1874  * vertex is not in \a poly
1875  */
1876 int poly_get_adj_loops_from_vert(
1877         const MPoly *poly,
1878         const MLoop *mloop, unsigned int vert,
1879         unsigned int r_adj[2])
1880 {
1881         int corner = poly_find_loop_from_vert(poly,
1882                                               &mloop[poly->loopstart],
1883                                               vert);
1884                 
1885         if (corner != -1) {
1886 #if 0   /* unused - this loop */
1887                 const MLoop *ml = &mloop[poly->loopstart + corner];
1888 #endif
1889
1890                 /* vertex was found */
1891                 r_adj[0] = ME_POLY_LOOP_PREV(mloop, poly, corner)->v;
1892                 r_adj[1] = ME_POLY_LOOP_NEXT(mloop, poly, corner)->v;
1893         }
1894
1895         return corner;
1896 }
1897
1898 /**
1899  * Return the index of the edge vert that is not equal to \a v. If
1900  * neither edge vertex is equal to \a v, returns -1.
1901  */
1902 int BKE_mesh_edge_other_vert(const MEdge *e, int v)
1903 {
1904         if (e->v1 == v)
1905                 return e->v2;
1906         else if (e->v2 == v)
1907                 return e->v1;
1908         else
1909                 return -1;
1910 }
1911
1912 /* basic vertex data functions */
1913 bool BKE_mesh_minmax(const Mesh *me, float r_min[3], float r_max[3])
1914 {
1915         int i = me->totvert;
1916         MVert *mvert;
1917         for (mvert = me->mvert; i--; mvert++) {
1918                 minmax_v3v3_v3(r_min, r_max, mvert->co);
1919         }
1920         
1921         return (me->totvert != 0);
1922 }
1923
1924 void BKE_mesh_transform(Mesh *me, float mat[4][4], bool do_keys)
1925 {
1926         int i;
1927         MVert *mvert = me->mvert;
1928         float (*lnors)[3] = CustomData_get_layer(&me->ldata, CD_NORMAL);
1929
1930         for (i = 0; i < me->totvert; i++, mvert++)
1931                 mul_m4_v3(mat, mvert->co);
1932
1933         if (do_keys && me->key) {
1934                 KeyBlock *kb;
1935                 for (kb = me->key->block.first; kb; kb = kb->next) {
1936                         float *fp = kb->data;
1937                         for (i = kb->totelem; i--; fp += 3) {
1938                                 mul_m4_v3(mat, fp);
1939                         }
1940                 }
1941         }
1942
1943         /* don't update normals, caller can do this explicitly.
1944          * We do update loop normals though, those may not be auto-generated (see e.g. STL import script)! */
1945         if (lnors) {
1946                 float m3[3][3];
1947
1948                 copy_m3_m4(m3, mat);
1949                 normalize_m3(m3);
1950                 for (i = 0; i < me->totloop; i++, lnors++) {
1951                         mul_m3_v3(m3, *lnors);
1952                 }
1953         }
1954 }
1955
1956 void BKE_mesh_translate(Mesh *me, const float offset[3], const bool do_keys)
1957 {
1958         int i = me->totvert;
1959         MVert *mvert;
1960         for (mvert = me->mvert; i--; mvert++) {
1961                 add_v3_v3(mvert->co, offset);
1962         }
1963         
1964         if (do_keys && me->key) {
1965                 KeyBlock *kb;
1966                 for (kb = me->key->block.first; kb; kb = kb->next) {
1967                         float *fp = kb->data;
1968                         for (i = kb->totelem; i--; fp += 3) {
1969                                 add_v3_v3(fp, offset);
1970                         }
1971                 }
1972         }
1973 }
1974
1975 void BKE_mesh_ensure_navmesh(Mesh *me)
1976 {
1977         if (!CustomData_has_layer(&me->pdata, CD_RECAST)) {
1978                 int i;
1979                 int numFaces = me->totpoly;
1980                 int *recastData;
1981                 recastData = (int *)MEM_mallocN(numFaces * sizeof(int), __func__);
1982                 for (i = 0; i < numFaces; i++) {
1983                         recastData[i] = i + 1;
1984                 }
1985                 CustomData_add_layer_named(&me->pdata, CD_RECAST, CD_ASSIGN, recastData, numFaces, "recastData");
1986         }
1987 }
1988
1989 void BKE_mesh_tessface_calc(Mesh *mesh)
1990 {
1991         mesh->totface = BKE_mesh_recalc_tessellation(&mesh->fdata, &mesh->ldata, &mesh->pdata,
1992                                                      mesh->mvert,
1993                                                      mesh->totface, mesh->totloop, mesh->totpoly,
1994                                                      /* calc normals right after, don't copy from polys here */
1995                                                      false);
1996
1997         BKE_mesh_update_customdata_pointers(mesh, true);
1998 }
1999
2000 void BKE_mesh_tessface_ensure(Mesh *mesh)
2001 {
2002         if (mesh->totpoly && mesh->totface == 0) {
2003                 BKE_mesh_tessface_calc(mesh);
2004         }
2005 }
2006
2007 void BKE_mesh_tessface_clear(Mesh *mesh)
2008 {
2009         mesh_tessface_clear_intern(mesh, true);
2010 }
2011
2012 void BKE_mesh_do_versions_cd_flag_init(Mesh *mesh)
2013 {
2014         if (UNLIKELY(mesh->cd_flag)) {
2015                 return;
2016         }
2017         else {
2018                 MVert *mv;
2019                 MEdge *med;
2020                 int i;
2021
2022                 for (mv = mesh->mvert, i = 0; i < mesh->totvert; mv++, i++) {
2023                         if (mv->bweight != 0) {
2024                                 mesh->cd_flag |= ME_CDFLAG_VERT_BWEIGHT;
2025                                 break;
2026                         }
2027                 }
2028
2029                 for (med = mesh->medge, i = 0; i < mesh->totedge; med++, i++) {
2030                         if (med->bweight != 0) {
2031                                 mesh->cd_flag |= ME_CDFLAG_EDGE_BWEIGHT;
2032                                 if (mesh->cd_flag & ME_CDFLAG_EDGE_CREASE) {
2033                                         break;
2034                                 }
2035                         }
2036                         if (med->crease != 0) {
2037                                 mesh->cd_flag |= ME_CDFLAG_EDGE_CREASE;
2038                                 if (mesh->cd_flag & ME_CDFLAG_EDGE_BWEIGHT) {
2039                                         break;
2040                                 }
2041                         }
2042                 }
2043
2044         }
2045 }
2046
2047
2048 /* -------------------------------------------------------------------- */
2049 /* MSelect functions (currently used in weight paint mode) */
2050
2051 void BKE_mesh_mselect_clear(Mesh *me)
2052 {
2053         if (me->mselect) {
2054                 MEM_freeN(me->mselect);
2055                 me->mselect = NULL;
2056         }
2057         me->totselect = 0;
2058 }
2059
2060 void BKE_mesh_mselect_validate(Mesh *me)
2061 {
2062         MSelect *mselect_src, *mselect_dst;
2063         int i_src, i_dst;
2064
2065         if (me->totselect == 0)
2066                 return;
2067
2068         mselect_src = me->mselect;
2069         mselect_dst = MEM_mallocN(sizeof(MSelect) * (me->totselect), "Mesh selection history");
2070
2071         for (i_src = 0, i_dst = 0; i_src < me->totselect; i_src++) {
2072                 int index = mselect_src[i_src].index;
2073                 switch (mselect_src[i_src].type) {
2074                         case ME_VSEL:
2075                         {
2076                                 if (me->mvert[index].flag & SELECT) {
2077                                         mselect_dst[i_dst] = mselect_src[i_src];
2078                                         i_dst++;
2079                                 }
2080                                 break;
2081                         }
2082                         case ME_ESEL:
2083                         {
2084                                 if (me->medge[index].flag & SELECT) {
2085                                         mselect_dst[i_dst] = mselect_src[i_src];
2086                                         i_dst++;
2087                                 }
2088                                 break;
2089                         }
2090                         case ME_FSEL:
2091                         {
2092                                 if (me->mpoly[index].flag & SELECT) {
2093                                         mselect_dst[i_dst] = mselect_src[i_src];
2094                                         i_dst++;
2095                                 }
2096                                 break;
2097                         }
2098                         default:
2099                         {
2100                                 BLI_assert(0);
2101                                 break;
2102                         }
2103                 }
2104         }
2105
2106         MEM_freeN(mselect_src);
2107
2108         if (i_dst == 0) {
2109                 MEM_freeN(mselect_dst);
2110                 mselect_dst = NULL;
2111         }
2112         else if (i_dst != me->totselect) {
2113                 mselect_dst = MEM_reallocN(mselect_dst, sizeof(MSelect) * i_dst);
2114         }
2115
2116         me->totselect = i_dst;
2117         me->mselect = mselect_dst;
2118
2119 }
2120
2121 /**
2122  * Return the index within me->mselect, or -1
2123  */
2124 int BKE_mesh_mselect_find(Mesh *me, int index, int type)
2125 {
2126         int i;
2127
2128         BLI_assert(ELEM(type, ME_VSEL, ME_ESEL, ME_FSEL));
2129
2130         for (i = 0; i < me->totselect; i++) {
2131                 if ((me->mselect[i].index == index) &&
2132                     (me->mselect[i].type == type))
2133                 {
2134                         return i;
2135                 }
2136         }
2137
2138         return -1;
2139 }
2140
2141 /**
2142  * Return The index of the active element.
2143  */
2144 int BKE_mesh_mselect_active_get(Mesh *me, int type)
2145 {
2146         BLI_assert(ELEM(type, ME_VSEL, ME_ESEL, ME_FSEL));
2147
2148         if (me->totselect) {
2149                 if (me->mselect[me->totselect - 1].type == type) {
2150                         return me->mselect[me->totselect - 1].index;
2151                 }
2152         }
2153         return -1;
2154 }
2155
2156 void BKE_mesh_mselect_active_set(Mesh *me, int index, int type)
2157 {
2158         const int msel_index = BKE_mesh_mselect_find(me, index, type);
2159
2160         if (msel_index == -1) {
2161                 /* add to the end */
2162                 me->mselect = MEM_reallocN(me->mselect, sizeof(MSelect) * (me->totselect + 1));
2163                 me->mselect[me->totselect].index = index;
2164                 me->mselect[me->totselect].type  = type;
2165                 me->totselect++;
2166         }
2167         else if (msel_index != me->totselect - 1) {
2168                 /* move to the end */
2169                 SWAP(MSelect, me->mselect[msel_index], me->mselect[me->totselect - 1]);
2170         }
2171
2172         BLI_assert((me->mselect[me->totselect - 1].index == index) &&
2173                    (me->mselect[me->totselect - 1].type  == type));
2174 }
2175
2176 void BKE_mesh_calc_normals_split(Mesh *mesh)
2177 {
2178         float (*r_loopnors)[3];
2179         float (*polynors)[3];
2180         short (*clnors)[2] = NULL;
2181         bool free_polynors = false;
2182
2183         if (CustomData_has_layer(&mesh->ldata, CD_NORMAL)) {
2184                 r_loopnors = CustomData_get_layer(&mesh->ldata, CD_NORMAL);
2185                 memset(r_loopnors, 0, sizeof(float[3]) * mesh->totloop);
2186         }
2187         else {
2188                 r_loopnors = CustomData_add_layer(&mesh->ldata, CD_NORMAL, CD_CALLOC, NULL, mesh->totloop);
2189                 CustomData_set_layer_flag(&mesh->ldata, CD_NORMAL, CD_FLAG_TEMPORARY);
2190         }
2191
2192         /* may be NULL */
2193         clnors = CustomData_get_layer(&mesh->ldata, CD_CUSTOMLOOPNORMAL);
2194
2195         if (CustomData_has_layer(&mesh->pdata, CD_NORMAL)) {
2196                 /* This assume that layer is always up to date, not sure this is the case (esp. in Edit mode?)... */
2197                 polynors = CustomData_get_layer(&mesh->pdata, CD_NORMAL);
2198                 free_polynors = false;
2199         }
2200         else {
2201                 polynors = MEM_mallocN(sizeof(float[3]) * mesh->totpoly, __func__);
2202                 BKE_mesh_calc_normals_poly(
2203                             mesh->mvert, NULL, mesh->totvert,
2204                             mesh->mloop, mesh->mpoly, mesh->totloop, mesh->totpoly, polynors, false);
2205                 free_polynors = true;
2206         }
2207
2208         BKE_mesh_normals_loop_split(
2209                 mesh->mvert, mesh->totvert, mesh->medge, mesh->totedge,
2210                 mesh->mloop, r_loopnors, mesh->totloop, mesh->mpoly, (const float (*)[3])polynors, mesh->totpoly,
2211                 (mesh->flag & ME_AUTOSMOOTH) != 0, mesh->smoothresh, NULL, clnors, NULL);
2212
2213         if (free_polynors) {
2214                 MEM_freeN(polynors);
2215         }
2216 }
2217
2218 /* Spli faces based on the edge angle.
2219  * Matches behavior of face splitting in render engines.
2220  */
2221 void BKE_mesh_split_faces(Mesh *mesh)
2222 {
2223         const int num_verts = mesh->totvert;
2224         const int num_edges = mesh->totedge;
2225         const int num_polys = mesh->totpoly;
2226         MVert *mvert = mesh->mvert;
2227         MEdge *medge = mesh->medge;
2228         MLoop *mloop = mesh->mloop;
2229         MPoly *mpoly = mesh->mpoly;
2230         float (*lnors)[3];
2231         int poly, num_new_verts = 0;
2232         if ((mesh->flag & ME_AUTOSMOOTH) == 0) {
2233                 return;
2234         }
2235         BKE_mesh_tessface_clear(mesh);
2236         /* Compute loop normals if needed. */
2237         if (!CustomData_has_layer(&mesh->ldata, CD_NORMAL)) {
2238                 BKE_mesh_calc_normals_split(mesh);
2239         }
2240         lnors = CustomData_get_layer(&mesh->ldata, CD_NORMAL);
2241         /* Count number of vertices to be split. */
2242         for (poly = 0; poly < num_polys; poly++) {
2243                 MPoly *mp = &mpoly[poly];
2244                 int loop;
2245                 for (loop = 0; loop < mp->totloop; loop++) {
2246                         MLoop *ml = &mloop[mp->loopstart + loop];
2247                         MVert *mv = &mvert[ml->v];
2248                         float vn[3];
2249                         normal_short_to_float_v3(vn, mv->no);
2250                         if (!equals_v3v3(vn, lnors[mp->loopstart + loop])) {
2251                                 num_new_verts++;
2252                         }
2253                 }
2254         }
2255         if (num_new_verts == 0) {
2256                 /* No new vertices are to be added, can do early exit. */
2257                 return;
2258         }
2259         /* Reallocate all vert and edge related data. */
2260         mesh->totvert += num_new_verts;
2261         mesh->totedge += 2 * num_new_verts;
2262         CustomData_realloc(&mesh->vdata, mesh->totvert);
2263         CustomData_realloc(&mesh->edata, mesh->totedge);
2264         /* Update pointers to a newly allocated memory. */
2265         BKE_mesh_update_customdata_pointers(mesh, false);
2266         mvert = mesh->mvert;
2267         medge = mesh->medge;
2268         /* Perform actual vertex split. */
2269         num_new_verts = 0;
2270         for (poly = 0; poly < num_polys; poly++) {
2271                 MPoly *mp = &mpoly[poly];
2272                 int loop;
2273                 for (loop = 0; loop < mp->totloop; loop++) {
2274                         int poly_loop = mp->loopstart + loop;
2275                         MLoop *ml = &mloop[poly_loop];
2276                         MVert *mv = &mvert[ml->v];
2277                         float vn[3];
2278                         normal_short_to_float_v3(vn, mv->no);
2279                         if (!equals_v3v3(vn, lnors[mp->loopstart + loop])) {
2280                                 int poly_loop_prev = mp->loopstart + (loop + mp->totloop - 1) % mp->totloop;
2281                                 MLoop *ml_prev = &mloop[poly_loop_prev];
2282                                 int new_edge_prev, new_edge;
2283                                 /* Cretae new vertex. */
2284                                 int new_vert = num_verts + num_new_verts;
2285                                 CustomData_copy_data(&mesh->vdata, &mesh->vdata,
2286                                                      ml->v, new_vert, 1);
2287                                 normal_float_to_short_v3(mvert[new_vert].no,
2288                                                          lnors[poly_loop]);
2289                                 /* Create new edges. */
2290                                 new_edge_prev = num_edges + 2 * num_new_verts;
2291                                 new_edge = num_edges + 2 * num_new_verts + 1;
2292                                 CustomData_copy_data(&mesh->edata, &mesh->edata,
2293                                                      ml_prev->e, new_edge_prev, 1);
2294                                 CustomData_copy_data(&mesh->edata, &mesh->edata,
2295                                                      ml->e, new_edge, 1);
2296                                 if (medge[new_edge_prev].v1 == ml->v) {
2297                                         medge[new_edge_prev].v1 = new_vert;
2298                                 }
2299                                 else {
2300                                         medge[new_edge_prev].v2 = new_vert;
2301                                 }
2302                                 if (medge[new_edge].v1 == ml->v) {
2303                                         medge[new_edge].v1 = new_vert;
2304                                 }
2305                                 else {
2306                                         medge[new_edge].v2 = new_vert;
2307                                 }
2308
2309                                 ml->v = new_vert;
2310                                 ml_prev->e = new_edge_prev;
2311                                 ml->e = new_edge;
2312                                 num_new_verts++;
2313                         }
2314                 }
2315         }
2316 }
2317
2318 /* settings: 1 - preview, 2 - render */
2319 Mesh *BKE_mesh_new_from_object(
2320         Main *bmain, Scene *sce, Object *ob,
2321         int apply_modifiers, int settings, int calc_tessface, int calc_undeformed)
2322 {
2323         Mesh *tmpmesh;
2324         Curve *tmpcu = NULL, *copycu;
2325         Object *tmpobj = NULL;
2326         int render = settings == eModifierMode_Render, i;
2327         int cage = !apply_modifiers;
2328
2329         /* perform the mesh extraction based on type */
2330         switch (ob->type) {
2331                 case OB_FONT:
2332                 case OB_CURVE:
2333                 case OB_SURF:
2334                 {
2335                         ListBase dispbase = {NULL, NULL};
2336                         DerivedMesh *derivedFinal = NULL;
2337                         int uv_from_orco;
2338
2339                         /* copies object and modifiers (but not the data) */
2340                         tmpobj = BKE_object_copy_ex(bmain, ob, true);
2341                         tmpcu = (Curve *)tmpobj->data;
2342                         tmpcu->id.us--;
2343
2344                         /* Copy cached display list, it might be needed by the stack evaluation.
2345                          * Ideally stack should be able to use render-time display list, but doing
2346                          * so is quite tricky and not safe so close to the release.
2347                          *
2348                          * TODO(sergey): Look into more proper solution.
2349                          */
2350                         if (ob->curve_cache != NULL) {
2351                                 if (tmpobj->curve_cache == NULL) {
2352                                         tmpobj->curve_cache = MEM_callocN(sizeof(CurveCache), "CurveCache for curve types");
2353                                 }
2354                                 BKE_displist_copy(&tmpobj->curve_cache->disp, &ob->curve_cache->disp);
2355                         }
2356
2357                         /* if getting the original caged mesh, delete object modifiers */
2358                         if (cage)
2359                                 BKE_object_free_modifiers(tmpobj);
2360
2361                         /* copies the data */
2362                         copycu = tmpobj->data = BKE_curve_copy((Curve *) ob->data);
2363
2364                         /* temporarily set edit so we get updates from edit mode, but
2365                          * also because for text datablocks copying it while in edit
2366                          * mode gives invalid data structures */
2367                         copycu->editfont = tmpcu->editfont;
2368                         copycu->editnurb = tmpcu->editnurb;
2369
2370                         /* get updated display list, and convert to a mesh */
2371                         BKE_displist_make_curveTypes_forRender(sce, tmpobj, &dispbase, &derivedFinal, false, render);
2372
2373                         copycu->editfont = NULL;
2374                         copycu->editnurb = NULL;
2375
2376                         tmpobj->derivedFinal = derivedFinal;
2377
2378                         /* convert object type to mesh */
2379                         uv_from_orco = (tmpcu->flag & CU_UV_ORCO) != 0;
2380                         BKE_mesh_from_nurbs_displist(tmpobj, &dispbase, uv_from_orco);
2381
2382                         tmpmesh = tmpobj->data;
2383
2384                         BKE_displist_free(&dispbase);
2385
2386                         /* BKE_mesh_from_nurbs changes the type to a mesh, check it worked.
2387                          * if it didn't the curve did not have any segments or otherwise 
2388                          * would have generated an empty mesh */
2389                         if (tmpobj->type != OB_MESH) {
2390                                 BKE_libblock_free_us(bmain, tmpobj);
2391                                 return NULL;
2392                         }
2393
2394                         BKE_mesh_texspace_copy_from_object(tmpmesh, ob);
2395
2396                         BKE_libblock_free_us(bmain, tmpobj);
2397                         break;
2398                 }
2399
2400                 case OB_MBALL:
2401                 {
2402                         /* metaballs don't have modifiers, so just convert to mesh */
2403                         Object *basis_ob = BKE_mball_basis_find(sce, ob);
2404                         /* todo, re-generatre for render-res */
2405                         /* metaball_polygonize(scene, ob) */
2406
2407                         if (ob != basis_ob)
2408                                 return NULL;  /* only do basis metaball */
2409
2410                         tmpmesh = BKE_mesh_add(bmain, "Mesh");
2411                         /* BKE_mesh_add gives us a user count we don't need */
2412                         tmpmesh->id.us--;
2413
2414                         if (render) {
2415                                 ListBase disp = {NULL, NULL};
2416                                 /* TODO(sergey): This is gonna to work for until EvaluationContext
2417                                  *               only contains for_render flag. As soon as CoW is
2418                                  *               implemented, this is to be rethinked.
2419                                  */
2420                                 EvaluationContext eval_ctx;
2421                                 DEG_evaluation_context_init(&eval_ctx, DAG_EVAL_RENDER);
2422                                 BKE_displist_make_mball_forRender(&eval_ctx, sce, ob, &disp);
2423                                 BKE_mesh_from_metaball(&disp, tmpmesh);
2424                                 BKE_displist_free(&disp);
2425                         }
2426                         else {
2427                                 ListBase disp = {NULL, NULL};
2428                                 if (ob->curve_cache) {
2429                                         disp = ob->curve_cache->disp;
2430                                 }
2431                                 BKE_mesh_from_metaball(&disp, tmpmesh);
2432                         }
2433
2434                         BKE_mesh_texspace_copy_from_object(tmpmesh, ob);
2435
2436                         break;
2437
2438                 }
2439                 case OB_MESH:
2440                         /* copies object and modifiers (but not the data) */
2441                         if (cage) {
2442                                 /* copies the data */
2443                                 tmpmesh = BKE_mesh_copy_ex(bmain, ob->data);
2444                                 /* if not getting the original caged mesh, get final derived mesh */
2445                         }
2446                         else {
2447                                 /* Make a dummy mesh, saves copying */
2448                                 DerivedMesh *dm;
2449                                 /* CustomDataMask mask = CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL; */
2450                                 CustomDataMask mask = CD_MASK_MESH; /* this seems more suitable, exporter,
2451                                                                  * for example, needs CD_MASK_MDEFORMVERT */
2452
2453                                 if (calc_undeformed)
2454                                         mask |= CD_MASK_ORCO;
2455
2456                                 /* Write the display mesh into the dummy mesh */
2457                                 if (render)
2458                                         dm = mesh_create_derived_render(sce, ob, mask);
2459                                 else
2460                                         dm = mesh_create_derived_view(sce, ob, mask);
2461
2462                                 tmpmesh = BKE_mesh_add(bmain, "Mesh");
2463                                 DM_to_mesh(dm, tmpmesh, ob, mask, true);
2464                         }
2465
2466                         /* BKE_mesh_add/copy gives us a user count we don't need */
2467                         tmpmesh->id.us--;
2468
2469                         break;
2470                 default:
2471                         /* "Object does not have geometry data") */
2472                         return NULL;
2473         }
2474
2475         /* Copy materials to new mesh */
2476         switch (ob->type) {
2477                 case OB_SURF:
2478                 case OB_FONT:
2479                 case OB_CURVE:
2480                         tmpmesh->totcol = tmpcu->totcol;
2481
2482                         /* free old material list (if it exists) and adjust user counts */
2483                         if (tmpcu->mat) {
2484                                 for (i = tmpcu->totcol; i-- > 0; ) {
2485                                         /* are we an object material or data based? */
2486
2487                                         tmpmesh->mat[i] = ob->matbits[i] ? ob->mat[i] : tmpcu->mat[i];
2488
2489                                         if (tmpmesh->mat[i]) {
2490                                                 tmpmesh->mat[i]->id.us++;
2491                                         }
2492                                 }
2493                         }
2494                         break;
2495
2496 #if 0
2497                 /* Crashes when assigning the new material, not sure why */
2498                 case OB_MBALL:
2499                         tmpmb = (MetaBall *)ob->data;
2500                         tmpmesh->totcol = tmpmb->totcol;
2501
2502                         /* free old material list (if it exists) and adjust user counts */
2503                         if (tmpmb->mat) {
2504                                 for (i = tmpmb->totcol; i-- > 0; ) {
2505                                         tmpmesh->mat[i] = tmpmb->mat[i]; /* CRASH HERE ??? */
2506                                         if (tmpmesh->mat[i]) {
2507                                                 tmpmb->mat[i]->id.us++;
2508                                         }
2509                                 }
2510                         }
2511                         break;
2512 #endif
2513
2514                 case OB_MESH:
2515                         if (!cage) {
2516                                 Mesh *origmesh = ob->data;
2517                                 tmpmesh->flag = origmesh->flag;
2518                                 tmpmesh->mat = MEM_dupallocN(origmesh->mat);
2519                                 tmpmesh->totcol = origmesh->totcol;
2520                                 tmpmesh->smoothresh = origmesh->smoothresh;
2521                                 if (origmesh->mat) {
2522                                         for (i = origmesh->totcol; i-- > 0; ) {
2523                                                 /* are we an object material or data based? */
2524                                                 tmpmesh->mat[i] = ob->matbits[i] ? ob->mat[i] : origmesh->mat[i];
2525
2526                                                 if (tmpmesh->mat[i]) {
2527                                                         tmpmesh->mat[i]->id.us++;
2528                                                 }
2529                                         }
2530                                 }
2531                         }
2532                         break;
2533         } /* end copy materials */
2534
2535         if (calc_tessface) {
2536                 /* cycles and exporters rely on this still */
2537                 BKE_mesh_tessface_ensure(tmpmesh);
2538         }
2539
2540         /* make sure materials get updated in objects */
2541         test_object_materials(bmain, &tmpmesh->id);
2542
2543         return tmpmesh;
2544 }
2545
2546 /* **** Depsgraph evaluation **** */
2547
2548 void BKE_mesh_eval_geometry(EvaluationContext *UNUSED(eval_ctx),
2549                             Mesh *mesh)
2550 {
2551         if (G.debug & G_DEBUG_DEPSGRAPH) {
2552                 printf("%s on %s\n", __func__, mesh->id.name);
2553         }
2554         if (mesh->bb == NULL || (mesh->bb->flag & BOUNDBOX_DIRTY)) {
2555                 BKE_mesh_texspace_calc(mesh);
2556         }
2557 }