示例#1
0
static void shader_get_from_context(const bContext *C, bNodeTreeType *UNUSED(treetype), bNodeTree **r_ntree, ID **r_id, ID **r_from)
{
	SpaceNode *snode = CTX_wm_space_node(C);
	Scene *scene = CTX_data_scene(C);
	Object *ob = OBACT;
	
	if (!BKE_scene_use_new_shading_nodes(scene) || snode->shaderfrom == SNODE_SHADER_OBJECT) {
		if (ob) {
			*r_from = &ob->id;
			if (ob->type == OB_LAMP) {
				*r_id = ob->data;
				*r_ntree = ((Lamp *)ob->data)->nodetree;
			}
			else {
				Material *ma = give_current_material(ob, ob->actcol);
				if (ma) {
					*r_id = &ma->id;
					*r_ntree = ma->nodetree;
				}
			}
		}
	}
	else { /* SNODE_SHADER_WORLD */
		if (scene->world) {
			*r_from = NULL;
			*r_id = &scene->world->id;
			*r_ntree = scene->world->nodetree;
		}
	}
}
示例#2
0
void ED_preview_shader_job(const bContext *C, void *owner, ID *id, ID *parent, MTex *slot, int sizex, int sizey, int method)
{
	Object *ob = CTX_data_active_object(C);
	wmJob *wm_job;
	ShaderPreview *sp;
	Scene *scene = CTX_data_scene(C);

	/* node previews not supported for cycles */
	if (BKE_scene_use_new_shading_nodes(scene) && method == PR_NODE_RENDER)
		return;

	wm_job = WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), owner, "Shader Preview",
	                    WM_JOB_EXCL_RENDER, WM_JOB_TYPE_RENDER_PREVIEW);
	sp = MEM_callocN(sizeof(ShaderPreview), "shader preview");

	/* customdata for preview thread */
	sp->scene = scene;
	sp->owner = owner;
	sp->sizex = sizex;
	sp->sizey = sizey;
	sp->pr_method = method;
	sp->id = id;
	sp->parent = parent;
	sp->slot = slot;

	/* hardcoded preview .blend for cycles/internal, this should be solved
	 * once with custom preview .blend path for external engines */
	if (BKE_scene_use_new_shading_nodes(scene))
		sp->pr_main = G_pr_main_cycles;
	else
		sp->pr_main = G_pr_main;

	if (ob && ob->totcol) copy_v4_v4(sp->col, ob->col);
	else sp->col[0] = sp->col[1] = sp->col[2] = sp->col[3] = 1.0f;
	
	/* setup job */
	WM_jobs_customdata_set(wm_job, sp, shader_preview_free);
	WM_jobs_timer(wm_job, 0.1, NC_MATERIAL, NC_MATERIAL);
	WM_jobs_callbacks(wm_job, common_preview_startjob, NULL, shader_preview_updatejob, NULL);
	
	WM_jobs_start(CTX_wm_manager(C), wm_job);
}
示例#3
0
static void node_add_menu(bContext *C, uiLayout *layout, void *arg_nodeclass)
{
	Main *bmain = CTX_data_main(C);
	Scene *scene = CTX_data_scene(C);
	SpaceNode *snode = CTX_wm_space_node(C);
	bNodeTree *ntree;
	int nodeclass = GET_INT_FROM_POINTER(arg_nodeclass);
	int event, compatibility = 0;
	
	ntree = snode->nodetree;
	
	if (!ntree) {
		uiItemS(layout);
		return;
	}

	if (ntree->type == NTREE_SHADER) {
		if (BKE_scene_use_new_shading_nodes(scene))
			compatibility = NODE_NEW_SHADING;
		else
			compatibility = NODE_OLD_SHADING;
	}
	
	if (nodeclass == NODE_CLASS_GROUP) {
		bNodeTree *ngroup;
		
		uiLayoutSetFunc(layout, do_node_add_group, NULL);
		
		/* XXX hack: negative numbers used for empty group types */
		if (node_tree_has_type(ntree->type, NODE_GROUP))
			uiItemV(layout, IFACE_("New Group"), 0, -NODE_GROUP);
		uiItemS(layout);
		
		for (ngroup = bmain->nodetree.first, event = 0; ngroup; ngroup = ngroup->id.next, ++event) {
			/* only use group trees */
			if (ngroup->type == ntree->type && ngroup->nodetype == NODE_GROUP) {
				uiItemV(layout, ngroup->id.name + 2, 0, event);
			}
		}
	}
	else {
		bNodeType *ntype;
		
		uiLayoutSetFunc(layout, do_node_add_static, NULL);
		
		for (ntype = ntreeGetType(ntree->type)->node_types.first; ntype; ntype = ntype->next) {
			if (ntype->nclass == nodeclass && ntype->name) {
				if (!compatibility || (ntype->compatibility & compatibility)) {
					uiItemV(layout, IFACE_(ntype->name), 0, ntype->type);
				}
			}
		}
	}
}
示例#4
0
void ED_render_scene_update_pre(Main *bmain, Scene *scene, bool time)
{
	/* Blender internal might access to the data which is gonna to be freed
	 * by the scene update functions. This applies for example to simulation
	 * data like smoke and fire.
	 */
	if (time && !BKE_scene_use_new_shading_nodes(scene)) {
		bScreen *sc;
		ScrArea *sa;
		for (sc = bmain->screen.first; sc; sc = sc->id.next) {
			for (sa = sc->areabase.first; sa; sa = sa->next) {
				ED_render_engine_area_exit(bmain, sa);
			}
		}
	}
}
示例#5
0
static void foreach_nodeclass(Scene *scene, void *calldata, bNodeClassCallback func)
{
	func(calldata, NODE_CLASS_INPUT, N_("Input"));
	func(calldata, NODE_CLASS_OUTPUT, N_("Output"));

	if (BKE_scene_use_new_shading_nodes(scene)) {
		func(calldata, NODE_CLASS_SHADER, N_("Shader"));
		func(calldata, NODE_CLASS_TEXTURE, N_("Texture"));
	}
	
	func(calldata, NODE_CLASS_OP_COLOR, N_("Color"));
	func(calldata, NODE_CLASS_OP_VECTOR, N_("Vector"));
	func(calldata, NODE_CLASS_CONVERTOR, N_("Convertor"));
	func(calldata, NODE_CLASS_SCRIPT, N_("Script"));
	func(calldata, NODE_CLASS_GROUP, N_("Group"));
	func(calldata, NODE_CLASS_INTERFACE, N_("Interface"));
	func(calldata, NODE_CLASS_LAYOUT, N_("Layout"));
}
static void icon_preview_startjob_all_sizes(void *customdata, short *stop, short *do_update, float *progress)
{
	IconPreview *ip = (IconPreview *)customdata;
	IconPreviewSize *cur_size = ip->sizes.first;
	const bool use_new_shading = BKE_scene_use_new_shading_nodes(ip->scene);

	while (cur_size) {
		PreviewImage *prv = ip->owner;
		ShaderPreview *sp = MEM_callocN(sizeof(ShaderPreview), "Icon ShaderPreview");
		const bool is_render = !prv->use_deferred;

		/* construct shader preview from image size and previewcustomdata */
		sp->scene = ip->scene;
		sp->owner = ip->owner;
		sp->sizex = cur_size->sizex;
		sp->sizey = cur_size->sizey;
		sp->pr_method = is_render ? PR_ICON_RENDER : PR_ICON_DEFERRED;
		sp->pr_rect = cur_size->rect;
		sp->id = ip->id;
		sp->bmain = ip->bmain;

		if (is_render) {
			BLI_assert(ip->id);
			if (use_new_shading) {
				/* texture icon rendering is hardcoded to use BI,
				 * so don't even think of using cycle's bmain for
				 * texture icons
				 */
				if (GS(ip->id->name) != ID_TE)
					sp->pr_main = G_pr_main_cycles;
				else
					sp->pr_main = G_pr_main;
			}
			else {
				sp->pr_main = G_pr_main;
			}
		}

		common_preview_startjob(sp, stop, do_update, progress);
		shader_preview_free(sp);

		cur_size = cur_size->next;
	}
}
示例#7
0
static void shader_get_from_context(const bContext *C, bNodeTreeType *UNUSED(treetype), bNodeTree **r_ntree, ID **r_id, ID **r_from)
{
	SpaceNode *snode = CTX_wm_space_node(C);
	Scene *scene = CTX_data_scene(C);
	Object *ob = OBACT;
	
	if ((snode->shaderfrom == SNODE_SHADER_OBJECT) ||
	    (BKE_scene_use_new_shading_nodes(scene) == false))
	{
		if (ob) {
			*r_from = &ob->id;
			if (ob->type == OB_LAMP) {
				*r_id = ob->data;
				*r_ntree = ((Lamp *)ob->data)->nodetree;
			}
			else {
				Material *ma = give_current_material(ob, ob->actcol);
				if (ma) {
					*r_id = &ma->id;
					*r_ntree = ma->nodetree;
				}
			}
		}
	}
#ifdef WITH_FREESTYLE
	else if (snode->shaderfrom == SNODE_SHADER_LINESTYLE) {
		FreestyleLineStyle *linestyle = BKE_linestyle_active_from_scene(scene);
		if (linestyle) {
			*r_from = NULL;
			*r_id = &linestyle->id;
			*r_ntree = linestyle->nodetree;
		}
	}
#endif
	else { /* SNODE_SHADER_WORLD */
		if (scene->world) {
			*r_from = NULL;
			*r_id = &scene->world->id;
			*r_ntree = scene->world->nodetree;
		}
	}
}
示例#8
0
static void set_texture_context(const bContext *C, SpaceButs *sbuts)
{
    Scene *scene = CTX_data_scene(C);

    if (BKE_scene_use_new_shading_nodes(scene)) {
        return;  /* No texture context in new shading mode */
    }

    {
        bool valid_world = ED_texture_context_check_world(C);
        bool valid_material = ED_texture_context_check_material(C);
        bool valid_lamp = ED_texture_context_check_lamp(C);
        bool valid_particles = ED_texture_context_check_particles(C);
        bool valid_others = ED_texture_context_check_others(C);

        /* this is similar to direct user action, no need to keep "better" ctxt in _prev */
        if ((sbuts->mainb == BCONTEXT_WORLD) && valid_world) {
            sbuts->texture_context = sbuts->texture_context_prev = SB_TEXC_WORLD;
        }
        else if ((sbuts->mainb == BCONTEXT_MATERIAL) && valid_material) {
            sbuts->texture_context = sbuts->texture_context_prev = SB_TEXC_MATERIAL;
        }
        else if ((sbuts->mainb == BCONTEXT_DATA) && valid_lamp) {
            sbuts->texture_context = sbuts->texture_context_prev = SB_TEXC_LAMP;
        }
        else if ((sbuts->mainb == BCONTEXT_PARTICLE) && valid_particles) {
            sbuts->texture_context = sbuts->texture_context_prev = SB_TEXC_PARTICLES;
        }
        else if ((ELEM(sbuts->mainb, BCONTEXT_MODIFIER, BCONTEXT_PHYSICS)) && valid_others) {
            sbuts->texture_context = sbuts->texture_context_prev = SB_TEXC_OTHER;
        }
        /* Else, try to revive a previous "better" ctxt... */
        else if ((sbuts->texture_context_prev != sbuts->texture_context) &&
                 (((sbuts->texture_context_prev == SB_TEXC_WORLD) && valid_world) ||
                  ((sbuts->texture_context_prev == SB_TEXC_MATERIAL) && valid_material) ||
                  ((sbuts->texture_context_prev == SB_TEXC_LAMP) && valid_lamp) ||
                  ((sbuts->texture_context_prev == SB_TEXC_PARTICLES) && valid_particles) ||
                  ((sbuts->texture_context_prev == SB_TEXC_OTHER) && valid_others)))
        {
            sbuts->texture_context = sbuts->texture_context_prev;
        }
        /* Else, just be sure that current context is valid! */
        else if (((sbuts->texture_context == SB_TEXC_WORLD) && !valid_world) ||
                 ((sbuts->texture_context == SB_TEXC_MATERIAL) && !valid_material) ||
                 ((sbuts->texture_context == SB_TEXC_LAMP) && !valid_lamp) ||
                 ((sbuts->texture_context == SB_TEXC_PARTICLES) && !valid_particles) ||
                 ((sbuts->texture_context == SB_TEXC_OTHER) && !valid_others))
        {
            /* this is default fallback, do keep "better" ctxt in _prev */
            sbuts->texture_context_prev = sbuts->texture_context;
            if (valid_material) {
                sbuts->texture_context = SB_TEXC_MATERIAL;
            }
            else if (valid_lamp) {
                sbuts->texture_context = SB_TEXC_LAMP;
            }
            else if (valid_particles) {
                sbuts->texture_context = SB_TEXC_PARTICLES;
            }
            else if (valid_world) {
                sbuts->texture_context = SB_TEXC_WORLD;
            }
            else if (valid_others) {
                sbuts->texture_context = SB_TEXC_OTHER;
            }
        }
    }
}
/* re->winx,winy is coordinate space of entire image, partrct the part within */
RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuffers, const char *layername, const char *viewname)
{
	RenderResult *rr;
	RenderLayer *rl;
	RenderView *rv;
	SceneRenderLayer *srl;
	int rectx, recty;
	int nr;
	
	rectx = BLI_rcti_size_x(partrct);
	recty = BLI_rcti_size_y(partrct);
	
	if (rectx <= 0 || recty <= 0)
		return NULL;
	
	rr = MEM_callocN(sizeof(RenderResult), "new render result");
	rr->rectx = rectx;
	rr->recty = recty;
	rr->renrect.xmin = 0; rr->renrect.xmax = rectx - 2 * crop;
	/* crop is one or two extra pixels rendered for filtering, is used for merging and display too */
	rr->crop = crop;

	/* tilerect is relative coordinates within render disprect. do not subtract crop yet */
	rr->tilerect.xmin = partrct->xmin - re->disprect.xmin;
	rr->tilerect.xmax = partrct->xmax - re->disprect.xmin;
	rr->tilerect.ymin = partrct->ymin - re->disprect.ymin;
	rr->tilerect.ymax = partrct->ymax - re->disprect.ymin;
	
	if (savebuffers) {
		rr->do_exr_tile = true;
	}

	render_result_views_new(rr, &re->r);

	/* check renderdata for amount of layers */
	for (nr = 0, srl = re->r.layers.first; srl; srl = srl->next, nr++) {

		if (layername && layername[0])
			if (!STREQ(srl->name, layername))
				continue;

		if (re->r.scemode & R_SINGLE_LAYER) {
			if (nr != re->r.actlay)
				continue;
		}
		else {
			if (srl->layflag & SCE_LAY_DISABLE)
				continue;
		}
		
		rl = MEM_callocN(sizeof(RenderLayer), "new render layer");
		BLI_addtail(&rr->layers, rl);
		
		BLI_strncpy(rl->name, srl->name, sizeof(rl->name));
		rl->lay = srl->lay;
		rl->lay_zmask = srl->lay_zmask;
		rl->lay_exclude = srl->lay_exclude;
		rl->layflag = srl->layflag;
		rl->passflag = srl->passflag; /* for debugging: srl->passflag | SCE_PASS_RAYHITS; */
		rl->pass_xor = srl->pass_xor;
		rl->light_override = srl->light_override;
		rl->mat_override = srl->mat_override;
		rl->rectx = rectx;
		rl->recty = recty;
		
		if (rr->do_exr_tile) {
			rl->display_buffer = MEM_mapallocN(rectx * recty * sizeof(unsigned int), "Combined display space rgba");
			rl->exrhandle = IMB_exr_get_handle();
		}

		for (rv = rr->views.first; rv; rv = rv->next) {
			const char *view = rv->name;

			if (viewname && viewname[0])
				if (!STREQ(view, viewname))
					continue;

			if (rr->do_exr_tile)
				IMB_exr_add_view(rl->exrhandle, view);

			/* a renderlayer should always have a Combined pass*/
			render_layer_add_pass(rr, rl, 4, SCE_PASS_COMBINED, view);

			if (srl->passflag  & SCE_PASS_Z)
				render_layer_add_pass(rr, rl, 1, SCE_PASS_Z, view);
			if (srl->passflag  & SCE_PASS_VECTOR)
				render_layer_add_pass(rr, rl, 4, SCE_PASS_VECTOR, view);
			if (srl->passflag  & SCE_PASS_NORMAL)
				render_layer_add_pass(rr, rl, 3, SCE_PASS_NORMAL, view);
			if (srl->passflag  & SCE_PASS_UV)
				render_layer_add_pass(rr, rl, 3, SCE_PASS_UV, view);
			if (srl->passflag  & SCE_PASS_RGBA)
				render_layer_add_pass(rr, rl, 4, SCE_PASS_RGBA, view);
			if (srl->passflag  & SCE_PASS_EMIT)
				render_layer_add_pass(rr, rl, 3, SCE_PASS_EMIT, view);
			if (srl->passflag  & SCE_PASS_DIFFUSE)
				render_layer_add_pass(rr, rl, 3, SCE_PASS_DIFFUSE, view);
			if (srl->passflag  & SCE_PASS_SPEC)
				render_layer_add_pass(rr, rl, 3, SCE_PASS_SPEC, view);
			if (srl->passflag  & SCE_PASS_AO)
				render_layer_add_pass(rr, rl, 3, SCE_PASS_AO, view);
			if (srl->passflag  & SCE_PASS_ENVIRONMENT)
				render_layer_add_pass(rr, rl, 3, SCE_PASS_ENVIRONMENT, view);
			if (srl->passflag  & SCE_PASS_INDIRECT)
				render_layer_add_pass(rr, rl, 3, SCE_PASS_INDIRECT, view);
			if (srl->passflag  & SCE_PASS_SHADOW)
				render_layer_add_pass(rr, rl, 3, SCE_PASS_SHADOW, view);
			if (srl->passflag  & SCE_PASS_REFLECT)
				render_layer_add_pass(rr, rl, 3, SCE_PASS_REFLECT, view);
			if (srl->passflag  & SCE_PASS_REFRACT)
				render_layer_add_pass(rr, rl, 3, SCE_PASS_REFRACT, view);
			if (srl->passflag  & SCE_PASS_INDEXOB)
				render_layer_add_pass(rr, rl, 1, SCE_PASS_INDEXOB, view);
			if (srl->passflag  & SCE_PASS_INDEXMA)
				render_layer_add_pass(rr, rl, 1, SCE_PASS_INDEXMA, view);
			if (srl->passflag  & SCE_PASS_MIST)
				render_layer_add_pass(rr, rl, 1, SCE_PASS_MIST, view);
			if (rl->passflag & SCE_PASS_RAYHITS)
				render_layer_add_pass(rr, rl, 4, SCE_PASS_RAYHITS, view);
			if (srl->passflag  & SCE_PASS_DIFFUSE_DIRECT)
				render_layer_add_pass(rr, rl, 3, SCE_PASS_DIFFUSE_DIRECT, view);
			if (srl->passflag  & SCE_PASS_DIFFUSE_INDIRECT)
				render_layer_add_pass(rr, rl, 3, SCE_PASS_DIFFUSE_INDIRECT, view);
			if (srl->passflag  & SCE_PASS_DIFFUSE_COLOR)
				render_layer_add_pass(rr, rl, 3, SCE_PASS_DIFFUSE_COLOR, view);
			if (srl->passflag  & SCE_PASS_GLOSSY_DIRECT)
				render_layer_add_pass(rr, rl, 3, SCE_PASS_GLOSSY_DIRECT, view);
			if (srl->passflag  & SCE_PASS_GLOSSY_INDIRECT)
				render_layer_add_pass(rr, rl, 3, SCE_PASS_GLOSSY_INDIRECT, view);
			if (srl->passflag  & SCE_PASS_GLOSSY_COLOR)
				render_layer_add_pass(rr, rl, 3, SCE_PASS_GLOSSY_COLOR, view);
			if (srl->passflag  & SCE_PASS_TRANSM_DIRECT)
				render_layer_add_pass(rr, rl, 3, SCE_PASS_TRANSM_DIRECT, view);
			if (srl->passflag  & SCE_PASS_TRANSM_INDIRECT)
				render_layer_add_pass(rr, rl, 3, SCE_PASS_TRANSM_INDIRECT, view);
			if (srl->passflag  & SCE_PASS_TRANSM_COLOR)
				render_layer_add_pass(rr, rl, 3, SCE_PASS_TRANSM_COLOR, view);
			if (srl->passflag  & SCE_PASS_SUBSURFACE_DIRECT)
				render_layer_add_pass(rr, rl, 3, SCE_PASS_SUBSURFACE_DIRECT, view);
			if (srl->passflag  & SCE_PASS_SUBSURFACE_INDIRECT)
				render_layer_add_pass(rr, rl, 3, SCE_PASS_SUBSURFACE_INDIRECT, view);
			if (srl->passflag  & SCE_PASS_SUBSURFACE_COLOR)
				render_layer_add_pass(rr, rl, 3, SCE_PASS_SUBSURFACE_COLOR, view);

#ifdef WITH_CYCLES_DEBUG
			if (BKE_scene_use_new_shading_nodes(re->scene)) {
				render_layer_add_debug_pass(rr, rl, 1, SCE_PASS_DEBUG,
				        re->r.debug_pass_type, view);
			}
#endif
		}
	}
	/* sss, previewrender and envmap don't do layers, so we make a default one */
	if (BLI_listbase_is_empty(&rr->layers) && !(layername && layername[0])) {
		rl = MEM_callocN(sizeof(RenderLayer), "new render layer");
		BLI_addtail(&rr->layers, rl);
		
		rl->rectx = rectx;
		rl->recty = recty;

		/* duplicate code... */
		if (rr->do_exr_tile) {
			rl->display_buffer = MEM_mapallocN(rectx * recty * sizeof(unsigned int), "Combined display space rgba");
			rl->exrhandle = IMB_exr_get_handle();
		}

		for (rv = rr->views.first; rv; rv = rv->next) {
			const char *view = rv->name;

			if (viewname && viewname[0])
				if (strcmp(view, viewname) != 0)
					continue;

			if (rr->do_exr_tile)
				IMB_exr_add_view(rl->exrhandle, view);

			/* a renderlayer should always have a Combined pass */
			render_layer_add_pass(rr, rl, 4, SCE_PASS_COMBINED, view);
		}

		/* note, this has to be in sync with scene.c */
		rl->lay = (1 << 20) - 1;
		rl->layflag = 0x7FFF;    /* solid ztra halo strand */
		rl->passflag = SCE_PASS_COMBINED;
		
		re->r.actlay = 0;
	}
	
	/* border render; calculate offset for use in compositor. compo is centralized coords */
	/* XXX obsolete? I now use it for drawing border render offset (ton) */
	rr->xof = re->disprect.xmin + BLI_rcti_cent_x(&re->disprect) - (re->winx / 2);
	rr->yof = re->disprect.ymin + BLI_rcti_cent_y(&re->disprect) - (re->winy / 2);
	
	return rr;
}
示例#10
0
/* 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;
}
示例#11
0
static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname)
{
	Main *bmain = arg->bmain;
	bNodeTree *ntree = arg->ntree;
	bNodeSocket *sock = arg->sock;
	uiLayout *layout = arg->layout;
	uiLayout *column = NULL;
	uiBlock *block = uiLayoutGetBlock(layout);
	uiBut *but;
	bNodeType *ntype;
	bNodeTree *ngroup;
	NodeLinkArg *argN;
	int first = 1;
	int compatibility= 0;

	if (ntree->type == NTREE_SHADER) {
		if (BKE_scene_use_new_shading_nodes(arg->scene))
			compatibility= NODE_NEW_SHADING;
		else
			compatibility= NODE_OLD_SHADING;
	}

	if (nclass == NODE_CLASS_GROUP) {
		for (ngroup=bmain->nodetree.first; ngroup; ngroup=ngroup->id.next) {
			bNodeSocket *gsock;
			char name[UI_MAX_NAME_STR];
			int i, j, num = 0;

			if (ngroup->type != ntree->type)
				continue;

			for (gsock=ngroup->inputs.first; gsock; gsock=gsock->next)
				if (ui_compatible_sockets(gsock->type, sock->type))
					num++;

			for (i=0, j=0, gsock=ngroup->outputs.first; gsock; gsock=gsock->next, i++) {
				if (!ui_compatible_sockets(gsock->type, sock->type))
					continue;

				if (first) {
					column= uiLayoutColumn(layout, 0);
					uiBlockSetCurLayout(block, column);

					uiItemL(column, cname, ICON_NODE);
					but= block->buttons.last;
					but->flag= UI_TEXT_LEFT;

					first = 0;
				}

				if (num > 1) {
					if (j == 0) {
						uiItemL(column, ngroup->id.name+2, ICON_NODE);
						but= block->buttons.last;
						but->flag= UI_TEXT_LEFT;
					}

					BLI_snprintf(name, UI_MAX_NAME_STR, "  %s", gsock->name);
					j++;
				}
				else
					BLI_strncpy(name, ngroup->id.name+2, UI_MAX_NAME_STR);

				but = uiDefBut(block, BUT, 0, ngroup->id.name+2, 0, 0, UI_UNIT_X*4, UI_UNIT_Y,
					NULL, 0.0, 0.0, 0.0, 0.0, "Add node to input");

				argN = MEM_dupallocN(arg);
				argN->type = NODE_GROUP;
				argN->ngroup = ngroup;
				argN->output = i;
				uiButSetNFunc(but, ui_node_link, argN, NULL);
			}
		}
	}
	else {
		bNodeTreeType *ttype= ntreeGetType(ntree->type);

		for (ntype=ttype->node_types.first; ntype; ntype=ntype->next) {
			bNodeSocketTemplate *stemp;
			char name[UI_MAX_NAME_STR];
			int i, j, num = 0;

			if (compatibility && !(ntype->compatibility & compatibility))
				continue;

			if (ntype->nclass != nclass)
				continue;

			for (i=0, stemp=ntype->outputs; stemp && stemp->type != -1; stemp++, i++)
				if (ui_compatible_sockets(stemp->type, sock->type))
					num++;

			for (i=0, j=0, stemp=ntype->outputs; stemp && stemp->type != -1; stemp++, i++) {
				if (!ui_compatible_sockets(stemp->type, sock->type))
					continue;

				if (first) {
					column= uiLayoutColumn(layout, 0);
					uiBlockSetCurLayout(block, column);

					uiItemL(column, cname, ICON_NODE);
					but= block->buttons.last;
					but->flag= UI_TEXT_LEFT;

					first = 0;
				}

				if (num > 1) {
					if (j == 0) {
						uiItemL(column, ntype->name, ICON_NODE);
						but= block->buttons.last;
						but->flag= UI_TEXT_LEFT;
					}

					BLI_snprintf(name, UI_MAX_NAME_STR, "  %s", stemp->name);
					j++;
				}
				else
					BLI_strncpy(name, ntype->name, UI_MAX_NAME_STR);

				but = uiDefBut(block, BUT, 0, name, 0, 0, UI_UNIT_X*4, UI_UNIT_Y,
					NULL, 0.0, 0.0, 0.0, 0.0, "Add node to input");

				argN = MEM_dupallocN(arg);
				argN->type = ntype->type;
				argN->output = i;
				uiButSetNFunc(but, ui_node_link, argN, NULL);
			}
		}
	}
}
示例#12
0
void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d,
                        Object *ob, DerivedMesh *dm, const int draw_flags)
{
	/* if not cycles, or preview-modifiers, or drawing matcaps */
	if ((!BKE_scene_use_new_shading_nodes(scene)) || (draw_flags & DRAW_MODIFIERS_PREVIEW) || (v3d->flag2 & V3D_SHOW_SOLID_MATCAP)) {
		draw_mesh_textured_old(scene, v3d, rv3d, ob, dm, draw_flags);
		return;
	}
	else if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)) {
		draw_mesh_paint(v3d, rv3d, ob, dm, draw_flags);
		return;
	}

	/* set opengl state for negative scale & color */
	if (ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW);
	else glFrontFace(GL_CCW);

	if ((v3d->drawtype == OB_TEXTURE) && (v3d->flag2 & V3D_SHADELESS_TEX))
		glColor3f(1.0f, 1.0f, 1.0f);
	else
		glEnable(GL_LIGHTING);

	{
		Mesh *me = ob->data;
		TexMatCallback data = {scene, ob, me, dm};
		bool (*set_face_cb)(void *, int);
		int glsl, picking = (G.f & G_PICKSEL);
		
		/* face hiding callback depending on mode */
		if (ob == scene->obedit)
			set_face_cb = tex_mat_set_face_editmesh_cb;
		else if (draw_flags & DRAW_FACE_SELECT)
			set_face_cb = tex_mat_set_face_mesh_cb;
		else
			set_face_cb = NULL;

		/* test if we can use glsl */
		glsl = (v3d->drawtype == OB_MATERIAL) && GPU_glsl_support() && !picking;

		GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, NULL);

		if (glsl || picking) {
			/* draw glsl or solid */
			dm->drawMappedFacesMat(dm,
			                       tex_mat_set_material_cb,
			                       set_face_cb, &data);
		}
		else {
			float zero[4] = {0.0f, 0.0f, 0.0f, 0.0f};

			/* draw textured */
			glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, zero);
			glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, zero);
			glMateriali(GL_FRONT_AND_BACK, GL_SHININESS, 0);

			dm->drawMappedFacesMat(dm,
			                       tex_mat_set_texture_cb,
			                       set_face_cb, &data);
		}

		GPU_end_object_materials();
	}

	/* reset opengl state */
	glDisable(GL_COLOR_MATERIAL);
	glDisable(GL_TEXTURE_2D);
	glDisable(GL_LIGHTING);
	glBindTexture(GL_TEXTURE_2D, 0);
	glFrontFace(GL_CCW);

	glMatrixMode(GL_TEXTURE);
	glLoadIdentity();
	glMatrixMode(GL_MODELVIEW);

	/* faceselect mode drawing over textured mesh */
	if (!(ob == scene->obedit) && (draw_flags & DRAW_FACE_SELECT))
		draw_mesh_face_select(rv3d, ob->data, dm);
}
static void draw_textured_begin(Scene *scene, View3D *v3d, RegionView3D *rv3d, Object *ob)
{
	unsigned char obcol[4];
	bool is_tex, solidtex;
	Mesh *me = ob->data;
	ImagePaintSettings *imapaint = &scene->toolsettings->imapaint;

	/* XXX scene->obedit warning */

	/* texture draw is abused for mask selection mode, do this so wire draw
	 * with face selection in weight paint is not lit. */
	if ((v3d->drawtype <= OB_WIRE) && (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT))) {
		solidtex = false;
		Gtexdraw.is_lit = 0;
	}
	else if (v3d->drawtype == OB_SOLID || ((ob->mode & OB_MODE_EDIT) && v3d->drawtype != OB_TEXTURE) ||
	        (BKE_scene_use_new_shading_nodes(scene) && (ob->mode & OB_MODE_TEXTURE_PAINT))) {
		/* draw with default lights in solid draw mode and edit mode */
		solidtex = true;
		Gtexdraw.is_lit = -1;
	}
	else {
		/* draw with lights in the scene otherwise */
		solidtex = false;
		if (v3d->flag2 & V3D_SHADELESS_TEX)
			Gtexdraw.is_lit = 0;
		else
			Gtexdraw.is_lit = GPU_scene_object_lights(scene, ob, v3d->lay, rv3d->viewmat, !rv3d->is_persp);
	}
	
	rgba_float_to_uchar(obcol, ob->col);

	if (solidtex || v3d->drawtype == OB_TEXTURE) is_tex = true;
	else is_tex = false;

	Gtexdraw.ob = ob;
	Gtexdraw.stencil = (imapaint->flag & IMAGEPAINT_PROJECT_LAYER_STENCIL) ? imapaint->stencil : NULL;
	Gtexdraw.is_texpaint = (ob->mode == OB_MODE_TEXTURE_PAINT);
	Gtexdraw.texpaint_material = (imapaint->mode == IMAGEPAINT_MODE_MATERIAL);
	Gtexdraw.canvas = (Gtexdraw.texpaint_material) ? NULL : imapaint->canvas;
	Gtexdraw.is_tex = is_tex;

	/* naughty multitexturing hacks to quickly support stencil + shading + alpha blending 
	 * in new texpaint code. The better solution here would be to support GLSL */
	if (Gtexdraw.is_texpaint) {			
		glActiveTexture(GL_TEXTURE1);
		glEnable(GL_TEXTURE_2D);
		glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
		glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
		glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
		glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PRIMARY_COLOR);
		glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_PREVIOUS);
		glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);
		glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
		glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
		
		/* load the stencil texture here */
		if (Gtexdraw.stencil != NULL) {
			glActiveTexture(GL_TEXTURE2);
			if (GPU_verify_image(Gtexdraw.stencil, NULL, false, false, false, false)) {
				float col[4] = {imapaint->stencil_col[0], imapaint->stencil_col[1], imapaint->stencil_col[2], 1.0f};
				glEnable(GL_TEXTURE_2D);
				glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
				glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
				glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PREVIOUS);
				glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_RGB, GL_CONSTANT);
				glTexEnvi(GL_TEXTURE_ENV, GL_SRC2_RGB, GL_TEXTURE);
				glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE);
				glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PREVIOUS);
				glTexEnvi(GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_TEXTURE);
				glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, col);
				if ((imapaint->flag & IMAGEPAINT_PROJECT_LAYER_STENCIL_INV) == 0) {
					glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_ONE_MINUS_SRC_COLOR);
				}
				else {
					glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_COLOR);
				}
			}
		}
		glActiveTexture(GL_TEXTURE0);
	}
	
	Gtexdraw.color_profile = BKE_scene_check_color_management_enabled(scene);
	Gtexdraw.use_game_mat = (RE_engines_find(scene->r.engine)->flag & RE_GAME) != 0;
	Gtexdraw.use_backface_culling = (v3d->flag2 & V3D_BACKFACE_CULLING) != 0;

	memcpy(Gtexdraw.obcol, obcol, sizeof(obcol));
	set_draw_settings_cached(1, NULL, NULL, Gtexdraw);
	glShadeModel(GL_SMOOTH);
	glCullFace(GL_BACK);
	glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, (me->flag & ME_TWOSIDED) ? GL_TRUE : GL_FALSE);
}
static void ui_node_menu_column(NodeLinkArg *arg, int nclass, const char *cname)
{
	bNodeTree *ntree = arg->ntree;
	bNodeSocket *sock = arg->sock;
	uiLayout *layout = arg->layout;
	uiLayout *column = NULL;
	uiBlock *block = uiLayoutGetBlock(layout);
	uiBut *but;
	NodeLinkArg *argN;
	int first = 1;
	int compatibility = 0;
	
	if (ntree->type == NTREE_SHADER) {
		if (BKE_scene_use_new_shading_nodes(arg->scene))
			compatibility = NODE_NEW_SHADING;
		else
			compatibility = NODE_OLD_SHADING;
	}

	NODE_TYPES_BEGIN(ntype) {
		NodeLinkItem *items;
		int totitems;
		char name[UI_MAX_NAME_STR];
		const char *cur_node_name = NULL;
		int i, num = 0;
		int icon = ICON_NONE;
		
		if (compatibility && !(ntype->compatibility & compatibility))
			continue;
		
		if (ntype->nclass != nclass)
			continue;
		
		arg->node_type = ntype;
		
		ui_node_link_items(arg, SOCK_OUT, &items, &totitems);
		
		for (i = 0; i < totitems; ++i)
			if (ui_compatible_sockets(items[i].socket_type, sock->type))
				num++;
		
		for (i = 0; i < totitems; ++i) {
			if (!ui_compatible_sockets(items[i].socket_type, sock->type))
				continue;
			
			if (first) {
				column = uiLayoutColumn(layout, 0);
				UI_block_layout_set_current(block, column);
				
				uiItemL(column, IFACE_(cname), ICON_NODE);
				but = block->buttons.last;
				
				first = 0;
			}
			
			if (num > 1) {
				if (!cur_node_name || !STREQ(cur_node_name, items[i].node_name)) {
					cur_node_name = items[i].node_name;
					/* XXX Do not use uiItemL here, it would add an empty icon as we are in a menu! */
					uiDefBut(block, UI_BTYPE_LABEL, 0, IFACE_(cur_node_name), 0, 0, UI_UNIT_X * 4, UI_UNIT_Y,
					         NULL, 0.0, 0.0, 0.0, 0.0, "");
				}

				BLI_snprintf(name, UI_MAX_NAME_STR, "%s", IFACE_(items[i].socket_name));
				icon = ICON_BLANK1;
			}
			else {
				BLI_strncpy(name, IFACE_(items[i].node_name), UI_MAX_NAME_STR);
				icon = ICON_NONE;
			}
			
			but = uiDefIconTextBut(block, UI_BTYPE_BUT, 0, icon, name, 0, 0, UI_UNIT_X * 4, UI_UNIT_Y,
			                       NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Add node to input"));
			
			argN = MEM_dupallocN(arg);
			argN->item = items[i];
			UI_but_funcN_set(but, ui_node_link, argN, NULL);
		}
		
		if (items)
			MEM_freeN(items);
	}
	NODE_TYPES_END
}
示例#15
0
void buttons_texture_context_compute(const bContext *C, SpaceButs *sbuts)
{
    /* gather available texture users in context. runs on every draw of
     * properties editor, before the buttons are created. */
    ButsContextTexture *ct = sbuts->texuser;
    Scene *scene = CTX_data_scene(C);
    ID *pinid = sbuts->pinid;

    set_texture_context(C, sbuts);

    if (!(BKE_scene_use_new_shading_nodes(scene) || (sbuts->texture_context == SB_TEXC_OTHER))) {
        if (ct) {
            BLI_freelistN(&ct->users);
            MEM_freeN(ct);
            sbuts->texuser = NULL;
        }

        return;
    }

    if (!ct) {
        ct = MEM_callocN(sizeof(ButsContextTexture), "ButsContextTexture");
        sbuts->texuser = ct;
    }
    else {
        BLI_freelistN(&ct->users);
    }

    buttons_texture_users_from_context(&ct->users, C, sbuts);

    if (pinid && GS(pinid->name) == ID_TE) {
        ct->user = NULL;
        ct->texture = (Tex *)pinid;
    }
    else {
        /* set one user as active based on active index */
        if (ct->index >= BLI_countlist(&ct->users))
            ct->index = 0;

        ct->user = BLI_findlink(&ct->users, ct->index);
        ct->texture = NULL;

        if (ct->user) {
            if (ct->user->ptr.data) {
                PointerRNA texptr;
                Tex *tex;

                /* get texture datablock pointer if it's a property */
                texptr = RNA_property_pointer_get(&ct->user->ptr, ct->user->prop);
                tex = (RNA_struct_is_a(texptr.type, &RNA_Texture)) ? texptr.data : NULL;

                ct->texture = tex;
            }
            else if (ct->user->node && !(ct->user->node->flag & NODE_ACTIVE_TEXTURE)) {
                ButsTextureUser *user;

                /* detect change of active texture node in same node tree, in that
                 * case we also automatically switch to the other node */
                for (user = ct->users.first; user; user = user->next) {
                    if (user->ntree == ct->user->ntree && user->node != ct->user->node) {
                        if (user->node->flag & NODE_ACTIVE_TEXTURE) {
                            ct->user = user;
                            ct->index = BLI_findindex(&ct->users, user);
                            break;
                        }
                    }
                }
            }
        }
    }
}
示例#16
0
/* OB_DUPLIPARTS */
static void make_duplis_particle_system(const DupliContext *ctx, ParticleSystem *psys)
{
	Scene *scene = ctx->scene;
	Object *par = ctx->object;
	bool for_render = ctx->eval_ctx->mode == DAG_EVAL_RENDER;
	bool use_texcoords = ELEM(ctx->eval_ctx->mode, DAG_EVAL_RENDER, DAG_EVAL_PREVIEW);

	GroupObject *go;
	Object *ob = NULL, **oblist = NULL, obcopy, *obcopylist = NULL;
	DupliObject *dob;
	ParticleDupliWeight *dw;
	ParticleSettings *part;
	ParticleData *pa;
	ChildParticle *cpa = NULL;
	ParticleKey state;
	ParticleCacheKey *cache;
	float ctime, pa_time, scale = 1.0f;
	float tmat[4][4], mat[4][4], pamat[4][4], vec[3], size = 0.0;
	float (*obmat)[4];
	int a, b, hair = 0;
	int totpart, totchild, totgroup = 0 /*, pa_num */;
	const bool dupli_type_hack = !BKE_scene_use_new_shading_nodes(scene);

	int no_draw_flag = PARS_UNEXIST;

	if (psys == NULL) return;

	part = psys->part;

	if (part == NULL)
		return;

	if (!psys_check_enabled(par, psys))
		return;

	if (!for_render)
		no_draw_flag |= PARS_NO_DISP;

	ctime = BKE_scene_frame_get(scene); /* NOTE: in old animsys, used parent object's timeoffset... */

	totpart = psys->totpart;
	totchild = psys->totchild;

	BLI_srandom((unsigned int)(31415926 + psys->seed));

	if ((psys->renderdata || part->draw_as == PART_DRAW_REND) && ELEM(part->ren_as, PART_DRAW_OB, PART_DRAW_GR)) {
		ParticleSimulationData sim = {NULL};
		sim.scene = scene;
		sim.ob = par;
		sim.psys = psys;
		sim.psmd = psys_get_modifier(par, psys);
		/* make sure emitter imat is in global coordinates instead of render view coordinates */
		invert_m4_m4(par->imat, par->obmat);

		/* first check for loops (particle system object used as dupli object) */
		if (part->ren_as == PART_DRAW_OB) {
			if (ELEM(part->dup_ob, NULL, par))
				return;
		}
		else { /*PART_DRAW_GR */
			if (part->dup_group == NULL || BLI_listbase_is_empty(&part->dup_group->gobject))
				return;

			if (BLI_findptr(&part->dup_group->gobject, par, offsetof(GroupObject, ob))) {
				return;
			}
		}

		/* if we have a hair particle system, use the path cache */
		if (part->type == PART_HAIR) {
			if (psys->flag & PSYS_HAIR_DONE)
				hair = (totchild == 0 || psys->childcache) && psys->pathcache;
			if (!hair)
				return;

			/* we use cache, update totchild according to cached data */
			totchild = psys->totchildcache;
			totpart = psys->totcached;
		}

		psys_check_group_weights(part);

		psys->lattice_deform_data = psys_create_lattice_deform_data(&sim);

		/* gather list of objects or single object */
		if (part->ren_as == PART_DRAW_GR) {
			if (ctx->do_update) {
				BKE_group_handle_recalc_and_update(ctx->eval_ctx, scene, par, part->dup_group);
			}

			if (part->draw & PART_DRAW_COUNT_GR) {
				for (dw = part->dupliweights.first; dw; dw = dw->next)
					totgroup += dw->count;
			}
			else {
				for (go = part->dup_group->gobject.first; go; go = go->next)
					totgroup++;
			}

			/* we also copy the actual objects to restore afterwards, since
			 * BKE_object_where_is_calc_time will change the object which breaks transform */
			oblist = MEM_callocN((size_t)totgroup * sizeof(Object *), "dupgroup object list");
			obcopylist = MEM_callocN((size_t)totgroup * sizeof(Object), "dupgroup copy list");

			if (part->draw & PART_DRAW_COUNT_GR && totgroup) {
				dw = part->dupliweights.first;

				for (a = 0; a < totgroup; dw = dw->next) {
					for (b = 0; b < dw->count; b++, a++) {
						oblist[a] = dw->ob;
						obcopylist[a] = *dw->ob;
					}
				}
			}
			else {
				go = part->dup_group->gobject.first;
				for (a = 0; a < totgroup; a++, go = go->next) {
					oblist[a] = go->ob;
					obcopylist[a] = *go->ob;
				}
			}
		}
		else {
			ob = part->dup_ob;
			obcopy = *ob;
		}

		if (totchild == 0 || part->draw & PART_DRAW_PARENT)
			a = 0;
		else
			a = totpart;

		for (pa = psys->particles; a < totpart + totchild; a++, pa++) {
			if (a < totpart) {
				/* handle parent particle */
				if (pa->flag & no_draw_flag)
					continue;

				/* pa_num = pa->num; */ /* UNUSED */
				pa_time = pa->time;
				size = pa->size;
			}
			else {
				/* handle child particle */
				cpa = &psys->child[a - totpart];

				/* pa_num = a; */ /* UNUSED */
				pa_time = psys->particles[cpa->parent].time;
				size = psys_get_child_size(psys, cpa, ctime, NULL);
			}

			/* some hair paths might be non-existent so they can't be used for duplication */
			if (hair && psys->pathcache &&
			    ((a < totpart && psys->pathcache[a]->segments < 0) ||
			     (a >= totpart && psys->childcache[a - totpart]->segments < 0)))
			{
				continue;
			}

			if (part->ren_as == PART_DRAW_GR) {
				/* prevent divide by zero below [#28336] */
				if (totgroup == 0)
					continue;

				/* for groups, pick the object based on settings */
				if (part->draw & PART_DRAW_RAND_GR)
					b = BLI_rand() % totgroup;
				else
					b = a % totgroup;

				ob = oblist[b];
				obmat = oblist[b]->obmat;
			}
			else {
				obmat = ob->obmat;
			}

			if (hair) {
				/* hair we handle separate and compute transform based on hair keys */
				if (a < totpart) {
					cache = psys->pathcache[a];
					psys_get_dupli_path_transform(&sim, pa, NULL, cache, pamat, &scale);
				}
				else {
					cache = psys->childcache[a - totpart];
					psys_get_dupli_path_transform(&sim, NULL, cpa, cache, pamat, &scale);
				}

				copy_v3_v3(pamat[3], cache->co);
				pamat[3][3] = 1.0f;

			}
			else {
				/* first key */
				state.time = ctime;
				if (psys_get_particle_state(&sim, a, &state, 0) == 0) {
					continue;
				}
				else {
					float tquat[4];
					normalize_qt_qt(tquat, state.rot);
					quat_to_mat4(pamat, tquat);
					copy_v3_v3(pamat[3], state.co);
					pamat[3][3] = 1.0f;
				}
			}

			if (part->ren_as == PART_DRAW_GR && psys->part->draw & PART_DRAW_WHOLE_GR) {
				for (go = part->dup_group->gobject.first, b = 0; go; go = go->next, b++) {

					copy_m4_m4(tmat, oblist[b]->obmat);
					/* apply particle scale */
					mul_mat3_m4_fl(tmat, size * scale);
					mul_v3_fl(tmat[3], size * scale);
					/* group dupli offset, should apply after everything else */
					if (!is_zero_v3(part->dup_group->dupli_ofs))
						sub_v3_v3(tmat[3], part->dup_group->dupli_ofs);
					/* individual particle transform */
					mul_m4_m4m4(mat, pamat, tmat);

					dob = make_dupli(ctx, go->ob, mat, a, false, false);
					dob->particle_system = psys;
					if (use_texcoords)
						psys_get_dupli_texture(psys, part, sim.psmd, pa, cpa, dob->uv, dob->orco);
				}
			}
			else {
				/* to give ipos in object correct offset */
				BKE_object_where_is_calc_time(scene, ob, ctime - pa_time);

				copy_v3_v3(vec, obmat[3]);
				obmat[3][0] = obmat[3][1] = obmat[3][2] = 0.0f;

				/* particle rotation uses x-axis as the aligned axis, so pre-rotate the object accordingly */
				if ((part->draw & PART_DRAW_ROTATE_OB) == 0) {
					float xvec[3], q[4], size_mat[4][4], original_size[3];

					mat4_to_size(original_size, obmat);
					size_to_mat4(size_mat, original_size);

					xvec[0] = -1.f;
					xvec[1] = xvec[2] = 0;
					vec_to_quat(q, xvec, ob->trackflag, ob->upflag);
					quat_to_mat4(obmat, q);
					obmat[3][3] = 1.0f;

					/* add scaling if requested */
					if ((part->draw & PART_DRAW_NO_SCALE_OB) == 0)
						mul_m4_m4m4(obmat, obmat, size_mat);
				}
				else if (part->draw & PART_DRAW_NO_SCALE_OB) {
					/* remove scaling */
					float size_mat[4][4], original_size[3];

					mat4_to_size(original_size, obmat);
					size_to_mat4(size_mat, original_size);
					invert_m4(size_mat);

					mul_m4_m4m4(obmat, obmat, size_mat);
				}

				mul_m4_m4m4(tmat, pamat, obmat);
				mul_mat3_m4_fl(tmat, size * scale);

				copy_m4_m4(mat, tmat);

				if (part->draw & PART_DRAW_GLOBAL_OB)
					add_v3_v3v3(mat[3], mat[3], vec);

				dob = make_dupli(ctx, ob, mat, a, false, false);
				dob->particle_system = psys;
				if (use_texcoords)
					psys_get_dupli_texture(psys, part, sim.psmd, pa, cpa, dob->uv, dob->orco);
				/* XXX blender internal needs this to be set to dupligroup to render
				 * groups correctly, but we don't want this hack for cycles */
				if (dupli_type_hack && ctx->group)
					dob->type = OB_DUPLIGROUP;
			}
		}

		/* restore objects since they were changed in BKE_object_where_is_calc_time */
		if (part->ren_as == PART_DRAW_GR) {
			for (a = 0; a < totgroup; a++)
				*(oblist[a]) = obcopylist[a];
		}
		else
			*ob = obcopy;
	}

	/* clean up */
	if (oblist)
		MEM_freeN(oblist);
	if (obcopylist)
		MEM_freeN(obcopylist);

	if (psys->lattice_deform_data) {
		end_latt_deform(psys->lattice_deform_data);
		psys->lattice_deform_data = NULL;
	}
}
示例#17
0
文件: drawmesh.c 项目: Moguri/blender
void draw_mesh_textured(Scene *scene, View3D *v3d, RegionView3D *rv3d,
                        Object *ob, DerivedMesh *dm, const int draw_flags)
{
	/* if not cycles, or preview-modifiers, or drawing matcaps */
	if ((draw_flags & DRAW_MODIFIERS_PREVIEW) ||
	    (v3d->flag2 & V3D_SHOW_SOLID_MATCAP) ||
	    (BKE_scene_use_new_shading_nodes(scene) == false) ||
	    ((ob->mode & OB_MODE_TEXTURE_PAINT) && ELEM(v3d->drawtype, OB_TEXTURE, OB_SOLID)))
	{
		draw_mesh_textured_old(scene, v3d, rv3d, ob, dm, draw_flags);
		return;
	}
	else if (ob->mode & (OB_MODE_VERTEX_PAINT | OB_MODE_WEIGHT_PAINT)) {
		draw_mesh_paint(v3d, rv3d, ob, dm, draw_flags);
		return;
	}

	/* set opengl state for negative scale & color */
	if (ob->transflag & OB_NEG_SCALE) glFrontFace(GL_CW);
	else glFrontFace(GL_CCW);

	Mesh *me = ob->data;

	bool shadeless = ((v3d->flag2 & V3D_SHADELESS_TEX) &&
	    ((v3d->drawtype == OB_TEXTURE) || (ob->mode & OB_MODE_TEXTURE_PAINT)));
	bool two_sided_lighting = (me->flag & ME_TWOSIDED) != 0;

	TexMatCallback data = {scene, ob, me, dm, shadeless, two_sided_lighting};
	bool (*set_face_cb)(void *, int);
	bool picking = (G.f & G_PICKSEL) != 0;
	
	/* face hiding callback depending on mode */
	if (ob == scene->obedit)
		set_face_cb = tex_mat_set_face_editmesh_cb;
	else if (draw_flags & DRAW_FACE_SELECT)
		set_face_cb = tex_mat_set_face_mesh_cb;
	else
		set_face_cb = NULL;

	/* test if we can use glsl */
	bool glsl = (v3d->drawtype == OB_MATERIAL) && !picking;

	GPU_begin_object_materials(v3d, rv3d, scene, ob, glsl, NULL);

	if (glsl || picking) {
		/* draw glsl or solid */
		dm->drawMappedFacesMat(dm,
		                       tex_mat_set_material_cb,
		                       set_face_cb, &data);
	}
	else {
		/* draw textured */
		dm->drawMappedFacesMat(dm,
		                       tex_mat_set_texture_cb,
		                       set_face_cb, &data);
	}

	GPU_end_object_materials();

	/* reset opengl state */
	GPU_end_object_materials();
	GPU_basic_shader_bind(GPU_SHADER_USE_COLOR);

	glBindTexture(GL_TEXTURE_2D, 0);

	glFrontFace(GL_CCW);

	glMatrixMode(GL_TEXTURE);
	glLoadIdentity();
	glMatrixMode(GL_MODELVIEW);

	/* faceselect mode drawing over textured mesh */
	if (!(ob == scene->obedit) && (draw_flags & DRAW_FACE_SELECT)) {
		bool draw_select_edges = (ob->mode & OB_MODE_TEXTURE_PAINT) == 0;
		draw_mesh_face_select(rv3d, ob->data, dm, draw_select_edges);
	}
}