diff options
-rw-r--r-- | source/blender/blenkernel/intern/brush.c | 1 | ||||
-rw-r--r-- | source/blender/editors/sculpt/sculpt.c | 134 | ||||
-rw-r--r-- | source/blender/makesrna/intern/rna_brush.c | 13 |
3 files changed, 95 insertions, 53 deletions
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c index 5faca56e1d7..c1db7a009e6 100644 --- a/source/blender/blenkernel/intern/brush.c +++ b/source/blender/blenkernel/intern/brush.c @@ -70,6 +70,7 @@ Brush *add_brush(char *name) brush->rate= 0.1f; brush->innerradius= 0.5f; brush->clone.alpha= 0.5; + brush->sculpt_tool = SCULPT_TOOL_DRAW; /* enable fake user by default */ brush->id.flag |= LIB_FAKEUSER; diff --git a/source/blender/editors/sculpt/sculpt.c b/source/blender/editors/sculpt/sculpt.c index 0df181c9dff..acd9f085532 100644 --- a/source/blender/editors/sculpt/sculpt.c +++ b/source/blender/editors/sculpt/sculpt.c @@ -124,13 +124,25 @@ typedef struct BrushActionSymm { float grab_delta[3]; } BrushActionSymm; +typedef enum StrokeFlags { + CLIP_X = 1, + CLIP_Y = 2, + CLIP_Z = 4 +} StrokeFlags; + /* Cache stroke properties that don't change after the initialization at the start of a stroke. Used because - RNA property lookup isn't particularly fast. */ + RNA property lookup isn't particularly fast. + + For descriptions of these settings, check the operator properties. +*/ typedef struct StrokeCache { float radius; float scale[3]; float flip; + int flag; + float clip_tolerance[3]; + int mouse[2]; } StrokeCache; typedef struct BrushAction { @@ -142,16 +154,11 @@ typedef struct BrushAction { vec3f *mesh_store; short (*orig_norms)[3]; - short mouse[2]; - float prev_radius; float radius; float *layer_disps; - char clip[3]; - float cliptol[3]; - float anchored_rot; /* Grab brush */ @@ -371,28 +378,28 @@ float brush_strength(SculptData *sd, StrokeCache *cache, BrushAction *a) switch(sd->brush->sculpt_tool){ case SCULPT_TOOL_DRAW: case SCULPT_TOOL_LAYER: - return sd->brush->alpha / 5000.0f * dir * pressure * flip * anchored; /*XXX: not sure why? multiplied by G.vd->grid */; + return sd->brush->alpha / 50.0f * dir * pressure * flip * anchored; /*XXX: not sure why? multiplied by G.vd->grid */; case SCULPT_TOOL_SMOOTH: - return sd->brush->alpha / 50.0f * pressure * anchored; + return sd->brush->alpha / .5f * pressure * anchored; case SCULPT_TOOL_PINCH: - return sd->brush->alpha / 1000.0f * dir * pressure * flip * anchored; + return sd->brush->alpha / 10.0f * dir * pressure * flip * anchored; case SCULPT_TOOL_GRAB: return 1; case SCULPT_TOOL_INFLATE: - return sd->brush->alpha / 5000.0f * dir * pressure * flip * anchored; + return sd->brush->alpha / 50.0f * dir * pressure * flip * anchored; case SCULPT_TOOL_FLATTEN: - return sd->brush->alpha / 500.0f * pressure * anchored; + return sd->brush->alpha / 5.0f * pressure * anchored; default: return 0; } } /* For clipping against a mirror modifier */ -void sculpt_clip(const BrushAction *a, float *co, const float val[3]) +void sculpt_clip(StrokeCache *cache, float *co, const float val[3]) { char i; for(i=0; i<3; ++i) { - if(a->clip[i] && (fabs(co[i]) <= a->cliptol[i])) + if((cache->flag & (CLIP_X << i)) && (fabs(co[i]) <= cache->clip_tolerance[i])) co[i]= 0.0f; else co[i]= val[i]; @@ -482,7 +489,7 @@ void do_draw_brush(SculptData *sd, SculptSession *ss, const BrushAction *a, cons co[1]+area_normal[1]*node->Fade*ss->cache->scale[1], co[2]+area_normal[2]*node->Fade*ss->cache->scale[2]}; - sculpt_clip(a, co, val); + sculpt_clip(ss->cache, co, val); node= node->next; } @@ -546,7 +553,7 @@ void do_smooth_brush(SculptSession *ss, const BrushAction *a, const ListBase* ac const float val[3]= {co[0]+(avg.x-co[0])*node->Fade, co[1]+(avg.y-co[1])*node->Fade, co[2]+(avg.z-co[2])*node->Fade}; - sculpt_clip(a, co, val); + sculpt_clip(ss->cache, co, val); node= node->next; } } @@ -560,7 +567,7 @@ void do_pinch_brush(SculptSession *ss, const BrushAction *a, const ListBase* act const float val[3]= {co[0]+(a->symm.center_3d[0]-co[0])*node->Fade, co[1]+(a->symm.center_3d[1]-co[1])*node->Fade, co[2]+(a->symm.center_3d[2]-co[2])*node->Fade}; - sculpt_clip(a, co, val); + sculpt_clip(ss->cache, co, val); node= node->next; } } @@ -580,7 +587,7 @@ void do_grab_brush(SculptData *sd, SculptSession *ss, BrushAction *a) VecCopyf(add, grab_delta); VecMulf(add, node->Fade); VecAddf(add, add, co); - sculpt_clip(a, co, add); + sculpt_clip(ss->cache, co, add); node= node->next; } @@ -616,7 +623,7 @@ void do_layer_brush(SculptData *sd, SculptSession *ss, BrushAction *a, const Lis const float val[3]= {a->mesh_store[node->Index].x+area_normal[0] * *disp*ss->cache->scale[0], a->mesh_store[node->Index].y+area_normal[1] * *disp*ss->cache->scale[1], a->mesh_store[node->Index].z+area_normal[2] * *disp*ss->cache->scale[2]}; - sculpt_clip(a, co, val); + sculpt_clip(ss->cache, co, val); } } @@ -642,7 +649,7 @@ void do_inflate_brush(SculptSession *ss, const BrushAction *a, const ListBase *a add[2]*= ss->cache->scale[2]; VecAddf(add, add, co); - sculpt_clip(a, co, add); + sculpt_clip(ss->cache, co, add); node= node->next; } @@ -697,7 +704,7 @@ void do_flatten_brush(SculptData *sd, SculptSession *ss, const BrushAction *a, c VecMulf(val, node->Fade); VecAddf(val, val, co); - sculpt_clip(a, co, val); + sculpt_clip(ss->cache, co, val); node= node->next; } @@ -846,8 +853,8 @@ float tex_strength(SculptData *sd, BrushAction *a, float *point, const float len py %= sy-1; avg= get_texcache_pixel_bilinear(ss, TC_SIZE*px/sx, TC_SIZE*py/sy); } else { - float fx= (point_2d[0] - a->mouse[0]) / bsize; - float fy= (point_2d[1] - a->mouse[1]) / bsize; + float fx= (point_2d[0] - ss->cache->mouse[0]) / bsize; + float fy= (point_2d[1] - ss->cache->mouse[1]) / bsize; float angle= atan2(fy, fx) - rot; float flen= sqrtf(fx*fx + fy*fy); @@ -1195,8 +1202,8 @@ static void init_brushaction(SculptData *sd, BrushAction *a, short *mouse, short modelspace coords */ if(a->firsttime || !anchored) { unproject(ss, a->symm.center_3d, mouse[0], mouse[1], mouse_depth); - a->mouse[0] = mouse[0]; - a->mouse[1] = mouse[1]; + /*a->mouse[0] = mouse[0]; + a->mouse[1] = mouse[1];*/ } if(anchored) { @@ -1237,22 +1244,7 @@ static void init_brushaction(SculptData *sd, BrushAction *a, short *mouse, short Normalize(a->symm.right); Normalize(a->symm.out); - /* Initialize mirror modifier clipping */ - for(i=0; i<3; ++i) { - a->clip[i]= 0; - a->cliptol[i]= 0; - } - for(md= ob->modifiers.first; md; md= md->next) { - if(md->type==eModifierType_Mirror && (md->mode & eModifierMode_Realtime)) { - const MirrorModifierData *mmd = (MirrorModifierData*) md; - - if(mmd->flag & MOD_MIR_CLIPPING) { - a->clip[mmd->axis]= 1; - if(mmd->tolerance > a->cliptol[mmd->axis]) - a->cliptol[mmd->axis] = mmd->tolerance; - } - } - } + if(b->sculpt_tool == SCULPT_TOOL_GRAB) { float gcenter[3]; @@ -1644,10 +1636,16 @@ static int sculpt_load_mats(bContext *C, bglMats *mats) } /* Initialize the stroke cache invariants from operator properties */ -static int sculpt_update_cache_invariants(StrokeCache *cache, wmOperator *op) +static int sculpt_update_cache_invariants(StrokeCache *cache, wmOperator *op, Object *ob) { + + memset(cache, 0, sizeof(StrokeCache)); + cache->radius = RNA_float_get(op->ptr, "radius"); RNA_float_get_array(op->ptr, "scale", cache->scale); + cache->flag = RNA_int_get(op->ptr, "flag"); + RNA_float_get_array(op->ptr, "clip_tolerance", cache->clip_tolerance); + RNA_int_get_array(op->ptr, "mouse", cache->mouse); } /* Initialize the stroke cache variants from operator properties */ @@ -1661,10 +1659,12 @@ static int sculpt_brush_stroke_init(bContext *C, wmOperator *op, wmEvent *event, { SculptData *sd = &CTX_data_scene(C)->sculptdata; Object *ob= CTX_data_active_object(C); + ModifierData *md; float brush_center[3], brush_edge[3]; float depth = get_depth(C, event->x, event->y); float size = brush_size(sd, sd->brush); - float scale[3]; + float scale[3], clip_tolerance[3] = {0,0,0}; + int mouse[2], flag = 0; unproject(ss, brush_center, event->x, event->y, depth); unproject(ss, brush_edge, event->x + size, event->y, depth); @@ -1672,13 +1672,32 @@ static int sculpt_brush_stroke_init(bContext *C, wmOperator *op, wmEvent *event, RNA_float_set(op->ptr, "radius", VecLenf(brush_center, brush_edge)); /* Set scaling adjustment */ - scale[0] = 1.0f / ob->size[0]; scale[1] = 1.0f / ob->size[1]; scale[2] = 1.0f / ob->size[2]; RNA_float_set_array(op->ptr, "scale", scale); - sculpt_update_cache_invariants(ss->cache, op); + /* Initialize mirror modifier clipping */ + for(md= ob->modifiers.first; md; md= md->next) { + if(md->type==eModifierType_Mirror && (md->mode & eModifierMode_Realtime)) { + const MirrorModifierData *mmd = (MirrorModifierData*) md; + + /* Mark each axis that needs clipping along with its tolerance */ + if(mmd->flag & MOD_MIR_CLIPPING) { + flag |= CLIP_X << mmd->axis; + if(mmd->tolerance > clip_tolerance[mmd->axis]) + clip_tolerance[mmd->axis] = mmd->tolerance; + } + } + } + RNA_int_set(op->ptr, "flag", flag); + RNA_float_set_array(op->ptr, "clip_tolerance", clip_tolerance); + + mouse[0] = event->x; + mouse[1] = event->y; + RNA_int_set_array(op->ptr, "mouse", mouse); + + sculpt_update_cache_invariants(ss->cache, op, ob); } static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, wmEvent *event) @@ -1688,12 +1707,6 @@ static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, wmEvent *even Mesh *me = get_mesh(ob); ARegion *ar = CTX_wm_region(C); - // XXX: temporary, just add one brush here for testing - sd->brush = MEM_callocN(sizeof(Brush), "test sculpt brush"); - sd->brush->size = 25; - sd->brush->alpha = 50; - sd->brush->sculpt_tool = SCULPT_TOOL_DRAW; - // XXX: temporary, much of sculptsession data should be in rna properties sd->session = MEM_callocN(sizeof(SculptSession), "test sculpt session"); sd->session->mvert = me->mvert; @@ -1763,7 +1776,7 @@ static int sculpt_brush_stroke_exec(bContext *C, wmOperator *op) ARegion *ar = CTX_wm_region(C); SculptData *sd = &CTX_data_scene(C)->sculptdata; - sculpt_update_cache_invariants(sd->session->cache, op); + sculpt_update_cache_invariants(sd->session->cache, op, ob); RNA_BEGIN(op->ptr, itemptr, "stroke") { float loc[3]; @@ -1786,7 +1799,8 @@ static int sculpt_brush_stroke_exec(bContext *C, wmOperator *op) void SCULPT_OT_brush_stroke(wmOperatorType *ot) { PropertyRNA *prop; - float vecdefault[] = {0,0,0}; + float vec3f_def[] = {0,0,0}; + int vec2i_def[] = {0,0}; ot->flag |= OPTYPE_REGISTER; @@ -1811,7 +1825,18 @@ void SCULPT_OT_brush_stroke(wmOperatorType *ot) to work as expected. */ prop= RNA_def_property(ot->srna, "scale", PROP_FLOAT, PROP_VECTOR); RNA_def_property_array(prop, 3); - RNA_def_property_float_array_default(prop, vecdefault); + RNA_def_property_float_array_default(prop, vec3f_def); + + prop= RNA_def_property(ot->srna, "flag", PROP_INT, PROP_NONE); + + prop= RNA_def_property(ot->srna, "clip_tolerance", PROP_FLOAT, PROP_VECTOR); + RNA_def_property_array(prop, 3); + RNA_def_property_float_array_default(prop, vec3f_def); + + /* The initial 2D location of the mouse */ + prop= RNA_def_property(ot->srna, "mouse", PROP_INT, PROP_VECTOR); + RNA_def_property_array(prop, 2); + RNA_def_property_int_array_default(prop, vec2i_def); } /**** Toggle operator for turning sculpt mode on or off ****/ @@ -1826,6 +1851,9 @@ static int sculpt_toggle_mode(bContext *C, wmOperator *op) /* Enter sculptmode */ G.f |= G_SCULPTMODE; + + /* Needed for testing, if there's no brush then create one */ + CTX_data_scene(C)->sculptdata.brush = add_brush("test brush"); } return OPERATOR_FINISHED; diff --git a/source/blender/makesrna/intern/rna_brush.c b/source/blender/makesrna/intern/rna_brush.c index 35622c0a6da..6459cd8f5a1 100644 --- a/source/blender/makesrna/intern/rna_brush.c +++ b/source/blender/makesrna/intern/rna_brush.c @@ -62,6 +62,15 @@ void rna_def_brush(BlenderRNA *brna) {BRUSH_BLEND_ERASE_ALPHA, "ERASE_ALPHA", "Erase Alpha", "Erase alpha while painting."}, {BRUSH_BLEND_ADD_ALPHA, "ADD_ALPHA", "Add Alpha", "Add alpha while painting."}, {0, NULL, NULL, NULL}}; + static EnumPropertyItem prop_sculpt_tool_items[] = { + {SCULPT_TOOL_DRAW, "DRAW", "Draw", ""}, + {SCULPT_TOOL_SMOOTH, "SMOOTH", "Smooth", ""}, + {SCULPT_TOOL_PINCH, "PINCH", "Pinch", ""}, + {SCULPT_TOOL_INFLATE, "INFLATE", "Inflate", ""}, + {SCULPT_TOOL_GRAB, "GRAB", "Grab", ""}, + {SCULPT_TOOL_LAYER, "LAYER", "Layer", ""}, + {SCULPT_TOOL_FLATTEN, "FLATTEN", "Flatten", ""}, + {0, NULL, NULL, NULL}}; srna= RNA_def_struct(brna, "Brush", "ID"); RNA_def_struct_ui_text(srna, "Brush", "Brush datablock for storing brush settings for painting and sculpting."); @@ -70,6 +79,10 @@ void rna_def_brush(BlenderRNA *brna) prop= RNA_def_property(srna, "blend", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, prop_blend_items); RNA_def_property_ui_text(prop, "Blending mode", "Brush blending mode."); + + prop= RNA_def_property(srna, "sculpt_tool", PROP_ENUM, PROP_NONE); + RNA_def_property_enum_items(prop, prop_sculpt_tool_items); + RNA_def_property_ui_text(prop, "Sculpt Tool", ""); /* number values */ prop= RNA_def_property(srna, "size", PROP_INT, PROP_NONE); |