diff --git a/release/scripts/startup/bl_ui/space_view3d_toolbar.py b/release/scripts/startup/bl_ui/space_view3d_toolbar.py index bd258fa18f6..a6db6fbdde8 100644 --- a/release/scripts/startup/bl_ui/space_view3d_toolbar.py +++ b/release/scripts/startup/bl_ui/space_view3d_toolbar.py @@ -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" diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c index 297489ee56f..d9c98bc0200 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.c +++ b/source/blender/blenkernel/intern/DerivedMesh.c @@ -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; diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index baf89f9f494..72ee9b55800 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -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); } diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 33094313acd..5d44841df8b 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -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; } diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c index c7733ced1f3..7156b49c026 100644 --- a/source/blender/editors/sculpt_paint/sculpt.c +++ b/source/blender/editors/sculpt_paint/sculpt.c @@ -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)) diff --git a/source/blender/editors/sculpt_paint/sculpt_intern.h b/source/blender/editors/sculpt_paint/sculpt_intern.h index 5e017d0dc20..33970ea0179 100644 --- a/source/blender/editors/sculpt_paint/sculpt_intern.h +++ b/source/blender/editors/sculpt_paint/sculpt_intern.h @@ -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 diff --git a/source/blender/editors/sculpt_paint/sculpt_undo.c b/source/blender/editors/sculpt_paint/sculpt_undo.c index eeca174d802..c4ea5c9478c 100644 --- a/source/blender/editors/sculpt_paint/sculpt_undo.c +++ b/source/blender/editors/sculpt_paint/sculpt_undo.c @@ -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 */ diff --git a/source/blender/editors/util/crazyspace.c b/source/blender/editors/util/crazyspace.c index a2b32ec7cf8..9560924941d 100644 --- a/source/blender/editors/util/crazyspace.c +++ b/source/blender/editors/util/crazyspace.c @@ -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; aob_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)