Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/sculpt_paint/sculpt.c')
-rw-r--r--source/blender/editors/sculpt_paint/sculpt.c414
1 files changed, 207 insertions, 207 deletions
diff --git a/source/blender/editors/sculpt_paint/sculpt.c b/source/blender/editors/sculpt_paint/sculpt.c
index 90d2eb31355..2a4c553a94c 100644
--- a/source/blender/editors/sculpt_paint/sculpt.c
+++ b/source/blender/editors/sculpt_paint/sculpt.c
@@ -64,6 +64,7 @@
#include "BKE_mesh.h"
#include "BKE_modifier.h"
#include "BKE_multires.h"
+#include "BKE_paint.h"
#include "BKE_sculpt.h"
#include "BKE_texture.h"
#include "BKE_utildefines.h"
@@ -217,12 +218,13 @@ static void project(bglMats *mats, const float v[3], short p[2])
shrink the brush. Skipped for grab brush because only the first mouse down
size is used, which is small if the user has just touched the pen to the
tablet */
-static char brush_size(Sculpt *sd)
+static char brush_size(Sculpt *sd, SculptSession *ss)
{
- float size= sd->brush->size;
+ Brush *brush = paint_brush(&sd->paint);
+ float size= brush->size;
- if((sd->brush->sculpt_tool != SCULPT_TOOL_GRAB) && (sd->brush->flag & BRUSH_SIZE_PRESSURE))
- size *= sd->session->cache->pressure;
+ if((brush->sculpt_tool != SCULPT_TOOL_GRAB) && (brush->flag & BRUSH_SIZE_PRESSURE))
+ size *= ss->cache->pressure;
return size;
}
@@ -232,17 +234,18 @@ static char brush_size(Sculpt *sd)
special multiplier found experimentally to scale the strength factor. */
static float brush_strength(Sculpt *sd, StrokeCache *cache)
{
+ Brush *brush = paint_brush(&sd->paint);
/* Primary strength input; square it to make lower values more sensitive */
- float alpha = sd->brush->alpha * sd->brush->alpha;
+ float alpha = brush->alpha * brush->alpha;
- float dir= sd->brush->flag & BRUSH_DIR_IN ? -1 : 1;
+ float dir= brush->flag & BRUSH_DIR_IN ? -1 : 1;
float pressure= 1;
float flip= cache->flip ? -1:1;
- if(sd->brush->flag & BRUSH_ALPHA_PRESSURE)
+ if(brush->flag & BRUSH_ALPHA_PRESSURE)
pressure *= cache->pressure;
- switch(sd->brush->sculpt_tool){
+ switch(brush->sculpt_tool){
case SCULPT_TOOL_DRAW:
case SCULPT_TOOL_INFLATE:
case SCULPT_TOOL_CLAY:
@@ -261,7 +264,7 @@ static float brush_strength(Sculpt *sd, StrokeCache *cache)
}
/* Handles clipping against a mirror modifier and SCULPT_LOCK axis flags */
-static void sculpt_clip(Sculpt *sd, float *co, const float val[3])
+static void sculpt_clip(Sculpt *sd, SculptSession *ss, float *co, const float val[3])
{
int i;
@@ -269,7 +272,7 @@ static void sculpt_clip(Sculpt *sd, float *co, const float val[3])
if(sd->flags & (SCULPT_LOCK_X << i))
continue;
- if((sd->session->cache->flag & (CLIP_X << i)) && (fabs(co[i]) <= sd->session->cache->clip_tolerance[i]))
+ if((ss->cache->flag & (CLIP_X << i)) && (fabs(co[i]) <= ss->cache->clip_tolerance[i]))
co[i]= 0.0f;
else
co[i]= val[i];
@@ -291,23 +294,24 @@ static void add_norm_if(float view_vec[3], float out[3], float out_flip[3], cons
/* Currently only for the draw brush; finds average normal for all active
vertices */
-static void calc_area_normal(Sculpt *sd, float out[3], const ListBase* active_verts)
+static void calc_area_normal(Sculpt *sd, SculptSession *ss, float out[3], const ListBase* active_verts)
{
- StrokeCache *cache = sd->session->cache;
+ Brush *brush = paint_brush(&sd->paint);
+ StrokeCache *cache = ss->cache;
ActiveData *node = active_verts->first;
- const int view = 0; /* XXX: should probably be a flag, not number: sd->brush_type==SCULPT_TOOL_DRAW ? sculptmode_brush()->view : 0; */
+ const int view = 0; /* XXX: should probably be a flag, not number: brush_type==SCULPT_TOOL_DRAW ? sculptmode_brush()->view : 0; */
float out_flip[3];
float *out_dir = cache->view_normal_symmetry;
out[0]=out[1]=out[2] = out_flip[0]=out_flip[1]=out_flip[2] = 0;
- if(sd->brush->flag & BRUSH_ANCHORED) {
+ if(brush->flag & BRUSH_ANCHORED) {
for(; node; node = node->next)
add_norm_if(out_dir, out, out_flip, cache->orig_norms[node->Index]);
}
else {
for(; node; node = node->next)
- add_norm_if(out_dir, out, out_flip, sd->session->mvert[node->Index].no);
+ add_norm_if(out_dir, out, out_flip, ss->mvert[node->Index].no);
}
if (out[0]==0.0 && out[1]==0.0 && out[2]==0.0) {
@@ -330,7 +334,7 @@ static void do_draw_brush(Sculpt *sd, SculptSession *ss, const ListBase* active_
float area_normal[3];
ActiveData *node= active_verts->first;
- calc_area_normal(sd, area_normal, active_verts);
+ calc_area_normal(sd, ss, area_normal, active_verts);
while(node){
float *co= ss->mvert[node->Index].co;
@@ -339,7 +343,7 @@ static void do_draw_brush(Sculpt *sd, SculptSession *ss, const ListBase* active_
co[1]+area_normal[1]*ss->cache->radius*node->Fade*ss->cache->scale[1],
co[2]+area_normal[2]*ss->cache->radius*node->Fade*ss->cache->scale[2]};
- sculpt_clip(sd, co, val);
+ sculpt_clip(sd, ss, co, val);
node= node->next;
}
@@ -389,37 +393,37 @@ static void neighbor_average(SculptSession *ss, float avg[3], const int vert)
VecCopyf(avg, ss->mvert[vert].co);
}
-static void do_smooth_brush(Sculpt *s, const ListBase* active_verts)
+static void do_smooth_brush(Sculpt *s, SculptSession *ss, const ListBase* active_verts)
{
ActiveData *node= active_verts->first;
int i;
for(i = 0; i < 2; ++i) {
while(node){
- float *co= s->session->mvert[node->Index].co;
+ float *co= ss->mvert[node->Index].co;
float avg[3], val[3];
- neighbor_average(s->session, avg, node->Index);
+ neighbor_average(ss, avg, node->Index);
val[0] = co[0]+(avg[0]-co[0])*node->Fade;
val[1] = co[1]+(avg[1]-co[1])*node->Fade;
val[2] = co[2]+(avg[2]-co[2])*node->Fade;
- sculpt_clip(s, co, val);
+ sculpt_clip(s, ss, co, val);
node= node->next;
}
}
}
-static void do_pinch_brush(Sculpt *s, const ListBase* active_verts)
+static void do_pinch_brush(Sculpt *s, SculptSession *ss, const ListBase* active_verts)
{
ActiveData *node= active_verts->first;
while(node) {
- float *co= s->session->mvert[node->Index].co;
- const float val[3]= {co[0]+(s->session->cache->location[0]-co[0])*node->Fade,
- co[1]+(s->session->cache->location[1]-co[1])*node->Fade,
- co[2]+(s->session->cache->location[2]-co[2])*node->Fade};
- sculpt_clip(s, co, val);
+ float *co= ss->mvert[node->Index].co;
+ const float val[3]= {co[0]+(ss->cache->location[0]-co[0])*node->Fade,
+ co[1]+(ss->cache->location[1]-co[1])*node->Fade,
+ co[2]+(ss->cache->location[2]-co[2])*node->Fade};
+ sculpt_clip(s, ss, co, val);
node= node->next;
}
}
@@ -438,7 +442,7 @@ static void do_grab_brush(Sculpt *sd, SculptSession *ss)
VecCopyf(add, grab_delta);
VecMulf(add, node->Fade);
VecAddf(add, add, co);
- sculpt_clip(sd, co, add);
+ sculpt_clip(sd, ss, co, add);
node= node->next;
}
@@ -454,7 +458,7 @@ static void do_layer_brush(Sculpt *sd, SculptSession *ss, const ListBase *active
if(ss->cache->flip)
lim = -lim;
- calc_area_normal(sd, area_normal, active_verts);
+ calc_area_normal(sd, ss, area_normal, active_verts);
while(node){
float *disp= &ss->layer_disps[node->Index];
@@ -471,16 +475,15 @@ static void do_layer_brush(Sculpt *sd, SculptSession *ss, const ListBase *active
val[1] = ss->mesh_co_orig[node->Index][1]+area_normal[1] * *disp*ss->cache->scale[1];
val[2] = ss->mesh_co_orig[node->Index][2]+area_normal[2] * *disp*ss->cache->scale[2];
- sculpt_clip(sd, co, val);
+ sculpt_clip(sd, ss, co, val);
node= node->next;
}
}
-static void do_inflate_brush(Sculpt *s, const ListBase *active_verts)
+static void do_inflate_brush(Sculpt *s, SculptSession *ss, const ListBase *active_verts)
{
ActiveData *node= active_verts->first;
- SculptSession *ss = s->session;
float add[3];
while(node) {
@@ -496,7 +499,7 @@ static void do_inflate_brush(Sculpt *s, const ListBase *active_verts)
add[2]*= ss->cache->scale[2];
VecAddf(add, add, co);
- sculpt_clip(s, co, add);
+ sculpt_clip(s, ss, co, add);
node= node->next;
}
@@ -546,7 +549,7 @@ static void do_flatten_clay_brush(Sculpt *sd, SculptSession *ss, const ListBase
float area_normal[3];
float cntr[3], cntr2[3], bstr;
- calc_area_normal(sd, area_normal, active_verts);
+ calc_area_normal(sd, ss, area_normal, active_verts);
calc_flatten_center(ss, node, cntr);
if(clay) {
@@ -589,7 +592,7 @@ static void do_flatten_clay_brush(Sculpt *sd, SculptSession *ss, const ListBase
VecMulf(val, fabs(node->Fade));
VecAddf(val, val, co);
- sculpt_clip(sd, co, val);
+ sculpt_clip(sd, ss, co, val);
}
node= node->next;
@@ -651,35 +654,29 @@ static float get_texcache_pixel_bilinear(const SculptSession *ss, float u, float
}
/* Return a multiplier for brush strength on a particular vertex. */
-static float tex_strength(Sculpt *sd, float *point, const float len)
+static float tex_strength(Sculpt *sd, SculptSession *ss, float *point, const float len)
{
- SculptSession *ss= sd->session;
- Brush *br = sd->brush;
+ Brush *br = paint_brush(&sd->paint);
+ MTex *tex = NULL;
float avg= 1;
- if(br->texact==-1 || !br->mtex[br->texact])
+ if(br->texact >= 0)
+ tex = br->mtex[br->texact];
+
+ if(!tex) {
avg= 1;
- else if(br->tex_mode==BRUSH_TEX_3D) {
- /* Get strength by feeding the vertex location directly
- into a texture */
+ }
+ else if(tex->brush_map_mode == MTEX_MAP_MODE_3D) {
float jnk;
- const float factor= 0.01;
- MTex mtex;
- memset(&mtex,0,sizeof(MTex));
- mtex.tex= br->mtex[br->texact]->tex;
- mtex.projx= 1;
- mtex.projy= 2;
- mtex.projz= 3;
- VecCopyf(mtex.size, br->mtex[br->texact]->size);
- VecMulf(mtex.size, factor);
- if(!sd->texsep)
- mtex.size[1]= mtex.size[2]= mtex.size[0];
-
- externtex(&mtex,point,&avg,&jnk,&jnk,&jnk,&jnk);
+
+ /* Get strength by feeding the vertex
+ location directly into a texture */
+ externtex(tex, point, &avg,
+ &jnk, &jnk, &jnk, &jnk);
}
else if(ss->texcache) {
const float bsize= ss->cache->pixel_radius * 2;
- const float rot= sd->brush->rot + ss->cache->rotation;
+ const float rot= tex->rot + ss->cache->rotation;
int px, py;
float flip[3], point_2d[2];
@@ -692,9 +689,9 @@ static float tex_strength(Sculpt *sd, float *point, const float len)
/* For Tile and Drag modes, get the 2D screen coordinates of the
and scale them up or down to the texture size. */
- if(br->tex_mode==BRUSH_TEX_TILE) {
- const int sx= (const int)br->mtex[br->texact]->size[0];
- const int sy= (const int)sd->texsep ? br->mtex[br->texact]->size[1] : sx;
+ if(tex->brush_map_mode == MTEX_MAP_MODE_TILED) {
+ const int sx= (const int)tex->size[0];
+ const int sy= (const int)tex->size[1];
float fx= point_2d[0];
float fy= point_2d[1];
@@ -714,7 +711,8 @@ static float tex_strength(Sculpt *sd, float *point, const float len)
if(sy != 1)
py %= sy-1;
avg= get_texcache_pixel_bilinear(ss, ss->texcache_side*px/sx, ss->texcache_side*py/sy);
- } else {
+ }
+ else if(tex->brush_map_mode == MTEX_MAP_MODE_FIXED) {
float fx= (point_2d[0] - ss->cache->mouse[0]) / bsize;
float fy= (point_2d[1] - ss->cache->mouse[1]) / bsize;
@@ -728,7 +726,7 @@ static float tex_strength(Sculpt *sd, float *point, const float len)
}
}
- avg*= brush_curve_strength(sd->brush, len, ss->cache->radius); /* Falloff curve */
+ avg*= brush_curve_strength(br, len, ss->cache->radius); /* Falloff curve */
return avg;
}
@@ -766,9 +764,9 @@ static void sculpt_add_damaged_rect(SculptSession *ss)
}
}
-static void do_brush_action(Sculpt *sd, StrokeCache *cache)
+static void do_brush_action(Sculpt *sd, SculptSession *ss, StrokeCache *cache)
{
- SculptSession *ss = sd->session;
+ Brush *brush = paint_brush(&sd->paint);
float av_dist;
ListBase active_verts={0,0};
ListBase *grab_active_verts = &ss->cache->grab_active_verts[ss->cache->symmetry];
@@ -777,7 +775,7 @@ static void do_brush_action(Sculpt *sd, StrokeCache *cache)
Mesh *me= NULL; /*XXX: get_mesh(OBACT); */
const float bstrength= brush_strength(sd, cache);
KeyBlock *keyblock= NULL; /*XXX: ob_get_keyblock(OBACT); */
- Brush *b = sd->brush;
+ Brush *b = brush;
int i;
sculpt_add_damaged_rect(ss);
@@ -797,7 +795,7 @@ static void do_brush_action(Sculpt *sd, StrokeCache *cache)
adata->Index = i;
/* Fade is used to store the final strength at which the brush
should modify a particular vertex. */
- adata->Fade= tex_strength(sd, vert, av_dist) * bstrength;
+ adata->Fade= tex_strength(sd, ss, vert, av_dist) * bstrength;
adata->dist = av_dist;
if(b->sculpt_tool == SCULPT_TOOL_GRAB && cache->first_time)
@@ -817,13 +815,13 @@ static void do_brush_action(Sculpt *sd, StrokeCache *cache)
do_draw_brush(sd, ss, &active_verts);
break;
case SCULPT_TOOL_SMOOTH:
- do_smooth_brush(sd, &active_verts);
+ do_smooth_brush(sd, ss, &active_verts);
break;
case SCULPT_TOOL_PINCH:
- do_pinch_brush(sd, &active_verts);
+ do_pinch_brush(sd, ss, &active_verts);
break;
case SCULPT_TOOL_INFLATE:
- do_inflate_brush(sd, &active_verts);
+ do_inflate_brush(sd, ss, &active_verts);
break;
case SCULPT_TOOL_GRAB:
do_grab_brush(sd, ss);
@@ -872,20 +870,21 @@ static void calc_brushdata_symm(StrokeCache *cache, const char symm)
cache->symmetry= symm;
}
-static void do_symmetrical_brush_actions(Sculpt *sd, StrokeCache *cache)
+static void do_symmetrical_brush_actions(Sculpt *sd, SculptSession *ss)
{
+ StrokeCache *cache = ss->cache;
const char symm = sd->flags & 7;
int i;
VecCopyf(cache->location, cache->true_location);
VecCopyf(cache->grab_delta_symmetry, cache->grab_delta);
cache->symmetry = 0;
- do_brush_action(sd, cache);
+ do_brush_action(sd, ss, cache);
for(i = 1; i <= symm; ++i) {
if(symm & i && (symm != 5 || i != 3) && (symm != 6 || (i != 3 && i != 5))) {
calc_brushdata_symm(cache, i);
- do_brush_action(sd, cache);
+ do_brush_action(sd, ss, cache);
}
}
@@ -958,9 +957,9 @@ static void projverts_clear_inside(SculptSession *ss)
}
#endif
-static void sculpt_update_tex(Sculpt *sd)
+static void sculpt_update_tex(Sculpt *sd, SculptSession *ss)
{
- SculptSession *ss= sd->session;
+ Brush *brush = paint_brush(&sd->paint);
if(ss->texcache) {
MEM_freeN(ss->texcache);
@@ -968,9 +967,9 @@ static void sculpt_update_tex(Sculpt *sd)
}
/* Need to allocate a bigger buffer for bigger brush size */
- ss->texcache_side = sd->brush->size * 2;
+ ss->texcache_side = brush->size * 2;
if(!ss->texcache || ss->texcache_side > ss->texcache_actual) {
- ss->texcache = brush_gen_texture_cache(sd->brush, sd->brush->size);
+ ss->texcache = brush_gen_texture_cache(brush, brush->size);
ss->texcache_actual = ss->texcache_side;
}
}
@@ -1021,8 +1020,8 @@ static struct MultiresModifierData *sculpt_multires_active(Object *ob)
static void sculpt_update_mesh_elements(bContext *C)
{
- SculptSession *ss = CTX_data_tool_settings(C)->sculpt->session;
Object *ob = CTX_data_active_object(C);
+ SculptSession *ss = ob->sculpt;
int oldtotvert = ss->totvert;
if((ss->multires = sculpt_multires_active(ob))) {
@@ -1055,12 +1054,14 @@ static void sculpt_update_mesh_elements(bContext *C)
static int sculpt_mode_poll(bContext *C)
{
- return G.f & G_SCULPTMODE;
+ Object *ob = CTX_data_active_object(C);
+ return ob && ob->mode & OB_MODE_SCULPT;
}
static int sculpt_poll(bContext *C)
{
- return G.f & G_SCULPTMODE && CTX_wm_area(C)->spacetype == SPACE_VIEW3D &&
+ return sculpt_mode_poll(C) && paint_brush(&CTX_data_tool_settings(C)->sculpt->paint) &&
+ CTX_wm_area(C)->spacetype == SPACE_VIEW3D &&
CTX_wm_region(C)->regiontype == RGN_TYPE_WINDOW;
}
@@ -1068,18 +1069,20 @@ static int sculpt_poll(bContext *C)
static void draw_paint_cursor(bContext *C, int x, int y, void *customdata)
{
Sculpt *sd= CTX_data_tool_settings(C)->sculpt;
+ SculptSession *ss= CTX_data_active_object(C)->sculpt;
+ Brush *brush = paint_brush(&sd->paint);
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);
+ glutil_draw_lined_arc(0.0, M_PI*2.0, brush->size, 40);
glTranslatef((float)-x, (float)-y, 0.0f);
- if(sd->session && sd->session->cache && sd->brush && (sd->brush->flag & BRUSH_SMOOTH_STROKE)) {
+ if(ss && ss->cache && brush && (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);
+ sdrawline(x, y, ss->cache->mouse[0] - ar->winrct.xmin, ss->cache->mouse[1] - ar->winrct.ymin);
}
glDisable(GL_BLEND);
@@ -1090,19 +1093,21 @@ static void toggle_paint_cursor(bContext *C)
{
Sculpt *s = CTX_data_scene(C)->toolsettings->sculpt;
- if(s->session->cursor) {
- WM_paint_cursor_end(CTX_wm_manager(C), s->session->cursor);
- s->session->cursor = NULL;
+ if(s->cursor) {
+ WM_paint_cursor_end(CTX_wm_manager(C), s->cursor);
+ s->cursor = NULL;
}
else {
- s->session->cursor =
+ s->cursor =
WM_paint_cursor_activate(CTX_wm_manager(C), sculpt_poll, draw_paint_cursor, NULL);
}
}
static void sculpt_undo_push(bContext *C, Sculpt *sd)
{
- switch(sd->brush->sculpt_tool) {
+ Brush *brush = paint_brush(&sd->paint);
+
+ switch(brush->sculpt_tool) {
case SCULPT_TOOL_DRAW:
ED_undo_push(C, "Draw Brush"); break;
case SCULPT_TOOL_SMOOTH:
@@ -1122,36 +1127,12 @@ static void sculpt_undo_push(bContext *C, Sculpt *sd)
}
}
-static int sculpt_brush_curve_preset_exec(bContext *C, wmOperator *op)
-{
- brush_curve_preset(CTX_data_scene(C)->toolsettings->sculpt->brush, RNA_enum_get(op->ptr, "mode"));
- return OPERATOR_FINISHED;
-}
-
-static void SCULPT_OT_brush_curve_preset(wmOperatorType *ot)
-{
- static EnumPropertyItem prop_mode_items[] = {
- {BRUSH_PRESET_SHARP, "SHARP", 0, "Sharp Curve", ""},
- {BRUSH_PRESET_SMOOTH, "SMOOTH", 0, "Smooth Curve", ""},
- {BRUSH_PRESET_MAX, "MAX", 0, "Max Curve", ""},
- {0, NULL, 0, NULL, NULL}};
-
- ot->name= "Preset";
- ot->idname= "SCULPT_OT_brush_curve_preset";
-
- ot->exec= sculpt_brush_curve_preset_exec;
- ot->poll= sculpt_mode_poll;
-
- ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
-
- RNA_def_enum(ot->srna, "mode", prop_mode_items, BRUSH_PRESET_SHARP, "Mode", "");
-}
-
/**** Radial control ****/
static int sculpt_radial_control_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
+ Brush *brush = paint_brush(&CTX_data_tool_settings(C)->sculpt->paint);
toggle_paint_cursor(C);
- brush_radial_control_invoke(op, CTX_data_scene(C)->toolsettings->sculpt->brush, 1);
+ brush_radial_control_invoke(op, brush, 1);
return WM_radial_control_invoke(C, op, event);
}
@@ -1165,7 +1146,9 @@ static int sculpt_radial_control_modal(bContext *C, wmOperator *op, wmEvent *eve
static int sculpt_radial_control_exec(bContext *C, wmOperator *op)
{
- return brush_radial_control_exec(op, CTX_data_scene(C)->toolsettings->sculpt->brush, 1);
+ Brush *brush = paint_brush(&CTX_data_tool_settings(C)->sculpt->paint);
+
+ return brush_radial_control_exec(op, brush, 1);
}
static void SCULPT_OT_radial_control(wmOperatorType *ot)
@@ -1209,12 +1192,13 @@ static void sculpt_cache_free(StrokeCache *cache)
}
/* Initialize the stroke cache invariants from operator properties */
-static void sculpt_update_cache_invariants(Sculpt *sd, bContext *C, wmOperator *op)
+static void sculpt_update_cache_invariants(Sculpt *sd, SculptSession *ss, bContext *C, wmOperator *op)
{
StrokeCache *cache = MEM_callocN(sizeof(StrokeCache), "stroke cache");
+ Brush *brush = paint_brush(&sd->paint);
int i;
- sd->session->cache = cache;
+ ss->cache = cache;
RNA_float_get_array(op->ptr, "scale", cache->scale);
cache->flag = RNA_int_get(op->ptr, "flag");
@@ -1235,72 +1219,74 @@ static void sculpt_update_cache_invariants(Sculpt *sd, bContext *C, wmOperator *
sculpt_update_mesh_elements(C);
/* Initialize layer brush displacements */
- if(sd->brush->sculpt_tool == SCULPT_TOOL_LAYER &&
- (!sd->session->layer_disps || !(sd->brush->flag & BRUSH_PERSISTENT))) {
- if(sd->session->layer_disps)
- MEM_freeN(sd->session->layer_disps);
- sd->session->layer_disps = MEM_callocN(sizeof(float) * sd->session->totvert, "layer brush displacements");
+ if(brush->sculpt_tool == SCULPT_TOOL_LAYER &&
+ (!ss->layer_disps || !(brush->flag & BRUSH_PERSISTENT))) {
+ if(ss->layer_disps)
+ MEM_freeN(ss->layer_disps);
+ ss->layer_disps = MEM_callocN(sizeof(float) * ss->totvert, "layer brush displacements");
}
/* Make copies of the mesh vertex locations and normals for some tools */
- if(sd->brush->sculpt_tool == SCULPT_TOOL_LAYER || (sd->brush->flag & BRUSH_ANCHORED)) {
- if(sd->brush->sculpt_tool != SCULPT_TOOL_LAYER ||
- !sd->session->mesh_co_orig || !(sd->brush->flag & BRUSH_PERSISTENT)) {
- if(!sd->session->mesh_co_orig)
- sd->session->mesh_co_orig= MEM_mallocN(sizeof(float) * 3 * sd->session->totvert,
+ if(brush->sculpt_tool == SCULPT_TOOL_LAYER || (brush->flag & BRUSH_ANCHORED)) {
+ if(brush->sculpt_tool != SCULPT_TOOL_LAYER ||
+ !ss->mesh_co_orig || !(brush->flag & BRUSH_PERSISTENT)) {
+ if(!ss->mesh_co_orig)
+ ss->mesh_co_orig= MEM_mallocN(sizeof(float) * 3 * ss->totvert,
"sculpt mesh vertices copy");
- for(i = 0; i < sd->session->totvert; ++i)
- VecCopyf(sd->session->mesh_co_orig[i], sd->session->mvert[i].co);
+ for(i = 0; i < ss->totvert; ++i)
+ VecCopyf(ss->mesh_co_orig[i], ss->mvert[i].co);
}
- if(sd->brush->flag & BRUSH_ANCHORED) {
- cache->orig_norms= MEM_mallocN(sizeof(short) * 3 * sd->session->totvert, "Sculpt orig norm");
- for(i = 0; i < sd->session->totvert; ++i) {
- cache->orig_norms[i][0] = sd->session->mvert[i].no[0];
- cache->orig_norms[i][1] = sd->session->mvert[i].no[1];
- cache->orig_norms[i][2] = sd->session->mvert[i].no[2];
+ if(brush->flag & BRUSH_ANCHORED) {
+ cache->orig_norms= MEM_mallocN(sizeof(short) * 3 * ss->totvert, "Sculpt orig norm");
+ for(i = 0; i < ss->totvert; ++i) {
+ cache->orig_norms[i][0] = ss->mvert[i].no[0];
+ cache->orig_norms[i][1] = ss->mvert[i].no[1];
+ cache->orig_norms[i][2] = ss->mvert[i].no[2];
}
- if(sd->session->face_normals) {
- float *fn = sd->session->face_normals;
- cache->face_norms= MEM_mallocN(sizeof(float) * 3 * sd->session->totface, "Sculpt face norms");
- for(i = 0; i < sd->session->totface; ++i, fn += 3)
+ if(ss->face_normals) {
+ float *fn = ss->face_normals;
+ cache->face_norms= MEM_mallocN(sizeof(float) * 3 * ss->totface, "Sculpt face norms");
+ for(i = 0; i < ss->totface; ++i, fn += 3)
VecCopyf(cache->face_norms[i], fn);
}
}
}
unproject(cache->mats, cache->true_location, cache->initial_mouse[0], cache->initial_mouse[1], cache->depth);
- cache->radius = unproject_brush_radius(sd->session, brush_size(sd));
+ cache->radius = unproject_brush_radius(ss, brush_size(sd, ss));
cache->rotation = 0;
cache->first_time = 1;
}
/* Initialize the stroke cache variants from operator properties */
-static void sculpt_update_cache_variants(Sculpt *sd, PointerRNA *ptr)
+static void sculpt_update_cache_variants(Sculpt *sd, SculptSession *ss, PointerRNA *ptr)
{
- StrokeCache *cache = sd->session->cache;
+ StrokeCache *cache = ss->cache;
+ Brush *brush = paint_brush(&sd->paint);
float grab_location[3];
int dx, dy;
- if(!(sd->brush->flag & BRUSH_ANCHORED))
+ if(!(brush->flag & BRUSH_ANCHORED))
RNA_float_get_array(ptr, "location", cache->true_location);
cache->flip = RNA_boolean_get(ptr, "flip");
RNA_int_get_array(ptr, "mouse", cache->mouse);
+ cache->pressure = RNA_float_get(ptr, "pressure");
/* Truly temporary data that isn't stored in properties */
cache->previous_pixel_radius = cache->pixel_radius;
- cache->pixel_radius = brush_size(sd);
+ cache->pixel_radius = brush_size(sd, ss);
- if(sd->brush->flag & BRUSH_ANCHORED) {
+ if(brush->flag & BRUSH_ANCHORED) {
dx = cache->mouse[0] - cache->initial_mouse[0];
dy = cache->mouse[1] - cache->initial_mouse[1];
cache->pixel_radius = sqrt(dx*dx + dy*dy);
- cache->radius = unproject_brush_radius(sd->session, cache->pixel_radius);
+ cache->radius = unproject_brush_radius(ss, cache->pixel_radius);
cache->rotation = atan2(dy, dx);
}
- else if(sd->brush->flag & BRUSH_RAKE) {
+ else if(brush->flag & BRUSH_RAKE) {
int update;
dx = cache->last_rake[0] - cache->mouse[0];
@@ -1319,7 +1305,7 @@ static void sculpt_update_cache_variants(Sculpt *sd, PointerRNA *ptr)
}
/* Find the grab delta */
- if(sd->brush->sculpt_tool == SCULPT_TOOL_GRAB) {
+ if(brush->sculpt_tool == SCULPT_TOOL_GRAB) {
unproject(cache->mats, grab_location, cache->mouse[0], cache->mouse[1], cache->depth);
if(!cache->first_time)
VecSubf(cache->grab_delta, grab_location, cache->old_grab_location);
@@ -1368,19 +1354,20 @@ static void sculpt_brush_stroke_init_properties(bContext *C, wmOperator *op, wmE
view3d_set_viewcontext(C, &vc);
RNA_float_set(op->ptr, "depth", read_cached_depth(&vc, event->x, event->y));
- sculpt_update_cache_invariants(sd, C, op);
+ sculpt_update_cache_invariants(sd, ss, C, op);
}
static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, wmEvent *event)
{
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
+ SculptSession *ss = CTX_data_active_object(C)->sculpt;
view3d_operator_needs_opengl(C);
/* 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);
+ sculpt_update_tex(sd, ss);
/* add modal handler */
WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
@@ -1388,14 +1375,14 @@ static int sculpt_brush_stroke_invoke(bContext *C, wmOperator *op, wmEvent *even
return OPERATOR_RUNNING_MODAL;
}
-static void sculpt_restore_mesh(Sculpt *sd)
+static void sculpt_restore_mesh(Sculpt *sd, SculptSession *ss)
{
- SculptSession *ss = sd->session;
StrokeCache *cache = ss->cache;
+ Brush *brush = paint_brush(&sd->paint);
int i;
/* Restore the mesh before continuing with anchored stroke */
- if((sd->brush->flag & BRUSH_ANCHORED) && ss->mesh_co_orig) {
+ if((brush->flag & BRUSH_ANCHORED) && ss->mesh_co_orig) {
for(i = 0; i < ss->totvert; ++i) {
VecCopyf(ss->mvert[i].co, ss->mesh_co_orig[i]);
ss->mvert[i].no[0] = cache->orig_norms[i][0];
@@ -1409,7 +1396,7 @@ static void sculpt_restore_mesh(Sculpt *sd)
VecCopyf(fn, cache->face_norms[i]);
}
- if(sd->brush->sculpt_tool == SCULPT_TOOL_LAYER)
+ if(brush->sculpt_tool == SCULPT_TOOL_LAYER)
memset(ss->layer_disps, 0, sizeof(float) * ss->totvert);
}
}
@@ -1422,32 +1409,35 @@ static void sculpt_post_stroke_free(SculptSession *ss)
static void sculpt_flush_update(bContext *C)
{
- Sculpt *s = CTX_data_tool_settings(C)->sculpt;
+ Object *ob = CTX_data_active_object(C);
+ SculptSession *ss = ob->sculpt;
ARegion *ar = CTX_wm_region(C);
- MultiresModifierData *mmd = s->session->multires;
+ MultiresModifierData *mmd = ss->multires;
- calc_damaged_verts(s->session);
+ calc_damaged_verts(ss);
if(mmd) {
- if(mmd->undo_verts && mmd->undo_verts != s->session->mvert)
+ if(mmd->undo_verts && mmd->undo_verts != ss->mvert)
MEM_freeN(mmd->undo_verts);
- mmd->undo_verts = s->session->mvert;
- mmd->undo_verts_tot = s->session->totvert;
- multires_mark_as_modified(CTX_data_active_object(C));
+ mmd->undo_verts = ss->mvert;
+ mmd->undo_verts_tot = ss->totvert;
+ multires_mark_as_modified(ob);
}
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)
+static int sculpt_smooth_stroke(Sculpt *s, SculptSession *ss, int output[2], wmEvent *event)
{
+ Brush *brush = paint_brush(&s->paint);
+
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;
+ if(brush->flag & BRUSH_SMOOTH_STROKE && brush->sculpt_tool != SCULPT_TOOL_GRAB) {
+ StrokeCache *cache = ss->cache;
float u = .9, v = 1.0 - u;
int dx = cache->mouse[0] - event->x, dy = cache->mouse[1] - event->y;
int radius = 50;
@@ -1467,7 +1457,7 @@ static int sculpt_smooth_stroke(Sculpt *s, int output[2], wmEvent *event)
/* Returns zero if the stroke dots should not be spaced, non-zero otherwise */
int sculpt_space_stroke_enabled(Sculpt *s)
{
- Brush *br = s->brush;
+ Brush *br = paint_brush(&s->paint);
return (br->flag & BRUSH_SPACE) && !(br->flag & BRUSH_ANCHORED) && (br->sculpt_tool != SCULPT_TOOL_GRAB);
}
@@ -1475,30 +1465,40 @@ int sculpt_space_stroke_enabled(Sculpt *s)
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;
+ SculptSession *ss = CTX_data_active_object(C)->sculpt;
+ StrokeCache *cache = ss->cache;
PointerRNA itemptr;
- float cur_depth;
+ float cur_depth, pressure = 1;
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);
+ unproject(ss->cache->mats, center, mouse[0], mouse[1], cur_depth);
+
+ /* Tablet */
+ if(event->custom == EVT_DATA_TABLET) {
+ wmTabletData *wmtab= event->customdata;
+ if(wmtab->Active != EVT_TABLET_NONE)
+ pressure= wmtab->Pressure;
+ }
/* 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);
+ RNA_float_set(&itemptr, "pressure", pressure);
+ sculpt_update_cache_variants(sd, ss, &itemptr);
- sculpt_restore_mesh(sd);
- do_symmetrical_brush_actions(sd, cache);
+ sculpt_restore_mesh(sd, ss);
+ do_symmetrical_brush_actions(sd, ss);
}
/* 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])
+static int sculpt_space_stroke(bContext *C, wmOperator *op, wmEvent *event, Sculpt *s, SculptSession *ss, const int final_mouse[2])
{
- StrokeCache *cache = s->session->cache;
+ StrokeCache *cache = ss->cache;
+ Brush *brush = paint_brush(&s->paint);
int cnt = 0;
if(sculpt_space_stroke_enabled(s)) {
@@ -1511,11 +1511,11 @@ static int sculpt_space_stroke(bContext *C, wmOperator *op, wmEvent *event, Scul
length = sqrt(vec[0]*vec[0] + vec[1]*vec[1]);
if(length > FLT_EPSILON) {
- scale = s->brush->spacing / length;
+ scale = brush->spacing / length;
vec[0] *= scale;
vec[1] *= scale;
- steps = (int)(length / s->brush->spacing);
+ steps = (int)(length / brush->spacing);
for(i = 0; i < steps; ++i, ++cnt) {
mouse[0] += vec[0];
mouse[1] += vec[1];
@@ -1530,38 +1530,39 @@ static int sculpt_space_stroke(bContext *C, wmOperator *op, wmEvent *event, Scul
static int sculpt_brush_stroke_modal(bContext *C, wmOperator *op, wmEvent *event)
{
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
+ SculptSession *ss = CTX_data_active_object(C)->sculpt;
ARegion *ar = CTX_wm_region(C);
float cur_depth;
sculpt_update_mesh_elements(C);
- if(!sd->session->cache) {
+ if(!ss->cache) {
ViewContext vc;
view3d_set_viewcontext(C, &vc);
cur_depth = read_cached_depth(&vc, event->x, event->y);
/* Don't start the stroke until a valid depth is found */
if(cur_depth < 1.0 - FLT_EPSILON) {
- sculpt_brush_stroke_init_properties(C, op, event, sd->session);
- sculptmode_update_all_projverts(sd->session);
+ sculpt_brush_stroke_init_properties(C, op, event, ss);
+ sculptmode_update_all_projverts(ss);
}
ED_region_tag_redraw(ar);
}
- if(sd->session->cache) {
+ if(ss->cache) {
int mouse[2];
- if(sculpt_smooth_stroke(sd, mouse, event)) {
+ if(sculpt_smooth_stroke(sd, ss, mouse, event)) {
if(sculpt_space_stroke_enabled(sd)) {
- if(!sculpt_space_stroke(C, op, event, sd, mouse))
+ if(!sculpt_space_stroke(C, op, event, sd, ss, mouse))
ED_region_tag_redraw(ar);
}
else
sculpt_brush_stroke_add_step(C, op, event, mouse);
sculpt_flush_update(C);
- sculpt_post_stroke_free(sd->session);
+ sculpt_post_stroke_free(ss);
}
else
ED_region_tag_redraw(ar);
@@ -1569,10 +1570,10 @@ static int sculpt_brush_stroke_modal(bContext *C, wmOperator *op, wmEvent *event
/* Finished */
if(event->type == LEFTMOUSE && event->val == 0) {
- if(sd->session->cache) {
- request_depth_update(sd->session->cache->vc.rv3d);
- sculpt_cache_free(sd->session->cache);
- sd->session->cache = NULL;
+ if(ss->cache) {
+ request_depth_update(ss->cache->vc.rv3d);
+ sculpt_cache_free(ss->cache);
+ ss->cache = NULL;
sculpt_undo_push(C, sd);
}
@@ -1585,24 +1586,25 @@ static int sculpt_brush_stroke_modal(bContext *C, wmOperator *op, wmEvent *event
static int sculpt_brush_stroke_exec(bContext *C, wmOperator *op)
{
Sculpt *sd = CTX_data_tool_settings(C)->sculpt;
+ SculptSession *ss = CTX_data_active_object(C)->sculpt;
view3d_operator_needs_opengl(C);
- sculpt_update_cache_invariants(sd, C, op);
- sculptmode_update_all_projverts(sd->session);
- sculpt_update_tex(sd);
+ sculpt_update_cache_invariants(sd, ss, C, op);
+ sculptmode_update_all_projverts(ss);
+ sculpt_update_tex(sd, ss);
RNA_BEGIN(op->ptr, itemptr, "stroke") {
- sculpt_update_cache_variants(sd, &itemptr);
+ sculpt_update_cache_variants(sd, ss, &itemptr);
- sculpt_restore_mesh(sd);
- do_symmetrical_brush_actions(sd, sd->session->cache);
+ sculpt_restore_mesh(sd, ss);
+ do_symmetrical_brush_actions(sd, ss);
- sculpt_post_stroke_free(sd->session);
+ sculpt_post_stroke_free(ss);
}
RNA_END;
sculpt_flush_update(C);
- sculpt_cache_free(sd->session->cache);
+ sculpt_cache_free(ss->cache);
sculpt_undo_push(C, sd);
@@ -1649,7 +1651,7 @@ static void SCULPT_OT_brush_stroke(wmOperatorType *ot)
static int sculpt_set_persistent_base(bContext *C, wmOperator *op)
{
- SculptSession *ss = CTX_data_tool_settings(C)->sculpt->session;
+ SculptSession *ss = CTX_data_active_object(C)->sculpt;
if(ss) {
if(ss->layer_disps)
@@ -1682,35 +1684,34 @@ static void SCULPT_OT_set_persistent_base(wmOperatorType *ot)
static int sculpt_toggle_mode(bContext *C, wmOperator *op)
{
ToolSettings *ts = CTX_data_tool_settings(C);
+ Object *ob = CTX_data_active_object(C);
- if(G.f & G_SCULPTMODE) {
- multires_force_update(CTX_data_active_object(C));
+ if(ob->mode & OB_MODE_SCULPT) {
+ multires_force_update(ob);
/* Leave sculptmode */
- G.f &= ~G_SCULPTMODE;
-
- toggle_paint_cursor(C);
+ ob->mode &= ~OB_MODE_SCULPT;
- sculptsession_free(ts->sculpt);
+ free_sculptsession(&ob->sculpt);
}
else {
/* Enter sculptmode */
- G.f |= G_SCULPTMODE;
+ ob->mode |= OB_MODE_SCULPT;
/* Create persistent sculpt mode data */
if(!ts->sculpt)
ts->sculpt = MEM_callocN(sizeof(Sculpt), "sculpt mode data");
/* Create sculpt mode session data */
- if(ts->sculpt->session)
- MEM_freeN(ts->sculpt->session);
- ts->sculpt->session = MEM_callocN(sizeof(SculptSession), "sculpt session");
+ if(ob->sculpt)
+ free_sculptsession(&ob->sculpt);
+ ob->sculpt = MEM_callocN(sizeof(SculptSession), "sculpt session");
- toggle_paint_cursor(C);
+ if(!ts->sculpt->cursor)
+ toggle_paint_cursor(C);
- /* If there's no brush, create one */
- brush_check_exists(&ts->sculpt->brush);
+ paint_init(&ts->sculpt->paint, "Brush");
WM_event_add_notifier(C, NC_SCENE|ND_MODE, CTX_data_scene(C));
}
@@ -1736,6 +1737,5 @@ void ED_operatortypes_sculpt()
WM_operatortype_append(SCULPT_OT_radial_control);
WM_operatortype_append(SCULPT_OT_brush_stroke);
WM_operatortype_append(SCULPT_OT_sculptmode_toggle);
- WM_operatortype_append(SCULPT_OT_brush_curve_preset);
WM_operatortype_append(SCULPT_OT_set_persistent_base);
}