2.5: Texture buttons preview now has an option to display the
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Tue, 21 Jul 2009 01:57:46 +0000 (01:57 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Tue, 21 Jul 2009 01:57:46 +0000 (01:57 +0000)
texture, the material, or both side by side.

release/ui/buttons_texture.py
source/blender/editors/include/ED_previewrender.h
source/blender/editors/include/UI_interface.h
source/blender/editors/interface/interface.c
source/blender/editors/interface/interface_intern.h
source/blender/editors/interface/interface_templates.c
source/blender/editors/interface/interface_widgets.c
source/blender/editors/preview/previewrender.c
source/blender/editors/space_node/space_node.c
source/blender/makesdna/DNA_material_types.h
source/blender/makesrna/intern/rna_ui_api.c

index 4c2f392b646bbf1f2559804b1cab7afc8ccbe4ea..49f04b886b4e9d7f32195e1f876f686712cd6b1b 100644 (file)
@@ -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
index 10067510e53627963fab0ed3042e823b1c24f183..0e50ea896d6805750ebf28fad5a58f79cef86ef3 100644 (file)
@@ -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
index 2fec61fda3c31bea21311c38ae4545d8b525d5ae..b7f75386113686180462e597446ab5468c96059a 100644 (file)
@@ -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);
index 27561f42b8a647fccc1848bc967030b7e2026fd2..284ec6943ea1f2e4f3fb04844d4ce4acbaa0d502 100644 (file)
@@ -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)
index 70d60502ac47cd23796499ea104469be7789e450..aef52572fe3ef812a461d6ea1d6360ecdcba1ddd 100644 (file)
@@ -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;
        
index f34774b0516c067f3c1277853a7b37f6d582cf60..c08e8efcdb5eaa89e97344c784cc371588079cc4 100644 (file)
@@ -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;
        }
 
-       block= uiLayoutGetBlock(layout);
+       /* decide what to render */
+       pid= id;
+       pparent= NULL;
 
-       row= uiLayoutRow(layout, 0);
+       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, "");
+               }
        }
 }
 
index 97c2bb55a691174baa18c4ed230ec6e69c3959f9..fa56af7403368eea28a6fcd238c32460fce741d4 100644 (file)
@@ -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);
index 28b9c6b18331fef1915236d98c3bdc3dd357c937..624952b48f5b865096044cf8457671aef440afd7 100644 (file)
@@ -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;
index ac3a884c5f822aa54f326cd7d9b80ac3100f06bb..7c6667a83f20e312429c202569be446b9ae3463a 100644 (file)
@@ -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;
index 561638bfd209bbab2f100490c85f445e93008903..fd73d371d87b1ead510ce7a5419830936c65e47c 100644 (file)
@@ -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
 
index e89e633acbe417804d6958fdb8fd080d2434402b..05255036992d5a49cfecd81927c95712c212cd8f 100644 (file)
@@ -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.");