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-03-14 23:00:01 +0300
committerNicholas Bishop <nicholasbishop@gmail.com>2007-03-14 23:00:01 +0300
commita567e43628e780b5cc88f0f1aa73eb3111eab0f5 (patch)
tree552ecb9d44e5fbfe65bf48f825049b0b8f50a4ec /source/blender
parent26aa15969fd263ffe7349462f61b4bb9c023e756 (diff)
== Sculpt Mode ==
* Added new brush, "Flatten". This brush pushes vertices along the normal defined by the average normal of each vertex within the brush area. The vertices are pushed towards the plane defined by vertices towards the edge of the brush. Essentially, this means that the direction of flattening is dependent on the surface beneath the brush. * In order to make space for the flatten brush, the controls inside the Sculpt palette were widened to 268. (Note that the panel width didn't change, so it still fits properly in the vertical layout.) * Todo: it would probably make sense to make the "View" slider available under the Brush tab available for the Flatten brush (currently it's only used for the Draw brush.)
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/makesdna/DNA_scene_types.h3
-rw-r--r--source/blender/src/buttons_editing.c27
-rw-r--r--source/blender/src/header_view3d.c10
-rw-r--r--source/blender/src/sculptmode.c158
4 files changed, 139 insertions, 59 deletions
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index df99c5c531e..99f4cc10944 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -373,7 +373,7 @@ typedef struct SculptData
struct MTex *mtex[10];
/* Settings for each brush */
- BrushData drawbrush, smoothbrush, pinchbrush, inflatebrush, grabbrush, layerbrush;
+ BrushData drawbrush, smoothbrush, pinchbrush, inflatebrush, grabbrush, layerbrush, flattenbrush;
short brush_type;
/* For the Brush Shape */
@@ -605,6 +605,7 @@ typedef struct Scene {
#define INFLATE_BRUSH 4
#define GRAB_BRUSH 5
#define LAYER_BRUSH 6
+#define FLATTEN_BRUSH 7
/* SculptData.texrept */
#define SCULPTREPT_DRAG 1
#define SCULPTREPT_TILE 2
diff --git a/source/blender/src/buttons_editing.c b/source/blender/src/buttons_editing.c
index c5fdb564884..aea738c0906 100644
--- a/source/blender/src/buttons_editing.c
+++ b/source/blender/src/buttons_editing.c
@@ -4451,11 +4451,12 @@ void sculptmode_draw_interface_tools(uiBlock *block, unsigned short cx, unsigned
uiBlockBeginAlign(block);
uiDefButS(block,ROW,REDRAWBUTSEDIT,"Draw",cx,cy,67,19,&sd->brush_type,14.0,DRAW_BRUSH,0,0,"Draw lines on the model");
uiDefButS(block,ROW,REDRAWBUTSEDIT,"Smooth",cx+67,cy,67,19,&sd->brush_type,14.0,SMOOTH_BRUSH,0,0,"Interactively smooth areas of the model");
- uiDefButS(block,ROW,REDRAWBUTSEDIT,"Pinch",cx+134,cy,66,19,&sd->brush_type,14.0,PINCH_BRUSH,0,0,"Interactively pinch areas of the model");
+ uiDefButS(block,ROW,REDRAWBUTSEDIT,"Pinch",cx+134,cy,67,19,&sd->brush_type,14.0,PINCH_BRUSH,0,0,"Interactively pinch areas of the model");
+ uiDefButS(block,ROW,REDRAWBUTSEDIT,"Inflate",cx+201,cy,67,19,&sd->brush_type,14,INFLATE_BRUSH,0,0,"Push vertices along the direction of their normals");
cy-= 20;
- uiDefButS(block,ROW,REDRAWBUTSEDIT,"Inflate",cx,cy,67,19,&sd->brush_type,14,INFLATE_BRUSH,0,0,"Push vertices along the direction of their normals");
- uiDefButS(block,ROW,REDRAWBUTSEDIT,"Grab", cx+67,cy,67,19,&sd->brush_type,14,GRAB_BRUSH,0,0,"Grabs a group of vertices and moves them with the mouse");
- uiDefButS(block,ROW,REDRAWBUTSEDIT,"Layer", cx+134,cy,66,19,&sd->brush_type,14, LAYER_BRUSH,0,0,"Adds a layer of depth");
+ uiDefButS(block,ROW,REDRAWBUTSEDIT,"Grab", cx,cy,89,19,&sd->brush_type,14,GRAB_BRUSH,0,0,"Grabs a group of vertices and moves them with the mouse");
+ uiDefButS(block,ROW,REDRAWBUTSEDIT,"Layer", cx+89,cy,89,19,&sd->brush_type,14, LAYER_BRUSH,0,0,"Adds a layer of depth");
+ uiDefButS(block,ROW,REDRAWBUTSEDIT,"Flatten", cx+178,cy,90,19,&sd->brush_type,14, FLATTEN_BRUSH,0,0,"Interactively flatten areas of the model");
cy-= 25;
uiBlockEndAlign(block);
@@ -4463,17 +4464,17 @@ void sculptmode_draw_interface_tools(uiBlock *block, unsigned short cx, unsigned
uiDefBut(block,LABEL,B_NOP,"Shape",cx,cy,90,19,NULL,0,0,0,0,"");
cy-= 20;
uiBlockBeginAlign(block);
- if(sd->brush_type!=SMOOTH_BRUSH && sd->brush_type!=GRAB_BRUSH) {
- uiDefButC(block,ROW,B_NOP,"Add",cx,cy,67,19,&sculptmode_brush()->dir,15.0,1.0,0, 0,"Add depth to model [Shift]");
- uiDefButC(block,ROW,B_NOP,"Sub",cx+67,cy,67,19,&sculptmode_brush()->dir,15.0,2.0,0, 0,"Subtract depth from model [Shift]");
+ if(sd->brush_type != SMOOTH_BRUSH && sd->brush_type != GRAB_BRUSH && sd->brush_type != FLATTEN_BRUSH) {
+ uiDefButC(block,ROW,B_NOP,"Add",cx,cy,89,19,&sculptmode_brush()->dir,15.0,1.0,0, 0,"Add depth to model [Shift]");
+ uiDefButC(block,ROW,B_NOP,"Sub",cx+89,cy,89,19,&sculptmode_brush()->dir,15.0,2.0,0, 0,"Subtract depth from model [Shift]");
}
if(sd->brush_type!=GRAB_BRUSH)
- uiDefButC(block,TOG,B_NOP,"Airbrush",cx+134,cy,66,19,&sculptmode_brush()->airbrush,0,0,0,0,"Brush makes changes without waiting for the mouse to move");
+ uiDefButC(block,TOG,B_NOP,"Airbrush",cx+178,cy,89,19,&sculptmode_brush()->airbrush,0,0,0,0,"Brush makes changes without waiting for the mouse to move");
cy-= 20;
- but= uiDefButS(block,NUMSLI,B_NOP,"Size: ",cx,cy,200,19,&sculptmode_brush()->size,1.0,200.0,0,0,"Set brush radius in pixels");
+ but= uiDefButS(block,NUMSLI,B_NOP,"Size: ",cx,cy,268,19,&sculptmode_brush()->size,1.0,200.0,0,0,"Set brush radius in pixels");
cy-= 20;
if(sd->brush_type!=GRAB_BRUSH)
- uiDefButC(block,NUMSLI,B_NOP,"Strength: ",cx,cy,200,19,&sculptmode_brush()->strength,1.0,100.0,0,0,"Set brush strength");
+ uiDefButC(block,NUMSLI,B_NOP,"Strength: ",cx,cy,268,19,&sculptmode_brush()->strength,1.0,100.0,0,0,"Set brush strength");
cy-= 25;
uiBlockEndAlign(block);
@@ -4481,9 +4482,9 @@ void sculptmode_draw_interface_tools(uiBlock *block, unsigned short cx, unsigned
uiDefBut( block,LABEL,B_NOP,"Symmetry",cx,cy,90,19,NULL,0,0,0,0,"");
cy-= 20;
uiBlockBeginAlign(block);
- uiDefButBitC(block, TOG, SYMM_X, 0, "X", cx,cy,67,19, &sd->symm, 0,0,0,0, "Mirror brush across X axis");
- uiDefButBitC(block, TOG, SYMM_Y, 0, "Y", cx+67,cy,67,19, &sd->symm, 0,0,0,0, "Mirror brush across Y axis");
- uiDefButBitC(block, TOG, SYMM_Z, 0, "Z", cx+134,cy,67,19, &sd->symm, 0,0,0,0, "Mirror brush across Z axis");
+ uiDefButBitC(block, TOG, SYMM_X, 0, "X", cx,cy,89,19, &sd->symm, 0,0,0,0, "Mirror brush across X axis");
+ uiDefButBitC(block, TOG, SYMM_Y, 0, "Y", cx+89,cy,89,19, &sd->symm, 0,0,0,0, "Mirror brush across Y axis");
+ uiDefButBitC(block, TOG, SYMM_Z, 0, "Z", cx+178,cy,90,19, &sd->symm, 0,0,0,0, "Mirror brush across Z axis");
uiBlockEndAlign(block);
cx+= 210;
diff --git a/source/blender/src/header_view3d.c b/source/blender/src/header_view3d.c
index fc02b236cdf..d41359fcf43 100644
--- a/source/blender/src/header_view3d.c
+++ b/source/blender/src/header_view3d.c
@@ -4117,10 +4117,9 @@ void do_view3d_sculptmenu(void *arg, int event)
case 3:
case 4:
case 5:
+ case 6:
sd->brush_type= event+1;
break;
- case 6:
- br->dir= br->dir==1 ? 2 : 1; break;
case 7:
br->airbrush= !br->airbrush; break;
case 8:
@@ -4151,6 +4150,8 @@ void do_view3d_sculptmenu(void *arg, int event)
case 17:
sculptmode_propset_init(PropsetSize);
break;
+ case 18:
+ br->dir= br->dir==1 ? 2 : 1; break;
}
allqueue(REDRAWBUTSEDIT, 0);
@@ -4208,11 +4209,12 @@ uiBlock *view3d_sculptmenu(void *arg_unused)
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
uiDefIconTextBut(block, BUTM, 1, (br->airbrush ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT), "Airbrush|A", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
- if(sd->brush_type!=SMOOTH_BRUSH) {
- uiDefIconTextBut(block, BUTM, 1, (br->dir==1 ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT), "Add|V", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
+ if(sd->brush_type!=SMOOTH_BRUSH && sd->brush_type!=FLATTEN_BRUSH) {
+ uiDefIconTextBut(block, BUTM, 1, (br->dir==1 ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT), "Add|V", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 18, "");
}
}
uiDefBut(block, SEPR, 0, "", 0, yco-=6, menuwidth, 6, NULL, 0.0, 0.0, 0, 0, "");
+ uiDefIconTextBut(block, BUTM, 1, (sd->brush_type==FLATTEN_BRUSH ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT), "Flatten", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 6, "");
uiDefIconTextBut(block, BUTM, 1, (sd->brush_type==LAYER_BRUSH ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT), "Layer|L", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
uiDefIconTextBut(block, BUTM, 1, (sd->brush_type==GRAB_BRUSH ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT), "Grab|G", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
uiDefIconTextBut(block, BUTM, 1, (sd->brush_type==INFLATE_BRUSH ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT), "Inflate|I", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
diff --git a/source/blender/src/sculptmode.c b/source/blender/src/sculptmode.c
index 53ac5467445..ce46b631510 100644
--- a/source/blender/src/sculptmode.c
+++ b/source/blender/src/sculptmode.c
@@ -115,6 +115,7 @@ typedef struct ActiveData {
struct ActiveData *next, *prev;
unsigned int Index;
float Fade;
+ float dist;
} ActiveData;
typedef struct GrabData {
@@ -195,10 +196,17 @@ void sculptmode_init(Scene *sce)
memset(sd, 0, sizeof(SculptData));
- sd->drawbrush.size=sd->smoothbrush.size=sd->pinchbrush.size=sd->inflatebrush.size=sd->grabbrush.size=sd->layerbrush.size= 50;
- sd->drawbrush.strength=sd->smoothbrush.strength=sd->pinchbrush.strength=sd->inflatebrush.strength=sd->grabbrush.strength=sd->layerbrush.strength= 25;
- sd->drawbrush.dir=sd->pinchbrush.dir=sd->inflatebrush.dir=sd->layerbrush.dir= 1;
- sd->drawbrush.airbrush=sd->smoothbrush.airbrush=sd->pinchbrush.airbrush=sd->inflatebrush.airbrush=sd->layerbrush.airbrush= 0;
+ sd->drawbrush.size = sd->smoothbrush.size = sd->pinchbrush.size =
+ sd->inflatebrush.size = sd->grabbrush.size =
+ sd->layerbrush.size = sd->flattenbrush.size = 50;
+ sd->drawbrush.strength = sd->smoothbrush.strength =
+ sd->pinchbrush.strength = sd->inflatebrush.strength =
+ sd->grabbrush.strength = sd->layerbrush.strength =
+ sd->flattenbrush.strength = 25;
+ sd->drawbrush.dir = sd->pinchbrush.dir = sd->inflatebrush.dir = sd->layerbrush.dir= 1;
+ sd->drawbrush.airbrush = sd->smoothbrush.airbrush =
+ sd->pinchbrush.airbrush = sd->inflatebrush.airbrush =
+ sd->layerbrush.airbrush = sd->flattenbrush.airbrush = 0;
sd->drawbrush.view= 0;
sd->brush_type= DRAW_BRUSH;
sd->texact= -1;
@@ -430,6 +438,8 @@ float brush_strength(EditData *e)
return 1;
case INFLATE_BRUSH:
return b->strength / 5000.0f * dir * pressure * flip;
+ case FLATTEN_BRUSH:
+ return b->strength / 500.0f * pressure;
default:
return 0;
}
@@ -647,6 +657,62 @@ void do_inflate_brush(const EditData *e, const ListBase *active_verts)
}
}
+void calc_flatten_center(Mesh *me, ActiveData *node, const EditData *e, float co[3])
+{
+ const int FTOT = 10;
+ ActiveData *outer[FTOT];
+ int i;
+
+ for(i = 0; i < FTOT; ++i)
+ outer[i] = node;
+
+ for(; node; node = node->next) {
+ for(i = 0; i < FTOT; ++i) {
+ if(node->dist > outer[i]->dist) {
+ outer[i] = node;
+ break;
+ }
+ }
+ }
+
+ co[0] = co[1] = co[2] = 0.0f;
+ for(i = 0; i < FTOT; ++i)
+ VecAddf(co, co, me->mvert[outer[i]->Index].co);
+ VecMulf(co, 1.0f / FTOT);
+}
+
+void do_flatten_brush(const EditData *e, 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);
+ float cntr[3];
+
+ calc_flatten_center(me, node, e, cntr);
+
+ while(node){
+ float *co= me->mvert[node->Index].co;
+ float p1[3], sub1[3], sub2[3], intr[3], val[3];
+
+ /* Find the intersection between squash-plane and vertex (along the area normal) */
+ VecSubf(p1, co, &area_normal.x);
+ VecSubf(sub1, cntr, p1);
+ VecSubf(sub2, co, p1);
+ VecSubf(intr, co, p1);
+ VecMulf(intr, Inpf(&area_normal.x, sub1) / Inpf(&area_normal.x, sub2));
+ VecAddf(intr, intr, p1);
+
+ VecSubf(val, intr, co);
+ VecMulf(val, node->Fade);
+ VecAddf(val, val, co);
+
+ sculpt_clip(e, co, val);
+
+ node= node->next;
+ }
+}
+
/* Creates a smooth curve for the brush shape. This is the cos(x) curve from
[0,PI] scaled to [0,len]. The range is scaled to [0,1]. */
float simple_strength(float p, const float len)
@@ -857,6 +923,7 @@ void do_brush_action(float *vertexcosnos, EditData e,
/* 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->dist = av_dist;
if(e.grabdata && e.grabdata->firsttime)
BLI_addtail(&e.grabdata->active_verts[e.grabdata->index], adata);
else
@@ -866,44 +933,50 @@ void do_brush_action(float *vertexcosnos, EditData e,
}
}
- /* Apply one type of brush action */
- switch(G.scene->sculptdata.brush_type){
- case DRAW_BRUSH:
- do_draw_brush(&e, &active_verts);
- break;
- case SMOOTH_BRUSH:
- do_smooth_brush(&e, &active_verts);
- break;
- case PINCH_BRUSH:
- do_pinch_brush(&e, &active_verts);
- break;
- case INFLATE_BRUSH:
- do_inflate_brush(&e, &active_verts);
- break;
- case GRAB_BRUSH:
- do_grab_brush(&e);
- break;
- case LAYER_BRUSH:
- do_layer_brush(&e, &active_verts);
- break;
- }
+ /* Only act if some verts are inside the brush area */
+ if(active_verts.first || (e.grabdata && e.grabdata->active_verts[e.grabdata->index].first)) {
+ /* Apply one type of brush action */
+ switch(G.scene->sculptdata.brush_type){
+ case DRAW_BRUSH:
+ do_draw_brush(&e, &active_verts);
+ break;
+ case SMOOTH_BRUSH:
+ do_smooth_brush(&e, &active_verts);
+ break;
+ case PINCH_BRUSH:
+ do_pinch_brush(&e, &active_verts);
+ break;
+ case INFLATE_BRUSH:
+ do_inflate_brush(&e, &active_verts);
+ break;
+ case GRAB_BRUSH:
+ do_grab_brush(&e);
+ break;
+ case LAYER_BRUSH:
+ do_layer_brush(&e, &active_verts);
+ break;
+ case FLATTEN_BRUSH:
+ do_flatten_brush(&e, &active_verts);
+ break;
+ }
- /* Copy the modified vertices from mesh to the active key */
- if(keyblock) {
- float *co= keyblock->data;
- if(co) {
- adata = e.grabdata ? e.grabdata->active_verts[e.grabdata->index].first : active_verts.first;
- for(; adata; adata= adata->next)
- if(adata->Index < keyblock->totelem)
- VecCopyf(&co[adata->Index*3], me->mvert[adata->Index].co);
+ /* Copy the modified vertices from mesh to the active key */
+ if(keyblock) {
+ float *co= keyblock->data;
+ if(co) {
+ adata = e.grabdata ? e.grabdata->active_verts[e.grabdata->index].first : active_verts.first;
+ for(; adata; adata= adata->next)
+ if(adata->Index < keyblock->totelem)
+ VecCopyf(&co[adata->Index*3], me->mvert[adata->Index].co);
+ }
}
- }
- if(vertexcosnos)
- BLI_freelistN(&active_verts);
- else {
- if(!e.grabdata)
- addlisttolist(damaged_verts, &active_verts);
+ if(vertexcosnos)
+ BLI_freelistN(&active_verts);
+ else {
+ if(!e.grabdata)
+ addlisttolist(damaged_verts, &active_verts);
+ }
}
}
@@ -1014,7 +1087,8 @@ BrushData *sculptmode_brush(void)
sd->brush_type==PINCH_BRUSH ? &sd->pinchbrush :
sd->brush_type==INFLATE_BRUSH ? &sd->inflatebrush :
sd->brush_type==GRAB_BRUSH ? &sd->grabbrush :
- sd->brush_type==LAYER_BRUSH ? &sd->layerbrush : NULL);
+ sd->brush_type==LAYER_BRUSH ? &sd->layerbrush :
+ sd->brush_type==FLATTEN_BRUSH ? &sd->flattenbrush : NULL);
}
void sculptmode_update_tex()
@@ -1399,7 +1473,7 @@ void sculptmode_selectbrush_menu(void)
pupmenu_set_active(sd->brush_type);
- val= pupmenu("Select Brush%t|Draw|Smooth|Pinch|Inflate|Grab|Layer");
+ val= pupmenu("Select Brush%t|Draw|Smooth|Pinch|Inflate|Grab|Layer|Flatten");
if(val>0) {
sd->brush_type= val;
@@ -1730,6 +1804,8 @@ void sculpt(void)
BIF_undo_push("Grab Brush"); break;
case LAYER_BRUSH:
BIF_undo_push("Layer Brush"); break;
+ case FLATTEN_BRUSH:
+ BIF_undo_push("Flatten Brush"); break;
default:
BIF_undo_push("Sculpting"); break;
}