Revision: 21278
          
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=21278
Author:   nicholasbishop
Date:     2009-07-01 01:06:50 +0200 (Wed, 01 Jul 2009)

Log Message:
-----------
2.5/Sculpt:

== Re-added smooth stroke ==

UI: toggle is just in the sculpt menu for now. Also changes the sculpt paint 
cursor slightly, draws a line between previous and current locations.

It's a different implementation than in 2.4, works like this:

The stroke interpolates between the last mouse location and the current 
location, weighted towards the previous location. If the stroke gets within a 
certain radius of the current mouse location, the stroke stops. This radius 
allows for sharp turns in the stroke.

Todo: there are two hard-coded parameters that should become user settable, 
that's the weighting between previous and current locations, and most 
important, the no-update radius.

Note also that this option was added as a per-brush flag, worth discussing 
whether that's the correct place, or whether it should be a sculpt setting like 
symmetry?

== Improved stroke spacing ==
The previous implementation of stroke spacing simply guaranteed that stroke 
dots would not occur any closer than the space setting. It now forces stroke 
dots to always be the specified distance apart.

Todo: Performance gets pretty awful with a small spacing setting, this needs 
optimization.

Modified Paths:
--------------
    branches/blender2.5/blender/source/blender/editors/sculpt_paint/sculpt.c
    
branches/blender2.5/blender/source/blender/editors/space_view3d/view3d_header.c
    branches/blender2.5/blender/source/blender/makesdna/DNA_brush_types.h
    branches/blender2.5/blender/source/blender/makesrna/intern/rna_brush.c

Modified: 
branches/blender2.5/blender/source/blender/editors/sculpt_paint/sculpt.c
===================================================================
--- branches/blender2.5/blender/source/blender/editors/sculpt_paint/sculpt.c    
2009-06-30 22:07:42 UTC (rev 21277)
+++ branches/blender2.5/blender/source/blender/editors/sculpt_paint/sculpt.c    
2009-06-30 23:06:50 UTC (rev 21278)
@@ -156,7 +156,6 @@
        float old_grab_location[3];
        int symmetry; /* Symmetry index between 0 and 7 */
        float view_normal[3], view_normal_symmetry[3];
-       int last_dot[2]; /* Last location of stroke application */
        int last_rake[2]; /* Last location of updating rake rotation */
 } StrokeCache;
 
@@ -849,15 +848,6 @@
        const char symm = sd->flags & 7;
        int i;
 
-       /* Brush spacing: only apply dot if next dot is far enough away */
-       if((sd->brush->flag & BRUSH_SPACE) && !(sd->brush->flag & 
BRUSH_ANCHORED) && !cache->first_time) {
-               int dx = cache->last_dot[0] - cache->mouse[0];
-               int dy = cache->last_dot[1] - cache->mouse[1];
-               if(sqrt(dx*dx+dy*dy) < sd->brush->spacing)
-                       return;
-       }
-       memcpy(cache->last_dot, cache->mouse, sizeof(int) * 2);
-
        VecCopyf(cache->location, cache->true_location);
        VecCopyf(cache->grab_delta_symmetry, cache->grab_delta);
        cache->symmetry = 0;
@@ -1050,16 +1040,21 @@
 {
        Sculpt *sd= CTX_data_tool_settings(C)->sculpt;
        
-       glTranslatef((float)x, (float)y, 0.0f);
-       
        glColor4ub(255, 100, 100, 128);
        glEnable( GL_LINE_SMOOTH );
        glEnable(GL_BLEND);
+
+       glTranslatef((float)x, (float)y, 0.0f);
        glutil_draw_lined_arc(0.0, M_PI*2.0, sd->brush->size, 40);
+       glTranslatef((float)-x, (float)-y, 0.0f);
+
+       if(sd->session && sd->session->cache && sd->brush && (sd->brush->flag & 
BRUSH_SMOOTH_STROKE)) {
+               ARegion *ar = CTX_wm_region(C);
+               sdrawline(x, y, sd->session->cache->mouse[0] - ar->winrct.xmin, 
sd->session->cache->mouse[1] - ar->winrct.ymin);
+       }
+
        glDisable(GL_BLEND);
        glDisable( GL_LINE_SMOOTH );
-       
-       glTranslatef((float)-x, (float)-y, 0.0f);
 }
 
 static void toggle_paint_cursor(bContext *C)
@@ -1202,6 +1197,9 @@
        RNA_int_get_array(op->ptr, "initial_mouse", cache->initial_mouse);
        cache->depth = RNA_float_get(op->ptr, "depth");
 
+       cache->mouse[0] = cache->initial_mouse[0];
+       cache->mouse[1] = cache->initial_mouse[1];
+
        /* Truly temporary data that isn't stored in properties */
 
        view3d_set_viewcontext(C, &cache->vc);
@@ -1407,13 +1405,99 @@
        ED_region_tag_redraw(ar);
 }
 
+/* Returns zero if no sculpt changes should be made, non-zero otherwise */
+static int sculpt_smooth_stroke(Sculpt *s, int output[2], wmEvent *event)
+{
+       output[0] = event->x;
+       output[1] = event->y;
+
+       if(s->brush->flag & BRUSH_SMOOTH_STROKE && s->brush->sculpt_tool != 
SCULPT_TOOL_GRAB) {
+               StrokeCache *cache = s->session->cache;
+               float u = .9, v = 1.0 - u;
+               int dx = cache->mouse[0] - event->x, dy = cache->mouse[1] - 
event->y;
+               int radius = 50;
+
+               /* If the mouse is moving within the radius of the last move,
+                  don't update the mouse position. This allows sharp turns. */
+               if(dx*dx + dy*dy < radius*radius)
+                       return 0;
+
+               output[0] = event->x * v + cache->mouse[0] * u;
+               output[1] = event->y * v + cache->mouse[1] * u;
+       }
+
+       return 1;
+}
+
+/* Returns zero if the stroke dots should not be spaced, non-zero otherwise */
+int sculpt_space_stroke_enabled(Sculpt *s)
+{
+       Brush *br = s->brush;
+       return (br->flag & BRUSH_SPACE) && !(br->flag & BRUSH_ANCHORED) && 
(br->sculpt_tool != SCULPT_TOOL_GRAB);
+}
+
+/* Put the location of the next sculpt stroke dot into the stroke RNA and 
apply it to the mesh */
+static void sculpt_brush_stroke_add_step(bContext *C, wmOperator *op, wmEvent 
*event, int mouse[2])
+{
+       Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
+       StrokeCache *cache = sd->session->cache;
+       PointerRNA itemptr;
+       float cur_depth;
+       float center[3];
+
+       cur_depth = read_cached_depth(&cache->vc, mouse[0], mouse[1]);
+       unproject(sd->session->cache->mats, center, mouse[0], mouse[1], 
cur_depth);
+                               
+       /* Add to stroke */
+       RNA_collection_add(op->ptr, "stroke", &itemptr);
+       RNA_float_set_array(&itemptr, "location", center);
+       RNA_int_set_array(&itemptr, "mouse", mouse);
+       RNA_boolean_set(&itemptr, "flip", event->shift);
+       sculpt_update_cache_variants(sd, &itemptr);
+                               
+       sculpt_restore_mesh(sd);
+       do_symmetrical_brush_actions(sd, cache);
+                               
+       sculpt_post_stroke_free(sd->session);
+}
+
+/* For brushes with stroke spacing enabled, moves mouse in steps
+   towards the final mouse location. */
+static int sculpt_space_stroke(bContext *C, wmOperator *op, wmEvent *event, 
Sculpt *s, const int final_mouse[2])
+{
+       StrokeCache *cache = s->session->cache;
+       int cnt = 0;
+
+       if(sculpt_space_stroke_enabled(s)) {
+               float vec[2] = {final_mouse[0] - cache->mouse[0], 
final_mouse[1] - cache->mouse[1]};
+               int mouse[2] = {cache->mouse[0], cache->mouse[1]};
+               float length, scale;
+               int steps = 0, i;
+
+               /* Normalize the vector between the last stroke dot and the 
goal */
+               length = sqrt(vec[0]*vec[0] + vec[1]*vec[1]);
+
+               if(length > FLT_EPSILON) {
+                       scale = s->brush->spacing / length;
+                       vec[0] *= scale;
+                       vec[1] *= scale;
+
+                       steps = (int)(length / s->brush->spacing);
+                       for(i = 0; i < steps; ++i, ++cnt) {
+                               mouse[0] += vec[0];
+                               mouse[1] += vec[1];
+                               sculpt_brush_stroke_add_step(C, op, event, 
mouse);
+                       }
+               }
+       }
+
+       return cnt;
+}
+
 static int sculpt_brush_stroke_modal(bContext *C, wmOperator *op, wmEvent 
*event)
 {
-       PointerRNA itemptr;
        Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
        ARegion *ar = CTX_wm_region(C);
-       float center[3];
-       int mouse[2] = {event->x, event->y};
        float cur_depth;
 
        sculpt_update_mesh_elements(C);
@@ -1433,21 +1517,19 @@
        }
 
        if(sd->session->cache) {
-               cur_depth = read_cached_depth(&sd->session->cache->vc, 
event->x, event->y);
-               unproject(sd->session->cache->mats, center, event->x, event->y, 
cur_depth);
+               int mouse[2];
 
-               /* Add to stroke */
-               RNA_collection_add(op->ptr, "stroke", &itemptr);
-               RNA_float_set_array(&itemptr, "location", center);
-               RNA_int_set_array(&itemptr, "mouse", mouse);
-               RNA_boolean_set(&itemptr, "flip", event->shift);
-               sculpt_update_cache_variants(sd, &itemptr);
-
-               sculpt_restore_mesh(sd);
-               do_symmetrical_brush_actions(CTX_data_tool_settings(C)->sculpt, 
sd->session->cache);
-
-               sculpt_flush_update(C);
-               sculpt_post_stroke_free(sd->session);
+               if(sculpt_smooth_stroke(sd, mouse, event)) {
+                       if(sculpt_space_stroke_enabled(sd)) {
+                               if(!sculpt_space_stroke(C, op, event, sd, 
mouse))
+                                       ED_region_tag_redraw(ar);
+                       }
+                       else
+                               sculpt_brush_stroke_add_step(C, op, event, 
mouse);
+                       sculpt_flush_update(C);
+               }
+               else
+                       ED_region_tag_redraw(ar);
        }
 
        /* Finished */

Modified: 
branches/blender2.5/blender/source/blender/editors/space_view3d/view3d_header.c
===================================================================
--- 
branches/blender2.5/blender/source/blender/editors/space_view3d/view3d_header.c 
    2009-06-30 22:07:42 UTC (rev 21277)
+++ 
branches/blender2.5/blender/source/blender/editors/space_view3d/view3d_header.c 
    2009-06-30 23:06:50 UTC (rev 21278)
@@ -4557,6 +4557,7 @@
        uiItemR(layout, NULL, 0, &rna, "rake", 0, 0, 0);
        uiItemR(layout, NULL, 0, &rna, "anchored", 0, 0, 0);
        uiItemR(layout, NULL, 0, &rna, "space", 0, 0, 0);
+       uiItemR(layout, NULL, 0, &rna, "smooth_stroke", 0, 0, 0);
 
        uiItemR(layout, NULL, 0, &rna, "flip_direction", 0, 0, 0);
 }

Modified: branches/blender2.5/blender/source/blender/makesdna/DNA_brush_types.h
===================================================================
--- branches/blender2.5/blender/source/blender/makesdna/DNA_brush_types.h       
2009-06-30 22:07:42 UTC (rev 21277)
+++ branches/blender2.5/blender/source/blender/makesdna/DNA_brush_types.h       
2009-06-30 23:06:50 UTC (rev 21278)
@@ -84,6 +84,7 @@
 #define BRUSH_ANCHORED         256
 #define BRUSH_DIR_IN           512
 #define BRUSH_SPACE            1024
+#define BRUSH_SMOOTH_STROKE    2048
 
 /* Brush.blend */
 #define BRUSH_BLEND_MIX                0

Modified: branches/blender2.5/blender/source/blender/makesrna/intern/rna_brush.c
===================================================================
--- branches/blender2.5/blender/source/blender/makesrna/intern/rna_brush.c      
2009-06-30 22:07:42 UTC (rev 21277)
+++ branches/blender2.5/blender/source/blender/makesrna/intern/rna_brush.c      
2009-06-30 23:06:50 UTC (rev 21278)
@@ -184,6 +184,10 @@
        prop= RNA_def_property(srna, "space", PROP_BOOLEAN, PROP_NONE);
        RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_SPACE);
        RNA_def_property_ui_text(prop, "Space", "Limit brush application to the 
distance specified by spacing.");
+
+       prop= RNA_def_property(srna, "smooth_stroke", PROP_BOOLEAN, PROP_NONE);
+       RNA_def_property_boolean_sdna(prop, NULL, "flag", BRUSH_SMOOTH_STROKE);
+       RNA_def_property_ui_text(prop, "Smooth Stroke", "Brush lags behind 
mouse and follows a smoother path.");
        
        /* not exposed in the interface yet
        prop= RNA_def_property(srna, "fixed_tex", PROP_BOOLEAN, PROP_NONE);


_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to