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>2007-06-25 02:28:28 +0400
committerNicholas Bishop <nicholasbishop@gmail.com>2007-06-25 02:28:28 +0400
commit8cf2d5ca4acb40459f6937f7b2c50e4fc42c22c7 (patch)
tree8d30288e77a902ee24a8f59a651b2e59ecbb1b21 /source/blender/src/sculptmode.c
parent296758ff0106eaa845fe1a1eeb14df2c6daa792d (diff)
== Sculpt Mode ==
Added a new input control that smooths the brush stroke. This option controlled by the menu item Sculpt>Input Control>Smooth Stroke. When enabled, the brush has a delayed effect on the model; a green line is drawn to indicate the smoothed path of the stroke. After ~200 pixels, the first half of the stroke will be applied to the model; the process then repeats, with a new segment of the stroke being applied to the model after every 200 pixels. On mouse up, any remaining portion of the stroke will be applied. Other changes: * Added a flags field to SculptData; currently only used for smooth stroke but other flags can be moved into it * Moved the damaged_rects/verts into SculptSession * Simplified brush application by moving init_editdata into do_symmetrical_brush_actions * Removed Averaging from sculpt Input menu; smooth stroke should take its place TODO: * Fix display of the smooth line in Partial Redraw mode * Make the smoothing and delay factors adjustable * Optimize the stroke application (currently using the old 'dot' style of applying the brush)
Diffstat (limited to 'source/blender/src/sculptmode.c')
-rw-r--r--source/blender/src/sculptmode.c126
1 files changed, 66 insertions, 60 deletions
diff --git a/source/blender/src/sculptmode.c b/source/blender/src/sculptmode.c
index c6c27c5ba59..2e42430203d 100644
--- a/source/blender/src/sculptmode.c
+++ b/source/blender/src/sculptmode.c
@@ -175,6 +175,7 @@ SculptData *sculpt_data(void)
}
void sculpt_init_session(void);
+void init_editdata(EditData *e, short *, short *);
SculptSession *sculpt_session(void)
{
@@ -881,7 +882,7 @@ float tex_strength(EditData *e, float *point, const float len,const unsigned vin
/* Mark area around the brush as damaged. projverts are marked if they are
inside the area and the damaged rectangle in 2D screen coordinates is
added to damaged_rects. */
-void sculptmode_add_damaged_rect(EditData *e, ListBase *damaged_rects)
+void sculptmode_add_damaged_rect(EditData *e)
{
short p[2];
const float radius= brush_size();
@@ -896,7 +897,7 @@ void sculptmode_add_damaged_rect(EditData *e, ListBase *damaged_rects)
rn->r.xmax= p[0]+radius;
rn->r.ymax= p[1]+radius;
- BLI_addtail(damaged_rects,rn);
+ BLI_addtail(&sculpt_session()->damaged_rects, rn);
/* Update insides */
for(i=0; i<me->totvert; ++i) {
@@ -909,8 +910,7 @@ void sculptmode_add_damaged_rect(EditData *e, ListBase *damaged_rects)
}
}
-void do_brush_action(float *vertexcosnos, EditData e,
- ListBase *damaged_verts, ListBase *damaged_rects)
+void do_brush_action(EditData e)
{
int i;
float av_dist;
@@ -920,8 +920,9 @@ void do_brush_action(float *vertexcosnos, EditData e,
Mesh *me= get_mesh(OBACT);
const float bstrength= brush_strength(&e);
KeyBlock *keyblock= ob_get_keyblock(OBACT);
+ SculptSession *ss = sculpt_session();
- sculptmode_add_damaged_rect(&e,damaged_rects);
+ sculptmode_add_damaged_rect(&e);
/* Build a list of all vertices that are potentially within the brush's
area of influence. Only do this once for the grab brush. */
@@ -929,7 +930,7 @@ void do_brush_action(float *vertexcosnos, EditData e,
for(i=0; i<me->totvert; ++i) {
/* Projverts.inside provides a rough bounding box */
if(projverts[i].inside) {
- vert= vertexcosnos ? &vertexcosnos[i*6] : me->mvert[i].co;
+ vert= ss->vertexcosnos ? &ss->vertexcosnos[i*6] : me->mvert[i].co;
av_dist= VecLenf(&e.center.x,vert);
if(av_dist < e.size) {
adata= (ActiveData*)MEM_mallocN(sizeof(ActiveData), "ActiveData");
@@ -985,11 +986,11 @@ void do_brush_action(float *vertexcosnos, EditData e,
}
}
- if(vertexcosnos)
+ if(ss->vertexcosnos)
BLI_freelistN(&active_verts);
else {
if(!e.grabdata)
- addlisttolist(damaged_verts, &active_verts);
+ addlisttolist(&ss->damaged_verts, &active_verts);
}
}
}
@@ -1019,27 +1020,28 @@ EditData flip_editdata(EditData *e, const char symm)
return fe;
}
-void do_symmetrical_brush_actions(float *vertexcosnos, EditData *e,
- ListBase *damaged_verts, ListBase *damaged_rects)
+void do_symmetrical_brush_actions(EditData * e, short co[2], short pr_co[2])
{
const char symm= sculpt_data()->symm;
+
+ init_editdata(e, co, pr_co);
- do_brush_action(vertexcosnos, flip_editdata(e, 0), damaged_verts, damaged_rects);
+ do_brush_action(flip_editdata(e, 0));
if(symm & SYMM_X)
- do_brush_action(vertexcosnos, flip_editdata(e, SYMM_X), damaged_verts, damaged_rects);
+ do_brush_action(flip_editdata(e, SYMM_X));
if(symm & SYMM_Y)
- do_brush_action(vertexcosnos, flip_editdata(e, SYMM_Y), damaged_verts, damaged_rects);
+ do_brush_action(flip_editdata(e, SYMM_Y));
if(symm & SYMM_Z)
- do_brush_action(vertexcosnos, flip_editdata(e, SYMM_Z), damaged_verts, damaged_rects);
+ do_brush_action(flip_editdata(e, SYMM_Z));
if(symm & SYMM_X && symm & SYMM_Y)
- do_brush_action(vertexcosnos, flip_editdata(e, SYMM_X | SYMM_Y), damaged_verts, damaged_rects);
+ do_brush_action(flip_editdata(e, SYMM_X | SYMM_Y));
if(symm & SYMM_X && symm & SYMM_Z)
- do_brush_action(vertexcosnos, flip_editdata(e, SYMM_X | SYMM_Z), damaged_verts, damaged_rects);
+ do_brush_action(flip_editdata(e, SYMM_X | SYMM_Z));
if(symm & SYMM_Y && symm & SYMM_Z)
- do_brush_action(vertexcosnos, flip_editdata(e, SYMM_Y | SYMM_Z), damaged_verts, damaged_rects);
+ do_brush_action(flip_editdata(e, SYMM_Y | SYMM_Z));
if(symm & SYMM_X && symm & SYMM_Y && symm & SYMM_Z)
- do_brush_action(vertexcosnos, flip_editdata(e, SYMM_X | SYMM_Y | SYMM_Z), damaged_verts, damaged_rects);
+ do_brush_action(flip_editdata(e, SYMM_X | SYMM_Y | SYMM_Z));
}
void add_face_normal(vec3f *norm, const MFace* face)
@@ -1165,12 +1167,15 @@ void sculptmode_update_tex()
}
}
-void init_editdata(SculptData *sd, EditData *e, short *mouse, short *pr_mouse, const char flip)
+/* pr_mouse is only used for the grab brush, can be NULL otherwise */
+void init_editdata(EditData *e, short *mouse, short *pr_mouse)
{
+ SculptData *sd = sculpt_data();
const float mouse_depth= get_depth(mouse[0],mouse[1]);
vec3f brush_edge_loc, zero_loc, oldloc;
ModifierData *md;
int i;
+ const char flip = (get_qual() == LR_SHIFTKEY);
e->flip= flip;
@@ -1182,6 +1187,10 @@ void init_editdata(SculptData *sd, EditData *e, short *mouse, short *pr_mouse, c
mouse_depth);
e->size= VecLenf(&e->center.x,&brush_edge_loc.x);
+ /* Set the pivot to allow the model to rotate around the center of the brush */
+ if(get_depth(mouse[0],mouse[1]) < 1.0)
+ sculpt_session()->pivot= e->center;
+
/* Now project the Up, Right, and Out normals from view to model coords */
zero_loc= unproject(0, 0, 0);
e->up= unproject(0, -1, 0);
@@ -1239,7 +1248,6 @@ void init_editdata(SculptData *sd, EditData *e, short *mouse, short *pr_mouse, c
}
}
}
-
void sculptmode_set_strength(const int delta)
{
int val = sculptmode_brush()->strength + delta;
@@ -1625,9 +1633,6 @@ void sculpt(void)
SculptSession *ss= sculpt_session();
Object *ob= OBACT;
short mouse[2], mvalo[2], firsttime=1, mousebut;
- ListBase damaged_verts= {0,0};
- ListBase damaged_rects= {0,0};
- float *vertexcosnos= 0;
short modifier_calculations= 0;
EditData e;
RectNode *rn= NULL;
@@ -1649,6 +1654,13 @@ void sculpt(void)
ss= sd->session;
}
+ if(sd->flags & SCULPT_INPUT_SMOOTH)
+ sculpt_stroke_new(256);
+
+ ss->damaged_rects.first = ss->damaged_rects.last = NULL;
+ ss->damaged_verts.first = ss->damaged_verts.last = NULL;
+ ss->vertexcosnos = NULL;
+
/* Check that vertex users are up-to-date */
if(ob != active_ob || ss->vertex_users_size != get_mesh(ob)->totvert) {
sculptmode_free_vertexusers(ss);
@@ -1686,8 +1698,8 @@ void sculpt(void)
init_sculptmatrices();
if(modifier_calculations)
- vertexcosnos= mesh_get_mapped_verts_nors(ob);
- sculptmode_update_all_projverts(vertexcosnos);
+ ss->vertexcosnos= mesh_get_mapped_verts_nors(ob);
+ sculptmode_update_all_projverts(ss->vertexcosnos);
e.grabdata= NULL;
e.layer_disps= NULL;
@@ -1708,56 +1720,43 @@ void sculpt(void)
if(firsttime || mouse[0]!=mvalo[0] || mouse[1]!=mvalo[1] || sculptmode_brush()->airbrush) {
firsttime= 0;
+ if(sd->flags & SCULPT_INPUT_SMOOTH)
+ sculpt_stroke_add_point(mouse[0], mouse[1]);
+
spacing+= sqrt(pow(mvalo[0]-mouse[0],2)+pow(mvalo[1]-mouse[1],2));
- if(modifier_calculations && !vertexcosnos)
- vertexcosnos= mesh_get_mapped_verts_nors(ob);
-
- if(G.scene->sculptdata.brush_type != GRAB_BRUSH && (sd->spacing==0 || spacing>sd->spacing)) {
- char i;
- float t= G.scene->sculptdata.averaging-1;
- const float sub= 1/(t+1);
- t/= (t+1);
- for(i=0; i<G.scene->sculptdata.averaging; ++i) {
- short avgco[2]= {mvalo[0]*t+mouse[0]*(1-t),
- mvalo[1]*t+mouse[1]*(1-t)};
-
- init_editdata(&G.scene->sculptdata,&e,avgco,mvalo,get_qual()==LR_SHIFTKEY);
-
- if(get_depth(mouse[0],mouse[1]) < 1.0)
- ss->pivot= e.center;
-
- /* The brush always has at least one area it affects,
- right beneath the mouse. It can have up to seven
- other areas that must also be modified, if all three
- axes of symmetry are on. */
- do_symmetrical_brush_actions(vertexcosnos,&e,&damaged_verts,&damaged_rects);
+ if(modifier_calculations && !ss->vertexcosnos)
+ ss->vertexcosnos= mesh_get_mapped_verts_nors(ob);
- t-= sub;
+ if(G.scene->sculptdata.brush_type != GRAB_BRUSH) {
+ if(sd->flags & SCULPT_INPUT_SMOOTH) {
+ sculpt_stroke_apply(&e);
+ }
+ else if(sd->spacing==0 || spacing>sd->spacing) {
+ do_symmetrical_brush_actions(&e, mouse, NULL);
+ spacing= 0;
}
- spacing= 0;
}
- else if(sd->brush_type==GRAB_BRUSH) {
- init_editdata(&G.scene->sculptdata,&e,mouse,mvalo,0);
+ else {
+ do_symmetrical_brush_actions(&e, mouse, mvalo);
ss->pivot= unproject(mouse[0],mouse[1],e.grabdata->depth);
- do_symmetrical_brush_actions(vertexcosnos,&e,&damaged_verts,&damaged_rects);
}
-
+
if(modifier_calculations || ob_get_keyblock(ob))
DAG_object_flush_update(G.scene, ob, OB_RECALC_DATA);
if(modifier_calculations || sd->brush_type == GRAB_BRUSH || !(sd->draw_flag & SCULPTDRAW_FAST)) {
- calc_damaged_verts(&damaged_verts,e.grabdata);
+ calc_damaged_verts(&ss->damaged_verts,e.grabdata);
scrarea_do_windraw(curarea);
screen_swapbuffers();
} else { /* Optimized drawing */
- calc_damaged_verts(&damaged_verts,e.grabdata);
+ calc_damaged_verts(&ss->damaged_verts,e.grabdata);
/* Draw the stored image to the screen */
glAccum(GL_RETURN, 1);
/* Clear each of the area(s) modified by the brush */
- for(rn=damaged_rects.first; rn; rn= rn->next) {
+ for(rn=ss->damaged_rects.first; rn; rn= rn->next) {
float col[3];
rcti clp= rn->r;
rcti *win= &curarea->winrct;
@@ -1798,20 +1797,26 @@ void sculpt(void)
myswapbuffers();
}
- BLI_freelistN(&damaged_rects);
+ BLI_freelistN(&ss->damaged_rects);
mvalo[0]= mouse[0];
mvalo[1]= mouse[1];
- if(vertexcosnos) {
- MEM_freeN(vertexcosnos);
- vertexcosnos= NULL;
+ if(ss->vertexcosnos) {
+ MEM_freeN(ss->vertexcosnos);
+ ss->vertexcosnos= NULL;
}
}
else BIF_wait_for_statechange();
}
+ if(sd->flags & SCULPT_INPUT_SMOOTH) {
+ sculpt_stroke_apply_all(&e);
+ calc_damaged_verts(&ss->damaged_verts,e.grabdata);
+ BLI_freelistN(&ss->damaged_rects);
+ }
+
if(projverts) MEM_freeN(projverts);
projverts= NULL;
if(e.layer_disps) MEM_freeN(e.layer_disps);
@@ -1823,6 +1828,7 @@ void sculpt(void)
BLI_freelistN(&e.grabdata->active_verts[i]);
MEM_freeN(e.grabdata);
}
+ sculpt_stroke_free();
switch(G.scene->sculptdata.brush_type) {
case DRAW_BRUSH: