Change texface draw to always use glShadeModel(GL_SMOOTH), with texface draw.
[blender-staging.git] / source / blender / blenkernel / intern / editderivedmesh.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) 2005 Blender Foundation.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): none yet.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/blenkernel/intern/editderivedmesh.c
29  *  \ingroup bke
30  */
31
32 #include "GL/glew.h"
33
34 #include "BLI_utildefines.h"
35 #include "BLI_blenlib.h"
36 #include "BLI_edgehash.h"
37 #include "BLI_editVert.h"
38 #include "BLI_math.h"
39 #include "BLI_pbvh.h"
40
41 #include "BKE_cdderivedmesh.h"
42 #include "BKE_global.h"
43 #include "BKE_mesh.h"
44 #include "BKE_paint.h"
45
46
47 #include "DNA_meshdata_types.h"
48 #include "DNA_object_types.h"
49 #include "DNA_curve_types.h" /* for Curve */
50
51 #include "MEM_guardedalloc.h"
52
53 #include "GPU_buffers.h"
54 #include "GPU_draw.h"
55 #include "GPU_extensions.h"
56 #include "GPU_material.h"
57
58 #include <string.h>
59 #include <limits.h>
60 #include <math.h>
61
62 extern GLubyte stipple_quarttone[128]; /* glutil.c, bad level data */
63
64 static void emDM_foreachMappedVert(
65                 DerivedMesh *dm,
66                 void (*func)(void *userData, int index, float *co, float *no_f, short *no_s),
67                 void *userData)
68 {
69         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
70         EditVert *eve;
71         int i;
72
73         for (i=0,eve= emdm->em->verts.first; eve; i++,eve=eve->next) {
74                 if (emdm->vertexCos) {
75                         func(userData, i, emdm->vertexCos[i], emdm->vertexNos[i], NULL);
76                 }
77                 else {
78                         func(userData, i, eve->co, eve->no, NULL);
79                 }
80         }
81 }
82 static void emDM_foreachMappedEdge(
83                 DerivedMesh *dm,
84                 void (*func)(void *userData, int index, float *v0co, float *v1co),
85                 void *userData)
86 {
87         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
88         EditEdge *eed;
89         int i;
90
91         if (emdm->vertexCos) {
92                 EditVert *eve;
93
94                 for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
95                         eve->tmp.l = (intptr_t) i++;
96                 for (i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next)
97                         func(userData, i, emdm->vertexCos[(int) eed->v1->tmp.l], emdm->vertexCos[(int) eed->v2->tmp.l]);
98         }
99         else {
100                 for (i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next)
101                         func(userData, i, eed->v1->co, eed->v2->co);
102         }
103 }
104
105 static void emDM_drawMappedEdges(
106                 DerivedMesh *dm,
107                 int (*setDrawOptions)(void *userData, int index),
108                 void *userData)
109 {
110         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
111         EditEdge *eed;
112         int i;
113
114         if (emdm->vertexCos) {
115                 EditVert *eve;
116
117                 for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
118                         eve->tmp.l = (intptr_t) i++;
119
120                 glBegin(GL_LINES);
121                 for (i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
122                         if (!setDrawOptions || setDrawOptions(userData, i)) {
123                                 glVertex3fv(emdm->vertexCos[(int) eed->v1->tmp.l]);
124                                 glVertex3fv(emdm->vertexCos[(int) eed->v2->tmp.l]);
125                         }
126                 }
127                 glEnd();
128         }
129         else {
130                 glBegin(GL_LINES);
131                 for (i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
132                         if (!setDrawOptions || setDrawOptions(userData, i)) {
133                                 glVertex3fv(eed->v1->co);
134                                 glVertex3fv(eed->v2->co);
135                         }
136                 }
137                 glEnd();
138         }
139 }
140 static void emDM_drawEdges(
141                 DerivedMesh *dm,
142                 int UNUSED(drawLooseEdges),
143                 int UNUSED(drawAllEdges))
144 {
145         emDM_drawMappedEdges(dm, NULL, NULL);
146 }
147
148 static void emDM_drawMappedEdgesInterp(
149                 DerivedMesh *dm,
150                 int (*setDrawOptions)(void *userData, int index),
151                 void (*setDrawInterpOptions)(void *userData, int index, float t),
152                 void *userData)
153 {
154         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
155         EditEdge *eed;
156         int i;
157
158         if (emdm->vertexCos) {
159                 EditVert *eve;
160
161                 for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
162                         eve->tmp.l = (intptr_t) i++;
163
164                 glBegin(GL_LINES);
165                 for (i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
166                         if (!setDrawOptions || setDrawOptions(userData, i)) {
167                                 setDrawInterpOptions(userData, i, 0.0);
168                                 glVertex3fv(emdm->vertexCos[(int) eed->v1->tmp.l]);
169                                 setDrawInterpOptions(userData, i, 1.0);
170                                 glVertex3fv(emdm->vertexCos[(int) eed->v2->tmp.l]);
171                         }
172                 }
173                 glEnd();
174         }
175         else {
176                 glBegin(GL_LINES);
177                 for (i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next) {
178                         if (!setDrawOptions || setDrawOptions(userData, i)) {
179                                 setDrawInterpOptions(userData, i, 0.0);
180                                 glVertex3fv(eed->v1->co);
181                                 setDrawInterpOptions(userData, i, 1.0);
182                                 glVertex3fv(eed->v2->co);
183                         }
184                 }
185                 glEnd();
186         }
187 }
188
189 static void emDM_drawUVEdges(DerivedMesh *dm)
190 {
191         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
192         EditFace *efa;
193         MTFace *tf;
194
195         glBegin(GL_LINES);
196         for (efa= emdm->em->faces.first; efa; efa= efa->next) {
197                 tf = CustomData_em_get(&emdm->em->fdata, efa->data, CD_MTFACE);
198
199                 if (tf && !(efa->h)) {
200                         glVertex2fv(tf->uv[0]);
201                         glVertex2fv(tf->uv[1]);
202
203                         glVertex2fv(tf->uv[1]);
204                         glVertex2fv(tf->uv[2]);
205
206                         if (!efa->v4) {
207                                 glVertex2fv(tf->uv[2]);
208                                 glVertex2fv(tf->uv[0]);
209                         }
210                         else {
211                                 glVertex2fv(tf->uv[2]);
212                                 glVertex2fv(tf->uv[3]);
213                                 glVertex2fv(tf->uv[3]);
214                                 glVertex2fv(tf->uv[0]);
215                         }
216                 }
217         }
218         glEnd();
219 }
220
221 static void emDM__calcFaceCent(EditFace *efa, float cent[3], float (*vertexCos)[3])
222 {
223         if (vertexCos) {
224                 copy_v3_v3(cent, vertexCos[(int) efa->v1->tmp.l]);
225                 add_v3_v3(cent, vertexCos[(int) efa->v2->tmp.l]);
226                 add_v3_v3(cent, vertexCos[(int) efa->v3->tmp.l]);
227                 if (efa->v4) add_v3_v3(cent, vertexCos[(int) efa->v4->tmp.l]);
228         }
229         else {
230                 copy_v3_v3(cent, efa->v1->co);
231                 add_v3_v3(cent, efa->v2->co);
232                 add_v3_v3(cent, efa->v3->co);
233                 if (efa->v4) add_v3_v3(cent, efa->v4->co);
234         }
235
236         if (efa->v4) {
237                 mul_v3_fl(cent, 0.25f);
238         }
239         else {
240                 mul_v3_fl(cent, 0.33333333333f);
241         }
242 }
243
244 static void emDM_foreachMappedFaceCenter(
245                 DerivedMesh *dm,
246                 void (*func)(void *userData, int index, float *co, float *no),
247                 void *userData)
248 {
249         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
250         EditVert *eve;
251         EditFace *efa;
252         float cent[3];
253         int i;
254
255         if (emdm->vertexCos) {
256                 for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
257                         eve->tmp.l = (intptr_t) i++;
258         }
259
260         for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) {
261                 emDM__calcFaceCent(efa, cent, emdm->vertexCos);
262                 func(userData, i, cent, emdm->vertexCos?emdm->faceNos[i]:efa->n);
263         }
264 }
265
266 /* note, material function is ignored for now. */
267 static void emDM_drawMappedFaces(
268                 DerivedMesh *dm,
269                 int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r),
270                 int (*setMaterial)(int, void *attribs),
271                 int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
272                 void *userData, int UNUSED(useColors))
273 {
274         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
275         EditFace *efa;
276         int i, draw, flush;
277         const int skip_normals= !glIsEnabled(GL_LIGHTING); /* could be passed as an arg */
278
279         /* GL_ZERO is used to detect if drawing has started or not */
280         GLenum poly_prev= GL_ZERO;
281         GLenum shade_prev= GL_ZERO;
282
283         (void)setMaterial; /* UNUSED */
284
285         /* currently unused -- each original face is handled separately */
286         (void)compareDrawOptions;
287
288         if (emdm->vertexCos) {
289                 /* add direct access */
290                 float (*vertexCos)[3]= emdm->vertexCos;
291                 float (*vertexNos)[3]= emdm->vertexNos;
292                 float (*faceNos)[3]=   emdm->faceNos;
293                 EditVert *eve;
294
295                 for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
296                         eve->tmp.l = (intptr_t) i++;
297
298                 for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) {
299                         int drawSmooth = (efa->flag & ME_SMOOTH);
300                         draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, i, &drawSmooth);
301                         if (draw) {
302                                 const GLenum poly_type= efa->v4 ? GL_QUADS:GL_TRIANGLES;
303                                 if (draw==2) { /* enabled with stipple */
304
305                                         if (poly_prev != GL_ZERO) glEnd();
306                                         poly_prev= GL_ZERO; /* force glBegin */
307
308                                         glEnable(GL_POLYGON_STIPPLE);
309                                         glPolygonStipple(stipple_quarttone);
310                                 }
311
312                                 if (skip_normals) {
313                                         if (poly_type != poly_prev) {
314                                                 if (poly_prev != GL_ZERO) glEnd();
315                                                 glBegin((poly_prev= poly_type));
316                                         }
317                                         glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
318                                         glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
319                                         glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
320                                         if (poly_type == GL_QUADS) glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
321                                 }
322                                 else {
323                                         const GLenum shade_type= drawSmooth ? GL_SMOOTH : GL_FLAT;
324                                         if (shade_type != shade_prev) {
325                                                 if (poly_prev != GL_ZERO) glEnd();
326                                                 glShadeModel((shade_prev= shade_type)); /* same as below but switch shading */
327                                                 glBegin((poly_prev= poly_type));
328                                         }
329                                         else if (poly_type != poly_prev) {
330                                                 if (poly_prev != GL_ZERO) glEnd();
331                                                 glBegin((poly_prev= poly_type));
332                                         }
333
334                                         if (!drawSmooth) {
335                                                 glNormal3fv(faceNos[i]);
336                                                 glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
337                                                 glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
338                                                 glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
339                                                 if (poly_type == GL_QUADS) glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
340                                         }
341                                         else {
342                                                 glNormal3fv(vertexNos[(int) efa->v1->tmp.l]);
343                                                 glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
344                                                 glNormal3fv(vertexNos[(int) efa->v2->tmp.l]);
345                                                 glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
346                                                 glNormal3fv(vertexNos[(int) efa->v3->tmp.l]);
347                                                 glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
348                                                 if (poly_type == GL_QUADS) {
349                                                         glNormal3fv(vertexNos[(int) efa->v4->tmp.l]);
350                                                         glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
351                                                 }
352                                         }
353                                 }
354
355                                 flush= (draw==2);
356                                 if (!skip_normals && !flush && efa->next)
357                                         flush|= efa->mat_nr != efa->next->mat_nr;
358
359                                 if (flush) {
360                                         glEnd();
361                                         poly_prev= GL_ZERO; /* force glBegin */
362
363                                         glDisable(GL_POLYGON_STIPPLE);
364                                 }
365                         }
366                 }
367         }
368         else {
369                 for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) {
370                         int drawSmooth = (efa->flag & ME_SMOOTH);
371                         draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, i, &drawSmooth);
372                         if (draw) {
373                                 const GLenum poly_type= efa->v4 ? GL_QUADS:GL_TRIANGLES;
374                                 if (draw==2) { /* enabled with stipple */
375
376                                         if (poly_prev != GL_ZERO) glEnd();
377                                         poly_prev= GL_ZERO; /* force glBegin */
378
379                                         glEnable(GL_POLYGON_STIPPLE);
380                                         glPolygonStipple(stipple_quarttone);
381                                 }
382
383                                 if (skip_normals) {
384                                         if (poly_type != poly_prev) {
385                                                 if (poly_prev != GL_ZERO) glEnd();
386                                                 glBegin((poly_prev= poly_type));
387                                         }
388                                         glVertex3fv(efa->v1->co);
389                                         glVertex3fv(efa->v2->co);
390                                         glVertex3fv(efa->v3->co);
391                                         if (poly_type == GL_QUADS) glVertex3fv(efa->v4->co);
392                                 }
393                                 else {
394                                         const GLenum shade_type= drawSmooth ? GL_SMOOTH : GL_FLAT;
395                                         if (shade_type != shade_prev) {
396                                                 if (poly_prev != GL_ZERO) glEnd();
397                                                 glShadeModel((shade_prev= shade_type)); /* same as below but switch shading */
398                                                 glBegin((poly_prev= poly_type));
399                                         }
400                                         else if (poly_type != poly_prev) {
401                                                 if (poly_prev != GL_ZERO) glEnd();
402                                                 glBegin((poly_prev= poly_type));
403                                         }
404
405                                         if (!drawSmooth) {
406                                                 glNormal3fv(efa->n);
407                                                 glVertex3fv(efa->v1->co);
408                                                 glVertex3fv(efa->v2->co);
409                                                 glVertex3fv(efa->v3->co);
410                                                 if (poly_type == GL_QUADS) glVertex3fv(efa->v4->co);
411                                         }
412                                         else {
413                                                 glNormal3fv(efa->v1->no);
414                                                 glVertex3fv(efa->v1->co);
415                                                 glNormal3fv(efa->v2->no);
416                                                 glVertex3fv(efa->v2->co);
417                                                 glNormal3fv(efa->v3->no);
418                                                 glVertex3fv(efa->v3->co);
419                                                 if (poly_type == GL_QUADS) {
420                                                         glNormal3fv(efa->v4->no);
421                                                         glVertex3fv(efa->v4->co);
422                                                 }
423                                         }
424                                 }
425
426                                 flush= (draw==2);
427                                 if (!skip_normals && !flush && efa->next)
428                                         flush|= efa->mat_nr != efa->next->mat_nr;
429
430                                 if (flush) {
431                                         glEnd();
432                                         poly_prev= GL_ZERO; /* force glBegin */
433
434                                         glDisable(GL_POLYGON_STIPPLE);
435                                 }
436                         }
437                 }
438         }
439
440         /* if non zero we know a face was rendered */
441         if (poly_prev != GL_ZERO) glEnd();
442 }
443
444 static void emDM_drawFacesTex_common(
445                 DerivedMesh *dm,
446                 int (*drawParams)(MTFace *tface, int has_mcol, int matnr),
447                 int (*drawParamsMapped)(void *userData, int index),
448                 int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
449                 void *userData)
450 {
451         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
452         EditMesh *em= emdm->em;
453         float (*vertexCos)[3]= emdm->vertexCos;
454         float (*vertexNos)[3]= emdm->vertexNos;
455         EditFace *efa;
456         int i;
457
458         (void) compareDrawOptions;
459
460         /* always use smooth shading even for flat faces, else vertex colors wont interpolate */
461         glShadeModel(GL_SMOOTH);
462
463         if (vertexCos) {
464                 EditVert *eve;
465
466                 for (i=0,eve=em->verts.first; eve; eve= eve->next)
467                         eve->tmp.l = (intptr_t) i++;
468
469                 for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) {
470                         MTFace *tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
471                         MCol *mcol= CustomData_em_get(&em->fdata, efa->data, CD_MCOL);
472                         unsigned char *cp= NULL;
473                         int drawSmooth= (efa->flag & ME_SMOOTH);
474                         int flag;
475
476                         if (drawParams)
477                                 flag= drawParams(tf, (mcol != NULL), efa->mat_nr);
478                         else if (drawParamsMapped)
479                                 flag= drawParamsMapped(userData, i);
480                         else
481                                 flag= 1;
482
483                         if (flag != 0) { /* flag 0 == the face is hidden or invisible */
484
485                                 /* we always want smooth here since otherwise vertex colors dont interpolate */
486                                 if (mcol) {
487                                         if (flag==1) {
488                                                 cp= (unsigned char*)mcol;
489                                         }
490                                 }
491
492                                 glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
493                                 if (!drawSmooth) {
494                                         glNormal3fv(emdm->faceNos[i]);
495
496                                         if (tf) glTexCoord2fv(tf->uv[0]);
497                                         if (cp) glColor3ub(cp[3], cp[2], cp[1]);
498                                         glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
499
500                                         if (tf) glTexCoord2fv(tf->uv[1]);
501                                         if (cp) glColor3ub(cp[7], cp[6], cp[5]);
502                                         glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
503
504                                         if (tf) glTexCoord2fv(tf->uv[2]);
505                                         if (cp) glColor3ub(cp[11], cp[10], cp[9]);
506                                         glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
507
508                                         if (efa->v4) {
509                                                 if (tf) glTexCoord2fv(tf->uv[3]);
510                                                 if (cp) glColor3ub(cp[15], cp[14], cp[13]);
511                                                 glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
512                                         }
513                                 }
514                                 else {
515                                         if (tf) glTexCoord2fv(tf->uv[0]);
516                                         if (cp) glColor3ub(cp[3], cp[2], cp[1]);
517                                         glNormal3fv(vertexNos[(int) efa->v1->tmp.l]);
518                                         glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
519
520                                         if (tf) glTexCoord2fv(tf->uv[1]);
521                                         if (cp) glColor3ub(cp[7], cp[6], cp[5]);
522                                         glNormal3fv(vertexNos[(int) efa->v2->tmp.l]);
523                                         glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
524
525                                         if (tf) glTexCoord2fv(tf->uv[2]);
526                                         if (cp) glColor3ub(cp[11], cp[10], cp[9]);
527                                         glNormal3fv(vertexNos[(int) efa->v3->tmp.l]);
528                                         glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
529
530                                         if (efa->v4) {
531                                                 if (tf) glTexCoord2fv(tf->uv[3]);
532                                                 if (cp) glColor3ub(cp[15], cp[14], cp[13]);
533                                                 glNormal3fv(vertexNos[(int) efa->v4->tmp.l]);
534                                                 glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
535                                         }
536                                 }
537                                 glEnd();
538                         }
539                 }
540         }
541         else {
542                 for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) {
543                         MTFace *tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
544                         MCol *mcol= CustomData_em_get(&em->fdata, efa->data, CD_MCOL);
545                         unsigned char *cp= NULL;
546                         int drawSmooth= (efa->flag & ME_SMOOTH);
547                         int flag;
548
549                         if (drawParams)
550                                 flag= drawParams(tf, (mcol != NULL), efa->mat_nr);
551                         else if (drawParamsMapped)
552                                 flag= drawParamsMapped(userData, i);
553                         else
554                                 flag= 1;
555
556                         if (flag != 0) { /* flag 0 == the face is hidden or invisible */
557
558                                 /* we always want smooth here since otherwise vertex colors dont interpolate */
559                                 if (mcol) {
560                                         if (flag==1) {
561                                                 cp= (unsigned char*)mcol;
562                                         }
563                                 }
564
565                                 glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
566                                 if (!drawSmooth) {
567                                         glNormal3fv(efa->n);
568
569                                         if (tf) glTexCoord2fv(tf->uv[0]);
570                                         if (cp) glColor3ub(cp[3], cp[2], cp[1]);
571                                         glVertex3fv(efa->v1->co);
572
573                                         if (tf) glTexCoord2fv(tf->uv[1]);
574                                         if (cp) glColor3ub(cp[7], cp[6], cp[5]);
575                                         glVertex3fv(efa->v2->co);
576
577                                         if (tf) glTexCoord2fv(tf->uv[2]);
578                                         if (cp) glColor3ub(cp[11], cp[10], cp[9]);
579                                         glVertex3fv(efa->v3->co);
580
581                                         if (efa->v4) {
582                                                 if (tf) glTexCoord2fv(tf->uv[3]);
583                                                 if (cp) glColor3ub(cp[15], cp[14], cp[13]);
584                                                 glVertex3fv(efa->v4->co);
585                                         }
586                                 }
587                                 else {
588                                         if (tf) glTexCoord2fv(tf->uv[0]);
589                                         if (cp) glColor3ub(cp[3], cp[2], cp[1]);
590                                         glNormal3fv(efa->v1->no);
591                                         glVertex3fv(efa->v1->co);
592
593                                         if (tf) glTexCoord2fv(tf->uv[1]);
594                                         if (cp) glColor3ub(cp[7], cp[6], cp[5]);
595                                         glNormal3fv(efa->v2->no);
596                                         glVertex3fv(efa->v2->co);
597
598                                         if (tf) glTexCoord2fv(tf->uv[2]);
599                                         if (cp) glColor3ub(cp[11], cp[10], cp[9]);
600                                         glNormal3fv(efa->v3->no);
601                                         glVertex3fv(efa->v3->co);
602
603                                         if (efa->v4) {
604                                                 if (tf) glTexCoord2fv(tf->uv[3]);
605                                                 if (cp) glColor3ub(cp[15], cp[14], cp[13]);
606                                                 glNormal3fv(efa->v4->no);
607                                                 glVertex3fv(efa->v4->co);
608                                         }
609                                 }
610                                 glEnd();
611                         }
612                 }
613         }
614
615         glShadeModel(GL_FLAT);
616 }
617
618 static void emDM_drawFacesTex(
619                 DerivedMesh *dm,
620                 int (*setDrawOptions)(MTFace *tface, int has_mcol, int matnr),
621                 int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
622                 void *userData)
623 {
624         emDM_drawFacesTex_common(dm, setDrawOptions, NULL, compareDrawOptions, userData);
625 }
626
627 static void emDM_drawMappedFacesTex(
628                 DerivedMesh *dm,
629                 int (*setDrawOptions)(void *userData, int index),
630                 int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
631                 void *userData)
632 {
633         emDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData);
634 }
635
636 static void emDM_drawMappedFacesGLSL(
637                 DerivedMesh *dm,
638                 int (*setMaterial)(int, void *attribs),
639                 int (*setDrawOptions)(void *userData, int index),
640                 void *userData)
641 {
642         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
643         EditMesh *em= emdm->em;
644         float (*vertexCos)[3]= emdm->vertexCos;
645         float (*vertexNos)[3]= emdm->vertexNos;
646         EditVert *eve;
647         EditFace *efa;
648         DMVertexAttribs attribs= {{{0}}};
649         GPUVertexAttribs gattribs;
650         /* int tfoffset; */ /* UNUSED */
651         int i, b, matnr, new_matnr, dodraw /* , layer */ /* UNUSED */;
652
653         dodraw = 0;
654         matnr = -1;
655
656         /* layer = CustomData_get_layer_index(&em->fdata, CD_MTFACE); */ /* UNUSED */
657         /* tfoffset = (layer == -1)? -1: em->fdata.layers[layer].offset; */ /* UNUSED */
658
659         /* always use smooth shading even for flat faces, else vertex colors wont interpolate */
660         glShadeModel(GL_SMOOTH);
661
662         for (i=0,eve=em->verts.first; eve; eve= eve->next)
663                 eve->tmp.l = (intptr_t) i++;
664
665 #define PASSATTRIB(efa, eve, vert) {                                                                                    \
666         if (attribs.totorco) {                                                                                                          \
667                 float *orco = attribs.orco.array[eve->tmp.l];                                                   \
668                 glVertexAttrib3fvARB(attribs.orco.glIndex, orco);                                               \
669         }                                                                                                                                                       \
670         for (b = 0; b < attribs.tottface; b++) {                                                                        \
671                 MTFace *_tf = (MTFace*)((char*)efa->data + attribs.tface[b].emOffset);  \
672                 glVertexAttrib2fvARB(attribs.tface[b].glIndex, _tf->uv[vert]);                  \
673         }                                                                                                                                                       \
674         for (b = 0; b < attribs.totmcol; b++) {                                                                         \
675                 MCol *cp = (MCol*)((char*)efa->data + attribs.mcol[b].emOffset);                \
676                 GLubyte col[4];                                                                                                                 \
677                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;                             \
678                 glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col);                                    \
679         }                                                                                                                                                       \
680         if (attribs.tottang) {                                                                                                          \
681                 float *tang = attribs.tang.array[i*4 + vert];                                                   \
682                 glVertexAttrib4fvARB(attribs.tang.glIndex, tang);                                               \
683         }                                                                                                                                                       \
684 }
685
686         for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) {
687                 int drawSmooth= (efa->flag & ME_SMOOTH);
688
689                 if (setDrawOptions && !setDrawOptions(userData, i))
690                         continue;
691
692                 new_matnr = efa->mat_nr + 1;
693                 if (new_matnr != matnr) {
694                         dodraw = setMaterial(matnr = new_matnr, &gattribs);
695                         if (dodraw)
696                                 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
697                 }
698
699                 if (dodraw) {
700                         glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
701                         if (!drawSmooth) {
702                                 if (vertexCos) glNormal3fv(emdm->faceNos[i]);
703                                 else glNormal3fv(efa->n);
704
705                                 PASSATTRIB(efa, efa->v1, 0);
706                                 if (vertexCos) glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
707                                 else glVertex3fv(efa->v1->co);
708
709                                 PASSATTRIB(efa, efa->v2, 1);
710                                 if (vertexCos) glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
711                                 else glVertex3fv(efa->v2->co);
712
713                                 PASSATTRIB(efa, efa->v3, 2);
714                                 if (vertexCos) glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
715                                 else glVertex3fv(efa->v3->co);
716
717                                 if (efa->v4) {
718                                         PASSATTRIB(efa, efa->v4, 3);
719                                         if (vertexCos) glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
720                                         else glVertex3fv(efa->v4->co);
721                                 }
722                         }
723                         else {
724                                 PASSATTRIB(efa, efa->v1, 0);
725                                 if (vertexCos) {
726                                         glNormal3fv(vertexNos[(int) efa->v1->tmp.l]);
727                                         glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
728                                 }
729                                 else {
730                                         glNormal3fv(efa->v1->no);
731                                         glVertex3fv(efa->v1->co);
732                                 }
733
734                                 PASSATTRIB(efa, efa->v2, 1);
735                                 if (vertexCos) {
736                                         glNormal3fv(vertexNos[(int) efa->v2->tmp.l]);
737                                         glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
738                                 }
739                                 else {
740                                         glNormal3fv(efa->v2->no);
741                                         glVertex3fv(efa->v2->co);
742                                 }
743
744                                 PASSATTRIB(efa, efa->v3, 2);
745                                 if (vertexCos) {
746                                         glNormal3fv(vertexNos[(int) efa->v3->tmp.l]);
747                                         glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
748                                 }
749                                 else {
750                                         glNormal3fv(efa->v3->no);
751                                         glVertex3fv(efa->v3->co);
752                                 }
753
754                                 if (efa->v4) {
755                                         PASSATTRIB(efa, efa->v4, 3);
756                                         if (vertexCos) {
757                                                 glNormal3fv(vertexNos[(int) efa->v4->tmp.l]);
758                                                 glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
759                                         }
760                                         else {
761                                                 glNormal3fv(efa->v4->no);
762                                                 glVertex3fv(efa->v4->co);
763                                         }
764                                 }
765                         }
766                         glEnd();
767                 }
768         }
769 #undef PASSATTRIB
770 }
771
772 static void emDM_drawFacesGLSL(
773                 DerivedMesh *dm,
774                 int (*setMaterial)(int, void *attribs))
775 {
776         dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
777 }
778
779 static void emDM_drawMappedFacesMat(
780                 DerivedMesh *dm,
781                 void (*setMaterial)(void *userData, int, void *attribs),
782                 int (*setFace)(void *userData, int index), void *userData)
783 {
784         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
785         EditMesh *em= emdm->em;
786         float (*vertexCos)[3]= emdm->vertexCos;
787         float (*vertexNos)[3]= emdm->vertexNos;
788         EditVert *eve;
789         EditFace *efa;
790         DMVertexAttribs attribs= {{{0}}};
791         GPUVertexAttribs gattribs;
792         int i, b, matnr, new_matnr;
793
794         matnr = -1;
795
796         /* always use smooth shading even for flat faces, else vertex colors wont interpolate */
797         glShadeModel(GL_SMOOTH);
798
799         for (i=0,eve=em->verts.first; eve; eve= eve->next)
800                 eve->tmp.l = (intptr_t) i++;
801
802 #define PASSATTRIB(efa, eve, vert) {                                                                                    \
803         if (attribs.totorco) {                                                                                                          \
804                 float *orco = attribs.orco.array[eve->tmp.l];                                                   \
805                 if (attribs.orco.glTexco)                                                                                               \
806                         glTexCoord3fv(orco);                                                                                            \
807                 else                                                                                                                                    \
808                         glVertexAttrib3fvARB(attribs.orco.glIndex, orco);                                       \
809         }                                                                                                                                                       \
810         for (b = 0; b < attribs.tottface; b++) {                                                                        \
811                 MTFace *_tf = (MTFace*)((char*)efa->data + attribs.tface[b].emOffset);  \
812                 if (attribs.tface[b].glTexco)                                                                                   \
813                         glTexCoord2fv(_tf->uv[vert]);                                                                           \
814                 else                                                                                                                                    \
815                         glVertexAttrib2fvARB(attribs.tface[b].glIndex, _tf->uv[vert]);          \
816         }                                                                                                                                                       \
817         for (b = 0; b < attribs.totmcol; b++) {                                                                         \
818                 MCol *cp = (MCol*)((char*)efa->data + attribs.mcol[b].emOffset);                \
819                 GLubyte col[4];                                                                                                                 \
820                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;                             \
821                 glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col);                                    \
822         }                                                                                                                                                       \
823         if (attribs.tottang) {                                                                                                          \
824                 float *tang = attribs.tang.array[i*4 + vert];                                                   \
825                 glVertexAttrib4fvARB(attribs.tang.glIndex, tang);                                               \
826         }                                                                                                                                                       \
827 }
828
829         for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) {
830                 int drawSmooth= (efa->flag & ME_SMOOTH);
831
832                 /* face hiding */
833                 if (setFace && !setFace(userData, i))
834                         continue;
835
836                 /* material */
837                 new_matnr = efa->mat_nr + 1;
838                 if (new_matnr != matnr) {
839                         setMaterial(userData, matnr = new_matnr, &gattribs);
840                         DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
841                 }
842
843                 /* face */
844                 glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
845                 if (!drawSmooth) {
846                         if (vertexCos) glNormal3fv(emdm->faceNos[i]);
847                         else glNormal3fv(efa->n);
848
849                         PASSATTRIB(efa, efa->v1, 0);
850                         if (vertexCos) glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
851                         else glVertex3fv(efa->v1->co);
852
853                         PASSATTRIB(efa, efa->v2, 1);
854                         if (vertexCos) glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
855                         else glVertex3fv(efa->v2->co);
856
857                         PASSATTRIB(efa, efa->v3, 2);
858                         if (vertexCos) glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
859                         else glVertex3fv(efa->v3->co);
860
861                         if (efa->v4) {
862                                 PASSATTRIB(efa, efa->v4, 3);
863                                 if (vertexCos) glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
864                                 else glVertex3fv(efa->v4->co);
865                         }
866                 }
867                 else {
868                         PASSATTRIB(efa, efa->v1, 0);
869                         if (vertexCos) {
870                                 glNormal3fv(vertexNos[(int) efa->v1->tmp.l]);
871                                 glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
872                         }
873                         else {
874                                 glNormal3fv(efa->v1->no);
875                                 glVertex3fv(efa->v1->co);
876                         }
877
878                         PASSATTRIB(efa, efa->v2, 1);
879                         if (vertexCos) {
880                                 glNormal3fv(vertexNos[(int) efa->v2->tmp.l]);
881                                 glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
882                         }
883                         else {
884                                 glNormal3fv(efa->v2->no);
885                                 glVertex3fv(efa->v2->co);
886                         }
887
888                         PASSATTRIB(efa, efa->v3, 2);
889                         if (vertexCos) {
890                                 glNormal3fv(vertexNos[(int) efa->v3->tmp.l]);
891                                 glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
892                         }
893                         else {
894                                 glNormal3fv(efa->v3->no);
895                                 glVertex3fv(efa->v3->co);
896                         }
897
898                         if (efa->v4) {
899                                 PASSATTRIB(efa, efa->v4, 3);
900                                 if (vertexCos) {
901                                         glNormal3fv(vertexNos[(int) efa->v4->tmp.l]);
902                                         glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
903                                 }
904                                 else {
905                                         glNormal3fv(efa->v4->no);
906                                         glVertex3fv(efa->v4->co);
907                                 }
908                         }
909                 }
910                 glEnd();
911         }
912 #undef PASSATTRIB
913 }
914
915 static void emDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
916 {
917         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
918         EditVert *eve;
919         int i;
920
921         if (emdm->em->verts.first) {
922                 for (i=0,eve= emdm->em->verts.first; eve; i++,eve= eve->next) {
923                         if (emdm->vertexCos) {
924                                 DO_MINMAX(emdm->vertexCos[i], min_r, max_r);
925                         }
926                         else {
927                                 DO_MINMAX(eve->co, min_r, max_r);
928                         }
929                 }
930         }
931         else {
932                 min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
933         }
934 }
935 static int emDM_getNumVerts(DerivedMesh *dm)
936 {
937         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
938
939         return BLI_countlist(&emdm->em->verts);
940 }
941
942 static int emDM_getNumEdges(DerivedMesh *dm)
943 {
944         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
945
946         return BLI_countlist(&emdm->em->edges);
947 }
948
949 static int emDM_getNumFaces(DerivedMesh *dm)
950 {
951         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
952
953         return BLI_countlist(&emdm->em->faces);
954 }
955
956 static void emDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3])
957 {
958         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
959         EditVert *eve;
960         int i;
961
962         for (i=0,eve= emdm->em->verts.first; eve; i++,eve=eve->next) {
963                 if (emdm->vertexCos) {
964                         copy_v3_v3(cos_r[i], emdm->vertexCos[i]);
965                 }
966                 else {
967                         copy_v3_v3(cos_r[i], eve->co);
968                 }
969         }
970 }
971
972 static void emDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
973 {
974         EditVert *ev = ((EditMeshDerivedMesh *)dm)->em->verts.first;
975         int i;
976
977         for (i = 0; i < index; ++i) ev = ev->next;
978
979         copy_v3_v3(vert_r->co, ev->co);
980
981         normal_float_to_short_v3(vert_r->no, ev->no);
982
983         /* TODO what to do with vert_r->flag? */
984         vert_r->bweight = (unsigned char) (ev->bweight*255.0f);
985 }
986
987 static void emDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
988 {
989         EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
990         EditEdge *ee = em->edges.first;
991         EditVert *ev, *v1, *v2;
992         int i;
993
994         for (i = 0; i < index; ++i) ee = ee->next;
995
996         edge_r->crease = (unsigned char) (ee->crease*255.0f);
997         edge_r->bweight = (unsigned char) (ee->bweight*255.0f);
998         /* TODO what to do with edge_r->flag? */
999         edge_r->flag = ME_EDGEDRAW|ME_EDGERENDER;
1000         if (ee->seam) edge_r->flag |= ME_SEAM;
1001         if (ee->sharp) edge_r->flag |= ME_SHARP;
1002 #if 0
1003         /* this needs setup of f2 field */
1004         if (!ee->f2) edge_r->flag |= ME_LOOSEEDGE;
1005 #endif
1006
1007         /* goddamn, we have to search all verts to find indices */
1008         v1 = ee->v1;
1009         v2 = ee->v2;
1010         for (i = 0, ev = em->verts.first; v1 || v2; i++, ev = ev->next) {
1011                 if (ev == v1) {
1012                         edge_r->v1 = i;
1013                         v1 = NULL;
1014                 }
1015                 if (ev == v2) {
1016                         edge_r->v2 = i;
1017                         v2 = NULL;
1018                 }
1019         }
1020 }
1021
1022 static void emDM_getFace(DerivedMesh *dm, int index, MFace *face_r)
1023 {
1024         EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
1025         EditFace *ef = em->faces.first;
1026         EditVert *ev, *v1, *v2, *v3, *v4;
1027         int i;
1028
1029         for (i = 0; i < index; ++i) ef = ef->next;
1030
1031         face_r->mat_nr = ef->mat_nr;
1032         face_r->flag = ef->flag;
1033
1034         /* goddamn, we have to search all verts to find indices */
1035         v1 = ef->v1;
1036         v2 = ef->v2;
1037         v3 = ef->v3;
1038         v4 = ef->v4;
1039         if (!v4) face_r->v4 = 0;
1040
1041         for (i = 0, ev = em->verts.first; v1 || v2 || v3 || v4;
1042                 i++, ev = ev->next) {
1043                 if (ev == v1) {
1044                         face_r->v1 = i;
1045                         v1 = NULL;
1046                 }
1047                 if (ev == v2) {
1048                         face_r->v2 = i;
1049                         v2 = NULL;
1050                 }
1051                 if (ev == v3) {
1052                         face_r->v3 = i;
1053                         v3 = NULL;
1054                 }
1055                 if (ev == v4) {
1056                         face_r->v4 = i;
1057                         v4 = NULL;
1058                 }
1059         }
1060
1061         test_index_face(face_r, NULL, 0, ef->v4?4:3);
1062 }
1063
1064 static void emDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
1065 {
1066         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
1067         EditVert *ev = emdm->em->verts.first;
1068         int i;
1069
1070         for (i=0; ev; ev = ev->next, ++vert_r, ++i) {
1071                 if (emdm->vertexCos)
1072                         copy_v3_v3(vert_r->co, emdm->vertexCos[i]);
1073                 else
1074                         copy_v3_v3(vert_r->co, ev->co);
1075
1076                 normal_float_to_short_v3(vert_r->no, ev->no);
1077
1078                 /* TODO what to do with vert_r->flag? */
1079                 vert_r->flag = 0;
1080                 vert_r->bweight = (unsigned char) (ev->bweight*255.0f);
1081         }
1082 }
1083
1084 static void emDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r)
1085 {
1086         EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
1087         EditEdge *ee = em->edges.first;
1088         EditVert *ev;
1089         int i;
1090
1091         /* store vertex indices in tmp union */
1092         for (ev = em->verts.first, i = 0; ev; ev = ev->next, ++i)
1093                 ev->tmp.l = (intptr_t) i;
1094
1095         for ( ; ee; ee = ee->next, ++edge_r) {
1096                 edge_r->crease = (unsigned char) (ee->crease*255.0f);
1097                 edge_r->bweight = (unsigned char) (ee->bweight*255.0f);
1098                 /* TODO what to do with edge_r->flag? */
1099                 edge_r->flag = ME_EDGEDRAW|ME_EDGERENDER;
1100                 if (ee->seam) edge_r->flag |= ME_SEAM;
1101                 if (ee->sharp) edge_r->flag |= ME_SHARP;
1102 #if 0
1103                 /* this needs setup of f2 field */
1104                 if (!ee->f2) edge_r->flag |= ME_LOOSEEDGE;
1105 #endif
1106
1107                 edge_r->v1 = (int)ee->v1->tmp.l;
1108                 edge_r->v2 = (int)ee->v2->tmp.l;
1109         }
1110 }
1111
1112 static void emDM_copyFaceArray(DerivedMesh *dm, MFace *face_r)
1113 {
1114         EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
1115         EditFace *ef = em->faces.first;
1116         EditVert *ev;
1117         int i;
1118
1119         /* store vertexes indices in tmp union */
1120         for (ev = em->verts.first, i = 0; ev; ev = ev->next, ++i)
1121                 ev->tmp.l = (intptr_t) i;
1122
1123         for ( ; ef; ef = ef->next, ++face_r) {
1124                 face_r->mat_nr = ef->mat_nr;
1125                 face_r->flag = ef->flag;
1126
1127                 face_r->v1 = (int)ef->v1->tmp.l;
1128                 face_r->v2 = (int)ef->v2->tmp.l;
1129                 face_r->v3 = (int)ef->v3->tmp.l;
1130                 if (ef->v4) face_r->v4 = (int)ef->v4->tmp.l;
1131                 else face_r->v4 = 0;
1132
1133                 test_index_face(face_r, NULL, 0, ef->v4?4:3);
1134         }
1135 }
1136
1137 static void *emDM_getFaceDataArray(DerivedMesh *dm, int type)
1138 {
1139         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
1140         EditMesh *em= emdm->em;
1141         EditFace *efa;
1142         char *data, *emdata;
1143         void *datalayer;
1144         int index, size;
1145
1146         datalayer = DM_get_face_data_layer(dm, type);
1147         if (datalayer)
1148                 return datalayer;
1149
1150         /* layers are store per face for editmesh, we convert to a temporary
1151          * data layer array in the derivedmesh when these are requested */
1152         if (type == CD_MTFACE || type == CD_MCOL) {
1153                 index = CustomData_get_layer_index(&em->fdata, type);
1154
1155                 if (index != -1) {
1156                         /* int offset = em->fdata.layers[index].offset; */ /* UNUSED */
1157                         size = CustomData_sizeof(type);
1158
1159                         DM_add_face_layer(dm, type, CD_CALLOC, NULL);
1160                         index = CustomData_get_layer_index(&dm->faceData, type);
1161                         dm->faceData.layers[index].flag |= CD_FLAG_TEMPORARY;
1162
1163                         data = datalayer = DM_get_face_data_layer(dm, type);
1164                         for (efa=em->faces.first; efa; efa=efa->next, data+=size) {
1165                                 emdata = CustomData_em_get(&em->fdata, efa->data, type);
1166                                 memcpy(data, emdata, size);
1167                         }
1168                 }
1169         }
1170
1171         return datalayer;
1172 }
1173
1174 static void emDM_release(DerivedMesh *dm)
1175 {
1176         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
1177
1178         if (DM_release(dm)) {
1179                 if (emdm->vertexCos) {
1180                         MEM_freeN(emdm->vertexCos);
1181                         MEM_freeN(emdm->vertexNos);
1182                         MEM_freeN(emdm->faceNos);
1183                 }
1184
1185                 MEM_freeN(emdm);
1186         }
1187 }
1188
1189 DerivedMesh *editmesh_get_derived(
1190                 EditMesh *em,
1191                 float (*vertexCos)[3])
1192 {
1193         EditMeshDerivedMesh *emdm = MEM_callocN(sizeof(*emdm), "emdm");
1194
1195         DM_init(&emdm->dm, DM_TYPE_EDITMESH, BLI_countlist(&em->verts),
1196                                          BLI_countlist(&em->edges), BLI_countlist(&em->faces));
1197
1198         emdm->dm.getMinMax = emDM_getMinMax;
1199
1200         emdm->dm.getNumVerts = emDM_getNumVerts;
1201         emdm->dm.getNumEdges = emDM_getNumEdges;
1202         emdm->dm.getNumFaces = emDM_getNumFaces;
1203
1204         emdm->dm.getVertCos = emDM_getVertCos;
1205
1206         emdm->dm.getVert = emDM_getVert;
1207         emdm->dm.getEdge = emDM_getEdge;
1208         emdm->dm.getFace = emDM_getFace;
1209         emdm->dm.copyVertArray = emDM_copyVertArray;
1210         emdm->dm.copyEdgeArray = emDM_copyEdgeArray;
1211         emdm->dm.copyFaceArray = emDM_copyFaceArray;
1212         emdm->dm.getFaceDataArray = emDM_getFaceDataArray;
1213
1214         emdm->dm.foreachMappedVert = emDM_foreachMappedVert;
1215         emdm->dm.foreachMappedEdge = emDM_foreachMappedEdge;
1216         emdm->dm.foreachMappedFaceCenter = emDM_foreachMappedFaceCenter;
1217
1218         emdm->dm.drawEdges = emDM_drawEdges;
1219         emdm->dm.drawMappedEdges = emDM_drawMappedEdges;
1220         emdm->dm.drawMappedEdgesInterp = emDM_drawMappedEdgesInterp;
1221         emdm->dm.drawMappedFaces = emDM_drawMappedFaces;
1222         emdm->dm.drawMappedFacesTex = emDM_drawMappedFacesTex;
1223         emdm->dm.drawMappedFacesGLSL = emDM_drawMappedFacesGLSL;
1224         emdm->dm.drawFacesTex = emDM_drawFacesTex;
1225         emdm->dm.drawFacesGLSL = emDM_drawFacesGLSL;
1226         emdm->dm.drawMappedFacesMat = emDM_drawMappedFacesMat;
1227         emdm->dm.drawUVEdges = emDM_drawUVEdges;
1228
1229         emdm->dm.release = emDM_release;
1230
1231         emdm->em = em;
1232         emdm->vertexCos = vertexCos;
1233
1234         if (CustomData_has_layer(&em->vdata, CD_MDEFORMVERT)) {
1235                 EditVert *eve;
1236                 int i;
1237
1238                 DM_add_vert_layer(&emdm->dm, CD_MDEFORMVERT, CD_CALLOC, NULL);
1239
1240                 for (eve = em->verts.first, i = 0; eve; eve = eve->next, ++i)
1241                         DM_set_vert_data(&emdm->dm, i, CD_MDEFORMVERT,
1242                                                          CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT));
1243         }
1244
1245         if (vertexCos) {
1246                 EditVert *eve;
1247                 EditFace *efa;
1248                 int totface = BLI_countlist(&em->faces);
1249                 int i;
1250
1251                 for (i=0,eve=em->verts.first; eve; eve= eve->next)
1252                         eve->tmp.l = (intptr_t) i++;
1253
1254                 emdm->vertexNos = MEM_callocN(sizeof(*emdm->vertexNos)*i, "emdm_vno");
1255                 emdm->faceNos = MEM_mallocN(sizeof(*emdm->faceNos)*totface, "emdm_vno");
1256
1257                 for (i=0, efa= em->faces.first; efa; i++, efa=efa->next) {
1258                         float *v1 = vertexCos[(int) efa->v1->tmp.l];
1259                         float *v2 = vertexCos[(int) efa->v2->tmp.l];
1260                         float *v3 = vertexCos[(int) efa->v3->tmp.l];
1261                         float *no = emdm->faceNos[i];
1262
1263                         if (efa->v4) {
1264                                 float *v4 = vertexCos[(int) efa->v4->tmp.l];
1265
1266                                 normal_quad_v3( no,v1, v2, v3, v4);
1267                                 add_v3_v3(emdm->vertexNos[(int) efa->v4->tmp.l], no);
1268                         }
1269                         else {
1270                                 normal_tri_v3( no,v1, v2, v3);
1271                         }
1272
1273                         add_v3_v3(emdm->vertexNos[(int) efa->v1->tmp.l], no);
1274                         add_v3_v3(emdm->vertexNos[(int) efa->v2->tmp.l], no);
1275                         add_v3_v3(emdm->vertexNos[(int) efa->v3->tmp.l], no);
1276                 }
1277
1278                 for (i=0, eve= em->verts.first; eve; i++, eve=eve->next) {
1279                         float *no = emdm->vertexNos[i];
1280                         /* following Mesh convention; we use vertex coordinate itself
1281                          * for normal in this case */
1282                         if (normalize_v3(no) == 0.0f) {
1283                                 normalize_v3_v3(no, vertexCos[i]);
1284                         }
1285                 }
1286         }
1287
1288         return (DerivedMesh*) emdm;
1289 }
1290