Fix glUniform called from glBegin/glEnd blocks
[blender.git] / source / blender / blenkernel / intern / cdderivedmesh.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) 2006 Blender Foundation.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): Ben Batt <benbatt@gmail.com>
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  *
27  * Implementation of CDDerivedMesh.
28  *
29  * BKE_cdderivedmesh.h contains the function prototypes for this file.
30  *
31  */
32
33 /** \file blender/blenkernel/intern/cdderivedmesh.c
34  *  \ingroup bke
35  */
36
37 #include "BLI_math.h"
38 #include "BLI_edgehash.h"
39 #include "BLI_utildefines.h"
40 #include "BLI_stackdefines.h"
41
42 #include "BKE_pbvh.h"
43 #include "BKE_cdderivedmesh.h"
44 #include "BKE_global.h"
45 #include "BKE_mesh.h"
46 #include "BKE_mesh_mapping.h"
47 #include "BKE_paint.h"
48 #include "BKE_editmesh.h"
49 #include "BKE_curve.h"
50
51 #include "DNA_mesh_types.h"
52 #include "DNA_meshdata_types.h"
53 #include "DNA_object_types.h"
54 #include "DNA_curve_types.h" /* for Curve */
55
56 #include "MEM_guardedalloc.h"
57
58 #include "GPU_buffers.h"
59 #include "GPU_draw.h"
60 #include "GPU_glew.h"
61 #include "GPU_shader.h"
62 #include "GPU_basic_shader.h"
63
64 #include <string.h>
65 #include <limits.h>
66 #include <math.h>
67
68 typedef struct {
69         DerivedMesh dm;
70
71         /* these point to data in the DerivedMesh custom data layers,
72          * they are only here for efficiency and convenience **/
73         MVert *mvert;
74         MEdge *medge;
75         MFace *mface;
76         MLoop *mloop;
77         MPoly *mpoly;
78
79         /* Cached */
80         struct PBVH *pbvh;
81         bool pbvh_draw;
82
83         /* Mesh connectivity */
84         MeshElemMap *pmap;
85         int *pmap_mem;
86 } CDDerivedMesh;
87
88 /**************** DerivedMesh interface functions ****************/
89 static int cdDM_getNumVerts(DerivedMesh *dm)
90 {
91         return dm->numVertData;
92 }
93
94 static int cdDM_getNumEdges(DerivedMesh *dm)
95 {
96         return dm->numEdgeData;
97 }
98
99 static int cdDM_getNumTessFaces(DerivedMesh *dm)
100 {
101         /* uncomment and add a breakpoint on the printf()
102          * to help debug tessfaces issues since BMESH merge. */
103 #if 0
104         if (dm->numTessFaceData == 0 && dm->numPolyData != 0) {
105                 printf("%s: has no faces!, call DM_ensure_tessface() if you need them\n");
106         }
107 #endif
108         return dm->numTessFaceData;
109 }
110
111 static int cdDM_getNumLoops(DerivedMesh *dm)
112 {
113         return dm->numLoopData;
114 }
115
116 static int cdDM_getNumPolys(DerivedMesh *dm)
117 {
118         return dm->numPolyData;
119 }
120
121 static void cdDM_getVert(DerivedMesh *dm, int index, MVert *r_vert)
122 {
123         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
124         *r_vert = cddm->mvert[index];
125 }
126
127 static void cdDM_getEdge(DerivedMesh *dm, int index, MEdge *r_edge)
128 {
129         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
130         *r_edge = cddm->medge[index];
131 }
132
133 static void cdDM_getTessFace(DerivedMesh *dm, int index, MFace *r_face)
134 {
135         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
136         *r_face = cddm->mface[index];
137 }
138
139 static void cdDM_copyVertArray(DerivedMesh *dm, MVert *r_vert)
140 {
141         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
142         memcpy(r_vert, cddm->mvert, sizeof(*r_vert) * dm->numVertData);
143 }
144
145 static void cdDM_copyEdgeArray(DerivedMesh *dm, MEdge *r_edge)
146 {
147         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
148         memcpy(r_edge, cddm->medge, sizeof(*r_edge) * dm->numEdgeData);
149 }
150
151 static void cdDM_copyTessFaceArray(DerivedMesh *dm, MFace *r_face)
152 {
153         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
154         memcpy(r_face, cddm->mface, sizeof(*r_face) * dm->numTessFaceData);
155 }
156
157 static void cdDM_copyLoopArray(DerivedMesh *dm, MLoop *r_loop)
158 {
159         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
160         memcpy(r_loop, cddm->mloop, sizeof(*r_loop) * dm->numLoopData);
161 }
162
163 static void cdDM_copyPolyArray(DerivedMesh *dm, MPoly *r_poly)
164 {
165         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
166         memcpy(r_poly, cddm->mpoly, sizeof(*r_poly) * dm->numPolyData);
167 }
168
169 static void cdDM_getMinMax(DerivedMesh *dm, float r_min[3], float r_max[3])
170 {
171         CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
172         int i;
173
174         if (dm->numVertData) {
175                 for (i = 0; i < dm->numVertData; i++) {
176                         minmax_v3v3_v3(r_min, r_max, cddm->mvert[i].co);
177                 }
178         }
179         else {
180                 zero_v3(r_min);
181                 zero_v3(r_max);
182         }
183 }
184
185 static void cdDM_getVertCo(DerivedMesh *dm, int index, float r_co[3])
186 {
187         CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
188
189         copy_v3_v3(r_co, cddm->mvert[index].co);
190 }
191
192 static void cdDM_getVertCos(DerivedMesh *dm, float (*r_cos)[3])
193 {
194         MVert *mv = CDDM_get_verts(dm);
195         int i;
196
197         for (i = 0; i < dm->numVertData; i++, mv++)
198                 copy_v3_v3(r_cos[i], mv->co);
199 }
200
201 static void cdDM_getVertNo(DerivedMesh *dm, int index, float r_no[3])
202 {
203         CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
204         normal_short_to_float_v3(r_no, cddm->mvert[index].no);
205 }
206
207 static const MeshElemMap *cdDM_getPolyMap(Object *ob, DerivedMesh *dm)
208 {
209         CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
210
211         if (!cddm->pmap && ob->type == OB_MESH) {
212                 Mesh *me = ob->data;
213
214                 BKE_mesh_vert_poly_map_create(
215                         &cddm->pmap, &cddm->pmap_mem,
216                         me->mpoly, me->mloop,
217                         me->totvert, me->totpoly, me->totloop);
218         }
219
220         return cddm->pmap;
221 }
222
223 static bool check_sculpt_object_deformed(Object *object, bool for_construction)
224 {
225         bool deformed = false;
226
227         /* Active modifiers means extra deformation, which can't be handled correct
228          * on birth of PBVH and sculpt "layer" levels, so use PBVH only for internal brush
229          * stuff and show final DerivedMesh so user would see actual object shape.
230          */
231         deformed |= object->sculpt->modifiers_active;
232
233         if (for_construction) {
234                 deformed |= object->sculpt->kb != NULL;
235         }
236         else {
237                 /* As in case with modifiers, we can't synchronize deformation made against
238                  * PBVH and non-locked keyblock, so also use PBVH only for brushes and
239                  * final DM to give final result to user.
240                  */
241                 deformed |= object->sculpt->kb && (object->shapeflag & OB_SHAPE_LOCK) == 0;
242         }
243
244         return deformed;
245 }
246
247 static bool can_pbvh_draw(Object *ob, DerivedMesh *dm)
248 {
249         CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
250         Mesh *me = ob->data;
251         bool deformed = check_sculpt_object_deformed(ob, false);
252
253         if (deformed) {
254                 return false;
255         }
256
257         return cddm->mvert == me->mvert || ob->sculpt->kb;
258 }
259
260 static PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm)
261 {
262         CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
263
264         if (!ob) {
265                 cddm->pbvh = NULL;
266                 return NULL;
267         }
268
269         if (!ob->sculpt)
270                 return NULL;
271
272         if (ob->sculpt->pbvh) {
273                 cddm->pbvh = ob->sculpt->pbvh;
274                 cddm->pbvh_draw = can_pbvh_draw(ob, dm);
275         }
276
277         /* Sculpting on a BMesh (dynamic-topology) gets a special PBVH */
278         if (!cddm->pbvh && ob->sculpt->bm) {
279                 cddm->pbvh = BKE_pbvh_new();
280                 cddm->pbvh_draw = true;
281
282                 BKE_pbvh_build_bmesh(cddm->pbvh, ob->sculpt->bm,
283                                      ob->sculpt->bm_smooth_shading,
284                                      ob->sculpt->bm_log, ob->sculpt->cd_vert_node_offset,
285                                      ob->sculpt->cd_face_node_offset);
286
287                 pbvh_show_diffuse_color_set(cddm->pbvh, ob->sculpt->show_diffuse_color);
288         }
289                 
290
291         /* always build pbvh from original mesh, and only use it for drawing if
292          * this derivedmesh is just original mesh. it's the multires subsurf dm
293          * that this is actually for, to support a pbvh on a modified mesh */
294         if (!cddm->pbvh && ob->type == OB_MESH) {
295                 Mesh *me = ob->data;
296                 const int looptris_num = poly_to_tri_count(me->totpoly, me->totloop);
297                 MLoopTri *looptri;
298                 bool deformed;
299
300                 cddm->pbvh = BKE_pbvh_new();
301                 cddm->pbvh_draw = can_pbvh_draw(ob, dm);
302
303                 looptri = MEM_mallocN(sizeof(*looptri) * looptris_num, __func__);
304
305                 BKE_mesh_recalc_looptri(
306                         me->mloop, me->mpoly,
307                         me->mvert,
308                         me->totloop, me->totpoly,
309                         looptri);
310                 
311                 BKE_pbvh_build_mesh(
312                         cddm->pbvh,
313                         me->mpoly, me->mloop,
314                         me->mvert, me->totvert, &me->vdata,
315                         looptri, looptris_num);
316
317                 pbvh_show_diffuse_color_set(cddm->pbvh, ob->sculpt->show_diffuse_color);
318
319                 deformed = check_sculpt_object_deformed(ob, true);
320
321                 if (deformed && ob->derivedDeform) {
322                         DerivedMesh *deformdm = ob->derivedDeform;
323                         float (*vertCos)[3];
324                         int totvert;
325
326                         totvert = deformdm->getNumVerts(deformdm);
327                         vertCos = MEM_mallocN(totvert * sizeof(float[3]), "cdDM_getPBVH vertCos");
328                         deformdm->getVertCos(deformdm, vertCos);
329                         BKE_pbvh_apply_vertCos(cddm->pbvh, vertCos);
330                         MEM_freeN(vertCos);
331                 }
332         }
333
334         return cddm->pbvh;
335 }
336
337 /* update vertex normals so that drawing smooth faces works during sculpt
338  * TODO: proper fix is to support the pbvh in all drawing modes */
339 static void cdDM_update_normals_from_pbvh(DerivedMesh *dm)
340 {
341         CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
342         float (*face_nors)[3];
343
344         /* Some callbacks do not use optimal PBVH draw, so needs all the
345          * possible data (like normals) to be copied from PBVH back to DM.
346          *
347          * This is safe to do if PBVH and DM are representing the same mesh,
348          * which could be wrong when modifiers are enabled for sculpt.
349          * So here we only doing update when there's no modifiers applied
350          * during sculpt.
351          *
352          * It's safe to do nothing if there are modifiers, because in this
353          * case modifier stack is re-constructed from scratch on every
354          * update.
355          */
356         if (!cddm->pbvh_draw) {
357                 return;
358         }
359
360         face_nors = CustomData_get_layer(&dm->polyData, CD_NORMAL);
361
362         BKE_pbvh_update(cddm->pbvh, PBVH_UpdateNormals, face_nors);
363 }
364
365 static void cdDM_drawVerts(DerivedMesh *dm)
366 {
367         GPU_vertex_setup(dm);
368         if (dm->drawObject->tot_loop_verts)
369                 glDrawArrays(GL_POINTS, 0, dm->drawObject->tot_loop_verts);
370         else
371                 glDrawArrays(GL_POINTS, 0, dm->drawObject->tot_loose_point);
372         GPU_buffers_unbind();
373 }
374
375 static void cdDM_drawUVEdges(DerivedMesh *dm)
376 {
377         CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
378         const MPoly *mpoly = cddm->mpoly;
379         int totpoly = dm->getNumPolys(dm);
380         int prevstart = 0;
381         bool prevdraw = true;
382         int curpos = 0;
383         int i;
384
385         GPU_uvedge_setup(dm);
386         for (i = 0; i < totpoly; i++, mpoly++) {
387                 const bool draw = (mpoly->flag & ME_HIDE) == 0;
388
389                 if (prevdraw != draw) {
390                         if (prevdraw && (curpos != prevstart)) {
391                                 glDrawArrays(GL_LINES, prevstart, curpos - prevstart);
392                         }
393                         prevstart = curpos;
394                 }
395
396                 curpos += 2 * mpoly->totloop;
397                 prevdraw = draw;
398         }
399         if (prevdraw && (curpos != prevstart)) {
400                 glDrawArrays(GL_LINES, prevstart, curpos - prevstart);
401         }
402         GPU_buffers_unbind();
403 }
404
405 static void cdDM_drawEdges(DerivedMesh *dm, bool drawLooseEdges, bool drawAllEdges)
406 {
407         CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
408         GPUDrawObject *gdo;
409         if (cddm->pbvh && cddm->pbvh_draw &&
410             BKE_pbvh_type(cddm->pbvh) == PBVH_BMESH)
411         {
412                 BKE_pbvh_draw(cddm->pbvh, NULL, NULL, NULL, true, false);
413
414                 return;
415         }
416         
417         GPU_edge_setup(dm);
418         gdo = dm->drawObject;
419         if (gdo->edges && gdo->points) {
420                 if (drawAllEdges && drawLooseEdges) {
421                         GPU_buffer_draw_elements(gdo->edges, GL_LINES, 0, gdo->totedge * 2);
422                 }
423                 else if (drawAllEdges) {
424                         GPU_buffer_draw_elements(gdo->edges, GL_LINES, 0, gdo->loose_edge_offset * 2);
425                 }
426                 else {
427                         GPU_buffer_draw_elements(gdo->edges, GL_LINES, 0, gdo->tot_edge_drawn * 2);
428                         GPU_buffer_draw_elements(gdo->edges, GL_LINES, gdo->loose_edge_offset * 2, dm->drawObject->tot_loose_edge_drawn * 2);
429                 }
430         }
431         GPU_buffers_unbind();
432 }
433
434 static void cdDM_drawLooseEdges(DerivedMesh *dm)
435 {
436         int start;
437         int count;
438
439         GPU_edge_setup(dm);
440
441         start = (dm->drawObject->loose_edge_offset * 2);
442         count = (dm->drawObject->totedge - dm->drawObject->loose_edge_offset) * 2;
443
444         if (count) {
445                 GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, start, count);
446         }
447
448         GPU_buffers_unbind();
449 }
450
451 static void cdDM_drawFacesSolid(
452         DerivedMesh *dm,
453         float (*partial_redraw_planes)[4],
454         bool UNUSED(fast), DMSetMaterial setMaterial)
455 {
456         CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
457         int a;
458
459         if (cddm->pbvh) {
460                 if (cddm->pbvh_draw && BKE_pbvh_has_faces(cddm->pbvh)) {
461                         float (*face_nors)[3] = CustomData_get_layer(&dm->polyData, CD_NORMAL);
462
463                         BKE_pbvh_draw(cddm->pbvh, partial_redraw_planes, face_nors,
464                                       setMaterial, false, false);
465                         return;
466                 }
467         }
468         
469         GPU_vertex_setup(dm);
470         GPU_normal_setup(dm);
471         GPU_triangle_setup(dm);
472         for (a = 0; a < dm->drawObject->totmaterial; a++) {
473                 if (!setMaterial || setMaterial(dm->drawObject->materials[a].mat_nr + 1, NULL)) {
474                         GPU_buffer_draw_elements(
475                                     dm->drawObject->triangles, GL_TRIANGLES,
476                                     dm->drawObject->materials[a].start, dm->drawObject->materials[a].totelements);
477                 }
478         }
479         GPU_buffers_unbind();
480 }
481
482 static void cdDM_drawFacesTex_common(
483         DerivedMesh *dm,
484         DMSetDrawOptionsTex drawParams,
485         DMSetDrawOptionsMappedTex drawParamsMapped,
486         DMCompareDrawOptions compareDrawOptions,
487         void *userData, DMDrawFlag flag)
488 {
489         CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
490         const MPoly *mpoly = cddm->mpoly;
491         MTexPoly *mtexpoly = DM_get_poly_data_layer(dm, CD_MTEXPOLY);
492         const  MLoopCol *mloopcol = NULL;
493         int i;
494         int colType, start_element, tot_drawn;
495         const bool use_hide = (flag & DM_DRAW_SKIP_HIDDEN) != 0;
496         const bool use_tface = (flag & DM_DRAW_USE_ACTIVE_UV) != 0;
497         const bool use_colors = (flag & DM_DRAW_USE_COLORS) != 0;
498         int totpoly;
499         int next_actualFace;
500         int mat_index;
501         int tot_element;
502
503         /* double lookup */
504         const int *index_mp_to_orig  = dm->getPolyDataArray(dm, CD_ORIGINDEX);
505
506         /* TODO: not entirely correct, but currently dynamic topology will
507          *       destroy UVs anyway, so textured display wouldn't work anyway
508          *
509          *       this will do more like solid view with lights set up for
510          *       textured view, but object itself will be displayed gray
511          *       (the same as it'll display without UV maps in textured view)
512          */
513         if (cddm->pbvh) {
514                 if (cddm->pbvh_draw &&
515                     BKE_pbvh_type(cddm->pbvh) == PBVH_BMESH &&
516                     BKE_pbvh_has_faces(cddm->pbvh))
517                 {
518                         GPU_set_tpage(NULL, false, false);
519                         BKE_pbvh_draw(cddm->pbvh, NULL, NULL, NULL, false, false);
520                         return;
521                 }
522                 else {
523                         cdDM_update_normals_from_pbvh(dm);
524                 }
525         }
526
527         if (use_colors) {
528                 colType = CD_TEXTURE_MLOOPCOL;
529                 mloopcol = dm->getLoopDataArray(dm, colType);
530                 if (!mloopcol) {
531                         colType = CD_PREVIEW_MLOOPCOL;
532                         mloopcol = dm->getLoopDataArray(dm, colType);
533                 }
534                 if (!mloopcol) {
535                         colType = CD_MLOOPCOL;
536                         mloopcol = dm->getLoopDataArray(dm, colType);
537                 }
538         }
539
540         GPU_vertex_setup(dm);
541         GPU_normal_setup(dm);
542         GPU_triangle_setup(dm);
543         if (flag & DM_DRAW_USE_TEXPAINT_UV)
544                 GPU_texpaint_uv_setup(dm);
545         else
546                 GPU_uv_setup(dm);
547         if (mloopcol) {
548                 GPU_color_setup(dm, colType);
549         }
550
551         /* lastFlag = 0; */ /* UNUSED */
552         for (mat_index = 0; mat_index < dm->drawObject->totmaterial; mat_index++) {
553                 GPUBufferMaterial *bufmat = dm->drawObject->materials + mat_index;
554                 next_actualFace = bufmat->polys[0];
555                 totpoly = bufmat->totpolys;
556
557                 tot_element = 0;
558                 tot_drawn = 0;
559                 start_element = 0;
560
561                 for (i = 0; i < totpoly; i++) {
562                         int actualFace = bufmat->polys[i];
563                         DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL;
564                         int flush = 0;
565                         int tot_tri_verts;
566
567                         if (i != totpoly - 1)
568                                 next_actualFace = bufmat->polys[i + 1];
569
570                         if (use_hide && (mpoly[actualFace].flag & ME_HIDE)) {
571                                 draw_option = DM_DRAW_OPTION_SKIP;
572                         }
573                         else if (drawParams) {
574                                 MTexPoly *tp = use_tface && mtexpoly ? &mtexpoly[actualFace] : NULL;
575                                 draw_option = drawParams(tp, (mloopcol != NULL), mpoly[actualFace].mat_nr);
576                         }
577                         else {
578                                 if (index_mp_to_orig) {
579                                         const int orig = index_mp_to_orig[actualFace];
580                                         if (orig == ORIGINDEX_NONE) {
581                                                 /* XXX, this is not really correct
582                                                  * it will draw the previous faces context for this one when we don't know its settings.
583                                                  * but better then skipping it altogether. - campbell */
584                                                 draw_option = DM_DRAW_OPTION_NORMAL;
585                                         }
586                                         else if (drawParamsMapped) {
587                                                 draw_option = drawParamsMapped(userData, orig, mpoly[actualFace].mat_nr);
588                                         }
589                                 }
590                                 else if (drawParamsMapped) {
591                                         draw_option = drawParamsMapped(userData, actualFace, mpoly[actualFace].mat_nr);
592                                 }
593                         }
594
595                         /* flush buffer if current triangle isn't drawable or it's last triangle */
596                         flush = (draw_option == DM_DRAW_OPTION_SKIP) || (i == totpoly - 1);
597
598                         if (!flush && compareDrawOptions) {
599                                 /* also compare draw options and flush buffer if they're different
600                                  * need for face selection highlight in edit mode */
601                                 flush |= compareDrawOptions(userData, actualFace, next_actualFace) == 0;
602                         }
603
604                         tot_tri_verts = ME_POLY_TRI_TOT(&mpoly[actualFace]) * 3;
605                         tot_element += tot_tri_verts;
606
607                         if (flush) {
608                                 if (draw_option != DM_DRAW_OPTION_SKIP)
609                                         tot_drawn += tot_tri_verts;
610
611                                 if (tot_drawn) {
612                                         if (mloopcol && draw_option != DM_DRAW_OPTION_NO_MCOL)
613                                                 GPU_color_switch(1);
614                                         else
615                                                 GPU_color_switch(0);
616
617                                         GPU_buffer_draw_elements(dm->drawObject->triangles, GL_TRIANGLES, bufmat->start + start_element, tot_drawn);
618                                         tot_drawn = 0;
619                                 }
620                                 start_element = tot_element;
621                         }
622                         else {
623                                 tot_drawn += tot_tri_verts;
624                         }
625                 }
626         }
627
628         GPU_buffers_unbind();
629         
630 }
631
632 static void cdDM_drawFacesTex(
633         DerivedMesh *dm,
634         DMSetDrawOptionsTex setDrawOptions,
635         DMCompareDrawOptions compareDrawOptions,
636         void *userData, DMDrawFlag flag)
637 {
638         cdDM_drawFacesTex_common(dm, setDrawOptions, NULL, compareDrawOptions, userData, flag);
639 }
640
641 static void cdDM_drawMappedFaces(
642         DerivedMesh *dm,
643         DMSetDrawOptions setDrawOptions,
644         DMSetMaterial setMaterial,
645         DMCompareDrawOptions compareDrawOptions,
646         void *userData, DMDrawFlag flag)
647 {
648         CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
649         const MPoly *mpoly = cddm->mpoly;
650         const MLoopCol *mloopcol = NULL;
651         const bool use_colors = (flag & DM_DRAW_USE_COLORS) != 0;
652         const bool use_hide = (flag & DM_DRAW_SKIP_HIDDEN) != 0;
653         int colType;
654         int i, j;
655         int start_element = 0, tot_element, tot_drawn;
656         int totpoly;
657         int tot_tri_elem;
658         int mat_index;
659         GPUBuffer *findex_buffer = NULL;
660
661         const int *index_mp_to_orig  = dm->getPolyDataArray(dm, CD_ORIGINDEX);
662
663         /* fist, setup common buffers */
664         GPU_vertex_setup(dm);
665         GPU_triangle_setup(dm);
666
667         totpoly = dm->getNumPolys(dm);
668
669         /* if we do selection, fill the selection buffer color */
670         if (G.f & G_BACKBUFSEL) {
671                 if (!(flag & DM_DRAW_SKIP_SELECT)) {
672                         Mesh *me = NULL;
673                         BMesh *bm = NULL;
674                         unsigned int *fi_map;
675
676                         if (flag & DM_DRAW_SELECT_USE_EDITMODE)
677                                 bm = userData;
678                         else
679                                 me = userData;
680
681                         findex_buffer = GPU_buffer_alloc(dm->drawObject->tot_loop_verts * sizeof(int));
682                         fi_map = GPU_buffer_lock(findex_buffer, GPU_BINDING_ARRAY);
683
684                         if (fi_map) {
685                                 for (i = 0; i < totpoly; i++, mpoly++) {
686                                         int selcol = 0xFFFFFFFF;
687                                         const int orig = (index_mp_to_orig) ? index_mp_to_orig[i] : i;
688                                         bool is_hidden;
689
690                                         if (orig != ORIGINDEX_NONE) {
691                                                 if (use_hide) {
692                                                         if (flag & DM_DRAW_SELECT_USE_EDITMODE) {
693                                                                 BMFace *efa = BM_face_at_index(bm, orig);
694                                                                 is_hidden = BM_elem_flag_test(efa, BM_ELEM_HIDDEN) != 0;
695                                                         }
696                                                         else {
697                                                                 is_hidden = (me->mpoly[orig].flag & ME_HIDE) != 0;
698                                                         }
699
700                                                         if (!is_hidden) {
701                                                                 GPU_select_index_get(orig + 1, &selcol);
702                                                         }
703                                                 }
704                                                 else {
705                                                         GPU_select_index_get(orig + 1, &selcol);
706                                                 }
707                                         }
708
709                                         for (j = 0; j < mpoly->totloop; j++)
710                                                 fi_map[start_element++] = selcol;
711                                 }
712
713                                 start_element = 0;
714                                 mpoly = cddm->mpoly;
715
716                                 GPU_buffer_unlock(findex_buffer, GPU_BINDING_ARRAY);
717                                 GPU_buffer_bind_as_color(findex_buffer);
718                         }
719                 }
720         }
721         else {
722                 GPU_normal_setup(dm);
723
724                 if (use_colors) {
725                         colType = CD_TEXTURE_MLOOPCOL;
726                         mloopcol = DM_get_loop_data_layer(dm, colType);
727                         if (!mloopcol) {
728                                 colType = CD_PREVIEW_MLOOPCOL;
729                                 mloopcol = DM_get_loop_data_layer(dm, colType);
730                         }
731                         if (!mloopcol) {
732                                 colType = CD_MLOOPCOL;
733                                 mloopcol = DM_get_loop_data_layer(dm, colType);
734                         }
735
736                         if (use_colors && mloopcol) {
737                                 GPU_color_setup(dm, colType);
738                         }
739                 }
740         }
741
742         tot_tri_elem = dm->drawObject->tot_triangle_point;
743
744         if (tot_tri_elem == 0) {
745                 /* avoid buffer problems in following code */
746         }
747         else if (setDrawOptions == NULL) {
748                 /* just draw the entire face array */
749                 GPU_buffer_draw_elements(dm->drawObject->triangles, GL_TRIANGLES, 0, tot_tri_elem);
750         }
751         else {
752                 for (mat_index = 0; mat_index < dm->drawObject->totmaterial; mat_index++) {
753                         GPUBufferMaterial *bufmat = dm->drawObject->materials + mat_index;
754                         DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL;
755                         int next_actualFace = bufmat->polys[0];
756                         totpoly = use_hide ? bufmat->totvisiblepolys : bufmat->totpolys;
757
758                         tot_element = 0;
759                         start_element = 0;
760                         tot_drawn = 0;
761
762                         if (setMaterial)
763                                 draw_option = setMaterial(bufmat->mat_nr + 1, NULL);
764
765                         if (draw_option != DM_DRAW_OPTION_SKIP) {
766                                 DMDrawOption last_draw_option = DM_DRAW_OPTION_NORMAL;
767
768                                 for (i = 0; i < totpoly; i++) {
769                                         int actualFace = next_actualFace;
770                                         int flush = 0;
771                                         int tot_tri_verts;
772
773                                         draw_option = DM_DRAW_OPTION_NORMAL;
774
775                                         if (i != totpoly - 1)
776                                                 next_actualFace = bufmat->polys[i + 1];
777
778                                         if (setDrawOptions) {
779                                                 const int orig = (index_mp_to_orig) ? index_mp_to_orig[actualFace] : actualFace;
780
781                                                 if (orig != ORIGINDEX_NONE) {
782                                                         draw_option = setDrawOptions(userData, orig);
783                                                 }
784                                         }
785
786                                         /* Goal is to draw as long of a contiguous triangle
787                                          * array as possible, so draw when we hit either an
788                                          * invisible triangle or at the end of the array */
789
790                                         /* flush buffer if current triangle isn't drawable or it's last triangle... */
791                                         flush = (draw_option != last_draw_option) || (i == totpoly - 1);
792
793                                         if (!flush && compareDrawOptions) {
794                                                 flush |= compareDrawOptions(userData, actualFace, next_actualFace) == 0;
795                                         }
796
797                                         tot_tri_verts = ME_POLY_TRI_TOT(&mpoly[actualFace]) * 3;
798                                         tot_element += tot_tri_verts;
799
800                                         if (flush) {
801                                                 if (draw_option != DM_DRAW_OPTION_SKIP) {
802                                                         tot_drawn += tot_tri_verts;
803
804                                                         if (last_draw_option != draw_option) {
805                                                                 if (draw_option == DM_DRAW_OPTION_STIPPLE) {
806                                                                         GPU_basic_shader_bind(GPU_SHADER_STIPPLE | GPU_SHADER_USE_COLOR);
807                                                                         GPU_basic_shader_stipple(GPU_SHADER_STIPPLE_QUARTTONE);
808                                                                 }
809                                                                 else {
810                                                                         GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
811                                                                 }
812                                                         }
813                                                 }
814
815                                                 if (tot_drawn) {
816                                                         GPU_buffer_draw_elements(dm->drawObject->triangles, GL_TRIANGLES, bufmat->start + start_element, tot_drawn);
817                                                         tot_drawn = 0;
818                                                 }
819
820                                                 last_draw_option = draw_option;
821                                                 start_element = tot_element;
822                                         }
823                                         else {
824                                                 if (draw_option != DM_DRAW_OPTION_SKIP) {
825                                                         tot_drawn += tot_tri_verts;
826                                                 }
827                                                 else {
828                                                         start_element = tot_element;
829                                                 }
830                                         }
831                                 }
832                         }
833                 }
834         }
835
836         GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);
837
838         GPU_buffers_unbind();
839
840         if (findex_buffer)
841                 GPU_buffer_free(findex_buffer);
842
843 }
844
845 static void cdDM_drawMappedFacesTex(
846         DerivedMesh *dm,
847         DMSetDrawOptionsMappedTex setDrawOptions,
848         DMCompareDrawOptions compareDrawOptions,
849         void *userData, DMDrawFlag flag)
850 {
851         cdDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData, flag);
852 }
853
854 static void cddm_draw_attrib_vertex(
855         DMVertexAttribs *attribs, const MVert *mvert, int a, int index, int loop, int vert,
856         const float *lnor, const bool smoothnormal)
857 {
858         DM_draw_attrib_vertex(attribs, a, index, vert, loop);
859
860         /* vertex normal */
861         if (lnor) {
862                 glNormal3fv(lnor);
863         }
864         else if (smoothnormal) {
865                 glNormal3sv(mvert[index].no);
866         }
867
868         /* vertex coordinate */
869         glVertex3fv(mvert[index].co);
870 }
871
872 typedef struct {
873         DMVertexAttribs attribs;
874         int numdata;
875
876         GPUAttrib datatypes[GPU_MAX_ATTRIB]; /* TODO, messing up when switching materials many times - [#21056]*/
877 } GPUMaterialConv;
878
879 static void cdDM_drawMappedFacesGLSL(
880         DerivedMesh *dm,
881         DMSetMaterial setMaterial,
882         DMSetDrawOptions setDrawOptions,
883         void *userData)
884 {
885         CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
886         GPUVertexAttribs gattribs;
887         const MVert *mvert = cddm->mvert;
888         const MPoly *mpoly = cddm->mpoly;
889         const MLoop *mloop = cddm->mloop;
890         const MLoopTri *lt = dm->getLoopTriArray(dm);
891         const int tottri = dm->getNumLoopTri(dm);
892         /* MTFace *tf = dm->getTessFaceDataArray(dm, CD_MTFACE); */ /* UNUSED */
893         const float (*nors)[3] = dm->getPolyDataArray(dm, CD_NORMAL);
894         const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL);
895         const int totpoly = dm->getNumPolys(dm);
896         const short dm_totmat = dm->totmat;
897         int a, b, matnr, new_matnr;
898         bool do_draw;
899         int orig;
900
901         const int *index_mp_to_orig  = dm->getPolyDataArray(dm, CD_ORIGINDEX);
902
903         /* TODO: same as for solid draw, not entirely correct, but works fine for now,
904          *       will skip using textures (dyntopo currently destroys UV anyway) and
905          *       works fine for matcap
906          */
907         if (cddm->pbvh) {
908                 if (cddm->pbvh_draw &&
909                     BKE_pbvh_type(cddm->pbvh) == PBVH_BMESH &&
910                     BKE_pbvh_has_faces(cddm->pbvh))
911                 {
912                         setMaterial(1, &gattribs);
913                         BKE_pbvh_draw(cddm->pbvh, NULL, NULL, NULL, false, false);
914                         return;
915                 }
916                 else {
917                         cdDM_update_normals_from_pbvh(dm);
918                 }
919         }
920
921         matnr = -1;
922         do_draw = false;
923
924         if (setDrawOptions != NULL) {
925                 DMVertexAttribs attribs;
926                 DEBUG_VBO("Using legacy code. cdDM_drawMappedFacesGLSL\n");
927                 memset(&attribs, 0, sizeof(attribs));
928
929                 glBegin(GL_TRIANGLES);
930
931                 for (a = 0; a < tottri; a++, lt++) {
932                         const MPoly *mp = &mpoly[lt->poly];
933                         const unsigned int  vtri[3] = {mloop[lt->tri[0]].v, mloop[lt->tri[1]].v, mloop[lt->tri[2]].v};
934                         const unsigned int *ltri = lt->tri;
935                         const float *ln1 = NULL, *ln2 = NULL, *ln3 = NULL;
936                         const bool smoothnormal = lnors || (mp->flag & ME_SMOOTH);
937                         new_matnr = mp->mat_nr;
938
939                         if (new_matnr != matnr) {
940                                 glEnd();
941
942                                 matnr = new_matnr;
943                                 do_draw = setMaterial(matnr + 1, &gattribs);
944                                 if (do_draw) {
945                                         DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
946                                         DM_draw_attrib_vertex_uniforms(&attribs);
947                                 }
948
949                                 glBegin(GL_TRIANGLES);
950                         }
951
952                         if (!do_draw) {
953                                 continue;
954                         }
955                         else /* if (setDrawOptions) */ {
956                                 orig = (index_mp_to_orig) ? index_mp_to_orig[lt->poly] : lt->poly;
957
958                                 if (orig == ORIGINDEX_NONE) {
959                                         /* since the material is set by setMaterial(), faces with no
960                                          * origin can be assumed to be generated by a modifier */ 
961                                         
962                                         /* continue */
963                                 }
964                                 else if (setDrawOptions(userData, orig) == DM_DRAW_OPTION_SKIP)
965                                         continue;
966                         }
967
968                         if (!smoothnormal) {
969                                 if (nors) {
970                                         glNormal3fv(nors[lt->poly]);
971                                 }
972                                 else {
973                                         /* TODO ideally a normal layer should always be available */
974                                         float nor[3];
975                                         normal_tri_v3(nor, mvert[vtri[0]].co, mvert[vtri[1]].co, mvert[vtri[2]].co);
976                                         glNormal3fv(nor);
977                                 }
978                         }
979                         else if (lnors) {
980                                 ln1 = lnors[ltri[0]];
981                                 ln2 = lnors[ltri[1]];
982                                 ln3 = lnors[ltri[2]];
983                         }
984                         
985                         cddm_draw_attrib_vertex(&attribs, mvert, a, vtri[0], ltri[0], 0, ln1, smoothnormal);
986                         cddm_draw_attrib_vertex(&attribs, mvert, a, vtri[1], ltri[1], 1, ln2, smoothnormal);
987                         cddm_draw_attrib_vertex(&attribs, mvert, a, vtri[2], ltri[2], 2, ln3, smoothnormal);
988                 }
989                 glEnd();
990         }
991         else {
992                 GPUMaterialConv *matconv;
993                 int offset;
994                 int *mat_orig_to_new;
995                 int tot_active_mat;
996                 GPUBuffer *buffer = NULL;
997                 unsigned char *varray;
998                 size_t max_element_size = 0;
999                 int tot_loops = 0;
1000
1001                 GPU_vertex_setup(dm);
1002                 GPU_normal_setup(dm);
1003                 GPU_triangle_setup(dm);
1004
1005                 tot_active_mat = dm->drawObject->totmaterial;
1006
1007                 matconv = MEM_callocN(sizeof(*matconv) * tot_active_mat,
1008                                       "cdDM_drawMappedFacesGLSL.matconv");
1009                 mat_orig_to_new = MEM_mallocN(sizeof(*mat_orig_to_new) * dm->totmat,
1010                                               "cdDM_drawMappedFacesGLSL.mat_orig_to_new");
1011
1012                 /* part one, check what attributes are needed per material */
1013                 for (a = 0; a < tot_active_mat; a++) {
1014                         new_matnr = dm->drawObject->materials[a].mat_nr;
1015
1016                         /* map from original material index to new
1017                          * GPUBufferMaterial index */
1018                         mat_orig_to_new[new_matnr] = a;
1019                         do_draw = setMaterial(new_matnr + 1, &gattribs);
1020
1021                         if (do_draw) {
1022                                 int numdata = 0;
1023                                 DM_vertex_attributes_from_gpu(dm, &gattribs, &matconv[a].attribs);
1024
1025                                 if (matconv[a].attribs.totorco && matconv[a].attribs.orco.array) {
1026                                         matconv[a].datatypes[numdata].index = matconv[a].attribs.orco.gl_index;
1027                                         matconv[a].datatypes[numdata].info_index = matconv[a].attribs.orco.gl_info_index;
1028                                         matconv[a].datatypes[numdata].size = 3;
1029                                         matconv[a].datatypes[numdata].type = GL_FLOAT;
1030                                         numdata++;
1031                                 }
1032                                 for (b = 0; b < matconv[a].attribs.tottface; b++) {
1033                                         if (matconv[a].attribs.tface[b].array) {
1034                                                 matconv[a].datatypes[numdata].index = matconv[a].attribs.tface[b].gl_index;
1035                                                 matconv[a].datatypes[numdata].info_index = matconv[a].attribs.tface[b].gl_info_index;
1036                                                 matconv[a].datatypes[numdata].size = 2;
1037                                                 matconv[a].datatypes[numdata].type = GL_FLOAT;
1038                                                 numdata++;
1039                                         }
1040                                 }
1041                                 for (b = 0; b < matconv[a].attribs.totmcol; b++) {
1042                                         if (matconv[a].attribs.mcol[b].array) {
1043                                                 matconv[a].datatypes[numdata].index = matconv[a].attribs.mcol[b].gl_index;
1044                                                 matconv[a].datatypes[numdata].info_index = matconv[a].attribs.mcol[b].gl_info_index;
1045                                                 matconv[a].datatypes[numdata].size = 4;
1046                                                 matconv[a].datatypes[numdata].type = GL_UNSIGNED_BYTE;
1047                                                 numdata++;
1048                                         }
1049                                 }
1050                                 for (b = 0; b < matconv[a].attribs.tottang; b++) {
1051                                         if (matconv[a].attribs.tang[b].array) {
1052                                                 matconv[a].datatypes[numdata].index = matconv[a].attribs.tang[b].gl_index;
1053                                                 matconv[a].datatypes[numdata].info_index = matconv[a].attribs.tang[b].gl_info_index;
1054                                                 matconv[a].datatypes[numdata].size = 4;
1055                                                 matconv[a].datatypes[numdata].type = GL_FLOAT;
1056                                                 numdata++;
1057                                         }
1058                                 }
1059                                 if (numdata != 0) {
1060                                         matconv[a].numdata = numdata;
1061                                         max_element_size = max_ii(GPU_attrib_element_size(matconv[a].datatypes, numdata), max_element_size);
1062                                 }
1063                         }
1064                 }
1065
1066                 /* part two, generate and fill the arrays with the data */
1067                 if (max_element_size > 0) {
1068                         buffer = GPU_buffer_alloc(max_element_size * dm->drawObject->tot_loop_verts);
1069
1070                         varray = GPU_buffer_lock_stream(buffer, GPU_BINDING_ARRAY);
1071                         if (varray == NULL) {
1072                                 GPU_buffers_unbind();
1073                                 GPU_buffer_free(buffer);
1074                                 MEM_freeN(mat_orig_to_new);
1075                                 MEM_freeN(matconv);
1076                                 fprintf(stderr, "Out of memory, can't draw object\n");
1077                                 return;
1078                         }
1079
1080                         for (a = 0; a < totpoly; a++, mpoly++) {
1081                                 const short mat_nr = ME_MAT_NR_TEST(mpoly->mat_nr, dm_totmat);
1082                                 int j;
1083                                 int i = mat_orig_to_new[mat_nr];
1084                                 offset = tot_loops * max_element_size;
1085
1086                                 if (matconv[i].numdata != 0) {
1087                                         if (matconv[i].attribs.totorco && matconv[i].attribs.orco.array) {
1088                                                 for (j = 0; j < mpoly->totloop; j++)
1089                                                         copy_v3_v3((float *)&varray[offset + j * max_element_size],
1090                                                                    (float *)matconv[i].attribs.orco.array[mloop[mpoly->loopstart + j].v]);
1091                                                 offset += sizeof(float) * 3;
1092                                         }
1093                                         for (b = 0; b < matconv[i].attribs.tottface; b++) {
1094                                                 if (matconv[i].attribs.tface[b].array) {
1095                                                         const MLoopUV *mloopuv = matconv[i].attribs.tface[b].array;
1096                                                         for (j = 0; j < mpoly->totloop; j++)
1097                                                                 copy_v2_v2((float *)&varray[offset + j * max_element_size], mloopuv[mpoly->loopstart + j].uv);
1098                                                         offset += sizeof(float) * 2;
1099                                                 }
1100                                         }
1101                                         for (b = 0; b < matconv[i].attribs.totmcol; b++) {
1102                                                 if (matconv[i].attribs.mcol[b].array) {
1103                                                         const MLoopCol *mloopcol = matconv[i].attribs.mcol[b].array;
1104                                                         for (j = 0; j < mpoly->totloop; j++)
1105                                                                 copy_v4_v4_uchar(&varray[offset + j * max_element_size], &mloopcol[mpoly->loopstart + j].r);
1106                                                         offset += sizeof(unsigned char) * 4;
1107                                                 }
1108                                         }
1109                                         for (b = 0; b < matconv[i].attribs.tottang; b++) {
1110                                                 if (matconv[i].attribs.tottang && matconv[i].attribs.tang[b].array) {
1111                                                         const float (*looptang)[4] = (const float (*)[4])matconv[i].attribs.tang[b].array;
1112                                                         for (j = 0; j < mpoly->totloop; j++)
1113                                                                 copy_v4_v4((float *)&varray[offset + j * max_element_size], looptang[mpoly->loopstart + j]);
1114                                                         offset += sizeof(float) * 4;
1115                                                 }
1116                                         }
1117                                 }
1118
1119                                 tot_loops += mpoly->totloop;
1120                         }
1121                         GPU_buffer_unlock(buffer, GPU_BINDING_ARRAY);
1122                 }
1123
1124                 for (a = 0; a < tot_active_mat; a++) {
1125                         new_matnr = dm->drawObject->materials[a].mat_nr;
1126
1127                         do_draw = setMaterial(new_matnr + 1, &gattribs);
1128
1129                         if (do_draw) {
1130                                 if (matconv[a].numdata) {
1131                                         GPU_interleaved_attrib_setup(buffer, matconv[a].datatypes, matconv[a].numdata, max_element_size);
1132                                 }
1133                                 GPU_buffer_draw_elements(dm->drawObject->triangles, GL_TRIANGLES,
1134                                                          dm->drawObject->materials[a].start, dm->drawObject->materials[a].totelements);
1135                                 if (matconv[a].numdata) {
1136                                         GPU_interleaved_attrib_unbind();
1137                                 }
1138                         }
1139                 }
1140
1141                 GPU_buffers_unbind();
1142                 if (buffer)
1143                         GPU_buffer_free(buffer);
1144
1145                 MEM_freeN(mat_orig_to_new);
1146                 MEM_freeN(matconv);
1147         }
1148 }
1149
1150 static void cdDM_drawFacesGLSL(DerivedMesh *dm, DMSetMaterial setMaterial)
1151 {
1152         dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
1153 }
1154
1155 static void cdDM_drawMappedFacesMat(
1156         DerivedMesh *dm,
1157         void (*setMaterial)(void *userData, int matnr, void *attribs),
1158         bool (*setFace)(void *userData, int index), void *userData)
1159 {
1160         CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
1161         GPUVertexAttribs gattribs;
1162         DMVertexAttribs attribs;
1163         MVert *mvert = cddm->mvert;
1164         const MPoly *mpoly = cddm->mpoly;
1165         const MLoop *mloop = cddm->mloop;
1166         const MLoopTri *lt = dm->getLoopTriArray(dm);
1167         const int tottri = dm->getNumLoopTri(dm);
1168         const float (*nors)[3] = dm->getPolyDataArray(dm, CD_NORMAL);
1169         const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL);
1170         int a, matnr, new_matnr;
1171         int orig;
1172
1173         const int *index_mp_to_orig  = dm->getPolyDataArray(dm, CD_ORIGINDEX);
1174
1175         /* TODO: same as for solid draw, not entirely correct, but works fine for now,
1176          *       will skip using textures (dyntopo currently destroys UV anyway) and
1177          *       works fine for matcap
1178          */
1179
1180         if (cddm->pbvh) {
1181                 if (cddm->pbvh_draw &&
1182                     BKE_pbvh_type(cddm->pbvh) == PBVH_BMESH &&
1183                     BKE_pbvh_has_faces(cddm->pbvh))
1184                 {
1185                         setMaterial(userData, 1, &gattribs);
1186                         BKE_pbvh_draw(cddm->pbvh, NULL, NULL, NULL, false, false);
1187                         return;
1188                 }
1189                 else {
1190                         cdDM_update_normals_from_pbvh(dm);
1191                 }
1192         }
1193
1194         matnr = -1;
1195
1196         memset(&attribs, 0, sizeof(attribs));
1197
1198         glBegin(GL_TRIANGLES);
1199
1200         for (a = 0; a < tottri; a++, lt++) {
1201                 const MPoly *mp = &mpoly[lt->poly];
1202                 const unsigned int  vtri[3] = {mloop[lt->tri[0]].v, mloop[lt->tri[1]].v, mloop[lt->tri[2]].v};
1203                 const unsigned int *ltri = lt->tri;
1204                 const bool smoothnormal = lnors || (mp->flag & ME_SMOOTH);
1205                 const float *ln1 = NULL, *ln2 = NULL, *ln3 = NULL;
1206
1207                 /* material */
1208                 new_matnr = mp->mat_nr + 1;
1209
1210                 if (new_matnr != matnr) {
1211                         glEnd();
1212
1213                         setMaterial(userData, matnr = new_matnr, &gattribs);
1214                         DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1215                         DM_draw_attrib_vertex_uniforms(&attribs);
1216
1217                         glBegin(GL_TRIANGLES);
1218                 }
1219
1220                 /* skipping faces */
1221                 if (setFace) {
1222                         orig = (index_mp_to_orig) ? index_mp_to_orig[lt->poly] : lt->poly;
1223
1224                         if (orig != ORIGINDEX_NONE && !setFace(userData, orig))
1225                                 continue;
1226                 }
1227
1228                 /* smooth normal */
1229                 if (!smoothnormal) {
1230                         if (nors) {
1231                                 glNormal3fv(nors[lt->poly]);
1232                         }
1233                         else {
1234                                 /* TODO ideally a normal layer should always be available */
1235                                 float nor[3];
1236                                 normal_tri_v3(nor, mvert[vtri[0]].co, mvert[vtri[1]].co, mvert[vtri[2]].co);
1237                                 glNormal3fv(nor);
1238                         }
1239                 }
1240                 else if (lnors) {
1241                         ln1 = lnors[ltri[0]];
1242                         ln2 = lnors[ltri[1]];
1243                         ln3 = lnors[ltri[2]];
1244                 }
1245
1246                 /* vertices */
1247                 cddm_draw_attrib_vertex(&attribs, mvert, a, vtri[0], ltri[0], 0, ln1, smoothnormal);
1248                 cddm_draw_attrib_vertex(&attribs, mvert, a, vtri[1], ltri[1], 1, ln2, smoothnormal);
1249                 cddm_draw_attrib_vertex(&attribs, mvert, a, vtri[2], ltri[2], 2, ln3, smoothnormal);
1250         }
1251         glEnd();
1252 }
1253
1254 static void cdDM_drawMappedEdges(DerivedMesh *dm, DMSetDrawOptions setDrawOptions, void *userData)
1255 {
1256         CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
1257         MVert *vert = cddm->mvert;
1258         MEdge *edge = cddm->medge;
1259         int i, orig, *index = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
1260
1261         glBegin(GL_LINES);
1262         for (i = 0; i < dm->numEdgeData; i++, edge++) {
1263                 if (index) {
1264                         orig = *index++;
1265                         if (setDrawOptions && orig == ORIGINDEX_NONE) continue;
1266                 }
1267                 else
1268                         orig = i;
1269
1270                 if (!setDrawOptions || (setDrawOptions(userData, orig) != DM_DRAW_OPTION_SKIP)) {
1271                         glVertex3fv(vert[edge->v1].co);
1272                         glVertex3fv(vert[edge->v2].co);
1273                 }
1274         }
1275         glEnd();
1276 }
1277
1278 typedef struct FaceCount {
1279         unsigned int i_visible;
1280         unsigned int i_hidden;
1281         unsigned int i_tri_visible;
1282         unsigned int i_tri_hidden;
1283 } FaceCount;
1284
1285 static void cdDM_buffer_copy_triangles(
1286         DerivedMesh *dm, unsigned int *varray,
1287         const int *mat_orig_to_new)
1288 {
1289         GPUBufferMaterial *gpumat, *gpumaterials = dm->drawObject->materials;
1290         int i, j, start;
1291
1292         const int gpu_totmat = dm->drawObject->totmaterial;
1293         const short dm_totmat = dm->totmat;
1294         const MPoly *mpoly = dm->getPolyArray(dm);
1295         const MLoopTri *lt = dm->getLoopTriArray(dm);
1296         const int totpoly = dm->getNumPolys(dm);
1297
1298         FaceCount *fc = MEM_mallocN(sizeof(*fc) * gpu_totmat, "gpumaterial.facecount");
1299
1300         for (i = 0; i < gpu_totmat; i++) {
1301                 fc[i].i_visible = 0;
1302                 fc[i].i_tri_visible = 0;
1303                 fc[i].i_hidden = gpumaterials[i].totpolys - 1;
1304                 fc[i].i_tri_hidden = gpumaterials[i].totelements - 1;
1305         }
1306
1307         for (i = 0; i < totpoly; i++) {
1308                 const short mat_nr = ME_MAT_NR_TEST(mpoly[i].mat_nr, dm_totmat);
1309                 int tottri = ME_POLY_TRI_TOT(&mpoly[i]);
1310                 int mati = mat_orig_to_new[mat_nr];
1311                 gpumat = gpumaterials + mati;
1312
1313                 if (mpoly[i].flag & ME_HIDE) {
1314                         for (j = 0; j < tottri; j++, lt++) {
1315                                 start = gpumat->start + fc[mati].i_tri_hidden;
1316                                 /* v1 v2 v3 */
1317                                 varray[start--] = lt->tri[2];
1318                                 varray[start--] = lt->tri[1];
1319                                 varray[start--] = lt->tri[0];
1320                                 fc[mati].i_tri_hidden -= 3;
1321                         }
1322                         gpumat->polys[fc[mati].i_hidden--] = i;
1323                 }
1324                 else {
1325                         for (j = 0; j < tottri; j++, lt++) {
1326                                 start = gpumat->start + fc[mati].i_tri_visible;
1327                                 /* v1 v2 v3 */
1328                                 varray[start++] = lt->tri[0];
1329                                 varray[start++] = lt->tri[1];
1330                                 varray[start++] = lt->tri[2];
1331                                 fc[mati].i_tri_visible += 3;
1332                         }
1333                         gpumat->polys[fc[mati].i_visible++] = i;
1334                 }
1335         }
1336
1337         /* set the visible polygons */
1338         for (i = 0; i < gpu_totmat; i++) {
1339                 gpumaterials[i].totvisiblepolys = fc[i].i_visible;
1340         }
1341
1342         MEM_freeN(fc);
1343 }
1344
1345 static void cdDM_buffer_copy_vertex(
1346         DerivedMesh *dm, float *varray)
1347 {
1348         const MVert *mvert;
1349         const MPoly *mpoly;
1350         const MLoop *mloop;
1351
1352         int i, j, start, totpoly;
1353
1354         mvert = dm->getVertArray(dm);
1355         mpoly = dm->getPolyArray(dm);
1356         mloop = dm->getLoopArray(dm);
1357         totpoly = dm->getNumPolys(dm);
1358
1359         start = 0;
1360
1361         for (i = 0; i < totpoly; i++, mpoly++) {
1362                 for (j = 0; j < mpoly->totloop; j++) {
1363                         copy_v3_v3(&varray[start], mvert[mloop[mpoly->loopstart + j].v].co);
1364                         start += 3;
1365                 }
1366         }
1367
1368         /* copy loose points */
1369         j = dm->drawObject->tot_loop_verts * 3;
1370         for (i = 0; i < dm->drawObject->totvert; i++) {
1371                 if (dm->drawObject->vert_points[i].point_index >= dm->drawObject->tot_loop_verts) {
1372                         copy_v3_v3(&varray[j], mvert[i].co);
1373                         j += 3;
1374                 }
1375         }
1376 }
1377
1378 static void cdDM_buffer_copy_normal(
1379         DerivedMesh *dm, short *varray)
1380 {
1381         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
1382         int i, j, totpoly;
1383         int start;
1384
1385         const float (*nors)[3] = dm->getPolyDataArray(dm, CD_NORMAL);
1386         const float (*lnors)[3] = dm->getLoopDataArray(dm, CD_NORMAL);
1387
1388         const MVert *mvert;
1389         const MPoly *mpoly;
1390         const MLoop *mloop;
1391
1392         mvert = dm->getVertArray(dm);
1393         mpoly = dm->getPolyArray(dm);
1394         mloop = dm->getLoopArray(dm);
1395         totpoly = dm->getNumPolys(dm);
1396
1397         /* we are in sculpt mode, disable loop normals (since they won't get updated) */
1398         if (cddm->pbvh)
1399                 lnors = NULL;
1400
1401         start = 0;
1402         for (i = 0; i < totpoly; i++, mpoly++) {
1403                 const bool smoothnormal = (mpoly->flag & ME_SMOOTH) != 0;
1404
1405                 if (lnors) {
1406                         /* Copy loop normals */
1407                         for (j = 0; j < mpoly->totloop; j++, start += 4) {
1408                                 normal_float_to_short_v3(&varray[start], lnors[mpoly->loopstart + j]);
1409                         }
1410                 }
1411                 else if (smoothnormal) {
1412                         /* Copy vertex normal */
1413                         for (j = 0; j < mpoly->totloop; j++, start += 4) {
1414                                 copy_v3_v3_short(&varray[start], mvert[mloop[mpoly->loopstart + j].v].no);
1415                         }
1416                 }
1417                 else {
1418                         /* Copy cached OR calculated face normal */
1419                         short f_no_s[3];
1420
1421                         if (nors) {
1422                                 normal_float_to_short_v3(f_no_s, nors[i]);
1423                         }
1424                         else {
1425                                 float f_no[3];
1426                                 BKE_mesh_calc_poly_normal(mpoly, &mloop[mpoly->loopstart], mvert, f_no);
1427                                 normal_float_to_short_v3(f_no_s, f_no);
1428                         }
1429
1430                         for (j = 0; j < mpoly->totloop; j++, start += 4) {
1431                                 copy_v3_v3_short(&varray[start], f_no_s);
1432                         }
1433                 }
1434         }
1435 }
1436
1437 static void cdDM_buffer_copy_uv(
1438         DerivedMesh *dm, float *varray)
1439 {
1440         int i, j, totpoly;
1441         int start;
1442
1443         const MPoly *mpoly;
1444         const MLoopUV *mloopuv;
1445
1446         if ((mloopuv = DM_get_loop_data_layer(dm, CD_MLOOPUV)) == NULL) {
1447                 return;
1448         }
1449
1450         mpoly = dm->getPolyArray(dm);
1451         totpoly = dm->getNumPolys(dm);
1452
1453         start = 0;
1454         for (i = 0; i < totpoly; i++, mpoly++) {
1455                 for (j = 0; j < mpoly->totloop; j++) {
1456                         copy_v2_v2(&varray[start], mloopuv[mpoly->loopstart + j].uv);
1457                         start += 2;
1458                 }
1459         }
1460 }
1461
1462 static void cdDM_buffer_copy_uv_texpaint(
1463         DerivedMesh *dm, float *varray)
1464 {
1465         int i, j, totpoly;
1466         int start;
1467
1468         const MPoly *mpoly;
1469
1470         int totmaterial = dm->totmat;
1471         const MLoopUV **uv_base;
1472         const MLoopUV  *uv_stencil_base;
1473         int stencil;
1474
1475         totpoly = dm->getNumPolys(dm);
1476
1477         /* should have been checked for before, reassert */
1478         BLI_assert(DM_get_loop_data_layer(dm, CD_MLOOPUV));
1479         uv_base = MEM_mallocN(totmaterial * sizeof(*uv_base), "texslots");
1480
1481         for (i = 0; i < totmaterial; i++) {
1482                 uv_base[i] = DM_paint_uvlayer_active_get(dm, i);
1483         }
1484
1485         stencil = CustomData_get_stencil_layer(&dm->loopData, CD_MLOOPUV);
1486         uv_stencil_base = CustomData_get_layer_n(&dm->loopData, CD_MLOOPUV, stencil);
1487
1488         mpoly = dm->getPolyArray(dm);
1489         start = 0;
1490
1491         for (i = 0; i < totpoly; i++, mpoly++) {
1492                 int mat_i = mpoly->mat_nr;
1493
1494                 for (j = 0; j < mpoly->totloop; j++) {
1495                         copy_v2_v2(&varray[start], uv_base[mat_i][mpoly->loopstart + j].uv);
1496                         copy_v2_v2(&varray[start + 2], uv_stencil_base[mpoly->loopstart + j].uv);
1497                         start += 4;
1498                 }
1499         }
1500
1501         MEM_freeN((void *)uv_base);
1502 }
1503
1504 /* treat varray_ as an array of MCol, four MCol's per face */
1505 static void cdDM_buffer_copy_mcol(
1506         DerivedMesh *dm, unsigned char *varray,
1507         const void *user_data)
1508 {
1509         int i, j, totpoly;
1510         int start;
1511
1512         const MLoopCol *mloopcol = user_data;
1513         const MPoly *mpoly = dm->getPolyArray(dm);
1514
1515         totpoly = dm->getNumPolys(dm);
1516
1517         start = 0;
1518
1519         for (i = 0; i < totpoly; i++, mpoly++) {
1520                 for (j = 0; j < mpoly->totloop; j++) {
1521                         copy_v3_v3_uchar(&varray[start], &mloopcol[mpoly->loopstart + j].r);
1522                         start += 3;
1523                 }
1524         }
1525 }
1526
1527 static void cdDM_buffer_copy_edge(
1528         DerivedMesh *dm, unsigned int *varray)
1529 {
1530         MEdge *medge, *medge_base;
1531         int i, totedge, iloose, inorm, iloosehidden, inormhidden;
1532         int tot_loose_hidden = 0, tot_loose = 0;
1533         int tot_hidden = 0, tot = 0;
1534
1535         medge_base = medge = dm->getEdgeArray(dm);
1536         totedge = dm->getNumEdges(dm);
1537
1538         for (i = 0; i < totedge; i++, medge++) {
1539                 if (medge->flag & ME_EDGEDRAW) {
1540                         if (medge->flag & ME_LOOSEEDGE) tot_loose++;
1541                         else tot++;
1542                 }
1543                 else {
1544                         if (medge->flag & ME_LOOSEEDGE) tot_loose_hidden++;
1545                         else tot_hidden++;
1546                 }
1547         }
1548
1549         inorm = 0;
1550         inormhidden = tot;
1551         iloose = tot + tot_hidden;
1552         iloosehidden = iloose + tot_loose;
1553
1554         medge = medge_base;
1555         for (i = 0; i < totedge; i++, medge++) {
1556                 if (medge->flag & ME_EDGEDRAW) {
1557                         if (medge->flag & ME_LOOSEEDGE) {
1558                                 varray[iloose * 2] = dm->drawObject->vert_points[medge->v1].point_index;
1559                                 varray[iloose * 2 + 1] = dm->drawObject->vert_points[medge->v2].point_index;
1560                                 iloose++;
1561                         }
1562                         else {
1563                                 varray[inorm * 2] = dm->drawObject->vert_points[medge->v1].point_index;
1564                                 varray[inorm * 2 + 1] = dm->drawObject->vert_points[medge->v2].point_index;
1565                                 inorm++;
1566                         }
1567                 }
1568                 else {
1569                         if (medge->flag & ME_LOOSEEDGE) {
1570                                 varray[iloosehidden * 2] = dm->drawObject->vert_points[medge->v1].point_index;
1571                                 varray[iloosehidden * 2 + 1] = dm->drawObject->vert_points[medge->v2].point_index;
1572                                 iloosehidden++;
1573                         }
1574                         else {
1575                                 varray[inormhidden * 2] = dm->drawObject->vert_points[medge->v1].point_index;
1576                                 varray[inormhidden * 2 + 1] = dm->drawObject->vert_points[medge->v2].point_index;
1577                                 inormhidden++;
1578                         }
1579                 }
1580         }
1581
1582         dm->drawObject->tot_loose_edge_drawn = tot_loose;
1583         dm->drawObject->loose_edge_offset = tot + tot_hidden;
1584         dm->drawObject->tot_edge_drawn = tot;
1585 }
1586
1587 static void cdDM_buffer_copy_uvedge(
1588         DerivedMesh *dm, float *varray)
1589 {
1590         int i, j, totpoly;
1591         int start;
1592         const MLoopUV *mloopuv;
1593         const MPoly *mpoly = dm->getPolyArray(dm);
1594
1595         if ((mloopuv = DM_get_loop_data_layer(dm, CD_MLOOPUV)) == NULL) {
1596                 return;
1597         }
1598
1599         totpoly = dm->getNumPolys(dm);
1600         start = 0;
1601
1602         for (i = 0; i < totpoly; i++, mpoly++) {
1603                 for (j = 0; j < mpoly->totloop; j++) {
1604                         copy_v2_v2(&varray[start], mloopuv[mpoly->loopstart + j].uv);
1605                         copy_v2_v2(&varray[start + 2], mloopuv[mpoly->loopstart + (j + 1) % mpoly->totloop].uv);
1606                         start += 4;
1607                 }
1608         }
1609 }
1610
1611 static void cdDM_copy_gpu_data(
1612         DerivedMesh *dm, int type, void *varray_p,
1613         const int *mat_orig_to_new, const void *user_data)
1614 {
1615         /* 'varray_p' cast is redundant but include for self-documentation */
1616         switch (type) {
1617                 case GPU_BUFFER_VERTEX:
1618                         cdDM_buffer_copy_vertex(dm, (float *)varray_p);
1619                         break;
1620                 case GPU_BUFFER_NORMAL:
1621                         cdDM_buffer_copy_normal(dm, (short *)varray_p);
1622                         break;
1623                 case GPU_BUFFER_COLOR:
1624                         cdDM_buffer_copy_mcol(dm, (unsigned char *)varray_p, user_data);
1625                         break;
1626                 case GPU_BUFFER_UV:
1627                         cdDM_buffer_copy_uv(dm, (float *)varray_p);
1628                         break;
1629                 case GPU_BUFFER_UV_TEXPAINT:
1630                         cdDM_buffer_copy_uv_texpaint(dm, (float *)varray_p);
1631                         break;
1632                 case GPU_BUFFER_EDGE:
1633                         cdDM_buffer_copy_edge(dm, (unsigned int *)varray_p);
1634                         break;
1635                 case GPU_BUFFER_UVEDGE:
1636                         cdDM_buffer_copy_uvedge(dm, (float *)varray_p);
1637                         break;
1638                 case GPU_BUFFER_TRIANGLES:
1639                         cdDM_buffer_copy_triangles(dm, (unsigned int *)varray_p, mat_orig_to_new);
1640                         break;
1641                 default:
1642                         break;
1643         }
1644 }
1645
1646 /* add a new point to the list of points related to a particular
1647  * vertex */
1648 #ifdef USE_GPU_POINT_LINK
1649
1650 static void cdDM_drawobject_add_vert_point(GPUDrawObject *gdo, int vert_index, int point_index)
1651 {
1652         GPUVertPointLink *lnk;
1653
1654         lnk = &gdo->vert_points[vert_index];
1655
1656         /* if first link is in use, add a new link at the end */
1657         if (lnk->point_index != -1) {
1658                 /* get last link */
1659                 for (; lnk->next; lnk = lnk->next) ;
1660
1661                 /* add a new link from the pool */
1662                 lnk = lnk->next = &gdo->vert_points_mem[gdo->vert_points_usage];
1663                 gdo->vert_points_usage++;
1664         }
1665
1666         lnk->point_index = point_index;
1667 }
1668
1669 #else
1670
1671 static void cdDM_drawobject_add_vert_point(GPUDrawObject *gdo, int vert_index, int point_index)
1672 {
1673         GPUVertPointLink *lnk;
1674         lnk = &gdo->vert_points[vert_index];
1675         if (lnk->point_index == -1) {
1676                 lnk->point_index = point_index;
1677         }
1678 }
1679
1680 #endif  /* USE_GPU_POINT_LINK */
1681
1682 /* for each vertex, build a list of points related to it; these lists
1683  * are stored in an array sized to the number of vertices */
1684 static void cdDM_drawobject_init_vert_points(
1685         GPUDrawObject *gdo,
1686         const MPoly *mpoly, const MLoop *mloop,
1687         int tot_poly)
1688 {
1689         int i;
1690         int tot_loops = 0;
1691
1692         /* allocate the array and space for links */
1693         gdo->vert_points = MEM_mallocN(sizeof(GPUVertPointLink) * gdo->totvert,
1694                                        "GPUDrawObject.vert_points");
1695 #ifdef USE_GPU_POINT_LINK
1696         gdo->vert_points_mem = MEM_callocN(sizeof(GPUVertPointLink) * gdo->totvert,
1697                                            "GPUDrawObject.vert_points_mem");
1698         gdo->vert_points_usage = 0;
1699 #endif
1700
1701         /* -1 indicates the link is not yet used */
1702         for (i = 0; i < gdo->totvert; i++) {
1703 #ifdef USE_GPU_POINT_LINK
1704                 gdo->vert_points[i].link = NULL;
1705 #endif
1706                 gdo->vert_points[i].point_index = -1;
1707         }
1708
1709         for (i = 0; i < tot_poly; i++) {
1710                 int j;
1711                 const MPoly *mp = &mpoly[i];
1712
1713                 /* assign unique indices to vertices of the mesh */
1714                 for (j = 0; j < mp->totloop; j++) {
1715                         cdDM_drawobject_add_vert_point(gdo, mloop[mp->loopstart + j].v, tot_loops + j);
1716                 }
1717                 tot_loops += mp->totloop;
1718         }
1719
1720         /* map any unused vertices to loose points */
1721         for (i = 0; i < gdo->totvert; i++) {
1722                 if (gdo->vert_points[i].point_index == -1) {
1723                         gdo->vert_points[i].point_index = gdo->tot_loop_verts + gdo->tot_loose_point;
1724                         gdo->tot_loose_point++;
1725                 }
1726         }
1727 }
1728
1729 /* see GPUDrawObject's structure definition for a description of the
1730  * data being initialized here */
1731 static GPUDrawObject *cdDM_GPUobject_new(DerivedMesh *dm)
1732 {
1733         GPUDrawObject *gdo;
1734         const MPoly *mpoly;
1735         const MLoop *mloop;
1736         const short dm_totmat = dm->totmat;
1737         GPUBufferMaterial *mat_info;
1738         int i, totloops, totpolys;
1739
1740         /* object contains at least one material (default included) so zero means uninitialized dm */
1741         BLI_assert(dm_totmat != 0);
1742
1743         mpoly = dm->getPolyArray(dm);
1744         mloop = dm->getLoopArray(dm);
1745
1746         totpolys = dm->getNumPolys(dm);
1747         totloops = dm->getNumLoops(dm);
1748
1749         /* get the number of points used by each material, treating
1750          * each quad as two triangles */
1751         mat_info = MEM_callocN(sizeof(*mat_info) * dm_totmat, "GPU_drawobject_new.mat_orig_to_new");
1752
1753         for (i = 0; i < totpolys; i++) {
1754                 const short mat_nr = ME_MAT_NR_TEST(mpoly[i].mat_nr, dm_totmat);
1755                 mat_info[mat_nr].totpolys++;
1756                 mat_info[mat_nr].totelements += 3 * ME_POLY_TRI_TOT(&mpoly[i]);
1757                 mat_info[mat_nr].totloops += mpoly[i].totloop;
1758         }
1759         /* create the GPUDrawObject */
1760         gdo = MEM_callocN(sizeof(GPUDrawObject), "GPUDrawObject");
1761         gdo->totvert = dm->getNumVerts(dm);
1762         gdo->totedge = dm->getNumEdges(dm);
1763
1764         GPU_buffer_material_finalize(gdo, mat_info, dm_totmat);
1765
1766         gdo->tot_loop_verts = totloops;
1767
1768         /* store total number of points used for triangles */
1769         gdo->tot_triangle_point = poly_to_tri_count(totpolys, totloops) * 3;
1770
1771         cdDM_drawobject_init_vert_points(gdo, mpoly, mloop, totpolys);
1772
1773         return gdo;
1774 }
1775
1776 static void cdDM_foreachMappedVert(
1777         DerivedMesh *dm,
1778         void (*func)(void *userData, int index, const float co[3], const float no_f[3], const short no_s[3]),
1779         void *userData,
1780         DMForeachFlag flag)
1781 {
1782         MVert *mv = CDDM_get_verts(dm);
1783         const int *index = DM_get_vert_data_layer(dm, CD_ORIGINDEX);
1784         int i;
1785
1786         if (index) {
1787                 for (i = 0; i < dm->numVertData; i++, mv++) {
1788                         const short *no = (flag & DM_FOREACH_USE_NORMAL) ? mv->no : NULL;
1789                         const int orig = *index++;
1790                         if (orig == ORIGINDEX_NONE) continue;
1791                         func(userData, orig, mv->co, NULL, no);
1792                 }
1793         }
1794         else {
1795                 for (i = 0; i < dm->numVertData; i++, mv++) {
1796                         const short *no = (flag & DM_FOREACH_USE_NORMAL) ? mv->no : NULL;
1797                         func(userData, i, mv->co, NULL, no);
1798                 }
1799         }
1800 }
1801
1802 static void cdDM_foreachMappedEdge(
1803         DerivedMesh *dm,
1804         void (*func)(void *userData, int index, const float v0co[3], const float v1co[3]),
1805         void *userData)
1806 {
1807         CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
1808         MVert *mv = cddm->mvert;
1809         MEdge *med = cddm->medge;
1810         int i, orig, *index = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
1811
1812         for (i = 0; i < dm->numEdgeData; i++, med++) {
1813                 if (index) {
1814                         orig = *index++;
1815                         if (orig == ORIGINDEX_NONE) continue;
1816                         func(userData, orig, mv[med->v1].co, mv[med->v2].co);
1817                 }
1818                 else
1819                         func(userData, i, mv[med->v1].co, mv[med->v2].co);
1820         }
1821 }
1822
1823 static void cdDM_foreachMappedLoop(
1824         DerivedMesh *dm,
1825         void (*func)(void *userData, int vertex_index, int face_index, const float co[3], const float no[3]),
1826         void *userData,
1827         DMForeachFlag flag)
1828 {
1829         /* We can't use dm->getLoopDataLayout(dm) here, we want to always access dm->loopData, EditDerivedBMesh would
1830          * return loop data from bmesh itself. */
1831         const float (*lnors)[3] = (flag & DM_FOREACH_USE_NORMAL) ? DM_get_loop_data_layer(dm, CD_NORMAL) : NULL;
1832
1833         const MVert *mv = CDDM_get_verts(dm);
1834         const MLoop *ml = CDDM_get_loops(dm);
1835         const MPoly *mp = CDDM_get_polys(dm);
1836         const int *v_index = DM_get_vert_data_layer(dm, CD_ORIGINDEX);
1837         const int *f_index = DM_get_poly_data_layer(dm, CD_ORIGINDEX);
1838         int p_idx, i;
1839
1840         for (p_idx = 0; p_idx < dm->numPolyData; ++p_idx, ++mp) {
1841                 for (i = 0; i < mp->totloop; ++i, ++ml) {
1842                         const int v_idx = v_index ? v_index[ml->v] : ml->v;
1843                         const int f_idx = f_index ? f_index[p_idx] : p_idx;
1844                         const float *no = lnors ? *lnors++ : NULL;
1845                         if (!ELEM(ORIGINDEX_NONE, v_idx, f_idx)) {
1846                                 func(userData, v_idx, f_idx, mv[ml->v].co, no);
1847                         }
1848                 }
1849         }
1850 }
1851
1852 static void cdDM_foreachMappedFaceCenter(
1853         DerivedMesh *dm,
1854         void (*func)(void *userData, int index, const float cent[3], const float no[3]),
1855         void *userData,
1856         DMForeachFlag flag)
1857 {
1858         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
1859         MVert *mvert = cddm->mvert;
1860         MPoly *mp;
1861         MLoop *ml;
1862         int i, orig, *index;
1863
1864         index = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
1865         mp = cddm->mpoly;
1866         for (i = 0; i < dm->numPolyData; i++, mp++) {
1867                 float cent[3];
1868                 float *no, _no[3];
1869
1870                 if (index) {
1871                         orig = *index++;
1872                         if (orig == ORIGINDEX_NONE) continue;
1873                 }
1874                 else {
1875                         orig = i;
1876                 }
1877                 
1878                 ml = &cddm->mloop[mp->loopstart];
1879                 BKE_mesh_calc_poly_center(mp, ml, mvert, cent);
1880
1881                 if (flag & DM_FOREACH_USE_NORMAL) {
1882                         BKE_mesh_calc_poly_normal(mp, ml, mvert, (no = _no));
1883                 }
1884                 else {
1885                         no = NULL;
1886                 }
1887
1888                 func(userData, orig, cent, no);
1889         }
1890
1891 }
1892
1893 void CDDM_recalc_tessellation_ex(DerivedMesh *dm, const bool do_face_nor_cpy)
1894 {
1895         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
1896
1897         dm->numTessFaceData = BKE_mesh_recalc_tessellation(
1898                 &dm->faceData, &dm->loopData, &dm->polyData,
1899                 cddm->mvert,
1900                 dm->numTessFaceData, dm->numLoopData, dm->numPolyData,
1901                 do_face_nor_cpy);
1902
1903         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1904
1905         /* Tessellation recreated faceData, and the active layer indices need to get re-propagated
1906          * from loops and polys to faces */
1907         CustomData_bmesh_update_active_layers(&dm->faceData, &dm->polyData, &dm->loopData);
1908 }
1909
1910 void CDDM_recalc_tessellation(DerivedMesh *dm)
1911 {
1912         CDDM_recalc_tessellation_ex(dm, true);
1913 }
1914
1915 void CDDM_recalc_looptri(DerivedMesh *dm)
1916 {
1917         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
1918         const unsigned int totpoly = dm->numPolyData;
1919         const unsigned int totloop = dm->numLoopData;
1920
1921         DM_ensure_looptri_data(dm);
1922
1923         BKE_mesh_recalc_looptri(
1924                 cddm->mloop, cddm->mpoly,
1925                 cddm->mvert,
1926                 totloop, totpoly,
1927                 cddm->dm.looptris.array);
1928 }
1929
1930 static const MLoopTri *cdDM_getLoopTriArray(DerivedMesh *dm)
1931 {
1932         if (dm->looptris.array) {
1933                 BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num);
1934         }
1935         else {
1936                 dm->recalcLoopTri(dm);
1937
1938                 /* ccdm is an exception here, that recalcLoopTri will fill in the array too  */
1939         }
1940         return dm->looptris.array;
1941 }
1942
1943 static void cdDM_free_internal(CDDerivedMesh *cddm)
1944 {
1945         if (cddm->pmap) MEM_freeN(cddm->pmap);
1946         if (cddm->pmap_mem) MEM_freeN(cddm->pmap_mem);
1947 }
1948
1949 static void cdDM_release(DerivedMesh *dm)
1950 {
1951         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
1952
1953         if (DM_release(dm)) {
1954                 cdDM_free_internal(cddm);
1955                 MEM_freeN(cddm);
1956         }
1957 }
1958
1959 /**************** CDDM interface functions ****************/
1960 static CDDerivedMesh *cdDM_create(const char *desc)
1961 {
1962         CDDerivedMesh *cddm;
1963         DerivedMesh *dm;
1964
1965         cddm = MEM_callocN(sizeof(*cddm), desc);
1966         dm = &cddm->dm;
1967
1968         dm->getMinMax = cdDM_getMinMax;
1969
1970         dm->getNumVerts = cdDM_getNumVerts;
1971         dm->getNumEdges = cdDM_getNumEdges;
1972         dm->getNumTessFaces = cdDM_getNumTessFaces;
1973         dm->getNumLoops = cdDM_getNumLoops;
1974         dm->getNumPolys = cdDM_getNumPolys;
1975
1976         dm->getVert = cdDM_getVert;
1977         dm->getEdge = cdDM_getEdge;
1978         dm->getTessFace = cdDM_getTessFace;
1979
1980         dm->copyVertArray = cdDM_copyVertArray;
1981         dm->copyEdgeArray = cdDM_copyEdgeArray;
1982         dm->copyTessFaceArray = cdDM_copyTessFaceArray;
1983         dm->copyLoopArray = cdDM_copyLoopArray;
1984         dm->copyPolyArray = cdDM_copyPolyArray;
1985
1986         dm->getVertData = DM_get_vert_data;
1987         dm->getEdgeData = DM_get_edge_data;
1988         dm->getTessFaceData = DM_get_tessface_data;
1989         dm->getVertDataArray = DM_get_vert_data_layer;
1990         dm->getEdgeDataArray = DM_get_edge_data_layer;
1991         dm->getTessFaceDataArray = DM_get_tessface_data_layer;
1992
1993         dm->getLoopTriArray = cdDM_getLoopTriArray;
1994
1995         dm->calcNormals = CDDM_calc_normals;
1996         dm->calcLoopNormals = CDDM_calc_loop_normals;
1997         dm->calcLoopNormalsSpaceArray = CDDM_calc_loop_normals_spacearr;
1998         dm->calcLoopTangents = DM_calc_loop_tangents;
1999         dm->recalcTessellation = CDDM_recalc_tessellation;
2000         dm->recalcLoopTri = CDDM_recalc_looptri;
2001
2002         dm->getVertCos = cdDM_getVertCos;
2003         dm->getVertCo = cdDM_getVertCo;
2004         dm->getVertNo = cdDM_getVertNo;
2005
2006         dm->getPBVH = cdDM_getPBVH;
2007         dm->getPolyMap = cdDM_getPolyMap;
2008
2009         dm->drawVerts = cdDM_drawVerts;
2010
2011         dm->drawUVEdges = cdDM_drawUVEdges;
2012         dm->drawEdges = cdDM_drawEdges;
2013         dm->drawLooseEdges = cdDM_drawLooseEdges;
2014         dm->drawMappedEdges = cdDM_drawMappedEdges;
2015
2016         dm->drawFacesSolid = cdDM_drawFacesSolid;
2017         dm->drawFacesTex = cdDM_drawFacesTex;
2018         dm->drawFacesGLSL = cdDM_drawFacesGLSL;
2019         dm->drawMappedFaces = cdDM_drawMappedFaces;
2020         dm->drawMappedFacesTex = cdDM_drawMappedFacesTex;
2021         dm->drawMappedFacesGLSL = cdDM_drawMappedFacesGLSL;
2022         dm->drawMappedFacesMat = cdDM_drawMappedFacesMat;
2023
2024         dm->gpuObjectNew = cdDM_GPUobject_new;
2025         dm->copy_gpu_data = cdDM_copy_gpu_data;
2026
2027         dm->foreachMappedVert = cdDM_foreachMappedVert;
2028         dm->foreachMappedEdge = cdDM_foreachMappedEdge;
2029         dm->foreachMappedLoop = cdDM_foreachMappedLoop;
2030         dm->foreachMappedFaceCenter = cdDM_foreachMappedFaceCenter;
2031
2032         dm->release = cdDM_release;
2033
2034         return cddm;
2035 }
2036
2037 DerivedMesh *CDDM_new(int numVerts, int numEdges, int numTessFaces, int numLoops, int numPolys)
2038 {
2039         CDDerivedMesh *cddm = cdDM_create("CDDM_new dm");
2040         DerivedMesh *dm = &cddm->dm;
2041
2042         DM_init(dm, DM_TYPE_CDDM, numVerts, numEdges, numTessFaces, numLoops, numPolys);
2043
2044         CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts);
2045         CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
2046         CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numTessFaces);
2047         CustomData_add_layer(&dm->polyData, CD_ORIGINDEX, CD_CALLOC, NULL, numPolys);
2048
2049         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
2050         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
2051         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numTessFaces);
2052         CustomData_add_layer(&dm->loopData, CD_MLOOP, CD_CALLOC, NULL, numLoops);
2053         CustomData_add_layer(&dm->polyData, CD_MPOLY, CD_CALLOC, NULL, numPolys);
2054
2055         cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
2056         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
2057         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
2058         cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
2059         cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
2060
2061         return dm;
2062 }
2063
2064 DerivedMesh *CDDM_from_mesh(Mesh *mesh)
2065 {
2066         CDDerivedMesh *cddm = cdDM_create(__func__);
2067         DerivedMesh *dm = &cddm->dm;
2068         CustomDataMask mask = CD_MASK_MESH & (~CD_MASK_MDISPS);
2069         int alloctype;
2070
2071         /* this does a referenced copy, with an exception for fluidsim */
2072
2073         DM_init(dm, DM_TYPE_CDDM, mesh->totvert, mesh->totedge, 0 /* mesh->totface */,
2074                 mesh->totloop, mesh->totpoly);
2075
2076         dm->deformedOnly = 1;
2077         dm->cd_flag = mesh->cd_flag;
2078
2079         alloctype = CD_REFERENCE;
2080
2081         CustomData_merge(&mesh->vdata, &dm->vertData, mask, alloctype,
2082                          mesh->totvert);
2083         CustomData_merge(&mesh->edata, &dm->edgeData, mask, alloctype,
2084                          mesh->totedge);
2085         CustomData_merge(&mesh->fdata, &dm->faceData, mask | CD_MASK_ORIGINDEX, alloctype,
2086                          0 /* mesh->totface */);
2087         CustomData_merge(&mesh->ldata, &dm->loopData, mask, alloctype,
2088                          mesh->totloop);
2089         CustomData_merge(&mesh->pdata, &dm->polyData, mask, alloctype,
2090                          mesh->totpoly);
2091
2092         cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
2093         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
2094         cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
2095         cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
2096 #if 0
2097         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
2098 #else
2099         cddm->mface = NULL;
2100 #endif
2101
2102         /* commented since even when CD_ORIGINDEX was first added this line fails
2103          * on the default cube, (after editmode toggle too) - campbell */
2104 #if 0
2105         BLI_assert(CustomData_has_layer(&cddm->dm.faceData, CD_ORIGINDEX));
2106 #endif
2107
2108         return dm;
2109 }
2110
2111 DerivedMesh *CDDM_from_curve(Object *ob)
2112 {
2113         ListBase disp = {NULL, NULL};
2114
2115         if (ob->curve_cache) {
2116                 disp = ob->curve_cache->disp;
2117         }
2118
2119         return CDDM_from_curve_displist(ob, &disp);
2120 }
2121
2122 DerivedMesh *CDDM_from_curve_displist(Object *ob, ListBase *dispbase)
2123 {
2124         Curve *cu = (Curve *) ob->data;
2125         DerivedMesh *dm;
2126         CDDerivedMesh *cddm;
2127         MVert *allvert;
2128         MEdge *alledge;
2129         MLoop *allloop;
2130         MPoly *allpoly;
2131         MLoopUV *alluv = NULL;
2132         int totvert, totedge, totloop, totpoly;
2133         bool use_orco_uv = (cu->flag & CU_UV_ORCO) != 0;
2134
2135         if (BKE_mesh_nurbs_displist_to_mdata(
2136                 ob, dispbase, &allvert, &totvert, &alledge,
2137                 &totedge, &allloop, &allpoly, (use_orco_uv) ? &alluv : NULL,
2138                 &totloop, &totpoly) != 0)
2139         {
2140                 /* Error initializing mdata. This often happens when curve is empty */
2141                 return CDDM_new(0, 0, 0, 0, 0);
2142         }
2143
2144         dm = CDDM_new(totvert, totedge, 0, totloop, totpoly);
2145         dm->deformedOnly = 1;
2146         dm->dirty |= DM_DIRTY_NORMALS;
2147
2148         cddm = (CDDerivedMesh *)dm;
2149
2150         memcpy(cddm->mvert, allvert, totvert * sizeof(MVert));
2151         memcpy(cddm->medge, alledge, totedge * sizeof(MEdge));
2152         memcpy(cddm->mloop, allloop, totloop * sizeof(MLoop));
2153         memcpy(cddm->mpoly, allpoly, totpoly * sizeof(MPoly));
2154
2155         if (alluv) {
2156                 const char *uvname = "Orco";
2157                 CustomData_add_layer_named(&cddm->dm.polyData, CD_MTEXPOLY, CD_DEFAULT, NULL, totpoly, uvname);
2158                 CustomData_add_layer_named(&cddm->dm.loopData, CD_MLOOPUV, CD_ASSIGN, alluv, totloop, uvname);
2159         }
2160
2161         MEM_freeN(allvert);
2162         MEM_freeN(alledge);
2163         MEM_freeN(allloop);
2164         MEM_freeN(allpoly);
2165
2166         return dm;
2167 }
2168
2169 static void loops_to_customdata_corners(
2170         BMesh *bm, CustomData *facedata,
2171         int cdindex, const BMLoop *l3[3],
2172         int numCol, int numTex)
2173 {
2174         const BMLoop *l;
2175         BMFace *f = l3[0]->f;
2176         MTFace *texface;
2177         MTexPoly *texpoly;
2178         MCol *mcol;
2179         MLoopCol *mloopcol;
2180         MLoopUV *mloopuv;
2181         int i, j, hasPCol = CustomData_has_layer(&bm->ldata, CD_PREVIEW_MLOOPCOL);
2182
2183         for (i = 0; i < numTex; i++) {
2184                 texface = CustomData_get_n(facedata, CD_MTFACE, cdindex, i);
2185                 texpoly = CustomData_bmesh_get_n(&bm->pdata, f->head.data, CD_MTEXPOLY, i);
2186                 
2187                 ME_MTEXFACE_CPY(texface, texpoly);
2188         
2189                 for (j = 0; j < 3; j++) {
2190                         l = l3[j];
2191                         mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_MLOOPUV, i);
2192                         copy_v2_v2(texface->uv[j], mloopuv->uv);
2193                 }
2194         }
2195
2196         for (i = 0; i < numCol; i++) {
2197                 mcol = CustomData_get_n(facedata, CD_MCOL, cdindex, i);
2198                 
2199                 for (j = 0; j < 3; j++) {
2200                         l = l3[j];
2201                         mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_MLOOPCOL, i);
2202                         MESH_MLOOPCOL_TO_MCOL(mloopcol, &mcol[j]);
2203                 }
2204         }
2205
2206         if (hasPCol) {
2207                 mcol = CustomData_get(facedata, cdindex, CD_PREVIEW_MCOL);
2208
2209                 for (j = 0; j < 3; j++) {
2210                         l = l3[j];
2211                         mloopcol = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PREVIEW_MLOOPCOL);
2212                         MESH_MLOOPCOL_TO_MCOL(mloopcol, &mcol[j]);
2213                 }
2214         }
2215 }
2216
2217 /* used for both editbmesh and bmesh */
2218 static DerivedMesh *cddm_from_bmesh_ex(
2219         struct BMesh *bm, const bool use_mdisps,
2220         /* EditBMesh vars for use_tessface */
2221         const bool use_tessface,
2222         const int em_tottri, const BMLoop *(*em_looptris)[3])
2223 {
2224         DerivedMesh *dm = CDDM_new(bm->totvert,
2225                                    bm->totedge,
2226                                    use_tessface ? em_tottri : 0,
2227                                    bm->totloop,
2228                                    bm->totface);
2229
2230         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2231         BMIter iter;
2232         BMVert *eve;
2233         BMEdge *eed;
2234         BMFace *efa;
2235         MVert *mvert = cddm->mvert;
2236         MEdge *medge = cddm->medge;
2237         MFace *mface = cddm->mface;
2238         MLoop *mloop = cddm->mloop;
2239         MPoly *mpoly = cddm->mpoly;
2240         int numCol = CustomData_number_of_layers(&bm->ldata, CD_MLOOPCOL);
2241         int numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY);
2242         int *index, add_orig;
2243         CustomDataMask mask;
2244         unsigned int i, j;
2245         
2246         const int cd_vert_bweight_offset = CustomData_get_offset(&bm->vdata, CD_BWEIGHT);
2247         const int cd_edge_bweight_offset = CustomData_get_offset(&bm->edata, CD_BWEIGHT);
2248         const int cd_edge_crease_offset  = CustomData_get_offset(&bm->edata, CD_CREASE);
2249         
2250         dm->deformedOnly = 1;
2251         
2252         /* don't add origindex layer if one already exists */
2253         add_orig = !CustomData_has_layer(&bm->pdata, CD_ORIGINDEX);
2254
2255         mask = use_mdisps ? CD_MASK_DERIVEDMESH | CD_MASK_MDISPS : CD_MASK_DERIVEDMESH;
2256         
2257         /* don't process shapekeys, we only feed them through the modifier stack as needed,
2258          * e.g. for applying modifiers or the like*/
2259         mask &= ~CD_MASK_SHAPEKEY;
2260         CustomData_merge(&bm->vdata, &dm->vertData, mask,
2261                          CD_CALLOC, dm->numVertData);
2262         CustomData_merge(&bm->edata, &dm->edgeData, mask,
2263                          CD_CALLOC, dm->numEdgeData);
2264         CustomData_merge(&bm->ldata, &dm->loopData, mask,
2265                          CD_CALLOC, dm->numLoopData);
2266         CustomData_merge(&bm->pdata, &dm->polyData, mask,
2267                          CD_CALLOC, dm->numPolyData);
2268
2269         /* add tessellation mface layers */
2270         if (use_tessface) {
2271                 CustomData_from_bmeshpoly(&dm->faceData, &dm->polyData, &dm->loopData, em_tottri);
2272         }
2273
2274         index = dm->getVertDataArray(dm, CD_ORIGINDEX);
2275
2276         BM_ITER_MESH_INDEX (eve, &iter, bm, BM_VERTS_OF_MESH, i) {
2277                 MVert *mv = &mvert[i];
2278
2279                 copy_v3_v3(mv->co, eve->co);
2280
2281                 BM_elem_index_set(eve, i); /* set_inline */
2282
2283                 normal_float_to_short_v3(mv->no, eve->no);
2284
2285                 mv->flag = BM_vert_flag_to_mflag(eve);
2286
2287                 if (cd_vert_bweight_offset != -1) mv->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eve, cd_vert_bweight_offset);
2288
2289                 if (add_orig) *index++ = i;
2290
2291                 CustomData_from_bmesh_block(&bm->vdata, &dm->vertData, eve->head.data, i);
2292         }
2293         bm->elem_index_dirty &= ~BM_VERT;
2294
2295         index = dm->getEdgeDataArray(dm, CD_ORIGINDEX);
2296         BM_ITER_MESH_INDEX (eed, &iter, bm, BM_EDGES_OF_MESH, i) {
2297                 MEdge *med = &medge[i];
2298
2299                 BM_elem_index_set(eed, i); /* set_inline */
2300
2301                 med->v1 = BM_elem_index_get(eed->v1);
2302                 med->v2 = BM_elem_index_get(eed->v2);
2303
2304                 med->flag = BM_edge_flag_to_mflag(eed);
2305
2306                 /* handle this differently to editmode switching,
2307                  * only enable draw for single user edges rather then calculating angle */
2308                 if ((med->flag & ME_EDGEDRAW) == 0) {
2309                         if (eed->l && eed->l == eed->l->radial_next) {
2310                                 med->flag |= ME_EDGEDRAW;
2311                         }
2312                 }
2313
2314                 if (cd_edge_crease_offset  != -1) med->crease  = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_crease_offset);
2315                 if (cd_edge_bweight_offset != -1) med->bweight = BM_ELEM_CD_GET_FLOAT_AS_UCHAR(eed, cd_edge_bweight_offset);
2316
2317                 CustomData_from_bmesh_block(&bm->edata, &dm->edgeData, eed->head.data, i);
2318                 if (add_orig) *index++ = i;
2319         }
2320         bm->elem_index_dirty &= ~BM_EDGE;
2321
2322         /* avoid this where possiblem, takes extra memory */
2323         if (use_tessface) {
2324
2325                 BM_mesh_elem_index_ensure(bm, BM_FACE);
2326
2327                 index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
2328                 for (i = 0; i < dm->numTessFaceData; i++) {
2329                         MFace *mf = &mface[i];
2330                         const BMLoop **l = em_looptris[i];
2331                         efa = l[0]->f;
2332
2333                         mf->v1 = BM_elem_index_get(l[0]->v);
2334                         mf->v2 = BM_elem_index_get(l[1]->v);
2335                         mf->v3 = BM_elem_index_get(l[2]->v);
2336                         mf->v4 = 0;
2337                         mf->mat_nr = efa->mat_nr;
2338                         mf->flag = BM_face_flag_to_mflag(efa);
2339
2340                         /* map mfaces to polygons in the same cddm intentionally */
2341                         *index++ = BM_elem_index_get(efa);
2342
2343                         loops_to_customdata_corners(bm, &dm->faceData, i, l, numCol, numTex);
2344                         test_index_face(mf, &dm->faceData, i, 3);
2345                 }
2346         }
2347         
2348         index = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
2349         j = 0;
2350         BM_ITER_MESH_INDEX (efa, &iter, bm, BM_FACES_OF_MESH, i) {
2351                 BMLoop *l_iter;
2352                 BMLoop *l_first;
2353                 MPoly *mp = &mpoly[i];
2354
2355                 BM_elem_index_set(efa, i); /* set_inline */
2356
2357                 mp->totloop = efa->len;
2358                 mp->flag = BM_face_flag_to_mflag(efa);
2359                 mp->loopstart = j;
2360                 mp->mat_nr = efa->mat_nr;
2361
2362                 l_iter = l_first = BM_FACE_FIRST_LOOP(efa);
2363                 do {
2364                         mloop->v = BM_elem_index_get(l_iter->v);
2365                         mloop->e = BM_elem_index_get(l_iter->e);
2366                         CustomData_from_bmesh_block(&bm->ldata, &dm->loopData, l_iter->head.data, j);
2367
2368                         BM_elem_index_set(l_iter, j); /* set_inline */
2369
2370                         j++;
2371                         mloop++;
2372                 } while ((l_iter = l_iter->next) != l_first);
2373
2374                 CustomData_from_bmesh_block(&bm->pdata, &dm->polyData, efa->head.data, i);
2375
2376                 if (add_orig) *index++ = i;
2377         }
2378         bm->elem_index_dirty &= ~(BM_FACE | BM_LOOP);
2379
2380         dm->cd_flag = BM_mesh_cd_flag_from_bmesh(bm);
2381
2382         return dm;
2383 }
2384
2385 struct DerivedMesh *CDDM_from_bmesh(struct BMesh *bm, const bool use_mdisps)
2386 {
2387         return cddm_from_bmesh_ex(
2388                 bm, use_mdisps, false,
2389                 /* these vars are for editmesh only */
2390                 0, NULL);
2391 }
2392
2393 DerivedMesh *CDDM_from_editbmesh(BMEditMesh *em, const bool use_mdisps, const bool use_tessface)
2394 {
2395         return cddm_from_bmesh_ex(
2396                 em->bm, use_mdisps,
2397                 /* editmesh */
2398                 use_tessface, em->tottri, (const BMLoop *(*)[3])em->looptris);
2399 }
2400
2401 static DerivedMesh *cddm_copy_ex(DerivedMesh *source, int faces_from_tessfaces)
2402 {
2403         CDDerivedMesh *cddm = cdDM_create("CDDM_copy cddm");
2404         DerivedMesh *dm = &cddm->dm;
2405         int numVerts = source->numVertData;
2406         int numEdges = source->numEdgeData;
2407         int numTessFaces = source->numTessFaceData;
2408         int numLoops = source->numLoopData;
2409         int numPolys = source->numPolyData;
2410
2411         /* ensure these are created if they are made on demand */
2412         source->getVertDataArray(source, CD_ORIGINDEX);
2413         source->getEdgeDataArray(source, CD_ORIGINDEX);
2414         source->getTessFaceDataArray(source, CD_ORIGINDEX);
2415         source->getPolyDataArray(source, CD_ORIGINDEX);
2416
2417         /* this initializes dm, and copies all non mvert/medge/mface layers */
2418         DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numTessFaces,
2419                          numLoops, numPolys);
2420         dm->deformedOnly = source->deformedOnly;
2421         dm->cd_flag = source->cd_flag;
2422         dm->dirty = source->dirty;
2423
2424         CustomData_copy_data(&source->vertData, &dm->vertData, 0, 0, numVerts);
2425         CustomData_copy_data(&source->edgeData, &dm->edgeData, 0, 0, numEdges);
2426         CustomData_copy_data(&source->faceData, &dm->faceData, 0, 0, numTessFaces);
2427
2428         /* now add mvert/medge/mface layers */
2429         cddm->mvert = source->dupVertArray(source);
2430         cddm->medge = source->dupEdgeArray(source);
2431         cddm->mface = source->dupTessFaceArray(source);
2432
2433         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_ASSIGN, cddm->mvert, numVerts);
2434         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_ASSIGN, cddm->medge, numEdges);
2435         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_ASSIGN, cddm->mface, numTessFaces);
2436         
2437         if (!faces_from_tessfaces)
2438                 DM_DupPolys(source, dm);
2439         else
2440                 CDDM_tessfaces_to_faces(dm);
2441
2442         cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
2443         cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
2444
2445         return dm;
2446 }
2447
2448 DerivedMesh *CDDM_copy(DerivedMesh *source)
2449 {
2450         return cddm_copy_ex(source, 0);
2451 }
2452
2453 DerivedMesh *CDDM_copy_from_tessface(DerivedMesh *source)
2454 {
2455         return cddm_copy_ex(source, 1);
2456 }
2457
2458 /* note, the CD_ORIGINDEX layers are all 0, so if there is a direct
2459  * relationship between mesh data this needs to be set by the caller. */
2460 DerivedMesh *CDDM_from_template_ex(
2461         DerivedMesh *source,
2462         int numVerts, int numEdges, int numTessFaces,
2463         int numLoops, int numPolys,
2464         CustomDataMask mask)
2465 {
2466         CDDerivedMesh *cddm = cdDM_create("CDDM_from_template dest");
2467         DerivedMesh *dm = &cddm->dm;
2468
2469         /* ensure these are created if they are made on demand */
2470         source->getVertDataArray(source, CD_ORIGINDEX);
2471         source->getEdgeDataArray(source, CD_ORIGINDEX);
2472         source->getTessFaceDataArray(source, CD_ORIGINDEX);
2473         source->getPolyDataArray(source, CD_ORIGINDEX);
2474
2475         /* this does a copy of all non mvert/medge/mface layers */
2476         DM_from_template_ex(
2477                 dm, source, DM_TYPE_CDDM,
2478                 numVerts, numEdges, numTessFaces,
2479                 numLoops, numPolys,
2480                 mask);
2481
2482         /* now add mvert/medge/mface layers */
2483         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
2484         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
2485         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numTessFaces);
2486         CustomData_add_layer(&dm->loopData, CD_MLOOP, CD_CALLOC, NULL, numLoops);
2487         CustomData_add_layer(&dm->polyData, CD_MPOLY, CD_CALLOC, NULL, numPolys);
2488
2489         if (!CustomData_get_layer(&dm->vertData, CD_ORIGINDEX))
2490                 CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts);
2491         if (!CustomData_get_layer(&dm->edgeData, CD_ORIGINDEX))
2492                 CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
2493         if (!CustomData_get_layer(&dm->faceData, CD_ORIGINDEX))
2494                 CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numTessFaces);
2495
2496         cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
2497         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
2498         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
2499         cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
2500         cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
2501
2502         return dm;
2503 }
2504 DerivedMesh *CDDM_from_template(
2505         DerivedMesh *source,
2506         int numVerts, int numEdges, int numTessFaces,
2507         int numLoops, int numPolys)
2508 {
2509         return CDDM_from_template_ex(
2510                 source, numVerts, numEdges, numTessFaces,
2511                 numLoops, numPolys,
2512                 CD_MASK_DERIVEDMESH);
2513 }
2514
2515 void CDDM_apply_vert_coords(DerivedMesh *dm, float (*vertCoords)[3])
2516 {
2517         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2518         MVert *vert;
2519         int i;
2520
2521         /* this will just return the pointer if it wasn't a referenced layer */
2522         vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2523         cddm->mvert = vert;
2524
2525         for (i = 0; i < dm->numVertData; ++i, ++vert)
2526                 copy_v3_v3(vert->co, vertCoords[i]);
2527
2528         cddm->dm.dirty |= DM_DIRTY_NORMALS;
2529 }
2530
2531 void CDDM_apply_vert_normals(DerivedMesh *dm, short (*vertNormals)[3])
2532 {
2533         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2534         MVert *vert;
2535         int i;
2536
2537         /* this will just return the pointer if it wasn't a referenced layer */
2538         vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2539         cddm->mvert = vert;
2540
2541         for (i = 0; i < dm->numVertData; ++i, ++vert)
2542                 copy_v3_v3_short(vert->no, vertNormals[i]);
2543
2544         cddm->dm.dirty &= ~DM_DIRTY_NORMALS;
2545 }
2546
2547 void CDDM_calc_normals_mapping_ex(DerivedMesh *dm, const bool only_face_normals)
2548 {
2549         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2550         float (*face_nors)[3] = NULL;
2551
2552         if (dm->numVertData == 0) {
2553                 cddm->dm.dirty &= ~DM_DIRTY_NORMALS;
2554                 return;
2555         }
2556
2557         /* now we skip calculating vertex normals for referenced layer,
2558          * no need to duplicate verts.
2559          * WATCH THIS, bmesh only change!,
2560          * need to take care of the side effects here - campbell */
2561 #if 0
2562         /* we don't want to overwrite any referenced layers */
2563         cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2564 #endif
2565
2566 #if 0
2567         if (dm->numTessFaceData == 0) {
2568                 /* No tessellation on this mesh yet, need to calculate one.
2569                  *
2570                  * Important not to update face normals from polys since it
2571                  * interferes with assigning the new normal layer in the following code.
2572                  */
2573                 CDDM_recalc_tessellation_ex(dm, false);
2574         }
2575         else {
2576                 /* A tessellation already exists, it should always have a CD_ORIGINDEX */
2577                 BLI_assert(CustomData_has_layer(&dm->faceData, CD_ORIGINDEX));
2578                 CustomData_free_layers(&dm->faceData, CD_NORMAL, dm->numTessFaceData);
2579         }
2580 #endif
2581
2582         face_nors = MEM_mallocN(sizeof(*face_nors) * dm->numPolyData, "face_nors");
2583
2584         /* calculate face normals */
2585         BKE_mesh_calc_normals_poly(
2586                 cddm->mvert, NULL, dm->numVertData, CDDM_get_loops(dm), CDDM_get_polys(dm),
2587                 dm->numLoopData, dm->numPolyData, face_nors,
2588                 only_face_normals);
2589
2590         CustomData_add_layer(&dm->polyData, CD_NORMAL, CD_ASSIGN, face_nors, dm->numPolyData);
2591
2592         cddm->dm.dirty &= ~DM_DIRTY_NORMALS;
2593 }
2594
2595 void CDDM_calc_normals_mapping(DerivedMesh *dm)
2596 {
2597         /* use this to skip calculating normals on original vert's, this may need to be changed */
2598         const bool only_face_normals = CustomData_is_referenced_layer(&dm->vertData, CD_MVERT);
2599
2600         CDDM_calc_normals_mapping_ex(dm, only_face_normals);
2601 }
2602
2603 #if 0
2604 /* bmesh note: this matches what we have in trunk */
2605 void CDDM_calc_normals(DerivedMesh *dm)
2606 {
2607         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2608         float (*poly_nors)[3];
2609
2610         if (dm->numVertData == 0) return;
2611
2612         /* we don't want to overwrite any referenced layers */
2613         cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2614
2615         /* fill in if it exists */
2616         poly_nors = CustomData_get_layer(&dm->polyData, CD_NORMAL);
2617         if (!poly_nors) {
2618                 poly_nors = CustomData_add_layer(&dm->polyData, CD_NORMAL, CD_CALLOC, NULL, dm->numPolyData);
2619         }
2620
2621         BKE_mesh_calc_normals_poly(cddm->mvert, dm->numVertData, CDDM_get_loops(dm), CDDM_get_polys(dm),
2622                                        dm->numLoopData, dm->numPolyData, poly_nors, false);
2623
2624         cddm->dm.dirty &= ~DM_DIRTY_NORMALS;
2625 }
2626 #else
2627
2628 /* poly normal layer is now only for final display */
2629 void CDDM_calc_normals(DerivedMesh *dm)
2630 {
2631         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2632
2633         /* we don't want to overwrite any referenced layers */
2634         cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2635
2636         BKE_mesh_calc_normals_poly(cddm->mvert, NULL, dm->numVertData, CDDM_get_loops(dm), CDDM_get_polys(dm),
2637                                    dm->numLoopData, dm->numPolyData, NULL, false);
2638
2639         cddm->dm.dirty &= ~DM_DIRTY_NORMALS;
2640 }
2641
2642 #endif
2643
2644 void CDDM_calc_loop_normals(DerivedMesh *dm, const bool use_split_normals, const float split_angle)
2645 {
2646         CDDM_calc_loop_normals_spacearr(dm, use_split_normals, split_angle, NULL);
2647 }
2648
2649 /* #define DEBUG_CLNORS */
2650 #ifdef DEBUG_CLNORS
2651 #  include "BLI_linklist.h"
2652 #endif
2653
2654 void CDDM_calc_loop_normals_spacearr(
2655         DerivedMesh *dm, const bool use_split_normals, const float split_angle, MLoopNorSpaceArray *r_lnors_spacearr)
2656 {
2657         MVert *mverts = dm->getVertArray(dm);
2658         MEdge *medges = dm->getEdgeArray(dm);
2659         MLoop *mloops = dm->getLoopArray(dm);
2660         MPoly *mpolys = dm->getPolyArray(dm);
2661
2662         CustomData *ldata, *pdata;
2663
2664         float (*lnors)[3];
2665         short (*clnor_data)[2];
2666         float (*pnors)[3];
2667
2668         const int numVerts = dm->getNumVerts(dm);
2669         const int numEdges = dm->getNumEdges(dm);
2670         const int numLoops = dm->getNumLoops(dm);
2671         const int numPolys = dm->getNumPolys(dm);
2672
2673         ldata = dm->getLoopDataLayout(dm);
2674         if (CustomData_has_layer(ldata, CD_NORMAL)) {
2675                 lnors = CustomData_get_layer(ldata, CD_NORMAL);
2676         }
2677         else {
2678                 lnors = CustomData_add_layer(ldata, CD_NORMAL, CD_CALLOC, NULL, numLoops);
2679         }
2680
2681         /* Compute poly (always needed) and vert normals. */
2682         /* Note we can't use DM_ensure_normals, since it won't keep computed poly nors... */
2683         pdata = dm->getPolyDataLayout(dm);
2684         pnors = CustomData_get_layer(pdata, CD_NORMAL);
2685         if (!pnors) {
2686                 pnors = CustomData_add_layer(pdata, CD_NORMAL, CD_CALLOC, NULL, numPolys);
2687         }
2688         BKE_mesh_calc_normals_poly(mverts, NULL, numVerts, mloops, mpolys, numLoops, numPolys, pnors,
2689                                    (dm->dirty & DM_DIRTY_NORMALS) ? false : true);
2690
2691         dm->dirty &= ~DM_DIRTY_NORMALS;
2692
2693         clnor_data = CustomData_get_layer(ldata, CD_CUSTOMLOOPNORMAL);
2694
2695         BKE_mesh_normals_loop_split(mverts, numVerts, medges, numEdges, mloops, lnors, numLoops,
2696                                     mpolys, (const float (*)[3])pnors, numPolys,
2697                                     use_split_normals, split_angle,
2698                                     r_lnors_spacearr, clnor_data, NULL);
2699 #ifdef DEBUG_CLNORS
2700         if (r_lnors_spacearr) {
2701                 int i;
2702                 for (i = 0; i < numLoops; i++) {
2703                         if (r_lnors_spacearr->lspacearr[i]->ref_alpha != 0.0f) {
2704                                 LinkNode *loops = r_lnors_spacearr->lspacearr[i]->loops;
2705                                 printf("Loop %d uses lnor space %p:\n", i, r_lnors_spacearr->lspacearr[i]);
2706                                 print_v3("\tfinal lnor", lnors[i]);
2707                                 print_v3("\tauto lnor", r_lnors_spacearr->lspacearr[i]->vec_lnor);
2708                                 print_v3("\tref_vec", r_lnors_spacearr->lspacearr[i]->vec_ref);
2709                                 printf("\talpha: %f\n\tbeta: %f\n\tloops: %p\n", r_lnors_spacearr->lspacearr[i]->ref_alpha,
2710                                        r_lnors_spacearr->lspacearr[i]->ref_beta, r_lnors_spacearr->lspacearr[i]->loops);
2711                                 printf("\t\t(shared with loops");
2712                                 while (loops) {
2713                                         printf(" %d", GET_INT_FROM_POINTER(loops->link));
2714                                         loops = loops->next;
2715                                 }
2716                                 printf(")\n");
2717                         }
2718                         else {
2719                                 printf("Loop %d has no lnor space\n", i);
2720                         }
2721                 }
2722         }
2723 #endif
2724 }
2725
2726
2727 void CDDM_calc_normals_tessface(DerivedMesh *dm)
2728 {
2729         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2730         float (*face_nors)[3];
2731
2732         if (dm->numVertData == 0) return;
2733
2734         /* we don't want to overwrite any referenced layers */
2735         cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2736
2737         /* fill in if it exists */
2738         face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL);
2739         if (!face_nors) {
2740                 face_nors = CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_CALLOC, NULL, dm->numTessFaceData);
2741         }
2742
2743         BKE_mesh_calc_normals_tessface(cddm->mvert, dm->numVertData,
2744                                        cddm->mface, dm->numTessFaceData, face_nors);
2745
2746         cddm->dm.dirty &= ~DM_DIRTY_NORMALS;
2747 }
2748
2749 #if 1
2750
2751 /**
2752  * Poly compare with vtargetmap
2753  * Function used by #CDDM_merge_verts.
2754  * The function compares poly_source after applying vtargetmap, with poly_target.
2755  * The two polys are identical if they share the same vertices in the same order, or in reverse order,
2756  * but starting position loopstart may be different.
2757  * The function is called with direct_reverse=1 for same order (i.e. same normal),
2758  * and may be called again with direct_reverse=-1 for reverse order.
2759  * \return 1 if polys are identical,  0 if polys are different.
2760  */
2761 static int cddm_poly_compare(
2762         MLoop *mloop_array,
2763         MPoly *mpoly_source, MPoly *mpoly_target,
2764         const int *vtargetmap, const int direct_reverse)
2765 {
2766         int vert_source, first_vert_source, vert_target;
2767         int i_loop_source;
2768         int i_loop_target, i_loop_target_start, i_loop_target_offset, i_loop_target_adjusted;
2769         bool compare_completed = false;
2770         bool same_loops = false;
2771
2772         MLoop *mloop_source, *mloop_target;
2773
2774         BLI_assert(direct_reverse == 1 || direct_reverse == -1);
2775
2776         i_loop_source = 0;
2777         mloop_source = mloop_array + mpoly_source->loopstart;
2778         vert_source = mloop_source->v;
2779
2780         if (vtargetmap[vert_source] != -1) {
2781                 vert_source = vtargetmap[vert_source];
2782         }
2783         else {
2784                 /* All source loop vertices should be mapped */
2785                 BLI_assert(false);
2786         }
2787
2788         /* Find same vertex within mpoly_target's loops */
2789         mloop_target = mloop_array + mpoly_target->loopstart;
2790         for (i_loop_target = 0; i_loop_target < mpoly_target->totloop; i_loop_target++, mloop_target++) {
2791                 if (mloop_target->v == vert_source) {
2792                         break;
2793                 }
2794         }
2795
2796         /* If same vertex not found, then polys cannot be equal */
2797         if (i_loop_target >= mpoly_target->totloop) {
2798                 return false;
2799         }
2800
2801         /* Now mloop_source and m_loop_target have one identical vertex */
2802         /* mloop_source is at position 0, while m_loop_target has advanced to find identical vertex */
2803         /* Go around the loop and check that all vertices match in same order */
2804         /* Skipping source loops when consecutive source vertices are mapped to same target vertex */
2805
2806         i_loop_target_start = i_loop_target;
2807         i_loop_target_offset = 0;
2808         first_vert_source = vert_source;
2809
2810         compare_completed = false;
2811         same_loops = false;
2812
2813         while (!compare_completed) {
2814
2815                 vert_target = mloop_target->v;
2816
2817                 /* First advance i_loop_source, until it points to different vertex, after mapping applied */
2818                 do {
2819                         i_loop_source++;
2820
2821                         if (i_loop_source == mpoly_source->totloop) {
2822                                 /* End of loops for source, must match end of loop for target.  */
2823                                 if (i_loop_target_offset == mpoly_target->totloop - 1) {
2824                                         compare_completed = true;
2825                                         same_loops = true;
2826                                         break;  /* Polys are identical */
2827                                 }
2828                                 else {
2829                                         compare_completed = true;
2830                                         same_loops = false;
2831                                         break;  /* Polys are different */
2832                                 }
2833                         }
2834
2835                         mloop_source++;
2836                         vert_source = mloop_source->v;
2837
2838                         if (vtargetmap[vert_source] != -1) {
2839                                 vert_source = vtargetmap[vert_source];
2840                         }
2841                         else {
2842                                 /* All source loop vertices should be mapped */
2843                                 BLI_assert(false);
2844                         }
2845
2846                 } while (vert_source == vert_target);
2847
2848                 if (compare_completed) {
2849                         break;
2850                 }
2851
2852                 /* Now advance i_loop_target as well */
2853                 i_loop_target_offset++;
2854
2855                 if (i_loop_target_offset == mpoly_target->totloop) {
2856                         /* End of loops for target only, that means no match */
2857                         /* except if all remaining source vertices are mapped to first target */
2858                         for (; i_loop_source < mpoly_source->totloop; i_loop_source++, mloop_source++) {
2859                                 vert_source = vtargetmap[mloop_source->v];
2860                                 if (vert_source != first_vert_source) {
2861                                         compare_completed = true;
2862                                         same_loops = false;
2863                                         break;
2864                                 }
2865                         }
2866                         if (!compare_completed) {
2867                                 same_loops = true;
2868                         }
2869                         break;
2870                 }
2871
2872                 /* Adjust i_loop_target for cycling around and for direct/reverse order defined by delta = +1 or -1 */
2873                 i_loop_target_adjusted = (i_loop_target_start + direct_reverse * i_loop_target_offset) % mpoly_target->totloop;
2874                 if (i_loop_target_adjusted < 0) {
2875                         i_loop_target_adjusted += mpoly_target->totloop;
2876                 }
2877                 mloop_target = mloop_array + mpoly_target->loopstart + i_loop_target_adjusted;
2878                 vert_target = mloop_target->v;
2879
2880                 if (vert_target != vert_source) {
2881                         same_loops = false;  /* Polys are different */
2882                         break;
2883                 }
2884         }
2885         return same_loops;
2886 }
2887
2888 /* Utility stuff for using GHash with polys */
2889
2890 typedef struct PolyKey {
2891         int poly_index;   /* index of the MPoly within the derived mesh */
2892         int totloops;     /* number of loops in the poly */
2893         unsigned int hash_sum;  /* Sum of all vertices indices */
2894         unsigned int hash_xor;  /* Xor of all vertices indices */
2895 } PolyKey;
2896
2897
2898 static unsigned int poly_gset_hash_fn(const void *key)
2899 {
2900         const PolyKey *pk = key;
2901         return pk->hash_sum;
2902 }
2903
2904 static bool poly_gset_compare_fn(const void *k1, const void *k2)
2905 {
2906         const PolyKey *pk1 = k1;
2907         const PolyKey *pk2 = k2;
2908         if ((pk1->hash_sum == pk2->hash_sum) &&
2909             (pk1->hash_xor == pk2->hash_xor) &&
2910             (pk1->totloops == pk2->totloops))
2911         {
2912                 /* Equality - note that this does not mean equality of polys */
2913                 return false;
2914         }
2915         else {
2916                 return true;
2917         }
2918 }
2919
2920 /**
2921  * Merge Verts
2922  *
2923  * This frees dm, and returns a new one.
2924  *
2925  * \param vtargetmap  The table that maps vertices to target vertices.  a value of -1
2926  * indicates a vertex is a target, and is to be kept.
2927  * This array is aligned with 'dm->numVertData'
2928  * \warning \a vtergatmap must **not** contain any chained mapping (v1 -> v2 -> v3 etc.), this is not supported
2929  * and will likely generate corrupted geometry.
2930  *
2931  * \param tot_vtargetmap  The number of non '-1' values in vtargetmap. (not the size)
2932  *
2933  * \param merge_mode enum with two modes.
2934  * - #CDDM_MERGE_VERTS_DUMP_IF_MAPPED
2935  * When called by the Mirror Modifier,
2936  * In this mode it skips any faces that have all vertices merged (to avoid creating pairs
2937  * of faces sharing the same set of vertices)
2938  * - #CDDM_MERGE_VERTS_DUMP_IF_EQUAL
2939  * When called by the Array Modifier,
2940  * In this mode, faces where all vertices are merged are double-checked,
2941  * to see whether all target vertices actually make up a poly already.
2942  * Indeed it could be that all of a poly's vertices are merged,
2943  * but merged to vertices that do not make up a single poly,
2944  * in which case the original poly should not be dumped.
2945  * Actually this later behavior could apply to the Mirror Modifier as well, but the additional checks are
2946  * costly and not necessary in the case of mirror, because each vertex is only merged to its own mirror.
2947  *
2948  * \note #CDDM_recalc_tessellation has to run on the returned DM if you want to access tessfaces.
2949  */
2950 DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap, const int tot_vtargetmap, const int merge_mode)
2951 {
2952 // #define USE_LOOPS
2953         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2954         CDDerivedMesh *cddm2 = NULL;
2955
2956         const int totvert = dm->numVertData;
2957         const int totedge = dm->numEdgeData;
2958         const int totloop = dm->numLoopData;
2959         const int totpoly = dm->numPolyData;
2960
2961         const int totvert_final = totvert - tot_vtargetmap;
2962
2963         MVert *mv, *mvert = MEM_mallocN(sizeof(*mvert) * totvert_final, __func__);
2964         int *oldv         = MEM_mallocN(sizeof(*oldv)  * totvert_final, __func__);
2965         int *newv         = MEM_mallocN(sizeof(*newv)  * totvert, __func__);
2966         STACK_DECLARE(mvert);
2967         STACK_DECLARE(oldv);
2968
2969         MEdge *med, *medge = MEM_mallocN(sizeof(*medge) * totedge, __func__);
2970         int *olde          = MEM_mallocN(sizeof(*olde)  * totedge, __func__);
2971         int *newe          = MEM_mallocN(sizeof(*newe)  * totedge, __func__);
2972         STACK_DECLARE(medge);
2973         STACK_DECLARE(olde);
2974
2975         MLoop *ml, *mloop = MEM_mallocN(sizeof(*mloop) * totloop, __func__);
2976         int *oldl         = MEM_mallocN(sizeof(*oldl)  * totloop, __func__);
2977 #ifdef USE_LOOPS
2978         int newl          = MEM_mallocN(sizeof(*newl)  * totloop, __func__);
2979 #endif
2980         STACK_DECLARE(mloop);
2981         STACK_DECLARE(oldl);
2982
2983         MPoly *mp, *mpoly = MEM_mallocN(sizeof(*medge) * totpoly, __func__);
2984         int *oldp         = MEM_mallocN(sizeof(*oldp)  * totpoly, __func__);
2985         STACK_DECLARE(mpoly);
2986         STACK_DECLARE(oldp);
2987
2988         EdgeHash *ehash = BLI_edgehash_new_ex(__func__, totedge);
2989
2990         int i, j, c;
2991
2992         PolyKey *poly_keys;
2993         GSet *poly_gset = NULL;
2994
2995         STACK_INIT(oldv, totvert_final);
2996         STACK_INIT(olde, totedge);
2997         STACK_INIT(oldl, totloop);
2998         STACK_INIT(oldp, totpoly);
2999
3000         STACK_INIT(mvert, totvert_final);
3001         STACK_INIT(medge, totedge);
3002         STACK_INIT(mloop, totloop);
3003         STACK_INIT(mpoly, totpoly);
3004
3005         /* fill newl with destination vertex indices */
3006         mv = cddm->mvert;
3007         c = 0;
3008         for (i = 0; i < totvert; i++, mv++) {
3009                 if (vtargetmap[i] == -1) {
3010                         STACK_PUSH(oldv, i);
3011                         STACK_PUSH(mvert, *mv);
3012                         newv[i] = c++;
3013                 }
3014                 else {
3015                         /* dummy value */
3016                         newv[i] = 0;
3017                 }
3018         }
3019         
3020         /* now link target vertices to destination indices */
3021         for (i = 0; i < totvert; i++) {
3022                 if (vtargetmap[i] != -1) {
3023                         newv[i] = newv[vtargetmap[i]];
3024                 }
3025         }
3026
3027         /* Don't remap vertices in cddm->mloop, because we need to know the original
3028          * indices in order to skip faces with all vertices merged.
3029          * The "update loop indices..." section further down remaps vertices in mloop.
3030          */
3031
3032         /* now go through and fix edges and faces */
3033         med = cddm->medge;
3034         c = 0;
3035         for (i = 0; i < totedge; i++, med++) {
3036                 const unsigned int v1 = (vtargetmap[med->v1] != -1) ? vtargetmap[med->v1] : med->v1;
3037                 const unsigned int v2 = (vtargetmap[med->v2] != -1) ? vtargetmap[med->v2] : med->v2;
3038                 if (LIKELY(v1 != v2)) {
3039                         void **val_p;
3040
3041                         if (BLI_edgehash_ensure_p(ehash, v1, v2, &val_p)) {
3042                                 newe[i] = GET_INT_FROM_POINTER(*val_p);
3043                         }
3044                         else {
3045                                 STACK_PUSH(olde, i);
3046                                 STACK_PUSH(medge, *med);
3047                                 newe[i] = c;
3048                                 *val_p = SET_INT_IN_POINTER(c);
3049                                 c++;
3050                         }
3051                 }
3052                 else {
3053                         newe[i] = -1;
3054                 }
3055         }
3056         
3057         if (merge_mode == CDDM_MERGE_VERTS_DUMP_IF_EQUAL) {
3058                 /* In this mode, we need to determine,  whenever a poly' vertices are all mapped */
3059                 /* if the targets already make up a poly, in which case the new poly is dropped */
3060                 /* This poly equality check is rather complex.   We use a BLI_ghash to speed it up with a first level check */
3061                 PolyKey *mpgh;
3062                 poly_keys = MEM_mallocN(sizeof(PolyKey) * totpoly, __func__);
3063                 poly_gset = BLI_gset_new_ex(poly_gset_hash_fn, poly_gset_compare_fn, __func__, totpoly);
3064                 /* Duplicates allowed because our compare function is not pure equality */
3065                 BLI_gset_flag_set(poly_gset, GHASH_FLAG_ALLOW_DUPES);
3066
3067                 mp = cddm->mpoly;
3068                 mpgh = poly_keys;
3069                 for (i = 0; i < totpoly; i++, mp++, mpgh++) {
3070                         mpgh->poly_index = i;
3071                         mpgh->totloops = mp->totloop;
3072                         ml = cddm->mloop + mp->loopstart;
3073                         mpgh->hash_sum = mpgh->hash_xor = 0;
3074                         for (j = 0; j < mp->totloop; j++, ml++) {
3075                                 mpgh->hash_sum += ml->v;
3076                                 mpgh->hash_xor ^= ml->v;
3077                         }
3078                         BLI_gset_insert(poly_gset, mpgh);
3079                 }
3080
3081                 if (cddm->pmap) {
3082                         MEM_freeN(cddm->pmap);
3083                         MEM_freeN(cddm->pmap_mem);
3084                 }
3085                 /* Can we optimise by reusing an old pmap ?  How do we know an old pmap is stale ?  */
3086                 /* When called by MOD_array.c, the cddm has just been created, so it has no valid pmap.   */
3087                 BKE_mesh_vert_poly_map_create(&cddm->pmap, &cddm->pmap_mem,
3088                                               cddm->mpoly, cddm->mloop,
3089                                               totvert, totpoly, totloop);
3090         }  /* done preparing for fast poly compare */