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) 2006 Blender Foundation.
19 * All rights reserved.
21 * The Original Code is: all of this file.
23 * Contributor(s): Ben Batt <benbatt@gmail.com>
25 * ***** END GPL LICENSE BLOCK *****
27 * Implementation of CDDerivedMesh.
29 * BKE_cdderivedmesh.h contains the function prototypes for this file.
33 /** \file blender/blenkernel/intern/cdderivedmesh.c
39 #include "BKE_cdderivedmesh.h"
40 #include "BKE_global.h"
42 #include "BKE_paint.h"
43 #include "BKE_utildefines.h"
44 #include "BKE_tessmesh.h"
46 #include "BLI_editVert.h"
47 #include "BLI_scanfill.h"
49 #include "BLI_blenlib.h"
50 #include "BLI_edgehash.h"
51 #include "BLI_editVert.h"
54 #include "BLI_array.h"
55 #include "BLI_smallhash.h"
56 #include "BLI_utildefines.h"
58 #include "BKE_cdderivedmesh.h"
59 #include "BKE_global.h"
61 #include "BKE_paint.h"
64 #include "DNA_meshdata_types.h"
65 #include "DNA_object_types.h"
66 #include "DNA_curve_types.h" /* for Curve */
68 #include "MEM_guardedalloc.h"
70 #include "GPU_buffers.h"
72 #include "GPU_extensions.h"
73 #include "GPU_material.h"
82 /* these point to data in the DerivedMesh custom data layers,
83 they are only here for efficiency and convenience **/
94 /* Mesh connectivity */
95 struct ListBase *fmap;
96 struct IndexNode *fmap_mem;
99 /**************** DerivedMesh interface functions ****************/
100 static int cdDM_getNumVerts(DerivedMesh *dm)
102 return dm->numVertData;
105 static int cdDM_getNumEdges(DerivedMesh *dm)
107 return dm->numEdgeData;
110 static int cdDM_getNumTessFaces(DerivedMesh *dm)
112 return dm->numFaceData;
115 static int cdDM_getNumPolys(DerivedMesh *dm)
117 return dm->numPolyData;
120 static void cdDM_getVert(DerivedMesh *dm, int index, MVert *vert_r)
122 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
123 *vert_r = cddm->mvert[index];
126 static void cdDM_getEdge(DerivedMesh *dm, int index, MEdge *edge_r)
128 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
129 *edge_r = cddm->medge[index];
132 static void cdDM_getTessFace(DerivedMesh *dm, int index, MFace *face_r)
134 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
135 *face_r = cddm->mface[index];
138 static void cdDM_copyVertArray(DerivedMesh *dm, MVert *vert_r)
140 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
141 memcpy(vert_r, cddm->mvert, sizeof(*vert_r) * dm->numVertData);
144 static void cdDM_copyEdgeArray(DerivedMesh *dm, MEdge *edge_r)
146 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
147 memcpy(edge_r, cddm->medge, sizeof(*edge_r) * dm->numEdgeData);
150 static void cdDM_copyTessFaceArray(DerivedMesh *dm, MFace *face_r)
152 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
153 memcpy(face_r, cddm->mface, sizeof(*face_r) * dm->numFaceData);
156 static void cdDM_copyLoopArray(DerivedMesh *dm, MLoop *loop_r)
158 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
159 memcpy(loop_r, cddm->mloop, sizeof(*loop_r) * dm->numLoopData);
162 static void cdDM_copyPolyArray(DerivedMesh *dm, MPoly *poly_r)
164 CDDerivedMesh *cddm = (CDDerivedMesh *)dm;
165 memcpy(poly_r, cddm->mpoly, sizeof(*poly_r) * dm->numPolyData);
168 static void cdDM_getMinMax(DerivedMesh *dm, float min_r[3], float max_r[3])
170 CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
173 if (dm->numVertData) {
174 for (i=0; i<dm->numVertData; i++) {
175 DO_MINMAX(cddm->mvert[i].co, min_r, max_r);
178 min_r[0] = min_r[1] = min_r[2] = max_r[0] = max_r[1] = max_r[2] = 0.0;
182 static void cdDM_getVertCo(DerivedMesh *dm, int index, float co_r[3])
184 CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
186 copy_v3_v3(co_r, cddm->mvert[index].co);
189 static void cdDM_getVertCos(DerivedMesh *dm, float (*cos_r)[3])
191 MVert *mv = CDDM_get_verts(dm);
194 for(i = 0; i < dm->numVertData; i++, mv++)
195 copy_v3_v3(cos_r[i], mv->co);
198 static void cdDM_getVertNo(DerivedMesh *dm, int index, float no_r[3])
200 CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
201 normal_short_to_float_v3(no_r, cddm->mvert[index].no);
204 static ListBase *cdDM_getFaceMap(Object *ob, DerivedMesh *dm)
206 CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
208 if(!cddm->fmap && ob->type == OB_MESH) {
211 create_vert_face_map(&cddm->fmap, &cddm->fmap_mem, me->mface,
212 me->totvert, me->totface);
218 static int can_pbvh_draw(Object *ob, DerivedMesh *dm)
220 CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
224 /* active modifiers means extra deformation, which can't be handled correct
225 on bith of PBVH and sculpt "layer" levels, so use PBVH only for internal brush
226 stuff and show final DerivedMesh so user would see actual object shape */
227 deformed|= ob->sculpt->modifiers_active;
229 /* as in case with modifiers, we can't synchronize deformation made against
230 PBVH and non-locked keyblock, so also use PBVH only for brushes and
231 final DM to give final result to user */
232 deformed|= ob->sculpt->kb && (ob->shapeflag&OB_SHAPE_LOCK) == 0;
237 return cddm->mvert == me->mvert || ob->sculpt->kb;
240 static struct PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm)
242 CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
251 if(ob->sculpt->pbvh) {
252 cddm->pbvh= ob->sculpt->pbvh;
253 cddm->pbvh_draw = can_pbvh_draw(ob, dm);
256 /* always build pbvh from original mesh, and only use it for drawing if
257 this derivedmesh is just original mesh. it's the multires subsurf dm
258 that this is actually for, to support a pbvh on a modified mesh */
259 if(!cddm->pbvh && ob->type == OB_MESH) {
260 SculptSession *ss= ob->sculpt;
262 cddm->pbvh = BLI_pbvh_new();
263 cddm->pbvh_draw = can_pbvh_draw(ob, dm);
264 BLI_pbvh_build_mesh(cddm->pbvh, me->mface, me->mvert,
265 me->totface, me->totvert);
267 if(ss->modifiers_active && ob->derivedDeform) {
268 DerivedMesh *deformdm= ob->derivedDeform;
272 totvert= deformdm->getNumVerts(deformdm);
273 vertCos= MEM_callocN(3*totvert*sizeof(float), "cdDM_getPBVH vertCos");
274 deformdm->getVertCos(deformdm, vertCos);
275 BLI_pbvh_apply_vertCos(cddm->pbvh, vertCos);
283 /* update vertex normals so that drawing smooth faces works during sculpt
284 TODO: proper fix is to support the pbvh in all drawing modes */
285 static void cdDM_update_normals_from_pbvh(DerivedMesh *dm)
287 CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
288 float (*face_nors)[3];
290 if(!cddm->pbvh || !cddm->pbvh_draw || !dm->numFaceData)
293 face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL);
295 BLI_pbvh_update(cddm->pbvh, PBVH_UpdateNormals, face_nors);
298 static void cdDM_drawVerts(DerivedMesh *dm)
300 CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
301 MVert *mv = cddm->mvert;
304 if( GPU_buffer_legacy(dm) ) {
306 for(i = 0; i < dm->numVertData; i++, mv++)
310 else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
311 GPU_vertex_setup(dm);
312 if( !GPU_buffer_legacy(dm) ) {
313 if(dm->drawObject->tot_triangle_point)
314 glDrawArrays(GL_POINTS,0, dm->drawObject->tot_triangle_point);
316 glDrawArrays(GL_POINTS,0, dm->drawObject->tot_loose_point);
322 static void cdDM_drawUVEdges(DerivedMesh *dm)
324 CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
325 MFace *mf = cddm->mface;
326 MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
330 if( GPU_buffer_legacy(dm) ) {
332 for(i = 0; i < dm->numFaceData; i++, mf++, tf++) {
333 if(!(mf->flag&ME_HIDE)) {
334 glVertex2fv(tf->uv[0]);
335 glVertex2fv(tf->uv[1]);
337 glVertex2fv(tf->uv[1]);
338 glVertex2fv(tf->uv[2]);
341 glVertex2fv(tf->uv[2]);
342 glVertex2fv(tf->uv[0]);
344 glVertex2fv(tf->uv[2]);
345 glVertex2fv(tf->uv[3]);
347 glVertex2fv(tf->uv[3]);
348 glVertex2fv(tf->uv[0]);
360 GPU_uvedge_setup(dm);
361 if( !GPU_buffer_legacy(dm) ) {
362 for(i = 0; i < dm->numFaceData; i++, mf++) {
363 if(!(mf->flag&ME_HIDE)) {
369 if( prevdraw != draw ) {
370 if( prevdraw > 0 && (curpos-prevstart) > 0) {
371 glDrawArrays(GL_LINES,prevstart,curpos-prevstart);
383 if( prevdraw > 0 && (curpos-prevstart) > 0 ) {
384 glDrawArrays(GL_LINES,prevstart,curpos-prevstart);
392 static void cdDM_drawEdges(DerivedMesh *dm, int drawLooseEdges, int drawAllEdges)
394 CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
395 MVert *mvert = cddm->mvert;
396 MEdge *medge = cddm->medge;
399 if( GPU_buffer_legacy(dm) ) {
400 DEBUG_VBO( "Using legacy code. cdDM_drawEdges\n" );
402 for(i = 0; i < dm->numEdgeData; i++, medge++) {
403 if((drawAllEdges || (medge->flag&ME_EDGEDRAW))
404 && (drawLooseEdges || !(medge->flag&ME_LOOSEEDGE))) {
405 glVertex3fv(mvert[medge->v1].co);
406 glVertex3fv(mvert[medge->v2].co);
411 else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
417 if( !GPU_buffer_legacy(dm) ) {
418 for(i = 0; i < dm->numEdgeData; i++, medge++) {
419 if((drawAllEdges || (medge->flag&ME_EDGEDRAW))
420 && (drawLooseEdges || !(medge->flag&ME_LOOSEEDGE))) {
426 if( prevdraw != draw ) {
427 if( prevdraw > 0 && (i-prevstart) > 0 ) {
428 GPU_buffer_draw_elements( dm->drawObject->edges, GL_LINES, prevstart*2, (i-prevstart)*2 );
434 if( prevdraw > 0 && (i-prevstart) > 0 ) {
435 GPU_buffer_draw_elements( dm->drawObject->edges, GL_LINES, prevstart*2, (i-prevstart)*2 );
442 static void cdDM_drawLooseEdges(DerivedMesh *dm)
444 CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
445 MVert *mvert = cddm->mvert;
446 MEdge *medge = cddm->medge;
449 if( GPU_buffer_legacy(dm) ) {
450 DEBUG_VBO( "Using legacy code. cdDM_drawLooseEdges\n" );
452 for(i = 0; i < dm->numEdgeData; i++, medge++) {
453 if(medge->flag&ME_LOOSEEDGE) {
454 glVertex3fv(mvert[medge->v1].co);
455 glVertex3fv(mvert[medge->v2].co);
460 else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
466 if( !GPU_buffer_legacy(dm) ) {
467 for(i = 0; i < dm->numEdgeData; i++, medge++) {
468 if(medge->flag&ME_LOOSEEDGE) {
474 if( prevdraw != draw ) {
475 if( prevdraw > 0 && (i-prevstart) > 0) {
476 GPU_buffer_draw_elements( dm->drawObject->edges, GL_LINES, prevstart*2, (i-prevstart)*2 );
482 if( prevdraw > 0 && (i-prevstart) > 0 ) {
483 GPU_buffer_draw_elements( dm->drawObject->edges, GL_LINES, prevstart*2, (i-prevstart)*2 );
490 static void cdDM_drawFacesSolid(DerivedMesh *dm,
491 float (*partial_redraw_planes)[4],
492 int UNUSED(fast), int (*setMaterial)(int, void *attribs))
494 CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
495 MVert *mvert = cddm->mvert;
496 MFace *mface = cddm->mface;
497 float *nors= dm->getTessFaceDataArray(dm, CD_NORMAL);
498 int a, glmode = -1, shademodel = -1, matnr = -1, drawCurrentMat = 1;
500 #define PASSVERT(index) { \
501 if(shademodel == GL_SMOOTH) { \
502 short *no = mvert[index].no; \
505 glVertex3fv(mvert[index].co); \
508 if(cddm->pbvh && cddm->pbvh_draw) {
509 if(dm->numFaceData) {
510 float (*face_nors)[3] = CustomData_get_layer(&dm->faceData, CD_NORMAL);
512 /* should be per face */
513 if(!setMaterial(mface->mat_nr+1, NULL))
516 glShadeModel((mface->flag & ME_SMOOTH)? GL_SMOOTH: GL_FLAT);
517 BLI_pbvh_draw(cddm->pbvh, partial_redraw_planes, face_nors, (mface->flag & ME_SMOOTH));
518 glShadeModel(GL_FLAT);
524 if( GPU_buffer_legacy(dm) ) {
525 DEBUG_VBO( "Using legacy code. cdDM_drawFacesSolid\n" );
526 glBegin(glmode = GL_QUADS);
527 for(a = 0; a < dm->numFaceData; a++, mface++) {
528 int new_glmode, new_matnr, new_shademodel;
530 new_glmode = mface->v4?GL_QUADS:GL_TRIANGLES;
531 new_matnr = mface->mat_nr + 1;
532 new_shademodel = (mface->flag & ME_SMOOTH)?GL_SMOOTH:GL_FLAT;
534 if(new_glmode != glmode || new_matnr != matnr
535 || new_shademodel != shademodel) {
538 drawCurrentMat = setMaterial(matnr = new_matnr, NULL);
540 glShadeModel(shademodel = new_shademodel);
541 glBegin(glmode = new_glmode);
545 if(shademodel == GL_FLAT) {
550 /* TODO make this better (cache facenormals as layer?) */
553 normal_quad_v3( nor,mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co, mvert[mface->v4].co);
555 normal_tri_v3( nor,mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co);
573 else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
574 GPU_vertex_setup( dm );
575 GPU_normal_setup( dm );
576 if( !GPU_buffer_legacy(dm) ) {
577 glShadeModel(GL_SMOOTH);
578 for( a = 0; a < dm->drawObject->totmaterial; a++ ) {
579 if( setMaterial(dm->drawObject->materials[a].mat_nr+1, NULL) )
580 glDrawArrays(GL_TRIANGLES, dm->drawObject->materials[a].start,
581 dm->drawObject->materials[a].totpoint);
584 GPU_buffer_unbind( );
588 glShadeModel(GL_FLAT);
591 static void cdDM_drawFacesColored(DerivedMesh *dm, int useTwoSided, unsigned char *col1, unsigned char *col2)
593 CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
595 unsigned char *cp1, *cp2;
596 MVert *mvert = cddm->mvert;
597 MFace *mface = cddm->mface;
607 /* there's a conflict here... twosided colors versus culling...? */
608 /* defined by history, only texture faces have culling option */
609 /* we need that as mesh option builtin, next to double sided lighting */
611 glEnable(GL_CULL_FACE);
614 cdDM_update_normals_from_pbvh(dm);
616 if( GPU_buffer_legacy(dm) ) {
617 DEBUG_VBO( "Using legacy code. cdDM_drawFacesColored\n" );
618 glShadeModel(GL_SMOOTH);
619 glBegin(glmode = GL_QUADS);
620 for(a = 0; a < dm->numFaceData; a++, mface++, cp1 += 16) {
621 int new_glmode = mface->v4?GL_QUADS:GL_TRIANGLES;
623 if(new_glmode != glmode) {
625 glBegin(glmode = new_glmode);
629 glVertex3fv(mvert[mface->v1].co);
631 glVertex3fv(mvert[mface->v2].co);
633 glVertex3fv(mvert[mface->v3].co);
636 glVertex3fv(mvert[mface->v4].co);
641 glVertex3fv(mvert[mface->v3].co );
643 glVertex3fv(mvert[mface->v2].co );
645 glVertex3fv(mvert[mface->v1].co );
648 glVertex3fv(mvert[mface->v4].co );
655 else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
656 GPU_color4_upload(dm,cp1);
657 GPU_vertex_setup(dm);
659 if( !GPU_buffer_legacy(dm) ) {
660 glShadeModel(GL_SMOOTH);
661 glDrawArrays(GL_TRIANGLES, 0, dm->drawObject->tot_triangle_point);
664 GPU_color4_upload(dm,cp2);
666 glCullFace(GL_FRONT);
667 glDrawArrays(GL_TRIANGLES, 0, dm->drawObject->tot_triangle_point);
674 glShadeModel(GL_FLAT);
675 glDisable(GL_CULL_FACE);
678 static void cdDM_drawFacesTex_common(DerivedMesh *dm,
679 int (*drawParams)(MTFace *tface, int has_mcol, int matnr),
680 int (*drawParamsMapped)(void *userData, int index),
683 CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
684 MVert *mv = cddm->mvert;
685 MFace *mf = DM_get_tessface_data_layer(dm, CD_MFACE);
686 MCol *realcol = dm->getTessFaceDataArray(dm, CD_TEXTURE_MCOL);
687 float *nors= dm->getTessFaceDataArray(dm, CD_NORMAL);
688 MTFace *tf = DM_get_tessface_data_layer(dm, CD_MTFACE);
689 int i, j, orig, *index = DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
690 int startFace = 0, lastFlag = 0xdeadbeef;
691 MCol *mcol = dm->getTessFaceDataArray(dm, CD_WEIGHT_MCOL);
693 mcol = dm->getTessFaceDataArray(dm, CD_MCOL);
695 cdDM_update_normals_from_pbvh(dm);
697 if( GPU_buffer_legacy(dm) ) {
698 DEBUG_VBO( "Using legacy code. cdDM_drawFacesTex_common\n" );
699 for(i = 0; i < dm->numFaceData; i++, mf++) {
702 unsigned char *cp = NULL;
705 flag = drawParams(tf? &tf[i]: NULL, (mcol != NULL), mf->mat_nr);
710 if(orig == ORIGINDEX_NONE) { if(nors) nors += 3; continue; }
711 if(drawParamsMapped) flag = drawParamsMapped(userData, orig);
712 else { if(nors) nors += 3; continue; }
715 if(drawParamsMapped) flag = drawParamsMapped(userData, i);
716 else { if(nors) nors += 3; continue; }
721 cp= (unsigned char*) &mcol[i*4];
723 if(!(mf->flag&ME_SMOOTH)) {
730 normal_quad_v3( nor,mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co);
732 normal_tri_v3( nor,mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co);
738 glBegin(mf->v4?GL_QUADS:GL_TRIANGLES);
739 if(tf) glTexCoord2fv(tf[i].uv[0]);
740 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
742 if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no);
743 glVertex3fv(mvert->co);
745 if(tf) glTexCoord2fv(tf[i].uv[1]);
746 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
748 if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no);
749 glVertex3fv(mvert->co);
751 if(tf) glTexCoord2fv(tf[i].uv[2]);
752 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
754 if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no);
755 glVertex3fv(mvert->co);
758 if(tf) glTexCoord2fv(tf[i].uv[3]);
759 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
761 if(mf->flag&ME_SMOOTH) glNormal3sv(mvert->no);
762 glVertex3fv(mvert->co);
769 } else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
774 GPU_vertex_setup( dm );
775 GPU_normal_setup( dm );
778 /*if( realcol && dm->drawObject->colType == CD_TEXTURE_MCOL ) {
780 } else if( mcol && dm->drawObject->colType == CD_MCOL ) {
785 unsigned char *colors = MEM_mallocN(dm->getNumTessFaces(dm)*4*3*sizeof(unsigned char), "cdDM_drawFacesTex_common");
786 for( i=0; i < dm->getNumTessFaces(dm); i++ ) {
787 for( j=0; j < 4; j++ ) {
788 /* bgr -> rgb is intentional (and stupid), but how its stored internally */
789 colors[i*12+j*3] = col[i*4+j].b;
790 colors[i*12+j*3+1] = col[i*4+j].g;
791 colors[i*12+j*3+2] = col[i*4+j].r;
794 GPU_color3_upload(dm,colors);
797 dm->drawObject->colType = CD_TEXTURE_MCOL;
799 dm->drawObject->colType = CD_MCOL;
801 GPU_color_setup( dm );
804 if( !GPU_buffer_legacy(dm) ) {
805 /* warning!, this logic is incorrect, see bug [#27175]
806 * firstly, there are no checks for changes in context, such as texface image.
807 * secondly, drawParams() sets the GL context, so checking if there is a change
808 * from lastFlag is too late once glDrawArrays() runs, since drawing the arrays
809 * will use the modified, OpenGL settings.
811 * However its tricky to fix this without duplicating the internal logic
812 * of drawParams(), perhaps we need an argument like...
813 * drawParams(..., keep_gl_state_but_return_when_changed) ?.
815 * We could also just disable VBO's here, since texface may be deprecated - campbell.
818 glShadeModel( GL_SMOOTH );
820 for(i = 0; i < dm->drawObject->tot_triangle_point/3; i++) {
821 int actualFace = dm->drawObject->triangle_to_mface[i];
825 flag = drawParams(tf? &tf[actualFace]: NULL, (mcol != NULL), mf[actualFace].mat_nr);
829 orig = index[actualFace];
830 if(orig == ORIGINDEX_NONE) continue;
832 flag = drawParamsMapped(userData, orig);
836 flag = drawParamsMapped(userData, actualFace);
838 if( flag != lastFlag ) {
839 if( startFace < i ) {
840 if( lastFlag != 0 ) { /* if the flag is 0 it means the face is hidden or invisible */
841 if (lastFlag==1 && col)
845 glDrawArrays(GL_TRIANGLES,startFace*3,(i-startFace)*3);
852 if( startFace < dm->drawObject->tot_triangle_point/3 ) {
853 if( lastFlag != 0 ) { /* if the flag is 0 it means the face is hidden or invisible */
854 if (lastFlag==1 && col)
858 glDrawArrays(GL_TRIANGLES, startFace*3, dm->drawObject->tot_triangle_point - startFace*3);
864 glShadeModel( GL_FLAT );
868 static void cdDM_drawFacesTex(DerivedMesh *dm, int (*setDrawOptions)(MTFace *tface, int has_mcol, int matnr))
870 cdDM_drawFacesTex_common(dm, setDrawOptions, NULL, NULL);
873 static void cdDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index, int *drawSmooth_r), void *userData, int useColors, int (*setMaterial)(int, void *attribs),
874 int (*compareDrawOptions)(void *userData, int cur_index, int next_index))
876 CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
877 MVert *mv = cddm->mvert;
878 MFace *mf = cddm->mface;
880 float *nors= DM_get_tessface_data_layer(dm, CD_NORMAL);
881 int i, orig, *index = DM_get_tessface_data_layer(dm, CD_ORIGINDEX);
883 mc = DM_get_tessface_data_layer(dm, CD_ID_MCOL);
885 mc = DM_get_tessface_data_layer(dm, CD_WEIGHT_MCOL);
887 mc = DM_get_tessface_data_layer(dm, CD_MCOL);
889 cdDM_update_normals_from_pbvh(dm);
891 /* back-buffer always uses legacy since VBO's would need the
892 * color array temporarily overwritten for drawing, then reset. */
893 if( GPU_buffer_legacy(dm) || G.f & G_BACKBUFSEL) {
894 DEBUG_VBO( "Using legacy code. cdDM_drawMappedFaces\n" );
895 for(i = 0; i < dm->numFaceData; i++, mf++) {
896 int drawSmooth = (mf->flag & ME_SMOOTH);
899 orig= (index==NULL) ? i : *index++;
901 if(orig == ORIGINDEX_NONE)
902 draw= setMaterial(mf->mat_nr + 1, NULL);
903 else if (setDrawOptions != NULL)
904 draw= setDrawOptions(userData, orig, &drawSmooth);
907 unsigned char *cp = NULL;
910 cp = (unsigned char *)&mc[i * 4];
912 /* no need to set shading mode to flat because
913 * normals are already used to change shading */
914 glShadeModel(GL_SMOOTH);
915 glBegin(mf->v4?GL_QUADS:GL_TRIANGLES);
924 normal_quad_v3( nor,mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co);
926 normal_tri_v3( nor,mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co);
931 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
932 glVertex3fv(mv[mf->v1].co);
933 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
934 glVertex3fv(mv[mf->v2].co);
935 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
936 glVertex3fv(mv[mf->v3].co);
938 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
939 glVertex3fv(mv[mf->v4].co);
942 if(cp) glColor3ub(cp[3], cp[2], cp[1]);
943 glNormal3sv(mv[mf->v1].no);
944 glVertex3fv(mv[mf->v1].co);
945 if(cp) glColor3ub(cp[7], cp[6], cp[5]);
946 glNormal3sv(mv[mf->v2].no);
947 glVertex3fv(mv[mf->v2].co);
948 if(cp) glColor3ub(cp[11], cp[10], cp[9]);
949 glNormal3sv(mv[mf->v3].no);
950 glVertex3fv(mv[mf->v3].co);
952 if(cp) glColor3ub(cp[15], cp[14], cp[13]);
953 glNormal3sv(mv[mf->v4].no);
954 glVertex3fv(mv[mf->v4].co);
960 printf("eek in cddm draw mapped faces!\n");
966 else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */
968 GPU_vertex_setup(dm);
969 GPU_normal_setup(dm);
970 if( useColors && mc )
972 if( !GPU_buffer_legacy(dm) ) {
973 int tottri = dm->drawObject->tot_triangle_point/3;
974 glShadeModel(GL_SMOOTH);
977 /* avoid buffer problems in following code */
979 if(setDrawOptions == NULL) {
980 /* just draw the entire face array */
981 glDrawArrays(GL_TRIANGLES, 0, (tottri) * 3);
984 /* we need to check if the next material changes */
985 int next_actualFace= dm->drawObject->triangle_to_mface[0];
987 for( i = 0; i < tottri; i++ ) {
988 //int actualFace = dm->drawObject->triangle_to_mface[i];
989 int actualFace = next_actualFace;
990 MFace *mface= mf + actualFace;
991 int drawSmooth= (mface->flag & ME_SMOOTH);
996 next_actualFace= dm->drawObject->triangle_to_mface[i+1];
998 orig= (index==NULL) ? actualFace : index[actualFace];
1000 if(orig == ORIGINDEX_NONE)
1001 draw= setMaterial(mface->mat_nr + 1, NULL);
1002 else if (setDrawOptions != NULL)
1003 draw= setDrawOptions(userData, orig, &drawSmooth);
1005 /* Goal is to draw as long of a contiguous triangle
1006 array as possible, so draw when we hit either an
1007 invisible triangle or at the end of the array */
1009 /* flush buffer if current triangle isn't drawable or it's last triangle... */
1010 flush= !draw || i == tottri - 1;
1012 /* ... or when material setting is dissferent */
1013 flush|= mf[actualFace].mat_nr != mf[next_actualFace].mat_nr;
1015 if(!flush && compareDrawOptions) {
1016 int next_orig= (index==NULL) ? next_actualFace : index[next_actualFace];
1018 if(orig==ORIGINDEX_NONE || next_orig==ORIGINDEX_NONE) {
1021 /* also compare draw options and flush buffer if they're different
1022 need for face selection highlight in edit mode */
1023 flush|= compareDrawOptions(userData, orig, next_orig) == 0;
1028 int first= prevstart*3;
1029 int count= (i-prevstart+(draw ? 1 : 0))*3; /* Add one to the length if we're drawing at the end of the array */
1032 glDrawArrays(GL_TRIANGLES, first, count);
1039 glShadeModel(GL_FLAT);
1041 GPU_buffer_unbind();
1045 static void cdDM_drawMappedFacesTex(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
1047 cdDM_drawFacesTex_common(dm, NULL, setDrawOptions, userData);
1050 static void cddm_draw_attrib_vertex(DMVertexAttribs *attribs, MVert *mvert, int a, int index, int vert, int smoothnormal)
1054 /* orco texture coordinates */
1055 if(attribs->totorco) {
1056 if(attribs->orco.glTexco)
1057 glTexCoord3fv(attribs->orco.array[index]);
1059 glVertexAttrib3fvARB(attribs->orco.glIndex, attribs->orco.array[index]);
1062 /* uv texture coordinates */
1063 for(b = 0; b < attribs->tottface; b++) {
1064 MTFace *tf = &attribs->tface[b].array[a];
1066 if(attribs->tface[b].glTexco)
1067 glTexCoord2fv(tf->uv[vert]);
1069 glVertexAttrib2fvARB(attribs->tface[b].glIndex, tf->uv[vert]);
1073 for(b = 0; b < attribs->totmcol; b++) {
1074 MCol *cp = &attribs->mcol[b].array[a*4 + vert];
1076 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1077 glVertexAttrib4ubvARB(attribs->mcol[b].glIndex, col);
1080 /* tangent for normal mapping */
1081 if(attribs->tottang) {
1082 float *tang = attribs->tang.array[a*4 + vert];
1083 glVertexAttrib4fvARB(attribs->tang.glIndex, tang);
1088 glNormal3sv(mvert[index].no);
1090 /* vertex coordinate */
1091 glVertex3fv(mvert[index].co);
1094 static void cdDM_drawMappedFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs), int (*setDrawOptions)(void *userData, int index), void *userData)
1096 CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
1097 GPUVertexAttribs gattribs;
1098 DMVertexAttribs attribs;
1099 MVert *mvert = cddm->mvert;
1100 MFace *mface = cddm->mface;
1101 /* MTFace *tf = dm->getTessFaceDataArray(dm, CD_MTFACE); */ /* UNUSED */
1102 float (*nors)[3] = dm->getTessFaceDataArray(dm, CD_NORMAL);
1103 int a, b, dodraw, matnr, new_matnr;
1104 int orig, *index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
1106 cdDM_update_normals_from_pbvh(dm);
1111 glShadeModel(GL_SMOOTH);
1113 if( GPU_buffer_legacy(dm) || setDrawOptions != NULL ) {
1114 DEBUG_VBO( "Using legacy code. cdDM_drawMappedFacesGLSL\n" );
1115 memset(&attribs, 0, sizeof(attribs));
1119 for(a = 0; a < dm->numFaceData; a++, mface++) {
1120 const int smoothnormal = (mface->flag & ME_SMOOTH);
1121 new_matnr = mface->mat_nr + 1;
1123 if(new_matnr != matnr) {
1126 dodraw = setMaterial(matnr = new_matnr, &gattribs);
1128 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1136 else if(setDrawOptions) {
1137 orig = (index)? index[a]: a;
1139 if(orig == ORIGINDEX_NONE) {
1140 /* since the material is set by setMaterial(), faces with no
1141 * origin can be assumed to be generated by a modifier */
1145 else if(!setDrawOptions(userData, orig))
1151 glNormal3fv(nors[a]);
1154 /* TODO ideally a normal layer should always be available */
1157 normal_quad_v3( nor,mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co, mvert[mface->v4].co);
1159 normal_tri_v3( nor,mvert[mface->v1].co, mvert[mface->v2].co, mvert[mface->v3].co);
1165 cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v1, 0, smoothnormal);
1166 cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v2, 1, smoothnormal);
1167 cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, smoothnormal);
1170 cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v4, 3, smoothnormal);
1172 cddm_draw_attrib_vertex(&attribs, mvert, a, mface->v3, 2, smoothnormal);
1177 GPUBuffer *buffer = NULL;
1178 char *varray = NULL;
1179 int numdata = 0, elementsize = 0, offset;
1180 int start = 0, numfaces = 0 /* , prevdraw = 0 */ /* UNUSED */, curface = 0;
1184 GPUAttrib datatypes[GPU_MAX_ATTRIB]; /* TODO, messing up when switching materials many times - [#21056]*/
1185 memset(&attribs, 0, sizeof(attribs));
1187 GPU_vertex_setup(dm);
1188 GPU_normal_setup(dm);
1190 if( !GPU_buffer_legacy(dm) ) {
1191 for( i = 0; i < dm->drawObject->tot_triangle_point/3; i++ ) {
1193 a = dm->drawObject->triangle_to_mface[i];
1196 new_matnr = mface->mat_nr + 1;
1198 if(new_matnr != matnr ) {
1199 numfaces = curface - start;
1200 if( numfaces > 0 ) {
1204 if( numdata != 0 ) {
1206 GPU_buffer_unlock(buffer);
1208 GPU_interleaved_attrib_setup(buffer,datatypes,numdata);
1211 glDrawArrays(GL_TRIANGLES,start*3,numfaces*3);
1213 if( numdata != 0 ) {
1215 GPU_buffer_free(buffer);
1224 /* prevdraw = dodraw; */ /* UNUSED */
1225 dodraw = setMaterial(matnr = new_matnr, &gattribs);
1227 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1229 if(attribs.totorco) {
1230 datatypes[numdata].index = attribs.orco.glIndex;
1231 datatypes[numdata].size = 3;
1232 datatypes[numdata].type = GL_FLOAT;
1235 for(b = 0; b < attribs.tottface; b++) {
1236 datatypes[numdata].index = attribs.tface[b].glIndex;
1237 datatypes[numdata].size = 2;
1238 datatypes[numdata].type = GL_FLOAT;
1241 for(b = 0; b < attribs.totmcol; b++) {
1242 datatypes[numdata].index = attribs.mcol[b].glIndex;
1243 datatypes[numdata].size = 4;
1244 datatypes[numdata].type = GL_UNSIGNED_BYTE;
1247 if(attribs.tottang) {
1248 datatypes[numdata].index = attribs.tang.glIndex;
1249 datatypes[numdata].size = 4;
1250 datatypes[numdata].type = GL_FLOAT;
1253 if( numdata != 0 ) {
1254 elementsize = GPU_attrib_element_size( datatypes, numdata );
1255 buffer = GPU_buffer_alloc( elementsize*dm->drawObject->tot_triangle_point);
1256 if( buffer == NULL ) {
1257 GPU_buffer_unbind();
1258 dm->drawObject->legacy = 1;
1261 varray = GPU_buffer_lock_stream(buffer);
1262 if( varray == NULL ) {
1263 GPU_buffer_unbind();
1264 GPU_buffer_free(buffer);
1265 dm->drawObject->legacy = 1;
1270 /* if the buffer was set, dont use it again.
1271 * prevdraw was assumed true but didnt run so set to false - [#21036] */
1272 /* prevdraw= 0; */ /* UNUSED */
1281 if( numdata != 0 ) {
1283 if(attribs.totorco) {
1284 copy_v3_v3((float *)&varray[elementsize*curface*3],(float *)attribs.orco.array[mface->v1]);
1285 copy_v3_v3((float *)&varray[elementsize*curface*3+elementsize],(float *)attribs.orco.array[mface->v2]);
1286 copy_v3_v3((float *)&varray[elementsize*curface*3+elementsize*2],(float *)attribs.orco.array[mface->v3]);
1287 offset += sizeof(float)*3;
1289 for(b = 0; b < attribs.tottface; b++) {
1290 MTFace *tf = &attribs.tface[b].array[a];
1291 copy_v2_v2((float *)&varray[elementsize*curface*3+offset],tf->uv[0]);
1292 copy_v2_v2((float *)&varray[elementsize*curface*3+offset+elementsize],tf->uv[1]);
1294 copy_v2_v2((float *)&varray[elementsize*curface*3+offset+elementsize*2],tf->uv[2]);
1295 offset += sizeof(float)*2;
1297 for(b = 0; b < attribs.totmcol; b++) {
1298 MCol *cp = &attribs.mcol[b].array[a*4 + 0];
1300 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1301 copy_v4_v4_char((char *)&varray[elementsize*curface*3+offset], (char *)col);
1302 cp = &attribs.mcol[b].array[a*4 + 1];
1303 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1304 copy_v4_v4_char((char *)&varray[elementsize*curface*3+offset+elementsize], (char *)col);
1305 cp = &attribs.mcol[b].array[a*4 + 2];
1306 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1307 copy_v4_v4_char((char *)&varray[elementsize*curface*3+offset+elementsize*2], (char *)col);
1308 offset += sizeof(unsigned char)*4;
1310 if(attribs.tottang) {
1311 float *tang = attribs.tang.array[a*4 + 0];
1312 copy_v4_v4((float *)&varray[elementsize*curface*3+offset], tang);
1313 tang = attribs.tang.array[a*4 + 1];
1314 copy_v4_v4((float *)&varray[elementsize*curface*3+offset+elementsize], tang);
1315 tang = attribs.tang.array[a*4 + 2];
1316 copy_v4_v4((float *)&varray[elementsize*curface*3+offset+elementsize*2], tang);
1317 offset += sizeof(float)*4;
1323 if( numdata != 0 ) {
1325 if(attribs.totorco) {
1326 copy_v3_v3((float *)&varray[elementsize*curface*3],(float *)attribs.orco.array[mface->v3]);
1327 copy_v3_v3((float *)&varray[elementsize*curface*3+elementsize],(float *)attribs.orco.array[mface->v4]);
1328 copy_v3_v3((float *)&varray[elementsize*curface*3+elementsize*2],(float *)attribs.orco.array[mface->v1]);
1329 offset += sizeof(float)*3;
1331 for(b = 0; b < attribs.tottface; b++) {
1332 MTFace *tf = &attribs.tface[b].array[a];
1333 copy_v2_v2((float *)&varray[elementsize*curface*3+offset],tf->uv[2]);
1334 copy_v2_v2((float *)&varray[elementsize*curface*3+offset+elementsize],tf->uv[3]);
1335 copy_v2_v2((float *)&varray[elementsize*curface*3+offset+elementsize*2],tf->uv[0]);
1336 offset += sizeof(float)*2;
1338 for(b = 0; b < attribs.totmcol; b++) {
1339 MCol *cp = &attribs.mcol[b].array[a*4 + 2];
1341 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1342 copy_v4_v4_char((char *)&varray[elementsize*curface*3+offset], (char *)col);
1343 cp = &attribs.mcol[b].array[a*4 + 3];
1344 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1345 copy_v4_v4_char((char *)&varray[elementsize*curface*3+offset+elementsize], (char *)col);
1346 cp = &attribs.mcol[b].array[a*4 + 0];
1347 col[0]= cp->b; col[1]= cp->g; col[2]= cp->r; col[3]= cp->a;
1348 copy_v4_v4_char((char *)&varray[elementsize*curface*3+offset+elementsize*2], (char *)col);
1349 offset += sizeof(unsigned char)*4;
1351 if(attribs.tottang) {
1352 float *tang = attribs.tang.array[a*4 + 2];
1353 copy_v4_v4((float *)&varray[elementsize*curface*3+offset], tang);
1354 tang = attribs.tang.array[a*4 + 3];
1355 copy_v4_v4((float *)&varray[elementsize*curface*3+offset+elementsize], tang);
1356 tang = attribs.tang.array[a*4 + 0];
1357 copy_v4_v4((float *)&varray[elementsize*curface*3+offset+elementsize*2], tang);
1358 offset += sizeof(float)*4;
1366 numfaces = curface - start;
1367 if( numfaces > 0 ) {
1369 if( numdata != 0 ) {
1370 GPU_buffer_unlock(buffer);
1371 GPU_interleaved_attrib_setup(buffer,datatypes,numdata);
1373 glDrawArrays(GL_TRIANGLES,start*3,(curface-start)*3);
1376 GPU_buffer_unbind();
1378 GPU_buffer_free(buffer);
1381 glShadeModel(GL_FLAT);
1384 static void cdDM_drawFacesGLSL(DerivedMesh *dm, int (*setMaterial)(int, void *attribs))
1386 dm->drawMappedFacesGLSL(dm, setMaterial, NULL, NULL);
1389 static void cdDM_drawMappedFacesMat(DerivedMesh *dm,
1390 void (*setMaterial)(void *userData, int, void *attribs),
1391 int (*setFace)(void *userData, int index), void *userData)
1393 CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
1394 GPUVertexAttribs gattribs;
1395 DMVertexAttribs attribs;
1396 MVert *mvert = cddm->mvert;
1397 MFace *mf = cddm->mface;
1398 float (*nors)[3] = dm->getTessFaceDataArray(dm, CD_NORMAL);
1399 int a, matnr, new_matnr;
1400 int orig, *index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
1402 cdDM_update_normals_from_pbvh(dm);
1406 glShadeModel(GL_SMOOTH);
1408 memset(&attribs, 0, sizeof(attribs));
1412 for(a = 0; a < dm->numFaceData; a++, mf++) {
1413 const int smoothnormal = (mf->flag & ME_SMOOTH);
1416 new_matnr = mf->mat_nr + 1;
1418 if(new_matnr != matnr) {
1421 setMaterial(userData, matnr = new_matnr, &gattribs);
1422 DM_vertex_attributes_from_gpu(dm, &gattribs, &attribs);
1427 /* skipping faces */
1429 orig = (index)? index[a]: a;
1431 if(orig != ORIGINDEX_NONE && !setFace(userData, orig))
1438 glNormal3fv(nors[a]);
1441 /* TODO ideally a normal layer should always be available */
1445 normal_quad_v3( nor,mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co, mvert[mf->v4].co);
1447 normal_tri_v3( nor,mvert[mf->v1].co, mvert[mf->v2].co, mvert[mf->v3].co);
1454 cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v1, 0, smoothnormal);
1455 cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v2, 1, smoothnormal);
1456 cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v3, 2, smoothnormal);
1459 cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v4, 3, smoothnormal);
1461 cddm_draw_attrib_vertex(&attribs, mvert, a, mf->v3, 2, smoothnormal);
1465 glShadeModel(GL_FLAT);
1468 static void cdDM_drawMappedEdges(DerivedMesh *dm, int (*setDrawOptions)(void *userData, int index), void *userData)
1470 CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
1471 MVert *vert = cddm->mvert;
1472 MEdge *edge = cddm->medge;
1473 int i, orig, *index = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
1476 for(i = 0; i < dm->numEdgeData; i++, edge++) {
1479 if(setDrawOptions && orig == ORIGINDEX_NONE) continue;
1484 if(!setDrawOptions || setDrawOptions(userData, orig)) {
1485 glVertex3fv(vert[edge->v1].co);
1486 glVertex3fv(vert[edge->v2].co);
1492 static void cdDM_foreachMappedVert(
1494 void (*func)(void *userData, int index, float *co,
1495 float *no_f, short *no_s),
1498 MVert *mv = CDDM_get_verts(dm);
1499 int i, orig, *index = DM_get_vert_data_layer(dm, CD_ORIGINDEX);
1501 for(i = 0; i < dm->numVertData; i++, mv++) {
1504 if(orig == ORIGINDEX_NONE) continue;
1505 func(userData, orig, mv->co, NULL, mv->no);
1508 func(userData, i, mv->co, NULL, mv->no);
1512 static void cdDM_foreachMappedEdge(
1514 void (*func)(void *userData, int index,
1515 float *v0co, float *v1co),
1518 CDDerivedMesh *cddm = (CDDerivedMesh*) dm;
1519 MVert *mv = cddm->mvert;
1520 MEdge *med = cddm->medge;
1521 int i, orig, *index = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
1523 for(i = 0; i < dm->numEdgeData; i++, med++) {
1526 if(orig == ORIGINDEX_NONE) continue;
1527 func(userData, orig, mv[med->v1].co, mv[med->v2].co);
1530 func(userData, i, mv[med->v1].co, mv[med->v2].co);
1534 static void cdDM_foreachMappedFaceCenter(
1536 void (*func)(void *userData, int index,
1537 float *cent, float *no),
1540 CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1541 MVert *mv = cddm->mvert;
1542 MPoly *mf = cddm->mpoly;
1543 MLoop *ml = cddm->mloop;
1544 int i, j, orig, *index;
1546 index = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
1548 for(i = 0; i < dm->numPolyData; i++, mf++) {
1554 if(orig == ORIGINDEX_NONE) continue;
1559 ml = &cddm->mloop[mf->loopstart];
1560 cent[0] = cent[1] = cent[2] = 0.0f;
1561 for (j=0; j<mf->totloop; j++, ml++) {
1562 add_v3_v3v3(cent, cent, mv[ml->v].co);
1564 mul_v3_fl(cent, 1.0f / (float)j);
1566 ml = &cddm->mloop[mf->loopstart];
1568 normal_quad_v3(no, mv[ml->v].co, mv[(ml+1)->v].co,
1569 mv[(ml+2)->v].co, mv[(ml+3)->v].co);
1571 normal_tri_v3(no, mv[ml->v].co, mv[(ml+1)->v].co, mv[(ml+2)->v].co);
1574 func(userData, orig, cent, no);
1579 void CDDM_recalc_tesselation(DerivedMesh *dm)
1581 CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1583 dm->numFaceData = mesh_recalcTesselation(&dm->faceData, &dm->loopData,
1584 &dm->polyData, cddm->mvert, dm->numFaceData, dm->numLoopData,
1587 if (!CustomData_get_layer(&dm->faceData, CD_ORIGINDEX)) {
1588 int *polyIndex = CustomData_get_layer(&dm->faceData, CD_POLYINDEX);
1589 CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_REFERENCE, polyIndex, dm->numFaceData);
1592 cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1595 static void cdDM_free_internal(CDDerivedMesh *cddm)
1597 if(cddm->fmap) MEM_freeN(cddm->fmap);
1598 if(cddm->fmap_mem) MEM_freeN(cddm->fmap_mem);
1601 static void cdDM_release(DerivedMesh *dm)
1603 CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1605 if (DM_release(dm)) {
1606 cdDM_free_internal(cddm);
1611 int CDDM_Check(DerivedMesh *dm)
1613 return dm && dm->getMinMax == cdDM_getMinMax;
1616 /**************** CDDM interface functions ****************/
1617 static CDDerivedMesh *cdDM_create(const char *desc)
1619 CDDerivedMesh *cddm;
1622 cddm = MEM_callocN(sizeof(*cddm), desc);
1625 dm->getMinMax = cdDM_getMinMax;
1627 dm->getNumVerts = cdDM_getNumVerts;
1628 dm->getNumEdges = cdDM_getNumEdges;
1629 dm->getNumTessFaces = cdDM_getNumTessFaces;
1630 dm->getNumPolys = cdDM_getNumPolys;
1632 dm->getVert = cdDM_getVert;
1633 dm->getEdge = cdDM_getEdge;
1634 dm->getTessFace = cdDM_getTessFace;
1636 dm->copyVertArray = cdDM_copyVertArray;
1637 dm->copyEdgeArray = cdDM_copyEdgeArray;
1638 dm->copyTessFaceArray = cdDM_copyTessFaceArray;
1639 dm->copyLoopArray = cdDM_copyLoopArray;
1640 dm->copyPolyArray = cdDM_copyPolyArray;
1642 dm->getVertData = DM_get_vert_data;
1643 dm->getEdgeData = DM_get_edge_data;
1644 dm->getTessFaceData = DM_get_tessface_data;
1645 dm->getVertDataArray = DM_get_vert_data_layer;
1646 dm->getEdgeDataArray = DM_get_edge_data_layer;
1647 dm->getTessFaceDataArray = DM_get_tessface_data_layer;
1649 dm->calcNormals = CDDM_calc_normals;
1650 dm->recalcTesselation = CDDM_recalc_tesselation;
1652 dm->getVertCos = cdDM_getVertCos;
1653 dm->getVertCo = cdDM_getVertCo;
1654 dm->getVertNo = cdDM_getVertNo;
1656 dm->getPBVH = cdDM_getPBVH;
1657 dm->getFaceMap = cdDM_getFaceMap;
1659 dm->drawVerts = cdDM_drawVerts;
1661 dm->drawUVEdges = cdDM_drawUVEdges;
1662 dm->drawEdges = cdDM_drawEdges;
1663 dm->drawLooseEdges = cdDM_drawLooseEdges;
1664 dm->drawMappedEdges = cdDM_drawMappedEdges;
1666 dm->drawFacesSolid = cdDM_drawFacesSolid;
1667 dm->drawFacesColored = cdDM_drawFacesColored;
1668 dm->drawFacesTex = cdDM_drawFacesTex;
1669 dm->drawFacesGLSL = cdDM_drawFacesGLSL;
1670 dm->drawMappedFaces = cdDM_drawMappedFaces;
1671 dm->drawMappedFacesTex = cdDM_drawMappedFacesTex;
1672 dm->drawMappedFacesGLSL = cdDM_drawMappedFacesGLSL;
1673 dm->drawMappedFacesMat = cdDM_drawMappedFacesMat;
1675 dm->foreachMappedVert = cdDM_foreachMappedVert;
1676 dm->foreachMappedEdge = cdDM_foreachMappedEdge;
1677 dm->foreachMappedFaceCenter = cdDM_foreachMappedFaceCenter;
1679 dm->release = cdDM_release;
1684 DerivedMesh *CDDM_new(int numVerts, int numEdges, int numFaces, int numLoops, int numPolys)
1686 CDDerivedMesh *cddm = cdDM_create("CDDM_new dm");
1687 DerivedMesh *dm = &cddm->dm;
1689 DM_init(dm, DM_TYPE_CDDM, numVerts, numEdges, numFaces, numLoops, numPolys);
1691 CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts);
1692 CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
1693 CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numFaces);
1694 CustomData_add_layer(&dm->faceData, CD_POLYINDEX, CD_CALLOC, NULL, numFaces);
1695 CustomData_add_layer(&dm->polyData, CD_ORIGINDEX, CD_CALLOC, NULL, numPolys);
1697 CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
1698 CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
1699 CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numFaces);
1700 CustomData_add_layer(&dm->loopData, CD_MLOOP, CD_CALLOC, NULL, numLoops);
1701 CustomData_add_layer(&dm->polyData, CD_MPOLY, CD_CALLOC, NULL, numPolys);
1703 cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
1704 cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
1705 cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1706 cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
1707 cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
1712 DerivedMesh *CDDM_from_mesh(Mesh *mesh, Object *UNUSED(ob))
1714 CDDerivedMesh *cddm = cdDM_create("CDDM_from_mesh dm");
1715 DerivedMesh *dm = &cddm->dm;
1716 CustomDataMask mask = CD_MASK_MESH & (~CD_MASK_MDISPS);
1718 int *polyindex = NULL;
1720 /* this does a referenced copy, with an exception for fluidsim */
1722 DM_init(dm, DM_TYPE_CDDM, mesh->totvert, mesh->totedge, mesh->totface,
1723 mesh->totloop, mesh->totpoly);
1725 dm->deformedOnly = 1;
1727 alloctype= CD_REFERENCE;
1729 CustomData_merge(&mesh->vdata, &dm->vertData, mask, alloctype,
1731 CustomData_merge(&mesh->edata, &dm->edgeData, mask, alloctype,
1733 CustomData_merge(&mesh->fdata, &dm->faceData, mask|CD_MASK_POLYINDEX, alloctype,
1735 CustomData_merge(&mesh->ldata, &dm->loopData, mask, alloctype,
1737 CustomData_merge(&mesh->pdata, &dm->polyData, mask, alloctype,
1740 cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
1741 cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
1742 cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
1743 cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
1744 cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
1746 /* commented since even when CD_POLYINDEX was first added this line fails
1747 * on the default cube, (after editmode toggle too) - campbell */
1749 BLI_assert(CustomData_has_layer(&cddm->dm.faceData, CD_POLYINDEX));
1752 polyindex = CustomData_get_layer(&dm->faceData, CD_POLYINDEX);
1753 if (!CustomData_has_layer(&cddm->dm.faceData, CD_ORIGINDEX)) {
1754 CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_REFERENCE, polyindex, mesh->totface);
1760 static DerivedMesh *UNUSED_FUNCTION(CDDM_from_editmesh)(EditMesh *em, Mesh *UNUSED(me))
1762 DerivedMesh *dm = CDDM_new(BLI_countlist(&em->verts),
1763 BLI_countlist(&em->edges),
1764 BLI_countlist(&em->faces), 0, 0);
1765 CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1769 MVert *mvert = cddm->mvert;
1770 MEdge *medge = cddm->medge;
1771 MFace *mface = cddm->mface;
1774 dm->deformedOnly = 1;
1776 CustomData_merge(&em->vdata, &dm->vertData, CD_MASK_DERIVEDMESH,
1777 CD_CALLOC, dm->numVertData);
1778 /* CustomData_merge(&em->edata, &dm->edgeData, CD_MASK_DERIVEDMESH,
1779 CD_CALLOC, dm->numEdgeData); */
1780 CustomData_merge(&em->fdata, &dm->faceData, CD_MASK_DERIVEDMESH,
1781 CD_CALLOC, dm->numFaceData);
1782 CustomData_merge(&em->fdata, &dm->faceData, CD_MASK_DERIVEDMESH,
1783 CD_CALLOC, dm->numFaceData);
1785 /* set eve->hash to vert index */
1786 for(i = 0, eve = em->verts.first; eve; eve = eve->next, ++i)
1789 /* Need to be able to mark loose edges */
1790 for(eed = em->edges.first; eed; eed = eed->next) {
1793 for(efa = em->faces.first; efa; efa = efa->next) {
1797 if(efa->e4) efa->e4->f2 = 1;
1800 index = dm->getVertDataArray(dm, CD_ORIGINDEX);
1801 for(i = 0, eve = em->verts.first; i < dm->numVertData;
1802 i++, eve = eve->next, index++) {
1803 MVert *mv = &mvert[i];
1805 copy_v3_v3(mv->co, eve->co);
1807 normal_float_to_short_v3(mv->no, eve->no);
1808 mv->bweight = (unsigned char) (eve->bweight * 255.0f);
1814 CustomData_from_em_block(&em->vdata, &dm->vertData, eve->data, i);
1817 index = dm->getEdgeDataArray(dm, CD_ORIGINDEX);
1818 for(i = 0, eed = em->edges.first; i < dm->numEdgeData;
1819 i++, eed = eed->next, index++) {
1820 MEdge *med = &medge[i];
1822 med->v1 = eed->v1->tmp.l;
1823 med->v2 = eed->v2->tmp.l;
1824 med->crease = (unsigned char) (eed->crease * 255.0f);
1825 med->bweight = (unsigned char) (eed->bweight * 255.0f);
1826 med->flag = ME_EDGEDRAW|ME_EDGERENDER;
1828 if(eed->seam) med->flag |= ME_SEAM;
1829 if(eed->sharp) med->flag |= ME_SHARP;
1830 if(!eed->f2) med->flag |= ME_LOOSEEDGE;
1834 /* CustomData_from_em_block(&em->edata, &dm->edgeData, eed->data, i); */
1837 index = dm->getTessFaceDataArray(dm, CD_POLYINDEX);
1838 for(i = 0, efa = em->faces.first; i < dm->numFaceData;
1839 i++, efa = efa->next, index++) {
1840 MFace *mf = &mface[i];
1842 mf->v1 = efa->v1->tmp.l;
1843 mf->v2 = efa->v2->tmp.l;
1844 mf->v3 = efa->v3->tmp.l;
1845 mf->v4 = efa->v4 ? efa->v4->tmp.l : 0;
1846 mf->mat_nr = efa->mat_nr;
1847 mf->flag = efa->flag;
1851 CustomData_from_em_block(&em->fdata, &dm->faceData, efa->data, i);
1852 test_index_face(mf, &dm->faceData, i, efa->v4?4:3);
1858 DerivedMesh *CDDM_from_curve(Object *ob)
1860 return CDDM_from_curve_customDB(ob, &ob->disp);
1863 DerivedMesh *CDDM_from_curve_customDB(Object *ob, ListBase *dispbase)
1866 CDDerivedMesh *cddm;
1872 int totvert, totedge, totface, totloop, totpoly;
1874 if (nurbs_to_mdata_customdb(ob, dispbase, &allvert, &totvert, &alledge,
1875 &totedge, &allface, &allloop, &allpoly, &totface, &totloop, &totpoly) != 0) {
1876 /* Error initializing mdata. This often happens when curve is empty */
1877 return CDDM_new(0, 0, 0, 0, 0);
1880 dm = CDDM_new(totvert, totedge, totface, totloop, totpoly);
1881 dm->deformedOnly = 1;
1883 cddm = (CDDerivedMesh*)dm;
1885 memcpy(cddm->mvert, allvert, totvert*sizeof(MVert));
1886 memcpy(cddm->medge, alledge, totedge*sizeof(MEdge));
1887 memcpy(cddm->mface, allface, totface*sizeof(MFace));
1888 memcpy(cddm->mloop, allloop, totloop*sizeof(MLoop));
1889 memcpy(cddm->mpoly, allpoly, totpoly*sizeof(MPoly));
1900 static void loops_to_customdata_corners(BMesh *bm, CustomData *facedata,
1901 int cdindex, BMLoop *l3[3],
1902 int numCol, int numTex)
1905 BMFace *f = l3[0]->f;
1911 int i, j, hasWCol = CustomData_has_layer(&bm->ldata, CD_WEIGHT_MLOOPCOL);
1913 for(i=0; i < numTex; i++){
1914 texface = CustomData_get_n(facedata, CD_MTFACE, cdindex, i);
1915 texpoly = CustomData_bmesh_get_n(&bm->pdata, f->head.data, CD_MTEXPOLY, i);
1917 texface->tpage = texpoly->tpage;
1918 texface->flag = texpoly->flag;
1919 texface->transp = texpoly->transp;
1920 texface->mode = texpoly->mode;
1921 texface->tile = texpoly->tile;
1922 texface->unwrap = texpoly->unwrap;
1924 for (j=0; j<3; j++) {
1926 mloopuv = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_MLOOPUV, i);
1927 texface->uv[j][0] = mloopuv->uv[0];
1928 texface->uv[j][1] = mloopuv->uv[1];
1932 for(i=0; i < numCol; i++){
1933 mcol = CustomData_get_n(facedata, CD_MCOL, cdindex, i);
1935 for (j=0; j<3; j++) {
1937 mloopcol = CustomData_bmesh_get_n(&bm->ldata, l->head.data, CD_MLOOPCOL, i);
1938 mcol[j].r = mloopcol->r;
1939 mcol[j].g = mloopcol->g;
1940 mcol[j].b = mloopcol->b;
1941 mcol[j].a = mloopcol->a;
1946 mcol = CustomData_get(facedata, cdindex, CD_WEIGHT_MCOL);
1948 for (j=0; j<3; j++) {
1950 mloopcol = CustomData_bmesh_get(&bm->ldata, l->head.data, CD_WEIGHT_MLOOPCOL);
1951 mcol[j].r = mloopcol->r;
1952 mcol[j].g = mloopcol->g;
1953 mcol[j].b = mloopcol->b;
1954 mcol[j].a = mloopcol->a;
1959 DerivedMesh *CDDM_from_BMEditMesh(BMEditMesh *em, Mesh *UNUSED(me), int use_mdisps)
1961 DerivedMesh *dm = CDDM_new(em->bm->totvert, em->bm->totedge,
1962 em->tottri, em->bm->totloop, em->bm->totface);
1963 CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
1969 MVert *mvert = cddm->mvert;
1970 MEdge *medge = cddm->medge;
1971 MFace *mface = cddm->mface;
1972 MLoop *mloop = cddm->mloop;
1973 MPoly *mpoly = cddm->mpoly;
1974 int numCol = CustomData_number_of_layers(&em->bm->ldata, CD_MLOOPCOL);
1975 int numTex = CustomData_number_of_layers(&em->bm->pdata, CD_MTEXPOLY);
1976 int i, j, *index, *polyindex, add_orig;
1977 int has_crease, has_edge_bweight, has_vert_bweight;
1980 has_edge_bweight = CustomData_has_layer(&em->bm->edata, CD_BWEIGHT);
1981 has_vert_bweight = CustomData_has_layer(&em->bm->vdata, CD_BWEIGHT);
1982 has_crease = CustomData_has_layer(&em->bm->edata, CD_CREASE);
1984 dm->deformedOnly = 1;
1986 /*don't add origindex layer if one already exists*/
1987 add_orig = !CustomData_has_layer(&em->bm->pdata, CD_ORIGINDEX);
1989 flag = use_mdisps ? CD_MASK_DERIVEDMESH|CD_MASK_MDISPS : CD_MASK_DERIVEDMESH;
1991 /*don't process shapekeys, we only feed them through the modifier stack as needed,
1992 e.g. for applying modifiers or the like*/
1993 flag &= ~CD_SHAPEKEY;
1994 CustomData_merge(&em->bm->vdata, &dm->vertData, flag,
1995 CD_CALLOC, dm->numVertData);
1996 CustomData_merge(&em->bm->edata, &dm->edgeData, flag,
1997 CD_CALLOC, dm->numEdgeData);
1998 CustomData_merge(&em->bm->ldata, &dm->loopData, flag,
1999 CD_CALLOC, dm->numLoopData);
2000 CustomData_merge(&em->bm->pdata, &dm->polyData, flag,
2001 CD_CALLOC, dm->numPolyData);
2003 /*add tesselation mface layers*/
2004 CustomData_from_bmeshpoly(&dm->faceData, &dm->polyData, &dm->loopData, em->tottri);
2006 index = dm->getVertDataArray(dm, CD_ORIGINDEX);
2008 eve = BMIter_New(&iter, bm, BM_VERTS_OF_MESH, NULL);
2009 for (i=0; eve; eve=BMIter_Step(&iter), i++, index++) {
2010 MVert *mv = &mvert[i];
2012 copy_v3_v3(mv->co, eve->co);
2014 BM_SetIndex(eve, i); /* set_inline */
2016 normal_float_to_short_v3(mv->no, eve->no);
2018 mv->flag = BMFlags_To_MEFlags(eve);
2020 if (has_vert_bweight)
2021 mv->bweight = (unsigned char)(BM_GetCDf(&bm->vdata, eve, CD_BWEIGHT)*255.0f);
2023 if (add_orig) *index = i;
2025 CustomData_from_bmesh_block(&bm->vdata, &dm->vertData, eve->head.data, i);
2027 bm->elem_index_dirty &= ~BM_VERT;
2029 index = dm->getEdgeDataArray(dm, CD_ORIGINDEX);
2030 eed = BMIter_New(&iter, bm, BM_EDGES_OF_MESH, NULL);
2031 for (i=0; eed; eed=BMIter_Step(&iter), i++, index++) {
2032 MEdge *med = &medge[i];
2034 BM_SetIndex(eed, i); /* set_inline */
2036 med->v1 = BM_GetIndex(eed->v1);
2037 med->v2 = BM_GetIndex(eed->v2);
2040 med->crease = (unsigned char)(BM_GetCDf(&bm->edata, eed, CD_CREASE)*255.0f);
2041 if (has_edge_bweight)
2042 med->bweight = (unsigned char)(BM_GetCDf(&bm->edata, eed, CD_BWEIGHT)*255.0f);
2044 med->flag = BMFlags_To_MEFlags(eed);
2046 CustomData_from_bmesh_block(&bm->edata, &dm->edgeData, eed->head.data, i);
2047 if (add_orig) *index = i;
2049 bm->elem_index_dirty &= ~BM_EDGE;
2051 BM_ElemIndex_Ensure(em->bm, BM_FACE);
2053 polyindex = dm->getTessFaceDataArray(dm, CD_POLYINDEX);
2054 index = dm->getTessFaceDataArray(dm, CD_ORIGINDEX);
2055 for(i = 0; i < dm->numFaceData; i++, index++, polyindex++) {
2056 MFace *mf = &mface[i];
2057 BMLoop **l = em->looptris[i];
2060 mf->v1 = BM_GetIndex(l[0]->v);
2061 mf->v2 = BM_GetIndex(l[1]->v);
2062 mf->v3 = BM_GetIndex(l[2]->v);
2064 mf->mat_nr = efa->mat_nr;
2065 mf->flag = BMFlags_To_MEFlags(efa);
2067 *index = add_orig ? BM_GetIndex(efa) : *(int*)CustomData_bmesh_get(&bm->pdata, efa->head.data, CD_ORIGINDEX);
2068 *polyindex = BM_GetIndex(efa);
2070 loops_to_customdata_corners(bm, &dm->faceData, i, l, numCol, numTex);
2071 test_index_face(mf, &dm->faceData, i, 3);
2074 index = CustomData_get_layer(&dm->polyData, CD_ORIGINDEX);
2076 efa = BMIter_New(&iter, bm, BM_FACES_OF_MESH, NULL);
2077 for (i=0; efa; i++, efa=BMIter_Step(&iter), index++) {
2079 MPoly *mp = &mpoly[i];
2081 mp->totloop = efa->len;
2082 mp->flag = BMFlags_To_MEFlags(efa);
2084 mp->mat_nr = efa->mat_nr;
2086 BM_ITER(l, &liter, bm, BM_LOOPS_OF_FACE, efa) {
2087 mloop->v = BM_GetIndex(l->v);
2088 mloop->e = BM_GetIndex(l->e);
2089 CustomData_from_bmesh_block(&bm->ldata, &dm->loopData, l->head.data, j);
2095 CustomData_from_bmesh_block(&bm->pdata, &dm->polyData, efa->head.data, i);
2097 if (add_orig) *index = i;
2103 DerivedMesh *CDDM_copy(DerivedMesh *source, int faces_from_tessfaces)
2105 CDDerivedMesh *cddm = cdDM_create("CDDM_copy cddm");
2106 DerivedMesh *dm = &cddm->dm;
2107 int numVerts = source->numVertData;
2108 int numEdges = source->numEdgeData;
2109 int numFaces = source->numFaceData;
2110 int numLoops = source->numLoopData;
2111 int numPolys = source->numPolyData;
2113 /* ensure these are created if they are made on demand */
2114 source->getVertDataArray(source, CD_ORIGINDEX);
2115 source->getEdgeDataArray(source, CD_ORIGINDEX);
2116 source->getTessFaceDataArray(source, CD_ORIGINDEX);
2118 /* this initializes dm, and copies all non mvert/medge/mface layers */
2119 DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numFaces,
2120 numLoops, numPolys);
2121 dm->deformedOnly = source->deformedOnly;
2123 CustomData_copy_data(&source->vertData, &dm->vertData, 0, 0, numVerts);
2124 CustomData_copy_data(&source->edgeData, &dm->edgeData, 0, 0, numEdges);
2125 CustomData_copy_data(&source->faceData, &dm->faceData, 0, 0, numFaces);
2127 /* now add mvert/medge/mface layers */
2128 cddm->mvert = source->dupVertArray(source);
2129 cddm->medge = source->dupEdgeArray(source);
2130 cddm->mface = source->dupTessFaceArray(source);
2132 CustomData_add_layer(&dm->vertData, CD_MVERT, CD_ASSIGN, cddm->mvert, numVerts);
2133 CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_ASSIGN, cddm->medge, numEdges);
2134 CustomData_add_layer(&dm->faceData, CD_MFACE, CD_ASSIGN, cddm->mface, numFaces);
2136 if (!faces_from_tessfaces)
2137 DM_DupPolys(source, dm);
2139 CDDM_tessfaces_to_faces(dm);
2141 cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
2142 cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
2144 /* BMESH_TODO: Find out why this is necessary (or else find a way to remove
2145 it). If it is necessary, add a comment explaining why. */
2146 CDDM_recalc_tesselation((DerivedMesh *)cddm);
2151 /* note, the CD_ORIGINDEX layers are all 0, so if there is a direct
2152 * relationship betwen mesh data this needs to be set by the caller. */
2153 DerivedMesh *CDDM_from_template(DerivedMesh *source,
2154 int numVerts, int numEdges, int numFaces,
2155 int numLoops, int numPolys)
2157 CDDerivedMesh *cddm = cdDM_create("CDDM_from_template dest");
2158 DerivedMesh *dm = &cddm->dm;
2160 /* ensure these are created if they are made on demand */
2161 source->getVertDataArray(source, CD_ORIGINDEX);
2162 source->getEdgeDataArray(source, CD_ORIGINDEX);
2163 source->getTessFaceDataArray(source, CD_ORIGINDEX);
2165 /* this does a copy of all non mvert/medge/mface layers */
2166 DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numFaces, numLoops, numPolys);
2168 /* now add mvert/medge/mface layers */
2169 CustomData_add_layer(&dm->vertData, CD_MVERT, CD_CALLOC, NULL, numVerts);
2170 CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
2171 CustomData_add_layer(&dm->faceData, CD_MFACE, CD_CALLOC, NULL, numFaces);
2172 CustomData_add_layer(&dm->loopData, CD_MLOOP, CD_CALLOC, NULL, numLoops);
2173 CustomData_add_layer(&dm->polyData, CD_MPOLY, CD_CALLOC, NULL, numPolys);
2175 if(!CustomData_get_layer(&dm->vertData, CD_ORIGINDEX))
2176 CustomData_add_layer(&dm->vertData, CD_ORIGINDEX, CD_CALLOC, NULL, numVerts);
2177 if(!CustomData_get_layer(&dm->edgeData, CD_ORIGINDEX))
2178 CustomData_add_layer(&dm->edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
2179 if(!CustomData_get_layer(&dm->faceData, CD_ORIGINDEX))
2180 CustomData_add_layer(&dm->faceData, CD_ORIGINDEX, CD_CALLOC, NULL, numFaces);
2181 if(!CustomData_get_layer(&dm->faceData, CD_POLYINDEX))
2182 CustomData_add_layer(&dm->faceData, CD_POLYINDEX, CD_CALLOC, NULL, numFaces);
2184 cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT);
2185 cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
2186 cddm->mface = CustomData_get_layer(&dm->faceData, CD_MFACE);
2187 cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP);
2188 cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY);
2193 void CDDM_apply_vert_coords(DerivedMesh *dm, float (*vertCoords)[3])
2195 CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2199 /* this will just return the pointer if it wasn't a referenced layer */
2200 vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT);
2203 for(i = 0; i < dm->numVertData; ++i, ++vert)
2204 copy_v3_v3(vert->co, vertCoords[i]);
2207 void CDDM_apply_vert_normals(DerivedMesh *dm, short (*vertNormals)[3])
2209 CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2213 /* this will just return the pointer if it wasn't a referenced layer */
2214 vert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT);
2217 for(i = 0; i < dm->numVertData; ++i, ++vert)
2218 copy_v3_v3_short(vert->no, vertNormals[i]);
2221 void CDDM_calc_normals(DerivedMesh *dm)
2223 CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2224 float (*face_nors)[3] = NULL;
2226 if(dm->numVertData == 0) return;
2228 /* we don't want to overwrite any referenced layers */
2229 cddm->mvert = CustomData_duplicate_referenced_layer(&dm->vertData, CD_MVERT);
2231 if (dm->numFaceData == 0) {
2232 /* No tesselation on this mesh yet, need to calculate one */
2233 CDDM_recalc_tesselation(dm);
2236 /* A tesselation already exists, it should always have a CD_POLYINDEX */
2237 BLI_assert(CustomData_has_layer(&dm->faceData, CD_POLYINDEX));
2238 CustomData_free_layers(&dm->faceData, CD_NORMAL, dm->numFaceData);
2241 face_nors = MEM_mallocN(sizeof(float)*3*dm->numFaceData, "face_nors");
2243 /* calculate face normals */
2244 mesh_calc_normals(cddm->mvert, dm->numVertData, CDDM_get_loops(dm), CDDM_get_polys(dm),
2245 dm->numLoopData, dm->numPolyData, NULL, cddm->mface, dm->numFaceData,
2246 CustomData_get_layer(&dm->faceData, CD_POLYINDEX), face_nors);
2248 CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_ASSIGN,
2249 face_nors, dm->numFaceData);
2255 vtargetmap is a table that maps vertices to target vertices. a value of -1
2256 indicates a vertex is a target, and is to be kept.
2258 this frees dm, and returns a new one.
2260 this is a really horribly written function. ger. - joeedh
2263 DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, int *vtargetmap)
2265 CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2266 CDDerivedMesh *cddm2 = NULL;
2267 MVert *mv, *mvert = NULL;
2268 BLI_array_declare(mvert);
2269 MEdge *me, *medge = NULL;
2270 BLI_array_declare(medge);
2271 MPoly *mp, *mpoly = NULL;
2272 BLI_array_declare(mpoly);
2273 MLoop *ml, *mloop = NULL;
2274 BLI_array_declare(mloop);
2275 EdgeHash *ehash = BLI_edgehash_new();
2276 int *newv = NULL, *newe = NULL, *newl = NULL;
2277 int *oldv = NULL, *olde = NULL, *oldl = NULL, *oldp = NULL;
2278 BLI_array_declare(oldv); BLI_array_declare(olde); BLI_array_declare(oldl); BLI_array_declare(oldp);
2279 int i, j, c, totloop, totpoly;
2281 totloop = dm->numLoopData;
2282 totpoly = dm->numPolyData;
2284 newv = MEM_callocN(sizeof(int)*dm->numVertData, "newv vtable CDDM_merge_verts");
2285 newe = MEM_callocN(sizeof(int)*dm->numEdgeData, "newv etable CDDM_merge_verts");
2286 newl = MEM_callocN(sizeof(int)*totloop, "newv ltable CDDM_merge_verts");
2288 /*fill newl with destination vertex indices*/
2291 for (i=0; i<dm->numVertData; i++, mv++) {
2292 if (vtargetmap[i] == -1) {
2293 BLI_array_append(oldv, i);
2295 BLI_array_append(mvert, *mv);
2299 /*now link target vertices to destination indices*/
2300 for (i=0; i<dm->numVertData; i++) {
2301 if (vtargetmap[i] != -1) {
2302 newv[i] = newv[vtargetmap[i]];
2306 /*find-replace merged vertices with target vertices*/
2309 for (i=0; i<totloop; i++, ml++) {
2313 if (vtargetmap[ml->v] != -1)
2314 ml->v = vtargetmap[ml->v];
2317 /*now go through and fix edges and faces*/
2320 for (i=0; i<dm->numEdgeData; i++, me++) {
2323 if (me->v1 == me->v2) {
2328 if (vtargetmap[me->v1] != -1)
2329 v1 = vtargetmap[me->v1];
2333 if (vtargetmap[me->v2] != -1)
2334 v2 = vtargetmap[me->v2];
2338 if (BLI_edgehash_haskey(ehash, v1, v2)) {
2339 newe[i] = GET_INT_FROM_POINTER(BLI_edgehash_lookup(ehash, v1, v2));
2341 BLI_array_append(olde, i);
2343 BLI_array_append(medge, *me);
2344 BLI_edgehash_insert(ehash, v1, v2, SET_INT_IN_POINTER(c));
2350 for (i=0; i<totpoly; i++, mp++) {
2353 ml = cddm->mloop + mp->loopstart;
2356 for (j=0; j<mp->totloop; j++, ml++) {
2360 me = cddm->medge + ml->e;
2361 if (me->v1 != me->v2) {
2362 BLI_array_append(oldl, j+mp->loopstart);
2363 BLI_array_append(mloop, *ml);
2364 newl[j+mp->loopstart] = BLI_array_count(mloop)-1;
2372 mp2 = BLI_array_append_r(mpoly, *mp);
2374 mp2->loopstart = BLI_array_count(mloop) - c;
2376 BLI_array_append(oldp, i);
2380 cddm2 = (CDDerivedMesh*) CDDM_from_template((DerivedMesh*)cddm, BLI_array_count(mvert), BLI_array_count(medge), 0, BLI_array_count(mloop), BLI_array_count(mpoly));
2382 /*update edge indices and copy customdata*/
2384 for (i=0; i<cddm2->dm.numEdgeData; i++, me++) {
2385 if (newv[me->v1] != -1)
2386 me->v1 = newv[me->v1];
2387 if (newv[me->v2] != -1)
2388 me->v2 = newv[me->v2];
2390 CustomData_copy_data(&dm->edgeData, &cddm2->dm.edgeData, olde[i], i, 1);
2393 /*update loop indices and copy customdata*/
2395 for (i=0; i<cddm2->dm.numLoopData; i++, ml++) {
2396 if (newe[ml->e] != -1)
2397 ml->e = newe[ml->e];
2398 if (newv[ml->v] != -1)
2399 ml->v = newv[ml->v];
2401 CustomData_copy_data(&dm->loopData, &cddm2->dm.loopData, oldl[i], i, 1);
2404 /*copy vertex customdata*/
2406 for (i=0; i<cddm2->dm.numVertData; i++, mv++) {
2407 CustomData_copy_data(&dm->vertData, &cddm2->dm.vertData, oldv[i], i, 1);
2410 /*copy poly customdata*/
2412 for (i=0; i<cddm2->dm.numPolyData; i++, mp++) {
2413 CustomData_copy_data(&dm->polyData, &cddm2->dm.polyData, oldp[i], i, 1);
2416 /*copy over data. CustomData_add_layer can do this, need to look it up.*/
2417 memcpy(cddm2->mvert, mvert, sizeof(MVert)*BLI_array_count(mvert));
2418 memcpy(cddm2->medge, medge, sizeof(MEdge)*BLI_array_count(medge));
2419 memcpy(cddm2->mloop, mloop, sizeof(MLoop)*BLI_array_count(mloop));
2420 memcpy(cddm2->mpoly, mpoly, sizeof(MPoly)*BLI_array_count(mpoly));
2421 BLI_array_free(mvert); BLI_array_free(medge); BLI_array_free(mloop); BLI_array_free(mpoly);
2423 CDDM_recalc_tesselation((DerivedMesh*)cddm2);
2440 BLI_edgehash_free(ehash, NULL);
2442 /*free old derivedmesh*/
2446 return (DerivedMesh*)cddm2;
2450 void CDDM_calc_edges(DerivedMesh *dm)
2452 CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2453 CustomData edgeData;
2454 EdgeHashIterator *ehi;
2455 MFace *mf = cddm->mface;
2457 EdgeHash *eh = BLI_edgehash_new();
2458 int i, *index, numEdges, maxFaces = dm->numFaceData;
2460 for (i = 0; i < maxFaces; i++, mf++) {
2461 if (!BLI_edgehash_haskey(eh, mf->v1, mf->v2))
2462 BLI_edgehash_insert(eh, mf->v1, mf->v2, NULL);
2463 if (!BLI_edgehash_haskey(eh, mf->v2, mf->v3))
2464 BLI_edgehash_insert(eh, mf->v2, mf->v3, NULL);
2467 if (!BLI_edgehash_haskey(eh, mf->v3, mf->v4))
2468 BLI_edgehash_insert(eh, mf->v3, mf->v4, NULL);
2469 if (!BLI_edgehash_haskey(eh, mf->v4, mf->v1))
2470 BLI_edgehash_insert(eh, mf->v4, mf->v1, NULL);
2472 if (!BLI_edgehash_haskey(eh, mf->v3, mf->v1))
2473 BLI_edgehash_insert(eh, mf->v3, mf->v1, NULL);
2477 numEdges = BLI_edgehash_size(eh);
2479 /* write new edges into a temporary CustomData */
2480 memset(&edgeData, 0, sizeof(edgeData));
2481 CustomData_add_layer(&edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
2482 CustomData_add_layer(&edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
2484 ehi = BLI_edgehashIterator_new(eh);
2485 med = CustomData_get_layer(&edgeData, CD_MEDGE);
2486 index = CustomData_get_layer(&edgeData, CD_ORIGINDEX);
2487 for(i = 0; !BLI_edgehashIterator_isDone(ehi);
2488 BLI_edgehashIterator_step(ehi), ++i, ++med, ++index) {
2489 BLI_edgehashIterator_getKey(ehi, (int*)&med->v1, (int*)&med->v2);
2491 med->flag = ME_EDGEDRAW|ME_EDGERENDER;
2492 *index = ORIGINDEX_NONE;
2494 BLI_edgehashIterator_free(ehi);
2496 /* free old CustomData and assign new one */
2497 CustomData_free(&dm->edgeData, dm->numEdgeData);
2498 dm->edgeData = edgeData;
2499 dm->numEdgeData = numEdges;
2501 cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
2503 BLI_edgehash_free(eh, NULL);
2506 /* warning, this uses existing edges but CDDM_calc_edges() doesn't */
2507 void CDDM_calc_edges_poly(DerivedMesh *dm)
2509 CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2510 CustomData edgeData;
2511 EdgeHashIterator *ehi;
2512 MPoly *mp = cddm->mpoly;
2515 EdgeHash *eh = BLI_edgehash_new();
2518 int i, j, *index, numEdges = cddm->dm.numEdgeData, maxFaces = dm->numPolyData;
2520 eindex = DM_get_edge_data_layer(dm, CD_ORIGINDEX);
2524 for (i=0; i < numEdges; i++, med++) {
2525 BLI_edgehash_insert(eh, med->v1, med->v2, SET_INT_IN_POINTER(i+1));
2529 for (i=0; i < maxFaces; i++, mp++) {
2530 ml = cddm->mloop + mp->loopstart;
2531 for (j=0; j<mp->totloop; j++, ml++) {
2533 v2 = (cddm->mloop + mp->loopstart + ((j+1)%mp->totloop))->v;
2534 if (!BLI_edgehash_haskey(eh, v1, v2)) {
2535 BLI_edgehash_insert(eh, v1, v2, NULL);
2540 numEdges = BLI_edgehash_size(eh);
2542 /* write new edges into a temporary CustomData */
2543 memset(&edgeData, 0, sizeof(edgeData));
2544 CustomData_add_layer(&edgeData, CD_MEDGE, CD_CALLOC, NULL, numEdges);
2545 CustomData_add_layer(&edgeData, CD_ORIGINDEX, CD_CALLOC, NULL, numEdges);
2547 ehi = BLI_edgehashIterator_new(eh);
2548 med = CustomData_get_layer(&edgeData, CD_MEDGE);
2549 index = CustomData_get_layer(&edgeData, CD_ORIGINDEX);
2550 for(i = 0; !BLI_edgehashIterator_isDone(ehi);
2551 BLI_edgehashIterator_step(ehi), ++i, ++med, ++index) {
2552 BLI_edgehashIterator_getKey(ehi, (int*)&med->v1, (int*)&med->v2);
2553 j = GET_INT_FROM_POINTER(BLI_edgehashIterator_getValue(ehi));
2555 med->flag = ME_EDGEDRAW|ME_EDGERENDER;
2556 *index = j==0 ? ORIGINDEX_NONE : eindex[j-1];
2558 BLI_edgehashIterator_setValue(ehi, SET_INT_IN_POINTER(i));
2560 BLI_edgehashIterator_free(ehi);
2562 /* free old CustomData and assign new one */
2563 CustomData_free(&dm->edgeData, dm->numEdgeData);
2564 dm->edgeData = edgeData;
2565 dm->numEdgeData = numEdges;
2567 cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE);
2570 for (i=0; i < maxFaces; i++, mp++) {
2571 ml = cddm->mloop + mp->loopstart;
2572 for (j=0; j<mp->totloop; j++, ml++) {
2574 v2 = (cddm->mloop + mp->loopstart + ((j+1)%mp->totloop))->v;
2575 ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, v1, v2));
2579 BLI_edgehash_free(eh, NULL);
2582 void CDDM_lower_num_verts(DerivedMesh *dm, int numVerts)
2584 if (numVerts < dm->numVertData)
2585 CustomData_free_elem(&dm->vertData, numVerts, dm->numVertData-numVerts);
2587 dm->numVertData = numVerts;
2590 void CDDM_lower_num_edges(DerivedMesh *dm, int numEdges)
2592 if (numEdges < dm->numEdgeData)
2593 CustomData_free_elem(&dm->edgeData, numEdges, dm->numEdgeData-numEdges);
2595 dm->numEdgeData = numEdges;
2598 void CDDM_lower_num_faces(DerivedMesh *dm, int numFaces)
2600 if (numFaces < dm->numFaceData)
2601 CustomData_free_elem(&dm->faceData, numFaces, dm->numFaceData-numFaces);
2603 dm->numFaceData = numFaces;
2606 MVert *CDDM_get_vert(DerivedMesh *dm, int index)
2608 return &((CDDerivedMesh*)dm)->mvert[index];
2611 MEdge *CDDM_get_edge(DerivedMesh *dm, int index)
2613 return &((CDDerivedMesh*)dm)->medge[index];
2616 MFace *CDDM_get_tessface(DerivedMesh *dm, int index)
2618 return &((CDDerivedMesh*)dm)->mface[index];
2621 MVert *CDDM_get_verts(DerivedMesh *dm)
2623 return ((CDDerivedMesh*)dm)->mvert;
2626 MEdge *CDDM_get_edges(DerivedMesh *dm)
2628 return ((CDDerivedMesh*)dm)->medge;
2631 MFace *CDDM_get_tessfaces(DerivedMesh *dm)
2633 return ((CDDerivedMesh*)dm)->mface;
2636 MLoop *CDDM_get_loops(DerivedMesh *dm)
2638 return ((CDDerivedMesh*)dm)->mloop;
2641 MPoly *CDDM_get_polys(DerivedMesh *dm)
2643 return ((CDDerivedMesh*)dm)->mpoly;
2646 void CDDM_tessfaces_to_faces(DerivedMesh *dm)
2648 /*converts mfaces to mpolys/mloops*/
2649 CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2652 EdgeHash *eh = BLI_edgehash_new();
2655 /*ensure we have all the edges we need*/
2656 CDDM_calc_edges(dm);
2660 for (i=0; i<cddm->dm.numEdgeData; i++, me++) {
2661 BLI_edgehash_insert(eh, me->v1, me->v2, SET_INT_IN_POINTER(i));
2666 for (i=0; i<cddm->dm.numFaceData; i++, mf++) {
2667 totloop += mf->v4 ? 4 : 3;
2670 CustomData_free(&cddm->dm.polyData, cddm->dm.numPolyData);
2671 CustomData_free(&cddm->dm.loopData, cddm->dm.numLoopData);
2673 cddm->dm.numLoopData = totloop;
2674 cddm->dm.numPolyData = cddm->dm.numFaceData;
2681 cddm->mloop = MEM_callocN(sizeof(MLoop)*totloop, "cddm->mloop in CDDM_tessfaces_to_faces");
2682 cddm->mpoly = MEM_callocN(sizeof(MPoly)*cddm->dm.numFaceData, "cddm->mpoly in CDDM_tessfaces_to_faces");
2684 CustomData_add_layer(&cddm->dm.loopData, CD_MLOOP, CD_ASSIGN, cddm->mloop, totloop);
2685 CustomData_add_layer(&cddm->dm.polyData, CD_MPOLY, CD_ASSIGN, cddm->mpoly, cddm->dm.numPolyData);
2686 CustomData_merge(&cddm->dm.faceData, &cddm->dm.polyData,
2687 CD_MASK_ORIGINDEX, CD_DUPLICATE, cddm->dm.numFaceData);
2689 polyindex = CustomData_get_layer(&cddm->dm.faceData, CD_POLYINDEX);
2695 for (i=0; i<cddm->dm.numFaceData; i++, mf++, mp++) {
2696 mp->flag = mf->flag;
2698 mp->mat_nr = mf->mat_nr;
2699 mp->totloop = mf->v4 ? 4 : 3;
2702 ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, mf->v1, mf->v2));
2706 ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, mf->v2, mf->v3));
2710 ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, mf->v3, mf->v4?mf->v4:mf->v1));
2715 ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(eh, mf->v4, mf->v1));
2723 BLI_edgehash_free(eh, NULL);
2726 void CDDM_set_mvert(DerivedMesh *dm, MVert *mvert)
2728 CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2730 if (!CustomData_has_layer(&dm->vertData, CD_MVERT))
2731 CustomData_add_layer(&dm->vertData, CD_MVERT, CD_ASSIGN, mvert, dm->numVertData);
2733 cddm->mvert = mvert;
2736 void CDDM_set_medge(DerivedMesh *dm, MEdge *medge)
2738 CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2740 if (!CustomData_has_layer(&dm->edgeData, CD_MEDGE))
2741 CustomData_add_layer(&dm->edgeData, CD_MEDGE, CD_ASSIGN, medge, dm->numEdgeData);
2743 cddm->medge = medge;
2746 void CDDM_set_mface(DerivedMesh *dm, MFace *mface)
2748 CDDerivedMesh *cddm = (CDDerivedMesh*)dm;
2750 if (!CustomData_has_layer(&dm->faceData, CD_MFACE))
2751 CustomData_add_layer(&dm->faceData, CD_MFACE, CD_ASSIGN, mface, dm->numFaceData);
2753 cddm->mface = mface;