Merging r42193 through r42349 from trunk into soc-2011-tomato
[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;
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                                 if (draw==2) {
356                                         glEnd();
357                                         poly_prev= GL_ZERO; /* force glBegin */
358
359                                         glDisable(GL_POLYGON_STIPPLE);
360                                 }
361                         }
362                 }
363         }
364         else {
365                 for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) {
366                         int drawSmooth = (efa->flag & ME_SMOOTH);
367                         draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, i, &drawSmooth);
368                         if (draw) {
369                                 const GLenum poly_type= efa->v4 ? GL_QUADS:GL_TRIANGLES;
370                                 if (draw==2) { /* enabled with stipple */
371
372                                         if (poly_prev != GL_ZERO) glEnd();
373                                         poly_prev= GL_ZERO; /* force glBegin */
374
375                                         glEnable(GL_POLYGON_STIPPLE);
376                                         glPolygonStipple(stipple_quarttone);
377                                 }
378
379                                 if (skip_normals) {
380                                         if (poly_type != poly_prev) {
381                                                 if (poly_prev != GL_ZERO) glEnd();
382                                                 glBegin((poly_prev= poly_type));
383                                         }
384                                         glVertex3fv(efa->v1->co);
385                                         glVertex3fv(efa->v2->co);
386                                         glVertex3fv(efa->v3->co);
387                                         if (poly_type == GL_QUADS) glVertex3fv(efa->v4->co);
388                                 }
389                                 else {
390                                         const GLenum shade_type= drawSmooth ? GL_SMOOTH : GL_FLAT;
391                                         if (shade_type != shade_prev) {
392                                                 if (poly_prev != GL_ZERO) glEnd();
393                                                 glShadeModel((shade_prev= shade_type)); /* same as below but switch shading */
394                                                 glBegin((poly_prev= poly_type));
395                                         }
396                                         else if (poly_type != poly_prev) {
397                                                 if (poly_prev != GL_ZERO) glEnd();
398                                                 glBegin((poly_prev= poly_type));
399                                         }
400
401                                         if (!drawSmooth) {
402                                                 glNormal3fv(efa->n);
403                                                 glVertex3fv(efa->v1->co);
404                                                 glVertex3fv(efa->v2->co);
405                                                 glVertex3fv(efa->v3->co);
406                                                 if (poly_type == GL_QUADS) glVertex3fv(efa->v4->co);
407                                         }
408                                         else {
409                                                 glNormal3fv(efa->v1->no);
410                                                 glVertex3fv(efa->v1->co);
411                                                 glNormal3fv(efa->v2->no);
412                                                 glVertex3fv(efa->v2->co);
413                                                 glNormal3fv(efa->v3->no);
414                                                 glVertex3fv(efa->v3->co);
415                                                 if (poly_type == GL_QUADS) {
416                                                         glNormal3fv(efa->v4->no);
417                                                         glVertex3fv(efa->v4->co);
418                                                 }
419                                         }
420                                 }
421
422
423                                 if (draw==2) {
424                                         glEnd();
425                                         poly_prev= GL_ZERO; /* force glBegin */
426
427                                         glDisable(GL_POLYGON_STIPPLE);
428                                 }
429                         }
430                 }
431         }
432
433         /* if non zero we know a face was rendered */
434         if (poly_prev != GL_ZERO) glEnd();
435 }
436
437 static void emDM_drawFacesTex_common(
438                 DerivedMesh *dm,
439                 int (*drawParams)(MTFace *tface, int has_mcol, int matnr),
440                 int (*drawParamsMapped)(void *userData, int index),
441                 int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
442                 void *userData)
443 {
444         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
445         EditMesh *em= emdm->em;
446         float (*vertexCos)[3]= emdm->vertexCos;
447         float (*vertexNos)[3]= emdm->vertexNos;
448         EditFace *efa;
449         int i;
450
451         (void) compareDrawOptions;
452
453         /* always use smooth shading even for flat faces, else vertex colors wont interpolate */
454         glShadeModel(GL_SMOOTH);
455
456         if (vertexCos) {
457                 EditVert *eve;
458
459                 for (i=0,eve=em->verts.first; eve; eve= eve->next)
460                         eve->tmp.l = (intptr_t) i++;
461
462                 for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) {
463                         MTFace *tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
464                         MCol *mcol= CustomData_em_get(&em->fdata, efa->data, CD_MCOL);
465                         unsigned char *cp= NULL;
466                         int drawSmooth= (efa->flag & ME_SMOOTH);
467                         int flag;
468
469                         if (drawParams)
470                                 flag= drawParams(tf, (mcol != NULL), efa->mat_nr);
471                         else if (drawParamsMapped)
472                                 flag= drawParamsMapped(userData, i);
473                         else
474                                 flag= 1;
475
476                         if (flag != 0) { /* flag 0 == the face is hidden or invisible */
477
478                                 /* we always want smooth here since otherwise vertex colors dont interpolate */
479                                 if (mcol) {
480                                         if (flag==1) {
481                                                 cp= (unsigned char*)mcol;
482                                         }
483                                 }
484                                 else {
485                                         glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
486                                 }
487
488                                 glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
489                                 if (!drawSmooth) {
490                                         glNormal3fv(emdm->faceNos[i]);
491
492                                         if (tf) glTexCoord2fv(tf->uv[0]);
493                                         if (cp) glColor3ub(cp[3], cp[2], cp[1]);
494                                         glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
495
496                                         if (tf) glTexCoord2fv(tf->uv[1]);
497                                         if (cp) glColor3ub(cp[7], cp[6], cp[5]);
498                                         glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
499
500                                         if (tf) glTexCoord2fv(tf->uv[2]);
501                                         if (cp) glColor3ub(cp[11], cp[10], cp[9]);
502                                         glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
503
504                                         if (efa->v4) {
505                                                 if (tf) glTexCoord2fv(tf->uv[3]);
506                                                 if (cp) glColor3ub(cp[15], cp[14], cp[13]);
507                                                 glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
508                                         }
509                                 }
510                                 else {
511                                         if (tf) glTexCoord2fv(tf->uv[0]);
512                                         if (cp) glColor3ub(cp[3], cp[2], cp[1]);
513                                         glNormal3fv(vertexNos[(int) efa->v1->tmp.l]);
514                                         glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
515
516                                         if (tf) glTexCoord2fv(tf->uv[1]);
517                                         if (cp) glColor3ub(cp[7], cp[6], cp[5]);
518                                         glNormal3fv(vertexNos[(int) efa->v2->tmp.l]);
519                                         glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
520
521                                         if (tf) glTexCoord2fv(tf->uv[2]);
522                                         if (cp) glColor3ub(cp[11], cp[10], cp[9]);
523                                         glNormal3fv(vertexNos[(int) efa->v3->tmp.l]);
524                                         glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
525
526                                         if (efa->v4) {
527                                                 if (tf) glTexCoord2fv(tf->uv[3]);
528                                                 if (cp) glColor3ub(cp[15], cp[14], cp[13]);
529                                                 glNormal3fv(vertexNos[(int) efa->v4->tmp.l]);
530                                                 glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
531                                         }
532                                 }
533                                 glEnd();
534                         }
535                 }
536         }
537         else {
538                 for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) {
539                         MTFace *tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
540                         MCol *mcol= CustomData_em_get(&em->fdata, efa->data, CD_MCOL);
541                         unsigned char *cp= NULL;
542                         int drawSmooth= (efa->flag & ME_SMOOTH);
543                         int flag;
544
545                         if (drawParams)
546                                 flag= drawParams(tf, (mcol != NULL), efa->mat_nr);
547                         else if (drawParamsMapped)
548                                 flag= drawParamsMapped(userData, i);
549                         else
550                                 flag= 1;
551
552                         if (flag != 0) { /* flag 0 == the face is hidden or invisible */
553
554                                 /* we always want smooth here since otherwise vertex colors dont interpolate */
555                                 if (mcol) {
556                                         if (flag==1) {
557                                                 cp= (unsigned char*)mcol;
558                                         }
559                                 }
560                                 else {
561                                         glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
562                                 }
563
564                                 glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
565                                 if (!drawSmooth) {
566                                         glNormal3fv(efa->n);
567
568                                         if (tf) glTexCoord2fv(tf->uv[0]);
569                                         if (cp) glColor3ub(cp[3], cp[2], cp[1]);
570                                         glVertex3fv(efa->v1->co);
571
572                                         if (tf) glTexCoord2fv(tf->uv[1]);
573                                         if (cp) glColor3ub(cp[7], cp[6], cp[5]);
574                                         glVertex3fv(efa->v2->co);
575
576                                         if (tf) glTexCoord2fv(tf->uv[2]);
577                                         if (cp) glColor3ub(cp[11], cp[10], cp[9]);
578                                         glVertex3fv(efa->v3->co);
579
580                                         if (efa->v4) {
581                                                 if (tf) glTexCoord2fv(tf->uv[3]);
582                                                 if (cp) glColor3ub(cp[15], cp[14], cp[13]);
583                                                 glVertex3fv(efa->v4->co);
584                                         }
585                                 }
586                                 else {
587                                         if (tf) glTexCoord2fv(tf->uv[0]);
588                                         if (cp) glColor3ub(cp[3], cp[2], cp[1]);
589                                         glNormal3fv(efa->v1->no);
590                                         glVertex3fv(efa->v1->co);
591
592                                         if (tf) glTexCoord2fv(tf->uv[1]);
593                                         if (cp) glColor3ub(cp[7], cp[6], cp[5]);
594                                         glNormal3fv(efa->v2->no);
595                                         glVertex3fv(efa->v2->co);
596
597                                         if (tf) glTexCoord2fv(tf->uv[2]);
598                                         if (cp) glColor3ub(cp[11], cp[10], cp[9]);
599                                         glNormal3fv(efa->v3->no);
600                                         glVertex3fv(efa->v3->co);
601
602                                         if (efa->v4) {
603                                                 if (tf) glTexCoord2fv(tf->uv[3]);
604                                                 if (cp) glColor3ub(cp[15], cp[14], cp[13]);
605                                                 glNormal3fv(efa->v4->no);
606                                                 glVertex3fv(efa->v4->co);
607                                         }
608                                 }
609                                 glEnd();
610                         }
611                 }
612         }
613 }
614
615 static void emDM_drawFacesTex(
616                 DerivedMesh *dm,
617                 int (*setDrawOptions)(MTFace *tface, int has_mcol, int matnr),
618                 int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
619                 void *userData)
620 {
621         emDM_drawFacesTex_common(dm, setDrawOptions, NULL, compareDrawOptions, userData);
622 }
623
624 static void emDM_drawMappedFacesTex(
625                 DerivedMesh *dm,
626                 int (*setDrawOptions)(void *userData, int index),
627                 int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
628                 void *userData)
629 {
630         emDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData);
631 }
632
633 static void emDM_drawMappedFacesGLSL(
634                 DerivedMesh *dm,
635                 int (*setMaterial)(int, void *attribs),
636                 int (*setDrawOptions)(void *userData, int index),
637                 void *userData)
638 {
639         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
640         EditMesh *em= emdm->em;
641         float (*vertexCos)[3]= emdm->vertexCos;
642         float (*vertexNos)[3]= emdm->vertexNos;
643         EditVert *eve;
644         EditFace *efa;
645         DMVertexAttribs attribs= {{{0}}};
646         GPUVertexAttribs gattribs;
647         /* int tfoffset; */ /* UNUSED */
648         int i, b, matnr, new_matnr, dodraw /* , layer */ /* UNUSED */;
649
650         dodraw = 0;
651         matnr = -1;
652
653         /* layer = CustomData_get_layer_index(&em->fdata, CD_MTFACE); */ /* UNUSED */
654         /* tfoffset = (layer == -1)? -1: em->fdata.layers[layer].offset; */ /* UNUSED */
655
656         /* always use smooth shading even for flat faces, else vertex colors wont interpolate */
657         glShadeModel(GL_SMOOTH);
658
659         for (i=0,eve=em->verts.first; eve; eve= eve->next)
660                 eve->tmp.l = (intptr_t) i++;
661
662 #define PASSATTRIB(efa, eve, vert) {                                                                                    \
663         if (attribs.totorco) {                                                                                                          \
664                 float *orco = attribs.orco.array[eve->tmp.l];                                                   \
665                 glVertexAttrib3fvARB(attribs.orco.glIndex, orco);                                               \
666         }                                                                                                                                                       \
667         for (b = 0; b < attribs.tottface; b++) {                                                                        \
668                 MTFace *_tf = (MTFace*)((char*)efa->data + attribs.tface[b].emOffset);  \
669                 glVertexAttrib2fvARB(attribs.tface[b].glIndex, _tf->uv[vert]);                  \
670         }                                                                                                                                                       \
671         for (b = 0; b < attribs.totmcol; b++) {                                                                         \
672                 MCol *cp = (MCol*)((char*)efa->data + attribs.mcol[b].emOffset);                \
673                 GLubyte col[4];                                                                                                                 \
674                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;                             \
675                 glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col);                                    \
676         }                                                                                                                                                       \
677         if (attribs.tottang) {                                                                                                          \
678                 float *tang = attribs.tang.array[i*4 + vert];                                                   \
679                 glVertexAttrib4fvARB(attribs.tang.glIndex, tang);                                               \
680         }                                                                                                                                                       \
681 }
682
683         for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) {
684                 int drawSmooth= (efa->flag & ME_SMOOTH);
685
686                 if (setDrawOptions && !setDrawOptions(userData, i))
687                         continue;
688
689                 new_matnr = efa->mat_nr + 1;
690                 if (new_matnr != matnr) {
691                         dodraw = setMaterial(matnr = new_matnr, &gattribs);
692                         if (dodraw)
693                                 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
694                 }
695
696                 if (dodraw) {
697                         glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
698                         if (!drawSmooth) {
699                                 if (vertexCos) glNormal3fv(emdm->faceNos[i]);
700                                 else glNormal3fv(efa->n);
701
702                                 PASSATTRIB(efa, efa->v1, 0);
703                                 if (vertexCos) glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
704                                 else glVertex3fv(efa->v1->co);
705
706                                 PASSATTRIB(efa, efa->v2, 1);
707                                 if (vertexCos) glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
708                                 else glVertex3fv(efa->v2->co);
709
710                                 PASSATTRIB(efa, efa->v3, 2);
711                                 if (vertexCos) glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
712                                 else glVertex3fv(efa->v3->co);
713
714                                 if (efa->v4) {
715                                         PASSATTRIB(efa, efa->v4, 3);
716                                         if (vertexCos) glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
717                                         else glVertex3fv(efa->v4->co);
718                                 }
719                         }
720                         else {
721                                 PASSATTRIB(efa, efa->v1, 0);
722                                 if (vertexCos) {
723                                         glNormal3fv(vertexNos[(int) efa->v1->tmp.l]);
724                                         glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
725                                 }
726                                 else {
727                                         glNormal3fv(efa->v1->no);
728                                         glVertex3fv(efa->v1->co);
729                                 }
730
731                                 PASSATTRIB(efa, efa->v2, 1);
732                                 if (vertexCos) {
733                                         glNormal3fv(vertexNos[(int) efa->v2->tmp.l]);
734                                         glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
735                                 }
736                                 else {
737                                         glNormal3fv(efa->v2->no);
738                                         glVertex3fv(efa->v2->co);
739                                 }
740
741                                 PASSATTRIB(efa, efa->v3, 2);
742                                 if (vertexCos) {
743                                         glNormal3fv(vertexNos[(int) efa->v3->tmp.l]);
744                                         glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
745                                 }
746                                 else {
747                                         glNormal3fv(efa->v3->no);
748                                         glVertex3fv(efa->v3->co);
749                                 }
750
751                                 if (efa->v4) {
752                                         PASSATTRIB(efa, efa->v4, 3);
753                                         if (vertexCos) {
754                                                 glNormal3fv(vertexNos[(int) efa->v4->tmp.l]);
755                                                 glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
756                                         }
757                                         else {
758                                                 glNormal3fv(efa->v4->no);
759                                                 glVertex3fv(efa->v4->co);
760                                         }
761                                 }
762                         }
763                         glEnd();
764                 }
765         }
766 #undef PASSATTRIB
767 }
768
769 static void emDM_drawFacesGLSL(
770                 DerivedMesh *dm,
771                 int (*setMaterial)(int, void *attribs))
772 {
773         dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
774 }
775
776 static void emDM_drawMappedFacesMat(
777                 DerivedMesh *dm,
778                 void (*setMaterial)(void *userData, int, void *attribs),
779                 int (*setFace)(void *userData, int index), void *userData)
780 {
781         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
782         EditMesh *em= emdm->em;
783         float (*vertexCos)[3]= emdm->vertexCos;
784         float (*vertexNos)[3]= emdm->vertexNos;
785         EditVert *eve;
786         EditFace *efa;
787         DMVertexAttribs attribs= {{{0}}};
788         GPUVertexAttribs gattribs;
789         int i, b, matnr, new_matnr;
790
791         matnr = -1;
792
793         /* always use smooth shading even for flat faces, else vertex colors wont interpolate */
794         glShadeModel(GL_SMOOTH);
795
796         for (i=0,eve=em->verts.first; eve; eve= eve->next)
797                 eve->tmp.l = (intptr_t) i++;
798
799 #define PASSATTRIB(efa, eve, vert) {                                                                                    \
800         if (attribs.totorco) {                                                                                                          \
801                 float *orco = attribs.orco.array[eve->tmp.l];                                                   \
802                 if (attribs.orco.glTexco)                                                                                               \
803                         glTexCoord3fv(orco);                                                                                            \
804                 else                                                                                                                                    \
805                         glVertexAttrib3fvARB(attribs.orco.glIndex, orco);                                       \
806         }                                                                                                                                                       \
807         for (b = 0; b < attribs.tottface; b++) {                                                                        \
808                 MTFace *_tf = (MTFace*)((char*)efa->data + attribs.tface[b].emOffset);  \
809                 if (attribs.tface[b].glTexco)                                                                                   \
810                         glTexCoord2fv(_tf->uv[vert]);                                                                           \
811                 else                                                                                                                                    \
812                         glVertexAttrib2fvARB(attribs.tface[b].glIndex, _tf->uv[vert]);          \
813         }                                                                                                                                                       \
814         for (b = 0; b < attribs.totmcol; b++) {                                                                         \
815                 MCol *cp = (MCol*)((char*)efa->data + attribs.mcol[b].emOffset);                \
816                 GLubyte col[4];                                                                                                                 \
817                 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;                             \
818                 glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col);                                    \
819         }                                                                                                                                                       \
820         if (attribs.tottang) {                                                                                                          \
821                 float *tang = attribs.tang.array[i*4 + vert];                                                   \
822                 glVertexAttrib4fvARB(attribs.tang.glIndex, tang);                                               \
823         }                                                                                                                                                       \
824 }
825
826         for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) {
827                 int drawSmooth= (efa->flag & ME_SMOOTH);
828
829                 /* face hiding */
830                 if (setFace && !setFace(userData, i))
831                         continue;
832
833                 /* material */
834                 new_matnr = efa->mat_nr + 1;
835                 if (new_matnr != matnr) {
836                         setMaterial(userData, matnr = new_matnr, &gattribs);
837                         DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
838                 }
839
840                 /* face */
841                 glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
842                 if (!drawSmooth) {
843                         if (vertexCos) glNormal3fv(emdm->faceNos[i]);
844                         else glNormal3fv(efa->n);
845
846                         PASSATTRIB(efa, efa->v1, 0);
847                         if (vertexCos) glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
848                         else glVertex3fv(efa->v1->co);
849
850                         PASSATTRIB(efa, efa->v2, 1);
851                         if (vertexCos) glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
852                         else glVertex3fv(efa->v2->co);
853
854                         PASSATTRIB(efa, efa->v3, 2);
855                         if (vertexCos) glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
856                         else glVertex3fv(efa->v3->co);
857
858                         if (efa->v4) {
859                                 PASSATTRIB(efa, efa->v4, 3);
860                                 if (vertexCos) glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
861                                 else glVertex3fv(efa->v4->co);
862                         }
863                 }
864                 else {
865                         PASSATTRIB(efa, efa->v1, 0);
866                         if (vertexCos) {
867                                 glNormal3fv(vertexNos[(int) efa->v1->tmp.l]);
868                                 glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
869                         }
870                         else {
871                                 glNormal3fv(efa->v1->no);
872                                 glVertex3fv(efa->v1->co);
873                         }
874
875                         PASSATTRIB(efa, efa->v2, 1);
876                         if (vertexCos) {
877                                 glNormal3fv(vertexNos[(int) efa->v2->tmp.l]);
878                                 glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
879                         }
880                         else {
881                                 glNormal3fv(efa->v2->no);
882                                 glVertex3fv(efa->v2->co);
883                         }
884
885                         PASSATTRIB(efa, efa->v3, 2);
886                         if (vertexCos) {
887                                 glNormal3fv(vertexNos[(int) efa->v3->tmp.l]);
888                                 glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
889                         }
890                         else {
891                                 glNormal3fv(efa->v3->no);
892                                 glVertex3fv(efa->v3->co);
893                         }
894
895                         if (efa->v4) {
896                                 PASSATTRIB(efa, efa->v4, 3);
897                                 if (vertexCos) {
898                                         glNormal3fv(vertexNos[(int) efa->v4->tmp.l]);
899                                         glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
900                                 }
901                                 else {
902                                         glNormal3fv(efa->v4->no);
903                                         glVertex3fv(efa->v4->co);
904                                 }
905                         }
906                 }
907                 glEnd();
908         }
909 #undef PASSATTRIB
910 }
911
912 static void emDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
913 {
914         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
915         EditVert *eve;
916         int i;
917
918         if (emdm->em->verts.first) {
919                 for (i=0,eve= emdm->em->verts.first; eve; i++,eve= eve->next) {
920                         if (emdm->vertexCos) {
921                                 DO_MINMAX(emdm->vertexCos[i], min_r, max_r);
922                         }
923                         else {
924                                 DO_MINMAX(eve->co, min_r, max_r);
925                         }
926                 }
927         }
928         else {
929                 min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
930         }
931 }
932 static int emDM_getNumVerts(DerivedMesh *dm)
933 {
934         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
935
936         return BLI_countlist(&emdm->em->verts);
937 }
938
939 static int emDM_getNumEdges(DerivedMesh *dm)
940 {
941         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
942
943         return BLI_countlist(&emdm->em->edges);
944 }
945
946 static int emDM_getNumFaces(DerivedMesh *dm)
947 {
948         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
949
950         return BLI_countlist(&emdm->em->faces);
951 }
952
953 static void emDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3])
954 {
955         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
956         EditVert *eve;
957         int i;
958
959         for (i=0,eve= emdm->em->verts.first; eve; i++,eve=eve->next) {
960                 if (emdm->vertexCos) {
961                         copy_v3_v3(cos_r[i], emdm->vertexCos[i]);
962                 }
963                 else {
964                         copy_v3_v3(cos_r[i], eve->co);
965                 }
966         }
967 }
968
969 static void emDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
970 {
971         EditVert *ev = ((EditMeshDerivedMesh *)dm)->em->verts.first;
972         int i;
973
974         for (i = 0; i < index; ++i) ev = ev->next;
975
976         copy_v3_v3(vert_r->co, ev->co);
977
978         normal_float_to_short_v3(vert_r->no, ev->no);
979
980         /* TODO what to do with vert_r->flag? */
981         vert_r->bweight = (unsigned char) (ev->bweight*255.0f);
982 }
983
984 static void emDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
985 {
986         EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
987         EditEdge *ee = em->edges.first;
988         EditVert *ev, *v1, *v2;
989         int i;
990
991         for (i = 0; i < index; ++i) ee = ee->next;
992
993         edge_r->crease = (unsigned char) (ee->crease*255.0f);
994         edge_r->bweight = (unsigned char) (ee->bweight*255.0f);
995         /* TODO what to do with edge_r->flag? */
996         edge_r->flag = ME_EDGEDRAW|ME_EDGERENDER;
997         if (ee->seam) edge_r->flag |= ME_SEAM;
998         if (ee->sharp) edge_r->flag |= ME_SHARP;
999 #if 0
1000         /* this needs setup of f2 field */
1001         if (!ee->f2) edge_r->flag |= ME_LOOSEEDGE;
1002 #endif
1003
1004         /* goddamn, we have to search all verts to find indices */
1005         v1 = ee->v1;
1006         v2 = ee->v2;
1007         for (i = 0, ev = em->verts.first; v1 || v2; i++, ev = ev->next) {
1008                 if (ev == v1) {
1009                         edge_r->v1 = i;
1010                         v1 = NULL;
1011                 }
1012                 if (ev == v2) {
1013                         edge_r->v2 = i;
1014                         v2 = NULL;
1015                 }
1016         }
1017 }
1018
1019 static void emDM_getFace(DerivedMesh *dm, int index, MFace *face_r)
1020 {
1021         EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
1022         EditFace *ef = em->faces.first;
1023         EditVert *ev, *v1, *v2, *v3, *v4;
1024         int i;
1025
1026         for (i = 0; i < index; ++i) ef = ef->next;
1027
1028         face_r->mat_nr = ef->mat_nr;
1029         face_r->flag = ef->flag;
1030
1031         /* goddamn, we have to search all verts to find indices */
1032         v1 = ef->v1;
1033         v2 = ef->v2;
1034         v3 = ef->v3;
1035         v4 = ef->v4;
1036         if (!v4) face_r->v4 = 0;
1037
1038         for (i = 0, ev = em->verts.first; v1 || v2 || v3 || v4;
1039                 i++, ev = ev->next) {
1040                 if (ev == v1) {
1041                         face_r->v1 = i;
1042                         v1 = NULL;
1043                 }
1044                 if (ev == v2) {
1045                         face_r->v2 = i;
1046                         v2 = NULL;
1047                 }
1048                 if (ev == v3) {
1049                         face_r->v3 = i;
1050                         v3 = NULL;
1051                 }
1052                 if (ev == v4) {
1053                         face_r->v4 = i;
1054                         v4 = NULL;
1055                 }
1056         }
1057
1058         test_index_face(face_r, NULL, 0, ef->v4?4:3);
1059 }
1060
1061 static void emDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
1062 {
1063         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
1064         EditVert *ev = emdm->em->verts.first;
1065         int i;
1066
1067         for (i=0; ev; ev = ev->next, ++vert_r, ++i) {
1068                 if (emdm->vertexCos)
1069                         copy_v3_v3(vert_r->co, emdm->vertexCos[i]);
1070                 else
1071                         copy_v3_v3(vert_r->co, ev->co);
1072
1073                 normal_float_to_short_v3(vert_r->no, ev->no);
1074
1075                 /* TODO what to do with vert_r->flag? */
1076                 vert_r->flag = 0;
1077                 vert_r->bweight = (unsigned char) (ev->bweight*255.0f);
1078         }
1079 }
1080
1081 static void emDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r)
1082 {
1083         EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
1084         EditEdge *ee = em->edges.first;
1085         EditVert *ev;
1086         int i;
1087
1088         /* store vertex indices in tmp union */
1089         for (ev = em->verts.first, i = 0; ev; ev = ev->next, ++i)
1090                 ev->tmp.l = (intptr_t) i;
1091
1092         for ( ; ee; ee = ee->next, ++edge_r) {
1093                 edge_r->crease = (unsigned char) (ee->crease*255.0f);
1094                 edge_r->bweight = (unsigned char) (ee->bweight*255.0f);
1095                 /* TODO what to do with edge_r->flag? */
1096                 edge_r->flag = ME_EDGEDRAW|ME_EDGERENDER;
1097                 if (ee->seam) edge_r->flag |= ME_SEAM;
1098                 if (ee->sharp) edge_r->flag |= ME_SHARP;
1099 #if 0
1100                 /* this needs setup of f2 field */
1101                 if (!ee->f2) edge_r->flag |= ME_LOOSEEDGE;
1102 #endif
1103
1104                 edge_r->v1 = (int)ee->v1->tmp.l;
1105                 edge_r->v2 = (int)ee->v2->tmp.l;
1106         }
1107 }
1108
1109 static void emDM_copyFaceArray(DerivedMesh *dm, MFace *face_r)
1110 {
1111         EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
1112         EditFace *ef = em->faces.first;
1113         EditVert *ev;
1114         int i;
1115
1116         /* store vertexes indices in tmp union */
1117         for (ev = em->verts.first, i = 0; ev; ev = ev->next, ++i)
1118                 ev->tmp.l = (intptr_t) i;
1119
1120         for ( ; ef; ef = ef->next, ++face_r) {
1121                 face_r->mat_nr = ef->mat_nr;
1122                 face_r->flag = ef->flag;
1123
1124                 face_r->v1 = (int)ef->v1->tmp.l;
1125                 face_r->v2 = (int)ef->v2->tmp.l;
1126                 face_r->v3 = (int)ef->v3->tmp.l;
1127                 if (ef->v4) face_r->v4 = (int)ef->v4->tmp.l;
1128                 else face_r->v4 = 0;
1129
1130                 test_index_face(face_r, NULL, 0, ef->v4?4:3);
1131         }
1132 }
1133
1134 static void *emDM_getFaceDataArray(DerivedMesh *dm, int type)
1135 {
1136         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
1137         EditMesh *em= emdm->em;
1138         EditFace *efa;
1139         char *data, *emdata;
1140         void *datalayer;
1141         int index, size;
1142
1143         datalayer = DM_get_face_data_layer(dm, type);
1144         if (datalayer)
1145                 return datalayer;
1146
1147         /* layers are store per face for editmesh, we convert to a temporary
1148          * data layer array in the derivedmesh when these are requested */
1149         if (type == CD_MTFACE || type == CD_MCOL) {
1150                 index = CustomData_get_layer_index(&em->fdata, type);
1151
1152                 if (index != -1) {
1153                         /* int offset = em->fdata.layers[index].offset; */ /* UNUSED */
1154                         size = CustomData_sizeof(type);
1155
1156                         DM_add_face_layer(dm, type, CD_CALLOC, NULL);
1157                         index = CustomData_get_layer_index(&dm->faceData, type);
1158                         dm->faceData.layers[index].flag |= CD_FLAG_TEMPORARY;
1159
1160                         data = datalayer = DM_get_face_data_layer(dm, type);
1161                         for (efa=em->faces.first; efa; efa=efa->next, data+=size) {
1162                                 emdata = CustomData_em_get(&em->fdata, efa->data, type);
1163                                 memcpy(data, emdata, size);
1164                         }
1165                 }
1166         }
1167
1168         return datalayer;
1169 }
1170
1171 static void emDM_release(DerivedMesh *dm)
1172 {
1173         EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
1174
1175         if (DM_release(dm)) {
1176                 if (emdm->vertexCos) {
1177                         MEM_freeN(emdm->vertexCos);
1178                         MEM_freeN(emdm->vertexNos);
1179                         MEM_freeN(emdm->faceNos);
1180                 }
1181
1182                 MEM_freeN(emdm);
1183         }
1184 }
1185
1186 DerivedMesh *editmesh_get_derived(
1187                 EditMesh *em,
1188                 float (*vertexCos)[3])
1189 {
1190         EditMeshDerivedMesh *emdm = MEM_callocN(sizeof(*emdm), "emdm");
1191
1192         DM_init(&emdm->dm, DM_TYPE_EDITMESH, BLI_countlist(&em->verts),
1193                                          BLI_countlist(&em->edges), BLI_countlist(&em->faces));
1194
1195         emdm->dm.getMinMax = emDM_getMinMax;
1196
1197         emdm->dm.getNumVerts = emDM_getNumVerts;
1198         emdm->dm.getNumEdges = emDM_getNumEdges;
1199         emdm->dm.getNumFaces = emDM_getNumFaces;
1200
1201         emdm->dm.getVertCos = emDM_getVertCos;
1202
1203         emdm->dm.getVert = emDM_getVert;
1204         emdm->dm.getEdge = emDM_getEdge;
1205         emdm->dm.getFace = emDM_getFace;
1206         emdm->dm.copyVertArray = emDM_copyVertArray;
1207         emdm->dm.copyEdgeArray = emDM_copyEdgeArray;
1208         emdm->dm.copyFaceArray = emDM_copyFaceArray;
1209         emdm->dm.getFaceDataArray = emDM_getFaceDataArray;
1210
1211         emdm->dm.foreachMappedVert = emDM_foreachMappedVert;
1212         emdm->dm.foreachMappedEdge = emDM_foreachMappedEdge;
1213         emdm->dm.foreachMappedFaceCenter = emDM_foreachMappedFaceCenter;
1214
1215         emdm->dm.drawEdges = emDM_drawEdges;
1216         emdm->dm.drawMappedEdges = emDM_drawMappedEdges;
1217         emdm->dm.drawMappedEdgesInterp = emDM_drawMappedEdgesInterp;
1218         emdm->dm.drawMappedFaces = emDM_drawMappedFaces;
1219         emdm->dm.drawMappedFacesTex = emDM_drawMappedFacesTex;
1220         emdm->dm.drawMappedFacesGLSL = emDM_drawMappedFacesGLSL;
1221         emdm->dm.drawFacesTex = emDM_drawFacesTex;
1222         emdm->dm.drawFacesGLSL = emDM_drawFacesGLSL;
1223         emdm->dm.drawMappedFacesMat = emDM_drawMappedFacesMat;
1224         emdm->dm.drawUVEdges = emDM_drawUVEdges;
1225
1226         emdm->dm.release = emDM_release;
1227
1228         emdm->em = em;
1229         emdm->vertexCos = vertexCos;
1230
1231         if (CustomData_has_layer(&em->vdata, CD_MDEFORMVERT)) {
1232                 EditVert *eve;
1233                 int i;
1234
1235                 DM_add_vert_layer(&emdm->dm, CD_MDEFORMVERT, CD_CALLOC, NULL);
1236
1237                 for (eve = em->verts.first, i = 0; eve; eve = eve->next, ++i)
1238                         DM_set_vert_data(&emdm->dm, i, CD_MDEFORMVERT,
1239                                                          CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT));
1240         }
1241
1242         if (vertexCos) {
1243                 EditVert *eve;
1244                 EditFace *efa;
1245                 int totface = BLI_countlist(&em->faces);
1246                 int i;
1247
1248                 for (i=0,eve=em->verts.first; eve; eve= eve->next)
1249                         eve->tmp.l = (intptr_t) i++;
1250
1251                 emdm->vertexNos = MEM_callocN(sizeof(*emdm->vertexNos)*i, "emdm_vno");
1252                 emdm->faceNos = MEM_mallocN(sizeof(*emdm->faceNos)*totface, "emdm_vno");
1253
1254                 for (i=0, efa= em->faces.first; efa; i++, efa=efa->next) {
1255                         float *v1 = vertexCos[(int) efa->v1->tmp.l];
1256                         float *v2 = vertexCos[(int) efa->v2->tmp.l];
1257                         float *v3 = vertexCos[(int) efa->v3->tmp.l];
1258                         float *no = emdm->faceNos[i];
1259
1260                         if (efa->v4) {
1261                                 float *v4 = vertexCos[(int) efa->v4->tmp.l];
1262
1263                                 normal_quad_v3( no,v1, v2, v3, v4);
1264                                 add_v3_v3(emdm->vertexNos[(int) efa->v4->tmp.l], no);
1265                         }
1266                         else {
1267                                 normal_tri_v3( no,v1, v2, v3);
1268                         }
1269
1270                         add_v3_v3(emdm->vertexNos[(int) efa->v1->tmp.l], no);
1271                         add_v3_v3(emdm->vertexNos[(int) efa->v2->tmp.l], no);
1272                         add_v3_v3(emdm->vertexNos[(int) efa->v3->tmp.l], no);
1273                 }
1274
1275                 for (i=0, eve= em->verts.first; eve; i++, eve=eve->next) {
1276                         float *no = emdm->vertexNos[i];
1277                         /* following Mesh convention; we use vertex coordinate itself
1278                          * for normal in this case */
1279                         if (normalize_v3(no) == 0.0f) {
1280                                 normalize_v3_v3(no, vertexCos[i]);
1281                         }
1282                 }
1283         }
1284
1285         return (DerivedMesh*) emdm;
1286 }
1287