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