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
path: root/source
diff options
context:
space:
mode:
authorNicholas Bishop <nicholasbishop@gmail.com>2008-01-25 07:17:38 +0300
committerNicholas Bishop <nicholasbishop@gmail.com>2008-01-25 07:17:38 +0300
commit7d157e2cd065080ab7e81b0e0d5f94a87c5c8f75 (patch)
treea427a80aafa1a73a1ed10d7be214ed7b3a55f0db /source
parent0252ad5d26452fa2d015e36e7a4a7d6892563e2e (diff)
== Sculpt ==
Cleaned up some old parts of sculpt. Got rid of the old EditData struct in favor of two new "brush action" structures, which split the symmetry data out from everything else. Cleaned up various names and such as well. There should be no user-visible changes.
Diffstat (limited to 'source')
-rw-r--r--source/blender/include/BDR_sculptmode.h8
-rw-r--r--source/blender/src/sculptmode-stroke.c12
-rw-r--r--source/blender/src/sculptmode.c441
3 files changed, 224 insertions, 237 deletions
diff --git a/source/blender/include/BDR_sculptmode.h b/source/blender/include/BDR_sculptmode.h
index 8b0b65be4de..e36b8674612 100644
--- a/source/blender/include/BDR_sculptmode.h
+++ b/source/blender/include/BDR_sculptmode.h
@@ -35,8 +35,8 @@
#include "BKE_sculpt.h"
struct uiBlock;
+struct BrushAction;
struct BrushData;
-struct EditData;
struct IndexNode;
struct KeyBlock;
struct Mesh;
@@ -65,7 +65,7 @@ void sculpt_stroke_draw();
void sculpt_radialcontrol_start(int mode);
struct BrushData *sculptmode_brush(void);
-void do_symmetrical_brush_actions(struct EditData *e, short *, short *);
+void do_symmetrical_brush_actions(struct BrushAction *a, short *, short *);
void sculptmode_update_tex(void);
char sculpt_modifiers_active(struct Object *ob);
@@ -76,8 +76,8 @@ void set_sculptmode(void);
void sculpt_stroke_new(const int max);
void sculpt_stroke_free();
void sculpt_stroke_add_point(const short x, const short y);
-void sculpt_stroke_apply(struct EditData *);
-void sculpt_stroke_apply_all(struct EditData *e);
+void sculpt_stroke_apply(struct BrushAction *);
+void sculpt_stroke_apply_all(struct BrushAction *);
void sculpt_stroke_draw();
diff --git a/source/blender/src/sculptmode-stroke.c b/source/blender/src/sculptmode-stroke.c
index c2c96b04a1d..69c20eeeddf 100644
--- a/source/blender/src/sculptmode-stroke.c
+++ b/source/blender/src/sculptmode-stroke.c
@@ -178,7 +178,7 @@ float sculpt_stroke_final_length(SculptStroke *stroke)
}
/* If partial is nonzero, cuts off apply after that length has been processed */
-static StrokePoint *sculpt_stroke_apply_generic(SculptStroke *stroke, struct EditData *e, const int partial)
+static StrokePoint *sculpt_stroke_apply_generic(SculptStroke *stroke, struct BrushAction *a, const int partial)
{
const int sdspace = sculpt_data()->spacing;
const short spacing = sdspace > 0 ? sdspace : 2;
@@ -215,13 +215,13 @@ static StrokePoint *sculpt_stroke_apply_generic(SculptStroke *stroke, struct Edi
co[0] = p->x*v + p->next->x*u;
co[1] = p->y*v + p->next->y*u;
- do_symmetrical_brush_actions(e, co, NULL);
+ do_symmetrical_brush_actions(a, co, NULL);
}
return p ? p->next : NULL;
}
-void sculpt_stroke_apply(struct EditData *e)
+void sculpt_stroke_apply(struct BrushAction *a)
{
SculptStroke *stroke = sculpt_session()->stroke;
/* TODO: make these values user-modifiable? */
@@ -232,7 +232,7 @@ void sculpt_stroke_apply(struct EditData *e)
sculpt_stroke_create_final();
if(sculpt_stroke_final_length(stroke) > min_len) {
- StrokePoint *p = sculpt_stroke_apply_generic(stroke, e, partial_len);
+ StrokePoint *p = sculpt_stroke_apply_generic(stroke, a, partial_len);
/* Replace remaining values in stroke->loc with remaining stroke->final values */
stroke->index = -1;
@@ -249,14 +249,14 @@ void sculpt_stroke_apply(struct EditData *e)
}
}
-void sculpt_stroke_apply_all(struct EditData *e)
+void sculpt_stroke_apply_all(struct BrushAction *a)
{
SculptStroke *stroke = sculpt_session()->stroke;
sculpt_stroke_create_final();
if(stroke) {
- sculpt_stroke_apply_generic(stroke, e, 0);
+ sculpt_stroke_apply_generic(stroke, a, 0);
}
}
diff --git a/source/blender/src/sculptmode.c b/source/blender/src/sculptmode.c
index 9e1fa16a44c..dbefadb2646 100644
--- a/source/blender/src/sculptmode.c
+++ b/source/blender/src/sculptmode.c
@@ -125,36 +125,39 @@ typedef struct ActiveData {
float dist;
} ActiveData;
-typedef struct GrabData {
- char firsttime;
- ListBase active_verts[8];
- unsigned char index;
- vec3f delta, delta_symm;
- float depth;
-} GrabData;
+typedef struct BrushActionSymm {
+ float center_3d[3];
+ char index;
-typedef struct EditData {
- vec3f center;
- float size;
- char flip;
- short mouse[2];
+ float up[3], right[3], out[3];
- /* Adjust brush strength along each axis
- to adjust for object scaling */
- float scale[3];
+ // Grab brush
+ float grab_delta[3];
+} BrushActionSymm;
- /* View normals */
- vec3f up, right, out;
+typedef struct BrushAction {
+ BrushActionSymm symm;
+
+ char firsttime;
+
+ short mouse[2];
+ float size_3d;
- GrabData *grabdata;
float *layer_disps;
vec3f *layer_store;
-
+ char flip;
+
char clip[3];
float cliptol[3];
-
- char symm;
-} EditData;
+
+ // Grab brush
+ ListBase grab_active_verts[8];
+ float depth;
+
+ /* Adjust brush strength along each axis
+ to adjust for object scaling */
+ float scale[3];
+} BrushAction;
typedef struct RectNode {
struct RectNode *next, *prev;
@@ -178,7 +181,7 @@ SculptData *sculpt_data(void)
}
void sculpt_init_session(void);
-void init_editdata(EditData *e, short *, short *);
+void init_brushaction(BrushAction *a, short *, short *);
void sculpt_undo_push(const short);
SculptSession *sculpt_session(void)
@@ -294,18 +297,16 @@ float get_depth(short x, short y)
/* Uses window coordinates (x,y) and depth component z to find a point in
modelspace */
-vec3f unproject(const short x, const short y, const float z)
+void unproject(float out[3], const short x, const short y, const float z)
{
SculptSession *ss= sculpt_session();
double ux, uy, uz;
- vec3f p;
gluUnProject(x,y,z, ss->mats->modelview, ss->mats->projection,
(GLint *)ss->mats->viewport, &ux, &uy, &uz );
- p.x= ux;
- p.y= uy;
- p.z= uz;
- return p;
+ out[0] = ux;
+ out[1] = uy;
+ out[2] = uz;
}
/* Convert a point in model coordinates to 2D screen coordinates. */
@@ -348,13 +349,13 @@ char brush_size()
/* Return modified brush strength. Includes the direction of the brush, positive
values pull vertices, negative values push. Uses tablet pressure and a
special multiplier found experimentally to scale the strength factor. */
-float brush_strength(EditData *e)
+float brush_strength(BrushAction *a)
{
const BrushData* b= sculptmode_brush();
float dir= b->dir==1 ? 1 : -1;
float pressure= 1;
short activedevice= get_activedevice();
- float flip= e->flip ? -1:1;
+ float flip= a->flip ? -1:1;
const float strength_factor= G.scene->sculptdata.tablet_strength / 10.0f;
if(ELEM(activedevice, DEV_STYLUS, DEV_ERASER))
@@ -385,11 +386,11 @@ float brush_strength(EditData *e)
}
/* For clipping against a mirror modifier */
-void sculpt_clip(const EditData *e, float *co, const float val[3])
+void sculpt_clip(const BrushAction *a, float *co, const float val[3])
{
char i;
for(i=0; i<3; ++i) {
- if(e->clip[i] && (fabs(co[i]) <= e->cliptol[i]))
+ if(a->clip[i] && (fabs(co[i]) <= a->cliptol[i]))
co[i]= 0.0f;
else
co[i]= val[i];
@@ -398,7 +399,7 @@ void sculpt_clip(const EditData *e, float *co, const float val[3])
/* Currently only for the draw brush; finds average normal for all active
vertices */
-vec3f calc_area_normal(const vec3f *outdir, const ListBase* active_verts)
+vec3f calc_area_normal(const float *outdir, const ListBase* active_verts)
{
Mesh *me= get_mesh(OBACT);
vec3f area_normal= {0,0,0};
@@ -412,28 +413,30 @@ vec3f calc_area_normal(const vec3f *outdir, const ListBase* active_verts)
node= node->next;
}
Normalize(&area_normal.x);
+
if(outdir) {
- area_normal.x= outdir->x * view + area_normal.x * (10-view);
- area_normal.y= outdir->y * view + area_normal.y * (10-view);
- area_normal.z= outdir->z * view + area_normal.z * (10-view);
+ area_normal.x= outdir[0] * view + area_normal.x * (10-view);
+ area_normal.y= outdir[1] * view + area_normal.y * (10-view);
+ area_normal.z= outdir[2] * view + area_normal.z * (10-view);
}
+
Normalize(&area_normal.x);
return area_normal;
}
-void do_draw_brush(const EditData *e, const ListBase* active_verts)
+void do_draw_brush(const BrushAction *a, const ListBase* active_verts)
{
Mesh *me= get_mesh(OBACT);
- const vec3f area_normal= calc_area_normal(&e->out, active_verts);
+ const vec3f area_normal= calc_area_normal(a->symm.out, active_verts);
ActiveData *node= active_verts->first;
while(node){
float *co= me->mvert[node->Index].co;
- const float val[3]= {co[0]+area_normal.x*node->Fade*e->scale[0],
- co[1]+area_normal.y*node->Fade*e->scale[1],
- co[2]+area_normal.z*node->Fade*e->scale[2]};
+ const float val[3]= {co[0]+area_normal.x*node->Fade*a->scale[0],
+ co[1]+area_normal.y*node->Fade*a->scale[1],
+ co[2]+area_normal.z*node->Fade*a->scale[2]};
- sculpt_clip(e, co, val);
+ sculpt_clip(a, co, val);
node= node->next;
}
@@ -489,7 +492,7 @@ vec3f neighbor_average(const int vert)
return avg;
}
-void do_smooth_brush(const EditData *e, const ListBase* active_verts)
+void do_smooth_brush(const BrushAction *a, const ListBase* active_verts)
{
ActiveData *node= active_verts->first;
Mesh *me= get_mesh(OBACT);
@@ -500,53 +503,53 @@ void do_smooth_brush(const EditData *e, const ListBase* active_verts)
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(e, co, val);
+ sculpt_clip(a, co, val);
node= node->next;
}
}
-void do_pinch_brush(const EditData *e, const ListBase* active_verts)
+void do_pinch_brush(const BrushAction *a, const ListBase* active_verts)
{
Mesh *me= get_mesh(OBACT);
ActiveData *node= active_verts->first;
while(node) {
float *co= me->mvert[node->Index].co;
- const float val[3]= {co[0]+(e->center.x-co[0])*node->Fade,
- co[1]+(e->center.y-co[1])*node->Fade,
- co[2]+(e->center.z-co[2])*node->Fade};
- sculpt_clip(e, co, val);
+ 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);
node= node->next;
}
}
-void do_grab_brush(EditData *e)
+void do_grab_brush(BrushAction *a)
{
Mesh *me= get_mesh(OBACT);
- ActiveData *node= e->grabdata->active_verts[e->grabdata->index].first;
+ ActiveData *node= a->grab_active_verts[a->symm.index].first;
float add[3];
while(node) {
float *co= me->mvert[node->Index].co;
- VecCopyf(add, &e->grabdata->delta_symm.x);
+ VecCopyf(add, a->symm.grab_delta);
VecMulf(add, node->Fade);
VecAddf(add, add, co);
- sculpt_clip(e, co, add);
+ sculpt_clip(a, co, add);
node= node->next;
}
}
-void do_layer_brush(EditData *e, const ListBase *active_verts)
+void do_layer_brush(BrushAction *a, const ListBase *active_verts)
{
Mesh *me= get_mesh(OBACT);
vec3f area_normal= calc_area_normal(NULL, active_verts);
ActiveData *node= active_verts->first;
- const float bstr= brush_strength(e);
+ const float bstr= brush_strength(a);
while(node){
- float *disp= &e->layer_disps[node->Index];
+ float *disp= &a->layer_disps[node->Index];
if((bstr > 0 && *disp < bstr) ||
(bstr < 0 && *disp > bstr)) {
@@ -563,10 +566,10 @@ void do_layer_brush(EditData *e, const ListBase *active_verts)
}
{
- const float val[3]= {e->layer_store[node->Index].x+area_normal.x * *disp*e->scale[0],
- e->layer_store[node->Index].y+area_normal.y * *disp*e->scale[1],
- e->layer_store[node->Index].z+area_normal.z * *disp*e->scale[2]};
- sculpt_clip(e, co, val);
+ const float val[3]= {a->layer_store[node->Index].x+area_normal.x * *disp*a->scale[0],
+ a->layer_store[node->Index].y+area_normal.y * *disp*a->scale[1],
+ a->layer_store[node->Index].z+area_normal.z * *disp*a->scale[2]};
+ sculpt_clip(a, co, val);
}
}
@@ -574,7 +577,7 @@ void do_layer_brush(EditData *e, const ListBase *active_verts)
}
}
-void do_inflate_brush(const EditData *e, const ListBase *active_verts)
+void do_inflate_brush(const BrushAction *a, const ListBase *active_verts)
{
ActiveData *node= active_verts->first;
float add[3];
@@ -588,18 +591,18 @@ void do_inflate_brush(const EditData *e, const ListBase *active_verts)
add[1]= no[1]/ 32767.0f;
add[2]= no[2]/ 32767.0f;
VecMulf(add, node->Fade);
- add[0]*= e->scale[0];
- add[1]*= e->scale[1];
- add[2]*= e->scale[2];
+ add[0]*= a->scale[0];
+ add[1]*= a->scale[1];
+ add[2]*= a->scale[2];
VecAddf(add, add, co);
- sculpt_clip(e, co, add);
+ sculpt_clip(a, co, add);
node= node->next;
}
}
-void calc_flatten_center(Mesh *me, ActiveData *node, const EditData *e, float co[3])
+void calc_flatten_center(Mesh *me, ActiveData *node, float co[3])
{
ActiveData *outer[FLATTEN_SAMPLE_SIZE];
int i;
@@ -622,15 +625,15 @@ void calc_flatten_center(Mesh *me, ActiveData *node, const EditData *e, float co
VecMulf(co, 1.0f / FLATTEN_SAMPLE_SIZE);
}
-void do_flatten_brush(const EditData *e, const ListBase *active_verts)
+void do_flatten_brush(const BrushAction *a, const ListBase *active_verts)
{
Mesh *me= get_mesh(OBACT);
ActiveData *node= active_verts->first;
/* area_normal and cntr define the plane towards which vertices are squashed */
- vec3f area_normal= calc_area_normal(&e->out, active_verts);
+ vec3f area_normal= calc_area_normal(a->symm.out, active_verts);
float cntr[3];
- calc_flatten_center(me, node, e, cntr);
+ calc_flatten_center(me, node, cntr);
while(node){
float *co= me->mvert[node->Index].co;
@@ -648,7 +651,7 @@ void do_flatten_brush(const EditData *e, const ListBase *active_verts)
VecMulf(val, node->Fade);
VecAddf(val, val, co);
- sculpt_clip(e, co, val);
+ sculpt_clip(a, co, val);
node= node->next;
}
@@ -709,7 +712,7 @@ unsigned *get_texcache_pixel(const SculptSession *ss, int px, int py)
}
/* Return a multiplier for brush strength on a particular vertex. */
-float tex_strength(EditData *e, float *point, const float len,const unsigned vindex)
+float tex_strength(BrushAction *a, float *point, const float len,const unsigned vindex)
{
SculptData *sd= sculpt_data();
SculptSession *ss= sculpt_session();
@@ -747,12 +750,12 @@ float tex_strength(EditData *e, float *point, const float len,const unsigned vin
/* If the active area is being applied for symmetry, flip it
across the symmetry axis in order to project it. This insures
that the brush texture will be oriented correctly. */
- if(!e->symm)
+ if(!a->symm.index)
pv= ss->projverts[vindex];
else {
float co[3];
VecCopyf(co, point);
- flip_coord(co, e->symm);
+ flip_coord(co, a->symm.index);
project(co, pv.co);
}
@@ -781,15 +784,15 @@ float tex_strength(EditData *e, float *point, const float len,const unsigned vin
py %= sy-1;
p= get_texcache_pixel(ss, tcw*px/sx, tch*py/sy);
} else {
- float fx= (pv.co[0] - e->mouse[0] + half) * (tcw*1.0f/bsize) - tcw/2;
- float fy= (pv.co[1] - e->mouse[1] + half) * (tch*1.0f/bsize) - tch/2;
-
+ float fx= (pv.co[0] - a->mouse[0] + half) * (tcw*1.0f/bsize) - tcw/2;
+ float fy= (pv.co[1] - a->mouse[1] + half) * (tch*1.0f/bsize) - tch/2;
+
float angle= atan2(fy, fx) - rot;
float len= sqrtf(fx*fx + fy*fy);
px= tcw/2 + len * cos(angle);
py= tch/2 + len * sin(angle);
-
+
p= get_texcache_pixel(ss, px, py);
}
@@ -801,7 +804,7 @@ float tex_strength(EditData *e, float *point, const float len,const unsigned vin
}
if(sd->texfade)
- avg*= curve_strength(len,e->size); /* Smooth curve */
+ avg*= curve_strength(len, a->size_3d); /* Smooth curve */
return avg;
}
@@ -809,7 +812,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 sculpt_add_damaged_rect(EditData *e)
+void sculpt_add_damaged_rect(BrushAction *a)
{
short p[2];
const float radius= brush_size();
@@ -819,7 +822,7 @@ void sculpt_add_damaged_rect(EditData *e)
unsigned i;
/* Find center */
- project(&e->center.x, p);
+ project(a->symm.center_3d, p);
rn->r.xmin= p[0]-radius;
rn->r.ymin= p[1]-radius;
rn->r.xmax= p[0]+radius;
@@ -868,7 +871,7 @@ void sculpt_clear_damaged_areas(SculptSession *ss)
}
}
-void do_brush_action(EditData e)
+void do_brush_action(BrushAction *a)
{
int i;
float av_dist;
@@ -876,29 +879,32 @@ void do_brush_action(EditData e)
ActiveData *adata= 0;
float *vert;
Mesh *me= get_mesh(OBACT);
- const float bstrength= brush_strength(&e);
+ const float bstrength= brush_strength(a);
KeyBlock *keyblock= ob_get_keyblock(OBACT);
+ SculptData *sd = sculpt_data();
SculptSession *ss = sculpt_session();
- sculpt_add_damaged_rect(&e);
+ sculpt_add_damaged_rect(a);
/* Build a list of all vertices that are potentially within the brush's
area of influence. Only do this once for the grab brush. */
- if(!e.grabdata || (e.grabdata && e.grabdata->firsttime)) {
+ if((sd->brush_type != GRAB_BRUSH) || a->firsttime) {
for(i=0; i<me->totvert; ++i) {
/* Projverts.inside provides a rough bounding box */
if(ss->projverts[i].inside) {
vert= ss->vertexcosnos ? &ss->vertexcosnos[i*6] : me->mvert[i].co;
- av_dist= VecLenf(&e.center.x,vert);
- if(av_dist < e.size) {
+ av_dist= VecLenf(a->symm.center_3d, vert);
+ if(av_dist < a->size_3d) {
adata= (ActiveData*)MEM_mallocN(sizeof(ActiveData), "ActiveData");
+
adata->Index = i;
/* Fade is used to store the final strength at which the brush
should modify a particular vertex. */
- adata->Fade= tex_strength(&e,vert,av_dist,i) * bstrength;
+ adata->Fade= tex_strength(a, vert, av_dist, i) * bstrength;
adata->dist = av_dist;
- if(e.grabdata && e.grabdata->firsttime)
- BLI_addtail(&e.grabdata->active_verts[e.grabdata->index], adata);
+
+ if(sd->brush_type == GRAB_BRUSH && a->firsttime)
+ BLI_addtail(&a->grab_active_verts[a->symm.index], adata);
else
BLI_addtail(&active_verts, adata);
}
@@ -907,29 +913,29 @@ void do_brush_action(EditData e)
}
/* Only act if some verts are inside the brush area */
- if(active_verts.first || (e.grabdata && e.grabdata->active_verts[e.grabdata->index].first)) {
+ if(active_verts.first || (sd->brush_type == GRAB_BRUSH && a->grab_active_verts[a->symm.index].first)) {
/* Apply one type of brush action */
switch(G.scene->sculptdata.brush_type){
case DRAW_BRUSH:
- do_draw_brush(&e, &active_verts);
+ do_draw_brush(a, &active_verts);
break;
case SMOOTH_BRUSH:
- do_smooth_brush(&e, &active_verts);
+ do_smooth_brush(a, &active_verts);
break;
case PINCH_BRUSH:
- do_pinch_brush(&e, &active_verts);
+ do_pinch_brush(a, &active_verts);
break;
case INFLATE_BRUSH:
- do_inflate_brush(&e, &active_verts);
+ do_inflate_brush(a, &active_verts);
break;
case GRAB_BRUSH:
- do_grab_brush(&e);
+ do_grab_brush(a);
break;
case LAYER_BRUSH:
- do_layer_brush(&e, &active_verts);
+ do_layer_brush(a, &active_verts);
break;
case FLATTEN_BRUSH:
- do_flatten_brush(&e, &active_verts);
+ do_flatten_brush(a, &active_verts);
break;
}
@@ -937,7 +943,11 @@ void do_brush_action(EditData e)
if(keyblock) {
float *co= keyblock->data;
if(co) {
- adata = e.grabdata ? e.grabdata->active_verts[e.grabdata->index].first : active_verts.first;
+ if(sd->brush_type == GRAB_BRUSH)
+ adata = a->grab_active_verts[a->symm.index].first;
+ else
+ adata = active_verts.first;
+
for(; adata; adata= adata->next)
if(adata->Index < keyblock->totelem)
VecCopyf(&co[adata->Index*3], me->mvert[adata->Index].co);
@@ -947,7 +957,7 @@ void do_brush_action(EditData e)
if(ss->vertexcosnos)
BLI_freelistN(&active_verts);
else {
- if(!e.grabdata)
+ if(sd->brush_type != GRAB_BRUSH)
addlisttolist(&ss->damaged_verts, &active_verts);
}
}
@@ -955,51 +965,37 @@ void do_brush_action(EditData e)
/* Flip all the editdata across the axis/axes specified by symm. Used to
calculate multiple modifications to the mesh when symmetry is enabled. */
-EditData flip_editdata(EditData *e, const char symm)
+void calc_brushdata_symm(BrushAction *a, const char symm)
{
- EditData fe= *e;
- GrabData *gd= fe.grabdata;
-
- flip_coord(&fe.center.x, symm);
- flip_coord(&fe.up.x, symm);
- flip_coord(&fe.right.x, symm);
- flip_coord(&fe.out.x, symm);
+ flip_coord(a->symm.center_3d, symm);
+ flip_coord(a->symm.up, symm);
+ flip_coord(a->symm.right, symm);
+ flip_coord(a->symm.out, symm);
- fe.symm= symm;
-
- project(&e->center.x,fe.mouse);
-
- if(gd) {
- gd->index= symm;
- gd->delta_symm= gd->delta;
- flip_coord(&gd->delta_symm.x, symm);
- }
+ a->symm.index= symm;
- return fe;
+ flip_coord(a->symm.grab_delta, symm);
}
-void do_symmetrical_brush_actions(EditData * e, short co[2], short pr_co[2])
+void do_symmetrical_brush_actions(BrushAction *a, short co[2], short pr_co[2])
{
- const char symm= sculpt_data()->symm;
+ const char symm = sculpt_data()->symm;
+ BrushActionSymm orig;
+ int i;
- init_editdata(e, co, pr_co);
-
- do_brush_action(flip_editdata(e, 0));
+ init_brushaction(a, co, pr_co);
+ orig = a->symm;
+ do_brush_action(a);
- if(symm & SYMM_X)
- do_brush_action(flip_editdata(e, SYMM_X));
- if(symm & SYMM_Y)
- do_brush_action(flip_editdata(e, SYMM_Y));
- if(symm & SYMM_Z)
- do_brush_action(flip_editdata(e, SYMM_Z));
- if(symm & SYMM_X && symm & SYMM_Y)
- do_brush_action(flip_editdata(e, SYMM_X | SYMM_Y));
- if(symm & SYMM_X && symm & SYMM_Z)
- do_brush_action(flip_editdata(e, SYMM_X | SYMM_Z));
- if(symm & SYMM_Y && symm & SYMM_Z)
- do_brush_action(flip_editdata(e, SYMM_Y | SYMM_Z));
- if(symm & SYMM_X && symm & SYMM_Y && symm & SYMM_Z)
- do_brush_action(flip_editdata(e, SYMM_X | SYMM_Y | SYMM_Z));
+ for(i = 1; i <= symm; ++i) {
+ if(symm & i && (symm != 5 || i != 3) && (symm != 6 || (i != 3 && i != 5))) {
+ // Restore the original symmetry data
+ a->symm = orig;
+
+ calc_brushdata_symm(a, i);
+ do_brush_action(a);
+ }
+ }
}
void add_face_normal(vec3f *norm, const MFace* face)
@@ -1039,19 +1035,17 @@ void update_damaged_vert(Mesh *me, ListBase *lb)
}
}
-void calc_damaged_verts(ListBase *damaged_verts, GrabData *grabdata)
+void calc_damaged_verts(ListBase *damaged_verts, BrushAction *a)
{
Mesh *me= get_mesh(OBACT);
+ int i;
+
+ for(i=0; i<8; ++i)
+ update_damaged_vert(me, &a->grab_active_verts[i]);
- if(grabdata) {
- int i;
- for(i=0; i<8; ++i)
- update_damaged_vert(me,&grabdata->active_verts[i]);
- } else {
- update_damaged_vert(me,damaged_verts);
- BLI_freelistN(damaged_verts);
- damaged_verts->first = damaged_verts->last = NULL;
- }
+ update_damaged_vert(me, damaged_verts);
+ BLI_freelistN(damaged_verts);
+ damaged_verts->first = damaged_verts->last = NULL;
}
void projverts_clear_inside(SculptSession *ss)
@@ -1137,83 +1131,80 @@ void sculptmode_update_tex()
}
/* pr_mouse is only used for the grab brush, can be NULL otherwise */
-void init_editdata(EditData *e, short *mouse, short *pr_mouse)
+void init_brushaction(BrushAction *a, 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;
+ const float mouse_depth = get_depth(mouse[0], mouse[1]);
+ float brush_edge_loc[3], zero_loc[3], oldloc[3];
ModifierData *md;
int i;
const char flip = (get_qual() == LR_SHIFTKEY);
- e->flip= flip;
+ a->flip = flip;
+ a->symm.index = 0;
+ a->mouse[0] = mouse[0];
+ a->mouse[1] = mouse[1];
/* Convert the location and size of the brush to
modelspace coords */
- e->center= unproject(mouse[0],mouse[1],mouse_depth);
- brush_edge_loc= unproject(mouse[0] +
- brush_size(),mouse[1],
- mouse_depth);
- e->size= VecLenf(&e->center.x,&brush_edge_loc.x);
+ unproject(a->symm.center_3d, mouse[0], mouse[1], mouse_depth);
+ unproject(brush_edge_loc, mouse[0] + brush_size(), mouse[1], mouse_depth);
+ a->size_3d = VecLenf(a->symm.center_3d, brush_edge_loc);
/* 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;
+ VecCopyf(&sculpt_session()->pivot.x, a->symm.center_3d);
/* 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);
- e->right= unproject(1, 0, 0);
- e->out= unproject(0, 0, -1);
- VecSubf(&e->up.x, &e->up.x, &zero_loc.x);
- VecSubf(&e->right.x, &e->right.x, &zero_loc.x);
- VecSubf(&e->out.x, &e->out.x, &zero_loc.x);
- Normalize(&e->up.x);
- Normalize(&e->right.x);
- Normalize(&e->out.x);
+ unproject(zero_loc, 0, 0, 0);
+ unproject(a->symm.up, 0, -1, 0);
+ unproject(a->symm.right, 1, 0, 0);
+ unproject(a->symm.out, 0, 0, -1);
+ VecSubf(a->symm.up, a->symm.up, zero_loc);
+ VecSubf(a->symm.right, a->symm.right, zero_loc);
+ VecSubf(a->symm.out, a->symm.out, zero_loc);
+ Normalize(a->symm.up);
+ Normalize(a->symm.right);
+ Normalize(a->symm.out);
/* Initialize mirror modifier clipping */
for(i=0; i<3; ++i) {
- e->clip[i]= 0;
- e->cliptol[i]= 0;
+ a->clip[i]= 0;
+ a->cliptol[i]= 0;
}
for(md= OBACT->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) {
- e->clip[mmd->axis]= 1;
- if(mmd->tolerance > e->cliptol[mmd->axis])
- e->cliptol[mmd->axis]= mmd->tolerance;
+ a->clip[mmd->axis]= 1;
+ if(mmd->tolerance > a->cliptol[mmd->axis])
+ a->cliptol[mmd->axis] = mmd->tolerance;
}
}
}
if(sd->brush_type == GRAB_BRUSH) {
- vec3f gcenter;
- if(!e->grabdata) {
- e->grabdata= MEM_callocN(sizeof(GrabData),"grab data");
- e->grabdata->firsttime= 1;
- e->grabdata->depth= mouse_depth;
- }
- else
- e->grabdata->firsttime= 0;
-
+ float gcenter[3];
+
+ if(a->firsttime)
+ a->depth = mouse_depth;
+
/* Find the delta */
- gcenter= unproject(mouse[0],mouse[1],e->grabdata->depth);
- oldloc= unproject(pr_mouse[0],pr_mouse[1],e->grabdata->depth);
- VecSubf(&e->grabdata->delta.x,&gcenter.x,&oldloc.x);
+ unproject(gcenter, mouse[0], mouse[1], a->depth);
+ unproject(oldloc, pr_mouse[0], pr_mouse[1], a->depth);
+ VecSubf(a->symm.grab_delta, gcenter, oldloc);
}
else if(sd->brush_type == LAYER_BRUSH) {
Mesh *me= get_mesh(OBACT);
- if(!e->layer_disps)
- e->layer_disps= MEM_callocN(sizeof(float)*me->totvert,"Layer disps");
- if(!e->layer_store) {
+ if(!a->layer_disps)
+ a->layer_disps= MEM_callocN(sizeof(float)*me->totvert,"Layer disps");
+ if(!a->layer_store) {
unsigned i;
- e->layer_store= MEM_mallocN(sizeof(vec3f)*me->totvert,"Layer store");
+ a->layer_store= MEM_mallocN(sizeof(vec3f)*me->totvert,"Layer store");
for(i=0; i<me->totvert; ++i)
- VecCopyf(&e->layer_store[i].x,me->mvert[i].co);
+ VecCopyf(&a->layer_store[i].x, me->mvert[i].co);
}
}
}
@@ -1470,11 +1461,11 @@ void sculpt(void)
/* lastSigMouse is for the rake, to store the last place the mouse movement was significant */
short mouse[2], mvalo[2], lastSigMouse[2],firsttime=1, mousebut;
short modifier_calculations= 0;
- EditData e;
+ BrushAction *a = MEM_callocN(sizeof(BrushAction), "brush action");
short spacing= 32000;
int scissor_box[4];
float offsetRot;
- int smooth_stroke = 0;
+ int smooth_stroke = 0, i;
if(!(G.f & G_SCULPTMODE) || G.obedit || !ob || ob->id.lib || !get_mesh(ob) || (get_mesh(ob)->totface == 0))
return;
@@ -1541,14 +1532,13 @@ void sculpt(void)
ss->vertexcosnos= mesh_get_mapped_verts_nors(ob);
sculptmode_update_all_projverts(ss->vertexcosnos);
- e.grabdata= NULL;
- e.layer_disps= NULL;
- e.layer_store= NULL;
+ a->layer_disps= NULL;
+ a->layer_store= NULL;
/* Set scaling adjustment */
- e.scale[0]= 1.0f / ob->size[0];
- e.scale[1]= 1.0f / ob->size[1];
- e.scale[2]= 1.0f / ob->size[2];
+ a->scale[0]= 1.0f / ob->size[0];
+ a->scale[1]= 1.0f / ob->size[1];
+ a->scale[2]= 1.0f / ob->size[2];
/* Capture original copy */
if(sd->flags & SCULPT_DRAW_FAST)
@@ -1571,6 +1561,7 @@ void sculpt(void)
}
if(firsttime || mouse[0]!=mvalo[0] || mouse[1]!=mvalo[1] || sculptmode_brush()->airbrush) {
+ a->firsttime = firsttime;
firsttime= 0;
if(smooth_stroke)
@@ -1583,27 +1574,27 @@ void sculpt(void)
if(G.scene->sculptdata.brush_type != GRAB_BRUSH) {
if(smooth_stroke) {
- sculpt_stroke_apply(&e);
+ sculpt_stroke_apply(a);
}
else if(sd->spacing==0 || spacing>sd->spacing) {
- do_symmetrical_brush_actions(&e, mouse, NULL);
+ do_symmetrical_brush_actions(a, mouse, NULL);
spacing= 0;
}
}
else {
- do_symmetrical_brush_actions(&e, mouse, mvalo);
- ss->pivot= unproject(mouse[0],mouse[1],e.grabdata->depth);
+ do_symmetrical_brush_actions(a, mouse, mvalo);
+ unproject(&ss->pivot.x, mouse[0], mouse[1], a->depth);
}
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->flags & SCULPT_DRAW_FAST)) {
- calc_damaged_verts(&ss->damaged_verts,e.grabdata);
+ calc_damaged_verts(&ss->damaged_verts, a);
scrarea_do_windraw(curarea);
screen_swapbuffers();
} else { /* Optimized drawing */
- calc_damaged_verts(&ss->damaged_verts,e.grabdata);
+ calc_damaged_verts(&ss->damaged_verts, a);
/* Draw the stored image to the screen */
glAccum(GL_RETURN, 1);
@@ -1648,20 +1639,16 @@ void sculpt(void)
set_tex_angle(offsetRot);
if(smooth_stroke) {
- sculpt_stroke_apply_all(&e);
- calc_damaged_verts(&ss->damaged_verts,e.grabdata);
+ sculpt_stroke_apply_all(a);
+ calc_damaged_verts(&ss->damaged_verts, a);
BLI_freelistN(&ss->damaged_rects);
}
- if(e.layer_disps) MEM_freeN(e.layer_disps);
- if(e.layer_store) MEM_freeN(e.layer_store);
- /* Free GrabData */
- if(e.grabdata) {
- int i;
- for(i=0; i<8; ++i)
- BLI_freelistN(&e.grabdata->active_verts[i]);
- MEM_freeN(e.grabdata);
- }
+ if(a->layer_disps) MEM_freeN(a->layer_disps);
+ if(a->layer_store) MEM_freeN(a->layer_store);
+ for(i=0; i<8; ++i)
+ BLI_freelistN(&a->grab_active_verts[i]);
+ MEM_freeN(a);
sculpt_stroke_free();
sculpt_undo_push(G.scene->sculptdata.brush_type);
@@ -1728,7 +1715,7 @@ void set_sculptmode(void)
static void sculptmode_do_pmv(Object *ob, rcti *hb_2d, int mode)
{
Mesh *me= get_mesh(ob);
- vec3f hidebox[6];
+ float hidebox[6][3];
vec3f plane_normals[4];
float plane_ds[4];
unsigned i, j;
@@ -1740,23 +1727,23 @@ static void sculptmode_do_pmv(Object *ob, rcti *hb_2d, int mode)
const unsigned SHOW= 0, HIDE=1;
/* Convert hide box from 2D to 3D */
- hidebox[0]= unproject(hb_2d->xmin, hb_2d->ymax, 1);
- hidebox[1]= unproject(hb_2d->xmax, hb_2d->ymax, 1);
- hidebox[2]= unproject(hb_2d->xmax, hb_2d->ymin, 1);
- hidebox[3]= unproject(hb_2d->xmin, hb_2d->ymin, 1);
- hidebox[4]= unproject(hb_2d->xmin, hb_2d->ymax, 0);
- hidebox[5]= unproject(hb_2d->xmax, hb_2d->ymin, 0);
+ unproject(hidebox[0], hb_2d->xmin, hb_2d->ymax, 1);
+ unproject(hidebox[1], hb_2d->xmax, hb_2d->ymax, 1);
+ unproject(hidebox[2], hb_2d->xmax, hb_2d->ymin, 1);
+ unproject(hidebox[3], hb_2d->xmin, hb_2d->ymin, 1);
+ unproject(hidebox[4], hb_2d->xmin, hb_2d->ymax, 0);
+ unproject(hidebox[5], hb_2d->xmax, hb_2d->ymin, 0);
/* Calculate normals for each side of hide box */
- CalcNormFloat(&hidebox[0].x,&hidebox[1].x,&hidebox[4].x,&plane_normals[0].x);
- CalcNormFloat(&hidebox[1].x,&hidebox[2].x,&hidebox[5].x,&plane_normals[1].x);
- CalcNormFloat(&hidebox[2].x,&hidebox[3].x,&hidebox[5].x,&plane_normals[2].x);
- CalcNormFloat(&hidebox[3].x,&hidebox[0].x,&hidebox[4].x,&plane_normals[3].x);
+ CalcNormFloat(hidebox[0], hidebox[1], hidebox[4], &plane_normals[0].x);
+ CalcNormFloat(hidebox[1], hidebox[2], hidebox[5], &plane_normals[1].x);
+ CalcNormFloat(hidebox[2], hidebox[3], hidebox[5], &plane_normals[2].x);
+ CalcNormFloat(hidebox[3], hidebox[0], hidebox[4], &plane_normals[3].x);
/* Calculate D for each side of hide box */
for(i= 0; i<4; ++i)
- plane_ds[i]= hidebox[i].x*plane_normals[i].x + hidebox[i].y*plane_normals[i].y +
- hidebox[i].z*plane_normals[i].z;
+ plane_ds[i]= hidebox[i][0]*plane_normals[i].x + hidebox[i][1]*plane_normals[i].y +
+ hidebox[i][2]*plane_normals[i].z;
/* Add partial visibility to mesh */
if(!me->pv) {