Fix for [#32992] Switching language does nothing under Windows.
[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 "GL/glew.h"
38
39 #include "BLI_math.h"
40 #include "BLI_blenlib.h"
41 #include "BLI_edgehash.h"
42 #include "BLI_math.h"
43 #include "BLI_pbvh.h"
44 #include "BLI_array.h"
45 #include "BLI_smallhash.h"
46 #include "BLI_utildefines.h"
47 #include "BLI_scanfill.h"
48
49 #include "BKE_cdderivedmesh.h"
50 #include "BKE_global.h"
51 #include "BKE_mesh.h"
52 #include "BKE_paint.h"
53 #include "BKE_tessmesh.h"
54 #include "BKE_curve.h"
55
56 #include "DNA_mesh_types.h"
57 #include "DNA_meshdata_types.h"
58 #include "DNA_object_types.h"
59 #include "DNA_curve_types.h" /* for Curve */
60
61 #include "MEM_guardedalloc.h"
62
63 #include "GPU_buffers.h"
64 #include "GPU_draw.h"
65 #include "GPU_extensions.h"
66 #include "GPU_material.h"
67
68 #include <string.h>
69 #include <limits.h>
70 #include <math.h>
71
72 typedef struct {
73         DerivedMesh dm;
74
75         /* these point to data in the DerivedMesh custom data layers,
76          * they are only here for efficiency and convenience **/
77         MVert *mvert;
78         MEdge *medge;
79         MFace *mface;
80         MLoop *mloop;
81         MPoly *mpoly;
82
83         /* Cached */
84         struct PBVH *pbvh;
85         int pbvh_draw;
86
87         /* Mesh connectivity */
88         MeshElemMap *pmap;
89         int *pmap_mem;
90 } CDDerivedMesh;
91
92 /**************** DerivedMesh interface functions ****************/
93 static int cdDM_getNumVerts(DerivedMesh *dm)
94 {
95         return dm->numVertData;
96 }
97
98 static int cdDM_getNumEdges(DerivedMesh *dm)
99 {
100         return dm->numEdgeData;
101 }
102
103 static int cdDM_getNumTessFaces(DerivedMesh *dm)
104 {
105         /* uncomment and add a breakpoint on the printf()
106          * to help debug tessfaces issues since BMESH merge. */
107 #if 0
108         if (dm->numTessFaceData == 0 && dm->numPolyData != 0) {
109                 printf("%s: has no faces!, call DM_ensure_tessface() if you need them\n");
110         }
111 #endif
112         return dm->numTessFaceData;
113 }
114
115 static int cdDM_getNumLoops(DerivedMesh *dm)
116 {
117         return dm->numLoopData;
118 }
119
120 static int cdDM_getNumPolys(DerivedMesh *dm)
121 {
122         return dm->numPolyData;
123 }
124
125 static void cdDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
126 {
127         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
128         *vert_r = cddm->mvert[index];
129 }
130
131 static void cdDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
132 {
133         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
134         *edge_r = cddm->medge[index];
135 }
136
137 static void cdDM_getTessFace(DerivedMesh *dm, int index, MFace *face_r)
138 {
139         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
140         *face_r = cddm->mface[index];
141 }
142
143 static void cdDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
144 {
145         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
146         memcpy(vert_r, cddm->mvert, sizeof(*vert_r) * dm->numVertData);
147 }
148
149 static void cdDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r)
150 {
151         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
152         memcpy(edge_r, cddm->medge, sizeof(*edge_r) * dm->numEdgeData);
153 }
154
155 static void cdDM_copyTessFaceArray(DerivedMesh *dm, MFace *face_r)
156 {
157         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
158         memcpy(face_r, cddm->mface, sizeof(*face_r) * dm->numTessFaceData);
159 }
160
161 static void cdDM_copyLoopArray(DerivedMesh *dm, MLoop *loop_r)
162 {
163         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
164         memcpy(loop_r, cddm->mloop, sizeof(*loop_r) * dm->numLoopData);
165 }
166
167 static void cdDM_copyPolyArray(DerivedMesh *dm, MPoly *poly_r)
168 {
169         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
170         memcpy(poly_r, cddm->mpoly, sizeof(*poly_r) * dm->numPolyData);
171 }
172
173 static void cdDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
174 {
175         CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
176         int i;
177
178         if (dm->numVertData) {
179                 for (i = 0; i < dm->numVertData; i++) {
180                         minmax_v3v3_v3(min_r, max_r, cddm->mvert[i].co);
181                 }
182         }
183         else {
184                 zero_v3(min_r);
185                 zero_v3(max_r);
186         }
187 }
188
189 static void cdDM_getVertCo(DerivedMesh *dm, int index, float co_r[3])
190 {
191         CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
192
193         copy_v3_v3(co_r, cddm->mvert[index].co);
194 }
195
196 static void cdDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3])
197 {
198         MVert *mv = CDDM_get_verts(dm);
199         int i;
200
201         for (i = 0; i < dm->numVertData; i++, mv++)
202                 copy_v3_v3(cos_r[i], mv->co);
203 }
204
205 static void cdDM_getVertNo(DerivedMesh *dm, int index, float no_r[3])
206 {
207         CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
208         normal_short_to_float_v3(no_r, cddm->mvert[index].no);
209 }
210
211 static const MeshElemMap *cdDM_getPolyMap(Object *ob, DerivedMesh *dm)
212 {
213         CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
214
215         if (!cddm->pmap && ob->type == OB_MESH) {
216                 Mesh *me = ob->data;
217
218                 create_vert_poly_map(&cddm->pmap, &cddm->pmap_mem,
219                                      me->mpoly, me->mloop,
220                                      me->totvert, me->totpoly, me->totloop);
221         }
222
223         return cddm->pmap;
224 }
225
226 static int can_pbvh_draw(Object *ob, DerivedMesh *dm)
227 {
228         CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
229         Mesh *me = ob->data;
230         int deformed = 0;
231
232         /* active modifiers means extra deformation, which can't be handled correct
233          * on birth of PBVH and sculpt "layer" levels, so use PBVH only for internal brush
234          * stuff and show final DerivedMesh so user would see actual object shape */
235         deformed |= ob->sculpt->modifiers_active;
236
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         deformed |= ob->sculpt->kb && (ob->shapeflag & OB_SHAPE_LOCK) == 0;
241
242         if (deformed)
243                 return 0;
244
245         return cddm->mvert == me->mvert || ob->sculpt->kb;
246 }
247
248 static PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm)
249 {
250         CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
251
252         if (!ob) {
253                 cddm->pbvh = NULL;
254                 return NULL;
255         }
256
257         if (!ob->sculpt)
258                 return NULL;
259
260         if (ob->sculpt->pbvh) {
261                 cddm->pbvh = ob->sculpt->pbvh;
262                 cddm->pbvh_draw = can_pbvh_draw(ob, dm);
263         }
264
265         /* always build pbvh from original mesh, and only use it for drawing if
266          * this derivedmesh is just original mesh. it's the multires subsurf dm
267          * that this is actually for, to support a pbvh on a modified mesh */
268         if (!cddm->pbvh && ob->type == OB_MESH) {
269                 SculptSession *ss = ob->sculpt;
270                 Mesh *me = ob->data;
271                 int deformed = 0;
272
273                 cddm->pbvh = BLI_pbvh_new();
274                 cddm->pbvh_draw = can_pbvh_draw(ob, dm);
275
276                 pbvh_show_diffuse_color_set(cddm->pbvh, ob->sculpt->show_diffuse_color);
277
278                 BKE_mesh_tessface_ensure(me);
279                 
280                 BLI_pbvh_build_mesh(cddm->pbvh, me->mface, me->mvert,
281                                     me->totface, me->totvert, &me->vdata);
282
283                 deformed = ss->modifiers_active || me->key;
284
285                 if (deformed && ob->derivedDeform) {
286                         DerivedMesh *deformdm = ob->derivedDeform;
287                         float (*vertCos)[3];
288                         int totvert;
289
290                         totvert = deformdm->getNumVerts(deformdm);
291                         vertCos = MEM_callocN(3 * totvert * sizeof(float), "cdDM_getPBVH vertCos");
292                         deformdm->getVertCos(deformdm, vertCos);
293                         BLI_pbvh_apply_vertCos(cddm->pbvh, vertCos);
294                         MEM_freeN(vertCos);
295                 }
296         }
297
298         return cddm->pbvh;
299 }
300
301 /* update vertex normals so that drawing smooth faces works during sculpt
302  * TODO: proper fix is to support the pbvh in all drawing modes */
303 static void cdDM_update_normals_from_pbvh(DerivedMesh *dm)
304 {
305         CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
306         float (*face_nors)[3];
307
308         if (!cddm->pbvh || !cddm->pbvh_draw || !dm->numTessFaceData)
309                 return;
310
311         face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL);
312
313         BLI_pbvh_update(cddm->pbvh, PBVH_UpdateNormals, face_nors);
314 }
315
316 static void cdDM_drawVerts(DerivedMesh *dm)
317 {
318         CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
319         MVert *mv = cddm->mvert;
320         int i;
321
322         if (GPU_buffer_legacy(dm)) {
323                 glBegin(GL_POINTS);
324                 for (i = 0; i < dm->numVertData; i++, mv++)
325                         glVertex3fv(mv->co);
326                 glEnd();
327         }
328         else {  /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
329                 GPU_vertex_setup(dm);
330                 if (!GPU_buffer_legacy(dm)) {
331                         if (dm->drawObject->tot_triangle_point)
332                                 glDrawArrays(GL_POINTS, 0, dm->drawObject->tot_triangle_point);
333                         else
334                                 glDrawArrays(GL_POINTS, 0, dm->drawObject->tot_loose_point);
335                 }
336                 GPU_buffer_unbind();
337         }
338 }
339
340 static void cdDM_drawUVEdges(DerivedMesh *dm)
341 {
342         CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
343         MFace *mf = cddm->mface;
344         MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
345         int i;
346
347         if (mf) {
348                 if (GPU_buffer_legacy(dm)) {
349                         glBegin(GL_LINES);
350                         for (i = 0; i < dm->numTessFaceData; i++, mf++, tf++) {
351                                 if (!(mf->flag & ME_HIDE)) {
352                                         glVertex2fv(tf->uv[0]);
353                                         glVertex2fv(tf->uv[1]);
354
355                                         glVertex2fv(tf->uv[1]);
356                                         glVertex2fv(tf->uv[2]);
357
358                                         if (!mf->v4) {
359                                                 glVertex2fv(tf->uv[2]);
360                                                 glVertex2fv(tf->uv[0]);
361                                         }
362                                         else {
363                                                 glVertex2fv(tf->uv[2]);
364                                                 glVertex2fv(tf->uv[3]);
365
366                                                 glVertex2fv(tf->uv[3]);
367                                                 glVertex2fv(tf->uv[0]);
368                                         }
369                                 }
370                         }
371                         glEnd();
372                 }
373                 else {
374                         int prevstart = 0;
375                         int prevdraw = 1;
376                         int draw = 1;
377                         int curpos = 0;
378
379                         GPU_uvedge_setup(dm);
380                         if (!GPU_buffer_legacy(dm)) {
381                                 for (i = 0; i < dm->numTessFaceData; i++, mf++) {
382                                         if (!(mf->flag & ME_HIDE)) {
383                                                 draw = 1;
384                                         }
385                                         else {
386                                                 draw = 0;
387                                         }
388                                         if (prevdraw != draw) {
389                                                 if (prevdraw > 0 && (curpos - prevstart) > 0) {
390                                                         glDrawArrays(GL_LINES, prevstart, curpos - prevstart);
391                                                 }
392                                                 prevstart = curpos;
393                                         }
394                                         if (mf->v4) {
395                                                 curpos += 8;
396                                         }
397                                         else {
398                                                 curpos += 6;
399                                         }
400                                         prevdraw = draw;
401                                 }
402                                 if (prevdraw > 0 && (curpos - prevstart) > 0) {
403                                         glDrawArrays(GL_LINES, prevstart, curpos - prevstart);
404                                 }
405                         }
406                         GPU_buffer_unbind();
407                 }
408         }
409 }
410
411 static void cdDM_drawEdges(DerivedMesh *dm, int drawLooseEdges, int drawAllEdges)
412 {
413         CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
414         MVert *mvert = cddm->mvert;
415         MEdge *medge = cddm->medge;
416         int i;
417         
418         if (GPU_buffer_legacy(dm)) {
419                 DEBUG_VBO("Using legacy code. cdDM_drawEdges\n");
420                 glBegin(GL_LINES);
421                 for (i = 0; i < dm->numEdgeData; i++, medge++) {
422                         if ((drawAllEdges || (medge->flag & ME_EDGEDRAW)) &&
423                             (drawLooseEdges || !(medge->flag & ME_LOOSEEDGE)))
424                         {
425                                 glVertex3fv(mvert[medge->v1].co);
426                                 glVertex3fv(mvert[medge->v2].co);
427                         }
428                 }
429                 glEnd();
430         }
431         else {  /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
432                 int prevstart = 0;
433                 int prevdraw = 1;
434                 int draw = TRUE;
435
436                 GPU_edge_setup(dm);
437                 if (!GPU_buffer_legacy(dm)) {
438                         for (i = 0; i < dm->numEdgeData; i++, medge++) {
439                                 if ((drawAllEdges || (medge->flag & ME_EDGEDRAW)) &&
440                                     (drawLooseEdges || !(medge->flag & ME_LOOSEEDGE)))
441                                 {
442                                         draw = TRUE;
443                                 }
444                                 else {
445                                         draw = FALSE;
446                                 }
447                                 if (prevdraw != draw) {
448                                         if (prevdraw > 0 && (i - prevstart) > 0) {
449                                                 GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, prevstart * 2, (i - prevstart) * 2);
450                                         }
451                                         prevstart = i;
452                                 }
453                                 prevdraw = draw;
454                         }
455                         if (prevdraw > 0 && (i - prevstart) > 0) {
456                                 GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, prevstart * 2, (i - prevstart) * 2);
457                         }
458                 }
459                 GPU_buffer_unbind();
460         }
461 }
462
463 static void cdDM_drawLooseEdges(DerivedMesh *dm)
464 {
465         CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
466         MVert *mvert = cddm->mvert;
467         MEdge *medge = cddm->medge;
468         int i;
469
470         if (GPU_buffer_legacy(dm)) {
471                 DEBUG_VBO("Using legacy code. cdDM_drawLooseEdges\n");
472                 glBegin(GL_LINES);
473                 for (i = 0; i < dm->numEdgeData; i++, medge++) {
474                         if (medge->flag & ME_LOOSEEDGE) {
475                                 glVertex3fv(mvert[medge->v1].co);
476                                 glVertex3fv(mvert[medge->v2].co);
477                         }
478                 }
479                 glEnd();
480         }
481         else {  /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
482                 int prevstart = 0;
483                 int prevdraw = 1;
484                 int draw = 1;
485
486                 GPU_edge_setup(dm);
487                 if (!GPU_buffer_legacy(dm)) {
488                         for (i = 0; i < dm->numEdgeData; i++, medge++) {
489                                 if (medge->flag & ME_LOOSEEDGE) {
490                                         draw = 1;
491                                 }
492                                 else {
493                                         draw = 0;
494                                 }
495                                 if (prevdraw != draw) {
496                                         if (prevdraw > 0 && (i - prevstart) > 0) {
497                                                 GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, prevstart * 2, (i - prevstart) * 2);
498                                         }
499                                         prevstart = i;
500                                 }
501                                 prevdraw = draw;
502                         }
503                         if (prevdraw > 0 && (i - prevstart) > 0) {
504                                 GPU_buffer_draw_elements(dm->drawObject->edges, GL_LINES, prevstart * 2, (i - prevstart) * 2);
505                         }
506                 }
507                 GPU_buffer_unbind();
508         }
509 }
510
511 static void cdDM_drawFacesSolid(DerivedMesh *dm,
512                                 float (*partial_redraw_planes)[4],
513                                 int UNUSED(fast), DMSetMaterial setMaterial)
514 {
515         CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
516         MVert *mvert = cddm->mvert;
517         MFace *mface = cddm->mface;
518         float *nors = dm->getTessFaceDataArray(dm, CD_NORMAL);
519         int a, glmode = -1, shademodel = -1, matnr = -1, drawCurrentMat = 1;
520
521 #define PASSVERT(index) {                                               \
522         if (shademodel == GL_SMOOTH) {                          \
523                 short *no = mvert[index].no;                    \
524                 glNormal3sv(no);                                                \
525         }                                                                                       \
526         glVertex3fv(mvert[index].co);                           \
527 } (void)0
528
529         if (cddm->pbvh && cddm->pbvh_draw) {
530                 if (dm->numTessFaceData) {
531                         float (*face_nors)[3] = CustomData_get_layer(&dm->faceData, CD_NORMAL);
532
533                         BLI_pbvh_draw(cddm->pbvh, partial_redraw_planes, face_nors, setMaterial);
534                         glShadeModel(GL_FLAT);
535                 }
536
537                 return;
538         }
539
540         if (GPU_buffer_legacy(dm)) {
541                 DEBUG_VBO("Using legacy code. cdDM_drawFacesSolid\n");
542                 glBegin(glmode = GL_QUADS);
543                 for (a = 0; a < dm->numTessFaceData; a++, mface++) {
544                         int new_glmode, new_matnr, new_shademodel;
545
546                         new_glmode = mface->v4 ? GL_QUADS : GL_TRIANGLES;
547                         new_matnr = mface->mat_nr + 1;
548                         new_shademodel = (mface->flag & ME_SMOOTH) ? GL_SMOOTH : GL_FLAT;
549                         
550                         if (new_glmode != glmode || new_matnr != matnr || new_shademodel != shademodel) {
551                                 glEnd();
552
553                                 drawCurrentMat = setMaterial(matnr = new_matnr, NULL);
554
555                                 glShadeModel(shademodel = new_shademodel);
556                                 glBegin(glmode = new_glmode);
557                         }
558                         
559                         if (drawCurrentMat) {
560                                 if (shademodel == GL_FLAT) {
561                                         if (nors) {
562                                                 glNormal3fv(nors);
563                                         }
564                                         else {
565                                                 /* TODO make this better (cache facenormals as layer?) */
566                                                 float nor[3];
567                                                 if (mface->v4) {
568                                                         normal_quad_v3(nor, mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co, mvert[mface->v4].co);
569                                                 }
570                                                 else {
571                                                         normal_tri_v3(nor, mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co);
572                                                 }
573                                                 glNormal3fv(nor);
574                                         }
575                                 }
576
577                                 PASSVERT(mface->v1);
578                                 PASSVERT(mface->v2);
579                                 PASSVERT(mface->v3);
580                                 if (mface->v4) {
581                                         PASSVERT(mface->v4);
582                                 }
583                         }
584
585                         if (nors) nors += 3;
586                 }
587                 glEnd();
588         }
589         else {  /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
590                 GPU_vertex_setup(dm);
591                 GPU_normal_setup(dm);
592                 if (!GPU_buffer_legacy(dm)) {
593                         glShadeModel(GL_SMOOTH);
594                         for (a = 0; a < dm->drawObject->totmaterial; a++) {
595                                 if (setMaterial(dm->drawObject->materials[a].mat_nr + 1, NULL)) {
596                                         glDrawArrays(GL_TRIANGLES, dm->drawObject->materials[a].start,
597                                                      dm->drawObject->materials[a].totpoint);
598                                 }
599                         }
600                 }
601                 GPU_buffer_unbind();
602         }
603
604 #undef PASSVERT
605         glShadeModel(GL_FLAT);
606 }
607
608 static void cdDM_drawFacesTex_common(DerivedMesh *dm,
609                                      DMSetDrawOptionsTex drawParams,
610                                      DMSetDrawOptions drawParamsMapped,
611                                      DMCompareDrawOptions compareDrawOptions,
612                                      void *userData)
613 {
614         CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
615         MVert *mv = cddm->mvert;
616         MFace *mf = DM_get_tessface_data_layer(dm, CD_MFACE);
617         float *nors = dm->getTessFaceDataArray(dm, CD_NORMAL);
618         MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
619         MCol *mcol;
620         int i, orig;
621         int colType, startFace = 0;
622
623         /* double lookup */
624         const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
625         const int *index_mp_to_orig  = dm->getPolyDataArray(dm, CD_ORIGINDEX);
626         if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) {
627                 index_mf_to_mpoly = index_mp_to_orig = NULL;
628         }
629
630         colType = CD_TEXTURE_MCOL;
631         mcol = dm->getTessFaceDataArray(dm, colType);
632         if (!mcol) {
633                 colType = CD_PREVIEW_MCOL;
634                 mcol = dm->getTessFaceDataArray(dm, colType);
635         }
636         if (!mcol) {
637                 colType = CD_MCOL;
638                 mcol = dm->getTessFaceDataArray(dm, colType);
639         }
640
641         cdDM_update_normals_from_pbvh(dm);
642
643         if (GPU_buffer_legacy(dm)) {
644                 DEBUG_VBO("Using legacy code. cdDM_drawFacesTex_common\n");
645                 for (i = 0; i < dm->numTessFaceData; i++, mf++) {
646                         MVert *mvert;
647                         DMDrawOption draw_option;
648                         unsigned char *cp = NULL;
649
650                         if (drawParams) {
651                                 draw_option = drawParams(tf ? &tf[i] : NULL, (mcol != NULL), mf->mat_nr);
652                         }
653                         else {
654                                 if (index_mf_to_mpoly) {
655                                         orig = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, i);
656                                         if (orig == ORIGINDEX_NONE) { if (nors) nors += 3; continue; }
657                                         if (drawParamsMapped)       { draw_option = drawParamsMapped(userData, orig); }
658                                         else                        { if (nors) nors += 3; continue; }
659                                 }
660                                 else if (drawParamsMapped) { draw_option = drawParamsMapped(userData, i); }
661                                 else                       { if (nors) nors += 3; continue; }
662                         }
663                         
664                         if (draw_option != DM_DRAW_OPTION_SKIP) {
665                                 if (draw_option != DM_DRAW_OPTION_NO_MCOL && mcol)
666                                         cp = (unsigned char *) &mcol[i * 4];
667
668                                 if (!(mf->flag & ME_SMOOTH)) {
669                                         if (nors) {
670                                                 glNormal3fv(nors);
671                                         }
672                                         else {
673                                                 float nor[3];
674                                                 if (mf->v4) {
675                                                         normal_quad_v3(nor, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co);
676                                                 }
677                                                 else {
678                                                         normal_tri_v3(nor, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co);
679                                                 }
680                                                 glNormal3fv(nor);
681                                         }
682                                 }
683
684                                 glBegin(mf->v4 ? GL_QUADS : GL_TRIANGLES);
685                                 if (tf) glTexCoord2fv(tf[i].uv[0]);
686                                 if (cp) glColor3ub(cp[3], cp[2], cp[1]);
687                                 mvert = &mv[mf->v1];
688                                 if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no);
689                                 glVertex3fv(mvert->co);
690                                         
691                                 if (tf) glTexCoord2fv(tf[i].uv[1]);
692                                 if (cp) glColor3ub(cp[7], cp[6], cp[5]);
693                                 mvert = &mv[mf->v2];
694                                 if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no);
695                                 glVertex3fv(mvert->co);
696
697                                 if (tf) glTexCoord2fv(tf[i].uv[2]);
698                                 if (cp) glColor3ub(cp[11], cp[10], cp[9]);
699                                 mvert = &mv[mf->v3];
700                                 if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no);
701                                 glVertex3fv(mvert->co);
702
703                                 if (mf->v4) {
704                                         if (tf) glTexCoord2fv(tf[i].uv[3]);
705                                         if (cp) glColor3ub(cp[15], cp[14], cp[13]);
706                                         mvert = &mv[mf->v4];
707                                         if (mf->flag & ME_SMOOTH) glNormal3sv(mvert->no);
708                                         glVertex3fv(mvert->co);
709                                 }
710                                 glEnd();
711                         }
712                         
713                         if (nors) nors += 3;
714                 }
715         }
716         else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
717                 GPU_vertex_setup(dm);
718                 GPU_normal_setup(dm);
719                 GPU_uv_setup(dm);
720                 if (mcol) {
721                         GPU_color_setup(dm, colType);
722                 }
723
724                 if (!GPU_buffer_legacy(dm)) {
725                         int tottri = dm->drawObject->tot_triangle_point / 3;
726                         int next_actualFace = dm->drawObject->triangle_to_mface[0];
727
728                         glShadeModel(GL_SMOOTH);
729                         /* lastFlag = 0; */ /* UNUSED */
730                         for (i = 0; i < tottri; i++) {
731                                 int actualFace = next_actualFace;
732                                 DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL;
733                                 int flush = 0;
734
735                                 if (i != tottri - 1)
736                                         next_actualFace = dm->drawObject->triangle_to_mface[i + 1];
737
738                                 if (drawParams) {
739                                         draw_option = drawParams(tf ? &tf[actualFace] : NULL, (mcol != NULL), mf[actualFace].mat_nr);
740                                 }
741                                 else {
742                                         if (index_mf_to_mpoly) {
743                                                 orig = DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, actualFace);
744                                                 if (orig == ORIGINDEX_NONE) {
745                                                         continue;
746                                                 }
747                                                 if (drawParamsMapped) {
748                                                         draw_option = drawParamsMapped(userData, orig);
749                                                 }
750                                         }
751                                         else if (drawParamsMapped) {
752                                                 draw_option = drawParamsMapped(userData, actualFace);
753                                         }
754                                 }
755
756                                 /* flush buffer if current triangle isn't drawable or it's last triangle */
757                                 flush = (draw_option == DM_DRAW_OPTION_SKIP) || (i == tottri - 1);
758
759                                 if (!flush && compareDrawOptions) {
760                                         /* also compare draw options and flush buffer if they're different
761                                          * need for face selection highlight in edit mode */
762                                         flush |= compareDrawOptions(userData, actualFace, next_actualFace) == 0;
763                                 }
764
765                                 if (flush) {
766                                         int first = startFace * 3;
767                                         /* Add one to the length if we're drawing at the end of the array */
768                                         int count = (i - startFace + (draw_option != DM_DRAW_OPTION_SKIP ? 1 : 0)) * 3;
769
770                                         if (count) {
771                                                 if (mcol && draw_option != DM_DRAW_OPTION_NO_MCOL)
772                                                         GPU_color_switch(1);
773                                                 else
774                                                         GPU_color_switch(0);
775
776                                                 glDrawArrays(GL_TRIANGLES, first, count);
777                                         }
778
779                                         startFace = i + 1;
780                                 }
781                         }
782                 }
783
784                 GPU_buffer_unbind();
785                 glShadeModel(GL_FLAT);
786         }
787 }
788
789 static void cdDM_drawFacesTex(DerivedMesh *dm,
790                               DMSetDrawOptionsTex setDrawOptions,
791                               DMCompareDrawOptions compareDrawOptions,
792                               void *userData)
793 {
794         cdDM_drawFacesTex_common(dm, setDrawOptions, NULL, compareDrawOptions, userData);
795 }
796
797 static void cdDM_drawMappedFaces(DerivedMesh *dm,
798                                  DMSetDrawOptions setDrawOptions,
799                                  DMSetMaterial setMaterial,
800                                  DMCompareDrawOptions compareDrawOptions,
801                                  void *userData, DMDrawFlag flag)
802 {
803         CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
804         MVert *mv = cddm->mvert;
805         MFace *mf = cddm->mface;
806         MCol *mcol;
807         float *nors = DM_get_tessface_data_layer(dm, CD_NORMAL);
808         int colType, useColors = flag & DM_DRAW_USE_COLORS;
809         int i, orig;
810
811
812         /* double lookup */
813         const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
814         const int *index_mp_to_orig  = dm->getPolyDataArray(dm, CD_ORIGINDEX);
815         if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) {
816                 index_mf_to_mpoly = index_mp_to_orig = NULL;
817         }
818
819
820         colType = CD_ID_MCOL;
821         mcol = DM_get_tessface_data_layer(dm, colType);
822         if (!mcol) {
823                 colType = CD_PREVIEW_MCOL;
824                 mcol = DM_get_tessface_data_layer(dm, colType);
825         }
826         if (!mcol) {
827                 colType = CD_MCOL;
828                 mcol = DM_get_tessface_data_layer(dm, colType);
829         }
830
831         printf("%s: %p(%d/%d)\n", __func__, mcol, CD_ID_MCOL, colType);
832
833         cdDM_update_normals_from_pbvh(dm);
834
835         /* back-buffer always uses legacy since VBO's would need the
836          * color array temporarily overwritten for drawing, then reset. */
837         if (GPU_buffer_legacy(dm) || G.f & G_BACKBUFSEL) {
838                 DEBUG_VBO("Using legacy code. cdDM_drawMappedFaces\n");
839                 for (i = 0; i < dm->numTessFaceData; i++, mf++) {
840                         int drawSmooth = (flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : (mf->flag & ME_SMOOTH);
841                         DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL;
842
843                         orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, i) : i;
844                         
845                         if (orig == ORIGINDEX_NONE)
846                                 draw_option = setMaterial(mf->mat_nr + 1, NULL);
847                         else if (setDrawOptions != NULL)
848                                 draw_option = setDrawOptions(userData, orig);
849
850                         if (draw_option != DM_DRAW_OPTION_SKIP) {
851                                 unsigned char *cp = NULL;
852
853                                 if (useColors && mcol)
854                                         cp = (unsigned char *)&mcol[i * 4];
855
856                                 /* no need to set shading mode to flat because
857                                  *  normals are already used to change shading */
858                                 glShadeModel(GL_SMOOTH);
859                                 glBegin(mf->v4 ? GL_QUADS : GL_TRIANGLES);
860
861                                 if (!drawSmooth) {
862                                         if (nors) {
863                                                 glNormal3fv(nors);
864                                         }
865                                         else {
866                                                 float nor[3];
867                                                 if (mf->v4) {
868                                                         normal_quad_v3(nor, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co);
869                                                 }
870                                                 else {
871                                                         normal_tri_v3(nor, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co);
872                                                 }
873                                                 glNormal3fv(nor);
874                                         }
875
876                                         if (cp) glColor3ub(cp[3], cp[2], cp[1]);
877                                         glVertex3fv(mv[mf->v1].co);
878                                         if (cp) glColor3ub(cp[7], cp[6], cp[5]);
879                                         glVertex3fv(mv[mf->v2].co);
880                                         if (cp) glColor3ub(cp[11], cp[10], cp[9]);
881                                         glVertex3fv(mv[mf->v3].co);
882                                         if (mf->v4) {
883                                                 if (cp) glColor3ub(cp[15], cp[14], cp[13]);
884                                                 glVertex3fv(mv[mf->v4].co);
885                                         }
886                                 }
887                                 else {
888                                         if (cp) glColor3ub(cp[3], cp[2], cp[1]);
889                                         glNormal3sv(mv[mf->v1].no);
890                                         glVertex3fv(mv[mf->v1].co);
891                                         if (cp) glColor3ub(cp[7], cp[6], cp[5]);
892                                         glNormal3sv(mv[mf->v2].no);
893                                         glVertex3fv(mv[mf->v2].co);
894                                         if (cp) glColor3ub(cp[11], cp[10], cp[9]);
895                                         glNormal3sv(mv[mf->v3].no);
896                                         glVertex3fv(mv[mf->v3].co);
897                                         if (mf->v4) {
898                                                 if (cp) glColor3ub(cp[15], cp[14], cp[13]);
899                                                 glNormal3sv(mv[mf->v4].no);
900                                                 glVertex3fv(mv[mf->v4].co);
901                                         }
902                                 }
903
904                                 glEnd();
905                         }
906                         
907                         if (nors) nors += 3;
908                 }
909         }
910         else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
911                 int prevstart = 0;
912                 GPU_vertex_setup(dm);
913                 GPU_normal_setup(dm);
914                 if (useColors && mcol) {
915                         GPU_color_setup(dm, colType);
916                 }
917                 if (!GPU_buffer_legacy(dm)) {
918                         int tottri = dm->drawObject->tot_triangle_point / 3;
919                         glShadeModel(GL_SMOOTH);
920                         
921                         if (tottri == 0) {
922                                 /* avoid buffer problems in following code */
923                         }
924                         if (setDrawOptions == NULL) {
925                                 /* just draw the entire face array */
926                                 glDrawArrays(GL_TRIANGLES, 0, (tottri) * 3);
927                         }
928                         else {
929                                 /* we need to check if the next material changes */
930                                 int next_actualFace = dm->drawObject->triangle_to_mface[0];
931                                 
932                                 for (i = 0; i < tottri; i++) {
933                                         //int actualFace = dm->drawObject->triangle_to_mface[i];
934                                         int actualFace = next_actualFace;
935                                         MFace *mface = mf + actualFace;
936                                         /*int drawSmooth = (flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : (mface->flag & ME_SMOOTH);*/ /* UNUSED */
937                                         DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL;
938                                         int flush = 0;
939
940                                         if (i != tottri - 1)
941                                                 next_actualFace = dm->drawObject->triangle_to_mface[i + 1];
942
943                                         orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, actualFace) : actualFace;
944
945                                         if (orig == ORIGINDEX_NONE)
946                                                 draw_option = setMaterial(mface->mat_nr + 1, NULL);
947                                         else if (setDrawOptions != NULL)
948                                                 draw_option = setDrawOptions(userData, orig);
949         
950                                         /* Goal is to draw as long of a contiguous triangle
951                                          * array as possible, so draw when we hit either an
952                                          * invisible triangle or at the end of the array */
953
954                                         /* flush buffer if current triangle isn't drawable or it's last triangle... */
955                                         flush = (draw_option == DM_DRAW_OPTION_SKIP) || (i == tottri - 1);
956
957                                         /* ... or when material setting is dissferent  */
958                                         flush |= mf[actualFace].mat_nr != mf[next_actualFace].mat_nr;
959
960                                         if (!flush && compareDrawOptions) {
961                                                 flush |= compareDrawOptions(userData, actualFace, next_actualFace) == 0;
962                                         }
963
964                                         if (flush) {
965                                                 int first = prevstart * 3;
966                                                 /* Add one to the length if we're drawing at the end of the array */
967                                                 int count = (i - prevstart + (draw_option != DM_DRAW_OPTION_SKIP ? 1 : 0)) * 3;
968
969                                                 if (count)
970                                                         glDrawArrays(GL_TRIANGLES, first, count);
971
972                                                 prevstart = i + 1;
973                                         }
974                                 }
975                         }
976
977                         glShadeModel(GL_FLAT);
978                 }
979                 GPU_buffer_unbind();
980         }
981 }
982
983 static void cdDM_drawMappedFacesTex(DerivedMesh *dm,
984                                     DMSetDrawOptions setDrawOptions,
985                                     DMCompareDrawOptions compareDrawOptions,
986                                     void *userData)
987 {
988         cdDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData);
989 }
990
991 static void cddm_draw_attrib_vertex(DMVertexAttribs *attribs, MVert *mvert, int a, int index, int vert, int smoothnormal)
992 {
993         int b;
994
995         /* orco texture coordinates */
996         if (attribs->totorco) {
997                 if (attribs->orco.gl_texco)
998                         glTexCoord3fv(attribs->orco.array[index]);
999                 else
1000                         glVertexAttrib3fvARB(attribs->orco.gl_index, attribs->orco.array[index]);
1001         }
1002
1003         /* uv texture coordinates */
1004         for (b = 0; b < attribs->tottface; b++) {
1005                 MTFace *tf = &attribs->tface[b].array[a];
1006
1007                 if (attribs->tface[b].gl_texco)
1008                         glTexCoord2fv(tf->uv[vert]);
1009                 else
1010                         glVertexAttrib2fvARB(attribs->tface[b].gl_index, tf->uv[vert]);
1011         }
1012
1013         /* vertex colors */
1014         for (b = 0; b < attribs->totmcol; b++) {
1015                 MCol *cp = &attribs->mcol[b].array[a * 4 + vert];
1016                 GLubyte col[4];
1017                 col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
1018                 glVertexAttrib4ubvARB(attribs->mcol[b].gl_index, col);
1019         }
1020
1021         /* tangent for normal mapping */
1022         if (attribs->tottang) {
1023                 float *tang = attribs->tang.array[a * 4 + vert];
1024                 glVertexAttrib4fvARB(attribs->tang.gl_index, tang);
1025         }
1026
1027         /* vertex normal */
1028         if (smoothnormal)
1029                 glNormal3sv(mvert[index].no);
1030         
1031         /* vertex coordinate */
1032         glVertex3fv(mvert[index].co);
1033 }
1034
1035 static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm,
1036                                      DMSetMaterial setMaterial,
1037                                      DMSetDrawOptions setDrawOptions,
1038                                      void *userData)
1039 {
1040         CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
1041         GPUVertexAttribs gattribs;
1042         DMVertexAttribs attribs;
1043         MVert *mvert = cddm->mvert;
1044         MFace *mface = cddm->mface;
1045         /* MTFace *tf = dm->getTessFaceDataArray(dm, CD_MTFACE); */ /* UNUSED */
1046         float (*nors)[3] = dm->getTessFaceDataArray(dm, CD_NORMAL);
1047         int a, b, do_draw, matnr, new_matnr;
1048         int orig;
1049
1050         /* double lookup */
1051         const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
1052         const int *index_mp_to_orig  = dm->getPolyDataArray(dm, CD_ORIGINDEX);
1053         if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) {
1054                 index_mf_to_mpoly = index_mp_to_orig = NULL;
1055         }
1056
1057         cdDM_update_normals_from_pbvh(dm);
1058
1059         matnr = -1;
1060         do_draw = FALSE;
1061
1062         glShadeModel(GL_SMOOTH);
1063
1064         if (GPU_buffer_legacy(dm) || setDrawOptions != NULL) {
1065                 DEBUG_VBO("Using legacy code. cdDM_drawMappedFacesGLSL\n");
1066                 memset(&attribs, 0, sizeof(attribs));
1067
1068                 glBegin(GL_QUADS);
1069
1070                 for (a = 0; a < dm->numTessFaceData; a++, mface++) {
1071                         const int smoothnormal = (mface->flag & ME_SMOOTH);
1072                         new_matnr = mface->mat_nr + 1;
1073
1074                         if (new_matnr != matnr) {
1075                                 glEnd();
1076
1077                                 do_draw = setMaterial(matnr = new_matnr, &gattribs);
1078                                 if (do_draw)
1079                                         DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1080
1081                                 glBegin(GL_QUADS);
1082                         }
1083
1084                         if (!do_draw) {
1085                                 continue;
1086                         }
1087                         else if (setDrawOptions) {
1088                                 orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, a) : a;
1089
1090                                 if (orig == ORIGINDEX_NONE) {
1091                                         /* since the material is set by setMaterial(), faces with no
1092                                          * origin can be assumed to be generated by a modifier */ 
1093                                         
1094                                         /* continue */
1095                                 }
1096                                 else if (setDrawOptions(userData, orig) == DM_DRAW_OPTION_SKIP)
1097                                         continue;
1098                         }
1099
1100                         if (!smoothnormal) {
1101                                 if (nors) {
1102                                         glNormal3fv(nors[a]);
1103                                 }
1104                                 else {
1105                                         /* TODO ideally a normal layer should always be available */
1106                                         float nor[3];
1107                                         if (mface->v4) {
1108                                                 normal_quad_v3(nor, mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co, mvert[mface->v4].co);
1109                                         }
1110                                         else {
1111                                                 normal_tri_v3(nor, mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co);
1112                                         }
1113                                         glNormal3fv(nor);
1114                                 }
1115                         }
1116
1117                         cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v1, 0, smoothnormal);
1118                         cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v2, 1, smoothnormal);
1119                         cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, smoothnormal);
1120
1121                         if (mface->v4)
1122                                 cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v4, 3, smoothnormal);
1123                         else
1124                                 cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, smoothnormal);
1125                 }
1126                 glEnd();
1127         }
1128         else {
1129                 GPUBuffer *buffer = NULL;
1130                 char *varray = NULL;
1131                 int numdata = 0, elementsize = 0, offset;
1132                 int start = 0, numfaces = 0 /* , prevdraw = 0 */ /* UNUSED */, curface = 0;
1133                 int i;
1134
1135                 MFace *mf = mface;
1136                 GPUAttrib datatypes[GPU_MAX_ATTRIB]; /* TODO, messing up when switching materials many times - [#21056]*/
1137                 memset(&attribs, 0, sizeof(attribs));
1138
1139                 GPU_vertex_setup(dm);
1140                 GPU_normal_setup(dm);
1141
1142                 if (!GPU_buffer_legacy(dm)) {
1143                         for (i = 0; i < dm->drawObject->tot_triangle_point / 3; i++) {
1144
1145                                 a = dm->drawObject->triangle_to_mface[i];
1146
1147                                 mface = mf + a;
1148                                 new_matnr = mface->mat_nr + 1;
1149
1150                                 if (new_matnr != matnr) {
1151                                         numfaces = curface - start;
1152                                         if (numfaces > 0) {
1153
1154                                                 if (do_draw) {
1155
1156                                                         if (numdata != 0) {
1157
1158                                                                 GPU_buffer_unlock(buffer);
1159
1160                                                                 GPU_interleaved_attrib_setup(buffer, datatypes, numdata);
1161                                                         }
1162
1163                                                         glDrawArrays(GL_TRIANGLES, start * 3, numfaces * 3);
1164
1165                                                         if (numdata != 0) {
1166
1167                                                                 GPU_buffer_free(buffer);
1168
1169                                                                 buffer = NULL;
1170                                                         }
1171
1172                                                 }
1173                                         }
1174                                         numdata = 0;
1175                                         start = curface;
1176                                         /* prevdraw = do_draw; */ /* UNUSED */
1177                                         do_draw = setMaterial(matnr = new_matnr, &gattribs);
1178                                         if (do_draw) {
1179                                                 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1180
1181                                                 if (attribs.totorco) {
1182                                                         datatypes[numdata].index = attribs.orco.gl_index;
1183                                                         datatypes[numdata].size = 3;
1184                                                         datatypes[numdata].type = GL_FLOAT;
1185                                                         numdata++;
1186                                                 }
1187                                                 for (b = 0; b < attribs.tottface; b++) {
1188                                                         datatypes[numdata].index = attribs.tface[b].gl_index;
1189                                                         datatypes[numdata].size = 2;
1190                                                         datatypes[numdata].type = GL_FLOAT;
1191                                                         numdata++;
1192                                                 }
1193                                                 for (b = 0; b < attribs.totmcol; b++) {
1194                                                         datatypes[numdata].index = attribs.mcol[b].gl_index;
1195                                                         datatypes[numdata].size = 4;
1196                                                         datatypes[numdata].type = GL_UNSIGNED_BYTE;
1197                                                         numdata++;
1198                                                 }
1199                                                 if (attribs.tottang) {
1200                                                         datatypes[numdata].index = attribs.tang.gl_index;
1201                                                         datatypes[numdata].size = 4;
1202                                                         datatypes[numdata].type = GL_FLOAT;
1203                                                         numdata++;
1204                                                 }
1205                                                 if (numdata != 0) {
1206                                                         elementsize = GPU_attrib_element_size(datatypes, numdata);
1207                                                         buffer = GPU_buffer_alloc(elementsize * dm->drawObject->tot_triangle_point);
1208                                                         if (buffer == NULL) {
1209                                                                 GPU_buffer_unbind();
1210                                                                 dm->drawObject->legacy = 1;
1211                                                                 return;
1212                                                         }
1213                                                         varray = GPU_buffer_lock_stream(buffer);
1214                                                         if (varray == NULL) {
1215                                                                 GPU_buffer_unbind();
1216                                                                 GPU_buffer_free(buffer);
1217                                                                 dm->drawObject->legacy = 1;
1218                                                                 return;
1219                                                         }
1220                                                 }
1221                                                 else {
1222                                                         /* if the buffer was set, don't use it again.
1223                                                          * prevdraw was assumed true but didnt run so set to false - [#21036] */
1224                                                         /* prevdraw = 0; */ /* UNUSED */
1225                                                         buffer = NULL;
1226                                                 }
1227                                         }
1228                                 }
1229
1230                                 if (do_draw && numdata != 0) {
1231                                         offset = 0;
1232                                         if (attribs.totorco) {
1233                                                 copy_v3_v3((float *)&varray[elementsize * curface * 3], (float *)attribs.orco.array[mface->v1]);
1234                                                 copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize], (float *)attribs.orco.array[mface->v2]);
1235                                                 copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize * 2], (float *)attribs.orco.array[mface->v3]);
1236                                                 offset += sizeof(float) * 3;
1237                                         }
1238                                         for (b = 0; b < attribs.tottface; b++) {
1239                                                 MTFace *tf = &attribs.tface[b].array[a];
1240                                                 copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset], tf->uv[0]);
1241                                                 copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize], tf->uv[1]);
1242
1243                                                 copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tf->uv[2]);
1244                                                 offset += sizeof(float) * 2;
1245                                         }
1246                                         for (b = 0; b < attribs.totmcol; b++) {
1247                                                 MCol *cp = &attribs.mcol[b].array[a * 4 + 0];
1248                                                 GLubyte col[4];
1249                                                 col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
1250                                                 copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset], (char *)col);
1251                                                 cp = &attribs.mcol[b].array[a * 4 + 1];
1252                                                 col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
1253                                                 copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize], (char *)col);
1254                                                 cp = &attribs.mcol[b].array[a * 4 + 2];
1255                                                 col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
1256                                                 copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize * 2], (char *)col);
1257                                                 offset += sizeof(unsigned char) * 4;
1258                                         }
1259                                         if (attribs.tottang) {
1260                                                 float *tang = attribs.tang.array[a * 4 + 0];
1261                                                 copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset], tang);
1262                                                 tang = attribs.tang.array[a * 4 + 1];
1263                                                 copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize], tang);
1264                                                 tang = attribs.tang.array[a * 4 + 2];
1265                                                 copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tang);
1266                                                 offset += sizeof(float) * 4;
1267                                         }
1268                                         (void)offset;
1269                                 }
1270                                 curface++;
1271                                 if (mface->v4) {
1272                                         if (do_draw && numdata != 0) {
1273                                                 offset = 0;
1274                                                 if (attribs.totorco) {
1275                                                         copy_v3_v3((float *)&varray[elementsize * curface * 3], (float *)attribs.orco.array[mface->v3]);
1276                                                         copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize], (float *)attribs.orco.array[mface->v4]);
1277                                                         copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize * 2], (float *)attribs.orco.array[mface->v1]);
1278                                                         offset += sizeof(float) * 3;
1279                                                 }
1280                                                 for (b = 0; b < attribs.tottface; b++) {
1281                                                         MTFace *tf = &attribs.tface[b].array[a];
1282                                                         copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset], tf->uv[2]);
1283                                                         copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize], tf->uv[3]);
1284                                                         copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tf->uv[0]);
1285                                                         offset += sizeof(float) * 2;
1286                                                 }
1287                                                 for (b = 0; b < attribs.totmcol; b++) {
1288                                                         MCol *cp = &attribs.mcol[b].array[a * 4 + 2];
1289                                                         GLubyte col[4];
1290                                                         col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
1291                                                         copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset], (char *)col);
1292                                                         cp = &attribs.mcol[b].array[a * 4 + 3];
1293                                                         col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
1294                                                         copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize], (char *)col);
1295                                                         cp = &attribs.mcol[b].array[a * 4 + 0];
1296                                                         col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
1297                                                         copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize * 2], (char *)col);
1298                                                         offset += sizeof(unsigned char) * 4;
1299                                                 }
1300                                                 if (attribs.tottang) {
1301                                                         float *tang = attribs.tang.array[a * 4 + 2];
1302                                                         copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset], tang);
1303                                                         tang = attribs.tang.array[a * 4 + 3];
1304                                                         copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize], tang);
1305                                                         tang = attribs.tang.array[a * 4 + 0];
1306                                                         copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tang);
1307                                                         offset += sizeof(float) * 4;
1308                                                 }
1309                                                 (void)offset;
1310                                         }
1311                                         curface++;
1312                                         i++;
1313                                 }
1314                         }
1315                         numfaces = curface - start;
1316                         if (numfaces > 0) {
1317                                 if (do_draw) {
1318                                         if (numdata != 0) {
1319                                                 GPU_buffer_unlock(buffer);
1320                                                 GPU_interleaved_attrib_setup(buffer, datatypes, numdata);
1321                                         }
1322                                         glDrawArrays(GL_TRIANGLES, start * 3, (curface - start) * 3);
1323                                 }
1324                         }
1325                         GPU_buffer_unbind();
1326                 }
1327                 GPU_buffer_free(buffer);
1328         }
1329
1330         glShadeModel(GL_FLAT);
1331 }
1332
1333 static void cdDM_drawFacesGLSL(DerivedMesh *dm, DMSetMaterial setMaterial)
1334 {
1335         dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
1336 }
1337
1338 static void cdDM_drawMappedFacesMat(DerivedMesh *dm,
1339                                     void (*setMaterial)(void *userData, int, void *attribs),
1340                                     int (*setFace)(void *userData, int index), void *userData)
1341 {
1342         CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
1343         GPUVertexAttribs gattribs;
1344         DMVertexAttribs attribs;
1345         MVert *mvert = cddm->mvert;
1346         MFace *mf = cddm->mface;
1347         float (*nors)[3] = dm->getTessFaceDataArray(dm, CD_NORMAL);
1348         int a, matnr, new_matnr;
1349         int orig;
1350
1351         /* double lookup */
1352         const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
1353         const int *index_mp_to_orig  = dm->getPolyDataArray(dm, CD_ORIGINDEX);
1354         if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) {
1355                 index_mf_to_mpoly = index_mp_to_orig = NULL;
1356         }
1357
1358         cdDM_update_normals_from_pbvh(dm);
1359
1360         matnr = -1;
1361
1362         glShadeModel(GL_SMOOTH);
1363
1364         memset(&attribs, 0, sizeof(attribs));
1365
1366         glBegin(GL_QUADS);
1367
1368         for (a = 0; a < dm->numTessFaceData; a++, mf++) {
1369                 const int smoothnormal = (mf->flag & ME_SMOOTH);
1370
1371                 /* material */
1372                 new_matnr = mf->mat_nr + 1;
1373
1374                 if (new_matnr != matnr) {
1375                         glEnd();
1376
1377                         setMaterial(userData, matnr = new_matnr, &gattribs);
1378                         DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1379
1380                         glBegin(GL_QUADS);
1381                 }
1382
1383                 /* skipping faces */
1384                 if (setFace) {
1385                         orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, a) : a;
1386
1387                         if (orig != ORIGINDEX_NONE && !setFace(userData, orig))
1388                                 continue;
1389                 }
1390
1391                 /* smooth normal */
1392                 if (!smoothnormal) {
1393                         if (nors) {
1394                                 glNormal3fv(nors[a]);
1395                         }
1396                         else {
1397                                 /* TODO ideally a normal layer should always be available */
1398                                 float nor[3];
1399
1400                                 if (mf->v4)
1401                                         normal_quad_v3(nor, mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co, mvert[mf->v4].co);
1402                                 else
1403                                         normal_tri_v3(nor, mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co);
1404
1405                                 glNormal3fv(nor);
1406                         }
1407                 }
1408
1409                 /* vertices */
1410                 cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v1, 0, smoothnormal);
1411                 cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v2, 1, smoothnormal);
1412                 cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v3, 2, smoothnormal);
1413
1414                 if (mf->v4)
1415                         cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v4, 3, smoothnormal);
1416                 else
1417                         cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v3, 2, smoothnormal);
1418         }
1419         glEnd();
1420
1421         glShadeModel(GL_FLAT);
1422 }
1423
1424 static void cdDM_drawMappedEdges(DerivedMesh *dm, DMSetDrawOptions setDrawOptions, void *userData)
1425 {
1426         CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
1427         MVert *vert = cddm->mvert;
1428         MEdge *edge = cddm->medge;
1429         int i, orig, *index = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
1430
1431         glBegin(GL_LINES);
1432         for (i = 0; i < dm->numEdgeData; i++, edge++) {
1433                 if (index) {
1434                         orig = *index++;
1435                         if (setDrawOptions && orig == ORIGINDEX_NONE) continue;
1436                 }
1437                 else
1438                         orig = i;
1439
1440                 if (!setDrawOptions || (setDrawOptions(userData, orig) != DM_DRAW_OPTION_SKIP)) {
1441                         glVertex3fv(vert[edge->v1].co);
1442                         glVertex3fv(vert[edge->v2].co);
1443                 }
1444         }
1445         glEnd();
1446 }
1447
1448 static void cdDM_foreachMappedVert(
1449         DerivedMesh *dm,
1450         void (*func)(void *userData, int index, const float co[3], const float no_f[3], const short no_s[3]),
1451         void *userData)
1452 {
1453         MVert *mv = CDDM_get_verts(dm);
1454         int i, orig, *index = DM_get_vert_data_layer(dm, CD_ORIGINDEX);
1455
1456         for (i = 0; i < dm->numVertData; i++, mv++) {
1457                 if (index) {
1458                         orig = *index++;
1459                         if (orig == ORIGINDEX_NONE) continue;
1460                         func(userData, orig, mv->co, NULL, mv->no);
1461                 }
1462                 else
1463                         func(userData, i, mv->co, NULL, mv->no);
1464         }
1465 }
1466
1467 static void cdDM_foreachMappedEdge(
1468         DerivedMesh *dm,
1469         void (*func)(void *userData, int index, const float v0co[3], const float v1co[3]),
1470         void *userData)
1471 {
1472         CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
1473         MVert *mv = cddm->mvert;
1474         MEdge *med = cddm->medge;
1475         int i, orig, *index = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
1476
1477         for (i = 0; i < dm->numEdgeData; i++, med++) {
1478                 if (index) {
1479                         orig = *index++;
1480                         if (orig == ORIGINDEX_NONE) continue;
1481                         func(userData, orig, mv[med->v1].co, mv[med->v2].co);
1482                 }
1483                 else
1484                         func(userData, i, mv[med->v1].co, mv[med->v2].co);
1485         }
1486 }
1487
1488 static void cdDM_foreachMappedFaceCenter(
1489         DerivedMesh *dm,
1490         void (*func)(void *userData, int index, const float cent[3], const float no[3]),
1491         void *userData)
1492 {
1493         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
1494         MVert *mvert = cddm->mvert;
1495         MPoly *mp;
1496         MLoop *ml;
1497         int i, j, orig, *index;
1498
1499         index = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
1500         mp = cddm->mpoly;
1501         for (i = 0; i < dm->numPolyData; i++, mp++) {
1502                 float cent[3];
1503                 float no[3];
1504
1505                 if (index) {
1506                         orig = *index++;
1507                         if (orig == ORIGINDEX_NONE) continue;
1508                 }
1509                 else
1510                         orig = i;
1511                 
1512                 ml = &cddm->mloop[mp->loopstart];
1513                 cent[0] = cent[1] = cent[2] = 0.0f;
1514                 for (j = 0; j < mp->totloop; j++, ml++) {
1515                         add_v3_v3v3(cent, cent, mvert[ml->v].co);
1516                 }
1517                 mul_v3_fl(cent, 1.0f / (float)j);
1518
1519                 ml = &cddm->mloop[mp->loopstart];
1520                 if (j > 3) {
1521                         normal_quad_v3(no,
1522                                        mvert[(ml + 0)->v].co,
1523                                        mvert[(ml + 1)->v].co,
1524                                        mvert[(ml + 2)->v].co,
1525                                        mvert[(ml + 3)->v].co);
1526                 }
1527                 else {
1528                         normal_tri_v3(no,
1529                                       mvert[(ml + 0)->v].co,
1530                                       mvert[(ml + 1)->v].co,
1531                                       mvert[(ml + 2)->v].co);
1532                 }
1533
1534                 func(userData, orig, cent, no);
1535         }
1536
1537 }
1538
1539 void CDDM_recalc_tessellation_ex(DerivedMesh *dm, const int do_face_nor_cpy)
1540 {
1541         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
1542
1543         dm->numTessFaceData = BKE_mesh_recalc_tessellation(&dm->faceData, &dm->loopData, &dm->polyData,
1544                                                            cddm->mvert,
1545                                                            dm->numTessFaceData, dm->numLoopData, dm->numPolyData,
1546                                                            do_face_nor_cpy);
1547
1548         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1549
1550         /* Tessellation recreated faceData, and the active layer indices need to get re-propagated
1551          * from loops and polys to faces */
1552         CustomData_bmesh_update_active_layers(&dm->faceData, &dm->polyData, &dm->loopData);
1553 }
1554
1555 void CDDM_recalc_tessellation(DerivedMesh *dm)
1556 {
1557         CDDM_recalc_tessellation_ex(dm, TRUE);
1558 }
1559
1560 static void cdDM_free_internal(CDDerivedMesh *cddm)
1561 {
1562         if (cddm->pmap) MEM_freeN(cddm->pmap);
1563         if (cddm->pmap_mem) MEM_freeN(cddm->pmap_mem);
1564 }
1565
1566 static void cdDM_release(DerivedMesh *dm)
1567 {
1568         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
1569
1570         if (DM_release(dm)) {
1571                 cdDM_free_internal(cddm);
1572                 MEM_freeN(cddm);
1573         }
1574 }
1575
1576 int CDDM_Check(DerivedMesh *dm)
1577 {
1578         return dm && dm->getMinMax == cdDM_getMinMax;
1579 }
1580
1581 /**************** CDDM interface functions ****************/
1582 static CDDerivedMesh *cdDM_create(const char *desc)
1583 {
1584         CDDerivedMesh *cddm;
1585         DerivedMesh *dm;
1586
1587         cddm = MEM_callocN(sizeof(*cddm), desc);
1588         dm = &cddm->dm;
1589
1590         dm->getMinMax = cdDM_getMinMax;
1591
1592         dm->getNumVerts = cdDM_getNumVerts;
1593         dm->getNumEdges = cdDM_getNumEdges;
1594         dm->getNumTessFaces = cdDM_getNumTessFaces;
1595         dm->getNumLoops = cdDM_getNumLoops;
1596         dm->getNumPolys = cdDM_getNumPolys;
1597
1598         dm->getVert = cdDM_getVert;
1599         dm->getEdge = cdDM_getEdge;
1600         dm->getTessFace = cdDM_getTessFace;
1601
1602         dm->copyVertArray = cdDM_copyVertArray;
1603         dm->copyEdgeArray = cdDM_copyEdgeArray;
1604         dm->copyTessFaceArray = cdDM_copyTessFaceArray;
1605         dm->copyLoopArray = cdDM_copyLoopArray;
1606         dm->copyPolyArray = cdDM_copyPolyArray;
1607
1608         dm->getVertData = DM_get_vert_data;
1609         dm->getEdgeData = DM_get_edge_data;
1610         dm->getTessFaceData = DM_get_tessface_data;
1611         dm->getVertDataArray = DM_get_vert_data_layer;
1612         dm->getEdgeDataArray = DM_get_edge_data_layer;
1613         dm->getTessFaceDataArray = DM_get_tessface_data_layer;
1614
1615         dm->calcNormals = CDDM_calc_normals_mapping;
1616         dm->recalcTessellation = CDDM_recalc_tessellation;
1617
1618         dm->getVertCos = cdDM_getVertCos;
1619         dm->getVertCo = cdDM_getVertCo;
1620         dm->getVertNo = cdDM_getVertNo;
1621
1622         dm->getPBVH = cdDM_getPBVH;
1623         dm->getPolyMap = cdDM_getPolyMap;
1624
1625         dm->drawVerts = cdDM_drawVerts;
1626
1627         dm->drawUVEdges = cdDM_drawUVEdges;
1628         dm->drawEdges = cdDM_drawEdges;
1629         dm->drawLooseEdges = cdDM_drawLooseEdges;
1630         dm->drawMappedEdges = cdDM_drawMappedEdges;
1631
1632         dm->drawFacesSolid = cdDM_drawFacesSolid;
1633         dm->drawFacesTex = cdDM_drawFacesTex;
1634         dm->drawFacesGLSL = cdDM_drawFacesGLSL;
1635         dm->drawMappedFaces = cdDM_drawMappedFaces;
1636         dm->drawMappedFacesTex = cdDM_drawMappedFacesTex;
1637         dm->drawMappedFacesGLSL = cdDM_drawMappedFacesGLSL;
1638         dm->drawMappedFacesMat = cdDM_drawMappedFacesMat;
1639
1640         dm->foreachMappedVert = cdDM_foreachMappedVert;
1641         dm->foreachMappedEdge = cdDM_foreachMappedEdge;
1642         dm->foreachMappedFaceCenter = cdDM_foreachMappedFaceCenter;
1643
1644         dm->release = cdDM_release;
1645
1646         return cddm;
1647 }
1648
1649 DerivedMesh *CDDM_new(int numVerts, int numEdges, int numTessFaces, int numLoops, int numPolys)
1650 {
1651         CDDerivedMesh *cddm = cdDM_create("CDDM_new dm");
1652         DerivedMesh *dm = &cddm->dm;
1653
1654         DM_init(dm, DM_TYPE_CDDM, numVerts, numEdges, numTessFaces, numLoops, numPolys);
1655
1656         CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts);
1657         CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
1658         CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numTessFaces);
1659         CustomData_add_layer(&dm->polyData, CD_ORIGINDEX, CD_CALLOC, NULL, numPolys);
1660
1661         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
1662         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
1663         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numTessFaces);
1664         CustomData_add_layer(&dm->loopData, CD_MLOOP, CD_CALLOC, NULL, numLoops);
1665         CustomData_add_layer(&dm->polyData, CD_MPOLY, CD_CALLOC, NULL, numPolys);
1666
1667         cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
1668         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
1669         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1670         cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
1671         cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
1672
1673         return dm;
1674 }
1675
1676 DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *UNUSED(ob))
1677 {
1678         CDDerivedMesh *cddm = cdDM_create("CDDM_from_mesh dm");
1679         DerivedMesh *dm = &cddm->dm;
1680         CustomDataMask mask = CD_MASK_MESH & (~CD_MASK_MDISPS);
1681         int alloctype;
1682
1683         /* this does a referenced copy, with an exception for fluidsim */
1684
1685         DM_init(dm, DM_TYPE_CDDM, mesh->totvert, mesh->totedge, mesh->totface,
1686                 mesh->totloop, mesh->totpoly);
1687
1688         dm->deformedOnly = 1;
1689
1690         alloctype = CD_REFERENCE;
1691
1692         CustomData_merge(&mesh->vdata, &dm->vertData, mask, alloctype,
1693                          mesh->totvert);
1694         CustomData_merge(&mesh->edata, &dm->edgeData, mask, alloctype,
1695                          mesh->totedge);
1696         CustomData_merge(&mesh->fdata, &dm->faceData, mask | CD_MASK_ORIGINDEX, alloctype,
1697                          mesh->totface);
1698         CustomData_merge(&mesh->ldata, &dm->loopData, mask, alloctype,
1699                          mesh->totloop);
1700         CustomData_merge(&mesh->pdata, &dm->polyData, mask, alloctype,
1701                          mesh->totpoly);
1702
1703         cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
1704         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
1705         cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
1706         cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
1707         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1708
1709         /* commented since even when CD_ORIGINDEX was first added this line fails
1710          * on the default cube, (after editmode toggle too) - campbell */
1711 #if 0
1712         BLI_assert(CustomData_has_layer(&cddm->dm.faceData, CD_ORIGINDEX));
1713 #endif
1714
1715         return dm;
1716 }
1717
1718 DerivedMesh *CDDM_from_curve(Object *ob)
1719 {
1720         return CDDM_from_curve_displist(ob, &ob->disp, NULL);
1721 }
1722
1723 DerivedMesh *CDDM_from_curve_orco(struct Scene *scene, Object *ob)
1724 {
1725         int *orco_index_ptr = NULL;
1726         int (*orco_index)[4] = NULL;
1727         float (*orco)[3] = NULL;
1728         DerivedMesh *dm = CDDM_from_curve_displist(ob, &ob->disp, &orco_index_ptr);
1729
1730         if (orco_index_ptr) {
1731                 orco = (float (*)[3])BKE_curve_make_orco(scene, ob);
1732         }
1733
1734         if (orco && orco_index_ptr) {
1735                 const char *uvname = "Orco";
1736
1737                 int totpoly = dm->getNumPolys(dm);
1738
1739                 MPoly *mpolys = dm->getPolyArray(dm);
1740                 MLoop *mloops = dm->getLoopArray(dm);
1741
1742                 MLoopUV *mloopuvs;
1743
1744                 CustomData_add_layer_named(&dm->polyData, CD_MTEXPOLY, CD_DEFAULT, NULL, dm->numPolyData, uvname);
1745                 mloopuvs = CustomData_add_layer_named(&dm->loopData, CD_MLOOPUV,  CD_DEFAULT, NULL, dm->numLoopData, uvname);
1746
1747                 BKE_mesh_nurbs_to_mdata_orco(mpolys, totpoly,
1748                                              mloops, mloopuvs,
1749                                              orco, orco_index);
1750         }
1751
1752         if (orco_index) {
1753                 MEM_freeN(orco_index);
1754         }
1755         if (orco) {
1756                 MEM_freeN(orco);
1757         }
1758
1759         return dm;
1760 }
1761
1762 DerivedMesh *CDDM_from_curve_displist(Object *ob, ListBase *dispbase, int **orco_index_ptr)
1763 {
1764         DerivedMesh *dm;
1765         CDDerivedMesh *cddm;
1766         MVert *allvert;
1767         MEdge *alledge;
1768         MLoop *allloop;
1769         MPoly *allpoly;
1770         int totvert, totedge, totloop, totpoly;
1771
1772         if (BKE_mesh_nurbs_displist_to_mdata(ob, dispbase, &allvert, &totvert, &alledge,
1773                                              &totedge, &allloop, &allpoly, &totloop, &totpoly, orco_index_ptr) != 0)
1774         {
1775                 /* Error initializing mdata. This often happens when curve is empty */
1776                 return CDDM_new(0, 0, 0, 0, 0);
1777         }
1778
1779         dm = CDDM_new(totvert, totedge, 0, totloop, totpoly);
1780         dm->deformedOnly = 1;
1781
1782         cddm = (CDDerivedMesh *)dm;
1783
1784         memcpy(cddm->mvert, allvert, totvert * sizeof(MVert));
1785         memcpy(cddm->medge, alledge, totedge * sizeof(MEdge));
1786         memcpy(cddm->mloop, allloop, totloop * sizeof(MLoop));
1787         memcpy(cddm->mpoly, allpoly, totpoly * sizeof(MPoly));
1788
1789         MEM_freeN(allvert);
1790         MEM_freeN(alledge);
1791         MEM_freeN(allloop);
1792         MEM_freeN(allpoly);
1793
1794         CDDM_calc_edges(dm);
1795
1796         return dm;
1797 }
1798
1799 static void loops_to_customdata_corners(BMesh *bm, CustomData *facedata,
1800                                         int cdindex, const BMLoop *l3[3],
1801                                         int numCol, int numTex)
1802 {
1803         const BMLoop *l;
1804         BMFace *f = l3[0]->f;
1805         MTFace *texface;
1806         MTexPoly *texpoly;
1807         MCol *mcol;
1808         MLoopCol *mloopcol;
1809         MLoopUV *mloopuv;
1810         int i, j, hasPCol = CustomData_has_layer(&bm->ldata, CD_PREVIEW_MLOOPCOL);
1811
1812         for (i = 0; i < numTex; i++) {
1813                 texface = CustomData_get_n(facedata, CD_MTFACE, cdindex, i);
1814                 texpoly = CustomData_bmesh_get_n(&bm->pdata, f->head.data, CD_MTEXPOLY, i);
1815                 
1816                 ME_MTEXFACE_CPY(texface, texpoly);
1817         
1818                 for (j = 0; j < 3; j++) {
1819                         l = l3[j];
1820                         mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_MLOOPUV, i);
1821                         copy_v2_v2(texface->uv[j], mloopuv->uv);
1822                 }
1823         }
1824
1825         for (i = 0; i < numCol; i++) {
1826                 mcol = CustomData_get_n(facedata, CD_MCOL, cdindex, i);
1827                 
1828                 for (j = 0; j < 3; j++) {
1829                         l = l3[j];
1830                         mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_MLOOPCOL, i);
1831                         MESH_MLOOPCOL_TO_MCOL(mloopcol, &mcol[j]);
1832                 }
1833         }
1834
1835         if (hasPCol) {
1836                 mcol = CustomData_get(facedata, cdindex, CD_PREVIEW_MCOL);
1837
1838                 for (j = 0; j < 3; j++) {
1839                         l = l3[j];
1840                         mloopcol = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PREVIEW_MLOOPCOL);
1841                         MESH_MLOOPCOL_TO_MCOL(mloopcol, &mcol[j]);
1842                 }
1843         }
1844 }
1845
1846 /* used for both editbmesh and bmesh */
1847 static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps,
1848                                        /* EditBMesh vars for use_tessface */
1849                                        int use_tessface,
1850                                        const int em_tottri, const BMLoop *(*em_looptris)[3]
1851                                        )
1852 {
1853         DerivedMesh *dm = CDDM_new(bm->totvert,
1854                                    bm->totedge,
1855                                    use_tessface ? em_tottri : 0,
1856                                    bm->totloop,
1857                                    bm->totface);
1858
1859         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
1860         BMIter iter, liter;
1861         BMVert *eve;
1862         BMEdge *eed;
1863         BMFace *efa;
1864         MVert *mvert = cddm->mvert;
1865         MEdge *medge = cddm->medge;
1866         MFace *mface = cddm->mface;
1867         MLoop *mloop = cddm->mloop;
1868         MPoly *mpoly = cddm->mpoly;
1869         int numCol = CustomData_number_of_layers(&bm->ldata, CD_MLOOPCOL);
1870         int numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY);
1871         int *index, add_orig;
1872         int has_crease, has_edge_bweight, has_vert_bweight;
1873         CustomDataMask mask;
1874         unsigned int i, j;
1875         
1876         has_edge_bweight = CustomData_has_layer(&bm->edata, CD_BWEIGHT);
1877         has_vert_bweight = CustomData_has_layer(&bm->vdata, CD_BWEIGHT);
1878         has_crease = CustomData_has_layer(&bm->edata, CD_CREASE);
1879         
1880         dm->deformedOnly = 1;
1881         
1882         /* don't add origindex layer if one already exists */
1883         add_orig = !CustomData_has_layer(&bm->pdata, CD_ORIGINDEX);
1884
1885         mask = use_mdisps ? CD_MASK_DERIVEDMESH | CD_MASK_MDISPS : CD_MASK_DERIVEDMESH;
1886         
1887         /* don't process shapekeys, we only feed them through the modifier stack as needed,
1888          * e.g. for applying modifiers or the like*/
1889         mask &= ~CD_MASK_SHAPEKEY;
1890         CustomData_merge(&bm->vdata, &dm->vertData, mask,
1891                          CD_CALLOC, dm->numVertData);
1892         CustomData_merge(&bm->edata, &dm->edgeData, mask,
1893                          CD_CALLOC, dm->numEdgeData);
1894         CustomData_merge(&bm->ldata, &dm->loopData, mask,
1895                          CD_CALLOC, dm->numLoopData);
1896         CustomData_merge(&bm->pdata, &dm->polyData, mask,
1897                          CD_CALLOC, dm->numPolyData);
1898         
1899         /* add tessellation mface layers */
1900         if (use_tessface) {
1901                 CustomData_from_bmeshpoly(&dm->faceData, &dm->polyData, &dm->loopData, em_tottri);
1902         }
1903
1904         index = dm->getVertDataArray(dm, CD_ORIGINDEX);
1905
1906         eve = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL);
1907         for (i = 0; eve; eve = BM_iter_step(&iter), i++, index++) {
1908                 MVert *mv = &mvert[i];
1909
1910                 copy_v3_v3(mv->co, eve->co);
1911
1912                 BM_elem_index_set(eve, i); /* set_inline */
1913
1914                 normal_float_to_short_v3(mv->no, eve->no);
1915
1916                 mv->flag = BM_vert_flag_to_mflag(eve);
1917
1918                 if (has_vert_bweight)
1919                         mv->bweight = (unsigned char)(BM_elem_float_data_get(&bm->vdata, eve, CD_BWEIGHT) * 255.0f);
1920
1921                 if (add_orig) *index = i;
1922
1923                 CustomData_from_bmesh_block(&bm->vdata, &dm->vertData, eve->head.data, i);
1924         }
1925         bm->elem_index_dirty &= ~BM_VERT;
1926
1927         index = dm->getEdgeDataArray(dm, CD_ORIGINDEX);
1928         eed = BM_iter_new(&iter, bm, BM_EDGES_OF_MESH, NULL);
1929         for (i = 0; eed; eed = BM_iter_step(&iter), i++, index++) {
1930                 MEdge *med = &medge[i];
1931
1932                 BM_elem_index_set(eed, i); /* set_inline */
1933
1934                 med->v1 = BM_elem_index_get(eed->v1);
1935                 med->v2 = BM_elem_index_get(eed->v2);
1936
1937                 if (has_crease)
1938                         med->crease = (unsigned char)(BM_elem_float_data_get(&bm->edata, eed, CD_CREASE) * 255.0f);
1939                 if (has_edge_bweight)
1940                         med->bweight = (unsigned char)(BM_elem_float_data_get(&bm->edata, eed, CD_BWEIGHT) * 255.0f);
1941                 
1942                 med->flag = BM_edge_flag_to_mflag(eed);
1943
1944                 /* handle this differently to editmode switching,
1945                  * only enable draw for single user edges rather then calculating angle */
1946                 if ((med->flag & ME_EDGEDRAW) == 0) {
1947                         if (eed->l && eed->l == eed->l->radial_next) {
1948                                 med->flag |= ME_EDGEDRAW;
1949                         }
1950                 }
1951
1952                 CustomData_from_bmesh_block(&bm->edata, &dm->edgeData, eed->head.data, i);
1953                 if (add_orig) *index = i;
1954         }
1955         bm->elem_index_dirty &= ~BM_EDGE;
1956
1957         /* avoid this where possiblem, takes extra memory */
1958         if (use_tessface) {
1959                 int *polyindex;
1960
1961                 BM_mesh_elem_index_ensure(bm, BM_FACE);
1962
1963                 index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
1964                 for (i = 0; i < dm->numTessFaceData; i++, index++, polyindex++) {
1965                         MFace *mf = &mface[i];
1966                         const BMLoop **l = em_looptris[i];
1967                         efa = l[0]->f;
1968
1969                         mf->v1 = BM_elem_index_get(l[0]->v);
1970                         mf->v2 = BM_elem_index_get(l[1]->v);
1971                         mf->v3 = BM_elem_index_get(l[2]->v);
1972                         mf->v4 = 0;
1973                         mf->mat_nr = efa->mat_nr;
1974                         mf->flag = BM_face_flag_to_mflag(efa);
1975
1976                         /* map mfaces to polygons in the same cddm intentionally */
1977                         *index = BM_elem_index_get(efa);
1978
1979                         loops_to_customdata_corners(bm, &dm->faceData, i, l, numCol, numTex);
1980                         test_index_face(mf, &dm->faceData, i, 3);
1981                 }
1982         }
1983         
1984         index = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
1985         j = 0;
1986         efa = BM_iter_new(&iter, bm, BM_FACES_OF_MESH, NULL);
1987         for (i = 0; efa; i++, efa = BM_iter_step(&iter), index++) {
1988                 BMLoop *l;
1989                 MPoly *mp = &mpoly[i];
1990
1991                 BM_elem_index_set(efa, i); /* set_inline */
1992
1993                 mp->totloop = efa->len;
1994                 mp->flag = BM_face_flag_to_mflag(efa);
1995                 mp->loopstart = j;
1996                 mp->mat_nr = efa->mat_nr;
1997                 
1998                 BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
1999                         mloop->v = BM_elem_index_get(l->v);
2000                         mloop->e = BM_elem_index_get(l->e);
2001                         CustomData_from_bmesh_block(&bm->ldata, &dm->loopData, l->head.data, j);
2002
2003                         j++;
2004                         mloop++;
2005                 }
2006
2007                 CustomData_from_bmesh_block(&bm->pdata, &dm->polyData, efa->head.data, i);
2008
2009                 if (add_orig) *index = i;
2010         }
2011         bm->elem_index_dirty &= ~BM_FACE;
2012
2013         return dm;
2014 }
2015
2016 struct DerivedMesh *CDDM_from_bmesh(struct BMesh *bm, int use_mdisps)
2017 {
2018         return cddm_from_bmesh_ex(bm, use_mdisps, FALSE,
2019                                   /* these vars are for editmesh only */
2020                                   0, NULL);
2021 }
2022
2023 DerivedMesh *CDDM_from_editbmesh(BMEditMesh *em, int use_mdisps, int use_tessface)
2024 {
2025         return cddm_from_bmesh_ex(em->bm, use_mdisps,
2026                                   /* editmesh */
2027                                   use_tessface, em->tottri, (const BMLoop *(*)[3])em->looptris);
2028 }
2029
2030 static DerivedMesh *cddm_copy_ex(DerivedMesh *source, int faces_from_tessfaces)
2031 {
2032         CDDerivedMesh *cddm = cdDM_create("CDDM_copy cddm");
2033         DerivedMesh *dm = &cddm->dm;
2034         int numVerts = source->numVertData;
2035         int numEdges = source->numEdgeData;
2036         int numTessFaces = source->numTessFaceData;
2037         int numLoops = source->numLoopData;
2038         int numPolys = source->numPolyData;
2039
2040         /* ensure these are created if they are made on demand */
2041         source->getVertDataArray(source, CD_ORIGINDEX);
2042         source->getEdgeDataArray(source, CD_ORIGINDEX);
2043         source->getTessFaceDataArray(source, CD_ORIGINDEX);
2044         source->getPolyDataArray(source, CD_ORIGINDEX);
2045
2046         /* this initializes dm, and copies all non mvert/medge/mface layers */
2047         DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numTessFaces,
2048                          numLoops, numPolys);
2049         dm->deformedOnly = source->deformedOnly;
2050         dm->dirty = source->dirty;
2051
2052         CustomData_copy_data(&source->vertData, &dm->vertData, 0, 0, numVerts);
2053         CustomData_copy_data(&source->edgeData, &dm->edgeData, 0, 0, numEdges);
2054         CustomData_copy_data(&source->faceData, &dm->faceData, 0, 0, numTessFaces);
2055
2056         /* now add mvert/medge/mface layers */
2057         cddm->mvert = source->dupVertArray(source);
2058         cddm->medge = source->dupEdgeArray(source);
2059         cddm->mface = source->dupTessFaceArray(source);
2060
2061         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_ASSIGN, cddm->mvert, numVerts);
2062         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_ASSIGN, cddm->medge, numEdges);
2063         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_ASSIGN, cddm->mface, numTessFaces);
2064         
2065         if (!faces_from_tessfaces)
2066                 DM_DupPolys(source, dm);
2067         else
2068                 CDDM_tessfaces_to_faces(dm);
2069
2070         cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
2071         cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
2072
2073         return dm;
2074 }
2075
2076 DerivedMesh *CDDM_copy(DerivedMesh *source)
2077 {
2078         return cddm_copy_ex(source, 0);
2079 }
2080
2081 DerivedMesh *CDDM_copy_from_tessface(DerivedMesh *source)
2082 {
2083         return cddm_copy_ex(source, 1);
2084 }
2085
2086 /* note, the CD_ORIGINDEX layers are all 0, so if there is a direct
2087  * relationship between mesh data this needs to be set by the caller. */
2088 DerivedMesh *CDDM_from_template(DerivedMesh *source,
2089                                 int numVerts, int numEdges, int numTessFaces,
2090                                 int numLoops, int numPolys)
2091 {
2092         CDDerivedMesh *cddm = cdDM_create("CDDM_from_template dest");
2093         DerivedMesh *dm = &cddm->dm;
2094
2095         /* ensure these are created if they are made on demand */
2096         source->getVertDataArray(source, CD_ORIGINDEX);
2097         source->getEdgeDataArray(source, CD_ORIGINDEX);
2098         source->getTessFaceDataArray(source, CD_ORIGINDEX);
2099         source->getPolyDataArray(source, CD_ORIGINDEX);
2100
2101         /* this does a copy of all non mvert/medge/mface layers */
2102         DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numTessFaces, numLoops, numPolys);
2103
2104         /* now add mvert/medge/mface layers */
2105         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
2106         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
2107         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numTessFaces);
2108         CustomData_add_layer(&dm->loopData, CD_MLOOP, CD_CALLOC, NULL, numLoops);
2109         CustomData_add_layer(&dm->polyData, CD_MPOLY, CD_CALLOC, NULL, numPolys);
2110
2111         if (!CustomData_get_layer(&dm->vertData, CD_ORIGINDEX))
2112                 CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts);
2113         if (!CustomData_get_layer(&dm->edgeData, CD_ORIGINDEX))
2114                 CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
2115         if (!CustomData_get_layer(&dm->faceData, CD_ORIGINDEX))
2116                 CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numTessFaces);
2117
2118         cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
2119         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
2120         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
2121         cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
2122         cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
2123
2124         return dm;
2125 }
2126
2127 void CDDM_apply_vert_coords(DerivedMesh *dm, float (*vertCoords)[3])
2128 {
2129         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2130         MVert *vert;
2131         int i;
2132
2133         /* this will just return the pointer if it wasn't a referenced layer */
2134         vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2135         cddm->mvert = vert;
2136
2137         for (i = 0; i < dm->numVertData; ++i, ++vert)
2138                 copy_v3_v3(vert->co, vertCoords[i]);
2139 }
2140
2141 void CDDM_apply_vert_normals(DerivedMesh *dm, short (*vertNormals)[3])
2142 {
2143         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2144         MVert *vert;
2145         int i;
2146
2147         /* this will just return the pointer if it wasn't a referenced layer */
2148         vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2149         cddm->mvert = vert;
2150
2151         for (i = 0; i < dm->numVertData; ++i, ++vert)
2152                 copy_v3_v3_short(vert->no, vertNormals[i]);
2153 }
2154
2155 void CDDM_calc_normals_mapping_ex(DerivedMesh *dm, const short only_face_normals)
2156 {
2157         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2158         float (*face_nors)[3] = NULL;
2159
2160         if (dm->numVertData == 0) return;
2161
2162         /* now we skip calculating vertex normals for referenced layer,
2163          * no need to duplicate verts.
2164          * WATCH THIS, bmesh only change!,
2165          * need to take care of the side effects here - campbell */
2166         #if 0
2167         /* we don't want to overwrite any referenced layers */
2168         cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2169         #endif
2170
2171
2172         if (dm->numTessFaceData == 0) {
2173                 /* No tessellation on this mesh yet, need to calculate one.
2174                  *
2175                  * Important not to update face normals from polys since it
2176                  * interferes with assigning the new normal layer in the following code.
2177                  */
2178                 CDDM_recalc_tessellation_ex(dm, FALSE);
2179         }
2180         else {
2181                 /* A tessellation already exists, it should always have a CD_ORIGINDEX */
2182                 BLI_assert(CustomData_has_layer(&dm->faceData, CD_ORIGINDEX));
2183                 CustomData_free_layers(&dm->faceData, CD_NORMAL, dm->numTessFaceData);
2184         }
2185
2186
2187         face_nors = MEM_mallocN(sizeof(float) * 3 * dm->numTessFaceData, "face_nors");
2188
2189         /* calculate face normals */
2190         BKE_mesh_calc_normals_mapping_ex(cddm->mvert, dm->numVertData, CDDM_get_loops(dm), CDDM_get_polys(dm),
2191                                          dm->numLoopData, dm->numPolyData, NULL, cddm->mface, dm->numTessFaceData,
2192                                          CustomData_get_layer(&dm->faceData, CD_ORIGINDEX), face_nors,
2193                                          only_face_normals);
2194
2195         CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_ASSIGN,
2196                              face_nors, dm->numTessFaceData);
2197 }
2198
2199
2200 void CDDM_calc_normals_mapping(DerivedMesh *dm)
2201 {
2202         /* use this to skip calculating normals on original vert's, this may need to be changed */
2203         const short only_face_normals = CustomData_is_referenced_layer(&dm->vertData, CD_MVERT);
2204
2205         CDDM_calc_normals_mapping_ex(dm, only_face_normals);
2206 }
2207
2208 /* bmesh note: this matches what we have in trunk */
2209 void CDDM_calc_normals(DerivedMesh *dm)
2210 {
2211         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2212         float (*poly_nors)[3];
2213
2214         if (dm->numVertData == 0) return;
2215
2216         /* we don't want to overwrite any referenced layers */
2217         cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2218
2219         /* fill in if it exists */
2220         poly_nors = CustomData_get_layer(&dm->polyData, CD_NORMAL);
2221         if (!poly_nors) {
2222                 poly_nors = CustomData_add_layer(&dm->polyData, CD_NORMAL, CD_CALLOC, NULL, dm->numPolyData);
2223         }
2224
2225         BKE_mesh_calc_normals(cddm->mvert, dm->numVertData, CDDM_get_loops(dm), CDDM_get_polys(dm),
2226                               dm->numLoopData, dm->numPolyData, poly_nors);
2227 }
2228
2229 void CDDM_calc_normals_tessface(DerivedMesh *dm)
2230 {
2231         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2232         float (*face_nors)[3];
2233
2234         if (dm->numVertData == 0) return;
2235
2236         /* we don't want to overwrite any referenced layers */
2237         cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2238
2239         /* fill in if it exists */
2240         face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL);
2241         if (!face_nors) {
2242                 face_nors = CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_CALLOC, NULL, dm->numTessFaceData);
2243         }
2244
2245         BKE_mesh_calc_normals_tessface(cddm->mvert, dm->numVertData,
2246                                        cddm->mface, dm->numTessFaceData, face_nors);
2247 }
2248
2249 #if 1
2250 /* merge verts
2251  *
2252  * vtargetmap is a table that maps vertices to target vertices.  a value of -1
2253  * indicates a vertex is a target, and is to be kept.
2254  *
2255  * this frees dm, and returns a new one.
2256  *
2257  * this is a really horribly written function.  ger. - joeedh
2258  *
2259  * note, CDDM_recalc_tessellation has to run on the returned DM if you want to access tessfaces.
2260  */
2261 DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap)
2262 {
2263         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2264         CDDerivedMesh *cddm2 = NULL;
2265         MVert *mv, *mvert = NULL;
2266         BLI_array_declare(mvert);
2267         MEdge *med, *medge = NULL;
2268         BLI_array_declare(medge);
2269         MPoly *mp, *mpoly = NULL;
2270         BLI_array_declare(mpoly);
2271         MLoop *ml, *mloop = NULL;
2272         BLI_array_declare(mloop);
2273         EdgeHash *ehash = BLI_edgehash_new();
2274         int *newv = NULL, *newe = NULL, *newl = NULL;
2275         int *oldv = NULL, *olde = NULL, *oldl = NULL, *oldp = NULL;
2276         BLI_array_declare(oldv); BLI_array_declare(olde); BLI_array_declare(oldl); BLI_array_declare(oldp);
2277         int i, j, c, totloop, totpoly;
2278         
2279         totloop = dm->numLoopData;
2280         totpoly = dm->numPolyData;
2281         
2282         newv = MEM_callocN(sizeof(int) * dm->numVertData, "newv vtable CDDM_merge_verts");
2283         newe = MEM_callocN(sizeof(int) * dm->numEdgeData, "newv etable CDDM_merge_verts");
2284         newl = MEM_callocN(sizeof(int) * totloop, "newv ltable CDDM_merge_verts");
2285         
2286         /* fill newl with destination vertex indices */
2287         mv = cddm->mvert;
2288         c = 0;
2289         for (i = 0; i < dm->numVertData; i++, mv++) {
2290                 if (vtargetmap[i] == -1) {
2291                         BLI_array_append(oldv, i);
2292                         newv[i] = c++;
2293                         BLI_array_append(mvert, *mv);
2294                 }
2295         }
2296         
2297         /* now link target vertices to destination indices */
2298         for (i = 0; i < dm->numVertData; i++) {
2299                 if (vtargetmap[i] != -1) {
2300                         newv[i] = newv[vtargetmap[i]];
2301                 }
2302         }
2303         
2304         /* find-replace merged vertices with target vertices */
2305         ml = cddm->mloop;
2306         for (i = 0; i < totloop; i++, ml++) {
2307                 if (vtargetmap[ml->v] != -1) {
2308                         ml->v = vtargetmap[ml->v];
2309                 }
2310         }
2311
2312         /* now go through and fix edges and faces */
2313         med = cddm->medge;
2314         c = 0;
2315         for (i = 0; i < dm->numEdgeData; i++, med++) {
2316                 
2317                 if (LIKELY(med->v1 != med->v2)) {
2318                         const unsigned int v1 = (vtargetmap[med->v1] != -1) ? vtargetmap[med->v1] : med->v1;
2319                         const unsigned int v2 = (vtargetmap[med->v2] != -1) ? vtargetmap[med->v2] : med->v2;
2320                         void **eh_p = BLI_edgehash_lookup_p(ehash, v1, v2);
2321
2322                         if (eh_p) {
2323                                 newe[i] = GET_INT_FROM_POINTER(*eh_p);
2324                         }
2325                         else {
2326                                 BLI_array_append(olde, i);
2327                                 newe[i] = c;
2328                                 BLI_array_append(medge, *med);
2329                                 BLI_edgehash_insert(ehash, v1, v2, SET_INT_IN_POINTER(c));
2330                                 c++;
2331                         }
2332                 }
2333                 else {
2334                         newe[i] = -1;
2335                 }
2336         }
2337         
2338         mp = cddm->mpoly;
2339         for (i = 0; i < totpoly; i++, mp++) {
2340                 MPoly *mp2;
2341                 
2342                 ml = cddm->mloop + mp->loopstart;
2343
2344                 c = 0;
2345                 for (j = 0; j < mp->totloop; j++, ml++) {
2346                         med = cddm->medge + ml->e;
2347                         if (LIKELY(med->v1 != med->v2)) {
2348                                 newl[j + mp->loopstart] = BLI_array_count(mloop);
2349                                 BLI_array_append(oldl, j + mp->loopstart);
2350                                 BLI_array_append(mloop, *ml);
2351                                 c++;
2352                         }
2353                 }
2354
2355                 if (UNLIKELY(c == 0)) {
2356                         continue;
2357                 }
2358                 
2359                 mp2 = BLI_array_append_r(mpoly, *mp);
2360                 mp2->totloop = c;
2361                 mp2->loopstart = BLI_array_count(mloop) - c;
2362                 
2363                 BLI_array_append(oldp, i);
2364         }
2365         
2366         /*create new cddm*/
2367         cddm2 = (CDDerivedMesh *) CDDM_from_template((DerivedMesh *)cddm, BLI_array_count(mvert), BLI_array_count(medge), 0, BLI_array_count(mloop), BLI_array_count(mpoly));
2368         
2369         /*update edge indices and copy customdata*/
2370         med = medge;
2371         for (i = 0; i < cddm2->dm.numEdgeData; i++, med++) {
2372                 if (newv[med->v1] != -1)
2373                         med->v1 = newv[med->v1];
2374                 if (newv[med->v2] != -1)
2375                         med->v2 = newv[med->v2];
2376                 
2377                 CustomData_copy_data(&dm->edgeData, &cddm2->dm.edgeData, olde[i], i, 1);
2378         }
2379         
2380         /*update loop indices and copy customdata*/
2381         ml = mloop;
2382         for (i = 0; i < cddm2->dm.numLoopData; i++, ml++) {
2383                 if (newe[ml->e] != -1)
2384                         ml->e = newe[ml->e];
2385                 if (newv[ml->v] != -1)
2386                         ml->v = newv[ml->v];
2387                         
2388                 CustomData_copy_data(&dm->loopData, &cddm2->dm.loopData, oldl[i], i, 1);
2389         }
2390         
2391         /*copy vertex customdata*/
2392         mv = mvert;
2393         for (i = 0; i < cddm2->dm.numVertData; i++, mv++) {
2394                 CustomData_copy_data(&dm->vertData, &cddm2->dm.vertData, oldv[i], i, 1);
2395         }
2396         
2397         /*copy poly customdata*/
2398         mp = mpoly;
2399         for (i = 0; i < cddm2->dm.numPolyData; i++, mp++) {
2400                 CustomData_copy_data(&dm->polyData, &cddm2->dm.polyData, oldp[i], i, 1);
2401         }
2402         
2403         /*copy over data.  CustomData_add_layer can do this, need to look it up.*/
2404         memcpy(cddm2->mvert, mvert, sizeof(MVert) * BLI_array_count(mvert));
2405         memcpy(cddm2->medge, medge, sizeof(MEdge) * BLI_array_count(medge));
2406         memcpy(cddm2->mloop, mloop, sizeof(MLoop) * BLI_array_count(mloop));
2407         memcpy(cddm2->mpoly, mpoly, sizeof(MPoly) * BLI_array_count(mpoly));
2408         BLI_array_free(mvert); BLI_array_free(medge); BLI_array_free(mloop); BLI_array_free(mpoly);
2409         
2410         if (newv) 
2411                 MEM_freeN(newv); 
2412         if (newe)
2413                 MEM_freeN(newe); 
2414         if (newl)
2415                 MEM_freeN(newl);
2416         if (oldv) 
2417                 MEM_freeN(oldv); 
2418         if (olde) 
2419                 MEM_freeN(olde); 
2420         if (oldl) 
2421                 MEM_freeN(oldl); 
2422         if (oldp) 
2423                 MEM_freeN(oldp);
2424         if (ehash)
2425                 BLI_edgehash_free(ehash, NULL);
2426
2427         /*free old derivedmesh*/
2428         dm->needsFree = 1;
2429         dm->release(dm);
2430         
2431         return (DerivedMesh *)cddm2;
2432 }
2433 #endif
2434
2435 void CDDM_calc_edges_tessface(DerivedMesh *dm)
2436 {
2437         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2438         CustomData edgeData;
2439         EdgeHashIterator *ehi;
2440         MFace *mf = cddm->mface;
2441         MEdge *med;
2442         EdgeHash *eh = BLI_edgehash_new();
2443         int i, *index, numEdges, maxFaces = dm->numTessFaceData;
2444
2445         for (i = 0; i < maxFaces; i++, mf++) {
2446                 if (!BLI_edgehash_haskey(eh, mf->v1, mf->v2))
2447                         BLI_edgehash_insert(eh, mf->v1, mf->v2, NULL);
2448                 if (!BLI_edgehash_haskey(eh, mf->v2, mf->v3))
2449                         BLI_edgehash_insert(eh, mf->v2, mf->v3, NULL);
2450                 
2451                 if (mf->v4) {
2452                         if (!BLI_edgehash_haskey(eh, mf->v3, mf->v4))
2453                                 BLI_edgehash_insert(eh, mf->v3, mf->v4, NULL);
2454                         if (!BLI_edgehash_haskey(eh, mf->v4, mf->v1))
2455                                 BLI_edgehash_insert(eh, mf->v4, mf->v1, NULL);
2456                 }
2457                 else {
2458                         if (!BLI_edgehash_haskey(eh, mf->v3, mf->v1))
2459                                 BLI_edgehash_insert(eh, mf->v3, mf->v1, NULL);
2460                 }
2461         }
2462
2463         numEdges = BLI_edgehash_size(eh);
2464
2465         /* write new edges into a temporary CustomData */
2466         CustomData_reset(&edgeData);
2467         CustomData_add_layer(&edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
2468         CustomData_add_layer(&edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
2469
2470         med = CustomData_get_layer(&edgeData, CD_MEDGE);
2471         index = CustomData_get_layer(&edgeData, CD_ORIGINDEX);
2472
2473         for (ehi = BLI_edgehashIterator_new(eh), i = 0;
2474              BLI_edgehashIterator_isDone(ehi) == FALSE;
2475              BLI_edgehashIterator_step(ehi), ++i, ++med, ++index)
2476         {
2477                 BLI_edgehashIterator_getKey(ehi, &med->v1, &med->v2);
2478
2479                 med->flag = ME_EDGEDRAW | ME_EDGERENDER;
2480                 *index = ORIGINDEX_NONE;
2481         }
2482         BLI_edgehashIterator_free(ehi);
2483
2484         /* free old CustomData and assign new one */
2485         CustomData_free(&dm->edgeData, dm->numEdgeData);
2486         dm->edgeData = edgeData;
2487         dm->numEdgeData = numEdges;
2488
2489         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
2490
2491         BLI_edgehash_free(eh, NULL);
2492 }
2493
2494 /* warning, this uses existing edges but CDDM_calc_edges_tessface() doesn't */
2495 void CDDM_calc_edges(DerivedMesh *dm)
2496 {
2497         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2498         CustomData edgeData;
2499         EdgeHashIterator *ehi;
2500         MPoly *mp = cddm->mpoly;
2501         MLoop *ml;
2502         MEdge *med;
2503         EdgeHash *eh = BLI_edgehash_new();
2504         int v1, v2;
2505         int *eindex;
2506         int i, j, *index, numEdges = cddm->dm.numEdgeData, maxFaces = dm->numPolyData;
2507
2508         eindex = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
2509
2510         med = cddm->medge;
2511         if (med) {
2512                 for (i = 0; i < numEdges; i++, med++) {
2513                         BLI_edgehash_insert(eh, med->v1, med->v2, SET_INT_IN_POINTER(i + 1));
2514                 }
2515         }
2516
2517         for (i = 0; i < maxFaces; i++, mp++) {
2518                 ml = cddm->mloop + mp->loopstart;
2519                 for (j = 0; j < mp->totloop; j++, ml++) {
2520                         v1 = ml->v;
2521                         v2 = ME_POLY_LOOP_NEXT(cddm->mloop, mp, j)->v;
2522                         if (!BLI_edgehash_haskey(eh, v1, v2)) {
2523                                 BLI_edgehash_insert(eh, v1, v2, NULL);
2524                         }
2525                 }
2526         }
2527
2528         numEdges = BLI_edgehash_size(eh);
2529
2530         /* write new edges into a temporary CustomData */
2531         CustomData_reset(&edgeData);
2532         CustomData_add_layer(&edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
2533         CustomData_add_layer(&edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
2534
2535         med = CustomData_get_layer(&edgeData, CD_MEDGE);
2536         index = CustomData_get_layer(&edgeData, CD_ORIGINDEX);
2537
2538         for (ehi = BLI_edgehashIterator_new(eh), i = 0;
2539              BLI_edgehashIterator_isDone(ehi) == FALSE;
2540              BLI_edgehashIterator_step(ehi), ++i, ++med, ++index)
2541         {
2542                 BLI_edgehashIterator_getKey(ehi, &med->v1, &med->v2);
2543                 j = GET_INT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi));
2544
2545                 med->flag = ME_EDGEDRAW | ME_EDGERENDER;
2546                 *index = j == 0 ? ORIGINDEX_NONE : eindex[j - 1];
2547
2548                 BLI_edgehashIterator_setValue(ehi, SET_INT_IN_POINTER(i));
2549         }
2550         BLI_edgehashIterator_free(ehi);
2551
2552         /* free old CustomData and assign new one */
2553         CustomData_free(&dm->edgeData, dm->numEdgeData);
2554         dm->edgeData = edgeData;
2555         dm->numEdgeData = numEdges;
2556
2557         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
2558
2559         mp = cddm->mpoly;
2560         for (i = 0; i < maxFaces; i++, mp++) {
2561                 ml = cddm->mloop + mp->loopstart;
2562                 for (j = 0; j < mp->totloop; j++, ml++) {
2563                         v1 = ml->v;
2564                         v2 = ME_POLY_LOOP_NEXT(cddm->mloop, mp, j)->v;
2565                         ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, v1, v2));
2566                 }
2567         }
2568
2569         BLI_edgehash_free(eh, NULL);
2570 }
2571
2572 void CDDM_lower_num_verts(DerivedMesh *dm, int numVerts)
2573 {
2574         if (numVerts < dm->numVertData)
2575                 CustomData_free_elem(&dm->vertData, numVerts, dm->numVertData - numVerts);
2576
2577         dm->numVertData = numVerts;
2578 }
2579
2580 void CDDM_lower_num_edges(DerivedMesh *dm, int numEdges)
2581 {
2582         if (numEdges < dm->numEdgeData)
2583                 CustomData_free_elem(&dm->edgeData, numEdges, dm->numEdgeData - numEdges);
2584
2585         dm->numEdgeData = numEdges;
2586 }
2587
2588 void CDDM_lower_num_tessfaces(DerivedMesh *dm, int numTessFaces)
2589 {
2590         if (numTessFaces < dm->numTessFaceData)
2591                 CustomData_free_elem(&dm->faceData, numTessFaces, dm->numTessFaceData - numTessFaces);
2592
2593         dm->numTessFaceData = numTessFaces;
2594 }
2595
2596 void CDDM_lower_num_polys(DerivedMesh *dm, int numPolys)
2597 {
2598         if (numPolys < dm->numPolyData)
2599                 CustomData_free_elem(&dm->polyData, numPolys, dm->numPolyData - numPolys);
2600
2601         dm->numPolyData = numPolys;
2602 }
2603
2604 /* mesh element access functions */
2605
2606 MVert *CDDM_get_vert(DerivedMesh *dm, int index)
2607 {
2608         return &((CDDerivedMesh *)dm)->mvert[index];
2609 }
2610
2611 MEdge *CDDM_get_edge(DerivedMesh *dm, int index)
2612 {
2613         return &((CDDerivedMesh *)dm)->medge[index];
2614 }
2615
2616 MFace *CDDM_get_tessface(DerivedMesh *dm, int index)
2617 {
2618         return &((CDDerivedMesh *)dm)->mface[index];
2619 }
2620
2621 MLoop *CDDM_get_loop(DerivedMesh *dm, int index)
2622 {
2623         return &((CDDerivedMesh *)dm)->mloop[index];
2624 }
2625
2626 MPoly *CDDM_get_poly(DerivedMesh *dm, int index)
2627 {
2628         return &((CDDerivedMesh *)dm)->mpoly[index];
2629 }
2630
2631 /* array access functions */
2632
2633 MVert *CDDM_get_verts(DerivedMesh *dm)
2634 {
2635         return ((CDDerivedMesh *)dm)->mvert;
2636 }
2637
2638 MEdge *CDDM_get_edges(DerivedMesh *dm)
2639 {
2640         return ((CDDerivedMesh *)dm)->medge;
2641 }
2642
2643 MFace *CDDM_get_tessfaces(DerivedMesh *dm)
2644 {
2645         return ((CDDerivedMesh *)dm)->mface;
2646 }
2647
2648 MLoop *CDDM_get_loops(DerivedMesh *dm)
2649 {
2650         return ((CDDerivedMesh *)dm)->mloop;
2651 }
2652
2653 MPoly *CDDM_get_polys(DerivedMesh *dm)
2654 {
2655         return ((CDDerivedMesh *)dm)->mpoly;
2656 }
2657
2658 void CDDM_tessfaces_to_faces(DerivedMesh *dm)
2659 {
2660         /* converts mfaces to mpolys/mloops */
2661         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2662
2663         BKE_mesh_convert_mfaces_to_mpolys_ex(NULL, &cddm->dm.faceData, &cddm->dm.loopData, &cddm->dm.polyData,
2664                                              cddm->dm.numEdgeData, cddm->dm.numTessFaceData,
2665                                              cddm->dm.numLoopData, cddm->dm.numPolyData,
2666                                              cddm->medge, cddm->mface,
2667                                              &cddm->dm.numLoopData, &cddm->dm.numPolyData,
2668                                              &cddm->mloop, &cddm->mpoly);
2669 }
2670
2671 void CDDM_set_mvert(DerivedMesh *dm, MVert *mvert)
2672 {
2673         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2674         
2675         if (!CustomData_has_layer(&dm->vertData, CD_MVERT))
2676                 CustomData_add_layer(&dm->vertData, CD_MVERT, CD_ASSIGN, mvert, dm->numVertData);
2677                                 
2678         cddm->mvert = mvert;
2679 }
2680
2681 void CDDM_set_medge(DerivedMesh *dm, MEdge *medge)
2682 {
2683         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2684
2685         if (!CustomData_has_layer(&dm->edgeData, CD_MEDGE))
2686                 CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_ASSIGN, medge, dm->numEdgeData);
2687
2688         cddm->medge = medge;
2689 }
2690
2691 void CDDM_set_mface(DerivedMesh *dm, MFace *mface)
2692 {
2693         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2694
2695         if (!CustomData_has_layer(&dm->faceData, CD_MFACE))
2696                 CustomData_add_layer(&dm->faceData, CD_MFACE, CD_ASSIGN, mface, dm->numTessFaceData);
2697
2698         cddm->mface = mface;
2699 }
2700
2701 void CDDM_set_mloop(DerivedMesh *dm, MLoop *mloop)
2702 {
2703         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2704
2705         if (!CustomData_has_layer(&dm->loopData, CD_MLOOP))
2706                 CustomData_add_layer(&dm->loopData, CD_MLOOP, CD_ASSIGN, mloop, dm->numLoopData);
2707
2708         cddm->mloop = mloop;
2709 }
2710
2711 void CDDM_set_mpoly(DerivedMesh *dm, MPoly *mpoly)
2712 {
2713         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2714
2715         if (!CustomData_has_layer(&dm->polyData, CD_MPOLY))
2716                 CustomData_add_layer(&dm->polyData, CD_MPOLY, CD_ASSIGN, mpoly, dm->numPolyData);
2717
2718         cddm->mpoly = mpoly;
2719 }