2 * ***** BEGIN GPL LICENSE BLOCK *****
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.
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.
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.
18 * The Original Code is Copyright (C) 2005 Blender Foundation.
19 * All rights reserved.
21 * The Original Code is: all of this file.
23 * Contributor(s): none yet.
25 * ***** END GPL LICENSE BLOCK *****
28 /** \file blender/blenkernel/intern/editderivedmesh.c
34 #include "BLI_utildefines.h"
35 #include "BLI_blenlib.h"
36 #include "BLI_edgehash.h"
37 #include "BLI_editVert.h"
41 #include "BKE_cdderivedmesh.h"
42 #include "BKE_global.h"
44 #include "BKE_paint.h"
47 #include "DNA_meshdata_types.h"
48 #include "DNA_object_types.h"
49 #include "DNA_curve_types.h" /* for Curve */
51 #include "MEM_guardedalloc.h"
53 #include "GPU_buffers.h"
55 #include "GPU_extensions.h"
56 #include "GPU_material.h"
62 extern GLubyte stipple_quarttone[128]; /* glutil.c, bad level data */
64 static void emDM_foreachMappedVert(
66 void (*func)(void *userData, int index, float *co, float *no_f, short *no_s),
69 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
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);
78 func(userData, i, eve->co, eve->no, NULL);
82 static void emDM_foreachMappedEdge(
84 void (*func)(void *userData, int index, float *v0co, float *v1co),
87 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
91 if (emdm->vertexCos) {
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]);
100 for (i=0,eed= emdm->em->edges.first; eed; i++,eed= eed->next)
101 func(userData, i, eed->v1->co, eed->v2->co);
105 static void emDM_drawMappedEdges(
107 int (*setDrawOptions)(void *userData, int index),
110 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
114 if (emdm->vertexCos) {
117 for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
118 eve->tmp.l = (intptr_t) i++;
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]);
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);
140 static void emDM_drawEdges(
142 int UNUSED(drawLooseEdges),
143 int UNUSED(drawAllEdges))
145 emDM_drawMappedEdges(dm, NULL, NULL);
148 static void emDM_drawMappedEdgesInterp(
150 int (*setDrawOptions)(void *userData, int index),
151 void (*setDrawInterpOptions)(void *userData, int index, float t),
154 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
158 if (emdm->vertexCos) {
161 for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
162 eve->tmp.l = (intptr_t) i++;
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]);
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);
189 static void emDM_drawUVEdges(DerivedMesh *dm)
191 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
196 for (efa= emdm->em->faces.first; efa; efa= efa->next) {
197 tf = CustomData_em_get(&emdm->em->fdata, efa->data, CD_MTFACE);
199 if (tf && !(efa->h)) {
200 glVertex2fv(tf->uv[0]);
201 glVertex2fv(tf->uv[1]);
203 glVertex2fv(tf->uv[1]);
204 glVertex2fv(tf->uv[2]);
207 glVertex2fv(tf->uv[2]);
208 glVertex2fv(tf->uv[0]);
211 glVertex2fv(tf->uv[2]);
212 glVertex2fv(tf->uv[3]);
213 glVertex2fv(tf->uv[3]);
214 glVertex2fv(tf->uv[0]);
221 static void emDM__calcFaceCent(EditFace *efa, float cent[3], float (*vertexCos)[3])
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]);
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);
237 mul_v3_fl(cent, 0.25f);
240 mul_v3_fl(cent, 0.33333333333f);
244 static void emDM_foreachMappedFaceCenter(
246 void (*func)(void *userData, int index, float *co, float *no),
249 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
255 if (emdm->vertexCos) {
256 for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
257 eve->tmp.l = (intptr_t) i++;
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);
266 /* note, material function is ignored for now. */
267 static void emDM_drawMappedFaces(
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))
274 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
277 const int skip_normals= !glIsEnabled(GL_LIGHTING); /* could be passed as an arg */
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;
283 (void)setMaterial; /* UNUSED */
285 /* currently unused -- each original face is handled separately */
286 (void)compareDrawOptions;
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;
295 for (i=0,eve=emdm->em->verts.first; eve; eve= eve->next)
296 eve->tmp.l = (intptr_t) i++;
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);
302 const GLenum poly_type= efa->v4 ? GL_QUADS:GL_TRIANGLES;
303 if (draw==2) { /* enabled with stipple */
305 if (poly_prev != GL_ZERO) glEnd();
306 poly_prev= GL_ZERO; /* force glBegin */
308 glEnable(GL_POLYGON_STIPPLE);
309 glPolygonStipple(stipple_quarttone);
313 if (poly_type != poly_prev) {
314 if (poly_prev != GL_ZERO) glEnd();
315 glBegin((poly_prev= poly_type));
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]);
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));
329 else if (poly_type != poly_prev) {
330 if (poly_prev != GL_ZERO) glEnd();
331 glBegin((poly_prev= poly_type));
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]);
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]);
357 poly_prev= GL_ZERO; /* force glBegin */
359 glDisable(GL_POLYGON_STIPPLE);
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);
369 const GLenum poly_type= efa->v4 ? GL_QUADS:GL_TRIANGLES;
370 if (draw==2) { /* enabled with stipple */
372 if (poly_prev != GL_ZERO) glEnd();
373 poly_prev= GL_ZERO; /* force glBegin */
375 glEnable(GL_POLYGON_STIPPLE);
376 glPolygonStipple(stipple_quarttone);
380 if (poly_type != poly_prev) {
381 if (poly_prev != GL_ZERO) glEnd();
382 glBegin((poly_prev= poly_type));
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);
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));
396 else if (poly_type != poly_prev) {
397 if (poly_prev != GL_ZERO) glEnd();
398 glBegin((poly_prev= poly_type));
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);
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);
425 poly_prev= GL_ZERO; /* force glBegin */
427 glDisable(GL_POLYGON_STIPPLE);
433 /* if non zero we know a face was rendered */
434 if (poly_prev != GL_ZERO) glEnd();
437 static void emDM_drawFacesTex_common(
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),
444 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
445 EditMesh *em= emdm->em;
446 float (*vertexCos)[3]= emdm->vertexCos;
447 float (*vertexNos)[3]= emdm->vertexNos;
451 (void) compareDrawOptions;
453 /* always use smooth shading even for flat faces, else vertex colors wont interpolate */
454 glShadeModel(GL_SMOOTH);
459 for (i=0,eve=em->verts.first; eve; eve= eve->next)
460 eve->tmp.l = (intptr_t) i++;
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);
470 flag= drawParams(tf, (mcol != NULL), efa->mat_nr);
471 else if (drawParamsMapped)
472 flag= drawParamsMapped(userData, i);
476 if (flag != 0) { /* flag 0 == the face is hidden or invisible */
478 /* we always want smooth here since otherwise vertex colors dont interpolate */
481 cp= (unsigned char*)mcol;
485 glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
488 glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
490 glNormal3fv(emdm->faceNos[i]);
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]);
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]);
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]);
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]);
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]);
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]);
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]);
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]);
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);
546 flag= drawParams(tf, (mcol != NULL), efa->mat_nr);
547 else if (drawParamsMapped)
548 flag= drawParamsMapped(userData, i);
552 if (flag != 0) { /* flag 0 == the face is hidden or invisible */
554 /* we always want smooth here since otherwise vertex colors dont interpolate */
557 cp= (unsigned char*)mcol;
561 glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
564 glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
568 if (tf) glTexCoord2fv(tf->uv[0]);
569 if (cp) glColor3ub(cp[3], cp[2], cp[1]);
570 glVertex3fv(efa->v1->co);
572 if (tf) glTexCoord2fv(tf->uv[1]);
573 if (cp) glColor3ub(cp[7], cp[6], cp[5]);
574 glVertex3fv(efa->v2->co);
576 if (tf) glTexCoord2fv(tf->uv[2]);
577 if (cp) glColor3ub(cp[11], cp[10], cp[9]);
578 glVertex3fv(efa->v3->co);
581 if (tf) glTexCoord2fv(tf->uv[3]);
582 if (cp) glColor3ub(cp[15], cp[14], cp[13]);
583 glVertex3fv(efa->v4->co);
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);
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);
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);
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);
615 static void emDM_drawFacesTex(
617 int (*setDrawOptions)(MTFace *tface, int has_mcol, int matnr),
618 int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
621 emDM_drawFacesTex_common(dm, setDrawOptions, NULL, compareDrawOptions, userData);
624 static void emDM_drawMappedFacesTex(
626 int (*setDrawOptions)(void *userData, int index),
627 int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
630 emDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData);
633 static void emDM_drawMappedFacesGLSL(
635 int (*setMaterial)(int, void *attribs),
636 int (*setDrawOptions)(void *userData, int index),
639 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
640 EditMesh *em= emdm->em;
641 float (*vertexCos)[3]= emdm->vertexCos;
642 float (*vertexNos)[3]= emdm->vertexNos;
645 DMVertexAttribs attribs= {{{0}}};
646 GPUVertexAttribs gattribs;
647 /* int tfoffset; */ /* UNUSED */
648 int i, b, matnr, new_matnr, dodraw /* , layer */ /* UNUSED */;
653 /* layer = CustomData_get_layer_index(&em->fdata, CD_MTFACE); */ /* UNUSED */
654 /* tfoffset = (layer == -1)? -1: em->fdata.layers[layer].offset; */ /* UNUSED */
656 /* always use smooth shading even for flat faces, else vertex colors wont interpolate */
657 glShadeModel(GL_SMOOTH);
659 for (i=0,eve=em->verts.first; eve; eve= eve->next)
660 eve->tmp.l = (intptr_t) i++;
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); \
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]); \
671 for (b = 0; b < attribs.totmcol; b++) { \
672 MCol *cp = (MCol*)((char*)efa->data + attribs.mcol[b].emOffset); \
674 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a; \
675 glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col); \
677 if (attribs.tottang) { \
678 float *tang = attribs.tang.array[i*4 + vert]; \
679 glVertexAttrib4fvARB(attribs.tang.glIndex, tang); \
683 for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) {
684 int drawSmooth= (efa->flag & ME_SMOOTH);
686 if (setDrawOptions && !setDrawOptions(userData, i))
689 new_matnr = efa->mat_nr + 1;
690 if (new_matnr != matnr) {
691 dodraw = setMaterial(matnr = new_matnr, &gattribs);
693 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
697 glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
699 if (vertexCos) glNormal3fv(emdm->faceNos[i]);
700 else glNormal3fv(efa->n);
702 PASSATTRIB(efa, efa->v1, 0);
703 if (vertexCos) glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
704 else glVertex3fv(efa->v1->co);
706 PASSATTRIB(efa, efa->v2, 1);
707 if (vertexCos) glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
708 else glVertex3fv(efa->v2->co);
710 PASSATTRIB(efa, efa->v3, 2);
711 if (vertexCos) glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
712 else glVertex3fv(efa->v3->co);
715 PASSATTRIB(efa, efa->v4, 3);
716 if (vertexCos) glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
717 else glVertex3fv(efa->v4->co);
721 PASSATTRIB(efa, efa->v1, 0);
723 glNormal3fv(vertexNos[(int) efa->v1->tmp.l]);
724 glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
727 glNormal3fv(efa->v1->no);
728 glVertex3fv(efa->v1->co);
731 PASSATTRIB(efa, efa->v2, 1);
733 glNormal3fv(vertexNos[(int) efa->v2->tmp.l]);
734 glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
737 glNormal3fv(efa->v2->no);
738 glVertex3fv(efa->v2->co);
741 PASSATTRIB(efa, efa->v3, 2);
743 glNormal3fv(vertexNos[(int) efa->v3->tmp.l]);
744 glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
747 glNormal3fv(efa->v3->no);
748 glVertex3fv(efa->v3->co);
752 PASSATTRIB(efa, efa->v4, 3);
754 glNormal3fv(vertexNos[(int) efa->v4->tmp.l]);
755 glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
758 glNormal3fv(efa->v4->no);
759 glVertex3fv(efa->v4->co);
769 static void emDM_drawFacesGLSL(
771 int (*setMaterial)(int, void *attribs))
773 dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
776 static void emDM_drawMappedFacesMat(
778 void (*setMaterial)(void *userData, int, void *attribs),
779 int (*setFace)(void *userData, int index), void *userData)
781 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
782 EditMesh *em= emdm->em;
783 float (*vertexCos)[3]= emdm->vertexCos;
784 float (*vertexNos)[3]= emdm->vertexNos;
787 DMVertexAttribs attribs= {{{0}}};
788 GPUVertexAttribs gattribs;
789 int i, b, matnr, new_matnr;
793 /* always use smooth shading even for flat faces, else vertex colors wont interpolate */
794 glShadeModel(GL_SMOOTH);
796 for (i=0,eve=em->verts.first; eve; eve= eve->next)
797 eve->tmp.l = (intptr_t) i++;
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); \
805 glVertexAttrib3fvARB(attribs.orco.glIndex, orco); \
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]); \
812 glVertexAttrib2fvARB(attribs.tface[b].glIndex, _tf->uv[vert]); \
814 for (b = 0; b < attribs.totmcol; b++) { \
815 MCol *cp = (MCol*)((char*)efa->data + attribs.mcol[b].emOffset); \
817 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a; \
818 glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col); \
820 if (attribs.tottang) { \
821 float *tang = attribs.tang.array[i*4 + vert]; \
822 glVertexAttrib4fvARB(attribs.tang.glIndex, tang); \
826 for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) {
827 int drawSmooth= (efa->flag & ME_SMOOTH);
830 if (setFace && !setFace(userData, i))
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);
841 glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
843 if (vertexCos) glNormal3fv(emdm->faceNos[i]);
844 else glNormal3fv(efa->n);
846 PASSATTRIB(efa, efa->v1, 0);
847 if (vertexCos) glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
848 else glVertex3fv(efa->v1->co);
850 PASSATTRIB(efa, efa->v2, 1);
851 if (vertexCos) glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
852 else glVertex3fv(efa->v2->co);
854 PASSATTRIB(efa, efa->v3, 2);
855 if (vertexCos) glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
856 else glVertex3fv(efa->v3->co);
859 PASSATTRIB(efa, efa->v4, 3);
860 if (vertexCos) glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
861 else glVertex3fv(efa->v4->co);
865 PASSATTRIB(efa, efa->v1, 0);
867 glNormal3fv(vertexNos[(int) efa->v1->tmp.l]);
868 glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
871 glNormal3fv(efa->v1->no);
872 glVertex3fv(efa->v1->co);
875 PASSATTRIB(efa, efa->v2, 1);
877 glNormal3fv(vertexNos[(int) efa->v2->tmp.l]);
878 glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
881 glNormal3fv(efa->v2->no);
882 glVertex3fv(efa->v2->co);
885 PASSATTRIB(efa, efa->v3, 2);
887 glNormal3fv(vertexNos[(int) efa->v3->tmp.l]);
888 glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
891 glNormal3fv(efa->v3->no);
892 glVertex3fv(efa->v3->co);
896 PASSATTRIB(efa, efa->v4, 3);
898 glNormal3fv(vertexNos[(int) efa->v4->tmp.l]);
899 glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
902 glNormal3fv(efa->v4->no);
903 glVertex3fv(efa->v4->co);
912 static void emDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
914 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
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);
924 DO_MINMAX(eve->co, min_r, max_r);
929 min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
932 static int emDM_getNumVerts(DerivedMesh *dm)
934 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
936 return BLI_countlist(&emdm->em->verts);
939 static int emDM_getNumEdges(DerivedMesh *dm)
941 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
943 return BLI_countlist(&emdm->em->edges);
946 static int emDM_getNumFaces(DerivedMesh *dm)
948 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
950 return BLI_countlist(&emdm->em->faces);
953 static void emDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3])
955 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
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]);
964 copy_v3_v3(cos_r[i], eve->co);
969 static void emDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
971 EditVert *ev = ((EditMeshDerivedMesh *)dm)->em->verts.first;
974 for (i = 0; i < index; ++i) ev = ev->next;
976 copy_v3_v3(vert_r->co, ev->co);
978 normal_float_to_short_v3(vert_r->no, ev->no);
980 /* TODO what to do with vert_r->flag? */
981 vert_r->bweight = (unsigned char) (ev->bweight*255.0f);
984 static void emDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
986 EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
987 EditEdge *ee = em->edges.first;
988 EditVert *ev, *v1, *v2;
991 for (i = 0; i < index; ++i) ee = ee->next;
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;
1000 /* this needs setup of f2 field */
1001 if (!ee->f2) edge_r->flag |= ME_LOOSEEDGE;
1004 /* goddamn, we have to search all verts to find indices */
1007 for (i = 0, ev = em->verts.first; v1 || v2; i++, ev = ev->next) {
1019 static void emDM_getFace(DerivedMesh *dm, int index, MFace *face_r)
1021 EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
1022 EditFace *ef = em->faces.first;
1023 EditVert *ev, *v1, *v2, *v3, *v4;
1026 for (i = 0; i < index; ++i) ef = ef->next;
1028 face_r->mat_nr = ef->mat_nr;
1029 face_r->flag = ef->flag;
1031 /* goddamn, we have to search all verts to find indices */
1036 if (!v4) face_r->v4 = 0;
1038 for (i = 0, ev = em->verts.first; v1 || v2 || v3 || v4;
1039 i++, ev = ev->next) {
1058 test_index_face(face_r, NULL, 0, ef->v4?4:3);
1061 static void emDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
1063 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
1064 EditVert *ev = emdm->em->verts.first;
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]);
1071 copy_v3_v3(vert_r->co, ev->co);
1073 normal_float_to_short_v3(vert_r->no, ev->no);
1075 /* TODO what to do with vert_r->flag? */
1077 vert_r->bweight = (unsigned char) (ev->bweight*255.0f);
1081 static void emDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r)
1083 EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
1084 EditEdge *ee = em->edges.first;
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;
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;
1100 /* this needs setup of f2 field */
1101 if (!ee->f2) edge_r->flag |= ME_LOOSEEDGE;
1104 edge_r->v1 = (int)ee->v1->tmp.l;
1105 edge_r->v2 = (int)ee->v2->tmp.l;
1109 static void emDM_copyFaceArray(DerivedMesh *dm, MFace *face_r)
1111 EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
1112 EditFace *ef = em->faces.first;
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;
1120 for ( ; ef; ef = ef->next, ++face_r) {
1121 face_r->mat_nr = ef->mat_nr;
1122 face_r->flag = ef->flag;
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;
1130 test_index_face(face_r, NULL, 0, ef->v4?4:3);
1134 static void *emDM_getFaceDataArray(DerivedMesh *dm, int type)
1136 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
1137 EditMesh *em= emdm->em;
1139 char *data, *emdata;
1143 datalayer = DM_get_face_data_layer(dm, type);
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);
1153 /* int offset = em->fdata.layers[index].offset; */ /* UNUSED */
1154 size = CustomData_sizeof(type);
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;
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);
1171 static void emDM_release(DerivedMesh *dm)
1173 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
1175 if (DM_release(dm)) {
1176 if (emdm->vertexCos) {
1177 MEM_freeN(emdm->vertexCos);
1178 MEM_freeN(emdm->vertexNos);
1179 MEM_freeN(emdm->faceNos);
1186 DerivedMesh *editmesh_get_derived(
1188 float (*vertexCos)[3])
1190 EditMeshDerivedMesh *emdm = MEM_callocN(sizeof(*emdm), "emdm");
1192 DM_init(&emdm->dm, DM_TYPE_EDITMESH, BLI_countlist(&em->verts),
1193 BLI_countlist(&em->edges), BLI_countlist(&em->faces));
1195 emdm->dm.getMinMax = emDM_getMinMax;
1197 emdm->dm.getNumVerts = emDM_getNumVerts;
1198 emdm->dm.getNumEdges = emDM_getNumEdges;
1199 emdm->dm.getNumFaces = emDM_getNumFaces;
1201 emdm->dm.getVertCos = emDM_getVertCos;
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;
1211 emdm->dm.foreachMappedVert = emDM_foreachMappedVert;
1212 emdm->dm.foreachMappedEdge = emDM_foreachMappedEdge;
1213 emdm->dm.foreachMappedFaceCenter = emDM_foreachMappedFaceCenter;
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;
1226 emdm->dm.release = emDM_release;
1229 emdm->vertexCos = vertexCos;
1231 if (CustomData_has_layer(&em->vdata, CD_MDEFORMVERT)) {
1235 DM_add_vert_layer(&emdm->dm, CD_MDEFORMVERT, CD_CALLOC, NULL);
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));
1245 int totface = BLI_countlist(&em->faces);
1248 for (i=0,eve=em->verts.first; eve; eve= eve->next)
1249 eve->tmp.l = (intptr_t) i++;
1251 emdm->vertexNos = MEM_callocN(sizeof(*emdm->vertexNos)*i, "emdm_vno");
1252 emdm->faceNos = MEM_mallocN(sizeof(*emdm->faceNos)*totface, "emdm_vno");
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];
1261 float *v4 = vertexCos[(int) efa->v4->tmp.l];
1263 normal_quad_v3( no,v1, v2, v3, v4);
1264 add_v3_v3(emdm->vertexNos[(int) efa->v4->tmp.l], no);
1267 normal_tri_v3( no,v1, v2, v3);
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);
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]);
1285 return (DerivedMesh*) emdm;