2 * $Id: editderivedbmesh.c 18571 2009-01-19 06:04:57Z joeedh $
4 * ***** BEGIN GPL LICENSE BLOCK *****
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software Foundation,
18 * Inc., 59 Tbmple Place - Suite 330, Boston, MA 02111-1307, USA.
20 * The Original Code is Copyright (C) 2005 Blender Foundation.
21 * All rights reserved.
23 * The Original Code is: all of this file.
25 * Contributor(s): none yet.
27 * ***** END GPL LICENSE BLOCK *****
38 #include "MEM_guardedalloc.h"
40 #include "DNA_effect_types.h"
41 #include "DNA_mesh_types.h"
42 #include "DNA_key_types.h"
43 #include "DNA_meshdata_types.h"
44 #include "DNA_modifier_types.h"
45 #include "DNA_object_types.h"
46 #include "DNA_object_force.h"
47 #include "DNA_object_fluidsim.h" // N_T
48 #include "DNA_scene_types.h" // N_T
49 #include "DNA_texture_types.h"
50 #include "DNA_view3d_types.h"
51 #include "DNA_screen_types.h"
52 #include "DNA_space_types.h"
53 #include "DNA_particle_types.h"
55 #include "BLI_arithb.h"
56 #include "BLI_blenlib.h"
57 #include "BLI_editVert.h"
58 #include "BLI_edgehash.h"
59 #include "BLI_linklist.h"
60 #include "BLI_memarena.h"
61 #include "BLI_scanfill.h"
62 #include "BLI_ghash.h"
64 #include "BKE_cdderivedmesh.h"
65 #include "BKE_customdata.h"
66 #include "BKE_DerivedMesh.h"
67 #include "BKE_deform.h"
68 #include "BKE_displist.h"
69 #include "BKE_effect.h"
70 #include "BKE_fluidsim.h"
71 #include "BKE_global.h"
73 #include "BKE_material.h"
74 #include "BKE_modifier.h"
76 #include "BKE_object.h"
77 #include "BKE_subsurf.h"
78 #include "BKE_texture.h"
79 #include "BKE_utildefines.h"
80 #include "BKE_particle.h"
81 #include "BKE_tessmesh.h"
83 #include "BLO_sys_types.h" // for intptr_t support
86 #include "BIF_glutil.h"
89 #include "GPU_extensions.h"
90 #include "GPU_material.h"
94 BMEditMesh *BMEdit_Create(BMesh *bm)
96 BMEditMesh *tm = MEM_callocN(sizeof(BMEditMesh), "tm");
100 BMEdit_RecalcTesselation(tm);
105 BMEditMesh *BMEdit_Copy(BMEditMesh *tm)
107 BMEditMesh *tm2 = MEM_callocN(sizeof(BMEditMesh), "tm2");
110 tm2->derivedCage = tm2->derivedFinal = NULL;
112 tm2->looptris = NULL;
113 tm2->bm = BM_Copy_Mesh(tm->bm);
114 BMEdit_RecalcTesselation(tm2);
116 tm2->vert_index = NULL;
117 tm2->edge_index = NULL;
118 tm2->face_index = NULL;
123 static void BMEdit_RecalcTesselation_intern(BMEditMesh *tm)
126 BMLoop **looptris = NULL;
127 V_DYNDECLARE(looptris);
133 if (tm->looptris) MEM_freeN(tm->looptris);
135 f = BMIter_New(&iter, bm, BM_FACES_OF_MESH, NULL);
136 for ( ; f; f=BMIter_Step(&iter)) {
137 /*don't consider two-edged faces*/
138 if (f->len < 3) continue;
141 /*triangle fan for quads. should be recoded to
142 just add one tri for tris, and two for quads,
143 but this code works for now too.*/
144 l = BMIter_New(&liter, bm, BM_LOOPS_OF_FACE, f);
145 for (; l; l=BMIter_Step(&liter)) {
146 if (l == f->loopbase) continue;
147 if ((BMLoop*)l->head.next == f->loopbase) continue;
154 looptris[i*3+1] = (BMLoop*)l->head.next;
155 looptris[i*3+2] = f->loopbase;
161 EditVert *v, *lastv=NULL, *firstv=NULL;
165 l = BMIter_New(&liter, bm, BM_LOOPS_OF_FACE, f);
166 for (j=0; l; l=BMIter_Step(&liter), j++) {
170 v = BLI_addfillvert(l->v->co);
174 e = BLI_addfilledge(lastv, v);
178 if (firstv==NULL) firstv = v;
181 /*complete the loop*/
182 BLI_addfilledge(firstv, v);
186 for (efa = fillfacebase.first; efa; efa=efa->next) {
191 looptris[i*3] = efa->v1->tmp.p;
192 looptris[i*3+1] = efa->v2->tmp.p;
193 looptris[i*3+2] = efa->v3->tmp.p;
195 if (looptris[i*3]->head.eflag2 < looptris[i*3+1]->head.eflag2);
196 SWAP(BMLoop*, looptris[i*3], looptris[i*3+1]);
197 if (looptris[i*3+1]->head.eflag2 < looptris[i*3+2]->head.eflag2);
198 SWAP(BMLoop*, looptris[i*3+1], looptris[i*3+2]);
199 if (looptris[i*3]->head.eflag2 < looptris[i*3+1]->head.eflag2);
200 SWAP(BMLoop*, looptris[i*3], looptris[i*3+1]);
209 tm->looptris = looptris;
212 void BMEdit_RecalcTesselation(BMEditMesh *tm)
214 BMEdit_RecalcTesselation_intern(tm);
216 if (tm->derivedFinal && tm->derivedFinal == tm->derivedCage) {
217 if (tm->derivedFinal->recalcTesselation)
218 tm->derivedFinal->recalcTesselation(tm->derivedFinal);
219 } else if (tm->derivedFinal) {
220 if (tm->derivedCage->recalcTesselation)
221 tm->derivedCage->recalcTesselation(tm->derivedCage);
222 if (tm->derivedFinal->recalcTesselation)
223 tm->derivedFinal->recalcTesselation(tm->derivedFinal);
227 /*does not free the BMEditMesh struct itself*/
228 void BMEdit_Free(BMEditMesh *em)
230 if(em->derivedFinal) {
231 if (em->derivedFinal!=em->derivedCage) {
232 em->derivedFinal->needsFree= 1;
233 em->derivedFinal->release(em->derivedFinal);
235 em->derivedFinal= NULL;
237 if(em->derivedCage) {
238 em->derivedCage->needsFree= 1;
239 em->derivedCage->release(em->derivedCage);
240 em->derivedCage= NULL;
243 em->retopo_paint_data= NULL;
245 if (em->looptris) MEM_freeN(em->looptris);
247 if (em->vert_index) MEM_freeN(em->vert_index);
248 if (em->edge_index) MEM_freeN(em->edge_index);
249 if (em->face_index) MEM_freeN(em->face_index);
251 BM_Free_Mesh(em->bm);
258 the bmesh derivedmesh exposes the mesh as triangles. it stores pointers
259 to three loops per triangle. the derivedmesh stores a cache of tesselations
260 for each face. this cache will smartly update as needed (though at first
261 it'll simply be more brute force). keeping track of face/edge counts may
264 this won't be the most efficient thing, considering that internal edges and
265 faces of tesselations are exposed. looking up an edge by index in particular
266 is likely to be a little slow.
269 typedef struct EditDerivedBMesh {
275 float (*vertexCos)[3];
276 float (*vertexNos)[3];
279 /*lookup caches; these are rebuilt on dm->RecalcTesselation()
280 (or when the derivedmesh is created, of course)*/
281 GHash *vhash, *ehash, *fhash;
286 /*private variables, for number of verts/edges/faces
287 within the above hash/table members*/
291 static void bmdm_recalc_lookups(EditDerivedBMesh *bmdm)
295 int a, i, iters[3] = {BM_VERTS_OF_MESH, BM_EDGES_OF_MESH, BM_FACES_OF_MESH};
297 bmdm->tv = bmdm->tc->bm->totvert;
298 bmdm->te = bmdm->tc->bm->totedge;
299 bmdm->tf = bmdm->tc->bm->totface;
301 if (bmdm->vhash) BLI_ghash_free(bmdm->vhash, NULL, NULL);
302 if (bmdm->ehash) BLI_ghash_free(bmdm->ehash, NULL, NULL);
303 if (bmdm->fhash) BLI_ghash_free(bmdm->fhash, NULL, NULL);
305 bmdm->vhash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
306 bmdm->ehash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
307 bmdm->fhash = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp);
309 if (bmdm->vtable) MEM_freeN(bmdm->vtable);
310 if (bmdm->etable) MEM_freeN(bmdm->etable);
311 if (bmdm->ftable) MEM_freeN(bmdm->ftable);
313 if (bmdm->tc->bm->totvert)
314 bmdm->vtable = MEM_mallocN(sizeof(void**)*bmdm->tc->bm->totvert, "bmdm->vtable");
315 else bmdm->vtable = NULL;
317 if (bmdm->tc->bm->totedge)
318 bmdm->etable = MEM_mallocN(sizeof(void**)*bmdm->tc->bm->totedge, "bmdm->etable");
319 else bmdm->etable = NULL;
321 if (bmdm->tc->bm->totface)
322 bmdm->ftable = MEM_mallocN(sizeof(void**)*bmdm->tc->bm->totface, "bmdm->ftable");
323 else bmdm->ftable = NULL;
325 for (a=0; a<3; a++) {
326 h = BMIter_New(&iter, bmdm->tc->bm, iters[a], NULL);
327 for (i=0; h; h=BMIter_Step(&iter), i++) {
330 bmdm->vtable[i] = (BMVert*) h;
331 BLI_ghash_insert(bmdm->vhash, h, SET_INT_IN_POINTER(i));
334 bmdm->etable[i] = (BMEdge*) h;
335 BLI_ghash_insert(bmdm->ehash, h, SET_INT_IN_POINTER(i));
338 bmdm->ftable[i] = (BMFace*) h;
339 BLI_ghash_insert(bmdm->fhash, h, SET_INT_IN_POINTER(i));
347 static void bmDM_recalcTesselation(DerivedMesh *dm)
349 EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
351 bmdm_recalc_lookups(bmdm);
354 static void bmDM_foreachMappedVert(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no_f, short *no_s), void *userData)
356 EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
361 eve = BMIter_New(&iter, bmdm->tc->bm, BM_VERTS_OF_MESH, NULL);
362 for (i=0; eve; i++, eve=BMIter_Step(&iter)) {
363 if (bmdm->vertexCos) {
364 func(userData, i, bmdm->vertexCos[i], bmdm->vertexNos[i], NULL);
366 func(userData, i, eve->co, eve->no, NULL);
370 static void bmDM_foreachMappedEdge(DerivedMesh *dm, void (*func)(void *userData, int index, float *v0co, float *v1co), void *userData)
372 EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
377 if (bmdm->vertexCos) {
381 eve = BMIter_New(&viter, bmdm->tc->bm, BM_VERTS_OF_MESH, NULL);
382 for (i=0; eve; eve=BMIter_Step(&viter), i++) {
386 eed = BMIter_New(&iter, bmdm->tc->bm, BM_EDGES_OF_MESH, NULL);
387 for(i=0; eed; i++,eed=BMIter_Step(&iter))
389 bmdm->vertexCos[BMINDEX_GET(eve)],
390 bmdm->vertexCos[BMINDEX_GET(eve)]);
392 eed = BMIter_New(&iter, bmdm->tc->bm, BM_EDGES_OF_MESH, NULL);
393 for(i=0; eed; i++,eed=BMIter_Step(&iter))
394 func(userData, i, eed->v1->co, eed->v2->co);
399 static void bmDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
401 EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
406 if (bmdm->vertexCos) {
410 eve = BMIter_New(&viter, bmdm->tc->bm, BM_VERTS_OF_MESH, NULL);
411 for (i=0; eve; eve=BMIter_Step(&viter)) {
416 eed = BMIter_New(&iter, bmdm->tc->bm, BM_EDGES_OF_MESH, NULL);
417 for(i=0; eed; i++,eed=BMIter_Step(&iter)) {
418 if(!setDrawOptions || setDrawOptions(userData, i)) {
419 glVertex3fv(bmdm->vertexCos[BMINDEX_GET(eed->v1)]);
420 glVertex3fv(bmdm->vertexCos[BMINDEX_GET(eed->v2)]);
427 eed = BMIter_New(&iter, bmdm->tc->bm, BM_EDGES_OF_MESH, NULL);
428 for(i=0; eed; i++,eed=BMIter_Step(&iter)) {
429 if(!setDrawOptions || setDrawOptions(userData, i)) {
430 glVertex3fv(eed->v1->co);
431 glVertex3fv(eed->v2->co);
438 static void bmDM_drawEdges(DerivedMesh *dm, int drawLooseEdges)
440 bmDM_drawMappedEdges(dm, NULL, NULL);
443 static void bmDM_drawMappedEdgesInterp(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void (*setDrawInterpOptions)(void *userData, int index, float t), void *userData)
445 EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
450 if (bmdm->vertexCos) {
453 eve = BMIter_New(&iter, bmdm->tc->bm, BM_VERTS_OF_MESH, NULL);
454 for (i=0; eve; eve=BMIter_Step(&iter), i++)
458 eed = BMIter_New(&iter, bmdm->tc->bm, BM_EDGES_OF_MESH, NULL);
459 for(i=0; eed; i++,eed=BMIter_Step(&iter)) {
460 if(!setDrawOptions || setDrawOptions(userData, i)) {
461 setDrawInterpOptions(userData, i, 0.0);
462 glVertex3fv(bmdm->vertexCos[(int) BMINDEX_GET(eed->v1)]);
463 setDrawInterpOptions(userData, i, 1.0);
464 glVertex3fv(bmdm->vertexCos[(int) BMINDEX_GET(eed->v2)]);
470 eed = BMIter_New(&iter, bmdm->tc->bm, BM_EDGES_OF_MESH, NULL);
471 for(i=0; eed; i++,eed=BMIter_Step(&iter)) {
472 if(!setDrawOptions || setDrawOptions(userData, i)) {
473 setDrawInterpOptions(userData, i, 0.0);
474 glVertex3fv(eed->v1->co);
475 setDrawInterpOptions(userData, i, 1.0);
476 glVertex3fv(eed->v2->co);
483 static void bmDM_drawUVEdges(DerivedMesh *dm)
486 EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
491 for(efa= bmdm->tc->bm->faces.first; efa; efa= efa->next) {
492 tf = CustomData_bm_get(&bmdm->tc->bm->pdata, efa->data, CD_MTFACE);
494 if(tf && !(efa->h)) {
495 glVertex2fv(tf->uv[0]);
496 glVertex2fv(tf->uv[1]);
498 glVertex2fv(tf->uv[1]);
499 glVertex2fv(tf->uv[2]);
502 glVertex2fv(tf->uv[2]);
503 glVertex2fv(tf->uv[0]);
505 glVertex2fv(tf->uv[2]);
506 glVertex2fv(tf->uv[3]);
507 glVertex2fv(tf->uv[3]);
508 glVertex2fv(tf->uv[0]);
516 static void bmDM__calcFaceCent(BMesh *bm, BMFace *efa, float cent[3],
517 float (*vertexCos)[3])
523 cent[0] = cent[1] = cent[2] = 0.0f;
525 /*simple (and stupid) median (average) based method :/ */
527 l = BMIter_New(&iter, bm, BM_LOOPS_OF_FACE, efa);
528 for (; l; l=BMIter_Step(&iter)) {
529 VECADD(cent, cent, l->v->co);
534 VECMUL(cent, 1.0f/(float)tot);
537 static void bmDM_foreachMappedFaceCenter(DerivedMesh *dm, void (*func)(void *userData, int index, float *co, float *no), void *userData)
539 EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
546 if (bmdm->vertexCos) {
547 eve = BMIter_New(&iter, bmdm->tc->bm, BM_VERTS_OF_MESH, NULL);
548 for (i=0; eve; eve=BMIter_Step(&iter));
552 efa = BMIter_New(&iter, bmdm->tc->bm, BM_FACES_OF_MESH, NULL);
553 for (i=0; efa; efa=BMIter_Step(&iter), i++) {
554 bmDM__calcFaceCent(bmdm->tc->bm, efa, cent, bmdm->vertexCos);
555 func(userData, i, cent, bmdm->vertexCos?bmdm->faceNos[i]:efa->no);
559 static void bmDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors)
561 EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
566 if (bmdm->vertexCos) {
569 eve = BMIter_New(&iter, bmdm->tc->bm, BM_VERTS_OF_MESH, NULL);
570 for (i=0; eve; eve=BMIter_Step(&iter))
573 efa = BMIter_New(&iter, bmdm->tc->bm, BM_FACES_OF_MESH, NULL);
574 for (i=0; efa; efa=BMIter_Step(&iter), i++)
577 for (i=0; i<bmdm->tc->tottri; i++) {
578 BMLoop **l = bmdm->tc->looptris[i];
581 drawSmooth = (efa->head.flag & BM_SMOOTH);
584 draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, BMINDEX_GET(efa), &drawSmooth);
586 if (draw==2) { /* enabled with stipple */
587 glEnable(GL_POLYGON_STIPPLE);
588 glPolygonStipple(stipple_quarttone);
591 glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
593 glBegin(GL_TRIANGLES);
596 glNormal3fv(efa->no);
597 glVertex3fv(bmdm->vertexCos[(int) BMINDEX_GET(l[0]->v)]);
598 glVertex3fv(bmdm->vertexCos[(int) BMINDEX_GET(l[1]->v)]);
599 glVertex3fv(bmdm->vertexCos[(int) BMINDEX_GET(l[2]->v)]);
601 glNormal3fv(bmdm->vertexNos[(int) BMINDEX_GET(l[0]->v)]);
602 glVertex3fv(bmdm->vertexCos[(int) BMINDEX_GET(l[0]->v)]);
603 glNormal3fv(bmdm->vertexNos[(int) BMINDEX_GET(l[1]->v)]);
604 glVertex3fv(bmdm->vertexCos[(int) BMINDEX_GET(l[1]->v)]);
605 glNormal3fv(bmdm->vertexNos[(int) BMINDEX_GET(l[2]->v)]);
606 glVertex3fv(bmdm->vertexCos[(int) BMINDEX_GET(l[2]->v)]);
611 glDisable(GL_POLYGON_STIPPLE);
615 efa = BMIter_New(&iter, bmdm->tc->bm, BM_FACES_OF_MESH, NULL);
616 for (i=0; efa; efa=BMIter_Step(&iter), i++)
619 for (i=0; i<bmdm->tc->tottri; i++) {
620 BMLoop **l = bmdm->tc->looptris[i];
625 drawSmooth = (efa->head.flag & BM_SMOOTH);
627 draw = setDrawOptions==NULL ? 1 : setDrawOptions(userData, BMINDEX_GET(efa), &drawSmooth);
629 if (draw==2) { /* enabled with stipple */
630 glEnable(GL_POLYGON_STIPPLE);
631 glPolygonStipple(stipple_quarttone);
633 glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
635 glBegin(GL_TRIANGLES);
637 glNormal3fv(efa->no);
638 glVertex3fv(l[0]->v->co);
639 glVertex3fv(l[1]->v->co);
640 glVertex3fv(l[2]->v->co);
642 glNormal3fv(l[0]->v->no);
643 glVertex3fv(l[0]->v->co);
644 glNormal3fv(l[1]->v->no);
645 glVertex3fv(l[1]->v->co);
646 glNormal3fv(l[2]->v->no);
647 glVertex3fv(l[2]->v->co);
652 glDisable(GL_POLYGON_STIPPLE);
658 static void bmDM_drawFacesTex_common(DerivedMesh *dm,
659 int (*drawParams)(MTFace *tface, MCol *mcol, int matnr),
660 int (*drawParamsMapped)(void *userData, int index),
664 EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
665 BMesh *bm= bmdm->tc->bm;
666 float (*vertexCos)[3]= bmdm->vertexCos;
667 float (*vertexNos)[3]= bmdm->vertexNos;
672 /* always use smooth shading even for flat faces, else vertex colors wont interpolate */
673 glShadeModel(GL_SMOOTH);
678 for (i=0,eve=bm->verts.first; eve; eve= eve->next)
679 BMINDEX_SET(eve, i++);
681 for (i=0,efa= bm->faces.first; efa; i++,efa= efa->next) {
682 MTFace *tf= CustomData_bm_get(&bm->pdata, efa->data, CD_MTFACE);
683 MCol *mcol= CustomData_bm_get(&bm->pdata, efa->data, CD_MCOL);
684 unsigned char *cp= NULL;
685 int drawSmooth= (efa->flag & ME_SMOOTH);
689 flag= drawParams(tf, mcol, efa->mat_nr);
690 else if(drawParamsMapped)
691 flag= drawParamsMapped(userData, i);
695 if(flag != 0) { /* flag 0 == the face is hidden or invisible */
697 /* we always want smooth here since otherwise vertex colors dont interpolate */
700 cp= (unsigned char*)mcol;
703 glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
706 glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
708 glNormal3fv(bmdm->faceNos[i]);
710 if(tf) glTexCoord2fv(tf->uv[0]);
711 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
712 glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
714 if(tf) glTexCoord2fv(tf->uv[1]);
715 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
716 glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
718 if(tf) glTexCoord2fv(tf->uv[2]);
719 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
720 glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
723 if(tf) glTexCoord2fv(tf->uv[3]);
724 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
725 glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
728 if(tf) glTexCoord2fv(tf->uv[0]);
729 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
730 glNormal3fv(vertexNos[(int) efa->v1->tmp.l]);
731 glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
733 if(tf) glTexCoord2fv(tf->uv[1]);
734 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
735 glNormal3fv(vertexNos[(int) efa->v2->tmp.l]);
736 glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
738 if(tf) glTexCoord2fv(tf->uv[2]);
739 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
740 glNormal3fv(vertexNos[(int) efa->v3->tmp.l]);
741 glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
744 if(tf) glTexCoord2fv(tf->uv[3]);
745 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
746 glNormal3fv(vertexNos[(int) efa->v4->tmp.l]);
747 glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
754 for (i=0,efa= bm->faces.first; efa; i++,efa= efa->next) {
755 MTFace *tf= CustomData_bm_get(&bm->pdata, efa->data, CD_MTFACE);
756 MCol *mcol= CustomData_bm_get(&bm->pdata, efa->data, CD_MCOL);
757 unsigned char *cp= NULL;
758 int drawSmooth= (efa->flag & ME_SMOOTH);
762 flag= drawParams(tf, mcol, efa->mat_nr);
763 else if(drawParamsMapped)
764 flag= drawParamsMapped(userData, i);
768 if(flag != 0) { /* flag 0 == the face is hidden or invisible */
769 /* we always want smooth here since otherwise vertex colors dont interpolate */
772 cp= (unsigned char*)mcol;
775 glShadeModel(drawSmooth?GL_SMOOTH:GL_FLAT);
778 glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
782 if(tf) glTexCoord2fv(tf->uv[0]);
783 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
784 glVertex3fv(efa->v1->co);
786 if(tf) glTexCoord2fv(tf->uv[1]);
787 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
788 glVertex3fv(efa->v2->co);
790 if(tf) glTexCoord2fv(tf->uv[2]);
791 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
792 glVertex3fv(efa->v3->co);
795 if(tf) glTexCoord2fv(tf->uv[3]);
796 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
797 glVertex3fv(efa->v4->co);
800 if(tf) glTexCoord2fv(tf->uv[0]);
801 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
802 glNormal3fv(efa->v1->no);
803 glVertex3fv(efa->v1->co);
805 if(tf) glTexCoord2fv(tf->uv[1]);
806 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
807 glNormal3fv(efa->v2->no);
808 glVertex3fv(efa->v2->co);
810 if(tf) glTexCoord2fv(tf->uv[2]);
811 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
812 glNormal3fv(efa->v3->no);
813 glVertex3fv(efa->v3->co);
816 if(tf) glTexCoord2fv(tf->uv[3]);
817 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
818 glNormal3fv(efa->v4->no);
819 glVertex3fv(efa->v4->co);
829 static void bmDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, MCol *mcol, int matnr))
831 bmDM_drawFacesTex_common(dm, setDrawOptions, NULL, NULL);
834 static void bmDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
836 bmDM_drawFacesTex_common(dm, NULL, setDrawOptions, userData);
839 static void bmDM_drawMappedFacesGLSL(DerivedMesh *dm,
840 int (*setMaterial)(int, void *attribs),
841 int (*setDrawOptions)(void *userData, int index), void *userData)
844 EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
845 BMesh *bm= bmdm->tc->bm;
846 float (*vertexCos)[3]= bmdm->vertexCos;
847 float (*vertexNos)[3]= bmdm->vertexNos;
850 DMVertexAttribs attribs;
851 GPUVertexAttribs gattribs;
853 int transp, new_transp, orig_transp, tfoffset;
854 int i, b, matnr, new_matnr, dodraw, layer;
859 transp = GPU_get_material_blend_mode();
860 orig_transp = transp;
861 layer = CustomData_get_layer_index(&bm->pdata, CD_MTFACE);
862 tfoffset = (layer == -1)? -1: bm->pdata.layers[layer].offset;
864 memset(&attribs, 0, sizeof(attribs));
866 /* always use smooth shading even for flat faces, else vertex colors wont interpolate */
867 glShadeModel(GL_SMOOTH);
869 for (i=0,eve=bm->verts.first; eve; eve= eve->next)
870 BMINDEX_SET(eve, i++);
872 #define PASSATTRIB(efa, eve, vert) { \
873 if(attribs.totorco) { \
874 float *orco = attribs.orco.array[BMINDEX_GET(eve)]; \
875 glVertexAttrib3fvARB(attribs.orco.glIndex, orco); \
877 for(b = 0; b < attribs.tottface; b++) { \
878 MTFace *_tf = (MTFace*)((char*)efa->data + attribs.tface[b].bmOffset); \
879 glVertexAttrib2fvARB(attribs.tface[b].glIndex, _tf->uv[vert]); \
881 for(b = 0; b < attribs.totmcol; b++) { \
882 MCol *cp = (MCol*)((char*)efa->data + attribs.mcol[b].bmOffset); \
884 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a; \
885 glVertexAttrib4ubvARB(attribs.mcol[b].glIndex, col); \
887 if(attribs.tottang) { \
888 float *tang = attribs.tang.array[i*4 + vert]; \
889 glVertexAttrib3fvARB(attribs.tang.glIndex, tang); \
893 for (i=0,efa= bm->faces.first; efa; i++,efa= efa->next) {
894 int drawSmooth= (efa->flag & ME_SMOOTH);
896 if(setDrawOptions && !setDrawOptions(userData, i))
899 new_matnr = efa->mat_nr + 1;
900 if(new_matnr != matnr) {
901 dodraw = setMaterial(matnr = new_matnr, &gattribs);
903 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
907 tf = (MTFace*)((char*)efa->data)+tfoffset;
908 new_transp = tf->transp;
910 if(new_transp != transp) {
911 if(new_transp == GPU_BLEND_SOLID && orig_transp != GPU_BLEND_SOLID)
912 GPU_set_material_blend_mode(orig_transp);
914 GPU_set_material_blend_mode(new_transp);
920 glBegin(efa->v4?GL_QUADS:GL_TRIANGLES);
922 if(vertexCos) glNormal3fv(bmdm->faceNos[i]);
923 else glNormal3fv(efa->n);
925 PASSATTRIB(efa, efa->v1, 0);
926 if(vertexCos) glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
927 else glVertex3fv(efa->v1->co);
929 PASSATTRIB(efa, efa->v2, 1);
930 if(vertexCos) glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
931 else glVertex3fv(efa->v2->co);
933 PASSATTRIB(efa, efa->v3, 2);
934 if(vertexCos) glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
935 else glVertex3fv(efa->v3->co);
938 PASSATTRIB(efa, efa->v4, 3);
939 if(vertexCos) glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
940 else glVertex3fv(efa->v4->co);
943 PASSATTRIB(efa, efa->v1, 0);
945 glNormal3fv(vertexNos[(int) efa->v1->tmp.l]);
946 glVertex3fv(vertexCos[(int) efa->v1->tmp.l]);
949 glNormal3fv(efa->v1->no);
950 glVertex3fv(efa->v1->co);
953 PASSATTRIB(efa, efa->v2, 1);
955 glNormal3fv(vertexNos[(int) efa->v2->tmp.l]);
956 glVertex3fv(vertexCos[(int) efa->v2->tmp.l]);
959 glNormal3fv(efa->v2->no);
960 glVertex3fv(efa->v2->co);
963 PASSATTRIB(efa, efa->v3, 2);
965 glNormal3fv(vertexNos[(int) efa->v3->tmp.l]);
966 glVertex3fv(vertexCos[(int) efa->v3->tmp.l]);
969 glNormal3fv(efa->v3->no);
970 glVertex3fv(efa->v3->co);
974 PASSATTRIB(efa, efa->v4, 3);
976 glNormal3fv(vertexNos[(int) efa->v4->tmp.l]);
977 glVertex3fv(vertexCos[(int) efa->v4->tmp.l]);
980 glNormal3fv(efa->v4->no);
981 glVertex3fv(efa->v4->co);
991 static void bmDM_drawFacesGLSL(DerivedMesh *dm,
992 int (*setMaterial)(int, void *attribs))
994 dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
997 static void bmDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
999 EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1004 if (bmdm->tc->bm->verts.first) {
1005 eve = BMIter_New(&iter, bmdm->tc->bm, BM_VERTS_OF_MESH, NULL);
1006 for (i=0; eve; eve=BMIter_Step(&iter), i++) {
1007 if (bmdm->vertexCos) {
1008 DO_MINMAX(bmdm->vertexCos[i], min_r, max_r);
1010 DO_MINMAX(eve->co, min_r, max_r);
1014 min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
1017 static int bmDM_getNumVerts(DerivedMesh *dm)
1019 EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1021 return bmdm->tc->bm->totvert;
1024 static int bmDM_getNumEdges(DerivedMesh *dm)
1026 EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1028 return bmdm->tc->bm->totedge;
1031 static int bmDM_getNumTessFaces(DerivedMesh *dm)
1033 EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1035 return bmdm->tc->tottri;
1038 static int bmDM_getNumFaces(DerivedMesh *dm)
1040 EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1042 return bmdm->tc->bm->totface;
1045 static int bmvert_to_mvert(BMVert *ev, MVert *vert_r)
1047 VECCOPY(vert_r->co, ev->co);
1049 vert_r->no[0] = (short)(ev->no[0] * 32767.0f);
1050 vert_r->no[1] = (short)(ev->no[1] * 32767.0f);
1051 vert_r->no[2] = (short)(ev->no[2] * 32767.0f);
1053 /* TODO what to do with vert_r->flag and vert_r->mat_nr? */
1054 vert_r->flag = BMFlags_To_MEFlags(ev);
1056 vert_r->bweight = (unsigned char) (ev->bweight*255.0f);
1059 static void bmDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
1065 if (index < 0 || index >= ((EditDerivedBMesh *)dm)->tv) {
1066 printf("error in bmDM_getVert.\n");
1070 ev = ((EditDerivedBMesh *)dm)->vtable[index];
1071 bmvert_to_mvert(ev, vert_r);
1074 static void bmDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
1076 EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1077 BMesh *bm = ((EditDerivedBMesh *)dm)->tc->bm;
1079 BMVert *ev, *v1, *v2;
1083 if (index < 0 || index >= ((EditDerivedBMesh *)dm)->te) {
1084 printf("error in bmDM_getEdge.\n");
1088 e = bmdm->etable[index];
1090 edge_r->crease = (unsigned char) (e->crease*255.0f);
1091 edge_r->bweight = (unsigned char) (e->bweight*255.0f);
1092 /* TODO what to do with edge_r->flag? */
1093 edge_r->flag = ME_EDGEDRAW|ME_EDGERENDER;
1094 edge_r->flag |= BMFlags_To_MEFlags(e);
1096 /* this needs setup of f2 field */
1097 if (!ee->f2) edge_r->flag |= ME_LOOSEEDGE;
1100 edge_r->v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(bmdm->vhash, e->v1));
1101 edge_r->v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(bmdm->vhash, e->v2));
1104 static void bmDM_getTessFace(DerivedMesh *dm, int index, MFace *face_r)
1106 EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1107 BMesh *bm = bmdm->tc->bm;
1113 if (index < 0 || index >= ((EditDerivedBMesh *)dm)->tf) {
1114 printf("error in bmDM_getTessFace.\n");
1118 l = ((EditDerivedBMesh *)dm)->tc->looptris[index];
1122 face_r->mat_nr = (unsigned char) ef->mat_nr;
1123 face_r->flag = BMFlags_To_MEFlags(ef);
1125 face_r->v1 = GET_INT_FROM_POINTER(BLI_ghash_lookup(bmdm->vhash, l[0]->v));
1126 face_r->v2 = GET_INT_FROM_POINTER(BLI_ghash_lookup(bmdm->vhash, l[1]->v));
1127 face_r->v3 = GET_INT_FROM_POINTER(BLI_ghash_lookup(bmdm->vhash, l[2]->v));
1130 test_index_face(face_r, NULL, 0, 3);
1133 static void bmDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
1135 BMesh *bm = ((EditDerivedBMesh *)dm)->tc->bm;
1139 ev = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
1140 for( ; ev; ev = BMIter_Step(&iter), ++vert_r) {
1141 VECCOPY(vert_r->co, ev->co);
1143 vert_r->no[0] = (short) (ev->no[0] * 32767.0);
1144 vert_r->no[1] = (short) (ev->no[1] * 32767.0);
1145 vert_r->no[2] = (short) (ev->no[2] * 32767.0);
1147 /* TODO what to do with vert_r->flag and vert_r->mat_nr? */
1149 vert_r->flag = BMFlags_To_MEFlags(ev);
1150 vert_r->bweight = (unsigned char) (ev->bweight*255.0f);
1154 static void bmDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r)
1156 BMesh *bm = ((EditDerivedBMesh *)dm)->tc->bm;
1162 /* store vertex indices in tmp union */
1163 ev = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
1164 for (i=0; ev; ev=BMIter_Step(&iter), i++)
1167 ee = BMIter_New(&iter, bm, BM_EDGES_OF_MESH, NULL);
1168 for( ; ee; ee=BMIter_Step(&iter)) {
1169 edge_r->crease = (unsigned char) (ee->crease*255.0f);
1170 edge_r->bweight = (unsigned char) (ee->bweight*255.0f);
1171 /* TODO what to do with edge_r->flag? */
1172 edge_r->flag = ME_EDGEDRAW|ME_EDGERENDER;
1173 if (ee->head.flag & BM_SEAM) edge_r->flag |= ME_SEAM;
1174 if (ee->head.flag & BM_SHARP) edge_r->flag |= ME_SHARP;
1176 /* this needs setup of f2 field */
1177 if (!ee->f2) edge_r->flag |= ME_LOOSEEDGE;
1180 edge_r->v1 = (int)BMINDEX_GET(ee->v1);
1181 edge_r->v2 = (int)BMINDEX_GET(ee->v2);
1185 static void bmDM_copyFaceArray(DerivedMesh *dm, MFace *face_r)
1187 EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
1188 BMesh *bm = ((EditDerivedBMesh *)dm)->tc->bm;
1195 /* store vertexes indices in tmp union */
1196 ev = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
1197 for (i=0; ev; ev=BMIter_Step(&iter), i++)
1200 for (i=0; i<bmdm->tc->tottri; i++) {
1201 l = bmdm->tc->looptris[i];
1204 face_r->mat_nr = (unsigned char) ef->mat_nr;
1206 /*HACK/TODO: need to convert this*/
1207 face_r->flag = ef->head.flag;
1209 face_r->v1 = BMINDEX_GET(l[0]->v);
1210 face_r->v2 = BMINDEX_GET(l[1]->v);
1211 face_r->v3 = BMINDEX_GET(l[2]->v);
1214 test_index_face(face_r, NULL, 0, 3);
1218 static void *bmDM_getFaceDataArray(DerivedMesh *dm, int type)
1220 EditDerivedBMesh *bmdm= (EditDerivedBMesh*) dm;
1221 BMesh *bm= bmdm->tc->bm;
1223 char *data, *bmdata;
1225 int index, offset, size, i;
1227 datalayer = DM_get_face_data_layer(dm, type);
1231 /* layers are store per face for editmesh, we convert to a tbmporary
1232 * data layer array in the derivedmesh when these are requested */
1233 if(type == CD_MTFACE || type == CD_MCOL) {
1234 index = CustomData_get_layer_index(&bm->pdata, type);
1237 offset = bm->pdata.layers[index].offset;
1238 size = CustomData_sizeof(type);
1240 DM_add_face_layer(dm, type, CD_CALLOC, NULL);
1241 index = CustomData_get_layer_index(&dm->faceData, type);
1242 dm->faceData.layers[index].flag |= CD_FLAG_TEMPORARY;
1244 data = datalayer = DM_get_face_data_layer(dm, type);
1245 for (i=0; i<bmdm->tc->tottri; i++, data+=size) {
1246 efa = bmdm->tc->looptris[i][0]->f;
1247 /*BMESH_TODO: need to still add tface data,
1248 derived from the loops.*/
1249 bmdata = CustomData_bmesh_get(&bm->pdata, efa->head.data, type);
1250 memcpy(data, bmdata, size);
1258 typedef struct bmDM_loopIter {
1267 typedef struct bmDM_faceIter {
1274 bmDM_loopIter loopiter;
1277 void bmDM_faceIterStep(void *self)
1279 bmDM_faceIter *iter = self;
1281 iter->f = iter->nextf;
1283 iter->head.mat_nr = iter->f->mat_nr;
1284 iter->head.flags = BMFlags_To_MEFlags(iter->f);
1287 iter->nextf = BMIter_Step(&iter->iter);
1289 if (!iter->nextf) iter->head.done = 1;
1292 void *bmDM_getFaceCDData(void *self, int type, int layer)
1294 bmDM_faceIter *iter = self;
1297 return CustomData_bmesh_get(&iter->bm->pdata, iter->f->head.data, type);
1298 else return CustomData_bmesh_get_n(&iter->bm->pdata, iter->f->head.data, type, layer);
1301 void bmDM_loopIterStep(void *self)
1303 bmDM_loopIter *iter = self;
1305 iter->l = iter->nextl;
1307 bmvert_to_mvert(iter->l->v, &iter->head.v);
1309 iter->head.vindex = BMINDEX_GET(iter->l->v);
1310 iter->head.eindex = BMINDEX_GET(iter->l->e);
1312 iter->nextl = BMIter_Step(&iter->iter);
1314 if (!iter->nextl) iter->head.done = 1;
1317 void *bmDM_getLoopCDData(void *self, int type, int layer)
1319 bmDM_loopIter *iter = self;
1322 return CustomData_bmesh_get(&iter->bm->ldata, iter->l->head.data, type);
1323 else return CustomData_bmesh_get_n(&iter->bm->ldata, iter->l->head.data, type, layer);
1326 void *bmDM_getVertCDData(void *self, int type, int layer)
1328 bmDM_loopIter *iter = self;
1331 return CustomData_bmesh_get(&iter->bm->vdata, iter->l->v->head.data, type);
1332 else return CustomData_bmesh_get_n(&iter->bm->vdata, iter->l->v->head.data, type, layer);
1335 void bmDM_iterFree(void *self)
1340 void bmDM_nulliterFree(void *self)
1344 DMLoopIter *bmDM_newLoopsIter(void *faceiter)
1346 bmDM_faceIter *fiter = faceiter;
1347 bmDM_loopIter *iter = &fiter->loopiter;
1349 memset(&fiter->loopiter, 0, sizeof(bmDM_loopIter));
1351 iter->bm = fiter->bm;
1353 iter->nextl = BMIter_New(&iter->iter, iter->bm, BM_LOOPS_OF_FACE, iter->f);
1355 iter->head.step = bmDM_loopIterStep;
1356 iter->head.getLoopCDData = bmDM_getLoopCDData;
1357 iter->head.getVertCDData = bmDM_getVertCDData;
1359 bmvert_to_mvert(iter->nextl->v, &iter->head.v);
1360 iter->head.vindex = BMINDEX_GET(iter->nextl->v);
1361 iter->head.eindex = BMINDEX_GET(iter->nextl->e);
1363 return (DMLoopIter*) iter;
1366 static DMFaceIter *bmDM_getFaceIter(void *dm)
1368 EditDerivedBMesh *bmdm= dm;
1369 bmDM_faceIter *iter = MEM_callocN(sizeof(bmDM_faceIter), "bmDM_faceIter");
1375 iter->bm = bmdm->tc->bm;
1376 iter->f = iter->nextf = BMIter_New(&iter->iter, iter->bm, BM_FACES_OF_MESH, NULL);
1378 iter->head.step = bmDM_faceIterStep;
1379 iter->head.free = bmDM_iterFree;
1380 iter->head.getCDData = bmDM_getFaceCDData;
1381 iter->head.getLoopsIter = bmDM_newLoopsIter;
1383 iter->head.mat_nr = iter->f->mat_nr;
1384 iter->head.flags = BMFlags_To_MEFlags(iter->f);
1386 /*set up vert/edge indices*/
1388 BM_ITER(v, &biter, iter->bm, BM_VERTS_OF_MESH, NULL) {
1394 BM_ITER(e, &biter, iter->bm, BM_EDGES_OF_MESH, NULL) {
1399 return (DMFaceIter*) iter;
1402 static void bmDM_release(void *dm)
1404 EditDerivedBMesh *bmdm= dm;
1406 if (DM_release(dm)) {
1407 if (bmdm->vertexCos) {
1408 MEM_freeN(bmdm->vertexCos);
1409 MEM_freeN(bmdm->vertexNos);
1410 MEM_freeN(bmdm->faceNos);
1413 BLI_ghash_free(bmdm->fhash, NULL, NULL);
1414 BLI_ghash_free(bmdm->ehash, NULL, NULL);
1415 BLI_ghash_free(bmdm->vhash, NULL, NULL);
1417 if (bmdm->vtable) MEM_freeN(bmdm->vtable);
1418 if (bmdm->etable) MEM_freeN(bmdm->etable);
1419 if (bmdm->ftable) MEM_freeN(bmdm->ftable);
1425 DerivedMesh *getEditDerivedBMesh(BMEditMesh *em, Object *ob,
1426 float (*vertexCos)[3])
1428 EditDerivedBMesh *bmdm = MEM_callocN(sizeof(*bmdm), "bmdm");
1433 DM_init((DerivedMesh*)bmdm, em->bm->totvert, em->bm->totedge, em->tottri,
1434 em->bm->totloop, em->bm->totface);
1436 bmdm->dm.getMinMax = bmDM_getMinMax;
1438 bmdm->dm.getNumVerts = bmDM_getNumVerts;
1439 bmdm->dm.getNumEdges = bmDM_getNumEdges;
1440 bmdm->dm.getNumTessFaces = bmDM_getNumTessFaces;
1441 bmdm->dm.getNumFaces = bmDM_getNumFaces;
1443 bmdm->dm.getVert = bmDM_getVert;
1444 bmdm->dm.getEdge = bmDM_getEdge;
1445 bmdm->dm.getTessFace = bmDM_getTessFace;
1446 bmdm->dm.copyVertArray = bmDM_copyVertArray;
1447 bmdm->dm.copyEdgeArray = bmDM_copyEdgeArray;
1448 bmdm->dm.copyTessFaceArray = bmDM_copyFaceArray;
1449 bmdm->dm.getTessFaceDataArray = bmDM_getFaceDataArray;
1451 bmdm->dm.newFaceIter = bmDM_getFaceIter;
1452 bmdm->dm.recalcTesselation = bmDM_recalcTesselation;
1454 bmdm->dm.foreachMappedVert = bmDM_foreachMappedVert;
1455 bmdm->dm.foreachMappedEdge = bmDM_foreachMappedEdge;
1456 bmdm->dm.foreachMappedFaceCenter = bmDM_foreachMappedFaceCenter;
1458 bmdm->dm.drawEdges = bmDM_drawEdges;
1459 bmdm->dm.drawMappedEdges = bmDM_drawMappedEdges;
1460 bmdm->dm.drawMappedEdgesInterp = bmDM_drawMappedEdgesInterp;
1461 bmdm->dm.drawMappedFaces = bmDM_drawMappedFaces;
1462 bmdm->dm.drawMappedFacesTex = bmDM_drawMappedFacesTex;
1463 bmdm->dm.drawMappedFacesGLSL = bmDM_drawMappedFacesGLSL;
1464 bmdm->dm.drawFacesTex = bmDM_drawFacesTex;
1465 bmdm->dm.drawFacesGLSL = bmDM_drawFacesGLSL;
1466 bmdm->dm.drawUVEdges = bmDM_drawUVEdges;
1468 bmdm->dm.release = bmDM_release;
1470 bmdm->vertexCos = vertexCos;
1472 if(CustomData_has_layer(&bm->vdata, CD_MDEFORMVERT)) {
1477 DM_add_vert_layer(&bmdm->dm, CD_MDEFORMVERT, CD_CALLOC, NULL);
1479 eve = BMIter_New(&iter, bmdm->tc->bm, BM_VERTS_OF_MESH, NULL);
1480 for (i=0; eve; eve=BMIter_Step(&iter), i++)
1481 DM_set_vert_data(&bmdm->dm, i, CD_MDEFORMVERT,
1482 CustomData_bmesh_get(&bm->vdata, eve->head.data, CD_MDEFORMVERT));
1488 int totface = bm->totface;
1491 eve=BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
1492 for (i=0; eve; eve=BMIter_Step(&iter), i++)
1493 BMINDEX_SET(eve, i);
1495 bmdm->vertexNos = MEM_callocN(sizeof(*bmdm->vertexNos)*i, "bmdm_vno");
1496 bmdm->faceNos = MEM_mallocN(sizeof(*bmdm->faceNos)*totface, "bmdm_vno");
1498 for (i=0; i<bmdm->tc->tottri; i++) {
1499 BMLoop **l = bmdm->tc->looptris[i];
1500 float *v1 = vertexCos[(int) BMINDEX_GET(l[0]->v)];
1501 float *v2 = vertexCos[(int) BMINDEX_GET(l[1]->v)];
1502 float *v3 = vertexCos[(int) BMINDEX_GET(l[2]->v)];
1503 float *no = bmdm->faceNos[i];
1505 CalcNormFloat(v1, v2, v3, no);
1506 VecAddf(bmdm->vertexNos[BMINDEX_GET(l[0]->v)], bmdm->vertexNos[BMINDEX_GET(l[0]->v)], no);
1507 VecAddf(bmdm->vertexNos[BMINDEX_GET(l[1]->v)], bmdm->vertexNos[BMINDEX_GET(l[1]->v)], no);
1508 VecAddf(bmdm->vertexNos[BMINDEX_GET(l[2]->v)], bmdm->vertexNos[BMINDEX_GET(l[2]->v)], no);
1511 eve=BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
1512 for (i=0; eve; eve=BMIter_Step(&iter), i++) {
1513 float *no = bmdm->vertexNos[i];
1514 /* following Mesh convention; we use vertex coordinate itself
1515 * for normal in this case */
1516 if (Normalize(no)==0.0) {
1517 VECCOPY(no, vertexCos[i]);
1523 bmdm_recalc_lookups(bmdm);
1525 return (DerivedMesh*) bmdm;