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:
authorNicholas Bishop <nicholasbishop@gmail.com>2009-01-15 08:09:33 +0300
committerNicholas Bishop <nicholasbishop@gmail.com>2009-01-15 08:09:33 +0300
commit4c17156c9eb37cee7b6b96b8ef58e34e7ad281f3 (patch)
treed41c9d64bb0d06e2899e52d4e14d734a9cb64c1c /source/blender/editors
parent52135dd4fac718b31b7653e42a7e4b332b2814f3 (diff)
Brought back anchored mode for sculpt brushes.
Diffstat (limited to 'source/blender/editors')
-rw-r--r--source/blender/editors/sculpt/sculpt.c133
1 files changed, 89 insertions, 44 deletions
diff --git a/source/blender/editors/sculpt/sculpt.c b/source/blender/editors/sculpt/sculpt.c
index 2d707fbe91a..5dc2f46e825 100644
--- a/source/blender/editors/sculpt/sculpt.c
+++ b/source/blender/editors/sculpt/sculpt.c
@@ -136,16 +136,19 @@ typedef enum StrokeFlags {
For descriptions of these settings, check the operator properties.
*/
typedef struct StrokeCache {
+ /* Invariants */
float radius;
float scale[3];
int flag;
float clip_tolerance[3];
- int mouse[2];
+ int initial_mouse[2];
float depth;
+ /* Variants */
float true_location[3];
float location[3];
float flip;
+ int mouse[2];
/* Truly temporary storage that isn't saved as a property */
MVert *mvert; /* Can be either Mesh mverts or MultiresDM mverts */
@@ -153,6 +156,8 @@ typedef struct StrokeCache {
float *layer_disps; /* Displacements for each vertex */
float (*mesh_store)[3]; /* Copy of the mesh vertices' locations */
short (*orig_norms)[3]; /* Copy of the mesh vertices' normals */
+ int anchored_rotation; /* Texture rotation in anchored mode */
+ int pixel_radius, previous_pixel_radius;
} StrokeCache;
typedef struct BrushAction {
@@ -160,13 +165,6 @@ typedef struct BrushAction {
char firsttime;
- float prev_radius;
- float radius;
-
- //float *layer_disps;
-
- float anchored_rot;
-
/* Grab brush */
ListBase grab_active_verts[8];
} BrushAction;
@@ -790,8 +788,8 @@ static float tex_strength(SculptData *sd, BrushAction *a, float *point, const fl
externtex(&mtex,point,&avg,&jnk,&jnk,&jnk,&jnk);
}
else if(ss->texcache) {
- const float bsize= a->radius * 2;
- const float rot= to_rad(sculpt_tex_angle(sd)) + a->anchored_rot;
+ const float bsize= ss->cache->pixel_radius * 2;
+ const float rot= to_rad(sculpt_tex_angle(sd)) + ss->cache->anchored_rotation;
int px, py;
float flip[3], point_2d[2];
@@ -827,8 +825,8 @@ static float tex_strength(SculptData *sd, BrushAction *a, float *point, const fl
py %= sy-1;
avg= get_texcache_pixel_bilinear(ss, TC_SIZE*px/sx, TC_SIZE*py/sy);
} else {
- float fx= (point_2d[0] - ss->cache->mouse[0]) / bsize;
- float fy= (point_2d[1] - ss->cache->mouse[1]) / bsize;
+ float fx= (point_2d[0] - ss->cache->initial_mouse[0]) / bsize;
+ float fy= (point_2d[1] - ss->cache->initial_mouse[1]) / bsize;
float angle= atan2(fy, fx) - rot;
float flen= sqrtf(fx*fx + fy*fy);
@@ -852,7 +850,7 @@ static void sculpt_add_damaged_rect(SculptSession *ss, BrushAction *a)
{
short p[2];
RectNode *rn= MEM_mallocN(sizeof(RectNode),"RectNode");
- const float radius = a->radius > a->prev_radius ? a->radius : a->prev_radius;
+ const float radius = MAX2(ss->cache->pixel_radius, ss->cache->previous_pixel_radius);
unsigned i;
/* Find center */
@@ -1598,6 +1596,27 @@ static void sculpt_load_mats(bContext *C, bglMats *mats)
mats->viewport[3] = ar->winy;
}
+static float unproject_brush_radius(SculptSession *ss, float offset)
+{
+ float brush_edge[3];
+
+ /* In anchored mode, brush size changes with mouse loc, otherwise it's fixed using the brush radius */
+ unproject(ss, brush_edge, ss->cache->initial_mouse[0] + offset,
+ ss->cache->initial_mouse[1], ss->cache->depth);
+
+ return VecLenf(ss->cache->true_location, brush_edge);
+}
+
+static void sculpt_cache_free(StrokeCache *cache)
+{
+ if(cache->layer_disps)
+ MEM_freeN(cache->layer_disps);
+ if(cache->mesh_store)
+ MEM_freeN(cache->mesh_store);
+ if(cache->orig_norms)
+ MEM_freeN(cache->orig_norms);
+}
+
/* Initialize the stroke cache invariants from operator properties */
static void sculpt_update_cache_invariants(SculptData *sd, wmOperator *op, Object *ob)
{
@@ -1606,38 +1625,57 @@ static void sculpt_update_cache_invariants(SculptData *sd, wmOperator *op, Objec
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);
+ RNA_int_get_array(op->ptr, "initial_mouse", cache->initial_mouse);
cache->depth = RNA_float_get(op->ptr, "depth");
/* Truly temporary data that isn't stored in properties */
cache->totvert = get_mesh(ob)->totvert; // XXX
cache->mvert = get_mesh(ob)->mvert; // XXX
- if(sd->brush->sculpt_tool == SCULPT_TOOL_LAYER) {
+ if(sd->brush->sculpt_tool == SCULPT_TOOL_LAYER || (sd->brush->flag & BRUSH_ANCHORED)) {
cache->layer_disps = MEM_callocN(sizeof(float) * cache->totvert, "layer brush displacements");
cache->mesh_store= MEM_mallocN(sizeof(float) * 3 * cache->totvert, "sculpt mesh vertices copy");
for(i = 0; i < cache->totvert; ++i)
VecCopyf(cache->mesh_store[i], cache->mvert[i].co);
+
+ if(sd->brush->flag & BRUSH_ANCHORED) {
+ cache->orig_norms= MEM_mallocN(sizeof(short) * 3 * cache->totvert, "Sculpt orig norm");
+ for(i = 0; i < cache->totvert; ++i) {
+ cache->orig_norms[i][0] = cache->mvert[i].no[0];
+ cache->orig_norms[i][1] = cache->mvert[i].no[1];
+ cache->orig_norms[i][2] = cache->mvert[i].no[2];
+ }
+ }
}
-}
-static void sculpt_cache_free(StrokeCache *cache)
-{
- if(cache->layer_disps)
- MEM_freeN(cache->layer_disps);
- if(cache->mesh_store)
- MEM_freeN(cache->mesh_store);
+ unproject(sd->session, cache->true_location, cache->initial_mouse[0], cache->initial_mouse[1], cache->depth);
+ cache->radius = unproject_brush_radius(sd->session, brush_size(sd));
}
/* Initialize the stroke cache variants from operator properties */
-static void sculpt_update_cache_variants(StrokeCache *cache, PointerRNA *ptr)
+static void sculpt_update_cache_variants(SculptData *sd, PointerRNA *ptr)
{
- RNA_float_get_array(ptr, "location", cache->true_location);
+ StrokeCache *cache = sd->session->cache;
+
+ if(!(sd->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->previous_pixel_radius = cache->pixel_radius;
+
+ /* Truly temporary data that isn't stored in properties */
+ if(sd->brush->flag & BRUSH_ANCHORED) {
+ int dx = cache->mouse[0] - cache->initial_mouse[0];
+ int 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->anchored_rotation = atan2(dy, dx);
+ } else
+ cache->pixel_radius = brush_size(sd);
}
/* Initialize stroke operator properties */
@@ -1646,21 +1684,10 @@ static void 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);
float scale[3], clip_tolerance[3] = {0,0,0};
int mouse[2], flag = 0;
- unproject(ss, brush_center, event->x, event->y, depth);
-
- /* In anchored mode, brush size changes with mouse loc, otherwise it's fixed using the brush radius */
- unproject(ss, brush_edge,
- event->x + ((sd->brush->flag & BRUSH_ANCHORED) ? 0 : size),
- event->y, depth);
-
- 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];
@@ -1686,10 +1713,10 @@ static void sculpt_brush_stroke_init(bContext *C, wmOperator *op, wmEvent *event
/* Initial mouse location */
mouse[0] = event->x;
mouse[1] = event->y;
- RNA_int_set_array(op->ptr, "mouse", mouse);
+ RNA_int_set_array(op->ptr, "initial_mouse", mouse);
/* Initial screen depth under the mouse */
- RNA_int_set(op->ptr, "depth", depth);
+ RNA_float_set(op->ptr, "depth", depth);
sculpt_update_cache_invariants(sd, op, ob);
}
@@ -1726,6 +1753,23 @@ static void sculpt_action_init(BrushAction *a)
memset(a, 0, sizeof(BrushAction));
}
+
+static void sculpt_restore_mesh(SculptData *sd)
+{
+ StrokeCache *cache = sd->session->cache;
+ int i;
+
+ /* Restore the mesh before continuing with anchored stroke */
+ if((sd->brush->flag & BRUSH_ANCHORED) && cache->mesh_store) {
+ for(i = 0; i < cache->totvert; ++i) {
+ VecCopyf(cache->mvert[i].co, cache->mesh_store[i]);
+ cache->mvert[i].no[0] = cache->orig_norms[i][0];
+ cache->mvert[i].no[1] = cache->orig_norms[i][1];
+ cache->mvert[i].no[2] = cache->orig_norms[i][2];
+ }
+ }
+}
+
static int sculpt_brush_stroke_modal(bContext *C, wmOperator *op, wmEvent *event)
{
PointerRNA itemptr;
@@ -1734,6 +1778,7 @@ static int sculpt_brush_stroke_modal(bContext *C, wmOperator *op, wmEvent *event
Object *ob= CTX_data_active_object(C);
ARegion *ar = CTX_wm_region(C);
float center[3];
+ int mouse[2] = {event->x, event->y};
sculpt_action_init(&a);
unproject(sd->session, center, event->x, event->y, get_depth(C, event->x, event->y));
@@ -1741,9 +1786,11 @@ static int sculpt_brush_stroke_modal(bContext *C, wmOperator *op, wmEvent *event
/* 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->session->cache, &itemptr);
+ sculpt_update_cache_variants(sd, &itemptr);
+ sculpt_restore_mesh(sd);
do_symmetrical_brush_actions(&CTX_data_scene(C)->sculptdata, sd->session->cache, &a);
//calc_damaged_verts(sd->session, &a);
BLI_freelistN(&sd->session->damaged_verts);
@@ -1776,8 +1823,9 @@ static int sculpt_brush_stroke_exec(bContext *C, wmOperator *op)
RNA_BEGIN(op->ptr, itemptr, "stroke") {
sculpt_action_init(&a);
- sculpt_update_cache_variants(sd->session->cache, &itemptr);
+ sculpt_update_cache_variants(sd, &itemptr);
+ sculpt_restore_mesh(sd);
do_symmetrical_brush_actions(sd, sd->session->cache, &a);
BLI_freelistN(&sd->session->damaged_verts);
}
@@ -1813,9 +1861,6 @@ static void SCULPT_OT_brush_stroke(wmOperatorType *ot)
prop= RNA_def_property(ot->srna, "stroke", PROP_COLLECTION, PROP_NONE);
RNA_def_property_struct_runtime(prop, &RNA_OperatorStrokeElement);
- /* Brush radius measured in object space, projected from the brush setting in pixels */
- prop= RNA_def_property(ot->srna, "radius", PROP_FLOAT, PROP_NONE);
-
/* If the object has a scaling factor, brushes also need to be scaled
to work as expected. */
prop= RNA_def_property(ot->srna, "scale", PROP_FLOAT, PROP_VECTOR);
@@ -1830,7 +1875,7 @@ static void SCULPT_OT_brush_stroke(wmOperatorType *ot)
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);
+ prop= RNA_def_property(ot->srna, "initial_mouse", PROP_INT, PROP_VECTOR);
RNA_def_property_array(prop, 2);
RNA_def_property_int_array_default(prop, vec2i_def);