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]);
356 if (!skip_normals && !flush && efa->next)
357 flush|= efa->mat_nr != efa->next->mat_nr;
361 poly_prev= GL_ZERO; /* force glBegin */
363 glDisable(GL_POLYGON_STIPPLE);
369 for (i=0,efa= emdm->em->faces.first; efa; i++,efa= efa->next) {
370 int drawSmooth = (efa->flag & ME_SMOOTH);
371 draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, i, &drawSmooth);
373 const GLenum poly_type= efa->v4 ? GL_QUADS:GL_TRIANGLES;
374 if (draw==2) { /* enabled with stipple */
376 if (poly_prev != GL_ZERO) glEnd();
377 poly_prev= GL_ZERO; /* force glBegin */
379 glEnable(GL_POLYGON_STIPPLE);
380 glPolygonStipple(stipple_quarttone);
384 if (poly_type != poly_prev) {
385 if (poly_prev != GL_ZERO) glEnd();
386 glBegin((poly_prev= poly_type));
388 glVertex3fv(efa->v1->co);
389 glVertex3fv(efa->v2->co);
390 glVertex3fv(efa->v3->co);
391 if (poly_type == GL_QUADS) glVertex3fv(efa->v4->co);
394 const GLenum shade_type= drawSmooth ? GL_SMOOTH : GL_FLAT;
395 if (shade_type != shade_prev) {
396 if (poly_prev != GL_ZERO) glEnd();
397 glShadeModel((shade_prev= shade_type)); /* same as below but switch shading */
398 glBegin((poly_prev= poly_type));
400 else if (poly_type != poly_prev) {
401 if (poly_prev != GL_ZERO) glEnd();
402 glBegin((poly_prev= poly_type));
407 glVertex3fv(efa->v1->co);
408 glVertex3fv(efa->v2->co);
409 glVertex3fv(efa->v3->co);
410 if (poly_type == GL_QUADS) glVertex3fv(efa->v4->co);
413 glNormal3fv(efa->v1->no);
414 glVertex3fv(efa->v1->co);
415 glNormal3fv(efa->v2->no);
416 glVertex3fv(efa->v2->co);
417 glNormal3fv(efa->v3->no);
418 glVertex3fv(efa->v3->co);
419 if (poly_type == GL_QUADS) {
420 glNormal3fv(efa->v4->no);
421 glVertex3fv(efa->v4->co);
427 if (!skip_normals && !flush && efa->next)
428 flush|= efa->mat_nr != efa->next->mat_nr;
432 poly_prev= GL_ZERO; /* force glBegin */
434 glDisable(GL_POLYGON_STIPPLE);
440 /* if non zero we know a face was rendered */
441 if (poly_prev != GL_ZERO) glEnd();
444 static void emDM_drawFacesTex_common(
446 int (*drawParams)(MTFace *tface, int has_mcol, int matnr),
447 int (*drawParamsMapped)(void *userData, int index),
448 int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
451 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
452 EditMesh *em= emdm->em;
453 float (*vertexCos)[3]= emdm->vertexCos;
454 float (*vertexNos)[3]= emdm->vertexNos;
458 (void) compareDrawOptions;
460 /* always use smooth shading even for flat faces, else vertex colors wont interpolate */
461 glShadeModel(GL_SMOOTH);
466 for (i=0,eve=em->verts.first; eve; eve= eve->next)
467 eve->tmp.l = (intptr_t) i++;
469 for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) {
470 MTFace *tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
471 MCol *mcol= CustomData_em_get(&em->fdata, efa->data, CD_MCOL);
472 unsigned char *cp= NULL;
473 int drawSmooth= (efa->flag & ME_SMOOTH);
477 flag= drawParams(tf, (mcol != NULL), efa->mat_nr);
478 else if (drawParamsMapped)
479 flag= drawParamsMapped(userData, i);
483 if (flag != 0) { /* flag 0 == the face is hidden or invisible */
485 /* we always want smooth here since otherwise vertex colors dont interpolate */
488 cp= (unsigned char*)mcol;
492 glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
495 glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
497 glNormal3fv(emdm->faceNos[i]);
499 if (tf) glTexCoord2fv(tf->uv[0]);
500 if (cp) glColor3ub(cp[3], cp[2], cp[1]);
501 glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
503 if (tf) glTexCoord2fv(tf->uv[1]);
504 if (cp) glColor3ub(cp[7], cp[6], cp[5]);
505 glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
507 if (tf) glTexCoord2fv(tf->uv[2]);
508 if (cp) glColor3ub(cp[11], cp[10], cp[9]);
509 glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
512 if (tf) glTexCoord2fv(tf->uv[3]);
513 if (cp) glColor3ub(cp[15], cp[14], cp[13]);
514 glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
518 if (tf) glTexCoord2fv(tf->uv[0]);
519 if (cp) glColor3ub(cp[3], cp[2], cp[1]);
520 glNormal3fv(vertexNos[(int) efa->v1->tmp.l]);
521 glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
523 if (tf) glTexCoord2fv(tf->uv[1]);
524 if (cp) glColor3ub(cp[7], cp[6], cp[5]);
525 glNormal3fv(vertexNos[(int) efa->v2->tmp.l]);
526 glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
528 if (tf) glTexCoord2fv(tf->uv[2]);
529 if (cp) glColor3ub(cp[11], cp[10], cp[9]);
530 glNormal3fv(vertexNos[(int) efa->v3->tmp.l]);
531 glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
534 if (tf) glTexCoord2fv(tf->uv[3]);
535 if (cp) glColor3ub(cp[15], cp[14], cp[13]);
536 glNormal3fv(vertexNos[(int) efa->v4->tmp.l]);
537 glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
545 for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) {
546 MTFace *tf= CustomData_em_get(&em->fdata, efa->data, CD_MTFACE);
547 MCol *mcol= CustomData_em_get(&em->fdata, efa->data, CD_MCOL);
548 unsigned char *cp= NULL;
549 int drawSmooth= (efa->flag & ME_SMOOTH);
553 flag= drawParams(tf, (mcol != NULL), efa->mat_nr);
554 else if (drawParamsMapped)
555 flag= drawParamsMapped(userData, i);
559 if (flag != 0) { /* flag 0 == the face is hidden or invisible */
561 /* we always want smooth here since otherwise vertex colors dont interpolate */
564 cp= (unsigned char*)mcol;
568 glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
571 glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
575 if (tf) glTexCoord2fv(tf->uv[0]);
576 if (cp) glColor3ub(cp[3], cp[2], cp[1]);
577 glVertex3fv(efa->v1->co);
579 if (tf) glTexCoord2fv(tf->uv[1]);
580 if (cp) glColor3ub(cp[7], cp[6], cp[5]);
581 glVertex3fv(efa->v2->co);
583 if (tf) glTexCoord2fv(tf->uv[2]);
584 if (cp) glColor3ub(cp[11], cp[10], cp[9]);
585 glVertex3fv(efa->v3->co);
588 if (tf) glTexCoord2fv(tf->uv[3]);
589 if (cp) glColor3ub(cp[15], cp[14], cp[13]);
590 glVertex3fv(efa->v4->co);
594 if (tf) glTexCoord2fv(tf->uv[0]);
595 if (cp) glColor3ub(cp[3], cp[2], cp[1]);
596 glNormal3fv(efa->v1->no);
597 glVertex3fv(efa->v1->co);
599 if (tf) glTexCoord2fv(tf->uv[1]);
600 if (cp) glColor3ub(cp[7], cp[6], cp[5]);
601 glNormal3fv(efa->v2->no);
602 glVertex3fv(efa->v2->co);
604 if (tf) glTexCoord2fv(tf->uv[2]);
605 if (cp) glColor3ub(cp[11], cp[10], cp[9]);
606 glNormal3fv(efa->v3->no);
607 glVertex3fv(efa->v3->co);
610 if (tf) glTexCoord2fv(tf->uv[3]);
611 if (cp) glColor3ub(cp[15], cp[14], cp[13]);
612 glNormal3fv(efa->v4->no);
613 glVertex3fv(efa->v4->co);
622 static void emDM_drawFacesTex(
624 int (*setDrawOptions)(MTFace *tface, int has_mcol, int matnr),
625 int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
628 emDM_drawFacesTex_common(dm, setDrawOptions, NULL, compareDrawOptions, userData);
631 static void emDM_drawMappedFacesTex(
633 int (*setDrawOptions)(void *userData, int index),
634 int (*compareDrawOptions)(void *userData, int cur_index, int next_index),
637 emDM_drawFacesTex_common(dm, NULL, setDrawOptions, compareDrawOptions, userData);
640 static void emDM_drawMappedFacesGLSL(
642 int (*setMaterial)(int, void *attribs),
643 int (*setDrawOptions)(void *userData, int index),
646 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
647 EditMesh *em= emdm->em;
648 float (*vertexCos)[3]= emdm->vertexCos;
649 float (*vertexNos)[3]= emdm->vertexNos;
652 DMVertexAttribs attribs= {{{0}}};
653 GPUVertexAttribs gattribs;
654 /* int tfoffset; */ /* UNUSED */
655 int i, b, matnr, new_matnr, dodraw /* , layer */ /* UNUSED */;
660 /* layer = CustomData_get_layer_index(&em->fdata, CD_MTFACE); */ /* UNUSED */
661 /* tfoffset = (layer == -1)? -1: em->fdata.layers[layer].offset; */ /* UNUSED */
663 /* always use smooth shading even for flat faces, else vertex colors wont interpolate */
664 glShadeModel(GL_SMOOTH);
666 for (i=0,eve=em->verts.first; eve; eve= eve->next)
667 eve->tmp.l = (intptr_t) i++;
669 #define PASSATTRIB(efa, eve, vert) { \
670 if (attribs.totorco) { \
671 float *orco = attribs.orco.array[eve->tmp.l]; \
672 glVertexAttrib3fvARB(attribs.orco.glIndex, orco); \
674 for (b = 0; b < attribs.tottface; b++) { \
675 MTFace *_tf = (MTFace*)((char*)efa->data + attribs.tface[b].emOffset); \
676 glVertexAttrib2fvARB(attribs.tface[b].glIndex, _tf->uv[vert]); \
678 for (b = 0; b < attribs.totmcol; b++) { \
679 MCol *cp = (MCol*)((char*)efa->data + attribs.mcol[b].emOffset); \
681 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a; \
682 glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col); \
684 if (attribs.tottang) { \
685 float *tang = attribs.tang.array[i*4 + vert]; \
686 glVertexAttrib4fvARB(attribs.tang.glIndex, tang); \
690 for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) {
691 int drawSmooth= (efa->flag & ME_SMOOTH);
693 if (setDrawOptions && !setDrawOptions(userData, i))
696 new_matnr = efa->mat_nr + 1;
697 if (new_matnr != matnr) {
698 dodraw = setMaterial(matnr = new_matnr, &gattribs);
700 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
704 glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
706 if (vertexCos) glNormal3fv(emdm->faceNos[i]);
707 else glNormal3fv(efa->n);
709 PASSATTRIB(efa, efa->v1, 0);
710 if (vertexCos) glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
711 else glVertex3fv(efa->v1->co);
713 PASSATTRIB(efa, efa->v2, 1);
714 if (vertexCos) glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
715 else glVertex3fv(efa->v2->co);
717 PASSATTRIB(efa, efa->v3, 2);
718 if (vertexCos) glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
719 else glVertex3fv(efa->v3->co);
722 PASSATTRIB(efa, efa->v4, 3);
723 if (vertexCos) glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
724 else glVertex3fv(efa->v4->co);
728 PASSATTRIB(efa, efa->v1, 0);
730 glNormal3fv(vertexNos[(int) efa->v1->tmp.l]);
731 glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
734 glNormal3fv(efa->v1->no);
735 glVertex3fv(efa->v1->co);
738 PASSATTRIB(efa, efa->v2, 1);
740 glNormal3fv(vertexNos[(int) efa->v2->tmp.l]);
741 glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
744 glNormal3fv(efa->v2->no);
745 glVertex3fv(efa->v2->co);
748 PASSATTRIB(efa, efa->v3, 2);
750 glNormal3fv(vertexNos[(int) efa->v3->tmp.l]);
751 glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
754 glNormal3fv(efa->v3->no);
755 glVertex3fv(efa->v3->co);
759 PASSATTRIB(efa, efa->v4, 3);
761 glNormal3fv(vertexNos[(int) efa->v4->tmp.l]);
762 glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
765 glNormal3fv(efa->v4->no);
766 glVertex3fv(efa->v4->co);
776 static void emDM_drawFacesGLSL(
778 int (*setMaterial)(int, void *attribs))
780 dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
783 static void emDM_drawMappedFacesMat(
785 void (*setMaterial)(void *userData, int, void *attribs),
786 int (*setFace)(void *userData, int index), void *userData)
788 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
789 EditMesh *em= emdm->em;
790 float (*vertexCos)[3]= emdm->vertexCos;
791 float (*vertexNos)[3]= emdm->vertexNos;
794 DMVertexAttribs attribs= {{{0}}};
795 GPUVertexAttribs gattribs;
796 int i, b, matnr, new_matnr;
800 /* always use smooth shading even for flat faces, else vertex colors wont interpolate */
801 glShadeModel(GL_SMOOTH);
803 for (i=0,eve=em->verts.first; eve; eve= eve->next)
804 eve->tmp.l = (intptr_t) i++;
806 #define PASSATTRIB(efa, eve, vert) { \
807 if (attribs.totorco) { \
808 float *orco = attribs.orco.array[eve->tmp.l]; \
809 if (attribs.orco.glTexco) \
810 glTexCoord3fv(orco); \
812 glVertexAttrib3fvARB(attribs.orco.glIndex, orco); \
814 for (b = 0; b < attribs.tottface; b++) { \
815 MTFace *_tf = (MTFace*)((char*)efa->data + attribs.tface[b].emOffset); \
816 if (attribs.tface[b].glTexco) \
817 glTexCoord2fv(_tf->uv[vert]); \
819 glVertexAttrib2fvARB(attribs.tface[b].glIndex, _tf->uv[vert]); \
821 for (b = 0; b < attribs.totmcol; b++) { \
822 MCol *cp = (MCol*)((char*)efa->data + attribs.mcol[b].emOffset); \
824 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a; \
825 glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col); \
827 if (attribs.tottang) { \
828 float *tang = attribs.tang.array[i*4 + vert]; \
829 glVertexAttrib4fvARB(attribs.tang.glIndex, tang); \
833 for (i=0,efa= em->faces.first; efa; i++,efa= efa->next) {
834 int drawSmooth= (efa->flag & ME_SMOOTH);
837 if (setFace && !setFace(userData, i))
841 new_matnr = efa->mat_nr + 1;
842 if (new_matnr != matnr) {
843 setMaterial(userData, matnr = new_matnr, &gattribs);
844 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
848 glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
850 if (vertexCos) glNormal3fv(emdm->faceNos[i]);
851 else glNormal3fv(efa->n);
853 PASSATTRIB(efa, efa->v1, 0);
854 if (vertexCos) glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
855 else glVertex3fv(efa->v1->co);
857 PASSATTRIB(efa, efa->v2, 1);
858 if (vertexCos) glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
859 else glVertex3fv(efa->v2->co);
861 PASSATTRIB(efa, efa->v3, 2);
862 if (vertexCos) glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
863 else glVertex3fv(efa->v3->co);
866 PASSATTRIB(efa, efa->v4, 3);
867 if (vertexCos) glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
868 else glVertex3fv(efa->v4->co);
872 PASSATTRIB(efa, efa->v1, 0);
874 glNormal3fv(vertexNos[(int) efa->v1->tmp.l]);
875 glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
878 glNormal3fv(efa->v1->no);
879 glVertex3fv(efa->v1->co);
882 PASSATTRIB(efa, efa->v2, 1);
884 glNormal3fv(vertexNos[(int) efa->v2->tmp.l]);
885 glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
888 glNormal3fv(efa->v2->no);
889 glVertex3fv(efa->v2->co);
892 PASSATTRIB(efa, efa->v3, 2);
894 glNormal3fv(vertexNos[(int) efa->v3->tmp.l]);
895 glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
898 glNormal3fv(efa->v3->no);
899 glVertex3fv(efa->v3->co);
903 PASSATTRIB(efa, efa->v4, 3);
905 glNormal3fv(vertexNos[(int) efa->v4->tmp.l]);
906 glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
909 glNormal3fv(efa->v4->no);
910 glVertex3fv(efa->v4->co);
919 static void emDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
921 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
925 if (emdm->em->verts.first) {
926 for (i=0,eve= emdm->em->verts.first; eve; i++,eve= eve->next) {
927 if (emdm->vertexCos) {
928 DO_MINMAX(emdm->vertexCos[i], min_r, max_r);
931 DO_MINMAX(eve->co, min_r, max_r);
936 min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
939 static int emDM_getNumVerts(DerivedMesh *dm)
941 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
943 return BLI_countlist(&emdm->em->verts);
946 static int emDM_getNumEdges(DerivedMesh *dm)
948 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
950 return BLI_countlist(&emdm->em->edges);
953 static int emDM_getNumFaces(DerivedMesh *dm)
955 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
957 return BLI_countlist(&emdm->em->faces);
960 static void emDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3])
962 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
966 for (i=0,eve= emdm->em->verts.first; eve; i++,eve=eve->next) {
967 if (emdm->vertexCos) {
968 copy_v3_v3(cos_r[i], emdm->vertexCos[i]);
971 copy_v3_v3(cos_r[i], eve->co);
976 static void emDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
978 EditVert *ev = ((EditMeshDerivedMesh *)dm)->em->verts.first;
981 for (i = 0; i < index; ++i) ev = ev->next;
983 copy_v3_v3(vert_r->co, ev->co);
985 normal_float_to_short_v3(vert_r->no, ev->no);
987 /* TODO what to do with vert_r->flag? */
988 vert_r->bweight = (unsigned char) (ev->bweight*255.0f);
991 static void emDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
993 EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
994 EditEdge *ee = em->edges.first;
995 EditVert *ev, *v1, *v2;
998 for (i = 0; i < index; ++i) ee = ee->next;
1000 edge_r->crease = (unsigned char) (ee->crease*255.0f);
1001 edge_r->bweight = (unsigned char) (ee->bweight*255.0f);
1002 /* TODO what to do with edge_r->flag? */
1003 edge_r->flag = ME_EDGEDRAW|ME_EDGERENDER;
1004 if (ee->seam) edge_r->flag |= ME_SEAM;
1005 if (ee->sharp) edge_r->flag |= ME_SHARP;
1007 /* this needs setup of f2 field */
1008 if (!ee->f2) edge_r->flag |= ME_LOOSEEDGE;
1011 /* goddamn, we have to search all verts to find indices */
1014 for (i = 0, ev = em->verts.first; v1 || v2; i++, ev = ev->next) {
1026 static void emDM_getFace(DerivedMesh *dm, int index, MFace *face_r)
1028 EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
1029 EditFace *ef = em->faces.first;
1030 EditVert *ev, *v1, *v2, *v3, *v4;
1033 for (i = 0; i < index; ++i) ef = ef->next;
1035 face_r->mat_nr = ef->mat_nr;
1036 face_r->flag = ef->flag;
1038 /* goddamn, we have to search all verts to find indices */
1043 if (!v4) face_r->v4 = 0;
1045 for (i = 0, ev = em->verts.first; v1 || v2 || v3 || v4;
1046 i++, ev = ev->next) {
1065 test_index_face(face_r, NULL, 0, ef->v4?4:3);
1068 static void emDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
1070 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
1071 EditVert *ev = emdm->em->verts.first;
1074 for (i=0; ev; ev = ev->next, ++vert_r, ++i) {
1075 if (emdm->vertexCos)
1076 copy_v3_v3(vert_r->co, emdm->vertexCos[i]);
1078 copy_v3_v3(vert_r->co, ev->co);
1080 normal_float_to_short_v3(vert_r->no, ev->no);
1082 /* TODO what to do with vert_r->flag? */
1084 vert_r->bweight = (unsigned char) (ev->bweight*255.0f);
1088 static void emDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r)
1090 EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
1091 EditEdge *ee = em->edges.first;
1095 /* store vertex indices in tmp union */
1096 for (ev = em->verts.first, i = 0; ev; ev = ev->next, ++i)
1097 ev->tmp.l = (intptr_t) i;
1099 for ( ; ee; ee = ee->next, ++edge_r) {
1100 edge_r->crease = (unsigned char) (ee->crease*255.0f);
1101 edge_r->bweight = (unsigned char) (ee->bweight*255.0f);
1102 /* TODO what to do with edge_r->flag? */
1103 edge_r->flag = ME_EDGEDRAW|ME_EDGERENDER;
1104 if (ee->seam) edge_r->flag |= ME_SEAM;
1105 if (ee->sharp) edge_r->flag |= ME_SHARP;
1107 /* this needs setup of f2 field */
1108 if (!ee->f2) edge_r->flag |= ME_LOOSEEDGE;
1111 edge_r->v1 = (int)ee->v1->tmp.l;
1112 edge_r->v2 = (int)ee->v2->tmp.l;
1116 static void emDM_copyFaceArray(DerivedMesh *dm, MFace *face_r)
1118 EditMesh *em = ((EditMeshDerivedMesh *)dm)->em;
1119 EditFace *ef = em->faces.first;
1123 /* store vertexes indices in tmp union */
1124 for (ev = em->verts.first, i = 0; ev; ev = ev->next, ++i)
1125 ev->tmp.l = (intptr_t) i;
1127 for ( ; ef; ef = ef->next, ++face_r) {
1128 face_r->mat_nr = ef->mat_nr;
1129 face_r->flag = ef->flag;
1131 face_r->v1 = (int)ef->v1->tmp.l;
1132 face_r->v2 = (int)ef->v2->tmp.l;
1133 face_r->v3 = (int)ef->v3->tmp.l;
1134 if (ef->v4) face_r->v4 = (int)ef->v4->tmp.l;
1135 else face_r->v4 = 0;
1137 test_index_face(face_r, NULL, 0, ef->v4?4:3);
1141 static void *emDM_getFaceDataArray(DerivedMesh *dm, int type)
1143 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
1144 EditMesh *em= emdm->em;
1146 char *data, *emdata;
1150 datalayer = DM_get_face_data_layer(dm, type);
1154 /* layers are store per face for editmesh, we convert to a temporary
1155 * data layer array in the derivedmesh when these are requested */
1156 if (type == CD_MTFACE || type == CD_MCOL) {
1157 index = CustomData_get_layer_index(&em->fdata, type);
1160 /* int offset = em->fdata.layers[index].offset; */ /* UNUSED */
1161 size = CustomData_sizeof(type);
1163 DM_add_face_layer(dm, type, CD_CALLOC, NULL);
1164 index = CustomData_get_layer_index(&dm->faceData, type);
1165 dm->faceData.layers[index].flag |= CD_FLAG_TEMPORARY;
1167 data = datalayer = DM_get_face_data_layer(dm, type);
1168 for (efa=em->faces.first; efa; efa=efa->next, data+=size) {
1169 emdata = CustomData_em_get(&em->fdata, efa->data, type);
1170 memcpy(data, emdata, size);
1178 static void emDM_release(DerivedMesh *dm)
1180 EditMeshDerivedMesh *emdm= (EditMeshDerivedMesh*) dm;
1182 if (DM_release(dm)) {
1183 if (emdm->vertexCos) {
1184 MEM_freeN(emdm->vertexCos);
1185 MEM_freeN(emdm->vertexNos);
1186 MEM_freeN(emdm->faceNos);
1193 DerivedMesh *editmesh_get_derived(
1195 float (*vertexCos)[3])
1197 EditMeshDerivedMesh *emdm = MEM_callocN(sizeof(*emdm), "emdm");
1199 DM_init(&emdm->dm, DM_TYPE_EDITMESH, BLI_countlist(&em->verts),
1200 BLI_countlist(&em->edges), BLI_countlist(&em->faces));
1202 emdm->dm.getMinMax = emDM_getMinMax;
1204 emdm->dm.getNumVerts = emDM_getNumVerts;
1205 emdm->dm.getNumEdges = emDM_getNumEdges;
1206 emdm->dm.getNumFaces = emDM_getNumFaces;
1208 emdm->dm.getVertCos = emDM_getVertCos;
1210 emdm->dm.getVert = emDM_getVert;
1211 emdm->dm.getEdge = emDM_getEdge;
1212 emdm->dm.getFace = emDM_getFace;
1213 emdm->dm.copyVertArray = emDM_copyVertArray;
1214 emdm->dm.copyEdgeArray = emDM_copyEdgeArray;
1215 emdm->dm.copyFaceArray = emDM_copyFaceArray;
1216 emdm->dm.getFaceDataArray = emDM_getFaceDataArray;
1218 emdm->dm.foreachMappedVert = emDM_foreachMappedVert;
1219 emdm->dm.foreachMappedEdge = emDM_foreachMappedEdge;
1220 emdm->dm.foreachMappedFaceCenter = emDM_foreachMappedFaceCenter;
1222 emdm->dm.drawEdges = emDM_drawEdges;
1223 emdm->dm.drawMappedEdges = emDM_drawMappedEdges;
1224 emdm->dm.drawMappedEdgesInterp = emDM_drawMappedEdgesInterp;
1225 emdm->dm.drawMappedFaces = emDM_drawMappedFaces;
1226 emdm->dm.drawMappedFacesTex = emDM_drawMappedFacesTex;
1227 emdm->dm.drawMappedFacesGLSL = emDM_drawMappedFacesGLSL;
1228 emdm->dm.drawFacesTex = emDM_drawFacesTex;
1229 emdm->dm.drawFacesGLSL = emDM_drawFacesGLSL;
1230 emdm->dm.drawMappedFacesMat = emDM_drawMappedFacesMat;
1231 emdm->dm.drawUVEdges = emDM_drawUVEdges;
1233 emdm->dm.release = emDM_release;
1236 emdm->vertexCos = vertexCos;
1238 if (CustomData_has_layer(&em->vdata, CD_MDEFORMVERT)) {
1242 DM_add_vert_layer(&emdm->dm, CD_MDEFORMVERT, CD_CALLOC, NULL);
1244 for (eve = em->verts.first, i = 0; eve; eve = eve->next, ++i)
1245 DM_set_vert_data(&emdm->dm, i, CD_MDEFORMVERT,
1246 CustomData_em_get(&em->vdata, eve->data, CD_MDEFORMVERT));
1252 int totface = BLI_countlist(&em->faces);
1255 for (i=0,eve=em->verts.first; eve; eve= eve->next)
1256 eve->tmp.l = (intptr_t) i++;
1258 emdm->vertexNos = MEM_callocN(sizeof(*emdm->vertexNos)*i, "emdm_vno");
1259 emdm->faceNos = MEM_mallocN(sizeof(*emdm->faceNos)*totface, "emdm_vno");
1261 for (i=0, efa= em->faces.first; efa; i++, efa=efa->next) {
1262 float *v1 = vertexCos[(int) efa->v1->tmp.l];
1263 float *v2 = vertexCos[(int) efa->v2->tmp.l];
1264 float *v3 = vertexCos[(int) efa->v3->tmp.l];
1265 float *no = emdm->faceNos[i];
1268 float *v4 = vertexCos[(int) efa->v4->tmp.l];
1270 normal_quad_v3( no,v1, v2, v3, v4);
1271 add_v3_v3(emdm->vertexNos[(int) efa->v4->tmp.l], no);
1274 normal_tri_v3( no,v1, v2, v3);
1277 add_v3_v3(emdm->vertexNos[(int) efa->v1->tmp.l], no);
1278 add_v3_v3(emdm->vertexNos[(int) efa->v2->tmp.l], no);
1279 add_v3_v3(emdm->vertexNos[(int) efa->v3->tmp.l], no);
1282 for (i=0, eve= em->verts.first; eve; i++, eve=eve->next) {
1283 float *no = emdm->vertexNos[i];
1284 /* following Mesh convention; we use vertex coordinate itself
1285 * for normal in this case */
1286 if (normalize_v3(no) == 0.0f) {
1287 normalize_v3_v3(no, vertexCos[i]);
1292 return (DerivedMesh*) emdm;