/* optimized tree execute test for compositing */ static void ntreeCompositExecTreeOld(bNodeTree *ntree, RenderData *rd, int do_preview) { bNodeExec *nodeexec; bNode *node; ListBase threads; ThreadData thdata; int totnode, curnode, rendering = TRUE, n; bNodeTreeExec *exec = ntree->execdata; if (do_preview) ntreeInitPreview(ntree, 0, 0); if (!ntree->execdata) { /* XXX this is the top-level tree, so we use the ntree->execdata pointer. */ exec = ntreeCompositBeginExecTree(ntree, 1); } ntree_composite_texnode(ntree, 1); /* prevent unlucky accidents */ if (G.background) rd->scemode &= ~R_COMP_CROP; /* setup callerdata for thread callback */ thdata.rd= rd; thdata.stack= exec->stack; /* fixed seed, for example noise texture */ BLI_srandom(rd->cfra); /* sets need_exec tags in nodes */ curnode = totnode= setExecutableNodes(exec, &thdata); BLI_init_threads(&threads, exec_composite_node, rd->threads); while (rendering) { if (BLI_available_threads(&threads)) { nodeexec= getExecutableNode(exec); if (nodeexec) { node = nodeexec->node; if (ntree->progress && totnode) ntree->progress(ntree->prh, (1.0f - curnode/(float)totnode)); if (ntree->stats_draw) { char str[128]; BLI_snprintf(str, sizeof(str), "Compositing %d %s", curnode, node->name); ntree->stats_draw(ntree->sdh, str); } curnode--; node->threaddata = &thdata; node->exec= NODE_PROCESSING; BLI_insert_thread(&threads, nodeexec); } else PIL_sleep_ms(50); } else PIL_sleep_ms(50); rendering= 0; /* test for ESC */ if (ntree->test_break && ntree->test_break(ntree->tbh)) { for (node= ntree->nodes.first; node; node= node->next) node->exec |= NODE_READY; } /* check for ready ones, and if we need to continue */ for (n=0, nodeexec=exec->nodeexec; n < exec->totnodes; ++n, ++nodeexec) { node = nodeexec->node; if (node->exec & NODE_READY) { if ((node->exec & NODE_FINISHED)==0) { BLI_remove_thread(&threads, nodeexec); /* this waits for running thread to finish btw */ node->exec |= NODE_FINISHED; /* freeing unused buffers */ if (rd->scemode & R_COMP_FREE) freeExecutableNode(exec); } } else rendering= 1; } } BLI_end_threads(&threads); /* XXX top-level tree uses the ntree->execdata pointer */ ntreeCompositEndExecTree(exec, 1); }
/* call this with NULL to restore assigned ID pointers in preview scene */ static Scene *preview_prepare_scene(Scene *scene, ID *id, int id_type, ShaderPreview *sp) { Scene *sce; Base *base; if(pr_main==NULL) return NULL; sce= pr_main->scene.first; if(sce) { /* this flag tells render to not execute depsgraph or ipos etc */ sce->r.scemode |= R_PREVIEWBUTS; /* set world always back, is used now */ sce->world= pr_main->world.first; /* now: exposure copy */ if(scene->world) { sce->world->exp= scene->world->exp; sce->world->range= scene->world->range; } sce->r.color_mgt_flag = scene->r.color_mgt_flag; /* prevent overhead for small renders and icons (32) */ if(id && sp->sizex < 40) sce->r.xparts= sce->r.yparts= 1; else sce->r.xparts= sce->r.yparts= 4; /* exception: don't color manage texture previews or icons */ if((id && sp->pr_method==PR_ICON_RENDER) || id_type == ID_TE) sce->r.color_mgt_flag &= ~R_COLOR_MANAGEMENT; if((id && sp->pr_method==PR_ICON_RENDER) && id_type != ID_WO) sce->r.alphamode= R_ALPHAPREMUL; else sce->r.alphamode= R_ADDSKY; sce->r.cfra= scene->r.cfra; strcpy(sce->r.engine, scene->r.engine); if(id_type==ID_MA) { Material *mat= NULL, *origmat= (Material *)id; if(origmat) { /* work on a copy */ mat= localize_material(origmat); sp->matcopy= mat; BLI_addtail(&pr_main->mat, mat); init_render_material(mat, 0, NULL); /* call that retrieves mode_l */ end_render_material(mat); /* un-useful option */ if(sp->pr_method==PR_ICON_RENDER) mat->shade_flag &= ~MA_OBCOLOR; /* turn on raytracing if needed */ if(mat->mode_l & MA_RAYMIRROR) sce->r.mode |= R_RAYTRACE; if(mat->material_type == MA_TYPE_VOLUME) sce->r.mode |= R_RAYTRACE; if((mat->mode_l & MA_RAYTRANSP) && (mat->mode_l & MA_TRANSP)) sce->r.mode |= R_RAYTRACE; if(preview_mat_has_sss(mat, NULL)) sce->r.mode |= R_SSS; /* turn off fake shadows if needed */ /* this only works in a specific case where the preview.blend contains * an object starting with 'c' which has a material linked to it (not the obdata) * and that material has a fake shadow texture in the active texture slot */ for(base= sce->base.first; base; base= base->next) { if(base->object->id.name[2]=='c') { Material *shadmat= give_current_material(base->object, base->object->actcol); if(shadmat) { if (mat->mode & MA_SHADBUF) shadmat->septex = 0; else shadmat->septex |= 1; } } } /* turn off bounce lights for volume, * doesn't make much visual difference and slows it down too */ if(mat->material_type == MA_TYPE_VOLUME) { for(base= sce->base.first; base; base= base->next) { if(base->object->type == OB_LAMP) { /* if doesn't match 'Lamp.002' --> main key light */ if( strcmp(base->object->id.name+2, "Lamp.002") != 0 ) { base->object->restrictflag |= OB_RESTRICT_RENDER; } } } } if(sp->pr_method==PR_ICON_RENDER) { if (mat->material_type == MA_TYPE_HALO) { sce->lay= 1<<MA_FLAT; } else { sce->lay= 1<<MA_SPHERE_A; } } else { sce->lay= 1<<mat->pr_type; if(mat->nodetree && sp->pr_method==PR_NODE_RENDER) { /* two previews, they get copied by wmJob */ ntreeInitPreview(mat->nodetree, sp->sizex, sp->sizey); ntreeInitPreview(origmat->nodetree, sp->sizex, sp->sizey); } } } else { sce->r.mode &= ~(R_OSA|R_RAYTRACE|R_SSS); } for(base= sce->base.first; base; base= base->next) { if(base->object->id.name[2]=='p') { /* copy over object color, in case material uses it */ copy_v4_v4(base->object->col, sp->col); if(ELEM4(base->object->type, OB_MESH, OB_CURVE, OB_SURF, OB_MBALL)) { /* don't use assign_material, it changed mat->id.us, which shows in the UI */ Material ***matar= give_matarar(base->object); int actcol= MAX2(base->object->actcol > 0, 1) - 1; if(matar && actcol < base->object->totcol) (*matar)[actcol]= mat; } else if (base->object->type == OB_LAMP) { base->object->restrictflag &= ~OB_RESTRICT_RENDER; } } } } else if(id_type==ID_TE) { Tex *tex= NULL, *origtex= (Tex *)id; if(origtex) { tex= localize_texture(origtex); sp->texcopy= tex; BLI_addtail(&pr_main->tex, tex); } sce->lay= 1<<MA_TEXTURE; for(base= sce->base.first; base; base= base->next) { if(base->object->id.name[2]=='t') { Material *mat= give_current_material(base->object, base->object->actcol); if(mat && mat->mtex[0]) { mat->mtex[0]->tex= tex; if(tex && sp->slot) mat->mtex[0]->which_output = sp->slot->which_output; /* show alpha in this case */ if(tex==NULL || (tex->flag & TEX_PRV_ALPHA)) { mat->mtex[0]->mapto |= MAP_ALPHA; mat->alpha= 0.0f; } else { mat->mtex[0]->mapto &= ~MAP_ALPHA; mat->alpha= 1.0f; } } } } if(tex && tex->nodetree && sp->pr_method==PR_NODE_RENDER) { /* two previews, they get copied by wmJob */ ntreeInitPreview(origtex->nodetree, sp->sizex, sp->sizey); ntreeInitPreview(tex->nodetree, sp->sizex, sp->sizey); } } else if(id_type==ID_LA) { Lamp *la= NULL, *origla= (Lamp *)id; /* work on a copy */ if(origla) { la= localize_lamp(origla); sp->lampcopy= la; BLI_addtail(&pr_main->lamp, la); } if(la && la->type==LA_SUN && (la->sun_effect_type & LA_SUN_EFFECT_SKY)) { sce->lay= 1<<MA_ATMOS; sce->world= scene->world; sce->camera= (Object *)BLI_findstring(&pr_main->object, "CameraAtmo", offsetof(ID, name)+2); } else { sce->lay= 1<<MA_LAMP; sce->world= NULL; sce->camera= (Object *)BLI_findstring(&pr_main->object, "Camera", offsetof(ID, name)+2); } sce->r.mode &= ~R_SHADOW; for(base= sce->base.first; base; base= base->next) { if(base->object->id.name[2]=='p') { if(base->object->type==OB_LAMP) base->object->data= la; } } } else if(id_type==ID_WO) { World *wrld= NULL, *origwrld= (World *)id; if(origwrld) { wrld= localize_world(origwrld); sp->worldcopy= wrld; BLI_addtail(&pr_main->world, wrld); } sce->lay= 1<<MA_SKY; sce->world= wrld; } return sce; } return NULL; }