e5aa152f68c856eb9622ec615baedb3434ca293c
[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         cdDM_update_normals_from_pbvh(dm);
832
833         /* back-buffer always uses legacy since VBO's would need the
834          * color array temporarily overwritten for drawing, then reset. */
835         if (GPU_buffer_legacy(dm) || G.f & G_BACKBUFSEL) {
836                 DEBUG_VBO("Using legacy code. cdDM_drawMappedFaces\n");
837                 for (i = 0; i < dm->numTessFaceData; i++, mf++) {
838                         int drawSmooth = (flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : (mf->flag & ME_SMOOTH);
839                         DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL;
840
841                         orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, i) : i;
842                         
843                         if (orig == ORIGINDEX_NONE)
844                                 draw_option = setMaterial(mf->mat_nr + 1, NULL);
845                         else if (setDrawOptions != NULL)
846                                 draw_option = setDrawOptions(userData, orig);
847
848                         if (draw_option != DM_DRAW_OPTION_SKIP) {
849                                 unsigned char *cp = NULL;
850
851                                 if (useColors && mcol)
852                                         cp = (unsigned char *)&mcol[i * 4];
853
854                                 /* no need to set shading mode to flat because
855                                  *  normals are already used to change shading */
856                                 glShadeModel(GL_SMOOTH);
857                                 glBegin(mf->v4 ? GL_QUADS : GL_TRIANGLES);
858
859                                 if (!drawSmooth) {
860                                         if (nors) {
861                                                 glNormal3fv(nors);
862                                         }
863                                         else {
864                                                 float nor[3];
865                                                 if (mf->v4) {
866                                                         normal_quad_v3(nor, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co);
867                                                 }
868                                                 else {
869                                                         normal_tri_v3(nor, mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co);
870                                                 }
871                                                 glNormal3fv(nor);
872                                         }
873
874                                         if (cp) glColor3ub(cp[3], cp[2], cp[1]);
875                                         glVertex3fv(mv[mf->v1].co);
876                                         if (cp) glColor3ub(cp[7], cp[6], cp[5]);
877                                         glVertex3fv(mv[mf->v2].co);
878                                         if (cp) glColor3ub(cp[11], cp[10], cp[9]);
879                                         glVertex3fv(mv[mf->v3].co);
880                                         if (mf->v4) {
881                                                 if (cp) glColor3ub(cp[15], cp[14], cp[13]);
882                                                 glVertex3fv(mv[mf->v4].co);
883                                         }
884                                 }
885                                 else {
886                                         if (cp) glColor3ub(cp[3], cp[2], cp[1]);
887                                         glNormal3sv(mv[mf->v1].no);
888                                         glVertex3fv(mv[mf->v1].co);
889                                         if (cp) glColor3ub(cp[7], cp[6], cp[5]);
890                                         glNormal3sv(mv[mf->v2].no);
891                                         glVertex3fv(mv[mf->v2].co);
892                                         if (cp) glColor3ub(cp[11], cp[10], cp[9]);
893                                         glNormal3sv(mv[mf->v3].no);
894                                         glVertex3fv(mv[mf->v3].co);
895                                         if (mf->v4) {
896                                                 if (cp) glColor3ub(cp[15], cp[14], cp[13]);
897                                                 glNormal3sv(mv[mf->v4].no);
898                                                 glVertex3fv(mv[mf->v4].co);
899                                         }
900                                 }
901
902                                 glEnd();
903                         }
904                         
905                         if (nors) nors += 3;
906                 }
907         }
908         else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
909                 int prevstart = 0;
910                 GPU_vertex_setup(dm);
911                 GPU_normal_setup(dm);
912                 if (useColors && mcol) {
913                         GPU_color_setup(dm, colType);
914                 }
915                 if (!GPU_buffer_legacy(dm)) {
916                         int tottri = dm->drawObject->tot_triangle_point / 3;
917                         glShadeModel(GL_SMOOTH);
918                         
919                         if (tottri == 0) {
920                                 /* avoid buffer problems in following code */
921                         }
922                         if (setDrawOptions == NULL) {
923                                 /* just draw the entire face array */
924                                 glDrawArrays(GL_TRIANGLES, 0, (tottri) * 3);
925                         }
926                         else {
927                                 /* we need to check if the next material changes */
928                                 int next_actualFace = dm->drawObject->triangle_to_mface[0];
929                                 
930                                 for (i = 0; i < tottri; i++) {
931                                         //int actualFace = dm->drawObject->triangle_to_mface[i];
932                                         int actualFace = next_actualFace;
933                                         MFace *mface = mf + actualFace;
934                                         /*int drawSmooth = (flag & DM_DRAW_ALWAYS_SMOOTH) ? 1 : (mface->flag & ME_SMOOTH);*/ /* UNUSED */
935                                         DMDrawOption draw_option = DM_DRAW_OPTION_NORMAL;
936                                         int flush = 0;
937
938                                         if (i != tottri - 1)
939                                                 next_actualFace = dm->drawObject->triangle_to_mface[i + 1];
940
941                                         orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, actualFace) : actualFace;
942
943                                         if (orig == ORIGINDEX_NONE)
944                                                 draw_option = setMaterial(mface->mat_nr + 1, NULL);
945                                         else if (setDrawOptions != NULL)
946                                                 draw_option = setDrawOptions(userData, orig);
947         
948                                         /* Goal is to draw as long of a contiguous triangle
949                                          * array as possible, so draw when we hit either an
950                                          * invisible triangle or at the end of the array */
951
952                                         /* flush buffer if current triangle isn't drawable or it's last triangle... */
953                                         flush = (draw_option == DM_DRAW_OPTION_SKIP) || (i == tottri - 1);
954
955                                         /* ... or when material setting is dissferent  */
956                                         flush |= mf[actualFace].mat_nr != mf[next_actualFace].mat_nr;
957
958                                         if (!flush && compareDrawOptions) {
959                                                 flush |= compareDrawOptions(userData, actualFace, next_actualFace) == 0;
960                                         }
961
962                                         if (flush) {
963                                                 int first = prevstart * 3;
964                                                 /* Add one to the length if we're drawing at the end of the array */
965                                                 int count = (i - prevstart + (draw_option != DM_DRAW_OPTION_SKIP ? 1 : 0)) * 3;
966
967                                                 if (count)
968                                                         glDrawArrays(GL_TRIANGLES, first, count);
969
970                                                 prevstart = i + 1;
971                                         }
972                                 }
973                         }
974
975                         glShadeModel(GL_FLAT);
976                 }
977                 GPU_buffer_unbind();
978         }
979 }
980
981 static void cdDM_drawMappedFacesTex(DerivedMesh *dm,
982                                     DMSetDrawOptions setDrawOptions,
983                                     DMCompareDrawOptions compareDrawOptions,
984                                     void *userData)
985 {
986         cdDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData);
987 }
988
989 static void cddm_draw_attrib_vertex(DMVertexAttribs *attribs, MVert *mvert, int a, int index, int vert, int smoothnormal)
990 {
991         int b;
992
993         /* orco texture coordinates */
994         if (attribs->totorco) {
995                 if (attribs->orco.gl_texco)
996                         glTexCoord3fv(attribs->orco.array[index]);
997                 else
998                         glVertexAttrib3fvARB(attribs->orco.gl_index, attribs->orco.array[index]);
999         }
1000
1001         /* uv texture coordinates */
1002         for (b = 0; b < attribs->tottface; b++) {
1003                 MTFace *tf = &attribs->tface[b].array[a];
1004
1005                 if (attribs->tface[b].gl_texco)
1006                         glTexCoord2fv(tf->uv[vert]);
1007                 else
1008                         glVertexAttrib2fvARB(attribs->tface[b].gl_index, tf->uv[vert]);
1009         }
1010
1011         /* vertex colors */
1012         for (b = 0; b < attribs->totmcol; b++) {
1013                 MCol *cp = &attribs->mcol[b].array[a * 4 + vert];
1014                 GLubyte col[4];
1015                 col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
1016                 glVertexAttrib4ubvARB(attribs->mcol[b].gl_index, col);
1017         }
1018
1019         /* tangent for normal mapping */
1020         if (attribs->tottang) {
1021                 float *tang = attribs->tang.array[a * 4 + vert];
1022                 glVertexAttrib4fvARB(attribs->tang.gl_index, tang);
1023         }
1024
1025         /* vertex normal */
1026         if (smoothnormal)
1027                 glNormal3sv(mvert[index].no);
1028         
1029         /* vertex coordinate */
1030         glVertex3fv(mvert[index].co);
1031 }
1032
1033 static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm,
1034                                      DMSetMaterial setMaterial,
1035                                      DMSetDrawOptions setDrawOptions,
1036                                      void *userData)
1037 {
1038         CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
1039         GPUVertexAttribs gattribs;
1040         DMVertexAttribs attribs;
1041         MVert *mvert = cddm->mvert;
1042         MFace *mface = cddm->mface;
1043         /* MTFace *tf = dm->getTessFaceDataArray(dm, CD_MTFACE); */ /* UNUSED */
1044         float (*nors)[3] = dm->getTessFaceDataArray(dm, CD_NORMAL);
1045         int a, b, do_draw, matnr, new_matnr;
1046         int orig;
1047
1048         /* double lookup */
1049         const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
1050         const int *index_mp_to_orig  = dm->getPolyDataArray(dm, CD_ORIGINDEX);
1051         if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) {
1052                 index_mf_to_mpoly = index_mp_to_orig = NULL;
1053         }
1054
1055         cdDM_update_normals_from_pbvh(dm);
1056
1057         matnr = -1;
1058         do_draw = FALSE;
1059
1060         glShadeModel(GL_SMOOTH);
1061
1062         if (GPU_buffer_legacy(dm) || setDrawOptions != NULL) {
1063                 DEBUG_VBO("Using legacy code. cdDM_drawMappedFacesGLSL\n");
1064                 memset(&attribs, 0, sizeof(attribs));
1065
1066                 glBegin(GL_QUADS);
1067
1068                 for (a = 0; a < dm->numTessFaceData; a++, mface++) {
1069                         const int smoothnormal = (mface->flag & ME_SMOOTH);
1070                         new_matnr = mface->mat_nr + 1;
1071
1072                         if (new_matnr != matnr) {
1073                                 glEnd();
1074
1075                                 do_draw = setMaterial(matnr = new_matnr, &gattribs);
1076                                 if (do_draw)
1077                                         DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1078
1079                                 glBegin(GL_QUADS);
1080                         }
1081
1082                         if (!do_draw) {
1083                                 continue;
1084                         }
1085                         else if (setDrawOptions) {
1086                                 orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, a) : a;
1087
1088                                 if (orig == ORIGINDEX_NONE) {
1089                                         /* since the material is set by setMaterial(), faces with no
1090                                          * origin can be assumed to be generated by a modifier */ 
1091                                         
1092                                         /* continue */
1093                                 }
1094                                 else if (setDrawOptions(userData, orig) == DM_DRAW_OPTION_SKIP)
1095                                         continue;
1096                         }
1097
1098                         if (!smoothnormal) {
1099                                 if (nors) {
1100                                         glNormal3fv(nors[a]);
1101                                 }
1102                                 else {
1103                                         /* TODO ideally a normal layer should always be available */
1104                                         float nor[3];
1105                                         if (mface->v4) {
1106                                                 normal_quad_v3(nor, mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co, mvert[mface->v4].co);
1107                                         }
1108                                         else {
1109                                                 normal_tri_v3(nor, mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co);
1110                                         }
1111                                         glNormal3fv(nor);
1112                                 }
1113                         }
1114
1115                         cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v1, 0, smoothnormal);
1116                         cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v2, 1, smoothnormal);
1117                         cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, smoothnormal);
1118
1119                         if (mface->v4)
1120                                 cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v4, 3, smoothnormal);
1121                         else
1122                                 cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, smoothnormal);
1123                 }
1124                 glEnd();
1125         }
1126         else {
1127                 GPUBuffer *buffer = NULL;
1128                 char *varray = NULL;
1129                 int numdata = 0, elementsize = 0, offset;
1130                 int start = 0, numfaces = 0 /* , prevdraw = 0 */ /* UNUSED */, curface = 0;
1131                 int i;
1132
1133                 MFace *mf = mface;
1134                 GPUAttrib datatypes[GPU_MAX_ATTRIB]; /* TODO, messing up when switching materials many times - [#21056]*/
1135                 memset(&attribs, 0, sizeof(attribs));
1136
1137                 GPU_vertex_setup(dm);
1138                 GPU_normal_setup(dm);
1139
1140                 if (!GPU_buffer_legacy(dm)) {
1141                         for (i = 0; i < dm->drawObject->tot_triangle_point / 3; i++) {
1142
1143                                 a = dm->drawObject->triangle_to_mface[i];
1144
1145                                 mface = mf + a;
1146                                 new_matnr = mface->mat_nr + 1;
1147
1148                                 if (new_matnr != matnr) {
1149                                         numfaces = curface - start;
1150                                         if (numfaces > 0) {
1151
1152                                                 if (do_draw) {
1153
1154                                                         if (numdata != 0) {
1155
1156                                                                 GPU_buffer_unlock(buffer);
1157
1158                                                                 GPU_interleaved_attrib_setup(buffer, datatypes, numdata);
1159                                                         }
1160
1161                                                         glDrawArrays(GL_TRIANGLES, start * 3, numfaces * 3);
1162
1163                                                         if (numdata != 0) {
1164
1165                                                                 GPU_buffer_free(buffer);
1166
1167                                                                 buffer = NULL;
1168                                                         }
1169
1170                                                 }
1171                                         }
1172                                         numdata = 0;
1173                                         start = curface;
1174                                         /* prevdraw = do_draw; */ /* UNUSED */
1175                                         do_draw = setMaterial(matnr = new_matnr, &gattribs);
1176                                         if (do_draw) {
1177                                                 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1178
1179                                                 if (attribs.totorco) {
1180                                                         datatypes[numdata].index = attribs.orco.gl_index;
1181                                                         datatypes[numdata].size = 3;
1182                                                         datatypes[numdata].type = GL_FLOAT;
1183                                                         numdata++;
1184                                                 }
1185                                                 for (b = 0; b < attribs.tottface; b++) {
1186                                                         datatypes[numdata].index = attribs.tface[b].gl_index;
1187                                                         datatypes[numdata].size = 2;
1188                                                         datatypes[numdata].type = GL_FLOAT;
1189                                                         numdata++;
1190                                                 }
1191                                                 for (b = 0; b < attribs.totmcol; b++) {
1192                                                         datatypes[numdata].index = attribs.mcol[b].gl_index;
1193                                                         datatypes[numdata].size = 4;
1194                                                         datatypes[numdata].type = GL_UNSIGNED_BYTE;
1195                                                         numdata++;
1196                                                 }
1197                                                 if (attribs.tottang) {
1198                                                         datatypes[numdata].index = attribs.tang.gl_index;
1199                                                         datatypes[numdata].size = 4;
1200                                                         datatypes[numdata].type = GL_FLOAT;
1201                                                         numdata++;
1202                                                 }
1203                                                 if (numdata != 0) {
1204                                                         elementsize = GPU_attrib_element_size(datatypes, numdata);
1205                                                         buffer = GPU_buffer_alloc(elementsize * dm->drawObject->tot_triangle_point);
1206                                                         if (buffer == NULL) {
1207                                                                 GPU_buffer_unbind();
1208                                                                 dm->drawObject->legacy = 1;
1209                                                                 return;
1210                                                         }
1211                                                         varray = GPU_buffer_lock_stream(buffer);
1212                                                         if (varray == NULL) {
1213                                                                 GPU_buffer_unbind();
1214                                                                 GPU_buffer_free(buffer);
1215                                                                 dm->drawObject->legacy = 1;
1216                                                                 return;
1217                                                         }
1218                                                 }
1219                                                 else {
1220                                                         /* if the buffer was set, don't use it again.
1221                                                          * prevdraw was assumed true but didnt run so set to false - [#21036] */
1222                                                         /* prevdraw = 0; */ /* UNUSED */
1223                                                         buffer = NULL;
1224                                                 }
1225                                         }
1226                                 }
1227
1228                                 if (do_draw && numdata != 0) {
1229                                         offset = 0;
1230                                         if (attribs.totorco) {
1231                                                 copy_v3_v3((float *)&varray[elementsize * curface * 3], (float *)attribs.orco.array[mface->v1]);
1232                                                 copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize], (float *)attribs.orco.array[mface->v2]);
1233                                                 copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize * 2], (float *)attribs.orco.array[mface->v3]);
1234                                                 offset += sizeof(float) * 3;
1235                                         }
1236                                         for (b = 0; b < attribs.tottface; b++) {
1237                                                 MTFace *tf = &attribs.tface[b].array[a];
1238                                                 copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset], tf->uv[0]);
1239                                                 copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize], tf->uv[1]);
1240
1241                                                 copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tf->uv[2]);
1242                                                 offset += sizeof(float) * 2;
1243                                         }
1244                                         for (b = 0; b < attribs.totmcol; b++) {
1245                                                 MCol *cp = &attribs.mcol[b].array[a * 4 + 0];
1246                                                 GLubyte col[4];
1247                                                 col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
1248                                                 copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset], (char *)col);
1249                                                 cp = &attribs.mcol[b].array[a * 4 + 1];
1250                                                 col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
1251                                                 copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize], (char *)col);
1252                                                 cp = &attribs.mcol[b].array[a * 4 + 2];
1253                                                 col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
1254                                                 copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize * 2], (char *)col);
1255                                                 offset += sizeof(unsigned char) * 4;
1256                                         }
1257                                         if (attribs.tottang) {
1258                                                 float *tang = attribs.tang.array[a * 4 + 0];
1259                                                 copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset], tang);
1260                                                 tang = attribs.tang.array[a * 4 + 1];
1261                                                 copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize], tang);
1262                                                 tang = attribs.tang.array[a * 4 + 2];
1263                                                 copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tang);
1264                                                 offset += sizeof(float) * 4;
1265                                         }
1266                                         (void)offset;
1267                                 }
1268                                 curface++;
1269                                 if (mface->v4) {
1270                                         if (do_draw && numdata != 0) {
1271                                                 offset = 0;
1272                                                 if (attribs.totorco) {
1273                                                         copy_v3_v3((float *)&varray[elementsize * curface * 3], (float *)attribs.orco.array[mface->v3]);
1274                                                         copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize], (float *)attribs.orco.array[mface->v4]);
1275                                                         copy_v3_v3((float *)&varray[elementsize * curface * 3 + elementsize * 2], (float *)attribs.orco.array[mface->v1]);
1276                                                         offset += sizeof(float) * 3;
1277                                                 }
1278                                                 for (b = 0; b < attribs.tottface; b++) {
1279                                                         MTFace *tf = &attribs.tface[b].array[a];
1280                                                         copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset], tf->uv[2]);
1281                                                         copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize], tf->uv[3]);
1282                                                         copy_v2_v2((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tf->uv[0]);
1283                                                         offset += sizeof(float) * 2;
1284                                                 }
1285                                                 for (b = 0; b < attribs.totmcol; b++) {
1286                                                         MCol *cp = &attribs.mcol[b].array[a * 4 + 2];
1287                                                         GLubyte col[4];
1288                                                         col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
1289                                                         copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset], (char *)col);
1290                                                         cp = &attribs.mcol[b].array[a * 4 + 3];
1291                                                         col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
1292                                                         copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize], (char *)col);
1293                                                         cp = &attribs.mcol[b].array[a * 4 + 0];
1294                                                         col[0] = cp->b; col[1] = cp->g; col[2] = cp->r; col[3] = cp->a;
1295                                                         copy_v4_v4_char((char *)&varray[elementsize * curface * 3 + offset + elementsize * 2], (char *)col);
1296                                                         offset += sizeof(unsigned char) * 4;
1297                                                 }
1298                                                 if (attribs.tottang) {
1299                                                         float *tang = attribs.tang.array[a * 4 + 2];
1300                                                         copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset], tang);
1301                                                         tang = attribs.tang.array[a * 4 + 3];
1302                                                         copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize], tang);
1303                                                         tang = attribs.tang.array[a * 4 + 0];
1304                                                         copy_v4_v4((float *)&varray[elementsize * curface * 3 + offset + elementsize * 2], tang);
1305                                                         offset += sizeof(float) * 4;
1306                                                 }
1307                                                 (void)offset;
1308                                         }
1309                                         curface++;
1310                                         i++;
1311                                 }
1312                         }
1313                         numfaces = curface - start;
1314                         if (numfaces > 0) {
1315                                 if (do_draw) {
1316                                         if (numdata != 0) {
1317                                                 GPU_buffer_unlock(buffer);
1318                                                 GPU_interleaved_attrib_setup(buffer, datatypes, numdata);
1319                                         }
1320                                         glDrawArrays(GL_TRIANGLES, start * 3, (curface - start) * 3);
1321                                 }
1322                         }
1323                         GPU_buffer_unbind();
1324                 }
1325                 GPU_buffer_free(buffer);
1326         }
1327
1328         glShadeModel(GL_FLAT);
1329 }
1330
1331 static void cdDM_drawFacesGLSL(DerivedMesh *dm, DMSetMaterial setMaterial)
1332 {
1333         dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
1334 }
1335
1336 static void cdDM_drawMappedFacesMat(DerivedMesh *dm,
1337                                     void (*setMaterial)(void *userData, int, void *attribs),
1338                                     int (*setFace)(void *userData, int index), void *userData)
1339 {
1340         CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
1341         GPUVertexAttribs gattribs;
1342         DMVertexAttribs attribs;
1343         MVert *mvert = cddm->mvert;
1344         MFace *mf = cddm->mface;
1345         float (*nors)[3] = dm->getTessFaceDataArray(dm, CD_NORMAL);
1346         int a, matnr, new_matnr;
1347         int orig;
1348
1349         /* double lookup */
1350         const int *index_mf_to_mpoly = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
1351         const int *index_mp_to_orig  = dm->getPolyDataArray(dm, CD_ORIGINDEX);
1352         if ((index_mf_to_mpoly && index_mp_to_orig) == FALSE) {
1353                 index_mf_to_mpoly = index_mp_to_orig = NULL;
1354         }
1355
1356         cdDM_update_normals_from_pbvh(dm);
1357
1358         matnr = -1;
1359
1360         glShadeModel(GL_SMOOTH);
1361
1362         memset(&attribs, 0, sizeof(attribs));
1363
1364         glBegin(GL_QUADS);
1365
1366         for (a = 0; a < dm->numTessFaceData; a++, mf++) {
1367                 const int smoothnormal = (mf->flag & ME_SMOOTH);
1368
1369                 /* material */
1370                 new_matnr = mf->mat_nr + 1;
1371
1372                 if (new_matnr != matnr) {
1373                         glEnd();
1374
1375                         setMaterial(userData, matnr = new_matnr, &gattribs);
1376                         DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1377
1378                         glBegin(GL_QUADS);
1379                 }
1380
1381                 /* skipping faces */
1382                 if (setFace) {
1383                         orig = (index_mf_to_mpoly) ? DM_origindex_mface_mpoly(index_mf_to_mpoly, index_mp_to_orig, a) : a;
1384
1385                         if (orig != ORIGINDEX_NONE && !setFace(userData, orig))
1386                                 continue;
1387                 }
1388
1389                 /* smooth normal */
1390                 if (!smoothnormal) {
1391                         if (nors) {
1392                                 glNormal3fv(nors[a]);
1393                         }
1394                         else {
1395                                 /* TODO ideally a normal layer should always be available */
1396                                 float nor[3];
1397
1398                                 if (mf->v4)
1399                                         normal_quad_v3(nor, mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co, mvert[mf->v4].co);
1400                                 else
1401                                         normal_tri_v3(nor, mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co);
1402
1403                                 glNormal3fv(nor);
1404                         }
1405                 }
1406
1407                 /* vertices */
1408                 cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v1, 0, smoothnormal);
1409                 cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v2, 1, smoothnormal);
1410                 cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v3, 2, smoothnormal);
1411
1412                 if (mf->v4)
1413                         cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v4, 3, smoothnormal);
1414                 else
1415                         cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v3, 2, smoothnormal);
1416         }
1417         glEnd();
1418
1419         glShadeModel(GL_FLAT);
1420 }
1421
1422 static void cdDM_drawMappedEdges(DerivedMesh *dm, DMSetDrawOptions setDrawOptions, void *userData)
1423 {
1424         CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
1425         MVert *vert = cddm->mvert;
1426         MEdge *edge = cddm->medge;
1427         int i, orig, *index = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
1428
1429         glBegin(GL_LINES);
1430         for (i = 0; i < dm->numEdgeData; i++, edge++) {
1431                 if (index) {
1432                         orig = *index++;
1433                         if (setDrawOptions && orig == ORIGINDEX_NONE) continue;
1434                 }
1435                 else
1436                         orig = i;
1437
1438                 if (!setDrawOptions || (setDrawOptions(userData, orig) != DM_DRAW_OPTION_SKIP)) {
1439                         glVertex3fv(vert[edge->v1].co);
1440                         glVertex3fv(vert[edge->v2].co);
1441                 }
1442         }
1443         glEnd();
1444 }
1445
1446 static void cdDM_foreachMappedVert(
1447         DerivedMesh *dm,
1448         void (*func)(void *userData, int index, const float co[3], const float no_f[3], const short no_s[3]),
1449         void *userData)
1450 {
1451         MVert *mv = CDDM_get_verts(dm);
1452         int i, orig, *index = DM_get_vert_data_layer(dm, CD_ORIGINDEX);
1453
1454         for (i = 0; i < dm->numVertData; i++, mv++) {
1455                 if (index) {
1456                         orig = *index++;
1457                         if (orig == ORIGINDEX_NONE) continue;
1458                         func(userData, orig, mv->co, NULL, mv->no);
1459                 }
1460                 else
1461                         func(userData, i, mv->co, NULL, mv->no);
1462         }
1463 }
1464
1465 static void cdDM_foreachMappedEdge(
1466         DerivedMesh *dm,
1467         void (*func)(void *userData, int index, const float v0co[3], const float v1co[3]),
1468         void *userData)
1469 {
1470         CDDerivedMesh *cddm = (CDDerivedMesh *) dm;
1471         MVert *mv = cddm->mvert;
1472         MEdge *med = cddm->medge;
1473         int i, orig, *index = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
1474
1475         for (i = 0; i < dm->numEdgeData; i++, med++) {
1476                 if (index) {
1477                         orig = *index++;
1478                         if (orig == ORIGINDEX_NONE) continue;
1479                         func(userData, orig, mv[med->v1].co, mv[med->v2].co);
1480                 }
1481                 else
1482                         func(userData, i, mv[med->v1].co, mv[med->v2].co);
1483         }
1484 }
1485
1486 static void cdDM_foreachMappedFaceCenter(
1487         DerivedMesh *dm,
1488         void (*func)(void *userData, int index, const float cent[3], const float no[3]),
1489         void *userData)
1490 {
1491         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
1492         MVert *mvert = cddm->mvert;
1493         MPoly *mp;
1494         MLoop *ml;
1495         int i, j, orig, *index;
1496
1497         index = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
1498         mp = cddm->mpoly;
1499         for (i = 0; i < dm->numPolyData; i++, mp++) {
1500                 float cent[3];
1501                 float no[3];
1502
1503                 if (index) {
1504                         orig = *index++;
1505                         if (orig == ORIGINDEX_NONE) continue;
1506                 }
1507                 else
1508                         orig = i;
1509                 
1510                 ml = &cddm->mloop[mp->loopstart];
1511                 cent[0] = cent[1] = cent[2] = 0.0f;
1512                 for (j = 0; j < mp->totloop; j++, ml++) {
1513                         add_v3_v3v3(cent, cent, mvert[ml->v].co);
1514                 }
1515                 mul_v3_fl(cent, 1.0f / (float)j);
1516
1517                 ml = &cddm->mloop[mp->loopstart];
1518                 if (j > 3) {
1519                         normal_quad_v3(no,
1520                                        mvert[(ml + 0)->v].co,
1521                                        mvert[(ml + 1)->v].co,
1522                                        mvert[(ml + 2)->v].co,
1523                                        mvert[(ml + 3)->v].co);
1524                 }
1525                 else {
1526                         normal_tri_v3(no,
1527                                       mvert[(ml + 0)->v].co,
1528                                       mvert[(ml + 1)->v].co,
1529                                       mvert[(ml + 2)->v].co);
1530                 }
1531
1532                 func(userData, orig, cent, no);
1533         }
1534
1535 }
1536
1537 void CDDM_recalc_tessellation_ex(DerivedMesh *dm, const int do_face_nor_cpy)
1538 {
1539         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
1540
1541         dm->numTessFaceData = BKE_mesh_recalc_tessellation(&dm->faceData, &dm->loopData, &dm->polyData,
1542                                                            cddm->mvert,
1543                                                            dm->numTessFaceData, dm->numLoopData, dm->numPolyData,
1544                                                            do_face_nor_cpy);
1545
1546         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1547
1548         /* Tessellation recreated faceData, and the active layer indices need to get re-propagated
1549          * from loops and polys to faces */
1550         CustomData_bmesh_update_active_layers(&dm->faceData, &dm->polyData, &dm->loopData);
1551 }
1552
1553 void CDDM_recalc_tessellation(DerivedMesh *dm)
1554 {
1555         CDDM_recalc_tessellation_ex(dm, TRUE);
1556 }
1557
1558 static void cdDM_free_internal(CDDerivedMesh *cddm)
1559 {
1560         if (cddm->pmap) MEM_freeN(cddm->pmap);
1561         if (cddm->pmap_mem) MEM_freeN(cddm->pmap_mem);
1562 }
1563
1564 static void cdDM_release(DerivedMesh *dm)
1565 {
1566         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
1567
1568         if (DM_release(dm)) {
1569                 cdDM_free_internal(cddm);
1570                 MEM_freeN(cddm);
1571         }
1572 }
1573
1574 int CDDM_Check(DerivedMesh *dm)
1575 {
1576         return dm && dm->getMinMax == cdDM_getMinMax;
1577 }
1578
1579 /**************** CDDM interface functions ****************/
1580 static CDDerivedMesh *cdDM_create(const char *desc)
1581 {
1582         CDDerivedMesh *cddm;
1583         DerivedMesh *dm;
1584
1585         cddm = MEM_callocN(sizeof(*cddm), desc);
1586         dm = &cddm->dm;
1587
1588         dm->getMinMax = cdDM_getMinMax;
1589
1590         dm->getNumVerts = cdDM_getNumVerts;
1591         dm->getNumEdges = cdDM_getNumEdges;
1592         dm->getNumTessFaces = cdDM_getNumTessFaces;
1593         dm->getNumLoops = cdDM_getNumLoops;
1594         dm->getNumPolys = cdDM_getNumPolys;
1595
1596         dm->getVert = cdDM_getVert;
1597         dm->getEdge = cdDM_getEdge;
1598         dm->getTessFace = cdDM_getTessFace;
1599
1600         dm->copyVertArray = cdDM_copyVertArray;
1601         dm->copyEdgeArray = cdDM_copyEdgeArray;
1602         dm->copyTessFaceArray = cdDM_copyTessFaceArray;
1603         dm->copyLoopArray = cdDM_copyLoopArray;
1604         dm->copyPolyArray = cdDM_copyPolyArray;
1605
1606         dm->getVertData = DM_get_vert_data;
1607         dm->getEdgeData = DM_get_edge_data;
1608         dm->getTessFaceData = DM_get_tessface_data;
1609         dm->getVertDataArray = DM_get_vert_data_layer;
1610         dm->getEdgeDataArray = DM_get_edge_data_layer;
1611         dm->getTessFaceDataArray = DM_get_tessface_data_layer;
1612
1613         dm->calcNormals = CDDM_calc_normals_mapping;
1614         dm->recalcTessellation = CDDM_recalc_tessellation;
1615
1616         dm->getVertCos = cdDM_getVertCos;
1617         dm->getVertCo = cdDM_getVertCo;
1618         dm->getVertNo = cdDM_getVertNo;
1619
1620         dm->getPBVH = cdDM_getPBVH;
1621         dm->getPolyMap = cdDM_getPolyMap;
1622
1623         dm->drawVerts = cdDM_drawVerts;
1624
1625         dm->drawUVEdges = cdDM_drawUVEdges;
1626         dm->drawEdges = cdDM_drawEdges;
1627         dm->drawLooseEdges = cdDM_drawLooseEdges;
1628         dm->drawMappedEdges = cdDM_drawMappedEdges;
1629
1630         dm->drawFacesSolid = cdDM_drawFacesSolid;
1631         dm->drawFacesTex = cdDM_drawFacesTex;
1632         dm->drawFacesGLSL = cdDM_drawFacesGLSL;
1633         dm->drawMappedFaces = cdDM_drawMappedFaces;
1634         dm->drawMappedFacesTex = cdDM_drawMappedFacesTex;
1635         dm->drawMappedFacesGLSL = cdDM_drawMappedFacesGLSL;
1636         dm->drawMappedFacesMat = cdDM_drawMappedFacesMat;
1637
1638         dm->foreachMappedVert = cdDM_foreachMappedVert;
1639         dm->foreachMappedEdge = cdDM_foreachMappedEdge;
1640         dm->foreachMappedFaceCenter = cdDM_foreachMappedFaceCenter;
1641
1642         dm->release = cdDM_release;
1643
1644         return cddm;
1645 }
1646
1647 DerivedMesh *CDDM_new(int numVerts, int numEdges, int numTessFaces, int numLoops, int numPolys)
1648 {
1649         CDDerivedMesh *cddm = cdDM_create("CDDM_new dm");
1650         DerivedMesh *dm = &cddm->dm;
1651
1652         DM_init(dm, DM_TYPE_CDDM, numVerts, numEdges, numTessFaces, numLoops, numPolys);
1653
1654         CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts);
1655         CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
1656         CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numTessFaces);
1657         CustomData_add_layer(&dm->polyData, CD_ORIGINDEX, CD_CALLOC, NULL, numPolys);
1658
1659         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
1660         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
1661         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numTessFaces);
1662         CustomData_add_layer(&dm->loopData, CD_MLOOP, CD_CALLOC, NULL, numLoops);
1663         CustomData_add_layer(&dm->polyData, CD_MPOLY, CD_CALLOC, NULL, numPolys);
1664
1665         cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
1666         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
1667         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1668         cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
1669         cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
1670
1671         return dm;
1672 }
1673
1674 DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *UNUSED(ob))
1675 {
1676         CDDerivedMesh *cddm = cdDM_create("CDDM_from_mesh dm");
1677         DerivedMesh *dm = &cddm->dm;
1678         CustomDataMask mask = CD_MASK_MESH & (~CD_MASK_MDISPS);
1679         int alloctype;
1680
1681         /* this does a referenced copy, with an exception for fluidsim */
1682
1683         DM_init(dm, DM_TYPE_CDDM, mesh->totvert, mesh->totedge, mesh->totface,
1684                 mesh->totloop, mesh->totpoly);
1685
1686         dm->deformedOnly = 1;
1687
1688         alloctype = CD_REFERENCE;
1689
1690         CustomData_merge(&mesh->vdata, &dm->vertData, mask, alloctype,
1691                          mesh->totvert);
1692         CustomData_merge(&mesh->edata, &dm->edgeData, mask, alloctype,
1693                          mesh->totedge);
1694         CustomData_merge(&mesh->fdata, &dm->faceData, mask | CD_MASK_ORIGINDEX, alloctype,
1695                          mesh->totface);
1696         CustomData_merge(&mesh->ldata, &dm->loopData, mask, alloctype,
1697                          mesh->totloop);
1698         CustomData_merge(&mesh->pdata, &dm->polyData, mask, alloctype,
1699                          mesh->totpoly);
1700
1701         cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
1702         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
1703         cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
1704         cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
1705         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1706
1707         /* commented since even when CD_ORIGINDEX was first added this line fails
1708          * on the default cube, (after editmode toggle too) - campbell */
1709 #if 0
1710         BLI_assert(CustomData_has_layer(&cddm->dm.faceData, CD_ORIGINDEX));
1711 #endif
1712
1713         return dm;
1714 }
1715
1716 DerivedMesh *CDDM_from_curve(Object *ob)
1717 {
1718         return CDDM_from_curve_displist(ob, &ob->disp, NULL);
1719 }
1720
1721 DerivedMesh *CDDM_from_curve_orco(struct Scene *scene, Object *ob)
1722 {
1723         int *orco_index_ptr = NULL;
1724         int (*orco_index)[4] = NULL;
1725         float (*orco)[3] = NULL;
1726         DerivedMesh *dm = CDDM_from_curve_displist(ob, &ob->disp, &orco_index_ptr);
1727
1728         if (orco_index_ptr) {
1729                 orco = (float (*)[3])BKE_curve_make_orco(scene, ob);
1730         }
1731
1732         if (orco && orco_index_ptr) {
1733                 const char *uvname = "Orco";
1734
1735                 int totpoly = dm->getNumPolys(dm);
1736
1737                 MPoly *mpolys = dm->getPolyArray(dm);
1738                 MLoop *mloops = dm->getLoopArray(dm);
1739
1740                 MLoopUV *mloopuvs;
1741
1742                 CustomData_add_layer_named(&dm->polyData, CD_MTEXPOLY, CD_DEFAULT, NULL, dm->numPolyData, uvname);
1743                 mloopuvs = CustomData_add_layer_named(&dm->loopData, CD_MLOOPUV,  CD_DEFAULT, NULL, dm->numLoopData, uvname);
1744
1745                 BKE_mesh_nurbs_to_mdata_orco(mpolys, totpoly,
1746                                              mloops, mloopuvs,
1747                                              orco, orco_index);
1748         }
1749
1750         if (orco_index) {
1751                 MEM_freeN(orco_index);
1752         }
1753         if (orco) {
1754                 MEM_freeN(orco);
1755         }
1756
1757         return dm;
1758 }
1759
1760 DerivedMesh *CDDM_from_curve_displist(Object *ob, ListBase *dispbase, int **orco_index_ptr)
1761 {
1762         DerivedMesh *dm;
1763         CDDerivedMesh *cddm;
1764         MVert *allvert;
1765         MEdge *alledge;
1766         MLoop *allloop;
1767         MPoly *allpoly;
1768         int totvert, totedge, totloop, totpoly;
1769
1770         if (BKE_mesh_nurbs_displist_to_mdata(ob, dispbase, &allvert, &totvert, &alledge,
1771                                              &totedge, &allloop, &allpoly, &totloop, &totpoly, orco_index_ptr) != 0)
1772         {
1773                 /* Error initializing mdata. This often happens when curve is empty */
1774                 return CDDM_new(0, 0, 0, 0, 0);
1775         }
1776
1777         dm = CDDM_new(totvert, totedge, 0, totloop, totpoly);
1778         dm->deformedOnly = 1;
1779
1780         cddm = (CDDerivedMesh *)dm;
1781
1782         memcpy(cddm->mvert, allvert, totvert * sizeof(MVert));
1783         memcpy(cddm->medge, alledge, totedge * sizeof(MEdge));
1784         memcpy(cddm->mloop, allloop, totloop * sizeof(MLoop));
1785         memcpy(cddm->mpoly, allpoly, totpoly * sizeof(MPoly));
1786
1787         MEM_freeN(allvert);
1788         MEM_freeN(alledge);
1789         MEM_freeN(allloop);
1790         MEM_freeN(allpoly);
1791
1792         CDDM_calc_edges(dm);
1793
1794         return dm;
1795 }
1796
1797 static void loops_to_customdata_corners(BMesh *bm, CustomData *facedata,
1798                                         int cdindex, const BMLoop *l3[3],
1799                                         int numCol, int numTex)
1800 {
1801         const BMLoop *l;
1802         BMFace *f = l3[0]->f;
1803         MTFace *texface;
1804         MTexPoly *texpoly;
1805         MCol *mcol;
1806         MLoopCol *mloopcol;
1807         MLoopUV *mloopuv;
1808         int i, j, hasPCol = CustomData_has_layer(&bm->ldata, CD_PREVIEW_MLOOPCOL);
1809
1810         for (i = 0; i < numTex; i++) {
1811                 texface = CustomData_get_n(facedata, CD_MTFACE, cdindex, i);
1812                 texpoly = CustomData_bmesh_get_n(&bm->pdata, f->head.data, CD_MTEXPOLY, i);
1813                 
1814                 ME_MTEXFACE_CPY(texface, texpoly);
1815         
1816                 for (j = 0; j < 3; j++) {
1817                         l = l3[j];
1818                         mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_MLOOPUV, i);
1819                         copy_v2_v2(texface->uv[j], mloopuv->uv);
1820                 }
1821         }
1822
1823         for (i = 0; i < numCol; i++) {
1824                 mcol = CustomData_get_n(facedata, CD_MCOL, cdindex, i);
1825                 
1826                 for (j = 0; j < 3; j++) {
1827                         l = l3[j];
1828                         mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_MLOOPCOL, i);
1829                         MESH_MLOOPCOL_TO_MCOL(mloopcol, &mcol[j]);
1830                 }
1831         }
1832
1833         if (hasPCol) {
1834                 mcol = CustomData_get(facedata, cdindex, CD_PREVIEW_MCOL);
1835
1836                 for (j = 0; j < 3; j++) {
1837                         l = l3[j];
1838                         mloopcol = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_PREVIEW_MLOOPCOL);
1839                         MESH_MLOOPCOL_TO_MCOL(mloopcol, &mcol[j]);
1840                 }
1841         }
1842 }
1843
1844 /* used for both editbmesh and bmesh */
1845 static DerivedMesh *cddm_from_bmesh_ex(struct BMesh *bm, int use_mdisps,
1846                                        /* EditBMesh vars for use_tessface */
1847                                        int use_tessface,
1848                                        const int em_tottri, const BMLoop *(*em_looptris)[3]
1849                                        )
1850 {
1851         DerivedMesh *dm = CDDM_new(bm->totvert,
1852                                    bm->totedge,
1853                                    use_tessface ? em_tottri : 0,
1854                                    bm->totloop,
1855                                    bm->totface);
1856
1857         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
1858         BMIter iter, liter;
1859         BMVert *eve;
1860         BMEdge *eed;
1861         BMFace *efa;
1862         MVert *mvert = cddm->mvert;
1863         MEdge *medge = cddm->medge;
1864         MFace *mface = cddm->mface;
1865         MLoop *mloop = cddm->mloop;
1866         MPoly *mpoly = cddm->mpoly;
1867         int numCol = CustomData_number_of_layers(&bm->ldata, CD_MLOOPCOL);
1868         int numTex = CustomData_number_of_layers(&bm->pdata, CD_MTEXPOLY);
1869         int *index, add_orig;
1870         int has_crease, has_edge_bweight, has_vert_bweight;
1871         CustomDataMask mask;
1872         unsigned int i, j;
1873         
1874         has_edge_bweight = CustomData_has_layer(&bm->edata, CD_BWEIGHT);
1875         has_vert_bweight = CustomData_has_layer(&bm->vdata, CD_BWEIGHT);
1876         has_crease = CustomData_has_layer(&bm->edata, CD_CREASE);
1877         
1878         dm->deformedOnly = 1;
1879         
1880         /* don't add origindex layer if one already exists */
1881         add_orig = !CustomData_has_layer(&bm->pdata, CD_ORIGINDEX);
1882
1883         mask = use_mdisps ? CD_MASK_DERIVEDMESH | CD_MASK_MDISPS : CD_MASK_DERIVEDMESH;
1884         
1885         /* don't process shapekeys, we only feed them through the modifier stack as needed,
1886          * e.g. for applying modifiers or the like*/
1887         mask &= ~CD_MASK_SHAPEKEY;
1888         CustomData_merge(&bm->vdata, &dm->vertData, mask,
1889                          CD_CALLOC, dm->numVertData);
1890         CustomData_merge(&bm->edata, &dm->edgeData, mask,
1891                          CD_CALLOC, dm->numEdgeData);
1892         CustomData_merge(&bm->ldata, &dm->loopData, mask,
1893                          CD_CALLOC, dm->numLoopData);
1894         CustomData_merge(&bm->pdata, &dm->polyData, mask,
1895                          CD_CALLOC, dm->numPolyData);
1896         
1897         /* add tessellation mface layers */
1898         if (use_tessface) {
1899                 CustomData_from_bmeshpoly(&dm->faceData, &dm->polyData, &dm->loopData, em_tottri);
1900         }
1901
1902         index = dm->getVertDataArray(dm, CD_ORIGINDEX);
1903
1904         eve = BM_iter_new(&iter, bm, BM_VERTS_OF_MESH, NULL);
1905         for (i = 0; eve; eve = BM_iter_step(&iter), i++, index++) {
1906                 MVert *mv = &mvert[i];
1907
1908                 copy_v3_v3(mv->co, eve->co);
1909
1910                 BM_elem_index_set(eve, i); /* set_inline */
1911
1912                 normal_float_to_short_v3(mv->no, eve->no);
1913
1914                 mv->flag = BM_vert_flag_to_mflag(eve);
1915
1916                 if (has_vert_bweight)
1917                         mv->bweight = (unsigned char)(BM_elem_float_data_get(&bm->vdata, eve, CD_BWEIGHT) * 255.0f);
1918
1919                 if (add_orig) *index = i;
1920
1921                 CustomData_from_bmesh_block(&bm->vdata, &dm->vertData, eve->head.data, i);
1922         }
1923         bm->elem_index_dirty &= ~BM_VERT;
1924
1925         index = dm->getEdgeDataArray(dm, CD_ORIGINDEX);
1926         eed = BM_iter_new(&iter, bm, BM_EDGES_OF_MESH, NULL);
1927         for (i = 0; eed; eed = BM_iter_step(&iter), i++, index++) {
1928                 MEdge *med = &medge[i];
1929
1930                 BM_elem_index_set(eed, i); /* set_inline */
1931
1932                 med->v1 = BM_elem_index_get(eed->v1);
1933                 med->v2 = BM_elem_index_get(eed->v2);
1934
1935                 if (has_crease)
1936                         med->crease = (unsigned char)(BM_elem_float_data_get(&bm->edata, eed, CD_CREASE) * 255.0f);
1937                 if (has_edge_bweight)
1938                         med->bweight = (unsigned char)(BM_elem_float_data_get(&bm->edata, eed, CD_BWEIGHT) * 255.0f);
1939                 
1940                 med->flag = BM_edge_flag_to_mflag(eed);
1941
1942                 /* handle this differently to editmode switching,
1943                  * only enable draw for single user edges rather then calculating angle */
1944                 if ((med->flag & ME_EDGEDRAW) == 0) {
1945                         if (eed->l && eed->l == eed->l->radial_next) {
1946                                 med->flag |= ME_EDGEDRAW;
1947                         }
1948                 }
1949
1950                 CustomData_from_bmesh_block(&bm->edata, &dm->edgeData, eed->head.data, i);
1951                 if (add_orig) *index = i;
1952         }
1953         bm->elem_index_dirty &= ~BM_EDGE;
1954
1955         /* avoid this where possiblem, takes extra memory */
1956         if (use_tessface) {
1957                 int *polyindex;
1958
1959                 BM_mesh_elem_index_ensure(bm, BM_FACE);
1960
1961                 index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
1962                 for (i = 0; i < dm->numTessFaceData; i++, index++, polyindex++) {
1963                         MFace *mf = &mface[i];
1964                         const BMLoop **l = em_looptris[i];
1965                         efa = l[0]->f;
1966
1967                         mf->v1 = BM_elem_index_get(l[0]->v);
1968                         mf->v2 = BM_elem_index_get(l[1]->v);
1969                         mf->v3 = BM_elem_index_get(l[2]->v);
1970                         mf->v4 = 0;
1971                         mf->mat_nr = efa->mat_nr;
1972                         mf->flag = BM_face_flag_to_mflag(efa);
1973
1974                         /* map mfaces to polygons in the same cddm intentionally */
1975                         *index = BM_elem_index_get(efa);
1976
1977                         loops_to_customdata_corners(bm, &dm->faceData, i, l, numCol, numTex);
1978                         test_index_face(mf, &dm->faceData, i, 3);
1979                 }
1980         }
1981         
1982         index = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
1983         j = 0;
1984         efa = BM_iter_new(&iter, bm, BM_FACES_OF_MESH, NULL);
1985         for (i = 0; efa; i++, efa = BM_iter_step(&iter), index++) {
1986                 BMLoop *l;
1987                 MPoly *mp = &mpoly[i];
1988
1989                 BM_elem_index_set(efa, i); /* set_inline */
1990
1991                 mp->totloop = efa->len;
1992                 mp->flag = BM_face_flag_to_mflag(efa);
1993                 mp->loopstart = j;
1994                 mp->mat_nr = efa->mat_nr;
1995                 
1996                 BM_ITER_ELEM (l, &liter, efa, BM_LOOPS_OF_FACE) {
1997                         mloop->v = BM_elem_index_get(l->v);
1998                         mloop->e = BM_elem_index_get(l->e);
1999                         CustomData_from_bmesh_block(&bm->ldata, &dm->loopData, l->head.data, j);
2000
2001                         j++;
2002                         mloop++;
2003                 }
2004
2005                 CustomData_from_bmesh_block(&bm->pdata, &dm->polyData, efa->head.data, i);
2006
2007                 if (add_orig) *index = i;
2008         }
2009         bm->elem_index_dirty &= ~BM_FACE;
2010
2011         return dm;
2012 }
2013
2014 struct DerivedMesh *CDDM_from_bmesh(struct BMesh *bm, int use_mdisps)
2015 {
2016         return cddm_from_bmesh_ex(bm, use_mdisps, FALSE,
2017                                   /* these vars are for editmesh only */
2018                                   0, NULL);
2019 }
2020
2021 DerivedMesh *CDDM_from_editbmesh(BMEditMesh *em, int use_mdisps, int use_tessface)
2022 {
2023         return cddm_from_bmesh_ex(em->bm, use_mdisps,
2024                                   /* editmesh */
2025                                   use_tessface, em->tottri, (const BMLoop *(*)[3])em->looptris);
2026 }
2027
2028 static DerivedMesh *cddm_copy_ex(DerivedMesh *source, int faces_from_tessfaces)
2029 {
2030         CDDerivedMesh *cddm = cdDM_create("CDDM_copy cddm");
2031         DerivedMesh *dm = &cddm->dm;
2032         int numVerts = source->numVertData;
2033         int numEdges = source->numEdgeData;
2034         int numTessFaces = source->numTessFaceData;
2035         int numLoops = source->numLoopData;
2036         int numPolys = source->numPolyData;
2037
2038         /* ensure these are created if they are made on demand */
2039         source->getVertDataArray(source, CD_ORIGINDEX);
2040         source->getEdgeDataArray(source, CD_ORIGINDEX);
2041         source->getTessFaceDataArray(source, CD_ORIGINDEX);
2042         source->getPolyDataArray(source, CD_ORIGINDEX);
2043
2044         /* this initializes dm, and copies all non mvert/medge/mface layers */
2045         DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numTessFaces,
2046                          numLoops, numPolys);
2047         dm->deformedOnly = source->deformedOnly;
2048         dm->dirty = source->dirty;
2049
2050         CustomData_copy_data(&source->vertData, &dm->vertData, 0, 0, numVerts);
2051         CustomData_copy_data(&source->edgeData, &dm->edgeData, 0, 0, numEdges);
2052         CustomData_copy_data(&source->faceData, &dm->faceData, 0, 0, numTessFaces);
2053
2054         /* now add mvert/medge/mface layers */
2055         cddm->mvert = source->dupVertArray(source);
2056         cddm->medge = source->dupEdgeArray(source);
2057         cddm->mface = source->dupTessFaceArray(source);
2058
2059         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_ASSIGN, cddm->mvert, numVerts);
2060         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_ASSIGN, cddm->medge, numEdges);
2061         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_ASSIGN, cddm->mface, numTessFaces);
2062         
2063         if (!faces_from_tessfaces)
2064                 DM_DupPolys(source, dm);
2065         else
2066                 CDDM_tessfaces_to_faces(dm);
2067
2068         cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
2069         cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
2070
2071         return dm;
2072 }
2073
2074 DerivedMesh *CDDM_copy(DerivedMesh *source)
2075 {
2076         return cddm_copy_ex(source, 0);
2077 }
2078
2079 DerivedMesh *CDDM_copy_from_tessface(DerivedMesh *source)
2080 {
2081         return cddm_copy_ex(source, 1);
2082 }
2083
2084 /* note, the CD_ORIGINDEX layers are all 0, so if there is a direct
2085  * relationship between mesh data this needs to be set by the caller. */
2086 DerivedMesh *CDDM_from_template(DerivedMesh *source,
2087                                 int numVerts, int numEdges, int numTessFaces,
2088                                 int numLoops, int numPolys)
2089 {
2090         CDDerivedMesh *cddm = cdDM_create("CDDM_from_template dest");
2091         DerivedMesh *dm = &cddm->dm;
2092
2093         /* ensure these are created if they are made on demand */
2094         source->getVertDataArray(source, CD_ORIGINDEX);
2095         source->getEdgeDataArray(source, CD_ORIGINDEX);
2096         source->getTessFaceDataArray(source, CD_ORIGINDEX);
2097         source->getPolyDataArray(source, CD_ORIGINDEX);
2098
2099         /* this does a copy of all non mvert/medge/mface layers */
2100         DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numTessFaces, numLoops, numPolys);
2101
2102         /* now add mvert/medge/mface layers */
2103         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
2104         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
2105         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numTessFaces);
2106         CustomData_add_layer(&dm->loopData, CD_MLOOP, CD_CALLOC, NULL, numLoops);
2107         CustomData_add_layer(&dm->polyData, CD_MPOLY, CD_CALLOC, NULL, numPolys);
2108
2109         if (!CustomData_get_layer(&dm->vertData, CD_ORIGINDEX))
2110                 CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts);
2111         if (!CustomData_get_layer(&dm->edgeData, CD_ORIGINDEX))
2112                 CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
2113         if (!CustomData_get_layer(&dm->faceData, CD_ORIGINDEX))
2114                 CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numTessFaces);
2115
2116         cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
2117         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
2118         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
2119         cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
2120         cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
2121
2122         return dm;
2123 }
2124
2125 void CDDM_apply_vert_coords(DerivedMesh *dm, float (*vertCoords)[3])
2126 {
2127         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2128         MVert *vert;
2129         int i;
2130
2131         /* this will just return the pointer if it wasn't a referenced layer */
2132         vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2133         cddm->mvert = vert;
2134
2135         for (i = 0; i < dm->numVertData; ++i, ++vert)
2136                 copy_v3_v3(vert->co, vertCoords[i]);
2137 }
2138
2139 void CDDM_apply_vert_normals(DerivedMesh *dm, short (*vertNormals)[3])
2140 {
2141         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2142         MVert *vert;
2143         int i;
2144
2145         /* this will just return the pointer if it wasn't a referenced layer */
2146         vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2147         cddm->mvert = vert;
2148
2149         for (i = 0; i < dm->numVertData; ++i, ++vert)
2150                 copy_v3_v3_short(vert->no, vertNormals[i]);
2151 }
2152
2153 void CDDM_calc_normals_mapping_ex(DerivedMesh *dm, const short only_face_normals)
2154 {
2155         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2156         float (*face_nors)[3] = NULL;
2157
2158         if (dm->numVertData == 0) return;
2159
2160         /* now we skip calculating vertex normals for referenced layer,
2161          * no need to duplicate verts.
2162          * WATCH THIS, bmesh only change!,
2163          * need to take care of the side effects here - campbell */
2164         #if 0
2165         /* we don't want to overwrite any referenced layers */
2166         cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2167         #endif
2168
2169
2170         if (dm->numTessFaceData == 0) {
2171                 /* No tessellation on this mesh yet, need to calculate one.
2172                  *
2173                  * Important not to update face normals from polys since it
2174                  * interferes with assigning the new normal layer in the following code.
2175                  */
2176                 CDDM_recalc_tessellation_ex(dm, FALSE);
2177         }
2178         else {
2179                 /* A tessellation already exists, it should always have a CD_ORIGINDEX */
2180                 BLI_assert(CustomData_has_layer(&dm->faceData, CD_ORIGINDEX));
2181                 CustomData_free_layers(&dm->faceData, CD_NORMAL, dm->numTessFaceData);
2182         }
2183
2184
2185         face_nors = MEM_mallocN(sizeof(float) * 3 * dm->numTessFaceData, "face_nors");
2186
2187         /* calculate face normals */
2188         BKE_mesh_calc_normals_mapping_ex(cddm->mvert, dm->numVertData, CDDM_get_loops(dm), CDDM_get_polys(dm),
2189                                          dm->numLoopData, dm->numPolyData, NULL, cddm->mface, dm->numTessFaceData,
2190                                          CustomData_get_layer(&dm->faceData, CD_ORIGINDEX), face_nors,
2191                                          only_face_normals);
2192
2193         CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_ASSIGN,
2194                              face_nors, dm->numTessFaceData);
2195 }
2196
2197
2198 void CDDM_calc_normals_mapping(DerivedMesh *dm)
2199 {
2200         /* use this to skip calculating normals on original vert's, this may need to be changed */
2201         const short only_face_normals = CustomData_is_referenced_layer(&dm->vertData, CD_MVERT);
2202
2203         CDDM_calc_normals_mapping_ex(dm, only_face_normals);
2204 }
2205
2206 /* bmesh note: this matches what we have in trunk */
2207 void CDDM_calc_normals(DerivedMesh *dm)
2208 {
2209         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2210         float (*poly_nors)[3];
2211
2212         if (dm->numVertData == 0) return;
2213
2214         /* we don't want to overwrite any referenced layers */
2215         cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2216
2217         /* fill in if it exists */
2218         poly_nors = CustomData_get_layer(&dm->polyData, CD_NORMAL);
2219         if (!poly_nors) {
2220                 poly_nors = CustomData_add_layer(&dm->polyData, CD_NORMAL, CD_CALLOC, NULL, dm->numPolyData);
2221         }
2222
2223         BKE_mesh_calc_normals(cddm->mvert, dm->numVertData, CDDM_get_loops(dm), CDDM_get_polys(dm),
2224                               dm->numLoopData, dm->numPolyData, poly_nors);
2225 }
2226
2227 void CDDM_calc_normals_tessface(DerivedMesh *dm)
2228 {
2229         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2230         float (*face_nors)[3];
2231
2232         if (dm->numVertData == 0) return;
2233
2234         /* we don't want to overwrite any referenced layers */
2235         cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT, dm->numVertData);
2236
2237         /* fill in if it exists */
2238         face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL);
2239         if (!face_nors) {
2240                 face_nors = CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_CALLOC, NULL, dm->numTessFaceData);
2241         }
2242
2243         BKE_mesh_calc_normals_tessface(cddm->mvert, dm->numVertData,
2244                                        cddm->mface, dm->numTessFaceData, face_nors);
2245 }
2246
2247 #if 1
2248 /* merge verts
2249  *
2250  * vtargetmap is a table that maps vertices to target vertices.  a value of -1
2251  * indicates a vertex is a target, and is to be kept.
2252  *
2253  * this frees dm, and returns a new one.
2254  *
2255  * this is a really horribly written function.  ger. - joeedh
2256  *
2257  * note, CDDM_recalc_tessellation has to run on the returned DM if you want to access tessfaces.
2258  */
2259 DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap)
2260 {
2261         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2262         CDDerivedMesh *cddm2 = NULL;
2263         MVert *mv, *mvert = NULL;
2264         BLI_array_declare(mvert);
2265         MEdge *med, *medge = NULL;
2266         BLI_array_declare(medge);
2267         MPoly *mp, *mpoly = NULL;
2268         BLI_array_declare(mpoly);
2269         MLoop *ml, *mloop = NULL;
2270         BLI_array_declare(mloop);
2271         EdgeHash *ehash = BLI_edgehash_new();
2272         int *newv = NULL, *newe = NULL, *newl = NULL;
2273         int *oldv = NULL, *olde = NULL, *oldl = NULL, *oldp = NULL;
2274         BLI_array_declare(oldv); BLI_array_declare(olde); BLI_array_declare(oldl); BLI_array_declare(oldp);
2275         int i, j, c, totloop, totpoly;
2276         
2277         totloop = dm->numLoopData;
2278         totpoly = dm->numPolyData;
2279         
2280         newv = MEM_callocN(sizeof(int) * dm->numVertData, "newv vtable CDDM_merge_verts");
2281         newe = MEM_callocN(sizeof(int) * dm->numEdgeData, "newv etable CDDM_merge_verts");
2282         newl = MEM_callocN(sizeof(int) * totloop, "newv ltable CDDM_merge_verts");
2283         
2284         /* fill newl with destination vertex indices */
2285         mv = cddm->mvert;
2286         c = 0;
2287         for (i = 0; i < dm->numVertData; i++, mv++) {
2288                 if (vtargetmap[i] == -1) {
2289                         BLI_array_append(oldv, i);
2290                         newv[i] = c++;
2291                         BLI_array_append(mvert, *mv);
2292                 }
2293         }
2294         
2295         /* now link target vertices to destination indices */
2296         for (i = 0; i < dm->numVertData; i++) {
2297                 if (vtargetmap[i] != -1) {
2298                         newv[i] = newv[vtargetmap[i]];
2299                 }
2300         }
2301         
2302         /* find-replace merged vertices with target vertices */
2303         ml = cddm->mloop;
2304         for (i = 0; i < totloop; i++, ml++) {
2305                 if (vtargetmap[ml->v] != -1) {
2306                         ml->v = vtargetmap[ml->v];
2307                 }
2308         }
2309
2310         /* now go through and fix edges and faces */
2311         med = cddm->medge;
2312         c = 0;
2313         for (i = 0; i < dm->numEdgeData; i++, med++) {
2314                 
2315                 if (LIKELY(med->v1 != med->v2)) {
2316                         const unsigned int v1 = (vtargetmap[med->v1] != -1) ? vtargetmap[med->v1] : med->v1;
2317                         const unsigned int v2 = (vtargetmap[med->v2] != -1) ? vtargetmap[med->v2] : med->v2;
2318                         void **eh_p = BLI_edgehash_lookup_p(ehash, v1, v2);
2319
2320                         if (eh_p) {
2321                                 newe[i] = GET_INT_FROM_POINTER(*eh_p);
2322                         }
2323                         else {
2324                                 BLI_array_append(olde, i);
2325                                 newe[i] = c;
2326                                 BLI_array_append(medge, *med);
2327                                 BLI_edgehash_insert(ehash, v1, v2, SET_INT_IN_POINTER(c));
2328                                 c++;
2329                         }
2330                 }
2331                 else {
2332                         newe[i] = -1;
2333                 }
2334         }
2335         
2336         mp = cddm->mpoly;
2337         for (i = 0; i < totpoly; i++, mp++) {
2338                 MPoly *mp2;
2339                 
2340                 ml = cddm->mloop + mp->loopstart;
2341
2342                 c = 0;
2343                 for (j = 0; j < mp->totloop; j++, ml++) {
2344                         med = cddm->medge + ml->e;
2345                         if (LIKELY(med->v1 != med->v2)) {
2346                                 newl[j + mp->loopstart] = BLI_array_count(mloop);
2347                                 BLI_array_append(oldl, j + mp->loopstart);
2348                                 BLI_array_append(mloop, *ml);
2349                                 c++;
2350                         }
2351                 }
2352
2353                 if (UNLIKELY(c == 0)) {
2354                         continue;
2355                 }
2356                 
2357                 mp2 = BLI_array_append_r(mpoly, *mp);
2358                 mp2->totloop = c;
2359                 mp2->loopstart = BLI_array_count(mloop) - c;
2360                 
2361                 BLI_array_append(oldp, i);
2362         }
2363         
2364         /*create new cddm*/
2365         cddm2 = (CDDerivedMesh *) CDDM_from_template((DerivedMesh *)cddm, BLI_array_count(mvert), BLI_array_count(medge), 0, BLI_array_count(mloop), BLI_array_count(mpoly));
2366         
2367         /*update edge indices and copy customdata*/
2368         med = medge;
2369         for (i = 0; i < cddm2->dm.numEdgeData; i++, med++) {
2370                 if (newv[med->v1] != -1)
2371                         med->v1 = newv[med->v1];
2372                 if (newv[med->v2] != -1)
2373                         med->v2 = newv[med->v2];
2374                 
2375                 CustomData_copy_data(&dm->edgeData, &cddm2->dm.edgeData, olde[i], i, 1);
2376         }
2377         
2378         /*update loop indices and copy customdata*/
2379         ml = mloop;
2380         for (i = 0; i < cddm2->dm.numLoopData; i++, ml++) {
2381                 if (newe[ml->e] != -1)
2382                         ml->e = newe[ml->e];
2383                 if (newv[ml->v] != -1)
2384                         ml->v = newv[ml->v];
2385                         
2386                 CustomData_copy_data(&dm->loopData, &cddm2->dm.loopData, oldl[i], i, 1);
2387         }
2388         
2389         /*copy vertex customdata*/
2390         mv = mvert;
2391         for (i = 0; i < cddm2->dm.numVertData; i++, mv++) {
2392                 CustomData_copy_data(&dm->vertData, &cddm2->dm.vertData, oldv[i], i, 1);
2393         }
2394         
2395         /*copy poly customdata*/
2396         mp = mpoly;
2397         for (i = 0; i < cddm2->dm.numPolyData; i++, mp++) {
2398                 CustomData_copy_data(&dm->polyData, &cddm2->dm.polyData, oldp[i], i, 1);
2399         }
2400         
2401         /*copy over data.  CustomData_add_layer can do this, need to look it up.*/
2402         memcpy(cddm2->mvert, mvert, sizeof(MVert) * BLI_array_count(mvert));
2403         memcpy(cddm2->medge, medge, sizeof(MEdge) * BLI_array_count(medge));
2404         memcpy(cddm2->mloop, mloop, sizeof(MLoop) * BLI_array_count(mloop));
2405         memcpy(cddm2->mpoly, mpoly, sizeof(MPoly) * BLI_array_count(mpoly));
2406         BLI_array_free(mvert); BLI_array_free(medge); BLI_array_free(mloop); BLI_array_free(mpoly);
2407         
2408         if (newv) 
2409                 MEM_freeN(newv); 
2410         if (newe)
2411                 MEM_freeN(newe); 
2412         if (newl)
2413                 MEM_freeN(newl);
2414         if (oldv) 
2415                 MEM_freeN(oldv); 
2416         if (olde) 
2417                 MEM_freeN(olde); 
2418         if (oldl) 
2419                 MEM_freeN(oldl); 
2420         if (oldp) 
2421                 MEM_freeN(oldp);
2422         if (ehash)
2423                 BLI_edgehash_free(ehash, NULL);
2424
2425         /*free old derivedmesh*/
2426         dm->needsFree = 1;
2427         dm->release(dm);
2428         
2429         return (DerivedMesh *)cddm2;
2430 }
2431 #endif
2432
2433 void CDDM_calc_edges_tessface(DerivedMesh *dm)
2434 {
2435         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2436         CustomData edgeData;
2437         EdgeHashIterator *ehi;
2438         MFace *mf = cddm->mface;
2439         MEdge *med;
2440         EdgeHash *eh = BLI_edgehash_new();
2441         int i, *index, numEdges, maxFaces = dm->numTessFaceData;
2442
2443         for (i = 0; i < maxFaces; i++, mf++) {
2444                 if (!BLI_edgehash_haskey(eh, mf->v1, mf->v2))
2445                         BLI_edgehash_insert(eh, mf->v1, mf->v2, NULL);
2446                 if (!BLI_edgehash_haskey(eh, mf->v2, mf->v3))
2447                         BLI_edgehash_insert(eh, mf->v2, mf->v3, NULL);
2448                 
2449                 if (mf->v4) {
2450                         if (!BLI_edgehash_haskey(eh, mf->v3, mf->v4))
2451                                 BLI_edgehash_insert(eh, mf->v3, mf->v4, NULL);
2452                         if (!BLI_edgehash_haskey(eh, mf->v4, mf->v1))
2453                                 BLI_edgehash_insert(eh, mf->v4, mf->v1, NULL);
2454                 }
2455                 else {
2456                         if (!BLI_edgehash_haskey(eh, mf->v3, mf->v1))
2457                                 BLI_edgehash_insert(eh, mf->v3, mf->v1, NULL);
2458                 }
2459         }
2460
2461         numEdges = BLI_edgehash_size(eh);
2462
2463         /* write new edges into a temporary CustomData */
2464         CustomData_reset(&edgeData);
2465         CustomData_add_layer(&edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
2466         CustomData_add_layer(&edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
2467
2468         med = CustomData_get_layer(&edgeData, CD_MEDGE);
2469         index = CustomData_get_layer(&edgeData, CD_ORIGINDEX);
2470
2471         for (ehi = BLI_edgehashIterator_new(eh), i = 0;
2472              BLI_edgehashIterator_isDone(ehi) == FALSE;
2473              BLI_edgehashIterator_step(ehi), ++i, ++med, ++index)
2474         {
2475                 BLI_edgehashIterator_getKey(ehi, &med->v1, &med->v2);
2476
2477                 med->flag = ME_EDGEDRAW | ME_EDGERENDER;
2478                 *index = ORIGINDEX_NONE;
2479         }
2480         BLI_edgehashIterator_free(ehi);
2481
2482         /* free old CustomData and assign new one */
2483         CustomData_free(&dm->edgeData, dm->numEdgeData);
2484         dm->edgeData = edgeData;
2485         dm->numEdgeData = numEdges;
2486
2487         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
2488
2489         BLI_edgehash_free(eh, NULL);
2490 }
2491
2492 /* warning, this uses existing edges but CDDM_calc_edges_tessface() doesn't */
2493 void CDDM_calc_edges(DerivedMesh *dm)
2494 {
2495         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2496         CustomData edgeData;
2497         EdgeHashIterator *ehi;
2498         MPoly *mp = cddm->mpoly;
2499         MLoop *ml;
2500         MEdge *med;
2501         EdgeHash *eh = BLI_edgehash_new();
2502         int v1, v2;
2503         int *eindex;
2504         int i, j, *index, numEdges = cddm->dm.numEdgeData, maxFaces = dm->numPolyData;
2505
2506         eindex = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
2507
2508         med = cddm->medge;
2509         if (med) {
2510                 for (i = 0; i < numEdges; i++, med++) {
2511                         BLI_edgehash_insert(eh, med->v1, med->v2, SET_INT_IN_POINTER(i + 1));
2512                 }
2513         }
2514
2515         for (i = 0; i < maxFaces; i++, mp++) {
2516                 ml = cddm->mloop + mp->loopstart;
2517                 for (j = 0; j < mp->totloop; j++, ml++) {
2518                         v1 = ml->v;
2519                         v2 = ME_POLY_LOOP_NEXT(cddm->mloop, mp, j)->v;
2520                         if (!BLI_edgehash_haskey(eh, v1, v2)) {
2521                                 BLI_edgehash_insert(eh, v1, v2, NULL);
2522                         }
2523                 }
2524         }
2525
2526         numEdges = BLI_edgehash_size(eh);
2527
2528         /* write new edges into a temporary CustomData */
2529         CustomData_reset(&edgeData);
2530         CustomData_add_layer(&edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
2531         CustomData_add_layer(&edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
2532
2533         med = CustomData_get_layer(&edgeData, CD_MEDGE);
2534         index = CustomData_get_layer(&edgeData, CD_ORIGINDEX);
2535
2536         for (ehi = BLI_edgehashIterator_new(eh), i = 0;
2537              BLI_edgehashIterator_isDone(ehi) == FALSE;
2538              BLI_edgehashIterator_step(ehi), ++i, ++med, ++index)
2539         {
2540                 BLI_edgehashIterator_getKey(ehi, &med->v1, &med->v2);
2541                 j = GET_INT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi));
2542
2543                 med->flag = ME_EDGEDRAW | ME_EDGERENDER;
2544                 *index = j == 0 ? ORIGINDEX_NONE : eindex[j - 1];
2545
2546                 BLI_edgehashIterator_setValue(ehi, SET_INT_IN_POINTER(i));
2547         }
2548         BLI_edgehashIterator_free(ehi);
2549
2550         /* free old CustomData and assign new one */
2551         CustomData_free(&dm->edgeData, dm->numEdgeData);
2552         dm->edgeData = edgeData;
2553         dm->numEdgeData = numEdges;
2554
2555         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
2556
2557         mp = cddm->mpoly;
2558         for (i = 0; i < maxFaces; i++, mp++) {
2559                 ml = cddm->mloop + mp->loopstart;
2560                 for (j = 0; j < mp->totloop; j++, ml++) {
2561                         v1 = ml->v;
2562                         v2 = ME_POLY_LOOP_NEXT(cddm->mloop, mp, j)->v;
2563                         ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, v1, v2));
2564                 }
2565         }
2566
2567         BLI_edgehash_free(eh, NULL);
2568 }
2569
2570 void CDDM_lower_num_verts(DerivedMesh *dm, int numVerts)
2571 {
2572         if (numVerts < dm->numVertData)
2573                 CustomData_free_elem(&dm->vertData, numVerts, dm->numVertData - numVerts);
2574
2575         dm->numVertData = numVerts;
2576 }
2577
2578 void CDDM_lower_num_edges(DerivedMesh *dm, int numEdges)
2579 {
2580         if (numEdges < dm->numEdgeData)
2581                 CustomData_free_elem(&dm->edgeData, numEdges, dm->numEdgeData - numEdges);
2582
2583         dm->numEdgeData = numEdges;
2584 }
2585
2586 void CDDM_lower_num_tessfaces(DerivedMesh *dm, int numTessFaces)
2587 {
2588         if (numTessFaces < dm->numTessFaceData)
2589                 CustomData_free_elem(&dm->faceData, numTessFaces, dm->numTessFaceData - numTessFaces);
2590
2591         dm->numTessFaceData = numTessFaces;
2592 }
2593
2594 void CDDM_lower_num_polys(DerivedMesh *dm, int numPolys)
2595 {
2596         if (numPolys < dm->numPolyData)
2597                 CustomData_free_elem(&dm->polyData, numPolys, dm->numPolyData - numPolys);
2598
2599         dm->numPolyData = numPolys;
2600 }
2601
2602 /* mesh element access functions */
2603
2604 MVert *CDDM_get_vert(DerivedMesh *dm, int index)
2605 {
2606         return &((CDDerivedMesh *)dm)->mvert[index];
2607 }
2608
2609 MEdge *CDDM_get_edge(DerivedMesh *dm, int index)
2610 {
2611         return &((CDDerivedMesh *)dm)->medge[index];
2612 }
2613
2614 MFace *CDDM_get_tessface(DerivedMesh *dm, int index)
2615 {
2616         return &((CDDerivedMesh *)dm)->mface[index];
2617 }
2618
2619 MLoop *CDDM_get_loop(DerivedMesh *dm, int index)
2620 {
2621         return &((CDDerivedMesh *)dm)->mloop[index];
2622 }
2623
2624 MPoly *CDDM_get_poly(DerivedMesh *dm, int index)
2625 {
2626         return &((CDDerivedMesh *)dm)->mpoly[index];
2627 }
2628
2629 /* array access functions */
2630
2631 MVert *CDDM_get_verts(DerivedMesh *dm)
2632 {
2633         return ((CDDerivedMesh *)dm)->mvert;
2634 }
2635
2636 MEdge *CDDM_get_edges(DerivedMesh *dm)
2637 {
2638         return ((CDDerivedMesh *)dm)->medge;
2639 }
2640
2641 MFace *CDDM_get_tessfaces(DerivedMesh *dm)
2642 {
2643         return ((CDDerivedMesh *)dm)->mface;
2644 }
2645
2646 MLoop *CDDM_get_loops(DerivedMesh *dm)
2647 {
2648         return ((CDDerivedMesh *)dm)->mloop;
2649 }
2650
2651 MPoly *CDDM_get_polys(DerivedMesh *dm)
2652 {
2653         return ((CDDerivedMesh *)dm)->mpoly;
2654 }
2655
2656 void CDDM_tessfaces_to_faces(DerivedMesh *dm)
2657 {
2658         /* converts mfaces to mpolys/mloops */
2659         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2660
2661         BKE_mesh_convert_mfaces_to_mpolys_ex(NULL, &cddm->dm.faceData, &cddm->dm.loopData, &cddm->dm.polyData,
2662                                              cddm->dm.numEdgeData, cddm->dm.numTessFaceData,
2663                                              cddm->dm.numLoopData, cddm->dm.numPolyData,
2664                                              cddm->medge, cddm->mface,
2665                                              &cddm->dm.numLoopData, &cddm->dm.numPolyData,
2666                                              &cddm->mloop, &cddm->mpoly);
2667 }
2668
2669 void CDDM_set_mvert(DerivedMesh *dm, MVert *mvert)
2670 {
2671         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2672         
2673         if (!CustomData_has_layer(&dm->vertData, CD_MVERT))
2674                 CustomData_add_layer(&dm->vertData, CD_MVERT, CD_ASSIGN, mvert, dm->numVertData);
2675                                 
2676         cddm->mvert = mvert;
2677 }
2678
2679 void CDDM_set_medge(DerivedMesh *dm, MEdge *medge)
2680 {
2681         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2682
2683         if (!CustomData_has_layer(&dm->edgeData, CD_MEDGE))
2684                 CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_ASSIGN, medge, dm->numEdgeData);
2685
2686         cddm->medge = medge;
2687 }
2688
2689 void CDDM_set_mface(DerivedMesh *dm, MFace *mface)
2690 {
2691         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2692
2693         if (!CustomData_has_layer(&dm->faceData, CD_MFACE))
2694                 CustomData_add_layer(&dm->faceData, CD_MFACE, CD_ASSIGN, mface, dm->numTessFaceData);
2695
2696         cddm->mface = mface;
2697 }
2698
2699 void CDDM_set_mloop(DerivedMesh *dm, MLoop *mloop)
2700 {
2701         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2702
2703         if (!CustomData_has_layer(&dm->loopData, CD_MLOOP))
2704                 CustomData_add_layer(&dm->loopData, CD_MLOOP, CD_ASSIGN, mloop, dm->numLoopData);
2705
2706         cddm->mloop = mloop;
2707 }
2708
2709 void CDDM_set_mpoly(DerivedMesh *dm, MPoly *mpoly)
2710 {
2711         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
2712
2713         if (!CustomData_has_layer(&dm->polyData, CD_MPOLY))
2714                 CustomData_add_layer(&dm->polyData, CD_MPOLY, CD_ASSIGN, mpoly, dm->numPolyData);
2715
2716         cddm->mpoly = mpoly;
2717 }