Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNicholas Bishop <nicholasbishop@gmail.com>2009-10-28 09:06:05 +0300
committerNicholas Bishop <nicholasbishop@gmail.com>2009-10-28 09:06:05 +0300
commit243c73e96e18c126227d43728e2d3639c9f7ee41 (patch)
tree7c34c44f28125754586c414a602327d4421e468a /source/blender
parent93beb0b85a4a0e301d9bfae9edee1fe7bdabba12 (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/blender')
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h13
-rw-r--r--source/blender/blenkernel/BKE_paint.h4
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c107
-rw-r--r--source/blender/blenkernel/intern/object.c11
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c2
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c67
-rw-r--r--source/blender/editors/space_view3d/drawobject.c8
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)