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