diff options
Diffstat (limited to 'source/blender/blenkernel/intern/cdderivedmesh.c')
-rw-r--r-- | source/blender/blenkernel/intern/cdderivedmesh.c | 106 |
1 files changed, 59 insertions, 47 deletions
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index b3e702ceee9..ca81e216006 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -54,7 +54,7 @@ #include "MEM_guardedalloc.h" -#include "gpu_buffers.h" +#include "GPU_buffers.h" #include "GPU_draw.h" #include "GPU_extensions.h" #include "GPU_material.h" @@ -74,6 +74,7 @@ typedef struct { /* Cached */ struct PBVH *pbvh; + int pbvh_draw; /* Mesh connectivity */ struct ListBase *fmap; struct IndexNode *fmap_mem; @@ -185,9 +186,20 @@ static ListBase *cdDM_getFaceMap(Object *ob, DerivedMesh *dm) return cddm->fmap; } +static int can_pbvh_draw(Object *ob, DerivedMesh *dm) +{ + CDDerivedMesh *cddm = (CDDerivedMesh*) dm; + Mesh *me= (ob)? ob->data: NULL; + + if(ob->sculpt->modifiers_active) return 0; + + return (cddm->mvert == me->mvert) || ob->sculpt->kb; +} + static struct PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm) { CDDerivedMesh *cddm = (CDDerivedMesh*) dm; + Mesh *me= (ob)? ob->data: NULL; if(!ob) { cddm->pbvh= NULL; @@ -196,13 +208,17 @@ static struct PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm) if(!ob->sculpt) return NULL; - if(ob->sculpt->pbvh) + if(ob->sculpt->pbvh) { cddm->pbvh= ob->sculpt->pbvh; + cddm->pbvh_draw = can_pbvh_draw(ob, dm); + } + /* always build pbvh from original mesh, and only use it for drawing if + this derivedmesh is just original mesh. it's the multires subsurf dm + that this is actually for, to support a pbvh on a modified mesh */ if(!cddm->pbvh && ob->type == OB_MESH) { - Mesh *me= ob->data; - cddm->pbvh = BLI_pbvh_new(); + cddm->pbvh_draw = can_pbvh_draw(ob, dm); BLI_pbvh_build_mesh(cddm->pbvh, me->mface, me->mvert, me->totface, me->totvert); } @@ -225,7 +241,8 @@ static void cdDM_drawVerts(DerivedMesh *dm) else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */ GPU_vertex_setup(dm); if( !GPU_buffer_legacy(dm) ) { - glDrawArrays(GL_POINTS,0,dm->drawObject->nelements); + if(dm->drawObject->nelements) glDrawArrays(GL_POINTS,0, dm->drawObject->nelements); + else glDrawArrays(GL_POINTS,0, dm->drawObject->nlooseverts); } GPU_buffer_unbind(); } @@ -417,7 +434,7 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm, glVertex3fv(mvert[index].co); \ } - if(cddm->pbvh) { + if(cddm->pbvh && cddm->pbvh_draw) { if(dm->numFaceData) { float (*face_nors)[3] = CustomData_get_layer(&dm->faceData, CD_NORMAL); @@ -728,7 +745,7 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, if( flag != lastFlag ) { if( startFace < i ) { if( lastFlag != 0 ) { /* if the flag is 0 it means the face is hidden or invisible */ - if (lastFlag==1 && mcol) + if (lastFlag==1 && col) GPU_color_switch(1); else GPU_color_switch(0); @@ -741,7 +758,7 @@ static void cdDM_drawFacesTex_common(DerivedMesh *dm, } if( startFace < dm->drawObject->nelements/3 ) { if( lastFlag != 0 ) { /* if the flag is 0 it means the face is hidden or invisible */ - if (lastFlag==1 && mcol) + if (lastFlag==1 && col) GPU_color_switch(1); else GPU_color_switch(0); @@ -847,47 +864,41 @@ static void cdDM_drawMappedFaces(DerivedMesh *dm, int (*setDrawOptions)(void *us } } else { /* use OpenGL VBOs or Vertex Arrays instead for better, faster rendering */ - int state = 1; - int prevstate = 1; int prevstart = 0; GPU_vertex_setup(dm); GPU_normal_setup(dm); if( useColors && mc ) GPU_color_setup(dm); if( !GPU_buffer_legacy(dm) ) { + int tottri = dm->drawObject->nelements/3; glShadeModel(GL_SMOOTH); - for( i = 0; i < dm->drawObject->nelements/3; i++ ) { + + for( i = 0; i < tottri; i++ ) { int actualFace = dm->drawObject->faceRemap[i]; int drawSmooth = (mf[actualFace].flag & ME_SMOOTH); - int dontdraw = 0; + int draw = 1; + if(index) { orig = index[actualFace]; if(setDrawOptions && orig == ORIGINDEX_NONE) - dontdraw = 1; + draw = 0; } else orig = actualFace; - if( dontdraw ) { - state = 0; - } - else { - if(!setDrawOptions || setDrawOptions(userData, orig, &drawSmooth)) { - state = 1; - } - else { - state = 0; - } - } - if( prevstate != state && prevstate == 1 ) { - if( i-prevstart > 0 ) { - glDrawArrays(GL_TRIANGLES,prevstart*3,(i-prevstart)*3); - } - prevstart = i; + + if(draw && setDrawOptions && !setDrawOptions(userData, orig, &drawSmooth)) + draw = 0; + + /* Goal is to draw as long of a contiguous triangle + array as possible, so draw when we hit either an + invisible triangle or at the end of the array */ + if(!draw || i == tottri - 1) { + if(prevstart != i) + /* Add one to the length (via `draw') + if we're drawing at the end of the array */ + glDrawArrays(GL_TRIANGLES,prevstart*3, (i-prevstart+draw)*3); + prevstart = i + 1; } - prevstate = state; - } - if(state==1) { - glDrawArrays(GL_TRIANGLES,prevstart*3,dm->drawObject->nelements-prevstart*3); } glShadeModel(GL_FLAT); } @@ -1347,12 +1358,12 @@ static void cdDM_foreachMappedFaceCenter( orig = i; VECCOPY(cent, mv[mf->v1].co); - add_v3_v3v3(cent, cent, mv[mf->v2].co); - add_v3_v3v3(cent, cent, mv[mf->v3].co); + add_v3_v3(cent, mv[mf->v2].co); + add_v3_v3(cent, mv[mf->v3].co); if (mf->v4) { normal_quad_v3( no,mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co, mv[mf->v4].co); - add_v3_v3v3(cent, cent, mv[mf->v4].co); + add_v3_v3(cent, mv[mf->v4].co); mul_v3_fl(cent, 0.25f); } else { normal_tri_v3( no,mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co); @@ -1663,6 +1674,11 @@ DerivedMesh *CDDM_from_template(DerivedMesh *source, CDDerivedMesh *cddm = cdDM_create("CDDM_from_template dest"); DerivedMesh *dm = &cddm->dm; + /* ensure these are created if they are made on demand */ + source->getVertDataArray(source, CD_ORIGINDEX); + source->getEdgeDataArray(source, CD_ORIGINDEX); + source->getFaceDataArray(source, CD_ORIGINDEX); + /* this does a copy of all non mvert/medge/mface layers */ DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numFaces); @@ -1750,25 +1766,21 @@ void CDDM_calc_normals(DerivedMesh *dm) else normal_tri_v3( f_no,mv[mf->v1].co, mv[mf->v2].co, mv[mf->v3].co); - add_v3_v3v3(temp_nors[mf->v1], temp_nors[mf->v1], f_no); - add_v3_v3v3(temp_nors[mf->v2], temp_nors[mf->v2], f_no); - add_v3_v3v3(temp_nors[mf->v3], temp_nors[mf->v3], f_no); + add_v3_v3(temp_nors[mf->v1], f_no); + add_v3_v3(temp_nors[mf->v2], f_no); + add_v3_v3(temp_nors[mf->v3], f_no); if(mf->v4) - add_v3_v3v3(temp_nors[mf->v4], temp_nors[mf->v4], f_no); + add_v3_v3(temp_nors[mf->v4], f_no); } /* normalize vertex normals and assign */ for(i = 0; i < numVerts; i++, mv++) { float *no = temp_nors[i]; - if (normalize_v3(no) == 0.0) { - VECCOPY(no, mv->co); - normalize_v3(no); - } + if (normalize_v3(no) == 0.0) + normalize_v3_v3(no, mv->co); - mv->no[0] = (short)(no[0] * 32767.0); - mv->no[1] = (short)(no[1] * 32767.0); - mv->no[2] = (short)(no[2] * 32767.0); + normal_float_to_short_v3(mv->no, no); } MEM_freeN(temp_nors); |