Progress indicators for threaded jobs
Now, rather than the bit-too-alarming stop sign, threaded wmJobs display a progress indicator in the header. This is an optional feature for each job type and still uses the same hardcoded ui template (could use further work here...). Currently implemented for: Render - parts completed, then nodes comped Compositor - nodes comped Fluid Sim - frames simulated Texture Bake - faces baked Example: http://mke3.net/blender/devel/2.5/progress.mov
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 205 KiB After Width: | Height: | Size: 205 KiB |
@@ -554,6 +554,10 @@ class USERPREF_PT_theme(bpy.types.Panel):
|
||||
ui = theme.user_interface.wcol_scroll
|
||||
col.label(text="Scroll Bar:")
|
||||
ui_items_general(col, ui)
|
||||
|
||||
ui = theme.user_interface.wcol_progress
|
||||
col.label(text="Progress Bar:")
|
||||
ui_items_general(col, ui)
|
||||
|
||||
ui = theme.user_interface.wcol_list_item
|
||||
col.label(text="List Item:")
|
||||
|
||||
@@ -2434,7 +2434,7 @@ void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview)
|
||||
bNode *node;
|
||||
ListBase threads;
|
||||
ThreadData thdata;
|
||||
int totnode, rendering= 1;
|
||||
int totnode, curnode, rendering= 1;
|
||||
|
||||
if(ntree==NULL) return;
|
||||
|
||||
@@ -2455,7 +2455,7 @@ void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview)
|
||||
BLI_srandom(rd->cfra);
|
||||
|
||||
/* sets need_exec tags in nodes */
|
||||
totnode= setExecutableNodes(ntree, &thdata);
|
||||
curnode = totnode= setExecutableNodes(ntree, &thdata);
|
||||
|
||||
BLI_init_threads(&threads, exec_composite_node, rd->threads);
|
||||
|
||||
@@ -2465,14 +2465,14 @@ void ntreeCompositExecTree(bNodeTree *ntree, RenderData *rd, int do_preview)
|
||||
node= getExecutableNode(ntree);
|
||||
if(node) {
|
||||
|
||||
if(ntree->timecursor)
|
||||
ntree->timecursor(ntree->tch, totnode);
|
||||
if(ntree->progress)
|
||||
ntree->progress(ntree->prh, (1.0 - curnode/(float)totnode));
|
||||
if(ntree->stats_draw) {
|
||||
char str[64];
|
||||
sprintf(str, "Compositing %d %s", totnode, node->name);
|
||||
sprintf(str, "Compositing %d %s", curnode, node->name);
|
||||
ntree->stats_draw(ntree->sdh, str);
|
||||
}
|
||||
totnode--;
|
||||
curnode--;
|
||||
|
||||
node->threaddata = &thdata;
|
||||
node->exec= NODE_PROCESSING;
|
||||
|
||||
@@ -2082,7 +2082,7 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree)
|
||||
|
||||
ntree->init= 0; /* to set callbacks and force setting types */
|
||||
ntree->owntype= NULL;
|
||||
ntree->timecursor= NULL;
|
||||
ntree->progress= NULL;
|
||||
|
||||
ntree->adt= newdataadr(fd, ntree->adt);
|
||||
direct_link_animdata(fd, ntree->adt);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -220,6 +220,7 @@ typedef struct uiLayout uiLayout;
|
||||
#define HISTOGRAM (47<<9)
|
||||
#define WAVEFORM (48<<9)
|
||||
#define VECTORSCOPE (49<<9)
|
||||
#define PROGRESSBAR (50<<9)
|
||||
|
||||
#define BUTTYPE (63<<9)
|
||||
|
||||
@@ -247,8 +248,9 @@ void uiDrawMenuBox(float minx, float miny, float maxx, float maxy, short flag, s
|
||||
void uiDrawBoxShadow(unsigned char alpha, float minx, float miny, float maxx, float maxy);
|
||||
|
||||
/* state for scrolldrawing */
|
||||
#define UI_SCROLL_PRESSED 1
|
||||
#define UI_SCROLL_ARROWS 2
|
||||
#define UI_SCROLL_PRESSED 1
|
||||
#define UI_SCROLL_ARROWS 2
|
||||
#define UI_SCROLL_NO_OUTLINE 4
|
||||
void uiWidgetScrollDraw(struct uiWidgetColors *wcol, struct rcti *rect, struct rcti *slider, int state);
|
||||
|
||||
/* Menu Callbacks */
|
||||
|
||||
@@ -2376,7 +2376,7 @@ static uiBut *ui_def_but(uiBlock *block, int type, int retval, char *str, short
|
||||
}
|
||||
}
|
||||
|
||||
if((block->flag & UI_BLOCK_LOOP) || ELEM7(but->type, MENU, TEX, LABEL, IDPOIN, BLOCK, BUTM, SEARCH_MENU))
|
||||
if((block->flag & UI_BLOCK_LOOP) || ELEM8(but->type, MENU, TEX, LABEL, IDPOIN, BLOCK, BUTM, SEARCH_MENU, PROGRESSBAR))
|
||||
but->flag |= (UI_TEXT_LEFT|UI_ICON_LEFT);
|
||||
else if(but->type==BUT_TOGDUAL)
|
||||
but->flag |= UI_ICON_LEFT;
|
||||
|
||||
@@ -184,11 +184,16 @@ static void button_timers_tooltip_remove(bContext *C, uiBut *but);
|
||||
|
||||
/* ******************** menu navigation helpers ************** */
|
||||
|
||||
static int ui_but_editable(uiBut *but)
|
||||
{
|
||||
return ELEM5(but->type, LABEL, SEPR, ROUNDBOX, LISTBOX, PROGRESSBAR);
|
||||
}
|
||||
|
||||
static uiBut *ui_but_prev(uiBut *but)
|
||||
{
|
||||
while(but->prev) {
|
||||
but= but->prev;
|
||||
if(!ELEM4(but->type, LABEL, SEPR, ROUNDBOX, LISTBOX)) return but;
|
||||
if(!ui_but_editable(but)) return but;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -197,7 +202,7 @@ static uiBut *ui_but_next(uiBut *but)
|
||||
{
|
||||
while(but->next) {
|
||||
but= but->next;
|
||||
if(!ELEM4(but->type, LABEL, SEPR, ROUNDBOX, LISTBOX)) return but;
|
||||
if(!ui_but_editable(but)) return but;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
@@ -208,7 +213,7 @@ static uiBut *ui_but_first(uiBlock *block)
|
||||
|
||||
but= block->buttons.first;
|
||||
while(but) {
|
||||
if(!ELEM4(but->type, LABEL, SEPR, ROUNDBOX, LISTBOX)) return but;
|
||||
if(!ui_but_editable(but)) return but;
|
||||
but= but->next;
|
||||
}
|
||||
return NULL;
|
||||
@@ -220,7 +225,7 @@ static uiBut *ui_but_last(uiBlock *block)
|
||||
|
||||
but= block->buttons.last;
|
||||
while(but) {
|
||||
if(!ELEM4(but->type, LABEL, SEPR, ROUNDBOX, LISTBOX)) return but;
|
||||
if(!ui_but_editable(but)) return but;
|
||||
but= but->prev;
|
||||
}
|
||||
return NULL;
|
||||
@@ -4313,6 +4318,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, wmEvent *event)
|
||||
case ROW:
|
||||
case LISTROW:
|
||||
case BUT_IMAGE:
|
||||
case PROGRESSBAR:
|
||||
retval= ui_do_but_EXIT(C, but, data, event);
|
||||
break;
|
||||
case HISTOGRAM:
|
||||
|
||||
@@ -87,7 +87,8 @@ typedef enum {
|
||||
UI_WTYPE_NORMAL,
|
||||
UI_WTYPE_BOX,
|
||||
UI_WTYPE_SCROLL,
|
||||
UI_WTYPE_LISTITEM
|
||||
UI_WTYPE_LISTITEM,
|
||||
UI_WTYPE_PROGRESSBAR,
|
||||
|
||||
} uiWidgetTypeEnum;
|
||||
|
||||
|
||||
@@ -2423,24 +2423,40 @@ void uiTemplateRunningJobs(uiLayout *layout, bContext *C)
|
||||
wmWindowManager *wm= CTX_wm_manager(C);
|
||||
ScrArea *sa= CTX_wm_area(C);
|
||||
uiBlock *block;
|
||||
|
||||
void *owner;
|
||||
int handle_event;
|
||||
|
||||
block= uiLayoutGetBlock(layout);
|
||||
uiBlockSetCurLayout(block, layout);
|
||||
|
||||
uiBlockSetHandleFunc(block, do_running_jobs, NULL);
|
||||
|
||||
if(sa->spacetype==SPACE_NODE) {
|
||||
if(WM_jobs_test(wm, sa))
|
||||
uiDefIconTextBut(block, BUT, B_STOPCAST, ICON_CANCEL, "Composite", 0,0,85,UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "Stop composite");
|
||||
owner = sa;
|
||||
handle_event= B_STOPCOMPO;
|
||||
} else {
|
||||
owner = scene;
|
||||
handle_event= B_STOPRENDER;
|
||||
}
|
||||
else {
|
||||
if(WM_jobs_test(wm, scene))
|
||||
uiDefIconTextBut(block, BUT, B_STOPRENDER, ICON_CANCEL, "Render", 0,0,75,UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "Stop rendering");
|
||||
if(WM_jobs_test(wm, screen))
|
||||
uiDefIconTextBut(block, BUT, B_STOPCAST, ICON_CANCEL, "Capture", 0,0,85,UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "Stop screencast");
|
||||
if(screen->animtimer)
|
||||
uiDefIconTextBut(block, BUT, B_STOPANIM, ICON_CANCEL, "Anim Player", 0,0,100,UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "Stop animation playback");
|
||||
|
||||
if(WM_jobs_test(wm, owner)) {
|
||||
uiLayout *abs;
|
||||
|
||||
abs = uiLayoutAbsolute(layout, 0);
|
||||
|
||||
uiDefIconBut(block, BUT, handle_event, ICON_PANEL_CLOSE,
|
||||
0, UI_UNIT_Y*0.1, UI_UNIT_X*0.8, UI_UNIT_Y*0.8, NULL, 0.0f, 0.0f, 0, 0, "Stop this job");
|
||||
uiDefBut(block, PROGRESSBAR, 0, WM_jobs_name(wm, owner),
|
||||
UI_UNIT_X, 0, 100, UI_UNIT_Y, NULL, 0.0f, 0.0f, WM_jobs_progress(wm, owner), 0, "Progress");
|
||||
|
||||
uiLayoutRow(layout, 0);
|
||||
}
|
||||
if(WM_jobs_test(wm, screen))
|
||||
uiDefIconTextBut(block, BUT, B_STOPCAST, ICON_CANCEL, "Capture", 0,0,85,UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "Stop screencast");
|
||||
if(screen->animtimer)
|
||||
uiDefIconTextBut(block, BUT, B_STOPANIM, ICON_CANCEL, "Anim Player", 0,0,100,UI_UNIT_Y, NULL, 0.0f, 0.0f, 0, 0, "Stop animation playback");
|
||||
|
||||
uiItemS(layout);
|
||||
}
|
||||
|
||||
/************************* Reports for Last Operator Template **************************/
|
||||
|
||||
@@ -1276,6 +1276,19 @@ static struct uiWidgetColors wcol_scroll= {
|
||||
5, -5
|
||||
};
|
||||
|
||||
static struct uiWidgetColors wcol_progress= {
|
||||
{0, 0, 0, 255},
|
||||
{190, 190, 190, 255},
|
||||
{100, 100, 100, 180},
|
||||
{68, 68, 68, 255},
|
||||
|
||||
{0, 0, 0, 255},
|
||||
{255, 255, 255, 255},
|
||||
|
||||
0,
|
||||
0, 0
|
||||
};
|
||||
|
||||
static struct uiWidgetColors wcol_list_item= {
|
||||
{0, 0, 0, 255},
|
||||
{0, 0, 0, 0},
|
||||
@@ -1322,6 +1335,7 @@ void ui_widget_color_init(ThemeUI *tui)
|
||||
tui->wcol_box= wcol_box;
|
||||
tui->wcol_scroll= wcol_scroll;
|
||||
tui->wcol_list_item= wcol_list_item;
|
||||
tui->wcol_progress= wcol_progress;
|
||||
|
||||
tui->wcol_state= wcol_state;
|
||||
}
|
||||
@@ -1954,6 +1968,7 @@ void uiWidgetScrollDraw(uiWidgetColors *wcol, rcti *rect, rcti *slider, int stat
|
||||
uiWidgetBase wtb;
|
||||
float rad;
|
||||
int horizontal;
|
||||
short outline=0;
|
||||
|
||||
widget_init(&wtb);
|
||||
|
||||
@@ -1995,6 +2010,10 @@ void uiWidgetScrollDraw(uiWidgetColors *wcol, rcti *rect, rcti *slider, int stat
|
||||
/* draw */
|
||||
wtb.emboss= 0; /* only emboss once */
|
||||
|
||||
/* exception for progress bar */
|
||||
if (state & UI_SCROLL_NO_OUTLINE)
|
||||
SWAP(short, outline, wtb.outline);
|
||||
|
||||
round_box_edges(&wtb, 15, slider, rad);
|
||||
|
||||
if(state & UI_SCROLL_ARROWS) {
|
||||
@@ -2013,6 +2032,9 @@ void uiWidgetScrollDraw(uiWidgetColors *wcol, rcti *rect, rcti *slider, int stat
|
||||
}
|
||||
}
|
||||
widgetbase_draw(&wtb, wcol);
|
||||
|
||||
if (state & UI_SCROLL_NO_OUTLINE)
|
||||
SWAP(short, outline, wtb.outline);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2077,9 +2099,35 @@ static void widget_scroll(uiBut *but, uiWidgetColors *wcol, rcti *rect, int stat
|
||||
uiWidgetScrollDraw(wcol, rect, &rect1, state);
|
||||
}
|
||||
|
||||
static void widget_progressbar(uiBut *but, uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
|
||||
{
|
||||
rcti rect_prog = *rect, rect_bar = *rect;
|
||||
float value = but->a1;
|
||||
float w, min;
|
||||
|
||||
/* make the progress bar a proportion of the original height */
|
||||
/* hardcoded 4px high for now */
|
||||
rect_prog.ymax = rect_prog.ymin + 4;
|
||||
rect_bar.ymax = rect_bar.ymin + 4;
|
||||
|
||||
w = value * (rect_prog.xmax - rect_prog.xmin);
|
||||
|
||||
/* ensure minimium size */
|
||||
min= rect_prog.ymax - rect_prog.ymin;
|
||||
w = MAX2(w, min);
|
||||
|
||||
rect_bar.xmax = rect_bar.xmin + w;
|
||||
|
||||
uiWidgetScrollDraw(wcol, &rect_prog, &rect_bar, UI_SCROLL_NO_OUTLINE);
|
||||
|
||||
/* raise text a bit */
|
||||
rect->ymin += 6;
|
||||
rect->xmin -= 6;
|
||||
}
|
||||
|
||||
static void widget_link(uiBut *but, uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
|
||||
{
|
||||
|
||||
|
||||
if(but->flag & UI_SELECT) {
|
||||
rcti rectlink;
|
||||
|
||||
@@ -2094,7 +2142,6 @@ static void widget_link(uiBut *but, uiWidgetColors *wcol, rcti *rect, int state,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void widget_numslider(uiBut *but, uiWidgetColors *wcol, rcti *rect, int state, int roundboxalign)
|
||||
{
|
||||
uiWidgetBase wtb, wtb1;
|
||||
@@ -2541,6 +2588,11 @@ static uiWidgetType *widget_type(uiWidgetTypeEnum type)
|
||||
wt.wcol_theme= &btheme->tui.wcol_list_item;
|
||||
wt.draw= widget_list_itembut;
|
||||
break;
|
||||
|
||||
case UI_WTYPE_PROGRESSBAR:
|
||||
wt.wcol_theme= &btheme->tui.wcol_progress;
|
||||
wt.custom= widget_progressbar;
|
||||
break;
|
||||
}
|
||||
|
||||
return &wt;
|
||||
@@ -2756,6 +2808,11 @@ void ui_draw_but(const bContext *C, ARegion *ar, uiStyle *style, uiBut *but, rct
|
||||
case BUT_CURVE:
|
||||
ui_draw_but_CURVE(ar, but, &tui->wcol_regular, rect);
|
||||
break;
|
||||
|
||||
case PROGRESSBAR:
|
||||
wt= widget_type(UI_WTYPE_PROGRESSBAR);
|
||||
fstyle= &style->widgetlabel;
|
||||
break;
|
||||
|
||||
case SCROLL:
|
||||
wt= widget_type(UI_WTYPE_SCROLL);
|
||||
|
||||
@@ -1463,6 +1463,28 @@ void init_userdef_do_versions(void)
|
||||
SETCOL(btheme->tv3d.lastsel_point, 0xff, 0xff, 0xff, 255);
|
||||
}
|
||||
}
|
||||
if (G.main->versionfile <= 252 || (G.main->versionfile == 252 && G.main->subversionfile < 5)) {
|
||||
bTheme *btheme;
|
||||
|
||||
/* interface_widgets.c */
|
||||
struct uiWidgetColors wcol_progress= {
|
||||
{0, 0, 0, 255},
|
||||
{190, 190, 190, 255},
|
||||
{100, 100, 100, 180},
|
||||
{68, 68, 68, 255},
|
||||
|
||||
{0, 0, 0, 255},
|
||||
{255, 255, 255, 255},
|
||||
|
||||
0,
|
||||
5, -5
|
||||
};
|
||||
|
||||
for(btheme= U.themes.first; btheme; btheme= btheme->next) {
|
||||
/* init progress bar theme */
|
||||
btheme->tui.wcol_progress= wcol_progress;
|
||||
}
|
||||
}
|
||||
|
||||
/* GL Texture Garbage Collection (variable abused above!) */
|
||||
if (U.textimeout == 0) {
|
||||
|
||||
@@ -102,7 +102,8 @@ typedef struct BakeRender {
|
||||
|
||||
short *stop;
|
||||
short *do_update;
|
||||
|
||||
float *progress;
|
||||
|
||||
ListBase threads;
|
||||
|
||||
/* backup */
|
||||
@@ -185,19 +186,20 @@ static void *do_bake_render(void *bake_v)
|
||||
{
|
||||
BakeRender *bkr= bake_v;
|
||||
|
||||
bkr->tot= RE_bake_shade_all_selected(bkr->re, bkr->scene->r.bake_mode, bkr->actob, NULL);
|
||||
bkr->tot= RE_bake_shade_all_selected(bkr->re, bkr->scene->r.bake_mode, bkr->actob, NULL, bkr->progress);
|
||||
bkr->ready= 1;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void bake_startjob(void *bkv, short *stop, short *do_update)
|
||||
static void bake_startjob(void *bkv, short *stop, short *do_update, float *progress)
|
||||
{
|
||||
BakeRender *bkr= bkv;
|
||||
Scene *scene= bkr->scene;
|
||||
|
||||
bkr->stop= stop;
|
||||
bkr->do_update= do_update;
|
||||
bkr->progress= progress;
|
||||
|
||||
RE_test_break_cb(bkr->re, NULL, thread_break);
|
||||
G.afbreek= 0; /* blender_test_break uses this global */
|
||||
@@ -205,7 +207,7 @@ static void bake_startjob(void *bkv, short *stop, short *do_update)
|
||||
RE_Database_Baking(bkr->re, scene, scene->lay, scene->r.bake_mode, bkr->actob);
|
||||
|
||||
/* baking itself is threaded, cannot use test_break in threads. we also update optional imagewindow */
|
||||
bkr->tot= RE_bake_shade_all_selected(bkr->re, scene->r.bake_mode, bkr->actob, bkr->do_update);
|
||||
bkr->tot= RE_bake_shade_all_selected(bkr->re, scene->r.bake_mode, bkr->actob, bkr->do_update, bkr->progress);
|
||||
}
|
||||
|
||||
static void bake_update(void *bkv)
|
||||
@@ -260,7 +262,7 @@ static int objects_bake_render_invoke(bContext *C, wmOperator *op, wmEvent *_eve
|
||||
bkr->reports= op->reports;
|
||||
|
||||
/* setup job */
|
||||
steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, WM_JOB_EXCL_RENDER|WM_JOB_PRIORITY);
|
||||
steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Texture Bake", WM_JOB_EXCL_RENDER|WM_JOB_PRIORITY|WM_JOB_PROGRESS);
|
||||
WM_jobs_customdata(steve, bkr, bake_freejob);
|
||||
WM_jobs_timer(steve, 0.2, NC_IMAGE, 0); /* TODO - only draw bake image, can we enforce this */
|
||||
WM_jobs_callbacks(steve, bake_startjob, NULL, bake_update, NULL);
|
||||
|
||||
@@ -708,7 +708,7 @@ typedef struct FluidBakeJob {
|
||||
/* from wmJob */
|
||||
void *owner;
|
||||
short *stop, *do_update;
|
||||
|
||||
float *progress;
|
||||
int current_frame;
|
||||
elbeemSimulationSettings *settings;
|
||||
} FluidBakeJob;
|
||||
@@ -732,19 +732,21 @@ static int fluidbake_breakjob(void *customdata)
|
||||
}
|
||||
|
||||
/* called by fluidbake, wmJob sends notifier */
|
||||
static void fluidbake_updatejob(void *customdata, char *str)
|
||||
static void fluidbake_updatejob(void *customdata, float progress)
|
||||
{
|
||||
FluidBakeJob *fb= customdata;
|
||||
|
||||
*(fb->do_update)= 1;
|
||||
*(fb->progress)= progress;
|
||||
}
|
||||
|
||||
static void fluidbake_startjob(void *customdata, short *stop, short *do_update)
|
||||
static void fluidbake_startjob(void *customdata, short *stop, short *do_update, float *progress)
|
||||
{
|
||||
FluidBakeJob *fb= customdata;
|
||||
|
||||
fb->stop= stop;
|
||||
fb->do_update = do_update;
|
||||
fb->progress = progress;
|
||||
|
||||
G.afbreek= 0; /* XXX shared with render - replace with job 'stop' switch */
|
||||
|
||||
@@ -753,14 +755,24 @@ static void fluidbake_startjob(void *customdata, short *stop, short *do_update)
|
||||
*stop = 0;
|
||||
}
|
||||
|
||||
static void fluidbake_endjob(void *customdata)
|
||||
{
|
||||
FluidBakeJob *fb= customdata;
|
||||
|
||||
if (fb->settings) {
|
||||
MEM_freeN(fb->settings);
|
||||
fb->settings = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int runSimulationCallback(void *data, int status, int frame) {
|
||||
FluidBakeJob *fb = (FluidBakeJob *)data;
|
||||
|
||||
//elbeemSimulationSettings *settings = fb->settings;
|
||||
elbeemSimulationSettings *settings = fb->settings;
|
||||
//printf("elbeem blender cb s%d, f%d, domainid:%d \n", status,frame, settings->domainId ); // DEBUG
|
||||
|
||||
if (status == FLUIDSIM_CBSTATUS_NEWFRAME)
|
||||
fluidbake_updatejob(fb, "");
|
||||
if (status == FLUIDSIM_CBSTATUS_NEWFRAME) {
|
||||
fluidbake_updatejob(fb, frame / (float)settings->noOfFrames);
|
||||
}
|
||||
|
||||
if (fluidbake_breakjob(fb)) {
|
||||
return FLUIDSIM_CBRET_ABORT;
|
||||
@@ -799,9 +811,9 @@ int fluidsimBake(bContext *C, ReportList *reports, Object *fsDomain)
|
||||
|
||||
wmJob *steve;
|
||||
FluidBakeJob *fb;
|
||||
elbeemSimulationSettings fsset;
|
||||
elbeemSimulationSettings *fsset= MEM_callocN(sizeof(elbeemSimulationSettings), "Fluid sim settings");
|
||||
|
||||
steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, 0);
|
||||
steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Fluid Sim", WM_JOB_PROGRESS);
|
||||
fb= MEM_callocN(sizeof(FluidBakeJob), "fluid bake job");
|
||||
|
||||
if(getenv(strEnvName)) {
|
||||
@@ -902,7 +914,7 @@ int fluidsimBake(bContext *C, ReportList *reports, Object *fsDomain)
|
||||
for(i=2; i<=allchannelSize; i++) {
|
||||
timeAtFrame[i] = timeAtFrame[i-1]+channelDomainTime[(i-1)*2+0];
|
||||
}
|
||||
} else {
|
||||
fsset->} else {
|
||||
for(i=2; i<=allchannelSize; i++) { timeAtFrame[i] = timeAtFrame[i-1]+aniFrameTime; }
|
||||
}
|
||||
|
||||
@@ -936,76 +948,77 @@ int fluidsimBake(bContext *C, ReportList *reports, Object *fsDomain)
|
||||
}
|
||||
|
||||
/* ******** export domain to elbeem ******** */
|
||||
elbeemResetSettings(&fsset);
|
||||
fsset.version = 1;
|
||||
elbeemResetSettings(fsset);
|
||||
fsset->version = 1;
|
||||
|
||||
// setup global settings
|
||||
copy_v3_v3(fsset.geoStart, domainSettings->bbStart);
|
||||
copy_v3_v3(fsset.geoSize, domainSettings->bbSize);
|
||||
copy_v3_v3(fsset->geoStart, domainSettings->bbStart);
|
||||
copy_v3_v3(fsset->geoSize, domainSettings->bbSize);
|
||||
|
||||
// simulate with 50^3
|
||||
fsset.resolutionxyz = (int)domainSettings->resolutionxyz;
|
||||
fsset.previewresxyz = (int)domainSettings->previewresxyz;
|
||||
fsset->resolutionxyz = (int)domainSettings->resolutionxyz;
|
||||
fsset->previewresxyz = (int)domainSettings->previewresxyz;
|
||||
|
||||
fsset.realsize = get_fluid_size_m(scene, fsDomain, domainSettings);
|
||||
fsset.viscosity = get_fluid_viscosity(domainSettings);
|
||||
get_fluid_gravity(fsset.gravity, scene, domainSettings);
|
||||
fsset->realsize = get_fluid_size_m(scene, fsDomain, domainSettings);
|
||||
fsset->viscosity = get_fluid_viscosity(domainSettings);
|
||||
get_fluid_gravity(fsset->gravity, scene, domainSettings);
|
||||
|
||||
// simulate 5 frames, each 0.03 seconds, output to ./apitest_XXX.bobj.gz
|
||||
fsset.animStart = domainSettings->animStart;
|
||||
fsset.aniFrameTime = channels->aniFrameTime;
|
||||
fsset.noOfFrames = noFrames; // is otherwise subtracted in parser
|
||||
fsset->animStart = domainSettings->animStart;
|
||||
fsset->aniFrameTime = channels->aniFrameTime;
|
||||
fsset->noOfFrames = noFrames; // is otherwise subtracted in parser
|
||||
|
||||
strcpy(targetFile, targetDir);
|
||||
strcat(targetFile, suffixSurface);
|
||||
// defaults for compressibility and adaptive grids
|
||||
fsset.gstar = domainSettings->gstar;
|
||||
fsset.maxRefine = domainSettings->maxRefine; // check <-> gridlevels
|
||||
fsset.generateParticles = domainSettings->generateParticles;
|
||||
fsset.numTracerParticles = domainSettings->generateTracers;
|
||||
fsset.surfaceSmoothing = domainSettings->surfaceSmoothing;
|
||||
fsset.surfaceSubdivs = domainSettings->surfaceSubdivs;
|
||||
fsset.farFieldSize = domainSettings->farFieldSize;
|
||||
strcpy( fsset.outputPath, targetFile);
|
||||
fsset->gstar = domainSettings->gstar;
|
||||
fsset->maxRefine = domainSettings->maxRefine; // check <-> gridlevels
|
||||
fsset->generateParticles = domainSettings->generateParticles;
|
||||
fsset->numTracerParticles = domainSettings->generateTracers;
|
||||
fsset->surfaceSmoothing = domainSettings->surfaceSmoothing;
|
||||
fsset->surfaceSubdivs = domainSettings->surfaceSubdivs;
|
||||
fsset->farFieldSize = domainSettings->farFieldSize;
|
||||
strcpy( fsset->outputPath, targetFile);
|
||||
|
||||
// domain channels
|
||||
fsset.channelSizeFrameTime =
|
||||
fsset.channelSizeViscosity =
|
||||
fsset.channelSizeGravity = channels->length;
|
||||
fsset.channelFrameTime = channels->DomainTime;
|
||||
fsset.channelViscosity = channels->DomainViscosity;
|
||||
fsset.channelGravity = channels->DomainGravity;
|
||||
fsset->channelSizeFrameTime =
|
||||
fsset->channelSizeViscosity =
|
||||
fsset->channelSizeGravity = channels->length;
|
||||
fsset->channelFrameTime = channels->DomainTime;
|
||||
fsset->channelViscosity = channels->DomainViscosity;
|
||||
fsset->channelGravity = channels->DomainGravity;
|
||||
|
||||
fsset.runsimCallback = &runSimulationCallback;
|
||||
fsset.runsimUserData = fb;
|
||||
fsset->runsimCallback = &runSimulationCallback;
|
||||
fsset->runsimUserData = fb;
|
||||
|
||||
if (domainSettings->typeFlags & OB_FSBND_NOSLIP) fsset.domainobsType = FLUIDSIM_OBSTACLE_NOSLIP;
|
||||
else if (domainSettings->typeFlags&OB_FSBND_PARTSLIP) fsset.domainobsType = FLUIDSIM_OBSTACLE_PARTSLIP;
|
||||
else if (domainSettings->typeFlags&OB_FSBND_FREESLIP) fsset.domainobsType = FLUIDSIM_OBSTACLE_FREESLIP;
|
||||
fsset.domainobsPartslip = domainSettings->partSlipValue;
|
||||
fsset.generateVertexVectors = (domainSettings->domainNovecgen==0);
|
||||
if (domainSettings->typeFlags & OB_FSBND_NOSLIP) fsset->domainobsType = FLUIDSIM_OBSTACLE_NOSLIP;
|
||||
else if (domainSettings->typeFlags&OB_FSBND_PARTSLIP) fsset->domainobsType = FLUIDSIM_OBSTACLE_PARTSLIP;
|
||||
else if (domainSettings->typeFlags&OB_FSBND_FREESLIP) fsset->domainobsType = FLUIDSIM_OBSTACLE_FREESLIP;
|
||||
fsset->domainobsPartslip = domainSettings->partSlipValue;
|
||||
fsset->generateVertexVectors = (domainSettings->domainNovecgen==0);
|
||||
|
||||
// init blender domain transform matrix
|
||||
{ int j;
|
||||
for(i=0; i<4; i++) {
|
||||
for(j=0; j<4; j++) {
|
||||
fsset.surfaceTrafo[i*4+j] = invDomMat[j][i];
|
||||
fsset->surfaceTrafo[i*4+j] = invDomMat[j][i];
|
||||
}
|
||||
} }
|
||||
|
||||
/* ******** init solver with settings ******** */
|
||||
elbeemInit();
|
||||
elbeemAddDomain(&fsset);
|
||||
elbeemAddDomain(fsset);
|
||||
|
||||
/* ******** export all fluid objects to elbeem ******** */
|
||||
export_fluid_objects(fobjects, scene, channels->length);
|
||||
|
||||
/* custom data for fluid bake job */
|
||||
fb->settings = &fsset;
|
||||
fb->settings = fsset;
|
||||
|
||||
/* setup job */
|
||||
WM_jobs_customdata(steve, fb, fluidbake_free);
|
||||
WM_jobs_timer(steve, 0.1, NC_SCENE|ND_FRAME, NC_SCENE|ND_FRAME);
|
||||
WM_jobs_callbacks(steve, fluidbake_startjob, NULL, NULL, NULL);
|
||||
WM_jobs_callbacks(steve, fluidbake_startjob, NULL, NULL, fluidbake_endjob);
|
||||
|
||||
WM_jobs_start(CTX_wm_manager(C), steve);
|
||||
|
||||
|
||||
@@ -441,6 +441,7 @@ typedef struct RenderJob {
|
||||
ImageUser iuser;
|
||||
short *stop;
|
||||
short *do_update;
|
||||
float *progress;
|
||||
ReportList *reports;
|
||||
} RenderJob;
|
||||
|
||||
@@ -519,6 +520,14 @@ static void image_renderinfo_cb(void *rjv, RenderStats *rs)
|
||||
|
||||
}
|
||||
|
||||
static void render_progress_update(void *rjv, float progress)
|
||||
{
|
||||
RenderJob *rj= rjv;
|
||||
|
||||
if (rj->progress)
|
||||
*rj->progress = progress;
|
||||
}
|
||||
|
||||
static void image_rect_update(void *rjv, RenderResult *rr, volatile rcti *renrect)
|
||||
{
|
||||
RenderJob *rj= rjv;
|
||||
@@ -540,13 +549,14 @@ static void image_rect_update(void *rjv, RenderResult *rr, volatile rcti *renrec
|
||||
BKE_image_release_ibuf(ima, lock);
|
||||
}
|
||||
|
||||
static void render_startjob(void *rjv, short *stop, short *do_update)
|
||||
static void render_startjob(void *rjv, short *stop, short *do_update, float *progress)
|
||||
{
|
||||
RenderJob *rj= rjv;
|
||||
// Main *mainp= BKE_undo_get_main(&rj->scene);
|
||||
|
||||
rj->stop= stop;
|
||||
rj->do_update= do_update;
|
||||
rj->progress= progress;
|
||||
|
||||
if(rj->anim)
|
||||
RE_BlenderAnim(rj->re, rj->scene, rj->lay, rj->scene->r.sfra, rj->scene->r.efra, rj->scene->r.frame_step, rj->reports);
|
||||
@@ -663,7 +673,7 @@ static int screen_render_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
||||
rj->reports= op->reports;
|
||||
|
||||
/* setup job */
|
||||
steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, WM_JOB_EXCL_RENDER|WM_JOB_PRIORITY);
|
||||
steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Render", WM_JOB_EXCL_RENDER|WM_JOB_PRIORITY|WM_JOB_PROGRESS);
|
||||
WM_jobs_customdata(steve, rj, render_freejob);
|
||||
WM_jobs_timer(steve, 0.2, NC_SCENE|ND_RENDER_RESULT, 0);
|
||||
WM_jobs_callbacks(steve, render_startjob, NULL, NULL, render_endjob);
|
||||
@@ -679,6 +689,7 @@ static int screen_render_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
||||
RE_test_break_cb(re, rj, render_breakjob);
|
||||
RE_display_draw_cb(re, rj, image_rect_update);
|
||||
RE_stats_draw_cb(re, rj, image_renderinfo_cb);
|
||||
RE_progress_cb(re, rj, render_progress_update);
|
||||
|
||||
rj->re= re;
|
||||
G.afbreek= 0;
|
||||
|
||||
@@ -1090,7 +1090,7 @@ static void icon_preview_startjob(void *customdata, short *stop, short *do_updat
|
||||
/* use same function for icon & shader, so the job manager
|
||||
does not run two of them at the same time. */
|
||||
|
||||
static void common_preview_startjob(void *customdata, short *stop, short *do_update)
|
||||
static void common_preview_startjob(void *customdata, short *stop, short *do_update, float *progress)
|
||||
{
|
||||
ShaderPreview *sp= customdata;
|
||||
|
||||
@@ -1107,7 +1107,7 @@ void ED_preview_icon_job(const bContext *C, void *owner, ID *id, unsigned int *r
|
||||
wmJob *steve;
|
||||
ShaderPreview *sp;
|
||||
|
||||
steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), owner, WM_JOB_EXCL_RENDER);
|
||||
steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), owner, "Icon Preview", WM_JOB_EXCL_RENDER);
|
||||
sp= MEM_callocN(sizeof(ShaderPreview), "shader preview");
|
||||
|
||||
/* customdata for preview thread */
|
||||
@@ -1132,7 +1132,7 @@ void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, M
|
||||
wmJob *steve;
|
||||
ShaderPreview *sp;
|
||||
|
||||
steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), owner, WM_JOB_EXCL_RENDER);
|
||||
steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), owner, "Shader Preview", WM_JOB_EXCL_RENDER);
|
||||
sp= MEM_callocN(sizeof(ShaderPreview), "shader preview");
|
||||
|
||||
/* customdata for preview thread */
|
||||
|
||||
@@ -215,7 +215,7 @@ static void screenshot_updatejob(void *sjv)
|
||||
|
||||
|
||||
/* only this runs inside thread */
|
||||
static void screenshot_startjob(void *sjv, short *stop, short *do_update)
|
||||
static void screenshot_startjob(void *sjv, short *stop, short *do_update, float *progress)
|
||||
{
|
||||
ScreenshotJob *sj= sjv;
|
||||
RenderData rd= sj->scene->r;
|
||||
@@ -296,7 +296,7 @@ static void screenshot_startjob(void *sjv, short *stop, short *do_update)
|
||||
static int screencast_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
bScreen *screen= CTX_wm_screen(C);
|
||||
wmJob *steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), screen, 0);
|
||||
wmJob *steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), screen, "Screencast", 0);
|
||||
ScreenshotJob *sj= MEM_callocN(sizeof(ScreenshotJob), "screenshot job");
|
||||
|
||||
/* setup sj */
|
||||
|
||||
@@ -1269,7 +1269,7 @@ static void thumbnail_joblist_free(ThumbnailJob *tj)
|
||||
BLI_freelistN(&tj->loadimages);
|
||||
}
|
||||
|
||||
static void thumbnails_startjob(void *tjv, short *stop, short *do_update)
|
||||
static void thumbnails_startjob(void *tjv, short *stop, short *do_update, float *progress)
|
||||
{
|
||||
ThumbnailJob *tj= tjv;
|
||||
FileImage* limg = tj->loadimages.first;
|
||||
@@ -1349,7 +1349,7 @@ void thumbnails_start(struct FileList* filelist, const struct bContext* C)
|
||||
BKE_reports_init(&tj->reports, RPT_PRINT);
|
||||
|
||||
/* setup job */
|
||||
steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), filelist, 0);
|
||||
steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), filelist, "Thumbnails", 0);
|
||||
WM_jobs_customdata(steve, tj, thumbnails_free);
|
||||
WM_jobs_timer(steve, 0.5, NC_WINDOW, NC_WINDOW);
|
||||
WM_jobs_callbacks(steve, thumbnails_startjob, NULL, thumbnails_update, NULL);
|
||||
|
||||
@@ -156,6 +156,10 @@ static void info_header_listener(ARegion *ar, wmNotifier *wmn)
|
||||
if(ELEM(wmn->data, ND_SCREENCAST, ND_ANIMPLAY))
|
||||
ED_region_tag_redraw(ar);
|
||||
break;
|
||||
case NC_WM:
|
||||
if(wmn->data == ND_JOB)
|
||||
ED_region_tag_redraw(ar);
|
||||
break;
|
||||
case NC_SCENE:
|
||||
if(wmn->data==ND_RENDER_RESULT)
|
||||
ED_region_tag_redraw(ar);
|
||||
|
||||
@@ -88,6 +88,7 @@ typedef struct CompoJob {
|
||||
bNodeTree *localtree;
|
||||
short *stop;
|
||||
short *do_update;
|
||||
float *progress;
|
||||
} CompoJob;
|
||||
|
||||
/* called by compo, only to check job 'stop' value */
|
||||
@@ -133,9 +134,16 @@ static void compo_updatejob(void *cjv)
|
||||
ntreeLocalSync(cj->localtree, cj->ntree);
|
||||
}
|
||||
|
||||
static void compo_progressjob(void *cjv, float progress)
|
||||
{
|
||||
CompoJob *cj= cjv;
|
||||
|
||||
*(cj->progress) = progress;
|
||||
}
|
||||
|
||||
|
||||
/* only this runs inside thread */
|
||||
static void compo_startjob(void *cjv, short *stop, short *do_update)
|
||||
static void compo_startjob(void *cjv, short *stop, short *do_update, float *progress)
|
||||
{
|
||||
CompoJob *cj= cjv;
|
||||
bNodeTree *ntree= cj->localtree;
|
||||
@@ -145,11 +153,14 @@ static void compo_startjob(void *cjv, short *stop, short *do_update)
|
||||
|
||||
cj->stop= stop;
|
||||
cj->do_update= do_update;
|
||||
cj->progress= progress;
|
||||
|
||||
ntree->test_break= compo_breakjob;
|
||||
ntree->tbh= cj;
|
||||
ntree->stats_draw= compo_redrawjob;
|
||||
ntree->sdh= cj;
|
||||
ntree->progress= compo_progressjob;
|
||||
ntree->prh= cj;
|
||||
|
||||
// XXX BIF_store_spare();
|
||||
|
||||
@@ -157,6 +168,7 @@ static void compo_startjob(void *cjv, short *stop, short *do_update)
|
||||
|
||||
ntree->test_break= NULL;
|
||||
ntree->stats_draw= NULL;
|
||||
ntree->progress= NULL;
|
||||
|
||||
}
|
||||
|
||||
@@ -166,7 +178,7 @@ void snode_composite_job(const bContext *C, ScrArea *sa)
|
||||
wmJob *steve;
|
||||
CompoJob *cj;
|
||||
|
||||
steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), sa, WM_JOB_EXCL_RENDER);
|
||||
steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), sa, "Compositing", WM_JOB_EXCL_RENDER|WM_JOB_PROGRESS);
|
||||
cj= MEM_callocN(sizeof(CompoJob), "compo job");
|
||||
|
||||
/* customdata for preview thread */
|
||||
|
||||
@@ -186,10 +186,10 @@ typedef struct bNodeTree {
|
||||
int pad2[2];
|
||||
|
||||
/* callbacks */
|
||||
void (*timecursor)(void *, int nr);
|
||||
void (*progress)(void *, float progress);
|
||||
void (*stats_draw)(void *, char *str);
|
||||
int (*test_break)(void *);
|
||||
void *tbh, *tch, *sdh;
|
||||
void *tbh, *prh, *sdh;
|
||||
|
||||
} bNodeTree;
|
||||
|
||||
|
||||
@@ -139,8 +139,8 @@ typedef struct ThemeUI {
|
||||
uiWidgetColors wcol_radio, wcol_option, wcol_toggle;
|
||||
uiWidgetColors wcol_num, wcol_numslider;
|
||||
uiWidgetColors wcol_menu, wcol_pulldown, wcol_menu_back, wcol_menu_item;
|
||||
uiWidgetColors wcol_box, wcol_scroll, wcol_list_item;
|
||||
|
||||
uiWidgetColors wcol_box, wcol_scroll, wcol_progress, wcol_list_item;
|
||||
|
||||
uiWidgetStateColors wcol_state;
|
||||
|
||||
char iconfile[80]; // FILE_MAXFILE length
|
||||
|
||||
@@ -524,6 +524,13 @@ static void rna_def_userdef_theme_ui(BlenderRNA *brna)
|
||||
RNA_def_property_struct_type(prop, "ThemeWidgetColors");
|
||||
RNA_def_property_ui_text(prop, "Scroll Widget Colors", "");
|
||||
RNA_def_property_update(prop, 0, "rna_userdef_update");
|
||||
|
||||
prop= RNA_def_property(srna, "wcol_progress", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_flag(prop, PROP_NEVER_NULL);
|
||||
RNA_def_property_pointer_sdna(prop, NULL, "wcol_progress");
|
||||
RNA_def_property_struct_type(prop, "ThemeWidgetColors");
|
||||
RNA_def_property_ui_text(prop, "Progress Bar Widget Colors", "");
|
||||
RNA_def_property_update(prop, 0, "rna_userdef_update");
|
||||
|
||||
prop= RNA_def_property(srna, "wcol_list_item", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_flag(prop, PROP_NEVER_NULL);
|
||||
|
||||
@@ -230,7 +230,7 @@ void RE_display_init_cb (struct Render *re, void *handle, void (*f)(void *handle
|
||||
void RE_display_clear_cb(struct Render *re, void *handle, void (*f)(void *handle, RenderResult *rr));
|
||||
void RE_display_draw_cb (struct Render *re, void *handle, void (*f)(void *handle, RenderResult *rr, volatile struct rcti *rect));
|
||||
void RE_stats_draw_cb (struct Render *re, void *handle, void (*f)(void *handle, RenderStats *rs));
|
||||
void RE_timecursor_cb (struct Render *re, void *handle, void (*f)(void *handle, int));
|
||||
void RE_progress_cb (struct Render *re, void *handle, void (*f)(void *handle, float));
|
||||
void RE_test_break_cb (struct Render *re, void *handle, int (*f)(void *handle));
|
||||
void RE_error_cb (struct Render *re, void *handle, void (*f)(void *handle, char *str));
|
||||
|
||||
|
||||
@@ -199,7 +199,7 @@ struct Image;
|
||||
struct Object;
|
||||
|
||||
void RE_shade_external(struct Render *re, struct ShadeInput *shi, struct ShadeResult *shr);
|
||||
int RE_bake_shade_all_selected(struct Render *re, int type, struct Object *actob, short *do_update);
|
||||
int RE_bake_shade_all_selected(struct Render *re, int type, struct Object *actob, short *do_update, float *progress);
|
||||
struct Image *RE_bake_shade_get_image(void);
|
||||
|
||||
#endif /* RE_SHADER_EXT_H */
|
||||
|
||||
@@ -234,8 +234,8 @@ struct Render
|
||||
|
||||
void (*stats_draw)(void *handle, RenderStats *ri);
|
||||
void *sdh;
|
||||
void (*timecursor)(void *handle, int i);
|
||||
void *tch;
|
||||
void (*progress)(void *handle, float i);
|
||||
void *prh;
|
||||
|
||||
int (*test_break)(void *handle);
|
||||
void *tbh;
|
||||
|
||||
@@ -131,7 +131,7 @@ static int thread_break(void *unused)
|
||||
static void result_nothing(void *unused, RenderResult *rr) {}
|
||||
static void result_rcti_nothing(void *unused, RenderResult *rr, volatile struct rcti *rect) {}
|
||||
static void stats_nothing(void *unused, RenderStats *rs) {}
|
||||
static void int_nothing(void *unused, int val) {}
|
||||
static void float_nothing(void *unused, float val) {}
|
||||
static void print_error(void *unused, char *str) {printf("ERROR: %s\n", str);}
|
||||
static int default_break(void *unused) {return G.afbreek == 1;}
|
||||
|
||||
@@ -1162,7 +1162,7 @@ Render *RE_NewRender(const char *name)
|
||||
re->display_init= result_nothing;
|
||||
re->display_clear= result_nothing;
|
||||
re->display_draw= result_rcti_nothing;
|
||||
re->timecursor= int_nothing;
|
||||
re->progress= float_nothing;
|
||||
re->test_break= default_break;
|
||||
re->error= print_error;
|
||||
if(G.background)
|
||||
@@ -1170,7 +1170,7 @@ Render *RE_NewRender(const char *name)
|
||||
else
|
||||
re->stats_draw= stats_nothing;
|
||||
/* clear callback handles */
|
||||
re->dih= re->dch= re->ddh= re->sdh= re->tch= re->tbh= re->erh= NULL;
|
||||
re->dih= re->dch= re->ddh= re->sdh= re->prh= re->tbh= re->erh= NULL;
|
||||
|
||||
/* init some variables */
|
||||
re->ycor= 1.0f;
|
||||
@@ -1374,10 +1374,10 @@ void RE_stats_draw_cb(Render *re, void *handle, void (*f)(void *handle, RenderSt
|
||||
re->stats_draw= f;
|
||||
re->sdh= handle;
|
||||
}
|
||||
void RE_timecursor_cb(Render *re, void *handle, void (*f)(void *handle, int))
|
||||
void RE_progress_cb(Render *re, void *handle, void (*f)(void *handle, float))
|
||||
{
|
||||
re->timecursor= f;
|
||||
re->tch= handle;
|
||||
re->progress= f;
|
||||
re->prh= handle;
|
||||
}
|
||||
|
||||
void RE_test_break_cb(Render *re, void *handle, int (*f)(void *handle))
|
||||
@@ -1694,6 +1694,7 @@ static void threaded_tile_processor(Render *re)
|
||||
free_render_result(&pa->fullresult, pa->result);
|
||||
pa->result= NULL;
|
||||
re->i.partsdone++;
|
||||
re->progress(re->prh, re->i.partsdone / (float)re->i.totpart);
|
||||
hasdrawn= 1;
|
||||
}
|
||||
}
|
||||
@@ -2376,8 +2377,11 @@ static void do_render_composite_fields_blur_3d(Render *re)
|
||||
if(!re->test_break(re->tbh)) {
|
||||
ntree->stats_draw= render_composit_stats;
|
||||
ntree->test_break= re->test_break;
|
||||
ntree->progress= re->progress;
|
||||
ntree->sdh= re->sdh;
|
||||
ntree->tbh= re->tbh;
|
||||
ntree->prh= re->prh;
|
||||
|
||||
/* in case it was never initialized */
|
||||
R.sdh= re->sdh;
|
||||
R.stats_draw= re->stats_draw;
|
||||
@@ -2393,7 +2397,8 @@ static void do_render_composite_fields_blur_3d(Render *re)
|
||||
|
||||
ntree->stats_draw= NULL;
|
||||
ntree->test_break= NULL;
|
||||
ntree->tbh= ntree->sdh= NULL;
|
||||
ntree->progress= NULL;
|
||||
ntree->tbh= ntree->sdh= ntree->prh= NULL;
|
||||
}
|
||||
}
|
||||
else if(re->r.scemode & R_FULL_SAMPLE)
|
||||
|
||||
@@ -2619,7 +2619,7 @@ static void *do_bake_thread(void *bs_v)
|
||||
/* using object selection tags, the faces with UV maps get baked */
|
||||
/* render should have been setup */
|
||||
/* returns 0 if nothing was handled */
|
||||
int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_update)
|
||||
int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_update, float *progress)
|
||||
{
|
||||
BakeShade *handles;
|
||||
ListBase threads;
|
||||
@@ -2680,12 +2680,18 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up
|
||||
/* wait for everything to be done */
|
||||
a= 0;
|
||||
while(a!=re->r.threads) {
|
||||
|
||||
PIL_sleep_ms(50);
|
||||
|
||||
for(a=0; a<re->r.threads; a++)
|
||||
/* calculate progress */
|
||||
for(vdone=0, a=0; a<re->r.threads; a++)
|
||||
vdone+= handles[a].vdone;
|
||||
if (progress)
|
||||
*progress = (float)(vdone / (float)re->totvlak);
|
||||
|
||||
for(a=0; a<re->r.threads; a++) {
|
||||
if(handles[a].ready==0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* filter and refresh images */
|
||||
@@ -2733,12 +2739,10 @@ int RE_bake_shade_all_selected(Render *re, int type, Object *actob, short *do_up
|
||||
}
|
||||
|
||||
/* calculate return value */
|
||||
for(a=0; a<re->r.threads; a++) {
|
||||
vdone+= handles[a].vdone;
|
||||
|
||||
for(a=0; a<re->r.threads; a++) {
|
||||
zbuf_free_span(handles[a].zspan);
|
||||
MEM_freeN(handles[a].zspan);
|
||||
}
|
||||
}
|
||||
|
||||
MEM_freeN(handles);
|
||||
|
||||
|
||||
@@ -299,15 +299,18 @@ int WM_framebuffer_to_index(unsigned int col);
|
||||
/* threaded Jobs Manager */
|
||||
#define WM_JOB_PRIORITY 1
|
||||
#define WM_JOB_EXCL_RENDER 2
|
||||
#define WM_JOB_PROGRESS 4
|
||||
|
||||
struct wmJob *WM_jobs_get(struct wmWindowManager *wm, struct wmWindow *win, void *owner, int flag);
|
||||
struct wmJob *WM_jobs_get(struct wmWindowManager *wm, struct wmWindow *win, void *owner, char *name, int flag);
|
||||
|
||||
int WM_jobs_test(struct wmWindowManager *wm, void *owner);
|
||||
float WM_jobs_progress(struct wmWindowManager *wm, void *owner);
|
||||
char *WM_jobs_name(struct wmWindowManager *wm, void *owner);
|
||||
|
||||
void WM_jobs_customdata(struct wmJob *, void *customdata, void (*free)(void *));
|
||||
void WM_jobs_timer(struct wmJob *, double timestep, unsigned int note, unsigned int endnote);
|
||||
void WM_jobs_callbacks(struct wmJob *,
|
||||
void (*startjob)(void *, short *, short *),
|
||||
void (*startjob)(void *, short *, short *, float *),
|
||||
void (*initjob)(void *),
|
||||
void (*update)(void *),
|
||||
void (*endjob)(void *));
|
||||
|
||||
@@ -158,6 +158,7 @@ typedef struct wmNotifier {
|
||||
#define ND_FILESAVE (2<<16)
|
||||
#define ND_DATACHANGED (3<<16)
|
||||
#define ND_HISTORY (4<<16)
|
||||
#define ND_JOB (5<<16)
|
||||
|
||||
/* NC_SCREEN screen */
|
||||
#define ND_SCREENBROWSE (1<<16)
|
||||
|
||||
@@ -26,6 +26,8 @@
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "DNA_windowmanager_types.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
@@ -89,7 +91,7 @@ struct wmJob {
|
||||
/* to prevent cpu overhead, use this one which only gets called when job really starts, not in thread */
|
||||
void (*initjob)(void *);
|
||||
/* this runs inside thread, and does full job */
|
||||
void (*startjob)(void *, short *stop, short *do_update);
|
||||
void (*startjob)(void *, short *stop, short *do_update, float *progress);
|
||||
/* update gets called if thread defines so, and max once per timerstep */
|
||||
/* it runs outside thread, blocking blender, no drawing! */
|
||||
void (*update)(void *);
|
||||
@@ -109,6 +111,10 @@ struct wmJob {
|
||||
void *owner;
|
||||
int flag;
|
||||
short suspended, running, ready, do_update, stop;
|
||||
float progress;
|
||||
|
||||
/* for display in header, identification */
|
||||
char name[128];
|
||||
|
||||
/* once running, we store this separately */
|
||||
void *run_customdata;
|
||||
@@ -119,18 +125,32 @@ struct wmJob {
|
||||
|
||||
};
|
||||
|
||||
/* finds:
|
||||
* 1st priority: job with same owner and name
|
||||
* 2nd priority: job with same owner
|
||||
*/
|
||||
static wmJob *wm_job_find(wmWindowManager *wm, void *owner, char *name)
|
||||
{
|
||||
wmJob *steve, *found=NULL;
|
||||
|
||||
for(steve= wm->jobs.first; steve; steve= steve->next)
|
||||
if(steve->owner==owner) {
|
||||
found= steve;
|
||||
if (name && strcmp(steve->name, name)==0)
|
||||
return steve;
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
/* ******************* public API ***************** */
|
||||
|
||||
/* returns current or adds new job, but doesnt run it */
|
||||
/* every owner only gets a single job, adding a new one will stop running stop and
|
||||
when stopped it starts the new one */
|
||||
wmJob *WM_jobs_get(wmWindowManager *wm, wmWindow *win, void *owner, int flag)
|
||||
wmJob *WM_jobs_get(wmWindowManager *wm, wmWindow *win, void *owner, char *name, int flag)
|
||||
{
|
||||
wmJob *steve;
|
||||
|
||||
for(steve= wm->jobs.first; steve; steve= steve->next)
|
||||
if(steve->owner==owner)
|
||||
break;
|
||||
wmJob *steve= wm_job_find(wm, owner, name);
|
||||
|
||||
if(steve==NULL) {
|
||||
steve= MEM_callocN(sizeof(wmJob), "new job");
|
||||
@@ -139,6 +159,7 @@ wmJob *WM_jobs_get(wmWindowManager *wm, wmWindow *win, void *owner, int flag)
|
||||
steve->win= win;
|
||||
steve->owner= owner;
|
||||
steve->flag= flag;
|
||||
BLI_strncpy(steve->name, name, sizeof(steve->name));
|
||||
}
|
||||
|
||||
return steve;
|
||||
@@ -156,6 +177,26 @@ int WM_jobs_test(wmWindowManager *wm, void *owner)
|
||||
return 0;
|
||||
}
|
||||
|
||||
float WM_jobs_progress(wmWindowManager *wm, void *owner)
|
||||
{
|
||||
wmJob *steve= wm_job_find(wm, owner, NULL);
|
||||
|
||||
if (steve && steve->flag & WM_JOB_PROGRESS)
|
||||
return steve->progress;
|
||||
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
char *WM_jobs_name(wmWindowManager *wm, void *owner)
|
||||
{
|
||||
wmJob *steve= wm_job_find(wm, owner, NULL);
|
||||
|
||||
if (steve)
|
||||
return steve->name;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void WM_jobs_customdata(wmJob *steve, void *customdata, void (*free)(void *))
|
||||
{
|
||||
/* pending job? just free */
|
||||
@@ -179,7 +220,7 @@ void WM_jobs_timer(wmJob *steve, double timestep, unsigned int note, unsigned in
|
||||
}
|
||||
|
||||
void WM_jobs_callbacks(wmJob *steve,
|
||||
void (*startjob)(void *, short *, short *),
|
||||
void (*startjob)(void *, short *, short *, float *),
|
||||
void (*initjob)(void *),
|
||||
void (*update)(void *),
|
||||
void (*endjob)(void *))
|
||||
@@ -194,7 +235,7 @@ static void *do_job_thread(void *job_v)
|
||||
{
|
||||
wmJob *steve= job_v;
|
||||
|
||||
steve->startjob(steve->run_customdata, &steve->stop, &steve->do_update);
|
||||
steve->startjob(steve->run_customdata, &steve->stop, &steve->do_update, &steve->progress);
|
||||
steve->ready= 1;
|
||||
|
||||
return NULL;
|
||||
@@ -248,6 +289,7 @@ void WM_jobs_start(wmWindowManager *wm, wmJob *steve)
|
||||
|
||||
steve->stop= 0;
|
||||
steve->ready= 0;
|
||||
steve->progress= 0.0;
|
||||
|
||||
BLI_init_threads(&steve->threads, do_job_thread, 1);
|
||||
BLI_insert_thread(&steve->threads, steve);
|
||||
@@ -354,6 +396,9 @@ void wm_jobs_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt)
|
||||
steve->update(steve->run_customdata);
|
||||
if(steve->note)
|
||||
WM_event_add_notifier(C, steve->note, NULL);
|
||||
|
||||
if (steve->flag & WM_JOB_PROGRESS)
|
||||
WM_event_add_notifier(C, NC_WM|ND_JOB, NULL);
|
||||
steve->do_update= 0;
|
||||
}
|
||||
|
||||
@@ -375,6 +420,8 @@ void wm_jobs_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt)
|
||||
if(steve->endnote)
|
||||
WM_event_add_notifier(C, steve->endnote, NULL);
|
||||
|
||||
WM_event_add_notifier(C, NC_WM|ND_JOB, NULL);
|
||||
|
||||
/* new job added for steve? */
|
||||
if(steve->customdata) {
|
||||
WM_jobs_start(wm, steve);
|
||||
|
||||
Reference in New Issue
Block a user