Force sculpting on highest multires level
authorSergey Sharybin <sergey.vfx@gmail.com>
Wed, 13 Nov 2019 15:58:32 +0000 (16:58 +0100)
committerSergey Sharybin <sergey.vfx@gmail.com>
Wed, 13 Nov 2019 16:15:54 +0000 (17:15 +0100)
This is a workaround for T58473 to avoid likely event of ruining
sculpted data.

Differential Revision: https://developer.blender.org/D6244

release/scripts/startup/bl_ui/properties_data_modifier.py
source/blender/blenkernel/BKE_multires.h
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/crazyspace.c
source/blender/blenkernel/intern/multires.c
source/blender/blenkernel/intern/paint.c
source/blender/editors/sculpt_paint/sculpt.c

index 124fe77cb52fda0c9d300cc085c435a467176b26..37b93e9ac28459277426e9030a2ce176cb73f8b7 100644 (file)
@@ -645,7 +645,8 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
         split = layout.split()
         col = split.column()
         col.prop(md, "levels", text="Preview")
-        col.prop(md, "sculpt_levels", text="Sculpt")
+        # TODO(sergey): Expose it again after T58473 is solved.
+        # col.prop(md, "sculpt_levels", text="Sculpt")
         col.prop(md, "render_levels", text="Render")
         col.prop(md, "quality")
 
index 7513717df418a893d550102f2f96c94327d3b292..50456fd4074fd5bcbb611c0ed063be1bd4720d05 100644 (file)
@@ -182,6 +182,8 @@ BLI_INLINE void BKE_multires_construct_tangent_matrix(float tangent_matrix[3][3]
                                                       const float dPdv[3],
                                                       const int corner);
 
+int BKE_multires_sculpt_level_get(const struct MultiresModifierData *mmd);
+
 #include "intern/multires_inline.h"
 
 #endif /* __BKE_MULTIRES_H__ */
index cc9db5eafb511f36d0394472afbcb495392e6cfa..9682ea74cfb97be385e3e40f776723b7a5d0649c 100644 (file)
@@ -918,7 +918,7 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
 
   /* Sculpt can skip certain modifiers. */
   MultiresModifierData *mmd = get_multires_modifier(scene, ob, 0);
-  const bool has_multires = (mmd && mmd->sculptlvl != 0);
+  const bool has_multires = (mmd && BKE_multires_sculpt_level_get(mmd) != 0);
   bool multires_applied = false;
   const bool sculpt_mode = ob->mode & OB_MODE_SCULPT && ob->sculpt && !use_render;
   const bool sculpt_dyntopo = (sculpt_mode && ob->sculpt->bm) && !use_render;
@@ -1036,7 +1036,8 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
     if (sculpt_mode && (!has_multires || multires_applied || sculpt_dyntopo)) {
       bool unsupported = false;
 
-      if (md->type == eModifierType_Multires && ((MultiresModifierData *)md)->sculptlvl == 0) {
+      if (md->type == eModifierType_Multires &&
+          BKE_multires_sculpt_level_get((MultiresModifierData *)md) == 0) {
         /* If multires is on level 0 skip it silently without warning message. */
         if (!sculpt_dyntopo) {
           continue;
index fe834658689529e75e0be615a5c1db2d70e260e3..f2ed84b412501b83e028fe0d997f3a67bfff9f06 100644 (file)
@@ -385,7 +385,7 @@ int BKE_sculpt_get_first_deform_matrices(struct Depsgraph *depsgraph,
   crazyspace_init_object_for_eval(depsgraph, object, &object_eval);
   MultiresModifierData *mmd = get_multires_modifier(scene, &object_eval, 0);
   const bool is_sculpt_mode = (object->mode & OB_MODE_SCULPT) != 0;
-  const bool has_multires = mmd != NULL && mmd->sculptlvl > 0;
+  const bool has_multires = mmd != NULL && BKE_multires_sculpt_level_get(mmd) > 0;
   const ModifierEvalContext mectx = {depsgraph, &object_eval, 0};
 
   if (is_sculpt_mode && has_multires) {
index 6a5e31bd2a23a6b6da45f62004c2456485eb2824..a539aa45cf6acca0a4f4480bb8075b4f76fcb9f8 100644 (file)
@@ -347,7 +347,7 @@ int multires_get_level(const Scene *scene,
                              mmd->renderlvl;
   }
   else if (ob->mode == OB_MODE_SCULPT) {
-    return mmd->sculptlvl;
+    return BKE_multires_sculpt_level_get(mmd);
   }
   else if (ignore_simplify) {
     return mmd->lvl;
@@ -2557,3 +2557,12 @@ int mdisp_rot_face_to_crn(struct MVert *UNUSED(mvert),
 
   return S;
 }
+
+/* This is a workaround for T58473.
+ * Force sculpting on the highest level for until the root of the issue is solved.
+ *
+ * When that issue is solved simple replace call of this function with mmd->sculptlvl. */
+int BKE_multires_sculpt_level_get(const struct MultiresModifierData *mmd)
+{
+  return mmd->totlvl;
+}
index cc9d1b98ba404d3900695ed85175c4064c34d40a..46ef24be5e9e042ab705487c400a4753cf19097e 100644 (file)
@@ -60,6 +60,7 @@
 #include "BKE_mesh_mapping.h"
 #include "BKE_mesh_runtime.h"
 #include "BKE_modifier.h"
+#include "BKE_multires.h"
 #include "BKE_object.h"
 #include "BKE_paint.h"
 #include "BKE_pbvh.h"
@@ -1117,7 +1118,7 @@ MultiresModifierData *BKE_sculpt_multires_active(Scene *scene, Object *ob)
         continue;
       }
 
-      if (mmd->sculptlvl > 0) {
+      if (BKE_multires_sculpt_level_get(mmd) > 0) {
         return mmd;
       }
       else {
@@ -1360,7 +1361,7 @@ int BKE_sculpt_mask_layers_ensure(Object *ob, MultiresModifierData *mmd)
    * isn't one already */
   if (mmd && !CustomData_has_layer(&me->ldata, CD_GRID_PAINT_MASK)) {
     GridPaintMask *gmask;
-    int level = max_ii(1, mmd->sculptlvl);
+    int level = max_ii(1, BKE_multires_sculpt_level_get(mmd));
     int gridsize = BKE_ccg_gridsize(level);
     int gridarea = gridsize * gridsize;
     int i, j;
index 43f1bbb33f37a8f2dd57c188e6a23d87a359cccd..f7a5052b74af74308ce622dd84d192e20ca37de7 100644 (file)
@@ -7662,7 +7662,7 @@ static int ed_object_sculptmode_flush_recalc_flag(Scene *scene,
 {
   int flush_recalc = 0;
   /* multires in sculpt mode could have different from object mode subdivision level */
-  flush_recalc |= mmd && mmd->sculptlvl != mmd->lvl;
+  flush_recalc |= mmd && BKE_multires_sculpt_level_get(mmd) != mmd->lvl;
   /* if object has got active modifiers, it's dm could be different in sculpt mode  */
   flush_recalc |= sculpt_has_active_modifiers(scene, ob);
   return flush_recalc;