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