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