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