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