Depsgraph: remove EvaluationContext, pass Depsgraph instead.
[blender.git] / source / blender / blenkernel / intern / editderivedmesh.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) 2005 Blender Foundation.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/blenkernel/intern/editderivedmesh.c
29  *  \ingroup bke
30  *
31  * basic design:
32  *
33  * the bmesh derivedmesh exposes the mesh as triangles.  it stores pointers
34  * to three loops per triangle.  the derivedmesh stores a cache of tessellations
35  * for each face.  this cache will smartly update as needed (though at first
36  * it'll simply be more brute force).  keeping track of face/edge counts may
37  * be a small problem.
38  *
39  * this won't be the most efficient thing, considering that internal edges and
40  * faces of tessellations are exposed.  looking up an edge by index in particular
41  * is likely to be a little slow.
42  */
43
44 #include "atomic_ops.h"
45
46 #include "BLI_math.h"
47 #include "BLI_jitter_2d.h"
48 #include "BLI_bitmap.h"
49 #include "BLI_task.h"
50
51 #include "BKE_cdderivedmesh.h"
52 #include "BKE_mesh.h"
53 #include "BKE_editmesh.h"
54 #include "BKE_editmesh_bvh.h"
55 #include "BKE_editmesh_tangent.h"
56
57 #include "DNA_scene_types.h"
58 #include "DNA_object_types.h"
59
60 #include "MEM_guardedalloc.h"
61
62 #include "GPU_glew.h"
63 #include "GPU_buffers.h"
64 #include "GPU_shader.h"
65 #include "GPU_basic_shader.h"
66
67 static void bmdm_get_tri_colpreview(BMLoop *ls[3], MLoopCol *lcol[3], unsigned char(*color_vert_array)[4]);
68
69 typedef struct EditDerivedBMesh {
70         DerivedMesh dm;
71
72         BMEditMesh *em;
73
74         /** when set, \a vertexNos, polyNos are lazy initialized */
75         const float (*vertexCos)[3];
76
77         /** lazy initialize (when \a vertexCos is set) */
78         float const (*vertexNos)[3];
79         float const (*polyNos)[3];
80         /** also lazy init but dont depend on \a vertexCos */
81         const float (*polyCos)[3];
82 } EditDerivedBMesh;
83
84 /* -------------------------------------------------------------------- */
85 /* Lazy initialize datastructures */
86
87 static void emDM_ensurePolyNormals(EditDerivedBMesh *bmdm);
88
89 static void emDM_ensureVertNormals(EditDerivedBMesh *bmdm)
90 {
91         if (bmdm->vertexCos && (bmdm->vertexNos == NULL)) {
92
93                 BMesh *bm = bmdm->em->bm;
94                 const float (*vertexCos)[3], (*polyNos)[3];
95                 float (*vertexNos)[3];
96
97                 /* calculate vertex normals from poly normals */
98                 emDM_ensurePolyNormals(bmdm);
99
100                 BM_mesh_elem_index_ensure(bm, BM_FACE);
101
102                 polyNos = bmdm->polyNos;
103                 vertexCos = bmdm->vertexCos;
104                 vertexNos = MEM_callocN(sizeof(*vertexNos) * bm->totvert, __func__);
105
106                 BM_verts_calc_normal_vcos(bm, polyNos, vertexCos, vertexNos);
107
108                 bmdm->vertexNos = (const float (*)[3])vertexNos;
109         }
110 }
111
112 static void emDM_ensurePolyNormals(EditDerivedBMesh *bmdm)
113 {
114         if (bmdm->vertexCos && (bmdm->polyNos == NULL)) {
115                 BMesh *bm = bmdm->em->bm;
116                 const float (*vertexCos)[3];
117                 float (*polyNos)[3];
118
119                 BMFace *efa;
120                 BMIter fiter;
121                 int i;
122
123                 BM_mesh_elem_index_ensure(bm, BM_VERT);
124
125                 polyNos = MEM_mallocN(sizeof(*polyNos) * bm->totface, __func__);
126
127                 vertexCos = bmdm->vertexCos;
128
129                 BM_ITER_MESH_INDEX (efa, &fiter, bm, BM_FACES_OF_MESH, i) {
130                         BM_elem_index_set(efa, i); /* set_inline */
131                         BM_face_calc_normal_vcos(bm, efa, polyNos[i], vertexCos);
132                 }
133                 bm->elem_index_dirty &= ~BM_FACE;
134
135                 bmdm->polyNos = (const float (*)[3])polyNos;
136         }
137 }
138
139 static void emDM_ensurePolyCenters(EditDerivedBMesh *bmdm)
140 {
141         if (bmdm->polyCos == NULL) {
142                 BMesh *bm = bmdm->em->bm;
143                 float (*polyCos)[3];
144
145                 BMFace *efa;
146                 BMIter fiter;
147                 int i;
148
149                 polyCos = MEM_mallocN(sizeof(*polyCos) * bm->totface, __func__);
150
151                 if (bmdm->vertexCos) {
152                         const float (*vertexCos)[3];
153                         vertexCos = bmdm->vertexCos;
154
155                         BM_mesh_elem_index_ensure(bm, BM_VERT);
156
157                         BM_ITER_MESH_INDEX (efa, &fiter, bm, BM_FACES_OF_MESH, i) {
158                                 BM_face_calc_center_mean_vcos(bm, efa, polyCos[i], vertexCos);
159                         }
160                 }
161                 else {
162                         BM_ITER_MESH_INDEX (efa, &fiter, bm, BM_FACES_OF_MESH, i) {
163                                 BM_face_calc_center_mean(efa, polyCos[i]);
164                         }
165                 }
166
167                 bmdm->polyCos = (const float (*)[3])polyCos;
168         }
169 }
170
171 static void emDM_calcNormals(DerivedMesh *dm)
172 {
173         /* Nothing to do: normals are already calculated and stored on the
174          * BMVerts and BMFaces */
175         dm->dirty &= ~DM_DIRTY_NORMALS;
176 }
177
178 static void emDM_calcLoopNormalsSpaceArray(
179         DerivedMesh *dm, const bool use_split_normals, const float split_angle, MLoopNorSpaceArray *r_lnors_spacearr);
180
181 static void emDM_calcLoopNormals(DerivedMesh *dm, const bool use_split_normals, const float split_angle)
182 {
183         emDM_calcLoopNormalsSpaceArray(dm, use_split_normals, split_angle, NULL);
184 }
185
186 /* #define DEBUG_CLNORS */
187
188 static void emDM_calcLoopNormalsSpaceArray(
189         DerivedMesh *dm, const bool use_split_normals, const float split_angle, MLoopNorSpaceArray *r_lnors_spacearr)
190 {
191         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
192         BMesh *bm = bmdm->em->bm;
193         const float (*vertexCos)[3], (*vertexNos)[3], (*polyNos)[3];
194         float (*loopNos)[3];
195         short (*clnors_data)[2];
196         int cd_loop_clnors_offset;
197
198         /* calculate loop normals from poly and vertex normals */
199         emDM_ensureVertNormals(bmdm);
200         emDM_ensurePolyNormals(bmdm);
201         dm->dirty &= ~DM_DIRTY_NORMALS;
202
203         vertexCos = bmdm->vertexCos;
204         vertexNos = bmdm->vertexNos;
205         polyNos = bmdm->polyNos;
206
207         loopNos = dm->getLoopDataArray(dm, CD_NORMAL);
208         if (!loopNos) {
209                 DM_add_loop_layer(dm, CD_NORMAL, CD_CALLOC, NULL);
210                 loopNos = dm->getLoopDataArray(dm, CD_NORMAL);
211         }
212
213         /* We can have both, give priority to dm's data, and fallback to bm's ones. */
214         clnors_data = dm->getLoopDataArray(dm, CD_CUSTOMLOOPNORMAL);
215         cd_loop_clnors_offset = clnors_data ? -1 : CustomData_get_offset(&bm->ldata, CD_CUSTOMLOOPNORMAL);
216
217         BM_loops_calc_normal_vcos(bm, vertexCos, vertexNos, polyNos, use_split_normals, split_angle, loopNos,
218                                   r_lnors_spacearr, clnors_data, cd_loop_clnors_offset);
219 #ifdef DEBUG_CLNORS
220         if (r_lnors_spacearr) {
221                 int i;
222                 for (i = 0; i < numLoops; i++) {
223                         if (r_lnors_spacearr->lspacearr[i]->ref_alpha != 0.0f) {
224                                 LinkNode *loops = r_lnors_spacearr->lspacearr[i]->loops;
225                                 printf("Loop %d uses lnor space %p:\n", i, r_lnors_spacearr->lspacearr[i]);
226                                 print_v3("\tfinal lnor:", loopNos[i]);
227                                 print_v3("\tauto lnor:", r_lnors_spacearr->lspacearr[i]->vec_lnor);
228                                 print_v3("\tref_vec:", r_lnors_spacearr->lspacearr[i]->vec_ref);
229                                 printf("\talpha: %f\n\tbeta: %f\n\tloops: %p\n", r_lnors_spacearr->lspacearr[i]->ref_alpha,
230                                        r_lnors_spacearr->lspacearr[i]->ref_beta, r_lnors_spacearr->lspacearr[i]->loops);
231                                 printf("\t\t(shared with loops");
232                                 while (loops) {
233                                         printf(" %d", GET_INT_FROM_POINTER(loops->link));
234                                         loops = loops->next;
235                                 }
236                                 printf(")\n");
237                         }
238                         else {
239                                 printf("Loop %d has no lnor space\n", i);
240                         }
241                 }
242         }
243 #endif
244 }
245
246 static void emDM_calc_loop_tangents(
247         DerivedMesh *dm, bool calc_active_tangent,
248         const char (*tangent_names)[MAX_NAME], int tangent_names_len)
249 {
250         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
251         BMEditMesh *em = bmdm->em;
252
253         if (CustomData_number_of_layers(&em->bm->ldata, CD_MLOOPUV) == 0) {
254                 return;
255         }
256
257         const float (*poly_normals)[3] = bmdm->polyNos;
258         const float (*loop_normals)[3] = CustomData_get_layer(&dm->loopData, CD_NORMAL);
259         const float (*vert_orco)[3] = dm->getVertDataArray(dm, CD_ORCO);  /* can be NULL */
260         BKE_editmesh_loop_tangent_calc(
261                 em, calc_active_tangent,
262                 tangent_names, tangent_names_len,
263                 poly_normals, loop_normals,
264                 vert_orco,
265                 &dm->loopData, dm->numLoopData,
266                 &dm->tangent_mask);
267 }
268
269
270 static void emDM_recalcTessellation(DerivedMesh *UNUSED(dm))
271 {
272         /* do nothing */
273 }
274
275 static void emDM_recalcLoopTri(DerivedMesh *dm)
276 {
277         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
278         BMLoop *(*looptris)[3] = bmdm->em->looptris;
279         MLoopTri *mlooptri;
280         const int tottri = bmdm->em->tottri;
281         int i;
282
283         DM_ensure_looptri_data(dm);
284         mlooptri = dm->looptris.array_wip;
285
286         BLI_assert(tottri == 0 || mlooptri != NULL);
287         BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num);
288         BLI_assert(tottri == dm->looptris.num);
289
290         BM_mesh_elem_index_ensure(bmdm->em->bm, BM_FACE | BM_LOOP);
291
292         for (i = 0; i < tottri; i++) {
293                 BMLoop **ltri = looptris[i];
294                 MLoopTri *lt = &mlooptri[i];
295
296                 ARRAY_SET_ITEMS(
297                         lt->tri,
298                         BM_elem_index_get(ltri[0]),
299                         BM_elem_index_get(ltri[1]),
300                         BM_elem_index_get(ltri[2]));
301                 lt->poly = BM_elem_index_get(ltri[0]->f);
302         }
303
304         BLI_assert(dm->looptris.array == NULL);
305         atomic_cas_ptr((void **)&dm->looptris.array, dm->looptris.array, dm->looptris.array_wip);
306         dm->looptris.array_wip = NULL;
307 }
308
309 static void emDM_foreachMappedVert(
310         DerivedMesh *dm,
311         void (*func)(void *userData, int index, const float co[3], const float no_f[3], const short no_s[3]),
312         void *userData,
313         DMForeachFlag flag)
314 {
315         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
316         BMesh *bm = bmdm->em->bm;
317         BMVert *eve;
318         BMIter iter;
319         int i;
320
321         if (bmdm->vertexCos) {
322                 const float (*vertexCos)[3] = bmdm->vertexCos;
323                 const float (*vertexNos)[3];
324
325                 if (flag & DM_FOREACH_USE_NORMAL) {
326                         emDM_ensureVertNormals(bmdm);
327                         vertexNos = bmdm->vertexNos;
328                 }
329                 else {
330                         vertexNos = NULL;
331                 }
332
333                 BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
334                         const float *no = (flag & DM_FOREACH_USE_NORMAL) ? vertexNos[i] : NULL;
335                         func(userData, i, vertexCos[i], no, NULL);
336                 }
337         }
338         else {
339                 BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
340                         const float *no = (flag & DM_FOREACH_USE_NORMAL) ? eve->no : NULL;
341                         func(userData, i, eve->co, no, NULL);
342                 }
343         }
344 }
345 static void emDM_foreachMappedEdge(
346         DerivedMesh *dm,
347         void (*func)(void *userData, int index, const float v0co[3], const float v1co[3]),
348         void *userData)
349 {
350         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
351         BMesh *bm = bmdm->em->bm;
352         BMEdge *eed;
353         BMIter iter;
354         int i;
355
356         if (bmdm->vertexCos) {
357
358                 BM_mesh_elem_index_ensure(bm, BM_VERT);
359
360                 BM_ITER_MESH_INDEX (eed, &iter, bm, BM_EDGES_OF_MESH, i) {
361                         func(userData, i,
362                              bmdm->vertexCos[BM_elem_index_get(eed->v1)],
363                              bmdm->vertexCos[BM_elem_index_get(eed->v2)]);
364                 }
365         }
366         else {
367                 BM_ITER_MESH_INDEX (eed, &iter, bm, BM_EDGES_OF_MESH, i) {
368                         func(userData, i, eed->v1->co, eed->v2->co);
369                 }
370         }
371 }
372
373 static void emDM_drawMappedEdges(
374         DerivedMesh *dm,
375         DMSetDrawOptions setDrawOptions,
376         void *userData)
377 {
378         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
379         BMesh *bm = bmdm->em->bm;
380         BMEdge *eed;
381         BMIter iter;
382         int i;
383
384         if (bmdm->vertexCos) {
385
386                 BM_mesh_elem_index_ensure(bm, BM_VERT);
387
388                 glBegin(GL_LINES);
389                 BM_ITER_MESH_INDEX (eed, &iter, bm, BM_EDGES_OF_MESH, i) {
390                         if (!setDrawOptions || (setDrawOptions(userData, i) != DM_DRAW_OPTION_SKIP)) {
391                                 glVertex3fv(bmdm->vertexCos[BM_elem_index_get(eed->v1)]);
392                                 glVertex3fv(bmdm->vertexCos[BM_elem_index_get(eed->v2)]);
393                         }
394                 }
395                 glEnd();
396         }
397         else {
398                 glBegin(GL_LINES);
399                 BM_ITER_MESH_INDEX (eed, &iter, bm, BM_EDGES_OF_MESH, i) {
400                         if (!setDrawOptions || (setDrawOptions(userData, i) != DM_DRAW_OPTION_SKIP)) {
401                                 glVertex3fv(eed->v1->co);
402                                 glVertex3fv(eed->v2->co);
403                         }
404                 }
405                 glEnd();
406         }
407 }
408 static void emDM_drawEdges(
409         DerivedMesh *dm,
410         bool UNUSED(drawLooseEdges),
411         bool UNUSED(drawAllEdges))
412 {
413         emDM_drawMappedEdges(dm, NULL, NULL);
414 }
415
416 static void emDM_drawMappedEdgesInterp(
417         DerivedMesh *dm,
418         DMSetDrawOptions setDrawOptions,
419         DMSetDrawInterpOptions setDrawInterpOptions,
420         void *userData)
421 {
422         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
423         BMesh *bm = bmdm->em->bm;
424         BMEdge *eed;
425         BMIter iter;
426         int i;
427
428         if (bmdm->vertexCos) {
429
430                 BM_mesh_elem_index_ensure(bm, BM_VERT);
431
432                 glBegin(GL_LINES);
433                 BM_ITER_MESH_INDEX (eed, &iter, bm, BM_EDGES_OF_MESH, i) {
434                         if (!setDrawOptions || (setDrawOptions(userData, i) != DM_DRAW_OPTION_SKIP)) {
435                                 setDrawInterpOptions(userData, i, 0.0);
436                                 glVertex3fv(bmdm->vertexCos[BM_elem_index_get(eed->v1)]);
437                                 setDrawInterpOptions(userData, i, 1.0);
438                                 glVertex3fv(bmdm->vertexCos[BM_elem_index_get(eed->v2)]);
439                         }
440                 }
441                 glEnd();
442         }
443         else {
444                 glBegin(GL_LINES);
445                 BM_ITER_MESH_INDEX (eed, &iter, bm, BM_EDGES_OF_MESH, i) {
446                         if (!setDrawOptions || (setDrawOptions(userData, i) != DM_DRAW_OPTION_SKIP)) {
447                                 setDrawInterpOptions(userData, i, 0.0);
448                                 glVertex3fv(eed->v1->co);
449                                 setDrawInterpOptions(userData, i, 1.0);
450                                 glVertex3fv(eed->v2->co);
451                         }
452                 }
453                 glEnd();
454         }
455 }
456
457 static void emDM_foreachMappedLoop(
458         DerivedMesh *dm,
459         void (*func)(void *userData, int vertex_index, int face_index, const float co[3], const float no[3]),
460         void *userData,
461         DMForeachFlag flag)
462 {
463         /* We can't use dm->getLoopDataLayout(dm) here, we want to always access dm->loopData, EditDerivedBMesh would
464          * return loop data from bmesh itself. */
465         const float (*lnors)[3] = (flag & DM_FOREACH_USE_NORMAL) ? DM_get_loop_data_layer(dm, CD_NORMAL) : NULL;
466
467         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
468         BMesh *bm = bmdm->em->bm;
469         BMFace *efa;
470         BMIter iter;
471
472         const float (*vertexCos)[3] = bmdm->vertexCos;
473         int f_idx;
474
475         BM_mesh_elem_index_ensure(bm, BM_VERT);
476
477         BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, f_idx) {
478                 BMLoop *l_iter, *l_first;
479
480                 l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
481                 do {
482                         const BMVert *eve = l_iter->v;
483                         const int v_idx = BM_elem_index_get(eve);
484                         const float *no = lnors ? *lnors++ : NULL;
485                         func(userData, v_idx, f_idx, vertexCos ? vertexCos[v_idx] : eve->co, no);
486                 } while ((l_iter = l_iter->next) != l_first);
487         }
488 }
489
490 static void emDM_foreachMappedFaceCenter(
491         DerivedMesh *dm,
492         void (*func)(void *userData, int index, const float co[3], const float no[3]),
493         void *userData,
494         DMForeachFlag flag)
495 {
496         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
497         BMesh *bm = bmdm->em->bm;
498         const float (*polyNos)[3];
499         const float (*polyCos)[3];
500         BMFace *efa;
501         BMIter iter;
502         int i;
503
504         emDM_ensurePolyCenters(bmdm);
505         polyCos = bmdm->polyCos;  /* always set */
506
507         if (flag & DM_FOREACH_USE_NORMAL) {
508                 emDM_ensurePolyNormals(bmdm);
509                 polyNos = bmdm->polyNos;  /* maybe NULL */
510         }
511         else {
512                 polyNos = NULL;
513         }
514
515         if (polyNos) {
516                 BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) {
517                         const float *no = polyNos[i];
518                         func(userData, i, polyCos[i], no);
519                 }
520         }
521         else {
522                 BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) {
523                         const float *no = (flag & DM_FOREACH_USE_NORMAL) ? efa->no : NULL;
524                         func(userData, i, polyCos[i], no);
525                 }
526         }
527 }
528
529 static void emDM_drawMappedFaces(
530         DerivedMesh *dm,
531         DMSetDrawOptions setDrawOptions,
532         DMSetMaterial setMaterial,
533         /* currently unused -- each original face is handled separately */
534         DMCompareDrawOptions UNUSED(compareDrawOptions),
535         void *userData,
536         DMDrawFlag flag)
537 {
538         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
539         BMEditMesh *em = bmdm->em;
540         BMesh *bm = em->bm;
541         BMFace *efa;
542         struct BMLoop *(*looptris)[3] = bmdm->em->looptris;
543         const int tottri = bmdm->em->tottri;
544         DMDrawOption draw_option;
545         int i;
546         const int skip_normals = !(flag & DM_DRAW_NEED_NORMALS);
547         const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL);
548         MLoopCol *lcol[3] = {NULL} /* , dummylcol = {0} */;
549         unsigned char(*color_vert_array)[4] = em->derivedVertColor;
550         unsigned char(*color_face_array)[4] = em->derivedFaceColor;
551         bool has_vcol_preview = (color_vert_array != NULL) && !skip_normals;
552         bool has_fcol_preview = (color_face_array != NULL) && !skip_normals;
553         bool has_vcol_any = has_vcol_preview;
554
555         /* GL_ZERO is used to detect if drawing has started or not */
556         GLenum poly_prev = GL_ZERO;
557         GLenum shade_prev = GL_ZERO;
558         DMDrawOption draw_option_prev = DM_DRAW_OPTION_SKIP;
559
560         /* call again below is ok */
561         if (has_vcol_preview) {
562                 BM_mesh_elem_index_ensure(bm, BM_VERT);
563         }
564         if (has_fcol_preview) {
565                 BM_mesh_elem_index_ensure(bm, BM_FACE);
566         }
567         if (has_vcol_preview || has_fcol_preview) {
568                 flag |= DM_DRAW_ALWAYS_SMOOTH;
569                 /* weak, this logic should really be moved higher up */
570                 setMaterial = NULL;
571         }
572
573         if (bmdm->vertexCos) {
574                 short prev_mat_nr = -1;
575
576                 /* add direct access */
577                 const float (*vertexCos)[3] = bmdm->vertexCos;
578                 const float (*vertexNos)[3];
579                 const float (*polyNos)[3];
580
581                 if (skip_normals) {
582                         vertexNos = NULL;
583                         polyNos = NULL;
584                 }
585                 else {
586                         emDM_ensureVertNormals(bmdm);
587                         emDM_ensurePolyNormals(bmdm);
588                         vertexNos = bmdm->vertexNos;
589                         polyNos = bmdm->polyNos;
590                 }
591
592                 BM_mesh_elem_index_ensure(bm, lnors ? BM_VERT | BM_FACE | BM_LOOP : BM_VERT | BM_FACE);
593
594                 for (i = 0; i < tottri; i++) {
595                         BMLoop **ltri = looptris[i];
596                         int drawSmooth;
597
598                         efa = ltri[0]->f;
599                         drawSmooth = lnors || ((flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : BM_elem_flag_test(efa, BM_ELEM_SMOOTH));
600
601                         draw_option = (!setDrawOptions ?
602                                        DM_DRAW_OPTION_NORMAL :
603                                        setDrawOptions(userData, BM_elem_index_get(efa)));
604                         if (draw_option != DM_DRAW_OPTION_SKIP) {
605                                 const GLenum poly_type = GL_TRIANGLES; /* BMESH NOTE, this is odd but keep it for now to match trunk */
606
607                                 if (draw_option_prev != draw_option) {
608                                         if (draw_option_prev == DM_DRAW_OPTION_STIPPLE) {
609                                                 if (poly_prev != GL_ZERO) glEnd();
610                                                 poly_prev = GL_ZERO; /* force glBegin */
611
612                                                 GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
613                                         }
614                                         draw_option_prev = draw_option;
615                                 }
616
617
618                                 if (efa->mat_nr != prev_mat_nr) {
619                                         if (setMaterial) {
620                                                 if (poly_prev != GL_ZERO) glEnd();
621                                                 poly_prev = GL_ZERO; /* force glBegin */
622
623                                                 setMaterial(efa->mat_nr + 1, NULL);
624                                         }
625                                         prev_mat_nr = efa->mat_nr;
626                                 }
627
628                                 if (draw_option == DM_DRAW_OPTION_STIPPLE) { /* enabled with stipple */
629
630                                         if (poly_prev != GL_ZERO) glEnd();
631                                         poly_prev = GL_ZERO; /* force glBegin */
632
633                                         GPU_basic_shader_bind(GPU_SHADER_STIPPLE | GPU_SHADER_USE_COLOR);
634                                         GPU_basic_shader_stipple(GPU_SHADER_STIPPLE_QUARTTONE);
635                                 }
636
637                                 if      (has_vcol_preview) bmdm_get_tri_colpreview(ltri, lcol, color_vert_array);
638                                 else if (has_fcol_preview) glColor3ubv((const GLubyte *)&(color_face_array[BM_elem_index_get(efa)]));
639                                 if (skip_normals) {
640                                         if (poly_type != poly_prev) {
641                                                 if (poly_prev != GL_ZERO) glEnd();
642                                                 glBegin((poly_prev = poly_type)); /* BMesh: will always be GL_TRIANGLES */
643                                         }
644                                         if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[0]->r));
645                                         glVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]);
646                                         if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[1]->r));
647                                         glVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]);
648                                         if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[2]->r));
649                                         glVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]);
650                                 }
651                                 else {
652                                         const GLenum shade_type = drawSmooth ? GL_SMOOTH : GL_FLAT;
653                                         if (shade_type != shade_prev) {
654                                                 if (poly_prev != GL_ZERO) glEnd();
655                                                 glShadeModel((shade_prev = shade_type)); /* same as below but switch shading */
656                                                 glBegin((poly_prev = poly_type)); /* BMesh: will always be GL_TRIANGLES */
657                                         }
658                                         if (poly_type != poly_prev) {
659                                                 if (poly_prev != GL_ZERO) glEnd();
660                                                 glBegin((poly_prev = poly_type)); /* BMesh: will always be GL_TRIANGLES */
661                                         }
662
663                                         if (!drawSmooth) {
664                                                 glNormal3fv(polyNos[BM_elem_index_get(efa)]);
665                                                 if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[0]->r));
666                                                 glVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]);
667                                                 if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[1]->r));
668                                                 glVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]);
669                                                 if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[2]->r));
670                                                 glVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]);
671                                         }
672                                         else {
673                                                 if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[0]->r));
674                                                 if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[0])]);
675                                                 else glNormal3fv(vertexNos[BM_elem_index_get(ltri[0]->v)]);
676                                                 glVertex3fv(vertexCos[BM_elem_index_get(ltri[0]->v)]);
677                                                 if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[1]->r));
678                                                 if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[1])]);
679                                                 else glNormal3fv(vertexNos[BM_elem_index_get(ltri[1]->v)]);
680                                                 glVertex3fv(vertexCos[BM_elem_index_get(ltri[1]->v)]);
681                                                 if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[2]->r));
682                                                 if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[2])]);
683                                                 else glNormal3fv(vertexNos[BM_elem_index_get(ltri[2]->v)]);
684                                                 glVertex3fv(vertexCos[BM_elem_index_get(ltri[2]->v)]);
685                                         }
686                                 }
687                         }
688                 }
689         }
690         else {
691                 short prev_mat_nr = -1;
692
693                 BM_mesh_elem_index_ensure(bm, lnors ? BM_FACE | BM_LOOP : BM_FACE);
694
695                 for (i = 0; i < tottri; i++) {
696                         BMLoop **ltri = looptris[i];
697                         int drawSmooth;
698
699                         efa = ltri[0]->f;
700                         drawSmooth = lnors || ((flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : BM_elem_flag_test(efa, BM_ELEM_SMOOTH));
701                         
702                         draw_option = (setDrawOptions ?
703                                            setDrawOptions(userData, BM_elem_index_get(efa)) :
704                                            DM_DRAW_OPTION_NORMAL);
705
706                         if (draw_option != DM_DRAW_OPTION_SKIP) {
707                                 const GLenum poly_type = GL_TRIANGLES; /* BMESH NOTE, this is odd but keep it for now to match trunk */
708
709                                 if (draw_option_prev != draw_option) {
710                                         if (draw_option_prev == DM_DRAW_OPTION_STIPPLE) {
711                                                 if (poly_prev != GL_ZERO) glEnd();
712                                                 poly_prev = GL_ZERO; /* force glBegin */
713
714                                                 GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
715                                         }
716                                         draw_option_prev = draw_option;
717                                 }
718
719                                 if (efa->mat_nr != prev_mat_nr) {
720                                         if (setMaterial) {
721                                                 if (poly_prev != GL_ZERO) glEnd();
722                                                 poly_prev = GL_ZERO; /* force glBegin */
723
724                                                 setMaterial(efa->mat_nr + 1, NULL);
725                                         }
726                                         prev_mat_nr = efa->mat_nr;
727                                 }
728                                 
729                                 if (draw_option == DM_DRAW_OPTION_STIPPLE) { /* enabled with stipple */
730
731                                         if (poly_prev != GL_ZERO) glEnd();
732                                         poly_prev = GL_ZERO; /* force glBegin */
733
734                                         GPU_basic_shader_bind(GPU_SHADER_STIPPLE | GPU_SHADER_USE_COLOR);
735                                         GPU_basic_shader_stipple(GPU_SHADER_STIPPLE_QUARTTONE);
736                                 }
737
738                                 if      (has_vcol_preview) bmdm_get_tri_colpreview(ltri, lcol, color_vert_array);
739                                 else if (has_fcol_preview) glColor3ubv((const GLubyte *)&(color_face_array[BM_elem_index_get(efa)]));
740
741                                 if (skip_normals) {
742                                         if (poly_type != poly_prev) {
743                                                 if (poly_prev != GL_ZERO) glEnd();
744                                                 glBegin((poly_prev = poly_type)); /* BMesh: will always be GL_TRIANGLES */
745                                         }
746                                         if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[0]->r));
747                                         glVertex3fv(ltri[0]->v->co);
748                                         if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[1]->r));
749                                         glVertex3fv(ltri[1]->v->co);
750                                         if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[2]->r));
751                                         glVertex3fv(ltri[2]->v->co);
752                                 }
753                                 else {
754                                         const GLenum shade_type = drawSmooth ? GL_SMOOTH : GL_FLAT;
755                                         if (shade_type != shade_prev) {
756                                                 if (poly_prev != GL_ZERO) glEnd();
757                                                 glShadeModel((shade_prev = shade_type)); /* same as below but switch shading */
758                                                 glBegin((poly_prev = poly_type)); /* BMesh: will always be GL_TRIANGLES */
759                                         }
760                                         if (poly_type != poly_prev) {
761                                                 if (poly_prev != GL_ZERO) glEnd();
762                                                 glBegin((poly_prev = poly_type)); /* BMesh: will always be GL_TRIANGLES */
763                                         }
764
765                                         if (!drawSmooth) {
766                                                 glNormal3fv(efa->no);
767                                                 if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[0]->r));
768                                                 glVertex3fv(ltri[0]->v->co);
769                                                 if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[1]->r));
770                                                 glVertex3fv(ltri[1]->v->co);
771                                                 if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[2]->r));
772                                                 glVertex3fv(ltri[2]->v->co);
773                                         }
774                                         else {
775                                                 if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[0]->r));
776                                                 if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[0])]);
777                                                 else glNormal3fv(ltri[0]->v->no);
778                                                 glVertex3fv(ltri[0]->v->co);
779                                                 if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[1]->r));
780                                                 if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[1])]);
781                                                 else glNormal3fv(ltri[1]->v->no);
782                                                 glVertex3fv(ltri[1]->v->co);
783                                                 if (has_vcol_any) glColor3ubv((const GLubyte *)&(lcol[2]->r));
784                                                 if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[2])]);
785                                                 else glNormal3fv(ltri[2]->v->no);
786                                                 glVertex3fv(ltri[2]->v->co);
787                                         }
788                                 }
789                         }
790                 }
791         }
792
793         /* if non zero we know a face was rendered */
794         if (poly_prev != GL_ZERO) glEnd();
795
796         if (draw_option_prev == DM_DRAW_OPTION_STIPPLE) {
797                 GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
798         }
799
800         if (shade_prev == GL_FLAT) {
801                 glShadeModel(GL_SMOOTH);
802         }
803 }
804
805 static void bmdm_get_tri_colpreview(BMLoop *ls[3], MLoopCol *lcol[3], unsigned char(*color_vert_array)[4])
806 {
807         lcol[0] = (MLoopCol *)color_vert_array[BM_elem_index_get(ls[0]->v)];
808         lcol[1] = (MLoopCol *)color_vert_array[BM_elem_index_get(ls[1]->v)];
809         lcol[2] = (MLoopCol *)color_vert_array[BM_elem_index_get(ls[2]->v)];
810 }
811
812 /**
813  * \note
814  *
815  * For UV's:
816  *   const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(loop, attribs->tface[i].em_offset);
817  *
818  * This is intentionally different to calling:
819  *   CustomData_bmesh_get_n(&bm->ldata, loop->head.data, CD_MLOOPUV, i);
820  *
821  * ... because the material may use layer names to select different UV's
822  * see: [#34378]
823  */
824 static void emdm_pass_attrib_vertex_glsl(const DMVertexAttribs *attribs, const BMLoop *loop)
825 {
826         BMVert *eve = loop->v;
827         int i;
828         const float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};
829
830         if (attribs->totorco) {
831                 int index = BM_elem_index_get(eve);
832                 const float *orco = (attribs->orco.array) ? attribs->orco.array[index] : zero;
833
834                 if (attribs->orco.gl_texco)
835                         glTexCoord3fv(orco);
836                 else
837                         glVertexAttrib3fv(attribs->orco.gl_index, orco);
838         }
839         for (i = 0; i < attribs->tottface; i++) {
840                 const float *uv;
841
842                 if (attribs->tface[i].em_offset != -1) {
843                         const MLoopUV *luv = BM_ELEM_CD_GET_VOID_P(loop, attribs->tface[i].em_offset);
844                         uv = luv->uv;
845                 }
846                 else {
847                         uv = zero;
848                 }
849
850                 if (attribs->tface[i].gl_texco)
851                         glTexCoord2fv(uv);
852                 else
853                         glVertexAttrib2fv(attribs->tface[i].gl_index, uv);
854         }
855         for (i = 0; i < attribs->totmcol; i++) {
856                 float col[4];
857                 if (attribs->mcol[i].em_offset != -1) {
858                         const MLoopCol *cp = BM_ELEM_CD_GET_VOID_P(loop, attribs->mcol[i].em_offset);
859                         rgba_uchar_to_float(col, &cp->r);
860                 }
861                 else {
862                         col[0] = 0.0f; col[1] = 0.0f; col[2] = 0.0f; col[3] = 0.0f;
863                 }
864                 glVertexAttrib4fv(attribs->mcol[i].gl_index, col);
865         }
866
867         for (i = 0; i < attribs->tottang; i++) {
868                 const float *tang;
869                 if (attribs->tang[i].em_offset != -1) {
870                         tang = attribs->tang[i].array[BM_elem_index_get(loop)];
871                 }
872                 else {
873                         tang = zero;
874                 }
875                 glVertexAttrib4fv(attribs->tang[i].gl_index, tang);
876         }
877 }
878
879 static void emDM_drawMappedFacesGLSL(
880         DerivedMesh *dm,
881         DMSetMaterial setMaterial,
882         DMSetDrawOptions setDrawOptions,
883         void *userData)
884 {
885         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
886         BMEditMesh *em = bmdm->em;
887         BMesh *bm = em->bm;
888         struct BMLoop *(*looptris)[3] = em->looptris;
889         /* add direct access */
890         const float (*vertexCos)[3] = bmdm->vertexCos;
891         const float (*vertexNos)[3];
892         const float (*polyNos)[3];
893         const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL);
894
895         BMFace *efa;
896         DMVertexAttribs attribs;
897         GPUVertexAttribs gattribs;
898
899         int i, matnr, new_matnr, fi;
900         bool do_draw;
901
902         do_draw = false;
903         matnr = -1;
904
905         memset(&attribs, 0, sizeof(attribs));
906
907         emDM_ensureVertNormals(bmdm);
908         emDM_ensurePolyNormals(bmdm);
909         vertexNos = bmdm->vertexNos;
910         polyNos = bmdm->polyNos;
911
912         BM_mesh_elem_index_ensure(bm, (BM_VERT | BM_FACE) | (lnors ? BM_LOOP : 0));
913
914         for (i = 0; i < em->tottri; i++) {
915                 BMLoop **ltri = looptris[i];
916                 int drawSmooth;
917
918                 efa = ltri[0]->f;
919
920                 if (setDrawOptions && (setDrawOptions(userData, BM_elem_index_get(efa)) == DM_DRAW_OPTION_SKIP))
921                         continue;
922
923                 /* material */
924                 new_matnr = efa->mat_nr + 1;
925                 if (new_matnr != matnr) {
926                         if (matnr != -1)
927                                 glEnd();
928
929                         do_draw = setMaterial(matnr = new_matnr, &gattribs);
930                         if (do_draw) {
931                                 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
932                                 DM_draw_attrib_vertex_uniforms(&attribs);
933                                 if (UNLIKELY(attribs.tottang && bm->elem_index_dirty & BM_LOOP)) {
934                                         BM_mesh_elem_index_ensure(bm, BM_LOOP);
935                                 }
936                         }
937
938                         glBegin(GL_TRIANGLES);
939                 }
940
941                 if (do_draw) {
942
943                         /* draw face */
944                         drawSmooth = lnors || BM_elem_flag_test(efa, BM_ELEM_SMOOTH);
945
946                         if (!drawSmooth) {
947                                 if (vertexCos) {
948                                         glNormal3fv(polyNos[BM_elem_index_get(efa)]);
949                                         for (fi = 0; fi < 3; fi++) {
950                                                 emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi]);
951                                                 glVertex3fv(vertexCos[BM_elem_index_get(ltri[fi]->v)]);
952                                         }
953                                 }
954                                 else {
955                                         glNormal3fv(efa->no);
956                                         for (fi = 0; fi < 3; fi++) {
957                                                 emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi]);
958                                                 glVertex3fv(ltri[fi]->v->co);
959                                         }
960                                 }
961                         }
962                         else {
963                                 if (vertexCos) {
964                                         for (fi = 0; fi < 3; fi++) {
965                                                 const int j = BM_elem_index_get(ltri[fi]->v);
966                                                 emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi]);
967                                                 if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[fi])]);
968                                                 else glNormal3fv(vertexNos[j]);
969                                                 glVertex3fv(vertexCos[j]);
970                                         }
971                                 }
972                                 else {
973                                         for (fi = 0; fi < 3; fi++) {
974                                                 emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi]);
975                                                 if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[fi])]);
976                                                 else glNormal3fv(ltri[fi]->v->no);
977                                                 glVertex3fv(ltri[fi]->v->co);
978                                         }
979                                 }
980                         }
981                 }
982         }
983
984         if (matnr != -1) {
985                 glEnd();
986         }
987 }
988
989 static void emDM_drawFacesGLSL(
990         DerivedMesh *dm,
991         int (*setMaterial)(int matnr, void *attribs))
992 {
993         dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
994 }
995
996 static void emDM_drawMappedFacesMat(
997         DerivedMesh *dm,
998         void (*setMaterial)(void *userData, int matnr, void *attribs),
999         bool (*setFace)(void *userData, int index), void *userData)
1000 {
1001         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1002         BMEditMesh *em = bmdm->em;
1003         BMesh *bm = em->bm;
1004         struct BMLoop *(*looptris)[3] = em->looptris;
1005         const float (*vertexCos)[3] = bmdm->vertexCos;
1006         const float (*vertexNos)[3];
1007         const float (*polyNos)[3];
1008         const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL);
1009         BMFace *efa;
1010         DMVertexAttribs attribs = {{{NULL}}};
1011         GPUVertexAttribs gattribs;
1012         int i, matnr, new_matnr, fi;
1013
1014         matnr = -1;
1015
1016         emDM_ensureVertNormals(bmdm);
1017         emDM_ensurePolyNormals(bmdm);
1018
1019         vertexNos = bmdm->vertexNos;
1020         polyNos = bmdm->polyNos;
1021
1022         BM_mesh_elem_index_ensure(bm, (BM_VERT | BM_FACE) | (lnors ? BM_LOOP : 0));
1023
1024         for (i = 0; i < em->tottri; i++) {
1025                 BMLoop **ltri = looptris[i];
1026                 int drawSmooth;
1027
1028                 efa = ltri[0]->f;
1029
1030                 /* face hiding */
1031                 if (setFace && !setFace(userData, BM_elem_index_get(efa)))
1032                         continue;
1033
1034                 /* material */
1035                 new_matnr = efa->mat_nr + 1;
1036                 if (new_matnr != matnr) {
1037                         if (matnr != -1)
1038                                 glEnd();
1039
1040                         setMaterial(userData, matnr = new_matnr, &gattribs);
1041                         DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1042                         if (UNLIKELY(attribs.tottang && bm->elem_index_dirty & BM_LOOP)) {
1043                                 BM_mesh_elem_index_ensure(bm, BM_LOOP);
1044                         }
1045
1046                         glBegin(GL_TRIANGLES);
1047                 }
1048
1049                 /* draw face */
1050                 drawSmooth = lnors || BM_elem_flag_test(efa, BM_ELEM_SMOOTH);
1051
1052                 if (!drawSmooth) {
1053                         if (vertexCos) {
1054                                 glNormal3fv(polyNos[BM_elem_index_get(efa)]);
1055                                 for (fi = 0; fi < 3; fi++) {
1056                                         emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi]);
1057                                         glVertex3fv(vertexCos[BM_elem_index_get(ltri[fi]->v)]);
1058                                 }
1059                         }
1060                         else {
1061                                 glNormal3fv(efa->no);
1062                                 for (fi = 0; fi < 3; fi++) {
1063                                         emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi]);
1064                                         glVertex3fv(ltri[fi]->v->co);
1065                                 }
1066                         }
1067                 }
1068                 else {
1069                         if (vertexCos) {
1070                                 for (fi = 0; fi < 3; fi++) {
1071                                         const int j = BM_elem_index_get(ltri[fi]->v);
1072                                         emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi]);
1073                                         if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[fi])]);
1074                                         else glNormal3fv(vertexNos[j]);
1075                                         glVertex3fv(vertexCos[j]);
1076                                 }
1077                         }
1078                         else {
1079                                 for (fi = 0; fi < 3; fi++) {
1080                                         emdm_pass_attrib_vertex_glsl(&attribs, ltri[fi]);
1081                                         if (lnors) glNormal3fv(lnors[BM_elem_index_get(ltri[fi])]);
1082                                         else glNormal3fv(ltri[fi]->v->no);
1083                                         glVertex3fv(ltri[fi]->v->co);
1084                                 }
1085                         }
1086                 }
1087         }
1088
1089         if (matnr != -1) {
1090                 glEnd();
1091         }
1092 }
1093
1094 static void emDM_getMinMax(DerivedMesh *dm, float r_min[3], float r_max[3])
1095 {
1096         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1097         BMesh *bm = bmdm->em->bm;
1098         BMVert *eve;
1099         BMIter iter;
1100         int i;
1101
1102         if (bm->totvert) {
1103                 if (bmdm->vertexCos) {
1104                         BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
1105                                 minmax_v3v3_v3(r_min, r_max, bmdm->vertexCos[i]);
1106                         }
1107                 }
1108                 else {
1109                         BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
1110                                 minmax_v3v3_v3(r_min, r_max, eve->co);
1111                         }
1112                 }
1113         }
1114         else {
1115                 zero_v3(r_min);
1116                 zero_v3(r_max);
1117         }
1118 }
1119 static int emDM_getNumVerts(DerivedMesh *dm)
1120 {
1121         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1122
1123         return bmdm->em->bm->totvert;
1124 }
1125
1126 static int emDM_getNumEdges(DerivedMesh *dm)
1127 {
1128         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1129
1130         return bmdm->em->bm->totedge;
1131 }
1132
1133 static int emDM_getNumTessFaces(DerivedMesh *dm)
1134 {
1135         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1136
1137         return bmdm->em->tottri;
1138 }
1139
1140 static int emDM_getNumLoops(DerivedMesh *dm)
1141 {
1142         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1143
1144         return bmdm->em->bm->totloop;
1145 }
1146
1147 static int emDM_getNumPolys(DerivedMesh *dm)
1148 {
1149         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1150
1151         return bmdm->em->bm->totface;
1152 }
1153
1154 static void bmvert_to_mvert(BMesh *bm, BMVert *ev, MVert *r_vert)
1155 {
1156         const float *f;
1157
1158         copy_v3_v3(r_vert->co, ev->co);
1159
1160         normal_float_to_short_v3(r_vert->no, ev->no);
1161
1162         r_vert->flag = BM_vert_flag_to_mflag(ev);
1163
1164         if ((f = CustomData_bmesh_get(&bm->vdata, ev->head.data, CD_BWEIGHT))) {
1165                 r_vert->bweight = (unsigned char)((*f) * 255.0f);
1166         }
1167 }
1168
1169 static void emDM_getVert(DerivedMesh *dm, int index, MVert *r_vert)
1170 {
1171         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1172         BMesh *bm = bmdm->em->bm;
1173         BMVert *ev;
1174
1175         if (UNLIKELY(index < 0 || index >= bm->totvert)) {
1176                 BLI_assert(!"error in emDM_getVert");
1177                 return;
1178         }
1179
1180         BLI_assert((bm->elem_table_dirty & BM_VERT) == 0);
1181         ev = bm->vtable[index];  /* should be BM_vert_at_index() */
1182         // ev = BM_vert_at_index(bm, index); /* warning, does list loop, _not_ ideal */
1183
1184         bmvert_to_mvert(bm, ev, r_vert);
1185         if (bmdm->vertexCos)
1186                 copy_v3_v3(r_vert->co, bmdm->vertexCos[index]);
1187 }
1188
1189 static void emDM_getVertCo(DerivedMesh *dm, int index, float r_co[3])
1190 {
1191         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1192         BMesh *bm = bmdm->em->bm;
1193
1194         if (UNLIKELY(index < 0 || index >= bm->totvert)) {
1195                 BLI_assert(!"error in emDM_getVertCo");
1196                 return;
1197         }
1198
1199         if (bmdm->vertexCos) {
1200                 copy_v3_v3(r_co, bmdm->vertexCos[index]);
1201         }
1202         else {
1203                 BMVert *ev;
1204
1205                 BLI_assert((bm->elem_table_dirty & BM_VERT) == 0);
1206                 ev = bm->vtable[index];  /* should be BM_vert_at_index() */
1207                 // ev = BM_vert_at_index(bm, index); /* warning, does list loop, _not_ ideal */
1208                 copy_v3_v3(r_co, ev->co);
1209         }
1210 }
1211
1212 static void emDM_getVertNo(DerivedMesh *dm, int index, float r_no[3])
1213 {
1214         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1215         BMesh *bm = bmdm->em->bm;
1216
1217         if (UNLIKELY(index < 0 || index >= bm->totvert)) {
1218                 BLI_assert(!"error in emDM_getVertNo");
1219                 return;
1220         }
1221
1222
1223         if (bmdm->vertexCos) {
1224                 emDM_ensureVertNormals(bmdm);
1225                 copy_v3_v3(r_no, bmdm->vertexNos[index]);
1226         }
1227         else {
1228                 BMVert *ev;
1229
1230                 BLI_assert((bm->elem_table_dirty & BM_VERT) == 0);
1231                 ev = bm->vtable[index];  /* should be BM_vert_at_index() */
1232                 // ev = BM_vert_at_index(bm, index); /* warning, does list loop, _not_ ideal */
1233                 copy_v3_v3(r_no, ev->no);
1234         }
1235 }
1236
1237 static void emDM_getPolyNo(DerivedMesh *dm, int index, float r_no[3])
1238 {
1239         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1240         BMesh *bm = bmdm->em->bm;
1241
1242         if (UNLIKELY(index < 0 || index >= bm->totface)) {
1243                 BLI_assert(!"error in emDM_getPolyNo");
1244                 return;
1245         }
1246
1247         if (bmdm->vertexCos) {
1248                 emDM_ensurePolyNormals(bmdm);
1249                 copy_v3_v3(r_no, bmdm->polyNos[index]);
1250         }
1251         else {
1252                 BMFace *efa;
1253
1254                 BLI_assert((bm->elem_table_dirty & BM_FACE) == 0);
1255                 efa = bm->ftable[index];  /* should be BM_vert_at_index() */
1256                 // efa = BM_face_at_index(bm, index); /* warning, does list loop, _not_ ideal */
1257                 copy_v3_v3(r_no, efa->no);
1258         }
1259 }
1260
1261 static void emDM_getEdge(DerivedMesh *dm, int index, MEdge *r_edge)
1262 {
1263         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1264         BMesh *bm = bmdm->em->bm;
1265         BMEdge *e;
1266         const float *f;
1267
1268         if (UNLIKELY(index < 0 || index >= bm->totedge)) {
1269                 BLI_assert(!"error in emDM_getEdge");
1270                 return;
1271         }
1272
1273         BLI_assert((bm->elem_table_dirty & BM_EDGE) == 0);
1274         e = bm->etable[index];  /* should be BM_edge_at_index() */
1275         // e = BM_edge_at_index(bm, index); /* warning, does list loop, _not_ ideal */
1276
1277         r_edge->flag = BM_edge_flag_to_mflag(e);
1278
1279         r_edge->v1 = BM_elem_index_get(e->v1);
1280         r_edge->v2 = BM_elem_index_get(e->v2);
1281
1282         if ((f = CustomData_bmesh_get(&bm->edata, e->head.data, CD_BWEIGHT))) {
1283                 r_edge->bweight = (unsigned char)((*f) * 255.0f);
1284         }
1285         if ((f = CustomData_bmesh_get(&bm->edata, e->head.data, CD_CREASE))) {
1286                 r_edge->crease = (unsigned char)((*f) * 255.0f);
1287         }
1288 }
1289
1290 static void emDM_getTessFace(DerivedMesh *dm, int index, MFace *r_face)
1291 {
1292         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1293         BMFace *ef;
1294         BMLoop **ltri;
1295
1296         if (UNLIKELY(index < 0 || index >= bmdm->em->tottri)) {
1297                 BLI_assert(!"error in emDM_getTessFace");
1298                 return;
1299         }
1300
1301         ltri = bmdm->em->looptris[index];
1302
1303         ef = ltri[0]->f;
1304
1305         r_face->mat_nr = (unsigned char) ef->mat_nr;
1306         r_face->flag = BM_face_flag_to_mflag(ef);
1307
1308         r_face->v1 = BM_elem_index_get(ltri[0]->v);
1309         r_face->v2 = BM_elem_index_get(ltri[1]->v);
1310         r_face->v3 = BM_elem_index_get(ltri[2]->v);
1311         r_face->v4 = 0;
1312
1313         test_index_face(r_face, NULL, 0, 3);
1314 }
1315
1316 static void emDM_copyVertArray(DerivedMesh *dm, MVert *r_vert)
1317 {
1318         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1319         BMesh *bm = bmdm->em->bm;
1320         BMVert *eve;
1321         BMIter iter;
1322         const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
1323
1324         if (bmdm->vertexCos) {
1325                 int i;
1326
1327                 BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
1328                         copy_v3_v3(r_vert->co, bmdm->vertexCos[i]);
1329                         normal_float_to_short_v3(r_vert->no, eve->no);
1330                         r_vert->flag = BM_vert_flag_to_mflag(eve);
1331
1332                         r_vert->bweight = (cd_vert_bweight_offset != -1) ? BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eve, cd_vert_bweight_offset) : 0;
1333
1334                         r_vert++;
1335                 }
1336         }
1337         else {
1338                 BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
1339                         copy_v3_v3(r_vert->co, eve->co);
1340                         normal_float_to_short_v3(r_vert->no, eve->no);
1341                         r_vert->flag = BM_vert_flag_to_mflag(eve);
1342
1343                         r_vert->bweight = (cd_vert_bweight_offset != -1) ? BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eve, cd_vert_bweight_offset) : 0;
1344
1345                         r_vert++;
1346                 }
1347         }
1348 }
1349
1350 static void emDM_copyEdgeArray(DerivedMesh *dm, MEdge *r_edge)
1351 {
1352         BMesh *bm = ((EditDerivedBMesh *)dm)->em->bm;
1353         BMEdge *eed;
1354         BMIter iter;
1355
1356         const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
1357         const int cd_edge_crease_offset  = CustomData_get_offset(&bm->edata, CD_CREASE);
1358
1359         BM_mesh_elem_index_ensure(bm, BM_VERT);
1360
1361         BM_ITER_MESH (eed, &iter, bm, BM_EDGES_OF_MESH) {
1362                 r_edge->v1 = BM_elem_index_get(eed->v1);
1363                 r_edge->v2 = BM_elem_index_get(eed->v2);
1364
1365                 r_edge->flag = BM_edge_flag_to_mflag(eed);
1366
1367                 r_edge->crease  = (cd_edge_crease_offset  != -1) ? BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_crease_offset)  : 0;
1368                 r_edge->bweight = (cd_edge_bweight_offset != -1) ? BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_bweight_offset) : 0;
1369
1370                 r_edge++;
1371         }
1372 }
1373
1374 static void emDM_copyTessFaceArray(DerivedMesh *dm, MFace *r_face)
1375 {
1376         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1377         BMesh *bm = bmdm->em->bm;
1378         struct BMLoop *(*looptris)[3] = bmdm->em->looptris;
1379         BMFace *ef;
1380         int i;
1381
1382         BM_mesh_elem_index_ensure(bm, BM_VERT);
1383
1384         for (i = 0; i < bmdm->em->tottri; i++, r_face++) {
1385                 BMLoop **ltri = looptris[i];
1386                 ef = ltri[0]->f;
1387
1388                 r_face->mat_nr = (unsigned char) ef->mat_nr;
1389
1390                 r_face->flag = BM_face_flag_to_mflag(ef);
1391                 r_face->edcode = 0;
1392
1393                 r_face->v1 = BM_elem_index_get(ltri[0]->v);
1394                 r_face->v2 = BM_elem_index_get(ltri[1]->v);
1395                 r_face->v3 = BM_elem_index_get(ltri[2]->v);
1396                 r_face->v4 = 0;
1397
1398                 test_index_face(r_face, NULL, 0, 3);
1399         }
1400 }
1401
1402 static void emDM_copyLoopArray(DerivedMesh *dm, MLoop *r_loop)
1403 {
1404         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1405         BMesh *bm = bmdm->em->bm;
1406         BMIter iter;
1407         BMFace *efa;
1408
1409         BM_mesh_elem_index_ensure(bm, BM_VERT | BM_EDGE);
1410
1411         BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
1412                 BMLoop *l_iter, *l_first;
1413                 l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
1414                 do {
1415                         r_loop->v = BM_elem_index_get(l_iter->v);
1416                         r_loop->e = BM_elem_index_get(l_iter->e);
1417                         r_loop++;
1418                 } while ((l_iter = l_iter->next) != l_first);
1419         }
1420 }
1421
1422 static void emDM_copyPolyArray(DerivedMesh *dm, MPoly *r_poly)
1423 {
1424         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1425         BMesh *bm = bmdm->em->bm;
1426         BMIter iter;
1427         BMFace *efa;
1428         int i;
1429
1430         i = 0;
1431         BM_ITER_MESH (efa, &iter, bm, BM_FACES_OF_MESH) {
1432                 r_poly->flag = BM_face_flag_to_mflag(efa);
1433                 r_poly->loopstart = i;
1434                 r_poly->totloop = efa->len;
1435                 r_poly->mat_nr = efa->mat_nr;
1436
1437                 r_poly++;
1438                 i += efa->len;
1439         }
1440 }
1441
1442 static void *emDM_getTessFaceDataArray(DerivedMesh *dm, int type)
1443 {
1444         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1445         BMesh *bm = bmdm->em->bm;
1446         void *datalayer;
1447
1448         datalayer = DM_get_tessface_data_layer(dm, type);
1449         if (datalayer)
1450                 return datalayer;
1451
1452         /* layers are store per face for editmesh, we convert to a temporary
1453          * data layer array in the derivedmesh when these are requested */
1454         if (type == CD_MTFACE || type == CD_MCOL) {
1455                 const char *bmdata;
1456                 char *data;
1457
1458                 bool has_type_source = CustomData_has_layer(&bm->ldata, (type == CD_MTFACE) ? CD_MLOOPUV : CD_MLOOPCOL);
1459
1460                 if (has_type_source) {
1461                         /* offset = bm->pdata.layers[index].offset; */ /* UNUSED */
1462                         BMLoop *(*looptris)[3] = bmdm->em->looptris;
1463                         const int size = CustomData_sizeof(type);
1464                         int i, j;
1465
1466                         DM_add_tessface_layer(dm, type, CD_CALLOC, NULL);
1467                         const int index = CustomData_get_layer_index(&dm->faceData, type);
1468                         dm->faceData.layers[index].flag |= CD_FLAG_TEMPORARY;
1469
1470                         data = datalayer = DM_get_tessface_data_layer(dm, type);
1471
1472                         if (type == CD_MTFACE) {
1473                                 const int cd_loop_uv_offset  = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
1474
1475                                 for (i = 0; i < bmdm->em->tottri; i++, data += size) {
1476                                         for (j = 0; j < 3; j++) {
1477                                                 // bmdata = CustomData_bmesh_get(&bm->ldata, looptris[i][j]->head.data, CD_MLOOPUV);
1478                                                 bmdata = BM_ELEM_CD_GET_VOID_P(looptris[i][j], cd_loop_uv_offset);
1479                                                 copy_v2_v2(((MTFace *)data)->uv[j], ((const MLoopUV *)bmdata)->uv);
1480                                         }
1481                                 }
1482                         }
1483                         else {
1484                                 const int cd_loop_color_offset  = CustomData_get_offset(&bm->ldata, CD_MLOOPCOL);
1485                                 for (i = 0; i < bmdm->em->tottri; i++, data += size) {
1486                                         for (j = 0; j < 3; j++) {
1487                                                 // bmdata = CustomData_bmesh_get(&bm->ldata, looptris[i][j]->head.data, CD_MLOOPCOL);
1488                                                 bmdata = BM_ELEM_CD_GET_VOID_P(looptris[i][j], cd_loop_color_offset);
1489                                                 MESH_MLOOPCOL_TO_MCOL(((const MLoopCol *)bmdata), (((MCol *)data) + j));
1490                                         }
1491                                 }
1492                         }
1493                 }
1494         }
1495
1496         /* Special handling for CD_TESSLOOPNORMAL, we generate it on demand as well. */
1497         if (type == CD_TESSLOOPNORMAL) {
1498                 const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL);
1499
1500                 if (lnors) {
1501                         BMLoop *(*looptris)[3] = bmdm->em->looptris;
1502                         short (*tlnors)[4][3], (*tlnor)[4][3];
1503                         int index, i, j;
1504
1505                         DM_add_tessface_layer(dm, type, CD_CALLOC, NULL);
1506                         index = CustomData_get_layer_index(&dm->faceData, type);
1507                         dm->faceData.layers[index].flag |= CD_FLAG_TEMPORARY;
1508
1509                         tlnor = tlnors = DM_get_tessface_data_layer(dm, type);
1510
1511                         BM_mesh_elem_index_ensure(bm, BM_LOOP);
1512
1513                         for (i = 0; i < bmdm->em->tottri; i++, tlnor++, looptris++) {
1514                                 for (j = 0; j < 3; j++) {
1515                                         normal_float_to_short_v3((*tlnor)[j], lnors[BM_elem_index_get((*looptris)[j])]);
1516                                 }
1517                         }
1518                 }
1519         }
1520
1521         return datalayer;
1522 }
1523
1524 static void emDM_getVertCos(DerivedMesh *dm, float (*r_cos)[3])
1525 {
1526         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1527         BMesh *bm = bmdm->em->bm;
1528         BMVert *eve;
1529         BMIter iter;
1530         int i;
1531
1532         if (bmdm->vertexCos) {
1533                 BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
1534                         copy_v3_v3(r_cos[i], bmdm->vertexCos[i]);
1535                 }
1536         }
1537         else {
1538                 BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
1539                         copy_v3_v3(r_cos[i], eve->co);
1540                 }
1541         }
1542 }
1543
1544 static void emDM_release(DerivedMesh *dm)
1545 {
1546         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1547
1548         if (DM_release(dm)) {
1549                 if (bmdm->vertexCos) {
1550                         MEM_freeN((void *)bmdm->vertexCos);
1551                         if (bmdm->vertexNos) {
1552                                 MEM_freeN((void *)bmdm->vertexNos);
1553                         }
1554                         if (bmdm->polyNos) {
1555                                 MEM_freeN((void *)bmdm->polyNos);
1556                         }
1557                 }
1558
1559                 if (bmdm->polyCos) {
1560                         MEM_freeN((void *)bmdm->polyCos);
1561                 }
1562
1563                 MEM_freeN(bmdm);
1564         }
1565 }
1566
1567 static CustomData *bmDm_getVertDataLayout(DerivedMesh *dm)
1568 {
1569         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1570
1571         return &bmdm->em->bm->vdata;
1572 }
1573
1574 static CustomData *bmDm_getEdgeDataLayout(DerivedMesh *dm)
1575 {
1576         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1577
1578         return &bmdm->em->bm->edata;
1579 }
1580
1581 static CustomData *bmDm_getTessFaceDataLayout(DerivedMesh *dm)
1582 {
1583         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1584
1585         return &bmdm->dm.faceData;
1586 }
1587
1588 static CustomData *bmDm_getLoopDataLayout(DerivedMesh *dm)
1589 {
1590         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1591
1592         return &bmdm->em->bm->ldata;
1593 }
1594
1595 static CustomData *bmDm_getPolyDataLayout(DerivedMesh *dm)
1596 {
1597         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1598
1599         return &bmdm->em->bm->pdata;
1600 }
1601
1602 /**
1603  * \note This may be called per-draw,
1604  * avoid allocating large arrays where possible and keep this a thin wrapper for #BMesh.
1605  */
1606 DerivedMesh *getEditDerivedBMesh(
1607         BMEditMesh *em, struct Object *UNUSED(ob),
1608         CustomDataMask data_mask,
1609         float (*vertexCos)[3])
1610 {
1611         EditDerivedBMesh *bmdm = MEM_callocN(sizeof(*bmdm), __func__);
1612         BMesh *bm = em->bm;
1613
1614         bmdm->em = em;
1615
1616         DM_init((DerivedMesh *)bmdm, DM_TYPE_EDITBMESH, bm->totvert,
1617                 bm->totedge, em->tottri, bm->totloop, bm->totface);
1618
1619         /* could also get from the objects mesh directly */
1620         bmdm->dm.cd_flag = BM_mesh_cd_flag_from_bmesh(bm);
1621
1622         bmdm->dm.getVertCos = emDM_getVertCos;
1623         bmdm->dm.getMinMax = emDM_getMinMax;
1624
1625         bmdm->dm.getVertDataLayout = bmDm_getVertDataLayout;
1626         bmdm->dm.getEdgeDataLayout = bmDm_getEdgeDataLayout;
1627         bmdm->dm.getTessFaceDataLayout = bmDm_getTessFaceDataLayout;
1628         bmdm->dm.getLoopDataLayout = bmDm_getLoopDataLayout;
1629         bmdm->dm.getPolyDataLayout = bmDm_getPolyDataLayout;
1630
1631         bmdm->dm.getNumVerts = emDM_getNumVerts;
1632         bmdm->dm.getNumEdges = emDM_getNumEdges;
1633         bmdm->dm.getNumTessFaces = emDM_getNumTessFaces;
1634         bmdm->dm.getNumLoops = emDM_getNumLoops;
1635         bmdm->dm.getNumPolys = emDM_getNumPolys;
1636
1637         bmdm->dm.getVert = emDM_getVert;
1638         bmdm->dm.getVertCo = emDM_getVertCo;
1639         bmdm->dm.getVertNo = emDM_getVertNo;
1640         bmdm->dm.getPolyNo = emDM_getPolyNo;
1641         bmdm->dm.getEdge = emDM_getEdge;
1642         bmdm->dm.getTessFace = emDM_getTessFace;
1643         bmdm->dm.copyVertArray = emDM_copyVertArray;
1644         bmdm->dm.copyEdgeArray = emDM_copyEdgeArray;
1645         bmdm->dm.copyTessFaceArray = emDM_copyTessFaceArray;
1646         bmdm->dm.copyLoopArray = emDM_copyLoopArray;
1647         bmdm->dm.copyPolyArray = emDM_copyPolyArray;
1648
1649         bmdm->dm.getTessFaceDataArray = emDM_getTessFaceDataArray;
1650
1651         bmdm->dm.calcNormals = emDM_calcNormals;
1652         bmdm->dm.calcLoopNormals = emDM_calcLoopNormals;
1653         bmdm->dm.calcLoopNormalsSpaceArray = emDM_calcLoopNormalsSpaceArray;
1654         bmdm->dm.calcLoopTangents = emDM_calc_loop_tangents;
1655         bmdm->dm.recalcTessellation = emDM_recalcTessellation;
1656         bmdm->dm.recalcLoopTri = emDM_recalcLoopTri;
1657
1658         bmdm->dm.foreachMappedVert = emDM_foreachMappedVert;
1659         bmdm->dm.foreachMappedLoop = emDM_foreachMappedLoop;
1660         bmdm->dm.foreachMappedEdge = emDM_foreachMappedEdge;
1661         bmdm->dm.foreachMappedFaceCenter = emDM_foreachMappedFaceCenter;
1662
1663         bmdm->dm.drawEdges = emDM_drawEdges;
1664         bmdm->dm.drawMappedEdges = emDM_drawMappedEdges;
1665         bmdm->dm.drawMappedEdgesInterp = emDM_drawMappedEdgesInterp;
1666         bmdm->dm.drawMappedFaces = emDM_drawMappedFaces;
1667         bmdm->dm.drawMappedFacesGLSL = emDM_drawMappedFacesGLSL;
1668         bmdm->dm.drawMappedFacesMat = emDM_drawMappedFacesMat;
1669         bmdm->dm.drawFacesGLSL = emDM_drawFacesGLSL;
1670
1671         bmdm->dm.release = emDM_release;
1672
1673         bmdm->vertexCos = (const float (*)[3])vertexCos;
1674         bmdm->dm.deformedOnly = (vertexCos != NULL);
1675
1676         const int cd_dvert_offset = (data_mask & CD_MASK_MDEFORMVERT) ?
1677                 CustomData_get_offset(&bm->vdata, CD_MDEFORMVERT) : -1;
1678
1679         if (cd_dvert_offset != -1) {
1680                 BMIter iter;
1681                 BMVert *eve;
1682                 int i;
1683
1684                 DM_add_vert_layer(&bmdm->dm, CD_MDEFORMVERT, CD_CALLOC, NULL);
1685
1686                 BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
1687                         DM_set_vert_data(&bmdm->dm, i, CD_MDEFORMVERT,
1688                                          BM_ELEM_CD_GET_VOID_P(eve, cd_dvert_offset));
1689                 }
1690         }
1691
1692         const int cd_skin_offset = (data_mask & CD_MASK_MVERT_SKIN) ?
1693                 CustomData_get_offset(&bm->vdata, CD_MVERT_SKIN) : -1;
1694
1695         if (cd_skin_offset != -1) {
1696                 BMIter iter;
1697                 BMVert *eve;
1698                 int i;
1699
1700                 DM_add_vert_layer(&bmdm->dm, CD_MVERT_SKIN, CD_CALLOC, NULL);
1701
1702                 BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
1703                         DM_set_vert_data(&bmdm->dm, i, CD_MVERT_SKIN,
1704                                          BM_ELEM_CD_GET_VOID_P(eve, cd_skin_offset));
1705                 }
1706         }
1707
1708         return (DerivedMesh *)bmdm;
1709 }
1710
1711
1712
1713 /* -------------------------------------------------------------------- */
1714 /* StatVis Functions */
1715
1716 static void axis_from_enum_v3(float v[3], const char axis)
1717 {
1718         zero_v3(v);
1719         if (axis < 3) v[axis]     =  1.0f;
1720         else          v[axis - 3] = -1.0f;
1721 }
1722
1723 static void statvis_calc_overhang(
1724         BMEditMesh *em,
1725         const float (*polyNos)[3],
1726         /* values for calculating */
1727         const float min, const float max, const char axis,
1728         /* result */
1729         unsigned char (*r_face_colors)[4])
1730 {
1731         BMIter iter;
1732         BMesh *bm = em->bm;
1733         BMFace *f;
1734         float dir[3];
1735         int index;
1736         const float minmax_irange = 1.0f / (max - min);
1737         bool is_max;
1738
1739         /* fallback */
1740         unsigned char col_fallback[4] = {64, 64, 64, 255}; /* gray */
1741         unsigned char col_fallback_max[4] = {0,  0,  0,  255}; /* max color */
1742
1743         BLI_assert(min <= max);
1744
1745         axis_from_enum_v3(dir, axis);
1746
1747         if (LIKELY(em->ob)) {
1748                 mul_transposed_mat3_m4_v3(em->ob->obmat, dir);
1749                 normalize_v3(dir);
1750         }
1751
1752         /* fallback max */
1753         {
1754                 float fcol[3];
1755                 weight_to_rgb(fcol, 1.0f);
1756                 rgb_float_to_uchar(col_fallback_max, fcol);
1757         }
1758
1759         /* now convert into global space */
1760         BM_ITER_MESH_INDEX (f, &iter, bm, BM_FACES_OF_MESH, index) {
1761                 float fac = angle_normalized_v3v3(polyNos ? polyNos[index] : f->no, dir) / (float)M_PI;
1762
1763                 /* remap */
1764                 if ((is_max = (fac <= max)) && (fac >= min)) {
1765                         float fcol[3];
1766                         fac = (fac - min) * minmax_irange;
1767                         fac = 1.0f - fac;
1768                         CLAMP(fac, 0.0f, 1.0f);
1769                         weight_to_rgb(fcol, fac);
1770                         rgb_float_to_uchar(r_face_colors[index], fcol);
1771                 }
1772                 else {
1773                         const unsigned char *fallback = is_max ? col_fallback_max : col_fallback;
1774                         copy_v4_v4_uchar(r_face_colors[index], fallback);
1775                 }
1776         }
1777 }
1778
1779 /* so we can use jitter values for face interpolation */
1780 static void uv_from_jitter_v2(float uv[2])
1781 {
1782         uv[0] += 0.5f;
1783         uv[1] += 0.5f;
1784         if (uv[0] + uv[1] > 1.0f) {
1785                 uv[0] = 1.0f - uv[0];
1786                 uv[1] = 1.0f - uv[1];
1787         }
1788
1789         CLAMP(uv[0], 0.0f, 1.0f);
1790         CLAMP(uv[1], 0.0f, 1.0f);
1791 }
1792
1793 static void statvis_calc_thickness(
1794         BMEditMesh *em,
1795         const float (*vertexCos)[3],
1796         /* values for calculating */
1797         const float min, const float max, const int samples,
1798         /* result */
1799         unsigned char (*r_face_colors)[4])
1800 {
1801         const float eps_offset = 0.00002f;  /* values <= 0.00001 give errors */
1802         float *face_dists = (float *)r_face_colors;  /* cheating */
1803         const bool use_jit = samples < 32;
1804         float jit_ofs[32][2];
1805         BMesh *bm = em->bm;
1806         const int tottri = em->tottri;
1807         const float minmax_irange = 1.0f / (max - min);
1808         int i;
1809
1810         struct BMLoop *(*looptris)[3] = em->looptris;
1811
1812         /* fallback */
1813         const unsigned char col_fallback[4] = {64, 64, 64, 255};
1814
1815         struct BMBVHTree *bmtree;
1816
1817         BLI_assert(min <= max);
1818
1819         copy_vn_fl(face_dists, em->bm->totface, max);
1820
1821         if (use_jit) {
1822                 int j;
1823                 BLI_assert(samples < 32);
1824                 BLI_jitter_init(jit_ofs, samples);
1825
1826                 for (j = 0; j < samples; j++) {
1827                         uv_from_jitter_v2(jit_ofs[j]);
1828                 }
1829         }
1830
1831         BM_mesh_elem_index_ensure(bm, BM_FACE);
1832         if (vertexCos) {
1833                 BM_mesh_elem_index_ensure(bm, BM_VERT);
1834         }
1835
1836         bmtree = BKE_bmbvh_new_from_editmesh(em, 0, vertexCos, false);
1837
1838         for (i = 0; i < tottri; i++) {
1839                 BMFace *f_hit;
1840                 BMLoop **ltri = looptris[i];
1841                 const int index = BM_elem_index_get(ltri[0]->f);
1842                 const float *cos[3];
1843                 float ray_co[3];
1844                 float ray_no[3];
1845
1846                 if (vertexCos) {
1847                         cos[0] = vertexCos[BM_elem_index_get(ltri[0]->v)];
1848                         cos[1] = vertexCos[BM_elem_index_get(ltri[1]->v)];
1849                         cos[2] = vertexCos[BM_elem_index_get(ltri[2]->v)];
1850                 }
1851                 else {
1852                         cos[0] = ltri[0]->v->co;
1853                         cos[1] = ltri[1]->v->co;
1854                         cos[2] = ltri[2]->v->co;
1855                 }
1856
1857                 normal_tri_v3(ray_no, cos[2], cos[1], cos[0]);
1858
1859 #define FACE_RAY_TEST_ANGLE \
1860                 f_hit = BKE_bmbvh_ray_cast(bmtree, ray_co, ray_no, 0.0f, \
1861                                            &dist, NULL, NULL); \
1862                 if (f_hit && dist < face_dists[index]) { \
1863                         float angle_fac = fabsf(dot_v3v3(ltri[0]->f->no, f_hit->no)); \
1864                         angle_fac = 1.0f - angle_fac; \
1865                         angle_fac = angle_fac * angle_fac * angle_fac; \
1866                         angle_fac = 1.0f - angle_fac; \
1867                         dist /= angle_fac; \
1868                         if (dist < face_dists[index]) { \
1869                                 face_dists[index] = dist; \
1870                         } \
1871                 } (void)0
1872
1873                 if (use_jit) {
1874                         int j;
1875                         for (j = 0; j < samples; j++) {
1876                                 float dist = face_dists[index];
1877                                 interp_v3_v3v3v3_uv(ray_co, cos[0], cos[1], cos[2], jit_ofs[j]);
1878                                 madd_v3_v3fl(ray_co, ray_no, eps_offset);
1879
1880                                 FACE_RAY_TEST_ANGLE;
1881                         }
1882                 }
1883                 else {
1884                         float dist = face_dists[index];
1885                         mid_v3_v3v3v3(ray_co, cos[0], cos[1], cos[2]);
1886                         madd_v3_v3fl(ray_co, ray_no, eps_offset);
1887
1888                         FACE_RAY_TEST_ANGLE;
1889                 }
1890         }
1891
1892         BKE_bmbvh_free(bmtree);
1893
1894         /* convert floats into color! */
1895         for (i = 0; i < bm->totface; i++) {
1896                 float fac = face_dists[i];
1897
1898                 /* important not '<=' */
1899                 if (fac < max) {
1900                         float fcol[3];
1901                         fac = (fac - min) * minmax_irange;
1902                         fac = 1.0f - fac;
1903                         CLAMP(fac, 0.0f, 1.0f);
1904                         weight_to_rgb(fcol, fac);
1905                         rgb_float_to_uchar(r_face_colors[i], fcol);
1906                 }
1907                 else {
1908                         copy_v4_v4_uchar(r_face_colors[i], col_fallback);
1909                 }
1910         }
1911 }
1912
1913 static void statvis_calc_intersect(
1914         BMEditMesh *em,
1915         const float (*vertexCos)[3],
1916         /* result */
1917         unsigned char (*r_face_colors)[4])
1918 {
1919         BMesh *bm = em->bm;
1920         int i;
1921
1922         /* fallback */
1923         // const char col_fallback[4] = {64, 64, 64, 255};
1924         float fcol[3];
1925         unsigned char col[3];
1926
1927         struct BMBVHTree *bmtree;
1928         BVHTreeOverlap *overlap;
1929         unsigned int overlap_len;
1930
1931         memset(r_face_colors, 64, sizeof(int) * em->bm->totface);
1932
1933         BM_mesh_elem_index_ensure(bm, BM_FACE);
1934         if (vertexCos) {
1935                 BM_mesh_elem_index_ensure(bm, BM_VERT);
1936         }
1937
1938         bmtree = BKE_bmbvh_new_from_editmesh(em, 0, vertexCos, false);
1939
1940         overlap = BKE_bmbvh_overlap(bmtree, bmtree, &overlap_len);
1941
1942         /* same for all faces */
1943         weight_to_rgb(fcol, 1.0f);
1944         rgb_float_to_uchar(col, fcol);
1945
1946         if (overlap) {
1947                 for (i = 0; i < overlap_len; i++) {
1948                         BMFace *f_hit_pair[2] = {
1949                             em->looptris[overlap[i].indexA][0]->f,
1950                             em->looptris[overlap[i].indexB][0]->f,
1951                         };
1952                         int j;
1953
1954                         for (j = 0; j < 2; j++) {
1955                                 BMFace *f_hit = f_hit_pair[j];
1956                                 int index;
1957
1958                                 index = BM_elem_index_get(f_hit);
1959
1960                                 copy_v3_v3_uchar(r_face_colors[index], col);
1961                         }
1962                 }
1963                 MEM_freeN(overlap);
1964         }
1965
1966         BKE_bmbvh_free(bmtree);
1967 }
1968
1969 static void statvis_calc_distort(
1970         BMEditMesh *em,
1971         const float (*vertexCos)[3], const float (*polyNos)[3],
1972         /* values for calculating */
1973         const float min, const float max,
1974         /* result */
1975         unsigned char (*r_face_colors)[4])
1976 {
1977         BMIter iter;
1978         BMesh *bm = em->bm;
1979         BMFace *f;
1980         const float *f_no;
1981         int index;
1982         const float minmax_irange = 1.0f / (max - min);
1983
1984         /* fallback */
1985         const unsigned char col_fallback[4] = {64, 64, 64, 255};
1986
1987         /* now convert into global space */
1988         BM_ITER_MESH_INDEX (f, &iter, bm, BM_FACES_OF_MESH, index) {
1989                 float fac;
1990
1991                 if (f->len == 3) {
1992                         fac = -1.0f;
1993                 }
1994                 else {
1995                         BMLoop *l_iter, *l_first;
1996                         if (vertexCos) {
1997                                 f_no = polyNos[index];
1998                         }
1999                         else {
2000                                 f_no = f->no;
2001                         }
2002
2003                         fac = 0.0f;
2004                         l_iter = l_first = BM_FACE_FIRST_LOOP(f);
2005                         do {
2006                                 float no_corner[3];
2007                                 if (vertexCos) {
2008                                         normal_tri_v3(no_corner,
2009                                                       vertexCos[BM_elem_index_get(l_iter->prev->v)],
2010                                                       vertexCos[BM_elem_index_get(l_iter->v)],
2011                                                       vertexCos[BM_elem_index_get(l_iter->next->v)]);
2012                                 }
2013                                 else {
2014                                         BM_loop_calc_face_normal_safe(l_iter, no_corner);
2015                                 }
2016                                 /* simple way to detect (what is most likely) concave */
2017                                 if (dot_v3v3(f_no, no_corner) < 0.0f) {
2018                                         negate_v3(no_corner);
2019                                 }
2020                                 fac = max_ff(fac, angle_normalized_v3v3(f_no, no_corner));
2021                         } while ((l_iter = l_iter->next) != l_first);
2022                         fac *= 2.0f;
2023                 }
2024
2025                 /* remap */
2026                 if (fac >= min) {
2027                         float fcol[3];
2028                         fac = (fac - min) * minmax_irange;
2029                         CLAMP(fac, 0.0f, 1.0f);
2030                         weight_to_rgb(fcol, fac);
2031                         rgb_float_to_uchar(r_face_colors[index], fcol);
2032                 }
2033                 else {
2034                         copy_v4_v4_uchar(r_face_colors[index], col_fallback);
2035                 }
2036         }
2037 }
2038
2039 static void statvis_calc_sharp(
2040         BMEditMesh *em,
2041         const float (*vertexCos)[3],
2042         /* values for calculating */
2043         const float min, const float max,
2044         /* result */
2045         unsigned char (*r_vert_colors)[4])
2046 {
2047         float *vert_angles = (float *)r_vert_colors;  /* cheating */
2048         BMIter iter;
2049         BMesh *bm = em->bm;
2050         BMEdge *e;
2051         //float f_no[3];
2052         const float minmax_irange = 1.0f / (max - min);
2053         int i;
2054
2055         /* fallback */
2056         const unsigned char col_fallback[4] = {64, 64, 64, 255};
2057
2058         (void)vertexCos;  /* TODO */
2059
2060         copy_vn_fl(vert_angles, em->bm->totvert, -M_PI);
2061
2062         /* first assign float values to verts */
2063         BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
2064                 float angle = BM_edge_calc_face_angle_signed(e);
2065                 float *col1 = &vert_angles[BM_elem_index_get(e->v1)];
2066                 float *col2 = &vert_angles[BM_elem_index_get(e->v2)];
2067                 *col1 = max_ff(*col1, angle);
2068                 *col2 = max_ff(*col2, angle);
2069         }
2070
2071         /* convert floats into color! */
2072         for (i = 0; i < bm->totvert; i++) {
2073                 float fac = vert_angles[i];
2074
2075                 /* important not '<=' */
2076                 if (fac > min) {
2077                         float fcol[3];
2078                         fac = (fac - min) * minmax_irange;
2079                         CLAMP(fac, 0.0f, 1.0f);
2080                         weight_to_rgb(fcol, fac);
2081                         rgb_float_to_uchar(r_vert_colors[i], fcol);
2082                 }
2083                 else {
2084                         copy_v4_v4_uchar(r_vert_colors[i], col_fallback);
2085                 }
2086         }
2087 }
2088
2089 void BKE_editmesh_statvis_calc(
2090         BMEditMesh *em, DerivedMesh *dm,
2091         const MeshStatVis *statvis)
2092 {
2093         EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
2094         BLI_assert(dm == NULL || dm->type == DM_TYPE_EDITBMESH);
2095
2096         switch (statvis->type) {
2097                 case SCE_STATVIS_OVERHANG:
2098                 {
2099                         BKE_editmesh_color_ensure(em, BM_FACE);
2100                         statvis_calc_overhang(
2101                                     em, bmdm ? bmdm->polyNos : NULL,
2102                                     statvis->overhang_min / (float)M_PI,
2103                                     statvis->overhang_max / (float)M_PI,
2104                                     statvis->overhang_axis,
2105                                     em->derivedFaceColor);
2106                         break;
2107                 }
2108                 case SCE_STATVIS_THICKNESS:
2109                 {
2110                         const float scale = 1.0f / mat4_to_scale(em->ob->obmat);
2111                         BKE_editmesh_color_ensure(em, BM_FACE);
2112                         statvis_calc_thickness(
2113                                     em, bmdm ? bmdm->vertexCos : NULL,
2114                                     statvis->thickness_min * scale,
2115                                     statvis->thickness_max * scale,
2116                                     statvis->thickness_samples,
2117                                     em->derivedFaceColor);
2118                         break;
2119                 }
2120                 case SCE_STATVIS_INTERSECT:
2121                 {
2122                         BKE_editmesh_color_ensure(em, BM_FACE);
2123                         statvis_calc_intersect(
2124                                     em, bmdm ? bmdm->vertexCos : NULL,
2125                                     em->derivedFaceColor);
2126                         break;
2127                 }
2128                 case SCE_STATVIS_DISTORT:
2129                 {
2130                         BKE_editmesh_color_ensure(em, BM_FACE);
2131
2132                         if (bmdm)
2133                                 emDM_ensurePolyNormals(bmdm);
2134
2135                         statvis_calc_distort(
2136                                 em, bmdm ? bmdm->vertexCos : NULL, bmdm ? bmdm->polyNos : NULL,
2137                                 statvis->distort_min,
2138                                 statvis->distort_max,
2139                                 em->derivedFaceColor);
2140                         break;
2141                 }
2142                 case SCE_STATVIS_SHARP:
2143                 {
2144                         BKE_editmesh_color_ensure(em, BM_VERT);
2145                         statvis_calc_sharp(
2146                                 em, bmdm ? bmdm->vertexCos : NULL,
2147                                 statvis->sharp_min,
2148                                 statvis->sharp_max,
2149                                 /* in this case they are vertex colors */
2150                                 em->derivedVertColor);
2151                         break;
2152                 }
2153         }
2154 }
2155
2156
2157
2158 /* -------------------------------------------------------------------- */
2159 /* Editmesh Vert Coords */
2160
2161 struct CageUserData {
2162         int totvert;
2163         float (*cos_cage)[3];
2164         BLI_bitmap *visit_bitmap;
2165 };
2166
2167 static void cage_mapped_verts_callback(
2168         void *userData, int index, const float co[3],
2169         const float UNUSED(no_f[3]), const short UNUSED(no_s[3]))
2170 {
2171         struct CageUserData *data = userData;
2172
2173         if ((index >= 0 && index < data->totvert) && (!BLI_BITMAP_TEST(data->visit_bitmap, index))) {
2174                 BLI_BITMAP_ENABLE(data->visit_bitmap, index);
2175                 copy_v3_v3(data->cos_cage[index], co);
2176         }
2177 }
2178
2179 float (*BKE_editmesh_vertexCos_get(struct Depsgraph *depsgraph, BMEditMesh *em, Scene *scene, int *r_numVerts))[3]
2180 {
2181         DerivedMesh *cage, *final;
2182         BLI_bitmap *visit_bitmap;
2183         struct CageUserData data;
2184         float (*cos_cage)[3];
2185
2186         cage = editbmesh_get_derived_cage_and_final(depsgraph, scene, em->ob, em, CD_MASK_BAREMESH, &final);
2187         cos_cage = MEM_callocN(sizeof(*cos_cage) * em->bm->totvert, "bmbvh cos_cage");
2188
2189         /* when initializing cage verts, we only want the first cage coordinate for each vertex,
2190          * so that e.g. mirror or array use original vertex coordinates and not mirrored or duplicate */
2191         visit_bitmap = BLI_BITMAP_NEW(em->bm->totvert, __func__);
2192
2193         data.totvert = em->bm->totvert;
2194         data.cos_cage = cos_cage;
2195         data.visit_bitmap = visit_bitmap;
2196
2197         cage->foreachMappedVert(cage, cage_mapped_verts_callback, &data, DM_FOREACH_NOP);
2198
2199         MEM_freeN(visit_bitmap);
2200
2201         if (r_numVerts) {
2202                 *r_numVerts = em->bm->totvert;
2203         }
2204
2205         return cos_cage;
2206 }