/* 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; }
/* 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; Main *pr_main = sp->pr_main; sce = preview_get_scene(pr_main); 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; BKE_color_managed_display_settings_copy(&sce->display_settings, &scene->display_settings); BKE_color_managed_view_settings_free(&sce->view_settings); BKE_color_managed_view_settings_copy(&sce->view_settings, &scene->view_settings); /* prevent overhead for small renders and icons (32) */ if (id && sp->sizex < 40) { sce->r.tilex = sce->r.tiley = 64; } else { sce->r.tilex = sce->r.xsch / 4; sce->r.tiley = sce->r.ysch / 4; } 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; if (id_type == ID_TE && sp->pr_method == PR_ICON_RENDER) { /* force blender internal for texture icons render, * seems commonly used render engines does not support * such kind of rendering */ BLI_strncpy(sce->r.engine, "BLENDER_RENDER", sizeof(sce->r.engine)); } else { BLI_strncpy(sce->r.engine, scene->r.engine, sizeof(sce->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); if (!BKE_scene_use_new_shading_nodes(scene)) { 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; } } } } } else { /* use current scene world to light sphere */ if (mat->pr_type == MA_SPHERE_A) sce->world = scene->world; } 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; /* same as above, use current scene world to light sphere */ if (BKE_scene_use_new_shading_nodes(scene)) sce->world = scene->world; } } else { sce->lay = 1 << mat->pr_type; if (mat->nodetree && sp->pr_method == PR_NODE_RENDER) { /* two previews, they get copied by wmJob */ BKE_node_preview_init_tree(mat->nodetree, sp->sizex, sp->sizey, TRUE); BKE_node_preview_init_tree(origmat->nodetree, sp->sizex, sp->sizey, TRUE); } } } 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 (OB_TYPE_SUPPORT_MATERIAL(base->object->type)) { /* don't use assign_material, it changed mat->id.us, which shows in the UI */ Material ***matar = give_matarar(base->object); int actcol = max_ii(base->object->actcol - 1, 0); 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; mat->mtex[0]->mapto &= ~MAP_ALPHA; mat->alpha = 1.0f; /* show alpha in this case */ if (tex == NULL || (tex->flag & TEX_PRV_ALPHA)) { if (!(tex && tex->type == TEX_IMAGE && (tex->imaflag & (TEX_USEALPHA | TEX_CALCALPHA)) == 0)) { mat->mtex[0]->mapto |= MAP_ALPHA; mat->alpha = 0.0f; } } } } } if (tex && tex->nodetree && sp->pr_method == PR_NODE_RENDER) { /* two previews, they get copied by wmJob */ BKE_node_preview_init_tree(origtex->nodetree, sp->sizex, sp->sizey, TRUE); BKE_node_preview_init_tree(tex->nodetree, sp->sizex, sp->sizey, TRUE); } } 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); } sce->lay = 1 << MA_LAMP; if (!BKE_scene_use_new_shading_nodes(scene)) { 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->world = NULL; sce->camera = (Object *)BLI_findstring(&pr_main->object, "Camera", offsetof(ID, name) + 2); } } 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; } } if (la && la->nodetree && sp->pr_method == PR_NODE_RENDER) { /* two previews, they get copied by wmJob */ BKE_node_preview_init_tree(origla->nodetree, sp->sizex, sp->sizey, TRUE); BKE_node_preview_init_tree(la->nodetree, sp->sizex, sp->sizey, TRUE); } } 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; if (wrld && wrld->nodetree && sp->pr_method == PR_NODE_RENDER) { /* two previews, they get copied by wmJob */ BKE_node_preview_init_tree(wrld->nodetree, sp->sizex, sp->sizey, TRUE); BKE_node_preview_init_tree(origwrld->nodetree, sp->sizex, sp->sizey, TRUE); } } return sce; } return NULL; }