2.5: Texture buttons preview now has an option to display the

texture, the material, or both side by side.
This commit is contained in:
Brecht Van Lommel 2009-07-21 01:57:46 +00:00
parent 6dfec894f9
commit 22f421a9ee
11 changed files with 158 additions and 63 deletions

@ -16,15 +16,19 @@ class TEXTURE_PT_preview(TextureButtonsPanel):
def draw(self, context):
layout = self.layout
tex = context.texture
mat = context.material
layout.template_preview(tex)
if mat:
layout.template_preview(tex, parent=mat)
else:
layout.template_preview(tex)
class TEXTURE_PT_context_texture(TextureButtonsPanel):
__idname__= "TEXTURE_PT_context_texture"
__no_header__ = True
def poll(self, context):
return (context.material or context.world or context.lamp)
return (context.material or context.world or context.lamp or context.texture)
def draw(self, context):
layout = self.layout

@ -70,9 +70,9 @@ pr_method:
void ED_preview_init_dbase(void);
void ED_preview_free_dbase(void);
void ED_preview_shader_job(const struct bContext *C, void *owner, struct ID *id, int sizex, int sizey);
void ED_preview_shader_job(const struct bContext *C, void *owner, struct ID *id, struct ID *parent, int sizex, int sizey);
void ED_preview_iconrender(struct Scene *scene, struct ID *id, int *rect, int sizex, int sizey);
void ED_preview_draw(const struct bContext *C, void *idp, rcti *rect);
void ED_preview_draw(const struct bContext *C, void *idp, void *parentp, rcti *rect);
#endif

@ -481,7 +481,7 @@ void uiButSetNFunc (uiBut *but, uiButHandleNFunc func, void *argN, void *arg2)
void uiButSetCompleteFunc(uiBut *but, uiButCompleteFunc func, void *arg);
void uiBlockSetDrawExtraFunc(uiBlock *block, void (*func)(const struct bContext *C, void *, struct rcti *rect));
void uiBlockSetDrawExtraFunc(uiBlock *block, void (*func)(const struct bContext *C, void *, void *, struct rcti *rect), void *arg);
/* Autocomplete
*
@ -619,7 +619,7 @@ void uiTemplateID(uiLayout *layout, struct bContext *C, struct PointerRNA *ptr,
char *newop, char *unlinkop);
uiLayout *uiTemplateModifier(uiLayout *layout, struct PointerRNA *ptr);
uiLayout *uiTemplateConstraint(uiLayout *layout, struct PointerRNA *ptr);
void uiTemplatePreview(uiLayout *layout, struct ID *id);
void uiTemplatePreview(uiLayout *layout, struct ID *id, struct ID *parent);
void uiTemplateColorRamp(uiLayout *layout, struct ColorBand *coba, int expand);
void uiTemplateCurveMapping(uiLayout *layout, struct CurveMapping *cumap, int type);
void uiTemplateLayers(uiLayout *layout, struct PointerRNA *ptr, char *propname);

@ -2772,9 +2772,10 @@ void uiBlockSetRenameFunc(uiBlock *block, uiButHandleRenameFunc func, void *arg1
}
void uiBlockSetDrawExtraFunc(uiBlock *block, void (*func)(const bContext *C, void *idv, rcti *rect))
void uiBlockSetDrawExtraFunc(uiBlock *block, void (*func)(const bContext *C, void *idv, void *argv, rcti *rect), void *arg)
{
block->drawextra= func;
block->drawextra_arg= arg;
}
void uiButSetFunc(uiBut *but, uiButHandleFunc func, void *arg1, void *arg2)

@ -269,7 +269,8 @@ struct uiBlock {
int (*block_event_func)(const struct bContext *C, struct uiBlock *, struct wmEvent *);
/* extra draw function for custom blocks */
void (*drawextra)(const struct bContext *C, void *idv, rcti *rect);
void (*drawextra)(const struct bContext *C, void *idv, void *argv, rcti *rect);
void *drawextra_arg;
int afterval, flag;

@ -1169,32 +1169,47 @@ static void do_preview_buttons(bContext *C, void *arg, int event)
}
}
void uiTemplatePreview(uiLayout *layout, ID *id)
void uiTemplatePreview(uiLayout *layout, ID *id, ID *parent)
{
uiLayout *row, *col;
uiBlock *block;
Material *ma;
ID *pid, *pparent;
if(id && !ELEM4(GS(id->name), ID_MA, ID_TE, ID_WO, ID_LA)) {
printf("uiTemplatePreview: expected ID of type material, texture, lamp or world.\n");
return;
}
/* decide what to render */
pid= id;
pparent= NULL;
if((id && GS(id->name) == ID_TE) && (parent && GS(parent->name) == ID_MA)) {
ma= ((Material*)parent);
if(ma->pr_texture == MA_PR_MATERIAL)
pid= parent;
else if(ma->pr_texture == MA_PR_BOTH)
pparent= parent;
}
/* layout */
block= uiLayoutGetBlock(layout);
row= uiLayoutRow(layout, 0);
col= uiLayoutColumn(row, 0);
uiLayoutSetKeepAspect(col, 1);
uiDefBut(block, BUT_EXTRA, 0, "", 0, 0, UI_UNIT_X*6, UI_UNIT_Y*6, id, 0.0, 0.0, 0, 0, "");
uiBlockSetDrawExtraFunc(block, ED_preview_draw);
/* add preview */
uiDefBut(block, BUT_EXTRA, 0, "", 0, 0, UI_UNIT_X*6, UI_UNIT_Y*6, pid, 0.0, 0.0, 0, 0, "");
uiBlockSetDrawExtraFunc(block, ED_preview_draw, pparent);
uiBlockSetHandleFunc(block, do_preview_buttons, NULL);
/* add buttons */
if(id) {
if(GS(id->name) == ID_MA) {
ma= (Material*)id;
if(GS(id->name) == ID_MA || (parent && GS(parent->name) == ID_MA)) {
if(GS(id->name) == ID_MA) ma= (Material*)id;
else ma= (Material*)parent;
uiLayoutColumn(row, 1);
@ -1205,6 +1220,14 @@ void uiTemplatePreview(uiLayout *layout, ID *id)
uiDefIconButC(block, ROW, B_MATPRV, ICON_HAIR, 0, 0,UI_UNIT_X*1.5,UI_UNIT_Y, &(ma->pr_type), 10, MA_HAIR, 0, 0, "Preview type: Hair strands");
uiDefIconButC(block, ROW, B_MATPRV, ICON_MATSPHERE, 0, 0,UI_UNIT_X*1.5,UI_UNIT_Y, &(ma->pr_type), 10, MA_SPHERE_A, 0, 0, "Preview type: Large sphere with sky");
}
if(GS(id->name) == ID_TE && (parent && GS(parent->name) == ID_MA)) {
uiLayoutRow(layout, 1);
uiDefButS(block, ROW, B_MATPRV, "Texture", 0, 0,UI_UNIT_X*10,UI_UNIT_Y, &(ma->pr_texture), 10, MA_PR_TEXTURE, 0, 0, "");
uiDefButS(block, ROW, B_MATPRV, "Material", 0, 0,UI_UNIT_X*10,UI_UNIT_Y, &(ma->pr_texture), 10, MA_PR_MATERIAL, 0, 0, "");
uiDefButS(block, ROW, B_MATPRV, "Both", 0, 0,UI_UNIT_X*10,UI_UNIT_Y, &(ma->pr_texture), 10, MA_PR_BOTH, 0, 0, "");
}
}
}

@ -2052,11 +2052,11 @@ static void widget_draw_extra_mask(const bContext *C, uiBut *but, uiWidgetType *
if(but->block->drawextra) {
/* note: drawextra can change rect +1 or -1, to match round errors of existing previews */
but->block->drawextra(C, but->poin, rect);
but->block->drawextra(C, but->poin, but->block->drawextra_arg, rect);
/* make mask to draw over image */
UI_GetThemeColor3ubv(TH_BACK, col);
glColor3ubv(col);
glColor3ubv((unsigned char*)col);
round_box__edges(&wtb, 15, rect, 0.0f, 4.0);
widgetbase_outline(&wtb);

@ -112,6 +112,7 @@ typedef struct ShaderPreview {
Scene *scene;
ID *id;
ID *parent;
int sizex, sizey;
int *pr_rect;
@ -273,11 +274,10 @@ static Object *find_object(ListBase *lb, const char *name)
/* call this with a pointer to initialize preview scene */
/* call this with NULL to restore assigned ID pointers in preview scene */
static Scene *preview_prepare_scene(Scene *scene, int id_type, ShaderPreview *sp)
static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPreview *sp)
{
Scene *sce;
Base *base;
ID *id= sp?sp->id:NULL;
if(pr_main==NULL) return NULL;
@ -410,38 +410,74 @@ static Scene *preview_prepare_scene(Scene *scene, int id_type, ShaderPreview *sp
/* new UI convention: draw is in pixel space already. */
/* uses ROUNDBOX button in block to get the rect */
void ED_preview_draw(const bContext *C, void *idp, rcti *rect)
static int ed_preview_draw_rect(ScrArea *sa, Scene *sce, ID *id, int split, int first, rcti *rect, rcti *newrect)
{
RenderResult rres;
char name[32];
int gamma_correct=0;
int offx=0, newx= rect->xmax-rect->xmin, newy= rect->ymax-rect->ymin;
if (id && GS(id->name) != ID_TE) {
/* exception: don't color manage texture previews - show the raw values */
if (sce) gamma_correct = sce->r.color_mgt_flag & R_COLOR_MANAGEMENT;
}
if(!split || first) sprintf(name, "Preview %p", sa);
else sprintf(name, "SecondPreview %p", sa);
if(split) {
if(first) {
offx= 0;
newx= newx/2;
}
else {
offx= newx/2;
newx= newx - newx/2;
}
}
RE_GetResultImage(RE_GetRender(name), &rres);
if(rres.rectf) {
if(ABS(rres.rectx-newx)<2 && ABS(rres.recty-newy)<2) {
newrect->xmax= MAX2(newrect->xmax, rect->xmin + rres.rectx + offx);
newrect->ymax= MAX2(newrect->ymax, rect->ymin + rres.recty);
glPushMatrix();
glTranslatef(offx, 0, 0);
glaDrawPixelsSafe_to32(rect->xmin, rect->ymin, rres.rectx, rres.recty, rres.rectx, rres.rectf, gamma_correct);
glPopMatrix();
return 1;
}
}
return 0;
}
void ED_preview_draw(const bContext *C, void *idp, void *parentp, rcti *rect)
{
if(idp) {
ScrArea *sa= CTX_wm_area(C);
Scene *sce = CTX_data_scene(C);
ID *id = (ID *)idp;
ID *parent= (ID *)parentp;
SpaceButs *sbuts= sa->spacedata.first;
RenderResult rres;
rcti newrect;
int ok;
int newx= rect->xmax-rect->xmin, newy= rect->ymax-rect->ymin;
int ok= 0;
char name[32];
int gamma_correct=0;
if (id && GS(id->name) != ID_TE) {
/* exception: don't color manage texture previews - show the raw values */
if (sce) gamma_correct = sce->r.color_mgt_flag & R_COLOR_MANAGEMENT;
}
sprintf(name, "Preview %p", sa);
RE_GetResultImage(RE_GetRender(name), &rres);
if(rres.rectf) {
if( ABS(rres.rectx-newx)<2 && ABS(rres.recty-newy)<2 ) {
/* correct size, then black outline matches */
rect->xmax= rect->xmin + rres.rectx;
rect->ymax= rect->ymin + rres.recty;
glaDrawPixelsSafe_to32(rect->xmin, rect->ymin, rres.rectx, rres.recty, rres.rectx, rres.rectf, gamma_correct);
ok= 1;
}
}
newrect.xmin= rect->xmin;
newrect.xmax= rect->xmin;
newrect.ymin= rect->ymin;
newrect.ymax= rect->ymin;
ok= ed_preview_draw_rect(sa, sce, id, (parent != NULL), 1, rect, &newrect);
if(parent)
ok &= ed_preview_draw_rect(sa, sce, parent, 1, 0, rect, &newrect);
if(ok)
*rect= newrect;
/* check for spacetype... */
if(sbuts->spacetype==SPACE_BUTS && sbuts->preview) {
@ -450,7 +486,7 @@ void ED_preview_draw(const bContext *C, void *idp, rcti *rect)
}
if(ok==0) {
ED_preview_shader_job(C, sa, idp, newx, newy);
ED_preview_shader_job(C, sa, id, parent, newx, newy);
}
}
}
@ -791,23 +827,20 @@ static void shader_preview_updatejob(void *spv)
}
/* runs inside thread for material, in foreground for icons */
static void shader_preview_startjob(void *customdata, short *stop, short *do_update)
static void shader_preview_render(ShaderPreview *sp, ID *id, int split, int first)
{
ShaderPreview *sp= customdata;
Render *re;
Scene *sce;
float oldlens;
char name [32];
char name[32];
int sizex;
sp->stop= stop;
sp->do_update= do_update;
/* get the stuff from the builtin preview dbase */
sce= preview_prepare_scene(sp->scene, GS(sp->id->name), sp);
sce= preview_prepare_scene(sp->scene, id, GS(id->name), sp); // XXX sizex
if(sce==NULL) return;
sprintf(name, "Preview %p", sp->owner);
if(!split || first) sprintf(name, "Preview %p", sp->owner);
else sprintf(name, "SecondPreview %p", sp->owner);
re= RE_GetRender(name);
/* full refreshed render from first tile */
@ -825,8 +858,15 @@ static void shader_preview_startjob(void *customdata, short *stop, short *do_upd
sce->r.scemode |= R_NO_IMAGE_LOAD;
}
/* in case of split preview, use border render */
if(split) {
if(first) sizex= sp->sizex/2;
else sizex= sp->sizex - sp->sizex/2;
}
else sizex= sp->sizex;
/* allocates or re-uses render result */
RE_InitState(re, NULL, &sce->r, sp->sizex, sp->sizey, NULL);
RE_InitState(re, NULL, &sce->r, sizex, sp->sizey, NULL);
/* callbacs are cleared on GetRender() */
if(sp->pr_method==PR_DO_RENDER) {
@ -835,8 +875,8 @@ static void shader_preview_startjob(void *customdata, short *stop, short *do_upd
}
/* lens adjust */
oldlens= ((Camera *)sce->camera->data)->lens;
if(sp->sizex > sp->sizey)
((Camera *)sce->camera->data)->lens *= (float)sp->sizey/(float)sp->sizex;
if(sizex > sp->sizey)
((Camera *)sce->camera->data)->lens *= (float)sp->sizey/(float)sizex;
/* entire cycle for render engine */
RE_SetCamera(re, sce->camera);
@ -845,7 +885,6 @@ static void shader_preview_startjob(void *customdata, short *stop, short *do_upd
RE_Database_Free(re);
((Camera *)sce->camera->data)->lens= oldlens;
*do_update= 1;
/* handle results */
if(sp->pr_method==PR_ICON_RENDER) {
@ -860,8 +899,25 @@ static void shader_preview_startjob(void *customdata, short *stop, short *do_upd
}
/* unassign the pointers, reset vars */
preview_prepare_scene(sp->scene, GS(sp->id->name), NULL);
preview_prepare_scene(sp->scene, NULL, GS(id->name), NULL);
}
/* runs inside thread for material, in foreground for icons */
static void shader_preview_startjob(void *customdata, short *stop, short *do_update)
{
ShaderPreview *sp= customdata;
sp->stop= stop;
sp->do_update= do_update;
if(sp->parent) {
shader_preview_render(sp, sp->parent, 1, 1);
shader_preview_render(sp, sp->id, 1, 0);
}
else
shader_preview_render(sp, sp->id, 0, 0);
*do_update= 1;
}
static void shader_preview_free(void *customdata)
@ -871,7 +927,7 @@ static void shader_preview_free(void *customdata)
MEM_freeN(sp);
}
void ED_preview_shader_job(const bContext *C, void *owner, ID *id, int sizex, int sizey)
void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, int sizex, int sizey)
{
wmJob *steve;
ShaderPreview *sp;
@ -890,6 +946,7 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, int sizex, in
sp->sizey= sizey;
sp->pr_method= PR_DO_RENDER;
sp->id = id;
sp->parent= parent;
/* setup job */
WM_jobs_customdata(steve, sp, shader_preview_free);
@ -905,8 +962,10 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, int sizex, in
/* rect should be allocated, sizex/sizy pixels, 32 bits */
void ED_preview_iconrender(Scene *scene, ID *id, int *rect, int sizex, int sizey)
{
ShaderPreview *sp= MEM_callocN(sizeof(ShaderPreview), "ShaderPreview");
ShaderPreview *sp;
short stop=0, do_update=0;
sp= MEM_callocN(sizeof(ShaderPreview), "ShaderPreview");
/* customdata for preview thread */
sp->scene= scene;

@ -168,7 +168,7 @@ static void node_area_refresh(const struct bContext *C, struct ScrArea *sa)
if(snode->treetype==NTREE_SHADER) {
Material *ma= (Material *)snode->id;
if(ma->use_nodes)
ED_preview_shader_job(C, sa, snode->id, 100, 100);
ED_preview_shader_job(C, sa, snode->id, NULL, 100, 100);
}
else if(snode->treetype==NTREE_COMPOSIT) {
Scene *scene= (Scene *)snode->id;

@ -93,7 +93,7 @@ typedef struct Material {
/* for buttons and render*/
char rgbsel, texact, pr_type, use_nodes;
short pr_back, pr_lamp, pad4, ml_flag; /* ml_flag is for disable base material */
short pr_back, pr_lamp, pr_texture, ml_flag; /* ml_flag is for disable base material */
/* shaders */
short diff_shader, spec_shader;
@ -326,6 +326,12 @@ typedef struct Material {
#define MA_HAIR 10
#define MA_ATMOS 11
/* pr_texture */
#define MA_PR_TEXTURE 0
#define MA_PR_MATERIAL 1
#define MA_PR_BOTH 2
/* pr_back */
#define MA_DARK 1

@ -242,6 +242,7 @@ void RNA_api_ui_layout(StructRNA *srna)
func= RNA_def_function(srna, "template_preview", "uiTemplatePreview");
parm= RNA_def_pointer(func, "id", "ID", "", "ID datablock.");
RNA_def_property_flag(parm, PROP_REQUIRED);
parm= RNA_def_pointer(func, "parent", "ID", "", "ID datablock.");
func= RNA_def_function(srna, "template_curve_mapping", "uiTemplateCurveMapping");
parm= RNA_def_pointer(func, "curvemap", "CurveMapping", "", "Curve mapping pointer.");