Sculpt UI: Make DynTopo constant detail a resolution value
authorJulian Eisel <eiseljulian@gmail.com>
Sat, 12 Nov 2016 15:14:09 +0000 (16:14 +0100)
committerJulian Eisel <eiseljulian@gmail.com>
Sat, 12 Nov 2016 15:53:38 +0000 (16:53 +0100)
This should make it easier to sculpt in high resolutions, downside is that the new way to calculate maximum edge length is a bit less intuitive. Maximum edge length used to be calculated as blender_unit * percentage_value, now it's blender_unit / value.

Reused old DNA struct member, but had to bump subversion to ensure correct compatibility conversion. Also changed default value slightly (would have had to set to 3.333... otherwise).

Was Requested by @monio (see https://rightclickselect.com/p/sculpting/zpbbbc/dyntopo-better-scale-input-in-constant-detail-mode) and I think it's worth testing.

release/scripts/startup/bl_ui/space_view3d_toolbar.py
source/blender/blenkernel/BKE_blender_version.h
source/blender/blenloader/intern/versioning_270.c
source/blender/editors/interface/resources.c
source/blender/editors/sculpt_paint/sculpt.c
source/blender/makesdna/DNA_scene_types.h
source/blender/makesrna/intern/rna_sculpt_paint.c

index f97e2d5b2d1e18a5038317dc96d0751a7b4b9271..3eb76a3b0f92d5c9f391d69d383075ff53f6c7c0 100644 (file)
@@ -1560,7 +1560,7 @@ class VIEW3D_PT_sculpt_dyntopo(Panel, View3DPaintPanel):
         sub.active = (brush and brush.sculpt_tool != 'MASK')
         if (sculpt.detail_type_method == 'CONSTANT'):
             row = sub.row(align=True)
-            row.prop(sculpt, "constant_detail")
+            row.prop(sculpt, "constant_detail_resolution")
             row.operator("sculpt.sample_detail_size", text="", icon='EYEDROPPER')
         elif (sculpt.detail_type_method == 'BRUSH'):
             sub.prop(sculpt, "detail_percent")
index 908e6f214f983ca0ca36a22f2fbb2157ae031c55..baf8510dd0dc19d67181b0196502890e3b7726a5 100644 (file)
@@ -28,7 +28,7 @@
  * and keep comment above the defines.
  * Use STRINGIFY() rather than defining with quotes */
 #define BLENDER_VERSION         278
-#define BLENDER_SUBVERSION      2
+#define BLENDER_SUBVERSION      3
 /* Several breakages with 270, e.g. constraint deg vs rad */
 #define BLENDER_MINVERSION      270
 #define BLENDER_MINSUBVERSION   6
index 8e855eb56b89ae6489c279c938da893a39187caf..8133d0496faadb718d92c1d0823bc079cc4a50e3 100644 (file)
@@ -1427,7 +1427,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
                }
        }
 
-       {
+       if (!MAIN_VERSION_ATLEAST(main, 278, 3)) {
                for (Scene *scene = main->scene.first; scene != NULL; scene = scene->id.next) {
                        if (scene->toolsettings != NULL) {
                                ToolSettings *ts = scene->toolsettings;
@@ -1454,5 +1454,16 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
                                }
                        }
                }
+
+               /* constant detail for sculpting is now a resolution value instead of
+                * a percentage, we reuse old DNA struct member but convert it */
+               for (Scene *scene = main->scene.first; scene != NULL; scene = scene->id.next) {
+                       if (scene->toolsettings != NULL) {
+                               ToolSettings *ts = scene->toolsettings;
+                               if (ts->sculpt && ts->sculpt->constant_detail != 0.0f) {
+                                       ts->sculpt->constant_detail = 100.0f / ts->sculpt->constant_detail;
+                               }
+                       }
+               }
        }
 }
index 5e24dc962553798f6763120be62c932b71a384a3..539284030c252e27585a3a55ba572628fca52b1d 100644 (file)
@@ -2750,17 +2750,21 @@ void init_userdef_do_versions(void)
                }
        }
 
+       if (!USER_VERSION_ATLEAST(278, 3)) {
+               for (bTheme *btheme = U.themes.first; btheme; btheme = btheme->next) {
+                       /* Keyframe Indicators (were using wrong alpha) */
+                       btheme->tv3d.time_keyframe[3] = btheme->tv3d.time_gp_keyframe[3] = 255;
+                       btheme->ttime.time_keyframe[3] = btheme->ttime.time_gp_keyframe[3] = 255;
+               }
+       }
+
        /**
         * Include next version bump.
         *
         * (keep this block even if it becomes empty).
         */
        {
-               for (bTheme *btheme = U.themes.first; btheme; btheme = btheme->next) {
-                       /* Keyframe Indicators (were using wrong alpha) */
-                       btheme->tv3d.time_keyframe[3] = btheme->tv3d.time_gp_keyframe[3] = 255;
-                       btheme->ttime.time_keyframe[3] = btheme->ttime.time_gp_keyframe[3] = 255;
-               }
+               
        }
 
        if (U.pixelsize == 0.0f)
index fe0fb3f50357d56adfef20bedc217d6d538e714f..53434b18d063cb6b531ee2edaad77a487a31749a 100644 (file)
@@ -4688,7 +4688,7 @@ static void sculpt_stroke_update_step(bContext *C, struct PaintStroke *UNUSED(st
        sculpt_restore_mesh(sd, ob);
 
        if (sd->flags & SCULPT_DYNTOPO_DETAIL_CONSTANT) {
-               BKE_pbvh_bmesh_detail_size_set(ss->pbvh, sd->constant_detail / 100.0f);
+               BKE_pbvh_bmesh_detail_size_set(ss->pbvh, 1.0f / sd->constant_detail);
        }
        else if (sd->flags & SCULPT_DYNTOPO_DETAIL_BRUSH) {
                BKE_pbvh_bmesh_detail_size_set(ss->pbvh, ss->cache->radius * sd->detail_percent / 100.0f);
@@ -5406,7 +5406,7 @@ static int sculpt_mode_toggle_exec(bContext *C, wmOperator *op)
                if (!ts->sculpt->detail_percent)
                        ts->sculpt->detail_percent = 25;
                if (ts->sculpt->constant_detail == 0.0f)
-                       ts->sculpt->constant_detail = 30.0f;
+                       ts->sculpt->constant_detail = 3.0f;
 
                /* Set sane default tiling offsets */
                if (!ts->sculpt->paint.tile_offset[0]) ts->sculpt->paint.tile_offset[0] = 1.0f;
@@ -5543,7 +5543,7 @@ static int sculpt_detail_flood_fill_exec(bContext *C, wmOperator *UNUSED(op))
        size = max_fff(bb_max[0], bb_max[1], bb_max[2]);
 
        /* update topology size */
-       BKE_pbvh_bmesh_detail_size_set(ss->pbvh, sd->constant_detail / 100.0f);
+       BKE_pbvh_bmesh_detail_size_set(ss->pbvh, 1.0f / sd->constant_detail);
 
        sculpt_undo_push_begin("Dynamic topology flood fill");
        sculpt_undo_push_node(ob, NULL, SCULPT_UNDO_COORDS);
@@ -5608,7 +5608,8 @@ static void sample_detail(bContext *C, int ss_co[2])
                         ray_start, ray_normal, false);
 
        if (srd.hit) {
-               sd->constant_detail = srd.detail * 100.0f;
+               /* convert edge length to detail resolution */
+               sd->constant_detail = 1.0f / srd.detail;
        }
 }
 
index 9b0781ebe708f347cb92783e160bab44fdcf584e..f5e71ae59a9d832d3694361166d311a8af047c6d 100644 (file)
@@ -1103,7 +1103,7 @@ typedef struct Sculpt {
        float gravity_factor;
 
        /* scale for constant detail size */
-       float constant_detail;
+       float constant_detail; /* Constant detail resolution (Blender unit / constant_detail) */
        float detail_percent;
        float pad;
 
index e169ef0d822964ac47d8b02abad28889750d8bc7..7f405f0fb1fa8e9c866acc66e064ec00f91bcba5 100644 (file)
@@ -600,10 +600,12 @@ static void rna_def_sculpt(BlenderRNA  *brna)
        RNA_def_property_ui_text(prop, "Detail Percentage", "Maximum edge length for dynamic topology sculpting (in brush percenage)");
        RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
 
-       prop = RNA_def_property(srna, "constant_detail", PROP_FLOAT, PROP_PERCENTAGE);
-       RNA_def_property_range(prop, 0.001, 10000.0);
-       RNA_def_property_ui_range(prop, 0.1, 100.0, 10, 2);
-       RNA_def_property_ui_text(prop, "Detail Size", "Maximum edge length for dynamic topology sculpting (as percentage of blender unit)");
+       prop = RNA_def_property(srna, "constant_detail_resolution", PROP_FLOAT, PROP_NONE);
+       RNA_def_property_float_sdna(prop, NULL, "constant_detail");
+       RNA_def_property_range(prop, 0.0001, FLT_MAX);
+       RNA_def_property_ui_range(prop, 0.001, 1000.0, 10, 2);
+       RNA_def_property_ui_text(prop, "Resolution", "Maximum edge length for dynamic topology sculpting (as divisor "
+                                "of blender unit - higher value means smaller edge length)");
        RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, NULL);
 
        prop = RNA_def_property(srna, "use_smooth_shading", PROP_BOOLEAN, PROP_NONE);