forked from bartvdbraak/blender
== Sculpt Mode ==
Applying Stephan Kassemeyer's patch (#6750) to add a curve modifier for sculpting. A few changes from the patch: * The default curve is closer to the old behavior * Fixed loading files already saved in sculpt mode * Changed the interface; split the brush texture controls off into a third sculpt tab, and put the curve (and curve reset) into the Brush tab.
This commit is contained in:
parent
1d8fdff909
commit
801c0799c1
@ -217,6 +217,8 @@ void multires_update_levels(struct Mesh *me, const int render);
|
||||
void multires_calc_level_maps(struct MultiresLevel *lvl);
|
||||
struct Multires *multires_copy(struct Multires *orig);
|
||||
/* sculptmode.c */
|
||||
struct SculptData;
|
||||
void sculpt_reset_curve(struct SculptData *sd);
|
||||
void sculptmode_free_all(struct Scene *sce);
|
||||
void sculptmode_init(struct Scene *sce);
|
||||
|
||||
|
@ -317,6 +317,7 @@ void multires_set_level(struct Object *ob, struct Mesh *me, const int render) {}
|
||||
void multires_update_levels(struct Mesh *me, const int render) {}
|
||||
void multires_calc_level_maps(struct MultiresLevel *lvl) {}
|
||||
struct Multires *multires_copy(struct Multires *orig) {return NULL;}
|
||||
void sculpt_reset_curve(struct SculptData *sd) {}
|
||||
void sculptmode_init(struct Scene *sce) {}
|
||||
void sculptmode_free_all(struct Scene *sce) {}
|
||||
|
||||
|
@ -3323,6 +3323,12 @@ static void direct_link_scene(FileData *fd, Scene *sce)
|
||||
/* SculptData textures */
|
||||
for(a=0; a<MAX_MTEX; ++a)
|
||||
sce->sculptdata.mtex[a]= newdataadr(fd,sce->sculptdata.mtex[a]);
|
||||
/* Sculpt intensity curve */
|
||||
sce->sculptdata.cumap= newdataadr(fd, sce->sculptdata.cumap);
|
||||
if(sce->sculptdata.cumap)
|
||||
direct_link_curvemapping(fd, sce->sculptdata.cumap);
|
||||
else
|
||||
sculpt_reset_curve(&sce->sculptdata);
|
||||
|
||||
if(sce->ed) {
|
||||
ListBase *old_seqbasep= &((Editing *)sce->ed)->seqbase;
|
||||
|
@ -1422,6 +1422,8 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
|
||||
|
||||
for(a=0; a<MAX_MTEX; ++a)
|
||||
writestruct(wd, DATA, "MTex", 1, sce->sculptdata.mtex[a]);
|
||||
if(sce->sculptdata.cumap)
|
||||
write_curvemapping(wd, sce->sculptdata.cumap);
|
||||
|
||||
ed= sce->ed;
|
||||
if(ed) {
|
||||
|
@ -99,12 +99,14 @@ SculptSession *sculpt_session(void);
|
||||
struct SculptData *sculpt_data(void);
|
||||
|
||||
/* Memory */
|
||||
void sculpt_reset_curve(struct SculptData *sd);
|
||||
void sculptmode_init(struct Scene *);
|
||||
void sculptmode_free_all(struct Scene *);
|
||||
void sculptmode_correct_state(void);
|
||||
|
||||
/* Interface */
|
||||
void sculptmode_draw_interface_tools(struct uiBlock *block,unsigned short cx, unsigned short cy);
|
||||
void sculptmode_draw_interface_brush(struct uiBlock *block,unsigned short cx, unsigned short cy);
|
||||
void sculptmode_draw_interface_textures(struct uiBlock *block,unsigned short cx, unsigned short cy);
|
||||
void sculptmode_rem_tex(void*,void*);
|
||||
void sculptmode_propset_init(PropsetMode mode);
|
||||
|
@ -424,6 +424,9 @@ typedef struct SculptData
|
||||
/* Pointers to all of sculptmodes's textures */
|
||||
struct MTex *mtex[10];
|
||||
|
||||
/* Editable brush shape */
|
||||
struct CurveMapping *cumap;
|
||||
|
||||
/* Settings for each brush */
|
||||
BrushData drawbrush, smoothbrush, pinchbrush, inflatebrush, grabbrush, layerbrush, flattenbrush;
|
||||
short brush_type;
|
||||
|
@ -5046,10 +5046,18 @@ void editing_panel_sculpting_tools()
|
||||
sculptmode_draw_interface_tools(block,0,200);
|
||||
}
|
||||
|
||||
void editing_panel_sculpting_brush()
|
||||
{
|
||||
uiBlock *block= uiNewBlock(&curarea->uiblocks, "editing_panel_sculpting_brush", UI_EMBOSS, UI_HELV, curarea->win);
|
||||
if(uiNewPanel(curarea, block, "Brush", "Editing", 300, 0, 318, 204)==0) return;
|
||||
|
||||
sculptmode_draw_interface_brush(block,0,200);
|
||||
}
|
||||
|
||||
void editing_panel_sculpting_textures()
|
||||
{
|
||||
uiBlock *block= uiNewBlock(&curarea->uiblocks, "editing_panel_sculpting_textures", UI_EMBOSS, UI_HELV, curarea->win);
|
||||
if(uiNewPanel(curarea, block, "Brush", "Editing", 300, 0, 318, 204)==0) return;
|
||||
uiBlock *block= uiNewBlock(&curarea->uiblocks, "editing_panel_sculpting_texture", UI_EMBOSS, UI_HELV, curarea->win);
|
||||
if(uiNewPanel(curarea, block, "Texture", "Editing", 300, 0, 318, 204)==0) return;
|
||||
|
||||
sculptmode_draw_interface_textures(block,0,200);
|
||||
}
|
||||
@ -5057,11 +5065,10 @@ void editing_panel_sculpting_textures()
|
||||
void sculptmode_draw_interface_tools(uiBlock *block, unsigned short cx, unsigned short cy)
|
||||
{
|
||||
SculptData *sd;
|
||||
uiBut *but;
|
||||
|
||||
if(!G.scene) return;
|
||||
sd= &G.scene->sculptdata;
|
||||
|
||||
|
||||
uiBlockBeginAlign(block);
|
||||
|
||||
uiDefBut(block,LABEL,B_NOP,"Brush",cx,cy,90,19,NULL,0,0,0,0,"");
|
||||
@ -5090,7 +5097,7 @@ void sculptmode_draw_interface_tools(uiBlock *block, unsigned short cx, unsigned
|
||||
if(sd->brush_type!=GRAB_BRUSH)
|
||||
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,268,19,&sculptmode_brush()->size,1.0,200.0,0,0,"Set brush radius in pixels");
|
||||
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,268,19,&sculptmode_brush()->strength,1.0,100.0,0,0,"Set brush strength");
|
||||
@ -5109,6 +5116,46 @@ void sculptmode_draw_interface_tools(uiBlock *block, unsigned short cx, unsigned
|
||||
cx+= 210;
|
||||
}
|
||||
|
||||
static void sculptmode_curves_reset(void *sd_v, void *j)
|
||||
{
|
||||
SculptData *sd = sd_v;
|
||||
sculpt_reset_curve(sd);
|
||||
curvemapping_changed(sd->cumap, 0);
|
||||
}
|
||||
|
||||
void sculptmode_draw_interface_brush(uiBlock *block, unsigned short cx, unsigned short cy)
|
||||
{
|
||||
SculptData *sd= sculpt_data();
|
||||
int orig_y = cy;
|
||||
rctf rect;
|
||||
uiBut *but;
|
||||
|
||||
uiBlockBeginAlign(block);
|
||||
cy-= 20;
|
||||
uiDefButC(block,TOG,REDRAWBUTSEDIT, "Curve", cx,cy,80,19, &sd->texfade, 0,0,0,0,"Use curve control for radial brush intensity");
|
||||
cy-= 20;
|
||||
but= uiDefBut(block, BUT, REDRAWBUTSEDIT, "Reset",cx,cy,80,19, NULL, 0,0,0,0, "Default curve preset");
|
||||
uiButSetFunc(but, sculptmode_curves_reset, sd, NULL);
|
||||
cy-= 25;
|
||||
uiBlockEndAlign(block);
|
||||
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButS(block,NUM,B_NOP, "Space", cx,cy,80,19, &sd->spacing, 0,500,20,0,"Non-zero inserts N pixels between dots");
|
||||
cy-= 20;
|
||||
if(sd->brush_type == DRAW_BRUSH)
|
||||
uiDefButC(block,NUM,B_NOP, "View", cx,cy,80,19, &sculptmode_brush()->view, 0,10,20,0,"Pulls brush direction towards view");
|
||||
uiBlockEndAlign(block);
|
||||
|
||||
/* Draw curve */
|
||||
cx += 90;
|
||||
cy = orig_y;
|
||||
rect.xmin= cx; rect.xmax= cx + 178;
|
||||
rect.ymin= cy - 160; rect.ymax= cy + 20;
|
||||
uiBlockBeginAlign(block);
|
||||
curvemap_buttons(block, sd->cumap, (char)0, B_NOP, 0, &rect);
|
||||
uiBlockEndAlign(block);
|
||||
}
|
||||
|
||||
void sculptmode_draw_interface_textures(uiBlock *block, unsigned short cx, unsigned short cy)
|
||||
{
|
||||
SculptData *sd= sculpt_data();
|
||||
@ -5119,24 +5166,7 @@ void sculptmode_draw_interface_textures(uiBlock *block, unsigned short cx, unsig
|
||||
uiBut *but;
|
||||
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefBut(block,LABEL,B_NOP,"Common",cx,cy,80,20,0,0,0,0,0,"");
|
||||
cy-= 20;
|
||||
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefButC(block,TOG,B_NOP, "Fade", cx,cy,80,19, &sd->texfade, 0,0,0,0,"Smooth the edges of the texture");
|
||||
cy-= 20;
|
||||
uiDefButS(block,NUM,B_NOP, "Space", cx,cy,80,19, &sd->spacing, 0,500,20,0,"Non-zero inserts N pixels between dots");
|
||||
cy-= 20;
|
||||
if(sd->brush_type == DRAW_BRUSH)
|
||||
uiDefButC(block,NUM,B_NOP, "View", cx,cy,80,19, &sculptmode_brush()->view, 0,10,20,0,"Pulls brush direction towards view");
|
||||
uiBlockEndAlign(block);
|
||||
|
||||
cy= orig_y;
|
||||
cx+= 85;
|
||||
uiBlockBeginAlign(block);
|
||||
uiDefBut(block,LABEL,B_NOP,"Texture",cx,cy,80,20,0,0,0,0,0,"");
|
||||
cy-= 20;
|
||||
|
||||
/* TEX CHANNELS */
|
||||
uiBlockBeginAlign(block);
|
||||
uiBlockSetCol(block, TH_BUT_NEUTRAL);
|
||||
@ -6034,6 +6064,8 @@ void editing_panels()
|
||||
uiNewPanelTabbed("Multires", "Editing");
|
||||
editing_panel_sculpting_tools();
|
||||
uiNewPanelTabbed("Multires", "Editing");
|
||||
editing_panel_sculpting_brush();
|
||||
uiNewPanelTabbed("Multires", "Editing");
|
||||
editing_panel_sculpting_textures();
|
||||
} else {
|
||||
if(G.f & (G_VERTEXPAINT | G_TEXTUREPAINT | G_WEIGHTPAINT) ) {
|
||||
|
@ -2252,7 +2252,7 @@ static void view3d_panel_object(short cntrl) // VIEW3D_HANDLER_OBJECT
|
||||
uiSetPanelHandler(VIEW3D_HANDLER_OBJECT); // for close and esc
|
||||
|
||||
if((G.f & G_SCULPTMODE) && !G.obedit) {
|
||||
if(!uiNewPanel(curarea, block, "Transform Properties", "View3d", 10, 230, 425, 234))
|
||||
if(!uiNewPanel(curarea, block, "Transform Properties", "View3d", 10, 230, 318, 234))
|
||||
return;
|
||||
} else if(G.f & G_PARTICLEEDIT && !G.obedit){
|
||||
if(!uiNewPanel(curarea, block, "Transform Properties", "View3d", 10, 230, 318, 234))
|
||||
|
@ -53,6 +53,7 @@
|
||||
#include "DNA_texture_types.h"
|
||||
#include "DNA_view3d_types.h"
|
||||
#include "DNA_userdef_types.h"
|
||||
#include "DNA_color_types.h"
|
||||
|
||||
#include "BKE_customdata.h"
|
||||
#include "BKE_DerivedMesh.h"
|
||||
@ -66,6 +67,7 @@
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_texture.h"
|
||||
#include "BKE_utildefines.h"
|
||||
#include "BKE_colortools.h"
|
||||
|
||||
#include "BIF_editkey.h"
|
||||
#include "BIF_editview.h"
|
||||
@ -190,6 +192,35 @@ SculptSession *sculpt_session(void)
|
||||
* Allocate/initialize/free data
|
||||
*/
|
||||
|
||||
// Default curve approximates 0.5 * (cos(pi * x) + 1), with 0 <= x <= 1;
|
||||
void sculpt_reset_curve(SculptData *sd)
|
||||
{
|
||||
CurveMap *cm = NULL;
|
||||
|
||||
if(!sd->cumap)
|
||||
sd->cumap = curvemapping_add(1, 0, 0, 1, 1);
|
||||
|
||||
cm = sd->cumap->cm;
|
||||
|
||||
if(cm->curve)
|
||||
MEM_freeN(cm->curve);
|
||||
cm->curve= MEM_callocN(6*sizeof(CurveMapPoint), "curve points");
|
||||
cm->flag &= ~CUMA_EXTEND_EXTRAPOLATE;
|
||||
cm->totpoint= 6;
|
||||
cm->curve[0].x= 0;
|
||||
cm->curve[0].y= 1;
|
||||
cm->curve[1].x= 0.1;
|
||||
cm->curve[1].y= 0.97553;
|
||||
cm->curve[2].x= 0.3;
|
||||
cm->curve[2].y= 0.79389;
|
||||
cm->curve[3].x= 0.9;
|
||||
cm->curve[3].y= 0.02447;
|
||||
cm->curve[4].x= 0.7;
|
||||
cm->curve[4].y= 0.20611;
|
||||
cm->curve[5].x= 1;
|
||||
cm->curve[5].y= 0;
|
||||
}
|
||||
|
||||
/* Initialize 'permanent' sculpt data that is saved with file kept after
|
||||
switching out of sculptmode. */
|
||||
void sculptmode_init(Scene *sce)
|
||||
@ -203,6 +234,9 @@ void sculptmode_init(Scene *sce)
|
||||
|
||||
sd= &sce->sculptdata;
|
||||
|
||||
if(sd->cumap)
|
||||
curvemapping_free(sd->cumap);
|
||||
|
||||
memset(sd, 0, sizeof(SculptData));
|
||||
|
||||
sd->drawbrush.size = sd->smoothbrush.size = sd->pinchbrush.size =
|
||||
@ -227,6 +261,7 @@ void sculptmode_init(Scene *sce)
|
||||
sd->tablet_size=3;
|
||||
sd->tablet_strength=10;
|
||||
sd->rake=0;
|
||||
sculpt_reset_curve(sd);
|
||||
}
|
||||
|
||||
void sculptmode_free_session(Scene *);
|
||||
@ -281,6 +316,9 @@ void sculptmode_free_all(Scene *sce)
|
||||
MEM_freeN(mtex);
|
||||
}
|
||||
}
|
||||
|
||||
curvemapping_free(sd->cumap);
|
||||
sd->cumap = NULL;
|
||||
}
|
||||
|
||||
/* vertex_users is an array of Lists that store all the faces that use a
|
||||
@ -735,12 +773,11 @@ void do_flatten_brush(const EditData *e, const ListBase *active_verts)
|
||||
}
|
||||
}
|
||||
|
||||
/* 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)
|
||||
/* Uses the brush curve control to find a strength value between 0 and 1 */
|
||||
float curve_strength(float p, const float len)
|
||||
{
|
||||
if(p > len) p= len;
|
||||
return 0.5f * (cos(M_PI*p/len) + 1);
|
||||
return curvemapping_evaluateF(G.scene->sculptdata.cumap, 0, p/len);
|
||||
}
|
||||
|
||||
/* Uses symm to selectively flip any axis of a coordinate. */
|
||||
@ -883,7 +920,7 @@ float tex_strength(EditData *e, float *point, const float len,const unsigned vin
|
||||
}
|
||||
|
||||
if(sd->texfade)
|
||||
avg*= simple_strength(len,e->size); /* Smooth curve */
|
||||
avg*= curve_strength(len,e->size); /* Smooth curve */
|
||||
|
||||
return avg;
|
||||
}
|
||||
@ -1323,7 +1360,7 @@ void sculptmode_propset_calctex()
|
||||
for(j=0; j<tsz; ++j) {
|
||||
float magn= sqrt(pow(i-tsz/2,2)+pow(j-tsz/2,2));
|
||||
if(sd->texfade)
|
||||
pd->texdata[i*tsz+j]= simple_strength(magn,tsz/2);
|
||||
pd->texdata[i*tsz+j]= curve_strength(magn,tsz/2);
|
||||
else
|
||||
pd->texdata[i*tsz+j]= magn < tsz/2 ? 1 : 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user