diff options
author | Nicholas Bishop <nicholasbishop@gmail.com> | 2009-10-28 09:06:05 +0300 |
---|---|---|
committer | Nicholas Bishop <nicholasbishop@gmail.com> | 2009-10-28 09:06:05 +0300 |
commit | 243c73e96e18c126227d43728e2d3639c9f7ee41 (patch) | |
tree | 7c34c44f28125754586c414a602327d4421e468a /source | |
parent | 93beb0b85a4a0e301d9bfae9edee1fe7bdabba12 (diff) |
Moved the PBVH from sculpt session to DerivedMesh/CDDM.
* Multires sculpting appears to work now
* PBVH gets recalculated in some cases where it shouldn't, haven't looked into this yet
Diffstat (limited to 'source')
-rw-r--r-- | source/blender/blenkernel/BKE_DerivedMesh.h | 13 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_paint.h | 4 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/cdderivedmesh.c | 107 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/object.c | 11 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/subsurf_ccg.c | 2 | ||||
-rw-r--r-- | source/blender/editors/sculpt_paint/sculpt.c | 67 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/drawobject.c | 8 |
7 files changed, 122 insertions, 90 deletions
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index 75d9ae7f360..d9b0c4bc357 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -59,6 +59,8 @@ struct MCol; struct ColorBand; struct GPUVertexAttribs; struct GPUDrawObject; +struct ListBase; +struct PBVH; /* number of sub-elements each mesh element has (for interpolation) */ #define SUB_ELEMS_VERT 0 @@ -73,6 +75,7 @@ struct DerivedMesh { int needsFree; /* checked on ->release, is set to 0 for cached results */ int deformedOnly; /* set by modifier stack if only deformed from original */ BVHCache bvhCache; + struct GPUDrawObject *drawObject; /* Misc. Queries */ @@ -180,6 +183,14 @@ struct DerivedMesh { /* Get vertex normal, undefined if index is not valid */ void (*getVertNo)(DerivedMesh *dm, int index, float no_r[3]); + /* Get a map of vertices to faces + */ + struct ListBase *(*getFaceMap)(DerivedMesh *dm); + + /* Get the BVH used for paint modes + */ + struct PBVH *(*getPBVH)(DerivedMesh *dm); + /* Drawing Operations */ /* Draw all vertices as bgl points (no options) */ @@ -204,7 +215,7 @@ struct DerivedMesh { * * Also called for *final* editmode DerivedMeshes */ - void (*drawFacesSolid)(DerivedMesh *dm, void *tree, float (*partial_redraw_planes)[4], + void (*drawFacesSolid)(DerivedMesh *dm, float (*partial_redraw_planes)[4], int (*setMaterial)(int, void *attribs)); /* Draw all faces diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h index 558659b520f..5bca174628d 100644 --- a/source/blender/blenkernel/BKE_paint.h +++ b/source/blender/blenkernel/BKE_paint.h @@ -69,17 +69,15 @@ typedef struct SculptSession { struct MFace *mface; int totvert, totface; float *face_normals; + struct PBVH *tree; /* Mesh connectivity */ struct ListBase *fmap; - struct IndexNode *fmap_mem; - int fmap_size; /* Used temporarily per-stroke */ float *vertexcosnos; /* Partial redraw */ - struct PBVH *tree; int partial_redraw; /* Used to cache the render of the active texture */ diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index 6ae1057767d..66e09022ff5 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -77,6 +77,12 @@ typedef struct { MVert *mvert; MEdge *medge; MFace *mface; + + /* Cached */ + struct PBVH *pbvh; + /* Mesh connectivity */ + struct ListBase *fmap; + struct IndexNode *fmap_mem; } CDDerivedMesh; /**************** DerivedMesh interface functions ****************/ @@ -171,6 +177,82 @@ static void cdDM_getVertNo(DerivedMesh *dm, int index, float no_r[3]) no_r[2] = no[2]/32767.f; } +/* Updates all the face and vertex normals in a node + + Note: the correctness of some vertex normals will be a little + off, not sure if this will be noticeable or not */ +static void update_node_normals(const int *face_indices, + const int *vert_indices, + int totface, int totvert, void *data) +{ + DerivedMesh *dm = data; + CDDerivedMesh *cddm = data; + float (*face_nors)[3]; + int i; + + /* make a face normal layer if not present */ + face_nors = CustomData_get_layer(&dm->faceData, CD_NORMAL); + if(!face_nors) + face_nors = CustomData_add_layer(&dm->faceData, CD_NORMAL, CD_CALLOC, + NULL, dm->numFaceData); + + /* Update face normals */ + for(i = 0; i < totface; ++i) { + MFace *f = cddm->mface + face_indices[i]; + float *fn = face_nors[face_indices[i]]; + + if(f->v4) + CalcNormFloat4(cddm->mvert[f->v1].co, cddm->mvert[f->v2].co, + cddm->mvert[f->v3].co, cddm->mvert[f->v4].co, fn); + else + CalcNormFloat(cddm->mvert[f->v1].co, cddm->mvert[f->v2].co, + cddm->mvert[f->v3].co, fn); + } + + /* Update vertex normals */ + for(i = 0; i < totvert; ++i) { + const int v = vert_indices[i]; + float no[3] = {0,0,0}; + IndexNode *face; + + for(face = cddm->fmap[v].first; face; face = face->next) + VecAddf(no, no, face_nors[face->index]); + + Normalize(no); + + cddm->mvert[v].no[0] = no[0] * 32767; + cddm->mvert[v].no[1] = no[1] * 32767; + cddm->mvert[v].no[2] = no[2] * 32767; + } +} + +static ListBase *cdDM_getFaceMap(DerivedMesh *dm) +{ + CDDerivedMesh *cddm = (CDDerivedMesh*) dm; + + if(!cddm->fmap) { + create_vert_face_map(&cddm->fmap, &cddm->fmap_mem, cddm->mface, + dm->getNumVerts(dm), dm->getNumFaces(dm)); + printf("rebuild fmap\n"); + } + + return cddm->fmap; +} + +static struct PBVH *cdDM_getPBVH(DerivedMesh *dm) +{ + CDDerivedMesh *cddm = (CDDerivedMesh*) dm; + + if(!cddm->pbvh) { + cddm->pbvh = BLI_pbvh_new(update_node_normals, cddm); + BLI_pbvh_build(cddm->pbvh, cddm->mface, cddm->mvert, + dm->getNumFaces(dm), dm->getNumVerts(dm)); + printf("rebuild pbvh\n"); + } + + return cddm->pbvh; +} + static void cdDM_drawVerts(DerivedMesh *dm) { CDDerivedMesh *cddm = (CDDerivedMesh*) dm; @@ -419,7 +501,7 @@ int planes_contain_AABB(float bb_min[3], float bb_max[3], void *data) return 1; } -static void cdDM_drawFacesSolid(DerivedMesh *dm, void *tree, +static void cdDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)[4], int (*setMaterial)(int, void *attribs)) { @@ -437,19 +519,19 @@ static void cdDM_drawFacesSolid(DerivedMesh *dm, void *tree, glVertex3fv(mvert[index].co); \ } - if(tree) { - BLI_pbvh_search(tree, BLI_pbvh_update_search_cb, + if(cddm->pbvh) { + BLI_pbvh_search(cddm->pbvh, BLI_pbvh_update_search_cb, PBVH_NodeData, NULL, NULL, PBVH_SEARCH_UPDATE); if(partial_redraw_planes) { - BLI_pbvh_search(tree, planes_contain_AABB, + BLI_pbvh_search(cddm->pbvh, planes_contain_AABB, partial_redraw_planes, draw_partial_cb, PBVH_DrawData, PBVH_SEARCH_MODIFIED); } else { - BLI_pbvh_search(tree, find_all, NULL, + BLI_pbvh_search(cddm->pbvh, find_all, NULL, draw_partial_cb, PBVH_DrawData, PBVH_SEARCH_NORMAL); @@ -1376,12 +1458,21 @@ static void cdDM_foreachMappedFaceCenter( } } +static void cdDM_free_internal(CDDerivedMesh *cddm) +{ + if(cddm->pbvh) BLI_pbvh_free(cddm->pbvh); + if(cddm->fmap) MEM_freeN(cddm->fmap); + if(cddm->fmap_mem) MEM_freeN(cddm->fmap_mem); +} + static void cdDM_release(DerivedMesh *dm) { CDDerivedMesh *cddm = (CDDerivedMesh*)dm; - if (DM_release(dm)) + if (DM_release(dm)) { + cdDM_free_internal(cddm); MEM_freeN(cddm); + } } /**************** CDDM interface functions ****************/ @@ -1416,6 +1507,9 @@ static CDDerivedMesh *cdDM_create(const char *desc) dm->getVertCo = cdDM_getVertCo; dm->getVertNo = cdDM_getVertNo; + dm->getPBVH = cdDM_getPBVH; + dm->getFaceMap = cdDM_getFaceMap; + dm->drawVerts = cdDM_drawVerts; dm->drawUVEdges = cdDM_drawUVEdges; @@ -1901,6 +1995,7 @@ static void MultiresDM_release(DerivedMesh *dm) } if(DM_release(dm)) { + cdDM_free_internal(&mrdm->cddm); MEM_freeN(mrdm->subco); MEM_freeN(mrdm->orco); if(mrdm->vert_face_map) diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c index 5c3419fb488..c1b9634e5ec 100644 --- a/source/blender/blenkernel/intern/object.c +++ b/source/blender/blenkernel/intern/object.c @@ -72,8 +72,6 @@ #include "BLI_blenlib.h" #include "BLI_arithb.h" #include "BLI_editVert.h" -#include "BLI_ghash.h" -#include "BLI_pbvh.h" #include "BKE_utildefines.h" @@ -231,12 +229,6 @@ void free_sculptsession(SculptSession **ssp) if(ssp && *ssp) { SculptSession *ss = *ssp; - if(ss->fmap) - MEM_freeN(ss->fmap); - - if(ss->fmap_mem) - MEM_freeN(ss->fmap_mem); - if(ss->texcache) MEM_freeN(ss->texcache); @@ -246,9 +238,6 @@ void free_sculptsession(SculptSession **ssp) if(ss->mesh_co_orig) MEM_freeN(ss->mesh_co_orig); - if(ss->tree) - BLI_pbvh_free(ss->tree); - if(ss->face_normals) MEM_freeN(ss->face_normals); diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 7c83431ebd8..1482bd75ff2 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -1615,7 +1615,7 @@ static void ccgDM_glNormalFast(float *a, float *b, float *c, float *d) } /* Only used by non-editmesh types */ -static void ccgDM_drawFacesSolid(DerivedMesh *dm, void *tree, float (*partial_redraw_planes)[4], int (*setMaterial)(int, void *attribs)) { +static void ccgDM_drawFacesSolid(DerivedMesh *dm, float (*partial_redraw_planes)[4], int (*setMaterial)(int, void *attribs)) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; CCGSubSurf *ss = ccgdm->ss; CCGFaceIterator *fi = ccgSubSurf_getFaceIterator(ss); diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index b4b002283fd..28ca5d2fecf 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -193,57 +193,6 @@ static void projectf(bglMats *mats, const float v[3], float p[2]) /*** BVH Tree ***/ -/* Updates all the face and vertex normals in a node - - Note: the correctness of some vertex normals will be a little - off, not sure if this will be noticeable or not */ -static void sculpt_update_normals(const int *face_indices, - const int *vert_indices, - int totface, int totvert, void *data) -{ - SculptSession *ss = data; - int i; - - /* Update face normals */ - for(i = 0; i < totface; ++i) { - MFace *f = ss->mface + face_indices[i]; - float *fn = ss->face_normals + face_indices[i] * 3; - - if(f->v4) - CalcNormFloat4(ss->mvert[f->v1].co, ss->mvert[f->v2].co, - ss->mvert[f->v3].co, ss->mvert[f->v4].co, fn); - else - CalcNormFloat(ss->mvert[f->v1].co, ss->mvert[f->v2].co, - ss->mvert[f->v3].co, fn); - } - - /* Update vertex normals */ - for(i = 0; i < totvert; ++i) { - const int v = vert_indices[i]; - float no[3] = {0,0,0}; - IndexNode *face; - - for(face = ss->fmap[v].first; face; face = face->next) - VecAddf(no, no, ss->face_normals + face->index*3); - - Normalize(no); - - ss->mvert[v].no[0] = no[0] * 32767; - ss->mvert[v].no[1] = no[1] * 32767; - ss->mvert[v].no[2] = no[2] * 32767; - } -} - -static void sculpt_rebuild_tree(SculptSession *ss) -{ - if(ss->tree) - BLI_pbvh_free(ss->tree); - - ss->tree = BLI_pbvh_new(sculpt_update_normals, ss); - BLI_pbvh_build(ss->tree, ss->mface, ss->mvert, ss->totface, - ss->totvert); -} - /* Get a screen-space rectangle of the modified area */ int sculpt_get_redraw_rect(ARegion *ar, RegionView3D *rv3d, Object *ob, rcti *rect) @@ -1054,11 +1003,10 @@ static struct MultiresModifierData *sculpt_multires_active(Object *ob) static void sculpt_update_mesh_elements(bContext *C) { Object *ob = CTX_data_active_object(C); + DerivedMesh *dm = mesh_get_derived_final(CTX_data_scene(C), ob, CD_MASK_BAREMESH); SculptSession *ss = ob->sculpt; - int oldtotvert = ss->totvert; if((ss->multires = sculpt_multires_active(ob))) { - DerivedMesh *dm = mesh_get_derived_final(CTX_data_scene(C), ob, CD_MASK_BAREMESH); ss->totvert = dm->getNumVerts(dm); ss->totface = dm->getNumFaces(dm); ss->mvert = dm->getVertDataArray(dm, CD_MVERT); @@ -1075,17 +1023,8 @@ static void sculpt_update_mesh_elements(bContext *C) ss->face_normals = MEM_callocN(sizeof(float) * 3 * me->totface, "sculpt face normals"); } - if(ss->tree) - BLI_pbvh_set_source(ss->tree, ss->mvert, ss->mface); - - if(ss->totvert != oldtotvert) { - if(ss->fmap) MEM_freeN(ss->fmap); - if(ss->fmap_mem) MEM_freeN(ss->fmap_mem); - create_vert_face_map(&ss->fmap, &ss->fmap_mem, ss->mface, ss->totvert, ss->totface); - ss->fmap_size = ss->totvert; - - sculpt_rebuild_tree(ss); - } + ss->tree = dm->getPBVH(dm); + ss->fmap = dm->getFaceMap(dm); } static int sculpt_mode_poll(bContext *C) diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c index 5d7e5932bd8..f7dba10200a 100644 --- a/source/blender/editors/space_view3d/drawobject.c +++ b/source/blender/editors/space_view3d/drawobject.c @@ -2692,7 +2692,7 @@ static void draw_mesh_object_outline(View3D *v3d, Object *ob, DerivedMesh *dm) drawFacesSolid() doesn't draw the transparent faces */ if(ob->dtx & OB_DRAWTRANSP) { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - dm->drawFacesSolid(dm, NULL, NULL, GPU_enable_material); + dm->drawFacesSolid(dm, NULL, GPU_enable_material); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); GPU_disable_material(); } @@ -2802,10 +2802,10 @@ static void draw_mesh_fancy(Scene *scene, ARegion *ar, View3D *v3d, RegionView3D ob->sculpt->partial_redraw = 0; } - dm->drawFacesSolid(dm, ob->sculpt->tree, fpl, GPU_enable_material); + dm->drawFacesSolid(dm, fpl, GPU_enable_material); } else - dm->drawFacesSolid(dm, NULL, NULL, GPU_enable_material); + dm->drawFacesSolid(dm, NULL, GPU_enable_material); GPU_disable_material(); @@ -6276,7 +6276,7 @@ static void draw_object_mesh_instance(Scene *scene, View3D *v3d, RegionView3D *r glEnable(GL_LIGHTING); if(dm) { - dm->drawFacesSolid(dm, NULL, NULL, GPU_enable_material); + dm->drawFacesSolid(dm, NULL, GPU_enable_material); GPU_end_object_materials(); } else if(edm) |