Revision: 44869
          
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=44869
Author:   nicholasbishop
Date:     2012-03-14 06:32:03 +0000 (Wed, 14 Mar 2012)
Log Message:
-----------
Skip hidden elements in PBVH iterator, raycast, and drawing.

Modified Paths:
--------------
    trunk/blender/source/blender/blenkernel/BKE_multires.h
    trunk/blender/source/blender/blenkernel/BKE_subsurf.h
    trunk/blender/source/blender/blenkernel/intern/multires.c
    trunk/blender/source/blender/blenkernel/intern/subsurf_ccg.c
    trunk/blender/source/blender/blenlib/BLI_pbvh.h
    trunk/blender/source/blender/blenlib/intern/pbvh.c
    trunk/blender/source/blender/editors/sculpt_paint/sculpt.c
    trunk/blender/source/blender/editors/sculpt_paint/sculpt_undo.c

Modified: trunk/blender/source/blender/blenkernel/BKE_multires.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_multires.h      2012-03-14 
06:31:49 UTC (rev 44868)
+++ trunk/blender/source/blender/blenkernel/BKE_multires.h      2012-03-14 
06:32:03 UTC (rev 44869)
@@ -32,17 +32,19 @@
  *  \ingroup bke
  */
 
+enum MultiresModifiedFlags;
 struct DerivedMesh;
+struct GridHidden;
+struct MDisps;
+struct MFace;
 struct Mesh;
-struct MFace;
+struct ModifierData;
 struct Multires;
 struct MultiresModifierData;
-struct ModifierData;
 struct Object;
 struct Scene;
-struct MDisps;
 
-void multires_mark_as_modified(struct Object *ob);
+void multires_mark_as_modified(struct Object *ob, enum MultiresModifiedFlags 
flags);
 
 void multires_force_update(struct Object *ob);
 void multires_force_render_update(struct Object *ob);
@@ -50,6 +52,7 @@
 
 /* internal, only called in subsurf_ccg.c */
 void multires_modifier_update_mdisps(struct DerivedMesh *dm);
+void multires_modifier_update_hidden(struct DerivedMesh *dm);
 
 void multiresModifier_set_levels_from_disps(struct MultiresModifierData *mmd, 
struct Object *ob);
 

Modified: trunk/blender/source/blender/blenkernel/BKE_subsurf.h
===================================================================
--- trunk/blender/source/blender/blenkernel/BKE_subsurf.h       2012-03-14 
06:31:49 UTC (rev 44868)
+++ trunk/blender/source/blender/blenkernel/BKE_subsurf.h       2012-03-14 
06:32:03 UTC (rev 44869)
@@ -71,6 +71,14 @@
    of this function to convert to grid coordinates at 'high_level' */
 int ccg_factor(int low_level, int high_level);
 
+typedef enum MultiresModifiedFlags {
+       /* indicates the grids have been sculpted on, so MDisps
+          have to be updated */
+       MULTIRES_COORDS_MODIFIED = 1,
+       /* indicates elements have been hidden or unhidden */
+       MULTIRES_HIDDEN_MODIFIED = 2
+} MultiresModifiedFlags;
+
 /**************************** Internal *****************************/
 
 typedef struct CCGDerivedMesh {
@@ -112,7 +120,7 @@
                float (*orco)[3];
 
                struct Object *ob;
-               int modified;
+               MultiresModifiedFlags modified_flags;
        } multires;
 
        struct EdgeHash *ehash;

Modified: trunk/blender/source/blender/blenkernel/intern/multires.c
===================================================================
--- trunk/blender/source/blender/blenkernel/intern/multires.c   2012-03-14 
06:31:49 UTC (rev 44868)
+++ trunk/blender/source/blender/blenkernel/intern/multires.c   2012-03-14 
06:32:03 UTC (rev 44869)
@@ -40,6 +40,7 @@
 #include "DNA_object_types.h"
 #include "DNA_scene_types.h"
 
+#include "BLI_bitmap.h"
 #include "BLI_blenlib.h"
 #include "BLI_math.h"
 #include "BLI_pbvh.h"
@@ -76,6 +77,180 @@
 static void multires_mvert_to_ss(DerivedMesh *dm, MVert *mvert);
 static void multiresModifier_disp_run(DerivedMesh *dm, Mesh *me, DerivedMesh 
*dm2, DispOp op, DMGridData **oldGridData, int totlvl);
 
+/** Grid hiding **/
+static BLI_bitmap multires_mdisps_upsample_hidden(BLI_bitmap lo_hidden,
+                                                                               
                  int lo_level,
+                                                                               
                  int hi_level,
+                                                                        
+                                                                               
                  /* assumed to be at hi_level (or
+                                                                               
                         null) */
+                                                                               
                  BLI_bitmap prev_hidden)
+{
+       BLI_bitmap subd;
+       int hi_gridsize = ccg_gridsize(hi_level);
+       int lo_gridsize = ccg_gridsize(lo_level);
+       int yh, xh, xl, yl, xo, yo, hi_ndx;
+       int offset, factor;
+
+       BLI_assert(lo_level <= hi_level);
+
+       /* fast case */
+       if(lo_level == hi_level)
+               return MEM_dupallocN(lo_hidden);
+
+       subd = BLI_BITMAP_NEW(hi_gridsize * hi_gridsize, "MDisps.hidden 
upsample");
+
+       factor = ccg_factor(lo_level, hi_level);
+       offset = 1 << (hi_level - lo_level - 1);
+
+       /* low-res blocks */
+       for(yl = 0; yl < lo_gridsize; yl++) {
+               for(xl = 0; xl < lo_gridsize; xl++) {
+                       int lo_val = BLI_BITMAP_GET(lo_hidden, yl * lo_gridsize 
+ xl);
+
+                       /* high-res blocks */
+                       for(yo = -offset; yo <= offset; yo++) {
+                               yh = yl * factor + yo;
+                               if(yh < 0 || yh >= hi_gridsize)
+                                       continue;
+
+                               for(xo = -offset; xo <= offset; xo++) {
+                                       xh = xl * factor + xo;
+                                       if(xh < 0 || xh >= hi_gridsize)
+                                               continue;
+
+                                       hi_ndx = yh * hi_gridsize + xh;
+
+                                       if(prev_hidden) {
+                                               /* If prev_hidden is available, 
copy it to
+                                                  subd, except when the 
equivalent element in
+                                                  lo_hidden is different */
+                                               if(lo_val != 
prev_hidden[hi_ndx])
+                                                       BLI_BITMAP_MODIFY(subd, 
hi_ndx, lo_val);
+                                               else
+                                                       BLI_BITMAP_MODIFY(subd, 
hi_ndx, prev_hidden[hi_ndx]);
+                                       }
+                                       else {
+                                               BLI_BITMAP_MODIFY(subd, hi_ndx, 
lo_val);
+                                       }
+                               }
+                       }
+               }
+       }
+
+       return subd;
+}
+
+static BLI_bitmap multires_mdisps_downsample_hidden(BLI_bitmap old_hidden,
+                                                                               
                        int old_level,
+                                                                               
                        int new_level)
+{
+       BLI_bitmap new_hidden;
+       int new_gridsize = ccg_gridsize(new_level);
+       int old_gridsize = ccg_gridsize(old_level);
+       int x, y, factor, old_value;
+
+       BLI_assert(new_level <= old_level);
+       factor = ccg_factor(new_level, old_level);
+       new_hidden = BLI_BITMAP_NEW(new_gridsize * new_gridsize,
+                                                               "downsample 
hidden");
+
+
+
+       for(y = 0; y < new_gridsize; y++) {
+               for(x = 0; x < new_gridsize; x++) {
+                       old_value = BLI_BITMAP_GET(old_hidden,
+                                                                          
factor*y*old_gridsize + x*factor);
+                       
+                       BLI_BITMAP_MODIFY(new_hidden, y*new_gridsize + x, 
old_value);
+               }
+       }
+
+       return new_hidden;
+}
+
+static void multires_output_hidden_to_ccgdm(CCGDerivedMesh *ccgdm,
+                                                                               
        Mesh *me, int level)
+{
+       const MDisps *mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
+       BLI_bitmap *grid_hidden = ccgdm->gridHidden;
+       int *gridOffset;
+       int i, j;
+       
+       gridOffset = ccgdm->dm.getGridOffset(&ccgdm->dm);
+
+       for (i = 0; i < me->totpoly; i++) {
+               for (j = 0; j < me->mpoly[i].totloop; j++) {
+                       int g = gridOffset[i] + j;
+                       const MDisps *md = &mdisps[g];
+                       BLI_bitmap gh = md->hidden;
+                       
+                       if (gh) {
+                               grid_hidden[g] =
+                                       multires_mdisps_downsample_hidden(gh, 
md->level, level);
+                       }
+               }
+       }
+}
+
+/* subdivide mdisps.hidden if needed (assumes that md.level reflects
+   the current level of md.hidden) */
+static void multires_mdisps_subdivide_hidden(MDisps *md, int new_level)
+{
+       BLI_bitmap subd;
+       
+       BLI_assert(md->hidden);
+
+       /* nothing to do if already subdivided enough */
+       if(md->level >= new_level)
+               return;
+
+       subd = multires_mdisps_upsample_hidden(md->hidden,
+                                                                               
   md->level,
+                                                                               
   new_level,
+                                                                               
   NULL);
+       
+       /* swap in the subdivided data */
+       MEM_freeN(md->hidden);
+       md->hidden = subd;
+}
+
+static MDisps *multires_mdisps_initialize_hidden(Mesh *me, int level)
+{
+       MDisps *mdisps = CustomData_add_layer(&me->ldata, CD_MDISPS,
+                                                                               
  CD_CALLOC, 0, me->totloop);
+       int gridsize = ccg_gridsize(level);
+       int gridarea = gridsize * gridsize;
+       int i, j, k;
+       
+       for (i = 0; i < me->totpoly; i++) {
+               int hide = 0;
+
+               for (j = 0; j < me->mpoly[i].totloop; j++) {
+                       if(me->mvert[me->mloop[me->mpoly[i].loopstart + 
j].v].flag & ME_HIDE) {
+                               hide = 1;
+                               break;
+                       }
+               }
+
+               if(!hide)
+                       continue;
+
+               for (j = 0; j < me->mpoly[i].totloop; j++) {
+                       MDisps *md = &mdisps[me->mpoly[i].loopstart + j];
+
+                       BLI_assert(!md->hidden);
+
+                       md->hidden = BLI_BITMAP_NEW(gridarea, "MDisps.hidden 
initialize");
+
+                       for(k = 0; k < gridarea; k++)
+                               BLI_BITMAP_SET(md->hidden, k);
+               }
+       }
+
+       return mdisps;
+}
+
 DerivedMesh *get_multires_dm(Scene *scene, MultiresModifierData *mmd, Object 
*ob)
 {
        ModifierData *md= (ModifierData *)mmd;
@@ -156,16 +331,16 @@
        mmd->renderlvl = CLAMPIS(MAX2(mmd->renderlvl, lvl), 0, mmd->totlvl);
 }
 
-static void multires_dm_mark_as_modified(DerivedMesh *dm)
+static void multires_dm_mark_as_modified(DerivedMesh *dm, 
MultiresModifiedFlags flags)
 {
        CCGDerivedMesh *ccgdm = (CCGDerivedMesh*)dm;
-       ccgdm->multires.modified = 1;
+       ccgdm->multires.modified_flags |= flags;
 }
 
-void multires_mark_as_modified(Object *ob)
+void multires_mark_as_modified(Object *ob, MultiresModifiedFlags flags)
 {
        if (ob && ob->derivedFinal)
-               multires_dm_mark_as_modified(ob->derivedFinal);
+               multires_dm_mark_as_modified(ob->derivedFinal, flags);
 }
 
 void multires_force_update(Object *ob)
@@ -205,7 +380,7 @@
        if (mrdm && srcdm && mrdm->getNumVerts(mrdm) == 
srcdm->getNumVerts(srcdm)) {
                multires_mvert_to_ss(mrdm, srcdm->getVertArray(srcdm));
 
-               multires_dm_mark_as_modified(mrdm);
+               multires_dm_mark_as_modified(mrdm, MULTIRES_COORDS_MODIFIED);
                multires_force_update(ob);
 
                mrdm->release(mrdm);
@@ -336,6 +511,9 @@
 
                if (mdisps[i].disps)
                        MEM_freeN(mdisps[i].disps);
+               
+               if (mdisps[i].level && mdisps[i].hidden)
+                       multires_mdisps_subdivide_hidden(&mdisps[i], lvl);
 
                mdisps[i].disps = disps;
                mdisps[i].totdisp = totdisp;
@@ -421,6 +599,14 @@
                                        hdisps = mdisp->disps;
 
                                        multires_copy_grid(ndisps, hdisps, 
nsize, hsize);
+                                       if (mdisp->hidden) {
+                                               BLI_bitmap gh =
+                                                       
multires_mdisps_downsample_hidden(mdisp->hidden,
+                                                                               
                                          mdisp->level,
+                                                                               
                                          lvl);
+                                               MEM_freeN(mdisp->hidden);
+                                               mdisp->hidden = gh;
+                                       }
 
                                        ndisps += nsize*nsize;
                                        hdisps += hsize*hsize;
@@ -637,7 +823,7 @@
 
        mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
        if (!mdisps)
-               mdisps = CustomData_add_layer(&me->ldata, CD_MDISPS, 
CD_DEFAULT, NULL, me->totloop);
+               mdisps = multires_mdisps_initialize_hidden(me, totlvl);
 
        if (mdisps->disps && !updateblock && totlvl > 1) {
                /* upsample */
@@ -940,7 +1126,38 @@
        }
 }
 
+void multires_modifier_update_hidden(DerivedMesh *dm)
+{
+       CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
+       BLI_bitmap *grid_hidden= ccgdm->gridHidden;
+       Mesh *me = ccgdm->multires.ob->data;
+       MDisps *mdisps = CustomData_get_layer(&me->ldata, CD_MDISPS);
+       int totlvl = ccgdm->multires.totlvl;
+       int lvl = ccgdm->multires.lvl;
 
+       if(mdisps) {
+               int i;
+               
+               for(i = 0; i < me->totloop; i++) {
+                       MDisps *md = &mdisps[i];
+                       BLI_bitmap gh = grid_hidden[i];
+
+                       if(!gh && md->hidden) {
+                               MEM_freeN(md->hidden);
+                               md->hidden = NULL;
+                       }
+                       else if(gh) {
+                               gh = multires_mdisps_upsample_hidden(gh, lvl, 
totlvl,
+                                                                               
                                         md->hidden);
+                               if(md->hidden)
+                                       MEM_freeN(md->hidden);
+                               
+                               md->hidden = gh;
+                       }
+               }
+       }
+}
+
 void multires_set_space(DerivedMesh *dm, Object *ob, int from, int to)
 {
        DerivedMesh *ccgdm = NULL, *subsurf = NULL;
@@ -1092,7 +1309,7 @@
 {
        Mesh *me= ob->data;
        DerivedMesh *result;
-       CCGDerivedMesh *ccgdm;
+       CCGDerivedMesh *ccgdm = NULL;
        DMGridData **gridData, **subGridData;
        int lvl= multires_get_level(ob, mmd, useRenderParams);
        int i, gridSize, numGrids;
@@ -1112,7 +1329,7 @@

@@ Diff output truncated at 10240 characters. @@
_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to