merge from 21113 to 21377
[blender.git] / source / blender / blenkernel / intern / cdderivedmesh.c
1 /*
2 * $Id$
3 *
4 * ***** BEGIN GPL LICENSE BLOCK *****
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software  Foundation,
18 * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19 *
20 * The Original Code is Copyright (C) 2006 Blender Foundation.
21 * All rights reserved.
22 *
23 * The Original Code is: all of this file.
24 *
25 * Contributor(s): Ben Batt <benbatt@gmail.com>
26 *
27 * ***** END GPL LICENSE BLOCK *****
28 *
29 * Implementation of CDDerivedMesh.
30 *
31 * BKE_cdderivedmesh.h contains the function prototypes for this file.
32 *
33 */ 
34
35 /* TODO maybe BIF_gl.h should include string.h? */
36 #include <string.h>
37 #include "BIF_gl.h"
38
39 #include "BKE_cdderivedmesh.h"
40 #include "BKE_customdata.h"
41 #include "BKE_DerivedMesh.h"
42 #include "BKE_displist.h"
43 #include "BKE_global.h"
44 #include "BKE_mesh.h"
45 #include "BKE_multires.h"
46 #include "BKE_utildefines.h"
47
48 #include "BLI_arithb.h"
49 #include "BLI_blenlib.h"
50 #include "BLI_edgehash.h"
51 #include "BLI_editVert.h"
52 #include "BLI_ghash.h"
53
54 #include "DNA_mesh_types.h"
55 #include "DNA_meshdata_types.h"
56 #include "DNA_modifier_types.h"
57 #include "DNA_object_fluidsim.h"
58 #include "DNA_object_types.h"
59 #include "DNA_scene_types.h"
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 } CDDerivedMesh;
81
82 /**************** DerivedMesh interface functions ****************/
83 static int cdDM_getNumVerts(DerivedMesh *dm)
84 {
85         return dm->numVertData;
86 }
87
88 static int cdDM_getNumEdges(DerivedMesh *dm)
89 {
90         return dm->numEdgeData;
91 }
92
93 static int cdDM_getNumFaces(DerivedMesh *dm)
94 {
95         return dm->numFaceData;
96 }
97
98 static void cdDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
99 {
100         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
101         *vert_r = cddm->mvert[index];
102 }
103
104 static void cdDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
105 {
106         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
107         *edge_r = cddm->medge[index];
108 }
109
110 static void cdDM_getFace(DerivedMesh *dm, int index, MFace *face_r)
111 {
112         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
113         *face_r = cddm->mface[index];
114 }
115
116 static void cdDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
117 {
118         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
119         memcpy(vert_r, cddm->mvert, sizeof(*vert_r) * dm->numVertData);
120 }
121
122 static void cdDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r)
123 {
124         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
125         memcpy(edge_r, cddm->medge, sizeof(*edge_r) * dm->numEdgeData);
126 }
127
128 static void cdDM_copyFaceArray(DerivedMesh *dm, MFace *face_r)
129 {
130         CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
131         memcpy(face_r, cddm->mface, sizeof(*face_r) * dm->numFaceData);
132 }
133
134 static void cdDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
135 {
136         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
137         int i;
138
139         if (dm->numVertData) {
140                 for (i=0; i<dm->numVertData; i++) {
141                         DO_MINMAX(cddm->mvert[i].co, min_r, max_r);
142                 }
143         } else {
144                 min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
145         }
146 }
147
148 static void cdDM_getVertCo(DerivedMesh *dm, int index, float co_r[3])
149 {
150         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
151
152         VECCOPY(co_r, cddm->mvert[index].co);
153 }
154
155 static void cdDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3])
156 {
157         MVert *mv = CDDM_get_verts(dm);
158         int i;
159
160         for(i = 0; i < dm->numVertData; i++, mv++)
161                 VECCOPY(cos_r[i], mv->co);
162 }
163
164 static void cdDM_getVertNo(DerivedMesh *dm, int index, float no_r[3])
165 {
166         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
167         short *no = cddm->mvert[index].no;
168
169         no_r[0] = no[0]/32767.f;
170         no_r[1] = no[1]/32767.f;
171         no_r[2] = no[2]/32767.f;
172 }
173
174 static void cdDM_drawVerts(DerivedMesh *dm)
175 {
176         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
177         MVert *mv = cddm->mvert;
178         int i;
179
180         glBegin(GL_POINTS);
181         for(i = 0; i < dm->numVertData; i++, mv++)
182                 glVertex3fv(mv->co);
183         glEnd();
184 }
185
186 static void cdDM_drawUVEdges(DerivedMesh *dm)
187 {
188         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
189         MFace *mf = cddm->mface;
190         MTFace *tf = DM_get_face_data_layer(dm, CD_MTFACE);
191         int i;
192
193         if(mf) {
194                 glBegin(GL_LINES);
195                 for(i = 0; i < dm->numFaceData; i++, mf++, tf++) {
196                         if(!(mf->flag&ME_HIDE)) {
197                                 glVertex2fv(tf->uv[0]);
198                                 glVertex2fv(tf->uv[1]);
199
200                                 glVertex2fv(tf->uv[1]);
201                                 glVertex2fv(tf->uv[2]);
202
203                                 if(!mf->v4) {
204                                         glVertex2fv(tf->uv[2]);
205                                         glVertex2fv(tf->uv[0]);
206                                 } else {
207                                         glVertex2fv(tf->uv[2]);
208                                         glVertex2fv(tf->uv[3]);
209
210                                         glVertex2fv(tf->uv[3]);
211                                         glVertex2fv(tf->uv[0]);
212                                 }
213                         }
214                 }
215                 glEnd();
216         }
217 }
218
219 static void cdDM_drawEdges(DerivedMesh *dm, int drawLooseEdges)
220 {
221         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
222         MVert *mvert = cddm->mvert;
223         MEdge *medge = cddm->medge;
224         int i;
225                 
226         glBegin(GL_LINES);
227         for(i = 0; i < dm->numEdgeData; i++, medge++) {
228                 if((medge->flag&ME_EDGEDRAW)
229                    && (drawLooseEdges || !(medge->flag&ME_LOOSEEDGE))) {
230                         glVertex3fv(mvert[medge->v1].co);
231                         glVertex3fv(mvert[medge->v2].co);
232                 }
233         }
234         glEnd();
235 }
236
237 static void cdDM_drawLooseEdges(DerivedMesh *dm)
238 {
239         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
240         MVert *mvert = cddm->mvert;
241         MEdge *medge = cddm->medge;
242         int i;
243
244         glBegin(GL_LINES);
245         for(i = 0; i < dm->numEdgeData; i++, medge++) {
246                 if(medge->flag&ME_LOOSEEDGE) {
247                         glVertex3fv(mvert[medge->v1].co);
248                         glVertex3fv(mvert[medge->v2].co);
249                 }
250         }
251         glEnd();
252 }
253
254 static void cdDM_drawFacesSolid(DerivedMesh *dm, int (*setMaterial)(int, void *attribs))
255 {
256         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
257         MVert *mvert = cddm->mvert;
258         MFace *mface = cddm->mface;
259         float *nors= dm->getFaceDataArray(dm, CD_NORMAL);
260         int a, glmode = -1, shademodel = -1, matnr = -1, drawCurrentMat = 1;
261
262 #define PASSVERT(index) {                                               \
263         if(shademodel == GL_SMOOTH) {                           \
264                 short *no = mvert[index].no;                    \
265                 glNormal3sv(no);                                                \
266         }                                                                                       \
267         glVertex3fv(mvert[index].co);   \
268 }
269
270         if( GPU_buffer_legacy(dm) ) {
271                 DEBUG_VBO( "Using legacy code. cdDM_drawFacesSolid\n" );
272                 glBegin(glmode = GL_QUADS);
273                 for(a = 0; a < dm->numFaceData; a++, mface++) {
274                         int new_glmode, new_matnr, new_shademodel;
275
276                         new_glmode = mface->v4?GL_QUADS:GL_TRIANGLES;
277                         new_matnr = mface->mat_nr + 1;
278                         new_shademodel = (mface->flag & ME_SMOOTH)?GL_SMOOTH:GL_FLAT;
279                         
280                         if(new_glmode != glmode || new_matnr != matnr
281                            || new_shademodel != shademodel) {
282                                 glEnd();
283
284                                 drawCurrentMat = setMaterial(matnr = new_matnr, NULL);
285
286                                 glShadeModel(shademodel = new_shademodel);
287                                 glBegin(glmode = new_glmode);
288                         } 
289                         
290                         if(drawCurrentMat) {
291                                 if(shademodel == GL_FLAT) {
292                                         if (nors) {
293                                                 glNormal3fv(nors);
294                                         }
295                                         else {
296                                                 /* TODO make this better (cache facenormals as layer?) */
297                                                 float nor[3];
298                                                 if(mface->v4) {
299                                                         CalcNormFloat4(mvert[mface->v1].co, mvert[mface->v2].co,
300                                                                                    mvert[mface->v3].co, mvert[mface->v4].co,
301                                                                                    nor);
302                                                 } else {
303                                                         CalcNormFloat(mvert[mface->v1].co, mvert[mface->v2].co,
304                                                                                   mvert[mface->v3].co, nor);
305                                                 }
306                                                 glNormal3fv(nor);
307                                         }
308                                 }
309
310                                 PASSVERT(mface->v1);
311                                 PASSVERT(mface->v2);
312                                 PASSVERT(mface->v3);
313                                 if(mface->v4) {
314                                         PASSVERT(mface->v4);
315                                 }
316                         }
317
318                         if(nors) nors += 3;
319                 }
320                 glEnd();
321         }
322         else {  /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
323                 GPU_vertex_setup( dm );
324                 GPU_normal_setup( dm );
325                 if( !GPU_buffer_legacy(dm) ) {
326                         glShadeModel(GL_SMOOTH);
327                         for( a = 0; a < dm->drawObject->nmaterials; a++ ) {
328                                 setMaterial(dm->drawObject->materials[a].mat_nr+1, NULL);
329                                 glDrawArrays(GL_TRIANGLES, dm->drawObject->materials[a].start, dm->drawObject->materials[a].end-dm->drawObject->materials[a].start);
330                         }
331                 }
332                 GPU_buffer_unbind( );
333         }
334
335 #undef PASSVERT
336         glShadeModel(GL_FLAT);
337 }
338
339 static void cdDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned char *col1, unsigned char *col2)
340 {
341         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
342         int a, glmode;
343         unsigned char *cp1, *cp2;
344         MVert *mvert = cddm->mvert;
345         MFace *mface = cddm->mface;
346
347         cp1 = col1;
348         if(col2) {
349                 cp2 = col2;
350         } else {
351                 cp2 = NULL;
352                 useTwoSided = 0;
353         }
354
355         /* there's a conflict here... twosided colors versus culling...? */
356         /* defined by history, only texture faces have culling option */
357         /* we need that as mesh option builtin, next to double sided lighting */
358         if(col1 && col2)
359                 glEnable(GL_CULL_FACE);
360
361         if( GPU_buffer_legacy(dm) ) {
362                 DEBUG_VBO( "Using legacy code. cdDM_drawFacesColored\n" );
363                 glShadeModel(GL_SMOOTH);
364                 glBegin(glmode = GL_QUADS);
365                 for(a = 0; a < dm->numFaceData; a++, mface++, cp1 += 16) {
366                         int new_glmode = mface->v4?GL_QUADS:GL_TRIANGLES;
367
368                         if(new_glmode != glmode) {
369                                 glEnd();
370                                 glBegin(glmode = new_glmode);
371                         }
372                                 
373                         glColor3ub(cp1[0], cp1[1], cp1[2]);
374                         glVertex3fv(mvert[mface->v1].co);
375                         glColor3ub(cp1[4], cp1[5], cp1[6]);
376                         glVertex3fv(mvert[mface->v2].co);
377                         glColor3ub(cp1[8], cp1[9], cp1[10]);
378                         glVertex3fv(mvert[mface->v3].co);
379                         if(mface->v4) {
380                                 glColor3ub(cp1[12], cp1[13], cp1[14]);
381                                 glVertex3fv(mvert[mface->v4].co);
382                         }
383                                 
384                         if(useTwoSided) {
385                                 glColor3ub(cp2[8], cp2[9], cp2[10]);
386                                 glVertex3fv(mvert[mface->v3].co );
387                                 glColor3ub(cp2[4], cp2[5], cp2[6]);
388                                 glVertex3fv(mvert[mface->v2].co );
389                                 glColor3ub(cp2[0], cp2[1], cp2[2]);
390                                 glVertex3fv(mvert[mface->v1].co );
391                                 if(mface->v4) {
392                                         glColor3ub(cp2[12], cp2[13], cp2[14]);
393                                         glVertex3fv(mvert[mface->v4].co );
394                                 }
395                         }
396                         if(col2) cp2 += 16;
397                 }
398                 glEnd();
399         }
400         else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
401                 GPU_color4_upload(dm,cp1);
402                 GPU_vertex_setup(dm);
403                 GPU_color_setup(dm);
404                 if( !GPU_buffer_legacy(dm) ) {
405                         glShadeModel(GL_SMOOTH);
406                         glDrawArrays(GL_TRIANGLES, 0, dm->drawObject->nelements);
407
408                         if( useTwoSided ) {
409                                 GPU_color4_upload(dm,cp2);
410                                 GPU_color_setup(dm);
411                                 glCullFace(GL_FRONT);
412                                 glDrawArrays(GL_TRIANGLES, 0, dm->drawObject->nelements);
413                                 glCullFace(GL_BACK);
414                         }
415                 }
416                 GPU_buffer_unbind();
417         }
418
419         glShadeModel(GL_FLAT);
420         glDisable(GL_CULL_FACE);
421 }
422
423 static void cdDM_drawFacesTex_common(DerivedMesh *dm,
424                int (*drawParams)(MTFace *tface, MCol *mcol, int matnr),
425                int (*drawParamsMapped)(void *userData, int index),
426                void *userData) 
427 {
428         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
429         MVert *mv = cddm->mvert;
430         MFace *mf = cddm->mface;
431         MCol *mcol = dm->getFaceDataArray(dm, CD_MCOL);
432         float *nors= dm->getFaceDataArray(dm, CD_NORMAL);
433         MTFace *tf = DM_get_face_data_layer(dm, CD_MTFACE);
434         int i, orig, *index = DM_get_face_data_layer(dm, CD_ORIGINDEX);
435         int startFace = 0, lastFlag = 0xdeadbeef;
436
437         if( GPU_buffer_legacy(dm) ) {
438                 DEBUG_VBO( "Using legacy code. cdDM_drawFacesTex_common\n" );
439                 for(i = 0; i < dm->numFaceData; i++, mf++) {
440                         MVert *mvert;
441                         int flag;
442                         unsigned char *cp = NULL;
443
444                         if(drawParams) {
445                                 flag = drawParams(tf? &tf[i]: NULL, mcol? &mcol[i*4]: NULL, mf->mat_nr);
446                         }
447                         else {
448                                 if(index) {
449                                         orig = *index++;
450                                         if(orig == ORIGINDEX_NONE)              { if(nors) nors += 3; continue; }
451                                         if(drawParamsMapped) flag = drawParamsMapped(userData, orig);
452                                         else    { if(nors) nors += 3; continue; }
453                                 }
454                                 else
455                                         if(drawParamsMapped) flag = drawParamsMapped(userData, i);
456                                         else    { if(nors) nors += 3; continue; }
457                         }
458                         
459                         if(flag != 0) {
460                                 if (flag==1 && mcol)
461                                         cp= (unsigned char*) &mcol[i*4];
462
463                                 if(!(mf->flag&ME_SMOOTH)) {
464                                         if (nors) {
465                                                 glNormal3fv(nors);
466                                         }
467                                         else {
468                                                 float nor[3];
469                                                 if(mf->v4) {
470                                                         CalcNormFloat4(mv[mf->v1].co, mv[mf->v2].co,
471                                                                                    mv[mf->v3].co, mv[mf->v4].co,
472                                                                                    nor);
473                                                 } else {
474                                                         CalcNormFloat(mv[mf->v1].co, mv[mf->v2].co,
475                                                                                   mv[mf->v3].co, nor);
476                                                 }
477                                                 glNormal3fv(nor);
478                                         }
479                                 }
480
481                                 glBegin(mf->v4?GL_QUADS:GL_TRIANGLES);
482                                 if(tf) glTexCoord2fv(tf[i].uv[0]);
483                                 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
484                                 mvert = &mv[mf->v1];
485                                 if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no);
486                                 glVertex3fv(mvert->co);
487                                         
488                                 if(tf) glTexCoord2fv(tf[i].uv[1]);
489                                 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
490                                 mvert = &mv[mf->v2];
491                                 if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no);
492                                 glVertex3fv(mvert->co);
493
494                                 if(tf) glTexCoord2fv(tf[i].uv[2]);
495                                 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
496                                 mvert = &mv[mf->v3];
497                                 if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no);
498                                 glVertex3fv(mvert->co);
499
500                                 if(mf->v4) {
501                                         if(tf) glTexCoord2fv(tf[i].uv[3]);
502                                         if(cp) glColor3ub(cp[15], cp[14], cp[13]);
503                                         mvert = &mv[mf->v4];
504                                         if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no);
505                                         glVertex3fv(mvert->co);
506                                 }
507                                 glEnd();
508                         }
509                         
510                         if(nors) nors += 3;
511                 }
512         } else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
513                 GPU_vertex_setup( dm );
514                 GPU_normal_setup( dm );
515                 GPU_uv_setup( dm );
516                 if( mcol != 0 ) {
517                         if( dm->drawObject->colType != CD_MCOL ) {
518                                 unsigned char *colors = MEM_mallocN(dm->getNumFaces(dm)*3*sizeof(unsigned char), "cdDM_drawFacesTex_common");
519                                 for( i=0; i < dm->getNumFaces(dm); i++ ) {
520                                         colors[i*3] = mcol[i].r;
521                                         colors[i*3+1] = mcol[i].g;
522                                         colors[i*3+2] = mcol[i].b;
523                                 }
524                                 GPU_color3_upload(dm,colors);
525                                 MEM_freeN(colors);
526                                 dm->drawObject->colType = CD_MCOL;
527                         }
528                         GPU_color_setup( dm );
529                 }
530                 if( !GPU_buffer_legacy(dm) ) {
531                         glShadeModel( GL_SMOOTH );
532                         for(i = 0; i < dm->drawObject->nelements/3; i++) {
533                                 int actualFace = dm->drawObject->faceRemap[i];
534                                 int flag;
535                                 unsigned char *cp = NULL;
536
537                                 if(drawParams) {
538                                         flag = drawParams(tf? &tf[actualFace]: NULL, mcol? &mcol[actualFace*4]: NULL, mf[actualFace].mat_nr);
539                                 }
540                                 else {
541                                         if(index) {
542                                                 orig = index[actualFace];
543                                                 if(drawParamsMapped)
544                                                         flag = drawParamsMapped(userData, orig);
545                                         }
546                                         else
547                                                 if(drawParamsMapped)
548                                                         flag = drawParamsMapped(userData, actualFace);
549                                 }
550                                 if( flag != lastFlag ) {
551                                         if( startFace < i ) {
552                                                 if( lastFlag != 0 ) { /* if the flag is 0 it means the face is hidden or invisible */
553                                                         if (lastFlag==1 && mcol)
554                                                                 GPU_color_switch(1);
555                                                         else
556                                                                 GPU_color_switch(0);
557                                                         glDrawArrays(GL_TRIANGLES,startFace*3,(i-startFace)*3);
558                                                 }
559                                         }
560                                         lastFlag = flag;
561                                         startFace = i;
562                                 }
563                         }
564                         if( startFace < dm->drawObject->nelements/3 ) {
565                                 if( lastFlag != 0 ) { /* if the flag is 0 it means the face is hidden or invisible */
566                                         if (lastFlag==1 && mcol)
567                                                 GPU_color_switch(1);
568                                         else
569                                                 GPU_color_switch(0);
570                                         glDrawArrays(GL_TRIANGLES,startFace*3,dm->drawObject->nelements-startFace*3);
571                                 }
572                         }
573                 }
574                 GPU_buffer_unbind();
575                 glShadeModel( GL_FLAT );
576         }
577 }
578
579 static void cdDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, MCol *mcol, int matnr))
580 {
581         cdDM_drawFacesTex_common(dm, setDrawOptions, NULL, NULL);
582 }
583
584 static void cdDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors)
585 {
586         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
587         MVert *mv = cddm->mvert;
588         MFace *mf = cddm->mface;
589         MCol *mc;
590         float *nors= dm->getFaceDataArray(dm, CD_NORMAL);
591         int i, orig, *index = DM_get_face_data_layer(dm, CD_ORIGINDEX);
592
593         mc = DM_get_face_data_layer(dm, CD_WEIGHT_MCOL);
594         if(!mc)
595                 mc = DM_get_face_data_layer(dm, CD_MCOL);
596
597         if( GPU_buffer_legacy(dm) ) {
598                 DEBUG_VBO( "Using legacy code. cdDM_drawFacesTex_common\n" );
599                 for(i = 0; i < dm->numFaceData; i++, mf++) {
600                         int drawSmooth = (mf->flag & ME_SMOOTH);
601
602                         if(index) {
603                                 orig = *index++;
604                                 if(setDrawOptions && orig == ORIGINDEX_NONE)
605                                         { if(nors) nors += 3; continue; }
606                         }
607                         else
608                                 orig = i;
609
610                         if(!setDrawOptions || setDrawOptions(userData, orig, &drawSmooth)) {
611                                 unsigned char *cp = NULL;
612
613                                 if(useColors && mc)
614                                         cp = (unsigned char *)&mc[i * 4];
615
616                                 glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
617                                 glBegin(mf->v4?GL_QUADS:GL_TRIANGLES);
618
619                                 if (!drawSmooth) {
620                                         if (nors) {
621                                                 glNormal3fv(nors);
622                                         }
623                                         else {
624                                                 float nor[3];
625                                                 if(mf->v4) {
626                                                         CalcNormFloat4(mv[mf->v1].co, mv[mf->v2].co,
627                                                                                    mv[mf->v3].co, mv[mf->v4].co,
628                                                                                    nor);
629                                                 } else {
630                                                         CalcNormFloat(mv[mf->v1].co, mv[mf->v2].co,
631                                                                                   mv[mf->v3].co, nor);
632                                                 }
633                                                 glNormal3fv(nor);
634                                         }
635
636                                         if(cp) glColor3ub(cp[3], cp[2], cp[1]);
637                                         glVertex3fv(mv[mf->v1].co);
638                                         if(cp) glColor3ub(cp[7], cp[6], cp[5]);
639                                         glVertex3fv(mv[mf->v2].co);
640                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
641                                         glVertex3fv(mv[mf->v3].co);
642                                         if(mf->v4) {
643                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
644                                                 glVertex3fv(mv[mf->v4].co);
645                                         }
646                                 } else {
647                                         if(cp) glColor3ub(cp[3], cp[2], cp[1]);
648                                         glNormal3sv(mv[mf->v1].no);
649                                         glVertex3fv(mv[mf->v1].co);
650                                         if(cp) glColor3ub(cp[7], cp[6], cp[5]);
651                                         glNormal3sv(mv[mf->v2].no);
652                                         glVertex3fv(mv[mf->v2].co);
653                                         if(cp) glColor3ub(cp[11], cp[10], cp[9]);
654                                         glNormal3sv(mv[mf->v3].no);
655                                         glVertex3fv(mv[mf->v3].co);
656                                         if(mf->v4) {
657                                                 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
658                                                 glNormal3sv(mv[mf->v4].no);
659                                                 glVertex3fv(mv[mf->v4].co);
660                                         }
661                                 }
662
663                                 glEnd();
664                         }
665                         
666                         if (nors) nors += 3;
667                 }
668         }
669         else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
670                 int state = 1;
671                 int prevstate = 1;
672                 int prevstart = 0;
673                 GPU_vertex_setup(dm);
674                 GPU_normal_setup(dm);
675                 if( useColors && mc )
676                         GPU_color_setup(dm);
677                 if( !GPU_buffer_legacy(dm) ) {
678                         glShadeModel(GL_SMOOTH);
679                         for( i = 0; i < dm->drawObject->nelements/3; i++ ) {
680                                 int actualFace = dm->drawObject->faceRemap[i];
681                                 int drawSmooth = (mf[actualFace].flag & ME_SMOOTH);
682                                 int dontdraw = 0;
683                                 if(index) {
684                                         orig = index[actualFace];
685                                         if(setDrawOptions && orig == ORIGINDEX_NONE)
686                                                 dontdraw = 1;
687                                 }
688                                 else
689                                         orig = i;
690                                 if( dontdraw ) {
691                                         state = 0;
692                                 }
693                                 else {
694                                         if(!setDrawOptions || setDrawOptions(userData, orig, &drawSmooth)) {
695                                                 state = 1;
696                                         }
697                                         else {
698                                                 state = 0;
699                                         }
700                                 }
701                                 if( prevstate != state && prevstate == 1 ) {
702                                         if( i-prevstart > 0 ) {
703                                                 glDrawArrays(GL_TRIANGLES,prevstart*3,(i-prevstart)*3);
704                                         }
705                                         prevstart = i;
706                                 }
707                                 prevstate = state;
708                         }
709                         if(state==1) {
710                                 glDrawArrays(GL_TRIANGLES,prevstart*3,dm->drawObject->nelements-prevstart*3);
711                         }
712                         glShadeModel(GL_FLAT);
713                 }
714                 GPU_buffer_unbind();
715         }
716 }
717
718 static void cdDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
719 {
720         cdDM_drawFacesTex_common(dm, NULL, setDrawOptions, userData);
721 }
722
723 static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs), int (*setDrawOptions)(void *userData, int index), void *userData)
724 {
725         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
726         GPUVertexAttribs gattribs;
727         DMVertexAttribs attribs;
728         MVert *mvert = cddm->mvert;
729         MFace *mface = cddm->mface;
730         MTFace *tf = dm->getFaceDataArray(dm, CD_MTFACE);
731         float (*nors)[3] = dm->getFaceDataArray(dm, CD_NORMAL);
732         int a, b, dodraw, smoothnormal, matnr, new_matnr;
733         int transp, new_transp, orig_transp;
734         int orig, *index = dm->getFaceDataArray(dm, CD_ORIGINDEX);
735
736         matnr = -1;
737         smoothnormal = 0;
738         dodraw = 0;
739         transp = GPU_get_material_blend_mode();
740         orig_transp = transp;
741
742         memset(&attribs, 0, sizeof(attribs));
743
744         glShadeModel(GL_SMOOTH);
745         glBegin(GL_QUADS);
746
747         for(a = 0; a < dm->numFaceData; a++, mface++) {
748                 new_matnr = mface->mat_nr + 1;
749
750                 if(new_matnr != matnr) {
751                         glEnd();
752
753                         dodraw = setMaterial(matnr = new_matnr, &gattribs);
754                         if(dodraw)
755                                 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
756
757                         glBegin(GL_QUADS);
758                 }
759
760                 if(!dodraw) {
761                         continue;
762                 }
763                 else if(setDrawOptions) {
764                         orig = index[a];
765
766                         if(orig == ORIGINDEX_NONE)
767                                 continue;
768                         else if(!setDrawOptions(userData, orig))
769                                 continue;
770                 }
771
772                 if(tf) {
773                         new_transp = tf[a].transp;
774
775                         if(new_transp != transp) {
776                                 glEnd();
777
778                                 if(new_transp == GPU_BLEND_SOLID && orig_transp != GPU_BLEND_SOLID)
779                                         GPU_set_material_blend_mode(orig_transp);
780                                 else
781                                         GPU_set_material_blend_mode(new_transp);
782                                 transp = new_transp;
783
784                                 glBegin(GL_QUADS);
785                         }
786                 }
787
788                 smoothnormal = (mface->flag & ME_SMOOTH);
789
790                 if(!smoothnormal) {
791                         if(nors) {
792                                 glNormal3fv(nors[a]);
793                         }
794                         else {
795                                 /* TODO ideally a normal layer should always be available */
796                                 float nor[3];
797                                 if(mface->v4) {
798                                         CalcNormFloat4(mvert[mface->v1].co, mvert[mface->v2].co,
799                                                                    mvert[mface->v3].co, mvert[mface->v4].co,
800                                                                    nor);
801                                 } else {
802                                         CalcNormFloat(mvert[mface->v1].co, mvert[mface->v2].co,
803                                                                   mvert[mface->v3].co, nor);
804                                 }
805                                 glNormal3fv(nor);
806                         }
807                 }
808
809 #define PASSVERT(index, vert) {                                                                                                 \
810         if(attribs.totorco)                                                                                                                     \
811                 glVertexAttrib3fvARB(attribs.orco.glIndex, attribs.orco.array[index]);  \
812         for(b = 0; b < attribs.tottface; b++) {                                                                         \
813                 MTFace *tf = &attribs.tface[b].array[a];                                                                \
814                 glVertexAttrib2fvARB(attribs.tface[b].glIndex, tf->uv[vert]);                   \
815         }                                                                                                                                                       \
816         for(b = 0; b < attribs.totmcol; b++) {                                                                          \
817                 MCol *cp = &attribs.mcol[b].array[a*4 + vert];                                                  \
818                 GLubyte col[4];                                                                                                                 \
819                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;                             \
820                 glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col);                                    \
821         }                                                                                                                                                       \
822         if(attribs.tottang) {                                                                                                           \
823                 float *tang = attribs.tang.array[a*4 + vert];                                                   \
824                 glVertexAttrib3fvARB(attribs.tang.glIndex, tang);                                               \
825         }                                                                                                                                                       \
826         if(smoothnormal)                                                                                                                        \
827                 glNormal3sv(mvert[index].no);                                                                                   \
828         glVertex3fv(mvert[index].co);                                                                                           \
829 }
830
831                 PASSVERT(mface->v1, 0);
832                 PASSVERT(mface->v2, 1);
833                 PASSVERT(mface->v3, 2);
834                 if(mface->v4)
835                         PASSVERT(mface->v4, 3)
836                 else
837                         PASSVERT(mface->v3, 2)
838
839 #undef PASSVERT
840         }
841         glEnd();
842
843         glShadeModel(GL_FLAT);
844 }
845
846 static void cdDM_drawFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs))
847 {
848         dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
849 }
850
851 static void cdDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
852 {
853         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
854         MVert *vert = cddm->mvert;
855         MEdge *edge = cddm->medge;
856         int i, orig, *index = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
857
858         glBegin(GL_LINES);
859         for(i = 0; i < dm->numEdgeData; i++, edge++) {
860                 if(index) {
861                         orig = *index++;
862                         if(setDrawOptions && orig == ORIGINDEX_NONE) continue;
863                 }
864                 else
865                         orig = i;
866
867                 if(!setDrawOptions || setDrawOptions(userData, orig)) {
868                         glVertex3fv(vert[edge->v1].co);
869                         glVertex3fv(vert[edge->v2].co);
870                 }
871         }
872         glEnd();
873 }
874
875 static void cdDM_foreachMappedVert(
876                            DerivedMesh *dm,
877                            void (*func)(void *userData, int index, float *co,
878                                         float *no_f, short *no_s),
879                            void *userData)
880 {
881         MVert *mv = CDDM_get_verts(dm);
882         int i, orig, *index = DM_get_vert_data_layer(dm, CD_ORIGINDEX);
883
884         for(i = 0; i < dm->numVertData; i++, mv++) {
885                 if(index) {
886                         orig = *index++;
887                         if(orig == ORIGINDEX_NONE) continue;
888                         func(userData, orig, mv->co, NULL, mv->no);
889                 }
890                 else
891                         func(userData, i, mv->co, NULL, mv->no);
892         }
893 }
894
895 static void cdDM_foreachMappedEdge(
896                            DerivedMesh *dm,
897                            void (*func)(void *userData, int index,
898                                         float *v0co, float *v1co),
899                            void *userData)
900 {
901         CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
902         MVert *mv = cddm->mvert;
903         MEdge *med = cddm->medge;
904         int i, orig, *index = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
905
906         for(i = 0; i < dm->numEdgeData; i++, med++) {
907                 if (index) {
908                         orig = *index++;
909                         if(orig == ORIGINDEX_NONE) continue;
910                         func(userData, orig, mv[med->v1].co, mv[med->v2].co);
911                 }
912                 else
913                         func(userData, i, mv[med->v1].co, mv[med->v2].co);
914         }
915 }
916
917 static void cdDM_foreachMappedFaceCenter(
918                            DerivedMesh *dm,
919                            void (*func)(void *userData, int index,
920                                         float *cent, float *no),
921                            void *userData)
922 {
923         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
924         MVert *mv = cddm->mvert;
925         MFace *mf = cddm->mface;
926         int i, orig, *index = DM_get_face_data_layer(dm, CD_ORIGINDEX);
927
928         for(i = 0; i < dm->numFaceData; i++, mf++) {
929                 float cent[3];
930                 float no[3];
931
932                 if (index) {
933                         orig = *index++;
934                         if(orig == ORIGINDEX_NONE) continue;
935                 }
936                 else
937                         orig = i;
938
939                 VECCOPY(cent, mv[mf->v1].co);
940                 VecAddf(cent, cent, mv[mf->v2].co);
941                 VecAddf(cent, cent, mv[mf->v3].co);
942
943                 if (mf->v4) {
944                         CalcNormFloat4(mv[mf->v1].co, mv[mf->v2].co,
945                                        mv[mf->v3].co, mv[mf->v4].co, no);
946                         VecAddf(cent, cent, mv[mf->v4].co);
947                         VecMulf(cent, 0.25f);
948                 } else {
949                         CalcNormFloat(mv[mf->v1].co, mv[mf->v2].co,
950                                       mv[mf->v3].co, no);
951                         VecMulf(cent, 0.33333333333f);
952                 }
953
954                 func(userData, orig, cent, no);
955         }
956 }
957
958 static void cdDM_release(DerivedMesh *dm)
959 {
960         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
961
962         if (DM_release(dm))
963                 MEM_freeN(cddm);
964 }
965
966 /**************** CDDM interface functions ****************/
967 static CDDerivedMesh *cdDM_create(const char *desc)
968 {
969         CDDerivedMesh *cddm;
970         DerivedMesh *dm;
971
972         cddm = MEM_callocN(sizeof(*cddm), desc);
973         dm = &cddm->dm;
974
975         dm->getMinMax = cdDM_getMinMax;
976
977         dm->getNumVerts = cdDM_getNumVerts;
978         dm->getNumFaces = cdDM_getNumFaces;
979         dm->getNumEdges = cdDM_getNumEdges;
980
981         dm->getVert = cdDM_getVert;
982         dm->getEdge = cdDM_getEdge;
983         dm->getFace = cdDM_getFace;
984         dm->copyVertArray = cdDM_copyVertArray;
985         dm->copyEdgeArray = cdDM_copyEdgeArray;
986         dm->copyFaceArray = cdDM_copyFaceArray;
987         dm->getVertData = DM_get_vert_data;
988         dm->getEdgeData = DM_get_edge_data;
989         dm->getFaceData = DM_get_face_data;
990         dm->getVertDataArray = DM_get_vert_data_layer;
991         dm->getEdgeDataArray = DM_get_edge_data_layer;
992         dm->getFaceDataArray = DM_get_face_data_layer;
993
994         dm->getVertCos = cdDM_getVertCos;
995         dm->getVertCo = cdDM_getVertCo;
996         dm->getVertNo = cdDM_getVertNo;
997
998         dm->drawVerts = cdDM_drawVerts;
999
1000         dm->drawUVEdges = cdDM_drawUVEdges;
1001         dm->drawEdges = cdDM_drawEdges;
1002         dm->drawLooseEdges = cdDM_drawLooseEdges;
1003         dm->drawMappedEdges = cdDM_drawMappedEdges;
1004
1005         dm->drawFacesSolid = cdDM_drawFacesSolid;
1006         dm->drawFacesColored = cdDM_drawFacesColored;
1007         dm->drawFacesTex = cdDM_drawFacesTex;
1008         dm->drawFacesGLSL = cdDM_drawFacesGLSL;
1009         dm->drawMappedFaces = cdDM_drawMappedFaces;
1010         dm->drawMappedFacesTex = cdDM_drawMappedFacesTex;
1011         dm->drawMappedFacesGLSL = cdDM_drawMappedFacesGLSL;
1012
1013         dm->foreachMappedVert = cdDM_foreachMappedVert;
1014         dm->foreachMappedEdge = cdDM_foreachMappedEdge;
1015         dm->foreachMappedFaceCenter = cdDM_foreachMappedFaceCenter;
1016
1017         dm->release = cdDM_release;
1018
1019         return cddm;
1020 }
1021
1022 DerivedMesh *CDDM_new(int numVerts, int numEdges, int numFaces)
1023 {
1024         CDDerivedMesh *cddm = cdDM_create("CDDM_new dm");
1025         DerivedMesh *dm = &cddm->dm;
1026
1027         DM_init(dm, numVerts, numEdges, numFaces);
1028
1029         CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts);
1030         CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
1031         CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numFaces);
1032
1033         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
1034         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
1035         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numFaces);
1036
1037         cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
1038         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
1039         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1040
1041         return dm;
1042 }
1043
1044 DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *ob)
1045 {
1046         CDDerivedMesh *cddm = cdDM_create("CDDM_from_mesh dm");
1047         DerivedMesh *dm = &cddm->dm;
1048         CustomDataMask mask = CD_MASK_MESH & (~CD_MASK_MDISPS);
1049         int i, *index, alloctype;
1050
1051         /* this does a referenced copy, the only new layers being ORIGINDEX,
1052          * with an exception for fluidsim */
1053
1054         DM_init(dm, mesh->totvert, mesh->totedge, mesh->totface);
1055
1056         CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, mesh->totvert);
1057         CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, mesh->totedge);
1058         CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, mesh->totface);
1059
1060         dm->deformedOnly = 1;
1061
1062         alloctype= CD_REFERENCE;
1063
1064         CustomData_merge(&mesh->vdata, &dm->vertData, mask, alloctype,
1065                          mesh->totvert);
1066         CustomData_merge(&mesh->edata, &dm->edgeData, mask, alloctype,
1067                          mesh->totedge);
1068         CustomData_merge(&mesh->fdata, &dm->faceData, mask, alloctype,
1069                          mesh->totface);
1070
1071         cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
1072         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
1073         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1074
1075         index = CustomData_get_layer(&dm->vertData, CD_ORIGINDEX);
1076         for(i = 0; i < mesh->totvert; ++i, ++index)
1077                 *index = i;
1078
1079         index = CustomData_get_layer(&dm->edgeData, CD_ORIGINDEX);
1080         for(i = 0; i < mesh->totedge; ++i, ++index)
1081                 *index = i;
1082
1083         index = CustomData_get_layer(&dm->faceData, CD_ORIGINDEX);
1084         for(i = 0; i < mesh->totface; ++i, ++index)
1085                 *index = i;
1086
1087         return dm;
1088 }
1089
1090 DerivedMesh *CDDM_from_editmesh(EditMesh *em, Mesh *me)
1091 {
1092         DerivedMesh *dm = CDDM_new(BLI_countlist(&em->verts),
1093                                    BLI_countlist(&em->edges),
1094                                    BLI_countlist(&em->faces));
1095         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1096         EditVert *eve;
1097         EditEdge *eed;
1098         EditFace *efa;
1099         MVert *mvert = cddm->mvert;
1100         MEdge *medge = cddm->medge;
1101         MFace *mface = cddm->mface;
1102         int i, *index;
1103
1104         dm->deformedOnly = 1;
1105
1106         CustomData_merge(&em->vdata, &dm->vertData, CD_MASK_DERIVEDMESH,
1107                          CD_CALLOC, dm->numVertData);
1108         /* CustomData_merge(&em->edata, &dm->edgeData, CD_MASK_DERIVEDMESH,
1109                          CD_CALLOC, dm->numEdgeData); */
1110         CustomData_merge(&em->fdata, &dm->faceData, CD_MASK_DERIVEDMESH,
1111                          CD_CALLOC, dm->numFaceData);
1112
1113         /* set eve->hash to vert index */
1114         for(i = 0, eve = em->verts.first; eve; eve = eve->next, ++i)
1115                 eve->tmp.l = i;
1116
1117         /* Need to be able to mark loose edges */
1118         for(eed = em->edges.first; eed; eed = eed->next) {
1119                 eed->f2 = 0;
1120         }
1121         for(efa = em->faces.first; efa; efa = efa->next) {
1122                 efa->e1->f2 = 1;
1123                 efa->e2->f2 = 1;
1124                 efa->e3->f2 = 1;
1125                 if(efa->e4) efa->e4->f2 = 1;
1126         }
1127
1128         index = dm->getVertDataArray(dm, CD_ORIGINDEX);
1129         for(i = 0, eve = em->verts.first; i < dm->numVertData;
1130             i++, eve = eve->next, index++) {
1131                 MVert *mv = &mvert[i];
1132
1133                 VECCOPY(mv->co, eve->co);
1134
1135                 mv->no[0] = eve->no[0] * 32767.0;
1136                 mv->no[1] = eve->no[1] * 32767.0;
1137                 mv->no[2] = eve->no[2] * 32767.0;
1138                 mv->bweight = (unsigned char) (eve->bweight * 255.0f);
1139
1140                 mv->mat_nr = 0;
1141                 mv->flag = 0;
1142
1143                 *index = i;
1144
1145                 CustomData_from_em_block(&em->vdata, &dm->vertData, eve->data, i);
1146         }
1147
1148         index = dm->getEdgeDataArray(dm, CD_ORIGINDEX);
1149         for(i = 0, eed = em->edges.first; i < dm->numEdgeData;
1150             i++, eed = eed->next, index++) {
1151                 MEdge *med = &medge[i];
1152
1153                 med->v1 = eed->v1->tmp.l;
1154                 med->v2 = eed->v2->tmp.l;
1155                 med->crease = (unsigned char) (eed->crease * 255.0f);
1156                 med->bweight = (unsigned char) (eed->bweight * 255.0f);
1157                 med->flag = ME_EDGEDRAW|ME_EDGERENDER;
1158                 
1159                 if(eed->seam) med->flag |= ME_SEAM;
1160                 if(eed->sharp) med->flag |= ME_SHARP;
1161                 if(!eed->f2) med->flag |= ME_LOOSEEDGE;
1162
1163                 *index = i;
1164
1165                 /* CustomData_from_em_block(&em->edata, &dm->edgeData, eed->data, i); */
1166         }
1167
1168         index = dm->getFaceDataArray(dm, CD_ORIGINDEX);
1169         for(i = 0, efa = em->faces.first; i < dm->numFaceData;
1170             i++, efa = efa->next, index++) {
1171                 MFace *mf = &mface[i];
1172
1173                 mf->v1 = efa->v1->tmp.l;
1174                 mf->v2 = efa->v2->tmp.l;
1175                 mf->v3 = efa->v3->tmp.l;
1176                 mf->v4 = efa->v4 ? efa->v4->tmp.l : 0;
1177                 mf->mat_nr = efa->mat_nr;
1178                 mf->flag = efa->flag;
1179
1180                 *index = i;
1181
1182                 CustomData_from_em_block(&em->fdata, &dm->faceData, efa->data, i);
1183                 test_index_face(mf, &dm->faceData, i, efa->v4?4:3);
1184         }
1185
1186         return dm;
1187 }
1188
1189 DerivedMesh *CDDM_copy(DerivedMesh *source)
1190 {
1191         CDDerivedMesh *cddm = cdDM_create("CDDM_copy cddm");
1192         DerivedMesh *dm = &cddm->dm;
1193         int numVerts = source->numVertData;
1194         int numEdges = source->numEdgeData;
1195         int numFaces = source->numFaceData;
1196
1197         /* this initializes dm, and copies all non mvert/medge/mface layers */
1198         DM_from_template(dm, source, numVerts, numEdges, numFaces);
1199         dm->deformedOnly = source->deformedOnly;
1200
1201         CustomData_copy_data(&source->vertData, &dm->vertData, 0, 0, numVerts);
1202         CustomData_copy_data(&source->edgeData, &dm->edgeData, 0, 0, numEdges);
1203         CustomData_copy_data(&source->faceData, &dm->faceData, 0, 0, numFaces);
1204
1205         /* now add mvert/medge/mface layers */
1206         cddm->mvert = source->dupVertArray(source);
1207         cddm->medge = source->dupEdgeArray(source);
1208         cddm->mface = source->dupFaceArray(source);
1209
1210         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_ASSIGN, cddm->mvert, numVerts);
1211         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_ASSIGN, cddm->medge, numEdges);
1212         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_ASSIGN, cddm->mface, numFaces);
1213
1214         return dm;
1215 }
1216
1217 DerivedMesh *CDDM_from_template(DerivedMesh *source,
1218                                 int numVerts, int numEdges, int numFaces)
1219 {
1220         CDDerivedMesh *cddm = cdDM_create("CDDM_from_template dest");
1221         DerivedMesh *dm = &cddm->dm;
1222
1223         /* this does a copy of all non mvert/medge/mface layers */
1224         DM_from_template(dm, source, numVerts, numEdges, numFaces);
1225
1226         /* now add mvert/medge/mface layers */
1227         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
1228         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
1229         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numFaces);
1230
1231         cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
1232         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
1233         cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1234
1235         return dm;
1236 }
1237
1238 void CDDM_apply_vert_coords(DerivedMesh *dm, float (*vertCoords)[3])
1239 {
1240         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1241         MVert *vert;
1242         int i;
1243
1244         /* this will just return the pointer if it wasn't a referenced layer */
1245         vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT);
1246         cddm->mvert = vert;
1247
1248         for(i = 0; i < dm->numVertData; ++i, ++vert)
1249                 VECCOPY(vert->co, vertCoords[i]);
1250 }
1251
1252 void CDDM_apply_vert_normals(DerivedMesh *dm, short (*vertNormals)[3])
1253 {
1254         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1255         MVert *vert;
1256         int i;
1257
1258         /* this will just return the pointer if it wasn't a referenced layer */
1259         vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT);
1260         cddm->mvert = vert;
1261
1262         for(i = 0; i < dm->numVertData; ++i, ++vert)
1263                 VECCOPY(vert->no, vertNormals[i]);
1264 }
1265
1266 /* adapted from mesh_calc_normals */
1267 void CDDM_calc_normals(DerivedMesh *dm)
1268 {
1269         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1270         float (*temp_nors)[3];
1271         float (*face_nors)[3];
1272         int i;
1273         int numVerts = dm->numVertData;
1274         int numFaces = dm->numFaceData;
1275         MFace *mf;
1276         MVert *mv;
1277
1278         if(numVerts == 0) return;
1279
1280         temp_nors = MEM_callocN(numVerts * sizeof(*temp_nors),
1281                                 "CDDM_calc_normals temp_nors");
1282
1283         /* we don't want to overwrite any referenced layers */
1284         mv = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT);
1285         cddm->mvert = mv;
1286
1287         /* make a face normal layer if not present */
1288         face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL);
1289         if(!face_nors)
1290                 face_nors = CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_CALLOC,
1291                                                  NULL, dm->numFaceData);
1292
1293         /* calculate face normals and add to vertex normals */
1294         mf = CDDM_get_faces(dm);
1295         for(i = 0; i < numFaces; i++, mf++) {
1296                 float *f_no = face_nors[i];
1297
1298                 if(mf->v4)
1299                         CalcNormFloat4(mv[mf->v1].co, mv[mf->v2].co,
1300                                        mv[mf->v3].co, mv[mf->v4].co, f_no);
1301                 else
1302                         CalcNormFloat(mv[mf->v1].co, mv[mf->v2].co,
1303                                       mv[mf->v3].co, f_no);
1304                 
1305                 VecAddf(temp_nors[mf->v1], temp_nors[mf->v1], f_no);
1306                 VecAddf(temp_nors[mf->v2], temp_nors[mf->v2], f_no);
1307                 VecAddf(temp_nors[mf->v3], temp_nors[mf->v3], f_no);
1308                 if(mf->v4)
1309                         VecAddf(temp_nors[mf->v4], temp_nors[mf->v4], f_no);
1310         }
1311
1312         /* normalize vertex normals and assign */
1313         for(i = 0; i < numVerts; i++, mv++) {
1314                 float *no = temp_nors[i];
1315                 
1316                 if (Normalize(no) == 0.0) {
1317                         VECCOPY(no, mv->co);
1318                         Normalize(no);
1319                 }
1320
1321                 mv->no[0] = (short)(no[0] * 32767.0);
1322                 mv->no[1] = (short)(no[1] * 32767.0);
1323                 mv->no[2] = (short)(no[2] * 32767.0);
1324         }
1325         
1326         MEM_freeN(temp_nors);
1327 }
1328
1329 void CDDM_calc_edges(DerivedMesh *dm)
1330 {
1331         CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1332         CustomData edgeData;
1333         EdgeHashIterator *ehi;
1334         MFace *mf = cddm->mface;
1335         MEdge *med;
1336         EdgeHash *eh = BLI_edgehash_new();
1337         int i, *index, numEdges, maxFaces = dm->numFaceData;
1338
1339         for (i = 0; i < maxFaces; i++, mf++) {
1340                 if (!BLI_edgehash_haskey(eh, mf->v1, mf->v2))
1341                         BLI_edgehash_insert(eh, mf->v1, mf->v2, NULL);
1342                 if (!BLI_edgehash_haskey(eh, mf->v2, mf->v3))
1343                         BLI_edgehash_insert(eh, mf->v2, mf->v3, NULL);
1344                 
1345                 if (mf->v4) {
1346                         if (!BLI_edgehash_haskey(eh, mf->v3, mf->v4))
1347                                 BLI_edgehash_insert(eh, mf->v3, mf->v4, NULL);
1348                         if (!BLI_edgehash_haskey(eh, mf->v4, mf->v1))
1349                                 BLI_edgehash_insert(eh, mf->v4, mf->v1, NULL);
1350                 } else {
1351                         if (!BLI_edgehash_haskey(eh, mf->v3, mf->v1))
1352                                 BLI_edgehash_insert(eh, mf->v3, mf->v1, NULL);
1353                 }
1354         }
1355
1356         numEdges = BLI_edgehash_size(eh);
1357
1358         /* write new edges into a temporary CustomData */
1359         memset(&edgeData, 0, sizeof(edgeData));
1360         CustomData_add_layer(&edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
1361         CustomData_add_layer(&edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
1362
1363         ehi = BLI_edgehashIterator_new(eh);
1364         med = CustomData_get_layer(&edgeData, CD_MEDGE);
1365         index = CustomData_get_layer(&edgeData, CD_ORIGINDEX);
1366         for(i = 0; !BLI_edgehashIterator_isDone(ehi);
1367             BLI_edgehashIterator_step(ehi), ++i, ++med, ++index) {
1368                 BLI_edgehashIterator_getKey(ehi, (int*)&med->v1, (int*)&med->v2);
1369
1370                 med->flag = ME_EDGEDRAW|ME_EDGERENDER;
1371                 *index = ORIGINDEX_NONE;
1372         }
1373         BLI_edgehashIterator_free(ehi);
1374
1375         /* free old CustomData and assign new one */
1376         CustomData_free(&dm->edgeData, dm->numEdgeData);
1377         dm->edgeData = edgeData;
1378         dm->numEdgeData = numEdges;
1379
1380         cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
1381
1382         BLI_edgehash_free(eh, NULL);
1383 }
1384
1385 void CDDM_lower_num_verts(DerivedMesh *dm, int numVerts)
1386 {
1387         if (numVerts < dm->numVertData)
1388                 CustomData_free_elem(&dm->vertData, numVerts, dm->numVertData-numVerts);
1389
1390         dm->numVertData = numVerts;
1391 }
1392
1393 void CDDM_lower_num_edges(DerivedMesh *dm, int numEdges)
1394 {
1395         if (numEdges < dm->numEdgeData)
1396                 CustomData_free_elem(&dm->edgeData, numEdges, dm->numEdgeData-numEdges);
1397
1398         dm->numEdgeData = numEdges;
1399 }
1400
1401 void CDDM_lower_num_faces(DerivedMesh *dm, int numFaces)
1402 {
1403         if (numFaces < dm->numFaceData)
1404                 CustomData_free_elem(&dm->faceData, numFaces, dm->numFaceData-numFaces);
1405
1406         dm->numFaceData = numFaces;
1407 }
1408
1409 MVert *CDDM_get_vert(DerivedMesh *dm, int index)
1410 {
1411         return &((CDDerivedMesh*)dm)->mvert[index];
1412 }
1413
1414 MEdge *CDDM_get_edge(DerivedMesh *dm, int index)
1415 {
1416         return &((CDDerivedMesh*)dm)->medge[index];
1417 }
1418
1419 MFace *CDDM_get_face(DerivedMesh *dm, int index)
1420 {
1421         return &((CDDerivedMesh*)dm)->mface[index];
1422 }
1423
1424 MVert *CDDM_get_verts(DerivedMesh *dm)
1425 {
1426         return ((CDDerivedMesh*)dm)->mvert;
1427 }
1428
1429 MEdge *CDDM_get_edges(DerivedMesh *dm)
1430 {
1431         return ((CDDerivedMesh*)dm)->medge;
1432 }
1433
1434 MFace *CDDM_get_faces(DerivedMesh *dm)
1435 {
1436         return ((CDDerivedMesh*)dm)->mface;
1437 }
1438
1439 /* Multires DerivedMesh, extends CDDM */
1440 typedef struct MultiresDM {
1441         CDDerivedMesh cddm;
1442
1443         MultiresModifierData *mmd;
1444
1445         int lvl, totlvl;
1446         float (*orco)[3];
1447         MVert *subco;
1448
1449         ListBase *vert_face_map, *vert_edge_map;
1450         IndexNode *vert_face_map_mem, *vert_edge_map_mem;
1451         int *face_offsets;
1452
1453         Mesh *me;
1454         int modified;
1455
1456         void (*update)(DerivedMesh*);
1457 } MultiresDM;
1458
1459 static void MultiresDM_release(DerivedMesh *dm)
1460 {
1461         MultiresDM *mrdm = (MultiresDM*)dm;
1462         int mvert_layer;
1463
1464         /* Before freeing, need to update the displacement map */
1465         if(dm->needsFree && mrdm->modified)
1466                 mrdm->update(dm);
1467
1468         /* If the MVert data is being used as the sculpt undo store, don't free it */
1469         mvert_layer = CustomData_get_layer_index(&dm->vertData, CD_MVERT);
1470         if(mvert_layer != -1) {
1471                 CustomDataLayer *cd = &dm->vertData.layers[mvert_layer];
1472                 if(cd->data == mrdm->mmd->undo_verts)
1473                         cd->flag |= CD_FLAG_NOFREE;
1474         }
1475
1476         if(DM_release(dm)) {
1477                 MEM_freeN(mrdm->subco);
1478                 MEM_freeN(mrdm->orco);
1479                 if(mrdm->vert_face_map)
1480                         MEM_freeN(mrdm->vert_face_map);
1481                 if(mrdm->vert_face_map_mem)
1482                         MEM_freeN(mrdm->vert_face_map_mem);
1483                 if(mrdm->vert_edge_map)
1484                         MEM_freeN(mrdm->vert_edge_map);
1485                 if(mrdm->vert_edge_map_mem)
1486                         MEM_freeN(mrdm->vert_edge_map_mem);
1487                 if(mrdm->face_offsets)
1488                         MEM_freeN(mrdm->face_offsets);
1489                 MEM_freeN(mrdm);
1490         }
1491 }
1492
1493 DerivedMesh *MultiresDM_new(MultiresSubsurf *ms, DerivedMesh *orig, int numVerts, int numEdges, int numFaces)
1494 {
1495         MultiresDM *mrdm = MEM_callocN(sizeof(MultiresDM), "MultiresDM");
1496         CDDerivedMesh *cddm = cdDM_create("MultiresDM CDDM");
1497         DerivedMesh *dm = NULL;
1498
1499         mrdm->cddm = *cddm;
1500         MEM_freeN(cddm);
1501         dm = &mrdm->cddm.dm;
1502
1503         mrdm->mmd = ms->mmd;
1504         mrdm->me = ms->me;
1505
1506         if(dm) {
1507                 MDisps *disps;
1508                 MVert *mvert;
1509                 int i;
1510
1511                 DM_from_template(dm, orig, numVerts, numEdges, numFaces);
1512                 CustomData_free_layers(&dm->faceData, CD_MDISPS, numFaces);
1513
1514                 disps = CustomData_get_layer(&orig->faceData, CD_MDISPS);
1515                 if(disps)
1516                         CustomData_add_layer(&dm->faceData, CD_MDISPS, CD_REFERENCE, disps, numFaces);
1517
1518
1519                 mvert = CustomData_get_layer(&orig->vertData, CD_MVERT);
1520                 mrdm->orco = MEM_callocN(sizeof(float) * 3 * orig->getNumVerts(orig), "multires orco");
1521                 for(i = 0; i < orig->getNumVerts(orig); ++i)
1522                         VecCopyf(mrdm->orco[i], mvert[i].co);
1523         }
1524         else
1525                 DM_init(dm, numVerts, numEdges, numFaces);
1526
1527         CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
1528         CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
1529         CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numFaces);
1530
1531         mrdm->cddm.mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
1532         mrdm->cddm.medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
1533         mrdm->cddm.mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1534
1535         mrdm->lvl = ms->mmd->lvl;
1536         mrdm->totlvl = ms->mmd->totlvl;
1537         mrdm->subco = MEM_callocN(sizeof(MVert)*numVerts, "multires subdivided verts");
1538         mrdm->modified = 0;
1539
1540         dm->release = MultiresDM_release;
1541
1542         return dm;
1543 }
1544
1545 Mesh *MultiresDM_get_mesh(DerivedMesh *dm)
1546 {
1547         return ((MultiresDM*)dm)->me;
1548 }
1549
1550 void *MultiresDM_get_orco(DerivedMesh *dm)
1551 {
1552         return ((MultiresDM*)dm)->orco;
1553
1554 }
1555
1556 MVert *MultiresDM_get_subco(DerivedMesh *dm)
1557 {
1558         return ((MultiresDM*)dm)->subco;
1559 }
1560
1561 int MultiresDM_get_totlvl(DerivedMesh *dm)
1562 {
1563         return ((MultiresDM*)dm)->totlvl;
1564 }
1565
1566 int MultiresDM_get_lvl(DerivedMesh *dm)
1567 {
1568         return ((MultiresDM*)dm)->lvl;
1569 }
1570
1571 void MultiresDM_set_orco(DerivedMesh *dm, float (*orco)[3])
1572 {
1573         ((MultiresDM*)dm)->orco = orco;
1574 }
1575
1576 void MultiresDM_set_update(DerivedMesh *dm, void (*update)(DerivedMesh*))
1577 {
1578         ((MultiresDM*)dm)->update = update;
1579 }
1580
1581 ListBase *MultiresDM_get_vert_face_map(DerivedMesh *dm)
1582 {
1583         MultiresDM *mrdm = (MultiresDM*)dm;
1584
1585         if(!mrdm->vert_face_map)
1586                 create_vert_face_map(&mrdm->vert_face_map, &mrdm->vert_face_map_mem, mrdm->me->mface,
1587                                      mrdm->me->totvert, mrdm->me->totface);
1588
1589         return mrdm->vert_face_map;
1590 }
1591
1592 ListBase *MultiresDM_get_vert_edge_map(DerivedMesh *dm)
1593 {
1594         MultiresDM *mrdm = (MultiresDM*)dm;
1595
1596         if(!mrdm->vert_edge_map)
1597                 create_vert_edge_map(&mrdm->vert_edge_map, &mrdm->vert_edge_map_mem, mrdm->me->medge,
1598                                      mrdm->me->totvert, mrdm->me->totedge);
1599
1600         return mrdm->vert_edge_map;
1601 }
1602
1603 int *MultiresDM_get_face_offsets(DerivedMesh *dm)
1604 {
1605         MultiresDM *mrdm = (MultiresDM*)dm;
1606         int i, accum = 0;
1607
1608         if(!mrdm->face_offsets) {
1609                 int len = (int)pow(2, mrdm->lvl - 2) - 1;
1610                 int area = len * len;
1611                 int t = 1 + len * 3 + area * 3, q = t + len + area;
1612
1613                 mrdm->face_offsets = MEM_callocN(sizeof(int) * mrdm->me->totface, "mrdm face offsets");
1614                 for(i = 0; i < mrdm->me->totface; ++i) {
1615                         mrdm->face_offsets[i] = accum;
1616
1617                         accum += (mrdm->me->mface[i].v4 ? q : t);
1618                 }
1619         }
1620
1621         return mrdm->face_offsets;
1622 }
1623
1624 void MultiresDM_mark_as_modified(DerivedMesh *dm)
1625 {
1626         ((MultiresDM*)dm)->modified = 1;
1627 }