Own TODO item: sculpting on constructive modifiers
authorSergey Sharybin <sergey.vfx@gmail.com>
Wed, 4 May 2011 13:15:42 +0000 (13:15 +0000)
committerSergey Sharybin <sergey.vfx@gmail.com>
Wed, 4 May 2011 13:15:42 +0000 (13:15 +0000)
- Constructive modifiers are enabled by default in sculpt mode.
- There's option to disable all constructive modifiers in the "Options"
  panel of toolbox in sculpt mode,
- Use one column in options panel to make strings easier to read
- No modifiers would still be applied on multires

release/scripts/startup/bl_ui/space_view3d_toolbar.py
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/cdderivedmesh.c
source/blender/blenkernel/intern/subsurf_ccg.c
source/blender/editors/sculpt_paint/sculpt.c
source/blender/editors/sculpt_paint/sculpt_intern.h
source/blender/editors/sculpt_paint/sculpt_undo.c
source/blender/editors/util/crazyspace.c
source/blender/makesdna/DNA_scene_types.h
source/blender/makesrna/intern/rna_sculpt_paint.c

index bd258fa18f62021d43cd1307d46096f90411b337..a6db6fbdde85b4eb35260e9dc85c8c90907858ac 100644 (file)
@@ -946,26 +946,21 @@ class VIEW3D_PT_sculpt_options(PaintPanel, bpy.types.Panel):
         sculpt = tool_settings.sculpt
         settings = __class__.paint_settings(context)
 
-        split = layout.split()
-
-        col = split.column()
-
-        col.prop(sculpt, "use_threaded", text="Threaded Sculpt")
-        col.prop(sculpt, "show_low_resolution")
-        col.prop(sculpt, "show_brush")
-
-        col.label(text="Unified Settings:")
-        col.prop(tool_settings, "sculpt_paint_use_unified_size", text="Size")
-        col.prop(tool_settings, "sculpt_paint_use_unified_strength", text="Strength")
-
-        col = split.column()
-
-        col.label(text="Lock:")
-        row = col.row(align=True)
+        layout.label(text="Lock:")
+        row = layout.row(align=True)
         row.prop(sculpt, "lock_x", text="X", toggle=True)
         row.prop(sculpt, "lock_y", text="Y", toggle=True)
         row.prop(sculpt, "lock_z", text="Z", toggle=True)
 
+        layout.prop(sculpt, "use_threaded", text="Threaded Sculpt")
+        layout.prop(sculpt, "show_low_resolution")
+        layout.prop(sculpt, "show_brush")
+        layout.prop(sculpt, "use_deform_only")
+
+        layout.label(text="Unified Settings:")
+        layout.prop(tool_settings, "sculpt_paint_use_unified_size", text="Size")
+        layout.prop(tool_settings, "sculpt_paint_use_unified_strength", text="Strength")
+
 
 class VIEW3D_PT_sculpt_symmetry(PaintPanel, bpy.types.Panel):
     bl_label = "Symmetry"
index 297489ee56fd3eeadd6e98c8cc405e1421129d7c..d9c98bc0200af2a4e782ec1b32add26497d7370e 100644 (file)
@@ -1772,11 +1772,20 @@ static void mesh_calc_modifiers(Scene *scene, Object *ob, float (*inputVertexCos
                        modifier_setError(md, "Modifier requires original data, bad stack position.");
                        continue;
                }
-               if(sculpt_mode && (!has_multires || multires_applied))
-                       if(mti->type != eModifierTypeType_OnlyDeform || multires_applied) {
+               if(sculpt_mode && (!has_multires || multires_applied)) {
+                       int unsupported= 0;
+
+                       if(scene->toolsettings->sculpt->flags & SCULPT_ONLY_DEFORM)
+                               unsupported|= mti->type != eModifierTypeType_OnlyDeform;
+
+                       unsupported|= md->type == eModifierType_Multires && ((MultiresModifierData*)md)->sculptlvl==0;
+                       unsupported|= multires_applied;
+
+                       if(unsupported) {
                                modifier_setError(md, "Not supported in sculpt mode.");
                                continue;
                        }
+               }
                if(needMapping && !modifier_supportsMapping(md)) continue;
                if(useDeform < 0 && mti->dependsOnTime && mti->dependsOnTime(md)) continue;
 
index baf89f9f494c67114cf9de9a5fc2d11a666ddb9f..72ee9b55800ff13cc029f2d7d2982e16036fde3f 100644 (file)
@@ -231,19 +231,21 @@ static struct PBVH *cdDM_getPBVH(Object *ob, DerivedMesh *dm)
           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) {
+               SculptSession *ss= ob->sculpt;
                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);
 
-               if(ob->sculpt->modifiers_active) {
+               if(ss->modifiers_active && ob->derivedDeform) {
+                       DerivedMesh *deformdm= ob->derivedDeform;
                        float (*vertCos)[3];
                        int totvert;
 
-                       totvert= dm->getNumVerts(dm);
+                       totvert= deformdm->getNumVerts(deformdm);
                        vertCos= MEM_callocN(3*totvert*sizeof(float), "cdDM_getPBVH vertCos");
-                       dm->getVertCos(dm, vertCos);
+                       deformdm->getVertCos(deformdm, vertCos);
                        BLI_pbvh_apply_vertCos(cddm->pbvh, vertCos);
                        MEM_freeN(vertCos);
                }
index 33094313acd0fea8959496b87985244b445fdfe9..5d44841df8b698b32e077717318bff0f786fdf08 100644 (file)
@@ -74,6 +74,7 @@
 static int ccgDM_getVertMapIndex(CCGSubSurf *ss, CCGVert *v);
 static int ccgDM_getEdgeMapIndex(CCGSubSurf *ss, CCGEdge *e);
 static int ccgDM_getFaceMapIndex(CCGSubSurf *ss, CCGFace *f);
+static int ccgDM_use_grid_pbvh(CCGDerivedMesh *ccgdm);
 
 ///
 
@@ -1157,7 +1158,7 @@ static void ccgDM_drawVerts(DerivedMesh *dm) {
 
 static void ccgdm_pbvh_update(CCGDerivedMesh *ccgdm)
 {
-       if(ccgdm->pbvh) {
+       if(ccgdm->pbvh && ccgDM_use_grid_pbvh(ccgdm)) {
                CCGFace **faces;
                int totface;
 
@@ -2249,10 +2250,22 @@ static ListBase *ccgDM_getFaceMap(Object *ob, DerivedMesh *dm)
        return ccgdm->fmap;
 }
 
+static int ccgDM_use_grid_pbvh(CCGDerivedMesh *ccgdm)
+{
+       MultiresModifierData *mmd= ccgdm->multires.mmd;
+
+       /* both of multires and subsurm modifiers are CCG, but
+          grids should only be used when sculpting on multires */
+       if(!mmd)
+               return 0;
+
+       return 1;
+}
+
 static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
 {
        CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
-       int gridSize, numGrids;
+       int gridSize, numGrids, grid_pbvh;
 
        if(!ob) {
                ccgdm->pbvh= NULL;
@@ -2262,13 +2275,17 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
        if(!ob->sculpt)
                return NULL;
 
+       grid_pbvh= ccgDM_use_grid_pbvh(ccgdm);
+
        if(ob->sculpt->pbvh) {
-          /* pbvh's grids, gridadj and gridfaces points to data inside ccgdm
-                 but this can be freed on ccgdm release, this updates the pointers
-                 when the ccgdm gets remade, the assumption is that the topology
-                 does not change. */
-               ccgdm_create_grids(dm);
-               BLI_pbvh_grids_update(ob->sculpt->pbvh, ccgdm->gridData, ccgdm->gridAdjacency, (void**)ccgdm->gridFaces);
+               if(grid_pbvh) {
+                       /* pbvh's grids, gridadj and gridfaces points to data inside ccgdm
+                          but this can be freed on ccgdm release, this updates the pointers
+                          when the ccgdm gets remade, the assumption is that the topology
+                          does not change. */
+                       ccgdm_create_grids(dm);
+                       BLI_pbvh_grids_update(ob->sculpt->pbvh, ccgdm->gridData, ccgdm->gridAdjacency, (void**)ccgdm->gridFaces);
+               }
 
                ccgdm->pbvh = ob->sculpt->pbvh;
        }
@@ -2279,14 +2296,21 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
        /* no pbvh exists yet, we need to create one. only in case of multires
           we build a pbvh over the modified mesh, in other cases the base mesh
           is being sculpted, so we build a pbvh from that. */
-       ccgdm_create_grids(dm);
+       if(grid_pbvh) {
+               ccgdm_create_grids(dm);
 
-       gridSize = ccgDM_getGridSize(dm);
-       numGrids = ccgDM_getNumGrids(dm);
+               gridSize = ccgDM_getGridSize(dm);
+               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);
+               ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new();
+               BLI_pbvh_build_grids(ccgdm->pbvh, ccgdm->gridData, ccgdm->gridAdjacency,
+                       numGrids, gridSize, (void**)ccgdm->gridFaces);
+       } else if(ob->type == OB_MESH) {
+               Mesh *me= ob->data;
+               ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new();
+               BLI_pbvh_build_mesh(ccgdm->pbvh, me->mface, me->mvert,
+                                  me->totface, me->totvert);
+       }
 
        return ccgdm->pbvh;
 }
index c7733ced1f39aeaadb830ca3c6c875eca9dca9a1..7156b49c0264b49f1ff7b57f87eea86ad1b4829f 100644 (file)
@@ -172,7 +172,7 @@ static int sculpt_has_active_modifiers(Scene *scene, Object *ob)
 }
 
 /* Checks if there are any supported deformation modifiers active */
-int sculpt_modifiers_active(Scene *scene, Object *ob)
+static int sculpt_modifiers_active(Scene *scene, Sculpt *sd, Object *ob)
 {
        ModifierData *md;
        Mesh *me= (Mesh*)ob->data;
@@ -189,12 +189,11 @@ int sculpt_modifiers_active(Scene *scene, Object *ob)
        /* exception for shape keys because we can edit those */
        for(; md; md= md->next) {
                ModifierTypeInfo *mti = modifierType_getInfo(md->type);
-
                if(!modifier_isEnabled(scene, md, eModifierMode_Realtime)) continue;
                if(md->type==eModifierType_ShapeKey) continue;
 
-               if(mti->type==eModifierTypeType_OnlyDeform)
-                       return 1;
+               if(mti->type==eModifierTypeType_OnlyDeform) return 1;
+               else if((sd->flags & SCULPT_ONLY_DEFORM)==0) return 1;
        }
 
        return 0;
@@ -2705,13 +2704,13 @@ void sculpt_free_deformMats(SculptSession *ss)
        ss->deform_imats = NULL;
 }
 
-void sculpt_update_mesh_elements(Scene *scene, Object *ob, int need_fmap)
+void sculpt_update_mesh_elements(Scene *scene, Sculpt *sd, Object *ob, int need_fmap)
 {
        DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
        SculptSession *ss = ob->sculpt;
        MultiresModifierData *mmd= sculpt_multires_active(scene, ob);
 
-       ss->modifiers_active= sculpt_modifiers_active(scene, ob);
+       ss->modifiers_active= sculpt_modifiers_active(scene, sd, ob);
 
        if(!mmd) ss->kb= ob_get_keyblock(ob);
        else ss->kb= NULL;
@@ -3256,7 +3255,7 @@ static void sculpt_stroke_modifiers_check(bContext *C, Object *ob)
                Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
                Brush *brush = paint_brush(&sd->paint);
 
-               sculpt_update_mesh_elements(CTX_data_scene(C), ob, brush->sculpt_tool == SCULPT_TOOL_SMOOTH);
+               sculpt_update_mesh_elements(CTX_data_scene(C), sd, ob, brush->sculpt_tool == SCULPT_TOOL_SMOOTH);
        }
 }
 
@@ -3358,7 +3357,7 @@ static int sculpt_brush_stroke_init(bContext *C, ReportList *UNUSED(reports))
        view3d_operator_needs_opengl(C);
        sculpt_brush_init_tex(sd, ss);
 
-       sculpt_update_mesh_elements(scene, ob, brush->sculpt_tool == SCULPT_TOOL_SMOOTH);
+       sculpt_update_mesh_elements(scene, sd, ob, brush->sculpt_tool == SCULPT_TOOL_SMOOTH);
 
        return 1;
 }
@@ -3685,7 +3684,7 @@ static void sculpt_init_session(Scene *scene, Object *ob)
 {
        ob->sculpt = MEM_callocN(sizeof(SculptSession), "sculpt session");
 
-       sculpt_update_mesh_elements(scene, ob, 0);
+       sculpt_update_mesh_elements(scene, scene->toolsettings->sculpt, ob, 0);
 }
 
 static int sculpt_toggle_mode(bContext *C, wmOperator *UNUSED(op))
index 5e017d0dc20d7b78974d42bf0591a8ff4e3d1d62..33970ea0179f86986e94d923eb149e2e45ce8b23 100644 (file)
@@ -64,7 +64,7 @@ struct Brush *sculptmode_brush(void);
 void sculpt(Sculpt *sd);
 
 int sculpt_poll(struct bContext *C);
-void sculpt_update_mesh_elements(struct Scene *scene, struct Object *ob, int need_fmap);
+void sculpt_update_mesh_elements(struct Scene *scene, struct Sculpt *sd, struct Object *ob, int need_fmap);
 
 /* Deformed mesh sculpt */
 void sculpt_free_deformMats(struct SculptSession *ss);
@@ -112,7 +112,6 @@ SculptUndoNode *sculpt_undo_get_node(PBVHNode *node);
 void sculpt_undo_push_begin(const char *name);
 void sculpt_undo_push_end(void);
 
-int sculpt_modifiers_active(Scene *scene, Object *ob);
 void sculpt_vertcos_to_key(Object *ob, KeyBlock *kb, float (*vertCos)[3]);
 
 #endif
index eeca174d8024461d14763a7b9a4731339537688b..c4ea5c9478c9af0c8f5ed0dabd0a968296b1c3c8 100644 (file)
@@ -84,6 +84,7 @@ static void sculpt_restore_deformed(SculptSession *ss, SculptUndoNode *unode, in
 static void sculpt_undo_restore(bContext *C, ListBase *lb)
 {
        Scene *scene = CTX_data_scene(C);
+       Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
        Object *ob = CTX_data_active_object(C);
        DerivedMesh *dm = mesh_get_derived_final(scene, ob, 0);
        SculptSession *ss = ob->sculpt;
@@ -93,7 +94,7 @@ static void sculpt_undo_restore(bContext *C, ListBase *lb)
        int *index;
        int i, j, update= 0;
 
-       sculpt_update_mesh_elements(scene, ob, 0);
+       sculpt_update_mesh_elements(scene, sd, ob, 0);
 
        for(unode=lb->first; unode; unode=unode->next) {
                if(!(strcmp(unode->idname, ob->id.name)==0))
@@ -113,7 +114,7 @@ static void sculpt_undo_restore(bContext *C, ListBase *lb)
                                if (kb) {
                                        ob->shapenr= BLI_findindex(&key->block, kb) + 1;
 
-                                       sculpt_update_mesh_elements(scene, ob, 0);
+                                       sculpt_update_mesh_elements(scene, sd, ob, 0);
                                        WM_event_add_notifier(C, NC_OBJECT|ND_DATA, ob);
                                } else {
                                        /* key has been removed -- skip this undo node */
index a2b32ec7cf866164130953b1cc9d41d174910e26..9560924941dc65bd33bee2b3d90b7c71f03fdb03 100644 (file)
@@ -425,4 +425,15 @@ void crazyspace_build_sculpt(Scene *scene, Object *ob, float (**deformmats)[3][3
                MEM_freeN(origVerts);
                MEM_freeN(quats);
        }
+
+       if(!*deformmats) {
+               int a, numVerts;
+               Mesh *me= (Mesh*)ob->data;
+
+               *deformcos= mesh_getVertexCos(me, &numVerts);
+               *deformmats= MEM_callocN(sizeof(*(*deformmats))*numVerts, "defmats");
+
+               for(a=0; a<numVerts; a++)
+                       unit_m3((*deformmats)[a]);
+       }
 }
index 962fc7d46c24e887dc58b7e1c3cce05ee012cb12..657bfb1c884885bde80df844f466d9ab6be830f8 100644 (file)
@@ -1159,6 +1159,7 @@ typedef enum SculptFlags {
        SCULPT_LOCK_Z = (1<<5),
        SCULPT_SYMMETRY_FEATHER = (1<<6),
        SCULPT_USE_OPENMP = (1<<7),
+       SCULPT_ONLY_DEFORM = (1<<8),
 } SculptFlags;
 
 /* sculpt_paint_settings */
index 58f19fe8799784185e8736568447fc260e3b4479..ce018fdfd6ef7fd8e90618c8a9af5c858d6a5426 100644 (file)
@@ -184,6 +184,16 @@ static int rna_Brush_mode_poll(PointerRNA *ptr, PointerRNA value)
        return brush->ob_mode & mode;
 }
 
+static void rna_Sculpt_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+       Object *ob= (scene->basact)? scene->basact->object: NULL;
+
+       if(ob) {
+               DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
+               WM_main_add_notifier(NC_OBJECT|ND_MODIFIER, ob);
+       }
+}
+
 #else
 
 static void rna_def_paint(BlenderRNA *brna)
@@ -260,6 +270,11 @@ static void rna_def_sculpt(BlenderRNA  *brna)
        prop= RNA_def_property(srna, "use_threaded", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flags", SCULPT_USE_OPENMP);
        RNA_def_property_ui_text(prop, "Use OpenMP", "Take advantage of multiple CPU cores to improve sculpting performance");
+
+       prop= RNA_def_property(srna, "use_deform_only", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flags", SCULPT_ONLY_DEFORM);
+       RNA_def_property_ui_text(prop, "Use Deform Only", "Use only deformation modifiers (temporary disable all constructive modifiers except multi-resolution)");
+       RNA_def_property_update(prop, NC_OBJECT|ND_DRAW, "rna_Sculpt_update");
 }
 
 static void rna_def_vertex_paint(BlenderRNA *brna)