forked from bartvdbraak/blender
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:
parent
6dfec894f9
commit
22f421a9ee
@ -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.");
|
||||
|
Loading…
Reference in New Issue
Block a user