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