Index: source/blender/blenkernel/intern/subsurf_ccg.c |
=================================================================== |
--- source/blender/blenkernel/intern/subsurf_ccg.c (revision 44561) |
+++ source/blender/blenkernel/intern/subsurf_ccg.c (working copy) |
@@ -45,6 +45,7 @@ |
#include "DNA_scene_types.h" |
#include "BLI_utildefines.h" |
+#include "BLI_bitmap.h" |
#include "BLI_blenlib.h" |
#include "BLI_edgehash.h" |
#include "BLI_math.h" |
@@ -55,6 +56,7 @@ |
#include "BKE_global.h" |
#include "BKE_mesh.h" |
#include "BKE_modifier.h" |
+#include "BKE_multires.h" |
#include "BKE_paint.h" |
#include "BKE_scene.h" |
#include "BKE_subsurf.h" |
@@ -949,6 +951,41 @@ static void ccgDM_getFinalFace(DerivedMesh *dm, int faceNum, MFace *mf) |
else mf->flag = ME_SMOOTH; |
} |
+/* Translate GridHidden into the ME_HIDE flag for MVerts. Assumes |
+ vertices are in the order output by ccgDM_copyFinalVertArray. */ |
+void subsurf_copy_grid_hidden(DerivedMesh *dm, const MPoly *mpoly, |
+ MVert *mvert, const GridHidden *grid_hidden) |
+{ |
+ CCGDerivedMesh *ccgdm = (CCGDerivedMesh*)dm; |
+ CCGSubSurf *ss = ccgdm->ss; |
+ int level = ccgSubSurf_getSubdivisionLevels(ss); |
+ int gridSize = ccgSubSurf_getGridSize(ss); |
+ int edgeSize = ccgSubSurf_getEdgeSize(ss); |
+ int totface = ccgSubSurf_getNumFaces(ss); |
+ int i, j, x, y; |
+ |
+ for(i = 0; i < totface; i++) { |
+ CCGFace *f = ccgdm->faceMap[i].face; |
+ |
+ for(j = 0; j < mpoly[i].totloop; j++) { |
+ const GridHidden *gh = &grid_hidden[mpoly[i].loopstart + j]; |
+ if(!gh->data) |
+ continue; |
+ |
+ for(y = 0; y < gridSize; y++) { |
+ for(x = 0; x < gridSize; x++) { |
+ int vndx, offset; |
+ |
+ vndx = getFaceIndex(ss, f, j, x, y, edgeSize, gridSize); |
+ offset = ccg_grid_offset_xy(gh->level, level, x, y); |
+ if(BLI_BITMAP_GET(gh->data, offset)) |
+ mvert[vndx].flag |= ME_HIDE; |
+ } |
+ } |
+ } |
+ } |
+} |
+ |
static void ccgDM_copyFinalVertArray(DerivedMesh *dm, MVert *mvert) |
{ |
CCGDerivedMesh *ccgdm = (CCGDerivedMesh*) dm; |
@@ -2403,12 +2440,18 @@ static void ccgDM_release(DerivedMesh *dm) |
if (DM_release(dm)) { |
/* Before freeing, need to update the displacement map */ |
- if(ccgdm->multires.modified) { |
+ if(ccgdm->multires.modified_flags) { |
/* Check that mmd still exists */ |
- if(!ccgdm->multires.local_mmd && BLI_findindex(&ccgdm->multires.ob->modifiers, ccgdm->multires.mmd) < 0) |
+ if(!ccgdm->multires.local_mmd && |
+ BLI_findindex(&ccgdm->multires.ob->modifiers, ccgdm->multires.mmd) < 0) |
ccgdm->multires.mmd = NULL; |
- if(ccgdm->multires.mmd) |
- ccgdm->multires.update(dm); |
+ |
+ if(ccgdm->multires.mmd) { |
+ if(ccgdm->multires.modified_flags & MULTIRES_COORDS_MODIFIED) |
+ multires_modifier_update_mdisps(dm); |
+ if(ccgdm->multires.modified_flags & MULTIRES_HIDDEN_MODIFIED) |
+ multires_modifier_update_hidden(dm); |
+ } |
} |
if (ccgdm->ehash) |
@@ -2807,7 +2850,7 @@ static int ccgDM_use_grid_pbvh(CCGDerivedMesh *ccgdm) |
static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm) |
{ |
CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm; |
- int gridSize, numGrids, grid_pbvh; |
+ int level, numGrids, grid_pbvh; |
if(!ob) { |
ccgdm->pbvh= NULL; |
@@ -2839,14 +2882,16 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm) |
we build a pbvh over the modified mesh, in other cases the base mesh |
is being sculpted, so we build a pbvh from that. */ |
if(grid_pbvh) { |
+ Mesh *me= ob->data; |
+ |
ccgdm_create_grids(dm); |
- gridSize = ccgDM_getGridSize(dm); |
+ level = ccgSubSurf_getSubdivisionLevels(ccgdm->ss); |
numGrids = ccgDM_getNumGrids(dm); |
ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new(); |
BLI_pbvh_build_grids(ccgdm->pbvh, ccgdm->gridData, ccgdm->gridAdjacency, |
- numGrids, gridSize, (void**)ccgdm->gridFaces); |
+ numGrids, level, (void**)ccgdm->gridFaces, &me->ldata); |
} else if(ob->type == OB_MESH) { |
Mesh *me= ob->data; |
ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new(); |
@@ -3439,3 +3484,17 @@ void subsurf_calculate_limit_positions(Mesh *me, float (*positions_r)[3]) |
dm->release(dm); |
} |
+/* get an offset into grid data, where the grid is subdivided to |
+ 'data_level', and the x/y inputs are at 'cur_level' */ |
+int ccg_grid_offset_xy(int data_level, int cur_level, |
+ int x, int y) |
+{ |
+ const int data_gridsize = ccg_gridsize(data_level); |
+ const int cur_gridsize = ccg_gridsize(cur_level); |
+ const int factor = 1 << (data_level - cur_level); |
+ |
+ BLI_assert(cur_level <= data_level); |
+ BLI_assert(x < cur_gridsize && y < cur_gridsize); |
+ |
+ return y*factor * data_gridsize + x*factor; |
+} |