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
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"

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.");
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;

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
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);
}

View 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;
}

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 */
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))

View 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

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)
{
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 */

View 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]);
}
}

View 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 */

View 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)