Did some refactoring with brush and sculpt to make radial control easier to add to...
authorNicholas Bishop <nicholasbishop@gmail.com>
Sun, 25 Jan 2009 07:28:11 +0000 (07:28 +0000)
committerNicholas Bishop <nicholasbishop@gmail.com>
Sun, 25 Jan 2009 07:28:11 +0000 (07:28 +0000)
source/blender/blenkernel/BKE_brush.h
source/blender/blenkernel/intern/brush.c
source/blender/editors/sculpt/sculpt.c
source/blender/makesdna/DNA_windowmanager_types.h
source/blender/windowmanager/WM_types.h

index 07ca975c46fecefb142c257b1486be506abee8b2..eba7558d4920dfdf491afc5e2e83c61dfcc44771 100644 (file)
@@ -34,6 +34,7 @@
 struct ID;
 struct Brush;
 struct ImBuf;
+struct wmOperator;
 
 /* datablock functions */
 struct Brush *add_brush(char *name);
@@ -58,6 +59,7 @@ typedef enum {
        BRUSH_PRESET_MAX
 } BrushCurvePreset;
 void brush_curve_preset(struct Brush *b, BrushCurvePreset preset);
+float brush_curve_strength(struct Brush *br, float p, const float len);
 
 /* sampling */
 float brush_sample_falloff(struct Brush *brush, float dist);
@@ -79,5 +81,12 @@ int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos,
 void brush_painter_break_stroke(BrushPainter *painter);
 void brush_painter_free(BrushPainter *painter);
 
+/* texture */
+unsigned int *brush_gen_texture_cache(struct Brush *br, int half_side);
+
+/* radial control */
+void brush_radial_control_invoke(struct wmOperator *op, struct Brush *br);
+int brush_radial_control_exec(struct wmOperator *op, struct Brush *br);
+
 #endif
 
index cd5eb2eb3d30017d82f19c5f7d582d51a8215fd4..804b14b66b168ceb9280318d0847dc6b08b5e0c0 100644 (file)
@@ -28,6 +28,7 @@
  */
 
 #include <math.h>
+#include <string.h>
 
 #include "MEM_guardedalloc.h"
 
@@ -36,6 +37,9 @@
 #include "DNA_image_types.h"
 #include "DNA_texture_types.h"
 #include "DNA_scene_types.h"
+#include "DNA_windowmanager_types.h"
+
+#include "RNA_access.h"
 
 #include "BLI_arithb.h"
 #include "BLI_blenlib.h"
@@ -43,6 +47,7 @@
 #include "BKE_brush.h"
 #include "BKE_colortools.h"
 #include "BKE_global.h"
+#include "BKE_image.h"
 #include "BKE_library.h"
 #include "BKE_main.h"
 #include "BKE_texture.h"
@@ -52,6 +57,7 @@
 #include "IMB_imbuf_types.h"
 
 #include "RE_render_ext.h" /* externtex */
+#include "RE_shader_ext.h"
 
 /* Datablock add/copy/free/make_local */
 
@@ -935,4 +941,123 @@ int brush_painter_paint(BrushPainter *painter, BrushFunc func, float *pos, doubl
        return totpaintops;
 }
 
+/* Uses the brush curve control to find a strength value between 0 and 1 */
+float brush_curve_strength(Brush *br, float p, const float len)
+{
+       if(p > len) p= len;
+       return curvemapping_evaluateF(br->curve, 0, p/len);
+}
+
+/* TODO: should probably be unified with BrushPainter stuff? */
+unsigned int *brush_gen_texture_cache(Brush *br, int half_side)
+{
+       unsigned int *texcache = NULL;
+       MTex *mtex = br->mtex[br->texact];
+       TexResult texres;
+       int hasrgb, ix, iy;
+       int side = half_side * 2;
+
+       memset(&texres, 0, sizeof(TexResult));
+       
+       if(mtex && mtex->tex) {
+               float x, y, step = 2.0 / side, co[3];
+
+               texcache = MEM_callocN(sizeof(int) * side * side, "Brush texture cache");
+
+               BKE_image_get_ibuf(mtex->tex->ima, NULL);
+               
+               /*do normalized cannonical view coords for texture*/
+               for (y=-1.0, iy=0; iy<side; iy++, y += step) {
+                       for (x=-1.0, ix=0; ix<side; ix++, x += step) {
+                               co[0]= x;
+                               co[1]= y;
+                               co[2]= 0.0f;
+                               
+                               /* This is copied from displace modifier code */
+                               hasrgb = multitex_ext(mtex->tex, co, NULL, NULL, 1, &texres);
+                       
+                               /* if the texture gave an RGB value, we assume it didn't give a valid
+                                * intensity, so calculate one (formula from do_material_tex).
+                                * if the texture didn't give an RGB value, copy the intensity across
+                                */
+                               if(hasrgb & TEX_RGB)
+                                       texres.tin = (0.35 * texres.tr + 0.45 *
+                                                     texres.tg + 0.2 * texres.tb);
+
+                               texres.tin = texres.tin * 255.0;
+                               ((char*)texcache)[(iy*side+ix)*4] = (char)texres.tin;
+                               ((char*)texcache)[(iy*side+ix)*4+1] = (char)texres.tin;
+                               ((char*)texcache)[(iy*side+ix)*4+2] = (char)texres.tin;
+                               ((char*)texcache)[(iy*side+ix)*4+3] = (char)texres.tin;
+                       }
+               }
+       }
+
+       return texcache;
+}
+
+/**** Radial Control ****/
+static struct ImBuf *brush_gen_radial_control_imbuf(Brush *br)
+{
+       ImBuf *im = MEM_callocN(sizeof(ImBuf), "radial control texture");
+       unsigned int *texcache;
+       int side = 128;
+       int half = side / 2;
+       int i, j;
+
+       texcache = brush_gen_texture_cache(br, half);
+       im->rect_float = MEM_callocN(sizeof(float) * side * side, "radial control rect");
+       im->x = im->y = side;
+
+       for(i=0; i<side; ++i) {
+               for(j=0; j<side; ++j) {
+                       float magn= sqrt(pow(i - half, 2) + pow(j - half, 2));
+                       im->rect_float[i*side + j]= brush_curve_strength(br, magn, half);
+               }
+       }
+
+       /* Modulate curve with texture */
+       if(texcache) {
+               for(i=0; i<side; ++i)
+                       for(j=0; j<side; ++j) {
+                               const int col= texcache[i*side+j];
+                               im->rect_float[i*side+j]*= (((char*)&col)[0]+((char*)&col)[1]+((char*)&col)[2])/3.0f/255.0f;
+                       }
+       }
+
+       MEM_freeN(texcache);
 
+       return im;
+}
+
+void brush_radial_control_invoke(wmOperator *op, Brush *br)
+{
+       int mode = RNA_int_get(op->ptr, "mode");
+       float original_value;
+
+       if(mode == WM_RADIALCONTROL_SIZE)
+               original_value = br->size;
+       else if(mode == WM_RADIALCONTROL_STRENGTH)
+               original_value = br->alpha;
+       else if(mode == WM_RADIALCONTROL_ANGLE)
+               original_value = br->rot;
+
+       RNA_float_set(op->ptr, "initial_value", original_value);
+       op->customdata = brush_gen_radial_control_imbuf(br);
+}
+
+int brush_radial_control_exec(wmOperator *op, Brush *br)
+{
+       int mode = RNA_int_get(op->ptr, "mode");
+       float new_value = RNA_float_get(op->ptr, "new_value");
+       const float conv = 0.017453293;
+
+       if(mode == WM_RADIALCONTROL_SIZE)
+               br->size = new_value;
+       else if(mode == WM_RADIALCONTROL_STRENGTH)
+               br->alpha = new_value;
+       else if(mode == WM_RADIALCONTROL_ANGLE)
+               br->rot = new_value * conv;
+
+       return OPERATOR_FINISHED;
+}
index a3cbc9549171a0599c966dd276823413261c68a1..6016025e041ee418dd1fe3e377ca6d2f7ef32083 100644 (file)
@@ -585,12 +585,6 @@ static void do_flatten_brush(Sculpt *sd, SculptSession *ss, const ListBase *acti
        }
 }
 
-/* Uses the brush curve control to find a strength value between 0 and 1 */
-static float curve_strength(CurveMapping *cumap, float p, const float len)
-{
-       if(p > len) p= len;
-       return curvemapping_evaluateF(cumap, 0, p/len);
-}
 
 /* Uses symm to selectively flip any axis of a coordinate. */
 static void flip_coord(float out[3], float in[3], const char symm)
@@ -724,7 +718,7 @@ static float tex_strength(Sculpt *sd, float *point, const float len)
                }
        }
 
-       avg*= curve_strength(sd->brush->curve, len, ss->cache->radius); /* Falloff curve */
+       avg*= brush_curve_strength(sd->brush, len, ss->cache->radius); /* Falloff curve */
 
        return avg;
 }
@@ -990,18 +984,9 @@ static void projverts_clear_inside(SculptSession *ss)
                ss->projverts[i].inside = 0;
 }
 
-static void sculpt_update_tex(Sculpt *sd, int half_size)
+static void sculpt_update_tex(Sculpt *sd)
 {
        SculptSession *ss= sd->session;
-       Brush *br = sd->brush;
-       MTex *mtex = br->mtex[br->texact];
-       TexResult texres;
-       int hasrgb, ix, iy;
-
-       memset(&texres, 0, sizeof(TexResult));
-       
-       /* Skip Default brush shape and non-textures */
-       if(br->texact == -1 || !br->mtex[br->texact]) return;
 
        if(ss->texcache) {
                MEM_freeN(ss->texcache);
@@ -1009,43 +994,11 @@ static void sculpt_update_tex(Sculpt *sd, int half_size)
        }
 
        /* Need to allocate a bigger buffer for bigger brush size */
-       ss->texcache_side = half_size * 2;
+       ss->texcache_side = sd->brush->size * 2;
        if(!ss->texcache || ss->texcache_side > ss->texcache_actual) {
-               ss->texcache = MEM_callocN(sizeof(int) * ss->texcache_side * ss->texcache_side, "Sculpt Texture cache");
+               ss->texcache = brush_gen_texture_cache(sd->brush, sd->brush->size);
                ss->texcache_actual = ss->texcache_side;
        }
-
-       if(mtex && mtex->tex) {
-               float x, y, step = 2.0 / ss->texcache_side, co[3];
-
-               BKE_image_get_ibuf(br->mtex[br->texact]->tex->ima, NULL);
-               
-               /*do normalized cannonical view coords for texture*/
-               for (y=-1.0, iy=0; iy<ss->texcache_side; iy++, y += step) {
-                       for (x=-1.0, ix=0; ix<ss->texcache_side; ix++, x += step) {
-                               co[0]= x;
-                               co[1]= y;
-                               co[2]= 0.0f;
-                               
-                               /* This is copied from displace modifier code */
-                               hasrgb = multitex_ext(mtex->tex, co, NULL, NULL, 1, &texres);
-                       
-                               /* if the texture gave an RGB value, we assume it didn't give a valid
-                                * intensity, so calculate one (formula from do_material_tex).
-                                * if the texture didn't give an RGB value, copy the intensity across
-                                */
-                               if(hasrgb & TEX_RGB)
-                                       texres.tin = (0.35 * texres.tr + 0.45 *
-                                                     texres.tg + 0.2 * texres.tb);
-
-                               texres.tin = texres.tin * 255.0;
-                               ((char*)ss->texcache)[(iy*ss->texcache_side+ix)*4] = (char)texres.tin;
-                               ((char*)ss->texcache)[(iy*ss->texcache_side+ix)*4+1] = (char)texres.tin;
-                               ((char*)ss->texcache)[(iy*ss->texcache_side+ix)*4+2] = (char)texres.tin;
-                               ((char*)ss->texcache)[(iy*ss->texcache_side+ix)*4+3] = (char)texres.tin;
-                       }
-               }
-       }
 }
 
 void sculptmode_selectbrush_menu(void)
@@ -1284,57 +1237,11 @@ static void sculpt_undo_push(bContext *C, Sculpt *sd)
        }
 }
 
-static ImBuf *sculpt_radial_control_texture(bContext *C)
-{
-       Sculpt *s = CTX_data_scene(C)->toolsettings->sculpt;
-       ImBuf *im = MEM_callocN(sizeof(ImBuf), "radial control texture");
-       unsigned int *texcache;
-       int side = 256;
-       int half = side / 2;
-       int i, j;
-
-       sculpt_update_tex(s, half);
-       texcache = s->session->texcache;
-       im->rect_float = MEM_callocN(sizeof(float) * side * side, "radial control rect");
-       im->x = im->y = side;
-
-       for(i=0; i<side; ++i) {
-               for(j=0; j<side; ++j) {
-                       float magn= sqrt(pow(i - half, 2) + pow(j - half, 2));
-                       im->rect_float[i*side + j]= curve_strength(s->brush->curve, magn, half);
-               }
-       }
-
-       /* Modulate curve with texture */
-       if(texcache) {
-               for(i=0; i<side; ++i)
-                       for(j=0; j<side; ++j) {
-                               const int col= texcache[i*side+j];
-                               im->rect_float[i*side+j]*= (((char*)&col)[0]+((char*)&col)[1]+((char*)&col)[2])/3.0f/255.0f;
-                       }
-       }
-
-       return im;
-}
-
+/**** Radial control ****/
 static int sculpt_radial_control_invoke(bContext *C, wmOperator *op, wmEvent *event)
 {
-       Brush *br = CTX_data_scene(C)->toolsettings->sculpt->brush;
-       int mode = RNA_int_get(op->ptr, "mode");
-       float original_value;
-
-       if(mode == WM_RADIALCONTROL_SIZE)
-               original_value = br->size;
-       else if(mode == WM_RADIALCONTROL_STRENGTH)
-               original_value = br->alpha;
-       else if(mode == WM_RADIALCONTROL_ANGLE)
-               original_value = br->rot;
-
        toggle_paint_cursor(C);
-
-       RNA_float_set(op->ptr, "initial_value", original_value);
-       op->customdata = sculpt_radial_control_texture(C);
-
+       brush_radial_control_invoke(op, CTX_data_scene(C)->toolsettings->sculpt->brush);
        return WM_radial_control_invoke(C, op, event);
 }
 
@@ -1348,22 +1255,9 @@ static int sculpt_radial_control_modal(bContext *C, wmOperator *op, wmEvent *eve
 
 static int sculpt_radial_control_exec(bContext *C, wmOperator *op)
 {
-       Brush *br = CTX_data_scene(C)->toolsettings->sculpt->brush;
-       int mode = RNA_int_get(op->ptr, "mode");
-       float new_value = RNA_float_get(op->ptr, "new_value");
-       const float conv = 0.017453293;
-
-       if(mode == WM_RADIALCONTROL_SIZE)
-               br->size = new_value;
-       else if(mode == WM_RADIALCONTROL_STRENGTH)
-               br->alpha = new_value;
-       else if(mode == WM_RADIALCONTROL_ANGLE)
-               br->rot = new_value * conv;
-
-       return OPERATOR_FINISHED;
+       return brush_radial_control_exec(op, CTX_data_scene(C)->toolsettings->sculpt->brush);
 }
 
-/**** Radial control ****/
 static void SCULPT_OT_radial_control(wmOperatorType *ot)
 {
        WM_OT_radial_control_partial(ot);
@@ -1577,7 +1471,7 @@ static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, wmEvent *even
        /* TODO: Shouldn't really have to do this at the start of every
           stroke, but sculpt would need some sort of notification when
           changes are made to the texture. */
-       sculpt_update_tex(sd, sd->brush->size);
+       sculpt_update_tex(sd);
 
        /* add modal handler */
        WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
@@ -1658,7 +1552,7 @@ static int sculpt_brush_stroke_exec(bContext *C, wmOperator *op)
        view3d_operator_needs_opengl(C);
        sculpt_update_cache_invariants(sd, C, op);
        sculptmode_update_all_projverts(sd->session);
-       sculpt_update_tex(sd, sd->brush->size);
+       sculpt_update_tex(sd);
 
        RNA_BEGIN(op->ptr, itemptr, "stroke") {
                sculpt_update_cache_variants(sd, &itemptr);
index c974fb92978648bbbb14ce085c0ab71db5e0dd8b..b4bf6db542f4593b55f826ba937662abea64a576 100644 (file)
@@ -205,5 +205,11 @@ typedef struct wmOperator {
 /* add this flag if the event should pass through */
 #define OPERATOR_PASS_THROUGH  8
 
+typedef enum wmRadialControlMode {
+       WM_RADIALCONTROL_SIZE,
+       WM_RADIALCONTROL_STRENGTH,
+       WM_RADIALCONTROL_ANGLE
+} wmRadialControlMode;
+
 #endif /* DNA_WINDOWMANAGER_TYPES_H */
 
index 1473bfcf1159ceda66ea86974723538369b36d49..f0747e6dad0c7a73695cd66621c2664f2cb0df74 100644 (file)
@@ -229,13 +229,6 @@ typedef struct wmGesture {
        /* customdata for lasso is short array */
 } wmGesture;
 
-/* **************** Radial control *******************/
-typedef enum wmRadialControlMode {
-       WM_RADIALCONTROL_SIZE,
-       WM_RADIALCONTROL_STRENGTH,
-       WM_RADIALCONTROL_ANGLE
-} wmRadialControlMode;
-
 /* ************** custom wmEvent data ************** */
 
 #define DEV_STYLUS     1