Own TODO item: sculpting on constructive modifiers

- 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
This commit is contained in:
Sergey Sharybin 2011-05-04 13:15:42 +00:00
parent 5d1fdb73ce
commit d000103e80
10 changed files with 104 additions and 48 deletions

View File

@ -946,26 +946,21 @@ class VIEW3D_PT_sculpt_options(PaintPanel, bpy.types.Panel):
sculpt = tool_settings.sculpt sculpt = tool_settings.sculpt
settings = __class__.paint_settings(context) settings = __class__.paint_settings(context)
split = layout.split() layout.label(text="Lock:")
row = layout.row(align=True)
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)
row.prop(sculpt, "lock_x", text="X", toggle=True) row.prop(sculpt, "lock_x", text="X", toggle=True)
row.prop(sculpt, "lock_y", text="Y", toggle=True) row.prop(sculpt, "lock_y", text="Y", toggle=True)
row.prop(sculpt, "lock_z", text="Z", 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): class VIEW3D_PT_sculpt_symmetry(PaintPanel, bpy.types.Panel):
bl_label = "Symmetry" bl_label = "Symmetry"

View 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."); modifier_setError(md, "Modifier requires original data, bad stack position.");
continue; continue;
} }
if(sculpt_mode && (!has_multires || multires_applied)) if(sculpt_mode && (!has_multires || multires_applied)) {
if(mti->type != eModifierTypeType_OnlyDeform || 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."); modifier_setError(md, "Not supported in sculpt mode.");
continue; continue;
} }
}
if(needMapping && !modifier_supportsMapping(md)) continue; if(needMapping && !modifier_supportsMapping(md)) continue;
if(useDeform < 0 && mti->dependsOnTime && mti->dependsOnTime(md)) continue; if(useDeform < 0 && mti->dependsOnTime && mti->dependsOnTime(md)) continue;

View 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 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 */ that this is actually for, to support a pbvh on a modified mesh */
if(!cddm->pbvh && ob->type == OB_MESH) { if(!cddm->pbvh && ob->type == OB_MESH) {
SculptSession *ss= ob->sculpt;
Mesh *me= ob->data; Mesh *me= ob->data;
cddm->pbvh = BLI_pbvh_new(); cddm->pbvh = BLI_pbvh_new();
cddm->pbvh_draw = can_pbvh_draw(ob, dm); cddm->pbvh_draw = can_pbvh_draw(ob, dm);
BLI_pbvh_build_mesh(cddm->pbvh, me->mface, me->mvert, BLI_pbvh_build_mesh(cddm->pbvh, me->mface, me->mvert,
me->totface, me->totvert); me->totface, me->totvert);
if(ob->sculpt->modifiers_active) { if(ss->modifiers_active && ob->derivedDeform) {
DerivedMesh *deformdm= ob->derivedDeform;
float (*vertCos)[3]; float (*vertCos)[3];
int totvert; int totvert;
totvert= dm->getNumVerts(dm); totvert= deformdm->getNumVerts(deformdm);
vertCos= MEM_callocN(3*totvert*sizeof(float), "cdDM_getPBVH vertCos"); 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); BLI_pbvh_apply_vertCos(cddm->pbvh, vertCos);
MEM_freeN(vertCos); MEM_freeN(vertCos);
} }

View File

@ -74,6 +74,7 @@
static int ccgDM_getVertMapIndex(CCGSubSurf *ss, CCGVert *v); static int ccgDM_getVertMapIndex(CCGSubSurf *ss, CCGVert *v);
static int ccgDM_getEdgeMapIndex(CCGSubSurf *ss, CCGEdge *e); static int ccgDM_getEdgeMapIndex(CCGSubSurf *ss, CCGEdge *e);
static int ccgDM_getFaceMapIndex(CCGSubSurf *ss, CCGFace *f); 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) static void ccgdm_pbvh_update(CCGDerivedMesh *ccgdm)
{ {
if(ccgdm->pbvh) { if(ccgdm->pbvh && ccgDM_use_grid_pbvh(ccgdm)) {
CCGFace **faces; CCGFace **faces;
int totface; int totface;
@ -2249,10 +2250,22 @@ static ListBase *ccgDM_getFaceMap(Object *ob, DerivedMesh *dm)
return ccgdm->fmap; 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) static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
{ {
CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm; CCGDerivedMesh *ccgdm= (CCGDerivedMesh*)dm;
int gridSize, numGrids; int gridSize, numGrids, grid_pbvh;
if(!ob) { if(!ob) {
ccgdm->pbvh= NULL; ccgdm->pbvh= NULL;
@ -2262,13 +2275,17 @@ static struct PBVH *ccgDM_getPBVH(Object *ob, DerivedMesh *dm)
if(!ob->sculpt) if(!ob->sculpt)
return NULL; return NULL;
grid_pbvh= ccgDM_use_grid_pbvh(ccgdm);
if(ob->sculpt->pbvh) { if(ob->sculpt->pbvh) {
/* pbvh's grids, gridadj and gridfaces points to data inside ccgdm if(grid_pbvh) {
but this can be freed on ccgdm release, this updates the pointers /* pbvh's grids, gridadj and gridfaces points to data inside ccgdm
when the ccgdm gets remade, the assumption is that the topology but this can be freed on ccgdm release, this updates the pointers
does not change. */ when the ccgdm gets remade, the assumption is that the topology
ccgdm_create_grids(dm); does not change. */
BLI_pbvh_grids_update(ob->sculpt->pbvh, ccgdm->gridData, ccgdm->gridAdjacency, (void**)ccgdm->gridFaces); ccgdm_create_grids(dm);
BLI_pbvh_grids_update(ob->sculpt->pbvh, ccgdm->gridData, ccgdm->gridAdjacency, (void**)ccgdm->gridFaces);
}
ccgdm->pbvh = ob->sculpt->pbvh; 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 /* 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 we build a pbvh over the modified mesh, in other cases the base mesh
is being sculpted, so we build a pbvh from that. */ 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); gridSize = ccgDM_getGridSize(dm);
numGrids = ccgDM_getNumGrids(dm); numGrids = ccgDM_getNumGrids(dm);
ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new(); ob->sculpt->pbvh= ccgdm->pbvh = BLI_pbvh_new();
BLI_pbvh_build_grids(ccgdm->pbvh, ccgdm->gridData, ccgdm->gridAdjacency, BLI_pbvh_build_grids(ccgdm->pbvh, ccgdm->gridData, ccgdm->gridAdjacency,
numGrids, gridSize, (void**)ccgdm->gridFaces); 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; return ccgdm->pbvh;
} }

View File

@ -172,7 +172,7 @@ static int sculpt_has_active_modifiers(Scene *scene, Object *ob)
} }
/* Checks if there are any supported deformation modifiers active */ /* 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; ModifierData *md;
Mesh *me= (Mesh*)ob->data; 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 */ /* exception for shape keys because we can edit those */
for(; md; md= md->next) { for(; md; md= md->next) {
ModifierTypeInfo *mti = modifierType_getInfo(md->type); ModifierTypeInfo *mti = modifierType_getInfo(md->type);
if(!modifier_isEnabled(scene, md, eModifierMode_Realtime)) continue; if(!modifier_isEnabled(scene, md, eModifierMode_Realtime)) continue;
if(md->type==eModifierType_ShapeKey) continue; if(md->type==eModifierType_ShapeKey) continue;
if(mti->type==eModifierTypeType_OnlyDeform) if(mti->type==eModifierTypeType_OnlyDeform) return 1;
return 1; else if((sd->flags & SCULPT_ONLY_DEFORM)==0) return 1;
} }
return 0; return 0;
@ -2705,13 +2704,13 @@ void sculpt_free_deformMats(SculptSession *ss)
ss->deform_imats = NULL; 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); DerivedMesh *dm = mesh_get_derived_final(scene, ob, CD_MASK_BAREMESH);
SculptSession *ss = ob->sculpt; SculptSession *ss = ob->sculpt;
MultiresModifierData *mmd= sculpt_multires_active(scene, ob); 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); if(!mmd) ss->kb= ob_get_keyblock(ob);
else ss->kb= NULL; 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; Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
Brush *brush = paint_brush(&sd->paint); 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); view3d_operator_needs_opengl(C);
sculpt_brush_init_tex(sd, ss); 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; return 1;
} }
@ -3685,7 +3684,7 @@ static void sculpt_init_session(Scene *scene, Object *ob)
{ {
ob->sculpt = MEM_callocN(sizeof(SculptSession), "sculpt session"); 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)) static int sculpt_toggle_mode(bContext *C, wmOperator *UNUSED(op))

View File

@ -64,7 +64,7 @@ struct Brush *sculptmode_brush(void);
void sculpt(Sculpt *sd); void sculpt(Sculpt *sd);
int sculpt_poll(struct bContext *C); 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 */ /* Deformed mesh sculpt */
void sculpt_free_deformMats(struct SculptSession *ss); 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_begin(const char *name);
void sculpt_undo_push_end(void); 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]); void sculpt_vertcos_to_key(Object *ob, KeyBlock *kb, float (*vertCos)[3]);
#endif #endif

View File

@ -84,6 +84,7 @@ static void sculpt_restore_deformed(SculptSession *ss, SculptUndoNode *unode, in
static void sculpt_undo_restore(bContext *C, ListBase *lb) static void sculpt_undo_restore(bContext *C, ListBase *lb)
{ {
Scene *scene = CTX_data_scene(C); Scene *scene = CTX_data_scene(C);
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
Object *ob = CTX_data_active_object(C); Object *ob = CTX_data_active_object(C);
DerivedMesh *dm = mesh_get_derived_final(scene, ob, 0); DerivedMesh *dm = mesh_get_derived_final(scene, ob, 0);
SculptSession *ss = ob->sculpt; SculptSession *ss = ob->sculpt;
@ -93,7 +94,7 @@ static void sculpt_undo_restore(bContext *C, ListBase *lb)
int *index; int *index;
int i, j, update= 0; 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) { for(unode=lb->first; unode; unode=unode->next) {
if(!(strcmp(unode->idname, ob->id.name)==0)) if(!(strcmp(unode->idname, ob->id.name)==0))
@ -113,7 +114,7 @@ static void sculpt_undo_restore(bContext *C, ListBase *lb)
if (kb) { if (kb) {
ob->shapenr= BLI_findindex(&key->block, kb) + 1; 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); WM_event_add_notifier(C, NC_OBJECT|ND_DATA, ob);
} else { } else {
/* key has been removed -- skip this undo node */ /* key has been removed -- skip this undo node */

View File

@ -425,4 +425,15 @@ void crazyspace_build_sculpt(Scene *scene, Object *ob, float (**deformmats)[3][3
MEM_freeN(origVerts); MEM_freeN(origVerts);
MEM_freeN(quats); 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]);
}
} }

View File

@ -1159,6 +1159,7 @@ typedef enum SculptFlags {
SCULPT_LOCK_Z = (1<<5), SCULPT_LOCK_Z = (1<<5),
SCULPT_SYMMETRY_FEATHER = (1<<6), SCULPT_SYMMETRY_FEATHER = (1<<6),
SCULPT_USE_OPENMP = (1<<7), SCULPT_USE_OPENMP = (1<<7),
SCULPT_ONLY_DEFORM = (1<<8),
} SculptFlags; } SculptFlags;
/* sculpt_paint_settings */ /* sculpt_paint_settings */

View File

@ -184,6 +184,16 @@ static int rna_Brush_mode_poll(PointerRNA *ptr, PointerRNA value)
return brush->ob_mode & mode; 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 #else
static void rna_def_paint(BlenderRNA *brna) 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); 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_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"); 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) static void rna_def_vertex_paint(BlenderRNA *brna)