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:
parent
5d1fdb73ce
commit
d000103e80
|
@ -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"
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue