Cleanup: BKE_library: remove 'test' param of id_copy.
[blender.git] / source / blender / blenkernel / intern / mesh_convert.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16
17 /** \file blender/blenkernel/intern/mesh_convert.c
18  *  \ingroup bke
19  */
20
21 #include "CLG_log.h"
22
23 #include "MEM_guardedalloc.h"
24
25 #include "DNA_scene_types.h"
26 #include "DNA_key_types.h"
27 #include "DNA_material_types.h"
28 #include "DNA_meta_types.h"
29 #include "DNA_object_types.h"
30 #include "DNA_mesh_types.h"
31 #include "DNA_curve_types.h"
32
33 #include "BLI_utildefines.h"
34 #include "BLI_math.h"
35 #include "BLI_listbase.h"
36 #include "BLI_edgehash.h"
37
38 #include "BKE_main.h"
39 #include "BKE_DerivedMesh.h"
40 #include "BKE_key.h"
41 #include "BKE_mesh.h"
42 #include "BKE_mesh_runtime.h"
43 #include "BKE_modifier.h"
44 #include "BKE_displist.h"
45 #include "BKE_library.h"
46 #include "BKE_material.h"
47 #include "BKE_mball.h"
48 /* these 2 are only used by conversion functions */
49 #include "BKE_curve.h"
50 /* -- */
51 #include "BKE_object.h"
52
53 #include "DEG_depsgraph.h"
54 #include "DEG_depsgraph_query.h"
55
56 /* Define for cases when you want extra validation of mesh
57  * after certain modifications.
58  */
59 // #undef VALIDATE_MESH
60
61 #ifdef VALIDATE_MESH
62 #  define ASSERT_IS_VALID_MESH(mesh) (BLI_assert((mesh == NULL) || (BKE_mesh_is_valid(mesh) == true)))
63 #else
64 #  define ASSERT_IS_VALID_MESH(mesh)
65 #endif
66
67 static CLG_LogRef LOG = {"bke.mesh_convert"};
68
69 void BKE_mesh_from_metaball(ListBase *lb, Mesh *me)
70 {
71         DispList *dl;
72         MVert *mvert;
73         MLoop *mloop, *allloop;
74         MPoly *mpoly;
75         const float *nors, *verts;
76         int a, *index;
77
78         dl = lb->first;
79         if (dl == NULL) return;
80
81         if (dl->type == DL_INDEX4) {
82                 mvert = CustomData_add_layer(&me->vdata, CD_MVERT, CD_CALLOC, NULL, dl->nr);
83                 allloop = mloop = CustomData_add_layer(&me->ldata, CD_MLOOP, CD_CALLOC, NULL, dl->parts * 4);
84                 mpoly = CustomData_add_layer(&me->pdata, CD_MPOLY, CD_CALLOC, NULL, dl->parts);
85                 me->mvert = mvert;
86                 me->mloop = mloop;
87                 me->mpoly = mpoly;
88                 me->totvert = dl->nr;
89                 me->totpoly = dl->parts;
90
91                 a = dl->nr;
92                 nors = dl->nors;
93                 verts = dl->verts;
94                 while (a--) {
95                         copy_v3_v3(mvert->co, verts);
96                         normal_float_to_short_v3(mvert->no, nors);
97                         mvert++;
98                         nors += 3;
99                         verts += 3;
100                 }
101
102                 a = dl->parts;
103                 index = dl->index;
104                 while (a--) {
105                         int count = index[2] != index[3] ? 4 : 3;
106
107                         mloop[0].v = index[0];
108                         mloop[1].v = index[1];
109                         mloop[2].v = index[2];
110                         if (count == 4)
111                                 mloop[3].v = index[3];
112
113                         mpoly->totloop = count;
114                         mpoly->loopstart = (int)(mloop - allloop);
115                         mpoly->flag = ME_SMOOTH;
116
117
118                         mpoly++;
119                         mloop += count;
120                         me->totloop += count;
121                         index += 4;
122                 }
123
124                 BKE_mesh_update_customdata_pointers(me, true);
125
126                 BKE_mesh_calc_normals(me);
127
128                 BKE_mesh_calc_edges(me, true, false);
129         }
130 }
131
132 /**
133  * Specialized function to use when we _know_ existing edges don't overlap with poly edges.
134  */
135 static void make_edges_mdata_extend(
136         MEdge **r_alledge, int *r_totedge,
137         const MPoly *mpoly, MLoop *mloop,
138         const int totpoly)
139 {
140         int totedge = *r_totedge;
141         int totedge_new;
142         EdgeHash *eh;
143         unsigned int eh_reserve;
144         const MPoly *mp;
145         int i;
146
147         eh_reserve = max_ii(totedge, BLI_EDGEHASH_SIZE_GUESS_FROM_POLYS(totpoly));
148         eh = BLI_edgehash_new_ex(__func__, eh_reserve);
149
150         for (i = 0, mp = mpoly; i < totpoly; i++, mp++) {
151                 BKE_mesh_poly_edgehash_insert(eh, mp, mloop + mp->loopstart);
152         }
153
154         totedge_new = BLI_edgehash_len(eh);
155
156 #ifdef DEBUG
157         /* ensure that there's no overlap! */
158         if (totedge_new) {
159                 MEdge *medge = *r_alledge;
160                 for (i = 0; i < totedge; i++, medge++) {
161                         BLI_assert(BLI_edgehash_haskey(eh, medge->v1, medge->v2) == false);
162                 }
163         }
164 #endif
165
166         if (totedge_new) {
167                 EdgeHashIterator *ehi;
168                 MEdge *medge;
169                 unsigned int e_index = totedge;
170
171                 *r_alledge = medge = (*r_alledge ? MEM_reallocN(*r_alledge, sizeof(MEdge) * (totedge + totedge_new)) :
172                                                    MEM_calloc_arrayN(totedge_new, sizeof(MEdge), __func__));
173                 medge += totedge;
174
175                 totedge += totedge_new;
176
177                 /* --- */
178                 for (ehi = BLI_edgehashIterator_new(eh);
179                      BLI_edgehashIterator_isDone(ehi) == false;
180                      BLI_edgehashIterator_step(ehi), ++medge, e_index++)
181                 {
182                         BLI_edgehashIterator_getKey(ehi, &medge->v1, &medge->v2);
183                         BLI_edgehashIterator_setValue(ehi, POINTER_FROM_UINT(e_index));
184
185                         medge->crease = medge->bweight = 0;
186                         medge->flag = ME_EDGEDRAW | ME_EDGERENDER;
187                 }
188                 BLI_edgehashIterator_free(ehi);
189
190                 *r_totedge = totedge;
191
192
193                 for (i = 0, mp = mpoly; i < totpoly; i++, mp++) {
194                         MLoop *l = &mloop[mp->loopstart];
195                         MLoop *l_prev = (l + (mp->totloop - 1));
196                         int j;
197                         for (j = 0; j < mp->totloop; j++, l++) {
198                                 /* lookup hashed edge index */
199                                 l_prev->e = POINTER_AS_UINT(BLI_edgehash_lookup(eh, l_prev->v, l->v));
200                                 l_prev = l;
201                         }
202                 }
203         }
204
205         BLI_edgehash_free(eh, NULL);
206 }
207
208
209 /* Initialize mverts, medges and, faces for converting nurbs to mesh and derived mesh */
210 /* return non-zero on error */
211 int BKE_mesh_nurbs_to_mdata(
212         Object *ob, MVert **r_allvert, int *r_totvert,
213         MEdge **r_alledge, int *r_totedge, MLoop **r_allloop, MPoly **r_allpoly,
214         int *r_totloop, int *r_totpoly)
215 {
216         ListBase disp = {NULL, NULL};
217
218         if (ob->runtime.curve_cache) {
219                 disp = ob->runtime.curve_cache->disp;
220         }
221
222         return BKE_mesh_nurbs_displist_to_mdata(
223                 ob, &disp,
224                 r_allvert, r_totvert,
225                 r_alledge, r_totedge,
226                 r_allloop, r_allpoly, NULL,
227                 r_totloop, r_totpoly);
228 }
229
230 /* BMESH: this doesn't calculate all edges from polygons,
231  * only free standing edges are calculated */
232
233 /* Initialize mverts, medges and, faces for converting nurbs to mesh and derived mesh */
234 /* use specified dispbase */
235 int BKE_mesh_nurbs_displist_to_mdata(
236         Object *ob, const ListBase *dispbase,
237         MVert **r_allvert, int *r_totvert,
238         MEdge **r_alledge, int *r_totedge,
239         MLoop **r_allloop, MPoly **r_allpoly,
240         MLoopUV **r_alluv,
241         int *r_totloop, int *r_totpoly)
242 {
243         Curve *cu = ob->data;
244         DispList *dl;
245         MVert *mvert;
246         MPoly *mpoly;
247         MLoop *mloop;
248         MLoopUV *mloopuv = NULL;
249         MEdge *medge;
250         const float *data;
251         int a, b, ofs, vertcount, startvert, totvert = 0, totedge = 0, totloop = 0, totpoly = 0;
252         int p1, p2, p3, p4, *index;
253         const bool conv_polys = ((CU_DO_2DFILL(cu) == false) ||  /* 2d polys are filled with DL_INDEX3 displists */
254                                  (ob->type == OB_SURF));  /* surf polys are never filled */
255
256         /* count */
257         dl = dispbase->first;
258         while (dl) {
259                 if (dl->type == DL_SEGM) {
260                         totvert += dl->parts * dl->nr;
261                         totedge += dl->parts * (dl->nr - 1);
262                 }
263                 else if (dl->type == DL_POLY) {
264                         if (conv_polys) {
265                                 totvert += dl->parts * dl->nr;
266                                 totedge += dl->parts * dl->nr;
267                         }
268                 }
269                 else if (dl->type == DL_SURF) {
270                         int tot;
271                         totvert += dl->parts * dl->nr;
272                         tot = (dl->parts - 1 + ((dl->flag & DL_CYCL_V) == 2)) * (dl->nr - 1 + (dl->flag & DL_CYCL_U));
273                         totpoly += tot;
274                         totloop += tot * 4;
275                 }
276                 else if (dl->type == DL_INDEX3) {
277                         int tot;
278                         totvert += dl->nr;
279                         tot = dl->parts;
280                         totpoly += tot;
281                         totloop += tot * 3;
282                 }
283                 dl = dl->next;
284         }
285
286         if (totvert == 0) {
287                 /* error("can't convert"); */
288                 /* Make Sure you check ob->data is a curve */
289                 return -1;
290         }
291
292         *r_allvert = mvert = MEM_calloc_arrayN(totvert, sizeof(MVert), "nurbs_init mvert");
293         *r_alledge = medge = MEM_calloc_arrayN(totedge, sizeof(MEdge), "nurbs_init medge");
294         *r_allloop = mloop = MEM_calloc_arrayN(totpoly, 4 * sizeof(MLoop), "nurbs_init mloop"); // totloop
295         *r_allpoly = mpoly = MEM_calloc_arrayN(totpoly, sizeof(MPoly), "nurbs_init mloop");
296
297         if (r_alluv)
298                 *r_alluv = mloopuv = MEM_calloc_arrayN(totpoly, 4 * sizeof(MLoopUV), "nurbs_init mloopuv");
299
300         /* verts and faces */
301         vertcount = 0;
302
303         dl = dispbase->first;
304         while (dl) {
305                 const bool is_smooth = (dl->rt & CU_SMOOTH) != 0;
306
307                 if (dl->type == DL_SEGM) {
308                         startvert = vertcount;
309                         a = dl->parts * dl->nr;
310                         data = dl->verts;
311                         while (a--) {
312                                 copy_v3_v3(mvert->co, data);
313                                 data += 3;
314                                 vertcount++;
315                                 mvert++;
316                         }
317
318                         for (a = 0; a < dl->parts; a++) {
319                                 ofs = a * dl->nr;
320                                 for (b = 1; b < dl->nr; b++) {
321                                         medge->v1 = startvert + ofs + b - 1;
322                                         medge->v2 = startvert + ofs + b;
323                                         medge->flag = ME_LOOSEEDGE | ME_EDGERENDER | ME_EDGEDRAW;
324
325                                         medge++;
326                                 }
327                         }
328
329                 }
330                 else if (dl->type == DL_POLY) {
331                         if (conv_polys) {
332                                 startvert = vertcount;
333                                 a = dl->parts * dl->nr;
334                                 data = dl->verts;
335                                 while (a--) {
336                                         copy_v3_v3(mvert->co, data);
337                                         data += 3;
338                                         vertcount++;
339                                         mvert++;
340                                 }
341
342                                 for (a = 0; a < dl->parts; a++) {
343                                         ofs = a * dl->nr;
344                                         for (b = 0; b < dl->nr; b++) {
345                                                 medge->v1 = startvert + ofs + b;
346                                                 if (b == dl->nr - 1) medge->v2 = startvert + ofs;
347                                                 else medge->v2 = startvert + ofs + b + 1;
348                                                 medge->flag = ME_LOOSEEDGE | ME_EDGERENDER | ME_EDGEDRAW;
349                                                 medge++;
350                                         }
351                                 }
352                         }
353                 }
354                 else if (dl->type == DL_INDEX3) {
355                         startvert = vertcount;
356                         a = dl->nr;
357                         data = dl->verts;
358                         while (a--) {
359                                 copy_v3_v3(mvert->co, data);
360                                 data += 3;
361                                 vertcount++;
362                                 mvert++;
363                         }
364
365                         a = dl->parts;
366                         index = dl->index;
367                         while (a--) {
368                                 mloop[0].v = startvert + index[0];
369                                 mloop[1].v = startvert + index[2];
370                                 mloop[2].v = startvert + index[1];
371                                 mpoly->loopstart = (int)(mloop - (*r_allloop));
372                                 mpoly->totloop = 3;
373                                 mpoly->mat_nr = dl->col;
374
375                                 if (mloopuv) {
376                                         int i;
377
378                                         for (i = 0; i < 3; i++, mloopuv++) {
379                                                 mloopuv->uv[0] = (mloop[i].v - startvert) / (float)(dl->nr - 1);
380                                                 mloopuv->uv[1] = 0.0f;
381                                         }
382                                 }
383
384                                 if (is_smooth) mpoly->flag |= ME_SMOOTH;
385                                 mpoly++;
386                                 mloop += 3;
387                                 index += 3;
388                         }
389                 }
390                 else if (dl->type == DL_SURF) {
391                         startvert = vertcount;
392                         a = dl->parts * dl->nr;
393                         data = dl->verts;
394                         while (a--) {
395                                 copy_v3_v3(mvert->co, data);
396                                 data += 3;
397                                 vertcount++;
398                                 mvert++;
399                         }
400
401                         for (a = 0; a < dl->parts; a++) {
402
403                                 if ( (dl->flag & DL_CYCL_V) == 0 && a == dl->parts - 1) break;
404
405                                 if (dl->flag & DL_CYCL_U) {         /* p2 -> p1 -> */
406                                         p1 = startvert + dl->nr * a;    /* p4 -> p3 -> */
407                                         p2 = p1 + dl->nr - 1;       /* -----> next row */
408                                         p3 = p1 + dl->nr;
409                                         p4 = p2 + dl->nr;
410                                         b = 0;
411                                 }
412                                 else {
413                                         p2 = startvert + dl->nr * a;
414                                         p1 = p2 + 1;
415                                         p4 = p2 + dl->nr;
416                                         p3 = p1 + dl->nr;
417                                         b = 1;
418                                 }
419                                 if ( (dl->flag & DL_CYCL_V) && a == dl->parts - 1) {
420                                         p3 -= dl->parts * dl->nr;
421                                         p4 -= dl->parts * dl->nr;
422                                 }
423
424                                 for (; b < dl->nr; b++) {
425                                         mloop[0].v = p1;
426                                         mloop[1].v = p3;
427                                         mloop[2].v = p4;
428                                         mloop[3].v = p2;
429                                         mpoly->loopstart = (int)(mloop - (*r_allloop));
430                                         mpoly->totloop = 4;
431                                         mpoly->mat_nr = dl->col;
432
433                                         if (mloopuv) {
434                                                 int orco_sizeu = dl->nr - 1;
435                                                 int orco_sizev = dl->parts - 1;
436                                                 int i;
437
438                                                 /* exception as handled in convertblender.c too */
439                                                 if (dl->flag & DL_CYCL_U) {
440                                                         orco_sizeu++;
441                                                         if (dl->flag & DL_CYCL_V)
442                                                                 orco_sizev++;
443                                                 }
444                                                 else if (dl->flag & DL_CYCL_V) {
445                                                         orco_sizev++;
446                                                 }
447
448                                                 for (i = 0; i < 4; i++, mloopuv++) {
449                                                         /* find uv based on vertex index into grid array */
450                                                         int v = mloop[i].v - startvert;
451
452                                                         mloopuv->uv[0] = (v / dl->nr) / (float)orco_sizev;
453                                                         mloopuv->uv[1] = (v % dl->nr) / (float)orco_sizeu;
454
455                                                         /* cyclic correction */
456                                                         if ((i == 1 || i == 2) && mloopuv->uv[0] == 0.0f)
457                                                                 mloopuv->uv[0] = 1.0f;
458                                                         if ((i == 0 || i == 1) && mloopuv->uv[1] == 0.0f)
459                                                                 mloopuv->uv[1] = 1.0f;
460                                                 }
461                                         }
462
463                                         if (is_smooth) mpoly->flag |= ME_SMOOTH;
464                                         mpoly++;
465                                         mloop += 4;
466
467                                         p4 = p3;
468                                         p3++;
469                                         p2 = p1;
470                                         p1++;
471                                 }
472                         }
473                 }
474
475                 dl = dl->next;
476         }
477
478         if (totpoly) {
479                 make_edges_mdata_extend(
480                         r_alledge, &totedge,
481                         *r_allpoly, *r_allloop, totpoly);
482         }
483
484         *r_totpoly = totpoly;
485         *r_totloop = totloop;
486         *r_totedge = totedge;
487         *r_totvert = totvert;
488
489         return 0;
490 }
491
492 Mesh *BKE_mesh_new_nomain_from_curve_displist(Object *ob, ListBase *dispbase)
493 {
494         Curve *cu = ob->data;
495         Mesh *mesh;
496         MVert *allvert;
497         MEdge *alledge;
498         MLoop *allloop;
499         MPoly *allpoly;
500         MLoopUV *alluv = NULL;
501         int totvert, totedge, totloop, totpoly;
502         bool use_orco_uv = (cu->flag & CU_UV_ORCO) != 0;
503
504         if (BKE_mesh_nurbs_displist_to_mdata(
505                 ob, dispbase, &allvert, &totvert, &alledge,
506                 &totedge, &allloop, &allpoly, (use_orco_uv) ? &alluv : NULL,
507                 &totloop, &totpoly) != 0)
508         {
509                 /* Error initializing mdata. This often happens when curve is empty */
510                 return BKE_mesh_new_nomain(0, 0, 0, 0, 0);
511         }
512
513         mesh = BKE_mesh_new_nomain(totvert, totedge, 0, totloop, totpoly);
514         mesh->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
515
516         memcpy(mesh->mvert, allvert, totvert * sizeof(MVert));
517         memcpy(mesh->medge, alledge, totedge * sizeof(MEdge));
518         memcpy(mesh->mloop, allloop, totloop * sizeof(MLoop));
519         memcpy(mesh->mpoly, allpoly, totpoly * sizeof(MPoly));
520
521         if (alluv) {
522                 const char *uvname = "Orco";
523                 CustomData_add_layer_named(&mesh->ldata, CD_MLOOPUV, CD_ASSIGN, alluv, totloop, uvname);
524         }
525
526         MEM_freeN(allvert);
527         MEM_freeN(alledge);
528         MEM_freeN(allloop);
529         MEM_freeN(allpoly);
530
531         return mesh;
532 }
533
534 Mesh *BKE_mesh_new_nomain_from_curve(Object *ob)
535 {
536         ListBase disp = {NULL, NULL};
537
538         if (ob->runtime.curve_cache) {
539                 disp = ob->runtime.curve_cache->disp;
540         }
541
542         return BKE_mesh_new_nomain_from_curve_displist(ob, &disp);
543 }
544
545 /* this may fail replacing ob->data, be sure to check ob->type */
546 void BKE_mesh_from_nurbs_displist(
547         Main *bmain, Object *ob, ListBase *dispbase, const bool use_orco_uv, const char *obdata_name, bool temporary)
548 {
549         Object *ob1;
550         Mesh *me_eval = ob->runtime.mesh_eval;
551         Mesh *me;
552         Curve *cu;
553         MVert *allvert = NULL;
554         MEdge *alledge = NULL;
555         MLoop *allloop = NULL;
556         MLoopUV *alluv = NULL;
557         MPoly *allpoly = NULL;
558         int totvert, totedge, totloop, totpoly;
559
560         cu = ob->data;
561
562         if (me_eval == NULL) {
563                 if (BKE_mesh_nurbs_displist_to_mdata(
564                             ob, dispbase, &allvert, &totvert,
565                             &alledge, &totedge, &allloop,
566                             &allpoly, (use_orco_uv) ? &alluv : NULL,
567                             &totloop, &totpoly) != 0)
568                 {
569                         /* Error initializing */
570                         return;
571                 }
572
573                 /* make mesh */
574                 me = BKE_mesh_add(bmain, obdata_name);
575                 me->totvert = totvert;
576                 me->totedge = totedge;
577                 me->totloop = totloop;
578                 me->totpoly = totpoly;
579
580                 me->mvert = CustomData_add_layer(&me->vdata, CD_MVERT, CD_ASSIGN, allvert, me->totvert);
581                 me->medge = CustomData_add_layer(&me->edata, CD_MEDGE, CD_ASSIGN, alledge, me->totedge);
582                 me->mloop = CustomData_add_layer(&me->ldata, CD_MLOOP, CD_ASSIGN, allloop, me->totloop);
583                 me->mpoly = CustomData_add_layer(&me->pdata, CD_MPOLY, CD_ASSIGN, allpoly, me->totpoly);
584
585                 if (alluv) {
586                         const char *uvname = "Orco";
587                         me->mloopuv = CustomData_add_layer_named(&me->ldata, CD_MLOOPUV, CD_ASSIGN, alluv, me->totloop, uvname);
588                 }
589
590                 BKE_mesh_calc_normals(me);
591         }
592         else {
593                 me = BKE_mesh_add(bmain, obdata_name);
594                 ob->runtime.mesh_eval = NULL;
595                 BKE_mesh_nomain_to_mesh(me_eval, me, ob, CD_MASK_MESH, false);
596         }
597
598         me->totcol = cu->totcol;
599         me->mat = cu->mat;
600
601         /* Copy evaluated texture space from curve to mesh.
602          *
603          * Note that we disable auto texture space feature since that will cause
604          * texture space to evaluate differently for curve and mesh, since curve
605          * uses CV to calculate bounding box, and mesh uses what is coming from
606          * tessellated curve.
607          */
608         me->texflag = cu->texflag & ~CU_AUTOSPACE;
609         copy_v3_v3(me->loc, cu->loc);
610         copy_v3_v3(me->size, cu->size);
611         copy_v3_v3(me->rot, cu->rot);
612         BKE_mesh_texspace_calc(me);
613
614         cu->mat = NULL;
615         cu->totcol = 0;
616
617         /* Do not decrement ob->data usercount here, it's done at end of func with BKE_id_free_us() call. */
618         ob->data = me;
619         ob->type = OB_MESH;
620
621         /* other users */
622         ob1 = bmain->object.first;
623         while (ob1) {
624                 if (ob1->data == cu) {
625                         ob1->type = OB_MESH;
626
627                         id_us_min((ID *)ob1->data);
628                         ob1->data = ob->data;
629                         id_us_plus((ID *)ob1->data);
630                 }
631                 ob1 = ob1->id.next;
632         }
633
634         if (temporary) {
635                 /* For temporary objects in BKE_mesh_new_from_object don't remap
636                  * the entire scene with associated depsgraph updates, which are
637                  * problematic for renderers exporting data. */
638                 id_us_min(&cu->id);
639                 BKE_id_free(bmain, cu);
640         }
641         else {
642                 BKE_id_free_us(bmain, cu);
643         }
644 }
645
646 void BKE_mesh_from_nurbs(Main *bmain, Object *ob)
647 {
648         Curve *cu = (Curve *) ob->data;
649         bool use_orco_uv = (cu->flag & CU_UV_ORCO) != 0;
650         ListBase disp = {NULL, NULL};
651
652         if (ob->runtime.curve_cache) {
653                 disp = ob->runtime.curve_cache->disp;
654         }
655
656         BKE_mesh_from_nurbs_displist(bmain, ob, &disp, use_orco_uv, cu->id.name, false);
657 }
658
659 typedef struct EdgeLink {
660         struct EdgeLink *next, *prev;
661         void *edge;
662 } EdgeLink;
663
664 typedef struct VertLink {
665         Link *next, *prev;
666         unsigned int index;
667 } VertLink;
668
669 static void prependPolyLineVert(ListBase *lb, unsigned int index)
670 {
671         VertLink *vl = MEM_callocN(sizeof(VertLink), "VertLink");
672         vl->index = index;
673         BLI_addhead(lb, vl);
674 }
675
676 static void appendPolyLineVert(ListBase *lb, unsigned int index)
677 {
678         VertLink *vl = MEM_callocN(sizeof(VertLink), "VertLink");
679         vl->index = index;
680         BLI_addtail(lb, vl);
681 }
682
683 void BKE_mesh_to_curve_nurblist(const Mesh *me, ListBase *nurblist, const int edge_users_test)
684 {
685         MVert       *mvert = me->mvert;
686         MEdge *med, *medge = me->medge;
687         MPoly *mp,  *mpoly = me->mpoly;
688         MLoop       *mloop = me->mloop;
689
690         int medge_len = me->totedge;
691         int mpoly_len = me->totpoly;
692         int totedges = 0;
693         int i;
694
695         /* only to detect edge polylines */
696         int *edge_users;
697
698         ListBase edges = {NULL, NULL};
699
700         /* get boundary edges */
701         edge_users = MEM_calloc_arrayN(medge_len, sizeof(int), __func__);
702         for (i = 0, mp = mpoly; i < mpoly_len; i++, mp++) {
703                 MLoop *ml = &mloop[mp->loopstart];
704                 int j;
705                 for (j = 0; j < mp->totloop; j++, ml++) {
706                         edge_users[ml->e]++;
707                 }
708         }
709
710         /* create edges from all faces (so as to find edges not in any faces) */
711         med = medge;
712         for (i = 0; i < medge_len; i++, med++) {
713                 if (edge_users[i] == edge_users_test) {
714                         EdgeLink *edl = MEM_callocN(sizeof(EdgeLink), "EdgeLink");
715                         edl->edge = med;
716
717                         BLI_addtail(&edges, edl);   totedges++;
718                 }
719         }
720         MEM_freeN(edge_users);
721
722         if (edges.first) {
723                 while (edges.first) {
724                         /* each iteration find a polyline and add this as a nurbs poly spline */
725
726                         ListBase polyline = {NULL, NULL}; /* store a list of VertLink's */
727                         bool closed = false;
728                         int totpoly = 0;
729                         MEdge *med_current = ((EdgeLink *)edges.last)->edge;
730                         unsigned int startVert = med_current->v1;
731                         unsigned int endVert = med_current->v2;
732                         bool ok = true;
733
734                         appendPolyLineVert(&polyline, startVert);   totpoly++;
735                         appendPolyLineVert(&polyline, endVert);     totpoly++;
736                         BLI_freelinkN(&edges, edges.last);          totedges--;
737
738                         while (ok) { /* while connected edges are found... */
739                                 EdgeLink *edl = edges.last;
740                                 ok = false;
741                                 while (edl) {
742                                         EdgeLink *edl_prev = edl->prev;
743
744                                         med = edl->edge;
745
746                                         if (med->v1 == endVert) {
747                                                 endVert = med->v2;
748                                                 appendPolyLineVert(&polyline, med->v2); totpoly++;
749                                                 BLI_freelinkN(&edges, edl);             totedges--;
750                                                 ok = true;
751                                         }
752                                         else if (med->v2 == endVert) {
753                                                 endVert = med->v1;
754                                                 appendPolyLineVert(&polyline, endVert); totpoly++;
755                                                 BLI_freelinkN(&edges, edl);             totedges--;
756                                                 ok = true;
757                                         }
758                                         else if (med->v1 == startVert) {
759                                                 startVert = med->v2;
760                                                 prependPolyLineVert(&polyline, startVert);  totpoly++;
761                                                 BLI_freelinkN(&edges, edl);                 totedges--;
762                                                 ok = true;
763                                         }
764                                         else if (med->v2 == startVert) {
765                                                 startVert = med->v1;
766                                                 prependPolyLineVert(&polyline, startVert);  totpoly++;
767                                                 BLI_freelinkN(&edges, edl);                 totedges--;
768                                                 ok = true;
769                                         }
770
771                                         edl = edl_prev;
772                                 }
773                         }
774
775                         /* Now we have a polyline, make into a curve */
776                         if (startVert == endVert) {
777                                 BLI_freelinkN(&polyline, polyline.last);
778                                 totpoly--;
779                                 closed = true;
780                         }
781
782                         /* --- nurbs --- */
783                         {
784                                 Nurb *nu;
785                                 BPoint *bp;
786                                 VertLink *vl;
787
788                                 /* create new 'nurb' within the curve */
789                                 nu = (Nurb *)MEM_callocN(sizeof(Nurb), "MeshNurb");
790
791                                 nu->pntsu = totpoly;
792                                 nu->pntsv = 1;
793                                 nu->orderu = 4;
794                                 nu->flagu = CU_NURB_ENDPOINT | (closed ? CU_NURB_CYCLIC : 0);  /* endpoint */
795                                 nu->resolu = 12;
796
797                                 nu->bp = (BPoint *)MEM_calloc_arrayN(totpoly, sizeof(BPoint), "bpoints");
798
799                                 /* add points */
800                                 vl = polyline.first;
801                                 for (i = 0, bp = nu->bp; i < totpoly; i++, bp++, vl = (VertLink *)vl->next) {
802                                         copy_v3_v3(bp->vec, mvert[vl->index].co);
803                                         bp->f1 = SELECT;
804                                         bp->radius = bp->weight = 1.0;
805                                 }
806                                 BLI_freelistN(&polyline);
807
808                                 /* add nurb to curve */
809                                 BLI_addtail(nurblist, nu);
810                         }
811                         /* --- done with nurbs --- */
812                 }
813         }
814 }
815
816 void BKE_mesh_to_curve(Main *bmain, Depsgraph *depsgraph, Scene *UNUSED(scene), Object *ob)
817 {
818         /* make new mesh data from the original copy */
819         Scene *scene_eval = DEG_get_evaluated_scene(depsgraph);
820         Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
821         Mesh *me_eval = mesh_get_eval_final(depsgraph, scene_eval, ob_eval, CD_MASK_MESH);
822         ListBase nurblist = {NULL, NULL};
823
824         BKE_mesh_to_curve_nurblist(me_eval, &nurblist, 0);
825         BKE_mesh_to_curve_nurblist(me_eval, &nurblist, 1);
826
827         if (nurblist.first) {
828                 Curve *cu = BKE_curve_add(bmain, ob->id.name + 2, OB_CURVE);
829                 cu->flag |= CU_3D;
830
831                 cu->nurb = nurblist;
832
833                 id_us_min(&((Mesh *)ob->data)->id);
834                 ob->data = cu;
835                 ob->type = OB_CURVE;
836
837                 BKE_object_free_derived_caches(ob);
838         }
839 }
840
841 /* settings: 1 - preview, 2 - render */
842 Mesh *BKE_mesh_new_from_object(
843         Depsgraph *depsgraph, Main *bmain, Scene *sce, Object *ob,
844         const bool apply_modifiers, const bool calc_undeformed)
845 {
846         Mesh *tmpmesh;
847         Curve *tmpcu = NULL, *copycu;
848         int i;
849         const bool render = (DEG_get_mode(depsgraph) == DAG_EVAL_RENDER);
850         const bool cage = !apply_modifiers;
851         bool do_mat_id_data_us = true;
852
853         /* perform the mesh extraction based on type */
854         switch (ob->type) {
855                 case OB_FONT:
856                 case OB_CURVE:
857                 case OB_SURF:
858                 {
859                         ListBase dispbase = {NULL, NULL};
860                         Mesh *me_eval_final = NULL;
861                         int uv_from_orco;
862
863                         /* copies object and modifiers (but not the data) */
864                         Object *tmpobj;
865                         /* TODO: make it temp copy outside bmain! */
866                         BKE_id_copy_ex(bmain, &ob->id, (ID **)&tmpobj, LIB_ID_COPY_CACHES | LIB_ID_CREATE_NO_DEG_TAG);
867                         tmpcu = (Curve *)tmpobj->data;
868
869                         /* Copy cached display list, it might be needed by the stack evaluation.
870                          * Ideally stack should be able to use render-time display list, but doing
871                          * so is quite tricky and not safe so close to the release.
872                          *
873                          * TODO(sergey): Look into more proper solution.
874                          */
875                         if (ob->runtime.curve_cache != NULL) {
876                                 if (tmpobj->runtime.curve_cache == NULL) {
877                                         tmpobj->runtime.curve_cache = MEM_callocN(sizeof(CurveCache), "CurveCache for curve types");
878                                 }
879                                 BKE_displist_copy(&tmpobj->runtime.curve_cache->disp, &ob->runtime.curve_cache->disp);
880                         }
881
882                         /* if getting the original caged mesh, delete object modifiers */
883                         if (cage)
884                                 BKE_object_free_modifiers(tmpobj, 0);
885
886                         /* copies the data */
887                         BKE_id_copy_ex(bmain, ob->data, (ID **)&copycu, LIB_ID_CREATE_NO_DEG_TAG);
888                         id_us_min(tmpobj->data);
889                         tmpobj->data = copycu;
890
891                         /* make sure texture space is calculated for a copy of curve,
892                          * it will be used for the final result.
893                          */
894                         BKE_curve_texspace_calc(copycu);
895
896                         /* temporarily set edit so we get updates from edit mode, but
897                          * also because for text datablocks copying it while in edit
898                          * mode gives invalid data structures */
899                         copycu->editfont = tmpcu->editfont;
900                         copycu->editnurb = tmpcu->editnurb;
901
902                         /* get updated display list, and convert to a mesh */
903                         BKE_displist_make_curveTypes_forRender(depsgraph, sce, tmpobj, &dispbase, &me_eval_final, false, render);
904
905                         copycu->editfont = NULL;
906                         copycu->editnurb = NULL;
907
908                         tmpobj->runtime.mesh_eval = me_eval_final;
909
910                         /* convert object type to mesh */
911                         uv_from_orco = (tmpcu->flag & CU_UV_ORCO) != 0;
912                         BKE_mesh_from_nurbs_displist(bmain, tmpobj, &dispbase, uv_from_orco, tmpcu->id.name + 2, true);
913
914                         tmpmesh = tmpobj->data;
915
916                         BKE_displist_free(&dispbase);
917
918                         /* BKE_mesh_from_nurbs changes the type to a mesh, check it worked.
919                          * if it didn't the curve did not have any segments or otherwise
920                          * would have generated an empty mesh */
921                         if (tmpobj->type != OB_MESH) {
922                                 BKE_id_free(bmain, tmpobj);
923                                 return NULL;
924                         }
925
926                         BKE_id_free(bmain, tmpobj);
927
928                         /* XXX The curve to mesh conversion is convoluted... But essentially, BKE_mesh_from_nurbs_displist()
929                          *     already transfers the ownership of materials from the temp copy of the Curve ID to the new
930                          *     Mesh ID, so we do not want to increase materials' usercount later. */
931                         do_mat_id_data_us = false;
932
933                         break;
934                 }
935
936                 case OB_MBALL:
937                 {
938                         /* metaballs don't have modifiers, so just convert to mesh */
939                         Object *basis_ob = BKE_mball_basis_find(sce, ob);
940                         /* todo, re-generatre for render-res */
941                         /* metaball_polygonize(scene, ob) */
942
943                         if (ob != basis_ob)
944                                 return NULL;  /* only do basis metaball */
945
946                         tmpmesh = BKE_mesh_add(bmain, ((ID *)ob->data)->name + 2);
947                         /* BKE_mesh_add gives us a user count we don't need */
948                         id_us_min(&tmpmesh->id);
949
950                         if (render) {
951                                 ListBase disp = {NULL, NULL};
952                                 BKE_displist_make_mball_forRender(depsgraph, sce, ob, &disp);
953                                 BKE_mesh_from_metaball(&disp, tmpmesh);
954                                 BKE_displist_free(&disp);
955                         }
956                         else {
957                                 ListBase disp = {NULL, NULL};
958                                 if (ob->runtime.curve_cache) {
959                                         disp = ob->runtime.curve_cache->disp;
960                                 }
961                                 BKE_mesh_from_metaball(&disp, tmpmesh);
962                         }
963
964                         BKE_mesh_texspace_copy_from_object(tmpmesh, ob);
965
966                         break;
967
968                 }
969                 case OB_MESH:
970                         /* copies object and modifiers (but not the data) */
971                         if (cage) {
972                                 /* copies the data */
973                                 Mesh *mesh = ob->data;
974                                 BKE_id_copy_ex(bmain, &mesh->id, (ID **)&tmpmesh, 0);
975                                 /* XXX BKE_mesh_copy() already handles materials usercount. */
976                                 do_mat_id_data_us = false;
977                         }
978                         /* if not getting the original caged mesh, get final derived mesh */
979                         else {
980                                 /* Make a dummy mesh, saves copying */
981                                 Mesh *me_eval;
982                                 /* CustomDataMask mask = CD_MASK_BAREMESH|CD_MASK_MTFACE|CD_MASK_MCOL; */
983                                 CustomDataMask mask = CD_MASK_MESH; /* this seems more suitable, exporter,
984                                                                      * for example, needs CD_MASK_MDEFORMVERT */
985
986                                 if (calc_undeformed)
987                                         mask |= CD_MASK_ORCO;
988
989                                 if (render) {
990                                         me_eval = mesh_create_eval_final_render(depsgraph, sce, ob, mask);
991                                 }
992                                 else {
993                                         me_eval = mesh_create_eval_final_view(depsgraph, sce, ob, mask);
994                                 }
995
996                                 tmpmesh = BKE_mesh_add(bmain, ((ID *)ob->data)->name + 2);
997                                 BKE_mesh_nomain_to_mesh(me_eval, tmpmesh, ob, mask, true);
998
999                                 /* Copy autosmooth settings from original mesh. */
1000                                 Mesh *me = (Mesh *)ob->data;
1001                                 tmpmesh->flag |= (me->flag & ME_AUTOSMOOTH);
1002                                 tmpmesh->smoothresh = me->smoothresh;
1003                         }
1004
1005                         /* BKE_mesh_add/copy gives us a user count we don't need */
1006                         id_us_min(&tmpmesh->id);
1007
1008                         break;
1009                 default:
1010                         /* "Object does not have geometry data") */
1011                         return NULL;
1012         }
1013
1014         /* Copy materials to new mesh */
1015         switch (ob->type) {
1016                 case OB_SURF:
1017                 case OB_FONT:
1018                 case OB_CURVE:
1019                         tmpmesh->totcol = tmpcu->totcol;
1020
1021                         /* free old material list (if it exists) and adjust user counts */
1022                         if (tmpcu->mat) {
1023                                 for (i = tmpcu->totcol; i-- > 0; ) {
1024                                         /* are we an object material or data based? */
1025                                         tmpmesh->mat[i] = give_current_material(ob, i + 1);
1026
1027                                         if (((ob->matbits && ob->matbits[i]) || do_mat_id_data_us)  && tmpmesh->mat[i]) {
1028                                                 id_us_plus(&tmpmesh->mat[i]->id);
1029                                         }
1030                                 }
1031                         }
1032                         break;
1033
1034                 case OB_MBALL:
1035                 {
1036                         MetaBall *tmpmb = (MetaBall *)ob->data;
1037                         tmpmesh->mat = MEM_dupallocN(tmpmb->mat);
1038                         tmpmesh->totcol = tmpmb->totcol;
1039
1040                         /* free old material list (if it exists) and adjust user counts */
1041                         if (tmpmb->mat) {
1042                                 for (i = tmpmb->totcol; i-- > 0; ) {
1043                                         /* are we an object material or data based? */
1044                                         tmpmesh->mat[i] = give_current_material(ob, i + 1);
1045
1046                                         if (((ob->matbits && ob->matbits[i]) || do_mat_id_data_us) && tmpmesh->mat[i]) {
1047                                                 id_us_plus(&tmpmesh->mat[i]->id);
1048                                         }
1049                                 }
1050                         }
1051                         break;
1052                 }
1053
1054                 case OB_MESH:
1055                         if (!cage) {
1056                                 Mesh *origmesh = ob->data;
1057                                 tmpmesh->flag = origmesh->flag;
1058                                 tmpmesh->mat = MEM_dupallocN(origmesh->mat);
1059                                 tmpmesh->totcol = origmesh->totcol;
1060                                 tmpmesh->smoothresh = origmesh->smoothresh;
1061                                 if (origmesh->mat) {
1062                                         for (i = origmesh->totcol; i-- > 0; ) {
1063                                                 /* are we an object material or data based? */
1064                                                 tmpmesh->mat[i] = give_current_material(ob, i + 1);
1065
1066                                                 if (((ob->matbits && ob->matbits[i]) || do_mat_id_data_us)  && tmpmesh->mat[i]) {
1067                                                         id_us_plus(&tmpmesh->mat[i]->id);
1068                                                 }
1069                                         }
1070                                 }
1071                         }
1072                         break;
1073         } /* end copy materials */
1074
1075         return tmpmesh;
1076 }
1077
1078
1079 static void add_shapekey_layers(Mesh *mesh_dest, Mesh *mesh_src)
1080 {
1081         KeyBlock *kb;
1082         Key *key = mesh_src->key;
1083         int i;
1084
1085         if (!mesh_src->key)
1086                 return;
1087
1088         /* ensure we can use mesh vertex count for derived mesh custom data */
1089         if (mesh_src->totvert != mesh_dest->totvert) {
1090                 CLOG_ERROR(&LOG, "vertex size mismatch (mesh/dm) '%s' (%d != %d)",
1091                            mesh_src->id.name + 2, mesh_src->totvert, mesh_dest->totvert);
1092                 return;
1093         }
1094
1095         for (i = 0, kb = key->block.first; kb; kb = kb->next, i++) {
1096                 int ci;
1097                 float *array;
1098
1099                 if (mesh_src->totvert != kb->totelem) {
1100                         CLOG_ERROR(&LOG, "vertex size mismatch (Mesh '%s':%d != KeyBlock '%s':%d)",
1101                                 mesh_src->id.name + 2, mesh_src->totvert, kb->name, kb->totelem);
1102                         array = MEM_calloc_arrayN((size_t)mesh_src->totvert, 3 * sizeof(float), __func__);
1103                 }
1104                 else {
1105                         array = MEM_malloc_arrayN((size_t)mesh_src->totvert, 3 * sizeof(float), __func__);
1106                         memcpy(array, kb->data, (size_t)mesh_src->totvert * 3 * sizeof(float));
1107                 }
1108
1109                 CustomData_add_layer_named(&mesh_dest->vdata, CD_SHAPEKEY, CD_ASSIGN, array, mesh_dest->totvert, kb->name);
1110                 ci = CustomData_get_layer_index_n(&mesh_dest->vdata, CD_SHAPEKEY, i);
1111
1112                 mesh_dest->vdata.layers[ci].uid = kb->uid;
1113         }
1114 }
1115
1116
1117 Mesh *BKE_mesh_create_derived_for_modifier(
1118         struct Depsgraph *depsgraph, Scene *scene, Object *ob,
1119         ModifierData *md, int build_shapekey_layers)
1120 {
1121         Mesh *me = ob->data;
1122         const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
1123         Mesh *result;
1124         KeyBlock *kb;
1125         ModifierEvalContext mectx = {depsgraph, ob, 0};
1126
1127         if (!(md->mode & eModifierMode_Realtime)) {
1128                 return NULL;
1129         }
1130
1131         if (mti->isDisabled && mti->isDisabled(scene, md, 0)) {
1132                 return NULL;
1133         }
1134
1135         if (build_shapekey_layers && me->key && (kb = BLI_findlink(&me->key->block, ob->shapenr - 1))) {
1136                 BKE_keyblock_convert_to_mesh(kb, me);
1137         }
1138
1139         if (mti->type == eModifierTypeType_OnlyDeform) {
1140                 int numVerts;
1141                 float (*deformedVerts)[3] = BKE_mesh_vertexCos_get(me, &numVerts);
1142
1143                 mti->deformVerts(md, &mectx, NULL, deformedVerts, numVerts);
1144                 BKE_id_copy_ex(
1145                         NULL, &me->id, (ID **)&result,
1146                         LIB_ID_CREATE_NO_MAIN |
1147                         LIB_ID_CREATE_NO_USER_REFCOUNT |
1148                         LIB_ID_CREATE_NO_DEG_TAG |
1149                         LIB_ID_COPY_NO_PREVIEW);
1150                 BKE_mesh_apply_vert_coords(result, deformedVerts);
1151
1152                 if (build_shapekey_layers)
1153                         add_shapekey_layers(result, me);
1154
1155                 MEM_freeN(deformedVerts);
1156         }
1157         else {
1158                 Mesh *mesh_temp;
1159                 BKE_id_copy_ex(
1160                         NULL, &me->id, (ID **)&mesh_temp,
1161                         LIB_ID_CREATE_NO_MAIN |
1162                         LIB_ID_CREATE_NO_USER_REFCOUNT |
1163                         LIB_ID_CREATE_NO_DEG_TAG |
1164                         LIB_ID_COPY_NO_PREVIEW);
1165
1166                 if (build_shapekey_layers)
1167                         add_shapekey_layers(mesh_temp, me);
1168
1169                 result = mti->applyModifier(md, &mectx, mesh_temp);
1170                 ASSERT_IS_VALID_MESH(result);
1171
1172                 if (mesh_temp != result) {
1173                         BKE_id_free(NULL, mesh_temp);
1174                 }
1175         }
1176
1177         return result;
1178 }
1179
1180 /* This is a Mesh-based copy of the same function in DerivedMesh.c */
1181 static void shapekey_layers_to_keyblocks(Mesh *mesh_src, Mesh *mesh_dst, int actshape_uid)
1182 {
1183         KeyBlock *kb;
1184         int i, j, tot;
1185
1186         if (!mesh_dst->key)
1187                 return;
1188
1189         tot = CustomData_number_of_layers(&mesh_src->vdata, CD_SHAPEKEY);
1190         for (i = 0; i < tot; i++) {
1191                 CustomDataLayer *layer = &mesh_src->vdata.layers[CustomData_get_layer_index_n(&mesh_src->vdata, CD_SHAPEKEY, i)];
1192                 float (*cos)[3], (*kbcos)[3];
1193
1194                 for (kb = mesh_dst->key->block.first; kb; kb = kb->next) {
1195                         if (kb->uid == layer->uid)
1196                                 break;
1197                 }
1198
1199                 if (!kb) {
1200                         kb = BKE_keyblock_add(mesh_dst->key, layer->name);
1201                         kb->uid = layer->uid;
1202                 }
1203
1204                 if (kb->data)
1205                         MEM_freeN(kb->data);
1206
1207                 cos = CustomData_get_layer_n(&mesh_src->vdata, CD_SHAPEKEY, i);
1208                 kb->totelem = mesh_src->totvert;
1209
1210                 kb->data = kbcos = MEM_malloc_arrayN(kb->totelem, 3 * sizeof(float), __func__);
1211                 if (kb->uid == actshape_uid) {
1212                         MVert *mvert = mesh_src->mvert;
1213
1214                         for (j = 0; j < mesh_src->totvert; j++, kbcos++, mvert++) {
1215                                 copy_v3_v3(*kbcos, mvert->co);
1216                         }
1217                 }
1218                 else {
1219                         for (j = 0; j < kb->totelem; j++, cos++, kbcos++) {
1220                                 copy_v3_v3(*kbcos, *cos);
1221                         }
1222                 }
1223         }
1224
1225         for (kb = mesh_dst->key->block.first; kb; kb = kb->next) {
1226                 if (kb->totelem != mesh_src->totvert) {
1227                         if (kb->data)
1228                                 MEM_freeN(kb->data);
1229
1230                         kb->totelem = mesh_src->totvert;
1231                         kb->data = MEM_calloc_arrayN(kb->totelem, 3 * sizeof(float), __func__);
1232                         CLOG_ERROR(&LOG, "lost a shapekey layer: '%s'! (bmesh internal error)", kb->name);
1233                 }
1234         }
1235 }
1236
1237
1238 /* This is a Mesh-based copy of DM_to_mesh() */
1239 void BKE_mesh_nomain_to_mesh(Mesh *mesh_src, Mesh *mesh_dst, Object *ob, CustomDataMask mask, bool take_ownership)
1240 {
1241         /* mesh_src might depend on mesh_dst, so we need to do everything with a local copy */
1242         /* TODO(Sybren): the above claim came from DM_to_mesh(); check whether it is still true with Mesh */
1243         Mesh tmp = *mesh_dst;
1244         int totvert, totedge /*, totface */ /* UNUSED */, totloop, totpoly;
1245         int did_shapekeys = 0;
1246         eCDAllocType alloctype = CD_DUPLICATE;
1247
1248         if (take_ownership /* && dm->type == DM_TYPE_CDDM && dm->needsFree */) {
1249                 bool has_any_referenced_layers =
1250                         CustomData_has_referenced(&mesh_src->vdata) ||
1251                         CustomData_has_referenced(&mesh_src->edata) ||
1252                         CustomData_has_referenced(&mesh_src->ldata) ||
1253                         CustomData_has_referenced(&mesh_src->fdata) ||
1254                         CustomData_has_referenced(&mesh_src->pdata);
1255                 if (!has_any_referenced_layers) {
1256                         alloctype = CD_ASSIGN;
1257                 }
1258         }
1259         CustomData_reset(&tmp.vdata);
1260         CustomData_reset(&tmp.edata);
1261         CustomData_reset(&tmp.fdata);
1262         CustomData_reset(&tmp.ldata);
1263         CustomData_reset(&tmp.pdata);
1264
1265         BKE_mesh_ensure_normals(mesh_src);
1266
1267         totvert = tmp.totvert = mesh_src->totvert;
1268         totedge = tmp.totedge = mesh_src->totedge;
1269         totloop = tmp.totloop = mesh_src->totloop;
1270         totpoly = tmp.totpoly = mesh_src->totpoly;
1271         tmp.totface = 0;
1272
1273         CustomData_copy(&mesh_src->vdata, &tmp.vdata, mask, alloctype, totvert);
1274         CustomData_copy(&mesh_src->edata, &tmp.edata, mask, alloctype, totedge);
1275         CustomData_copy(&mesh_src->ldata, &tmp.ldata, mask, alloctype, totloop);
1276         CustomData_copy(&mesh_src->pdata, &tmp.pdata, mask, alloctype, totpoly);
1277         tmp.cd_flag = mesh_src->cd_flag;
1278         tmp.runtime.deformed_only = mesh_src->runtime.deformed_only;
1279
1280         if (CustomData_has_layer(&mesh_src->vdata, CD_SHAPEKEY)) {
1281                 KeyBlock *kb;
1282                 int uid;
1283
1284                 if (ob) {
1285                         kb = BLI_findlink(&mesh_dst->key->block, ob->shapenr - 1);
1286                         if (kb) {
1287                                 uid = kb->uid;
1288                         }
1289                         else {
1290                                 CLOG_ERROR(&LOG, "could not find active shapekey %d!", ob->shapenr - 1);
1291
1292                                 uid = INT_MAX;
1293                         }
1294                 }
1295                 else {
1296                         /* if no object, set to INT_MAX so we don't mess up any shapekey layers */
1297                         uid = INT_MAX;
1298                 }
1299
1300                 shapekey_layers_to_keyblocks(mesh_src, mesh_dst, uid);
1301                 did_shapekeys = 1;
1302         }
1303
1304         /* copy texture space */
1305         if (ob) {
1306                 BKE_mesh_texspace_copy_from_object(&tmp, ob);
1307         }
1308
1309         /* not all DerivedMeshes store their verts/edges/faces in CustomData, so
1310          * we set them here in case they are missing */
1311         /* TODO(Sybren): we could probably replace CD_ASSIGN with alloctype and always directly pass mesh_src->mxxx,
1312          * instead of using a ternary operator. */
1313         if (!CustomData_has_layer(&tmp.vdata, CD_MVERT)) {
1314                 CustomData_add_layer(
1315                         &tmp.vdata, CD_MVERT, CD_ASSIGN,
1316                         (alloctype == CD_ASSIGN) ? mesh_src->mvert : MEM_dupallocN(mesh_src->mvert),
1317                         totvert);
1318         }
1319         if (!CustomData_has_layer(&tmp.edata, CD_MEDGE)) {
1320                 CustomData_add_layer(
1321                         &tmp.edata, CD_MEDGE, CD_ASSIGN,
1322                         (alloctype == CD_ASSIGN) ? mesh_src->medge : MEM_dupallocN(mesh_src->medge),
1323                         totedge);
1324         }
1325         if (!CustomData_has_layer(&tmp.pdata, CD_MPOLY)) {
1326                 /* TODO(Sybren): assignment to tmp.mxxx is probably not necessary due to the
1327                  * BKE_mesh_update_customdata_pointers() call below. */
1328                 tmp.mloop = (alloctype == CD_ASSIGN) ? mesh_src->mloop : MEM_dupallocN(mesh_src->mloop);
1329                 tmp.mpoly = (alloctype == CD_ASSIGN) ? mesh_src->mpoly : MEM_dupallocN(mesh_src->mpoly);
1330
1331                 CustomData_add_layer(&tmp.ldata, CD_MLOOP, CD_ASSIGN, tmp.mloop, tmp.totloop);
1332                 CustomData_add_layer(&tmp.pdata, CD_MPOLY, CD_ASSIGN, tmp.mpoly, tmp.totpoly);
1333         }
1334
1335         /* object had got displacement layer, should copy this layer to save sculpted data */
1336         /* NOTE: maybe some other layers should be copied? nazgul */
1337         if (CustomData_has_layer(&mesh_dst->ldata, CD_MDISPS)) {
1338                 if (totloop == mesh_dst->totloop) {
1339                         MDisps *mdisps = CustomData_get_layer(&mesh_dst->ldata, CD_MDISPS);
1340                         CustomData_add_layer(&tmp.ldata, CD_MDISPS, alloctype, mdisps, totloop);
1341                 }
1342         }
1343
1344         /* yes, must be before _and_ after tessellate */
1345         BKE_mesh_update_customdata_pointers(&tmp, false);
1346
1347         /* since 2.65 caller must do! */
1348         // BKE_mesh_tessface_calc(&tmp);
1349
1350         CustomData_free(&mesh_dst->vdata, mesh_dst->totvert);
1351         CustomData_free(&mesh_dst->edata, mesh_dst->totedge);
1352         CustomData_free(&mesh_dst->fdata, mesh_dst->totface);
1353         CustomData_free(&mesh_dst->ldata, mesh_dst->totloop);
1354         CustomData_free(&mesh_dst->pdata, mesh_dst->totpoly);
1355
1356         /* ok, this should now use new CD shapekey data,
1357          * which should be fed through the modifier
1358          * stack */
1359         if (tmp.totvert != mesh_dst->totvert && !did_shapekeys && mesh_dst->key) {
1360                 CLOG_ERROR(&LOG, "YEEK! this should be recoded! Shape key loss!: ID '%s'", tmp.id.name);
1361                 if (tmp.key && !(tmp.id.tag & LIB_TAG_NO_MAIN)) {
1362                         id_us_min(&tmp.key->id);
1363                 }
1364                 tmp.key = NULL;
1365         }
1366
1367         /* Clear selection history */
1368         MEM_SAFE_FREE(tmp.mselect);
1369         tmp.totselect = 0;
1370         BLI_assert(ELEM(tmp.bb, NULL, mesh_dst->bb));
1371         if (mesh_dst->bb) {
1372                 MEM_freeN(mesh_dst->bb);
1373                 tmp.bb = NULL;
1374         }
1375
1376         /* skip the listbase */
1377         MEMCPY_STRUCT_OFS(mesh_dst, &tmp, id.prev);
1378
1379         if (take_ownership) {
1380                 if (alloctype == CD_ASSIGN) {
1381                         CustomData_free_typemask(&mesh_src->vdata, mesh_src->totvert, ~mask);
1382                         CustomData_free_typemask(&mesh_src->edata, mesh_src->totedge, ~mask);
1383                         CustomData_free_typemask(&mesh_src->ldata, mesh_src->totloop, ~mask);
1384                         CustomData_free_typemask(&mesh_src->pdata, mesh_src->totpoly, ~mask);
1385                 }
1386                 BKE_id_free(NULL, mesh_src);
1387         }
1388 }
1389
1390 /* This is a Mesh-based copy of DM_to_meshkey() */
1391 void BKE_mesh_nomain_to_meshkey(Mesh *mesh_src, Mesh *mesh_dst, KeyBlock *kb)
1392 {
1393         int a, totvert = mesh_src->totvert;
1394         float *fp;
1395         MVert *mvert;
1396
1397         if (totvert == 0 || mesh_dst->totvert == 0 || mesh_dst->totvert != totvert) {
1398                 return;
1399         }
1400
1401         if (kb->data) MEM_freeN(kb->data);
1402         kb->data = MEM_malloc_arrayN(mesh_dst->key->elemsize, mesh_dst->totvert, "kb->data");
1403         kb->totelem = totvert;
1404
1405         fp = kb->data;
1406         mvert = mesh_src->mvert;
1407
1408         for (a = 0; a < kb->totelem; a++, fp += 3, mvert++) {
1409                 copy_v3_v3(fp, mvert->co);
1410         }
1411 }