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