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