static int buttons_context_path_particle(ButsContextPath *path)
{
	Object *ob;
	ParticleSystem *psys;
	PointerRNA *ptr = &path->ptr[path->len - 1];

	/* if we already have (pinned) particle settings, we're done */
	if (RNA_struct_is_a(ptr->type, &RNA_ParticleSettings)) {
		return 1;
	}
	/* if we have an object, get the active particle system */
	if (buttons_context_path_object(path)) {
		ob = path->ptr[path->len - 1].data;

		if (ob && ob->type == OB_MESH) {
			psys = psys_get_current(ob);

			RNA_pointer_create(&ob->id, &RNA_ParticleSystem, psys, &path->ptr[path->len]);
			path->len++;
			return 1;
		}
	}

	/* no path to a particle system possible */
	return 0;
}
static int buttons_context_path_pose_bone(ButsContextPath *path)
{
	PointerRNA *ptr = &path->ptr[path->len - 1];

	/* if we already have a (pinned) PoseBone, we're done */
	if (RNA_struct_is_a(ptr->type, &RNA_PoseBone)) {
		return 1;
	}

	/* if we have an armature, get the active bone */
	if (buttons_context_path_object(path)) {
		Object *ob = path->ptr[path->len - 1].data;
		bArmature *arm = ob->data; /* path->ptr[path->len-1].data - works too */

		if (ob->type != OB_ARMATURE || arm->edbo) {
			return 0;
		}
		else {
			if (arm->act_bone) {
				bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, arm->act_bone->name);
				if (pchan) {
					RNA_pointer_create(&ob->id, &RNA_PoseBone, pchan, &path->ptr[path->len]);
					path->len++;
					return 1;
				}
			}
		}
	}

	/* no path to a bone possible */
	return 0;
}
static int buttons_context_path_data(ButsContextPath *path, int type)
{
	Object *ob;
	PointerRNA *ptr = &path->ptr[path->len - 1];

	/* if we already have a data, we're done */
	if (RNA_struct_is_a(ptr->type, &RNA_Mesh) && (type == -1 || type == OB_MESH)) return 1;
	else if (RNA_struct_is_a(ptr->type, &RNA_Curve) && (type == -1 || ELEM(type, OB_CURVE, OB_SURF, OB_FONT))) return 1;
	else if (RNA_struct_is_a(ptr->type, &RNA_Armature) && (type == -1 || type == OB_ARMATURE)) return 1;
	else if (RNA_struct_is_a(ptr->type, &RNA_MetaBall) && (type == -1 || type == OB_MBALL)) return 1;
	else if (RNA_struct_is_a(ptr->type, &RNA_Lattice) && (type == -1 || type == OB_LATTICE)) return 1;
	else if (RNA_struct_is_a(ptr->type, &RNA_Camera) && (type == -1 || type == OB_CAMERA)) return 1;
	else if (RNA_struct_is_a(ptr->type, &RNA_Lamp) && (type == -1 || type == OB_LAMP)) return 1;
	else if (RNA_struct_is_a(ptr->type, &RNA_Speaker) && (type == -1 || type == OB_SPEAKER)) return 1;
	/* try to get an object in the path, no pinning supported here */
	else if (buttons_context_path_object(path)) {
		ob = path->ptr[path->len - 1].data;

		if (ob && (type == -1 || type == ob->type)) {
			RNA_id_pointer_create(ob->data, &path->ptr[path->len]);
			path->len++;

			return 1;
		}
	}

	/* no path to data possible */
	return 0;
}
示例#4
0
static int buttons_context_path_material(ButsContextPath *path, int for_texture)
{
	Object *ob;
	PointerRNA *ptr= &path->ptr[path->len-1];
	Material *ma;

	/* if we already have a (pinned) material, we're done */
	if(RNA_struct_is_a(ptr->type, &RNA_Material)) {
		return 1;
	}
	/* if we have an object, use the object material slot */
	else if(buttons_context_path_object(path)) {
		ob= path->ptr[path->len-1].data;

		if(ob && ob->type && (ob->type<OB_LAMP)) {
			ma= give_current_material(ob, ob->actcol);
			RNA_id_pointer_create(&ma->id, &path->ptr[path->len]);
			path->len++;

			if(for_texture && give_current_material_texture_node(ma))
				return 1;
			
			ma= give_node_material(ma);
			if(ma) {
				RNA_id_pointer_create(&ma->id, &path->ptr[path->len]);
				path->len++;
			}			
			return 1;
		}
	}

	/* no path to a material possible */
	return 0;
}
static int buttons_context_path_modifier(ButsContextPath *path)
{
	Object *ob;

	if (buttons_context_path_object(path)) {
		ob = path->ptr[path->len - 1].data;

		if (ob && ELEM(ob->type, OB_MESH, OB_CURVE, OB_FONT, OB_SURF, OB_LATTICE))
			return 1;
	}

	return 0;
}
static int buttons_context_path_material(ButsContextPath *path, bool for_texture, bool new_shading)
{
	Object *ob;
	PointerRNA *ptr = &path->ptr[path->len - 1];
	Material *ma;

	/* if we already have a (pinned) material, we're done */
	if (RNA_struct_is_a(ptr->type, &RNA_Material)) {
		return 1;
	}
	/* if we have an object, use the object material slot */
	else if (buttons_context_path_object(path)) {
		ob = path->ptr[path->len - 1].data;

		if (ob && OB_TYPE_SUPPORT_MATERIAL(ob->type)) {
			ma = give_current_material(ob, ob->actcol);
			RNA_id_pointer_create(&ma->id, &path->ptr[path->len]);
			path->len++;

			if (for_texture && give_current_material_texture_node(ma))
				return 1;

			if (!new_shading) {
				/* Only try to get mat from node in case of old shading system (see T40331). */
				ma = give_node_material(ma);
				if (ma) {
					RNA_id_pointer_create(&ma->id, &path->ptr[path->len]);
					path->len++;
				}
			}
			return 1;
		}
	}

	/* no path to a material possible */
	return 0;
}
static int buttons_context_path(const bContext *C, ButsContextPath *path, int mainb, int flag)
{
	SpaceButs *sbuts = CTX_wm_space_buts(C);
	ID *id;
	int found;

	memset(path, 0, sizeof(*path));
	path->flag = flag;
	path->tex_ctx = sbuts->texture_context;

	/* if some ID datablock is pinned, set the root pointer */
	if (sbuts->pinid) {
		id = sbuts->pinid;

		RNA_id_pointer_create(id, &path->ptr[0]);
		path->len++;
	}

	/* no pinned root, use scene as root */
	if (path->len == 0) {
		id = (ID *)CTX_data_scene(C);
		RNA_id_pointer_create(id, &path->ptr[0]);
		path->len++;
	}

	/* now for each buttons context type, we try to construct a path,
	 * tracing back recursively */
	switch (mainb) {
		case BCONTEXT_SCENE:
		case BCONTEXT_RENDER:
			found = buttons_context_path_scene(path);
			break;
		case BCONTEXT_RENDER_LAYER:
#ifdef WITH_FREESTYLE
			if (buttons_context_linestyle_pinnable(C)) {
				found = buttons_context_path_linestyle(path);
				if (found) {
					break;
				}
			}
#endif
			found = buttons_context_path_scene(path);
			break;
		case BCONTEXT_WORLD:
			found = buttons_context_path_world(path);
			break;
		case BCONTEXT_OBJECT:
		case BCONTEXT_PHYSICS:
		case BCONTEXT_CONSTRAINT:
			found = buttons_context_path_object(path);
			break;
		case BCONTEXT_MODIFIER:
			found = buttons_context_path_modifier(path);
			break;
		case BCONTEXT_DATA:
			found = buttons_context_path_data(path, -1);
			break;
		case BCONTEXT_PARTICLE:
			found = buttons_context_path_particle(path);
			break;
		case BCONTEXT_MATERIAL:
			found = buttons_context_path_material(path, false, (sbuts->texuser != NULL));
			break;
		case BCONTEXT_TEXTURE:
			found = buttons_context_path_texture(path, sbuts->texuser);
			break;
		case BCONTEXT_BONE:
			found = buttons_context_path_bone(path);
			if (!found)
				found = buttons_context_path_data(path, OB_ARMATURE);
			break;
		case BCONTEXT_BONE_CONSTRAINT:
			found = buttons_context_path_pose_bone(path);
			break;
		default:
			found = 0;
			break;
	}

	return found;
}
static int buttons_context_path_texture(ButsContextPath *path, ButsContextTexture *ct)
{
	if (ct) {
		/* new shading system */
		PointerRNA *ptr = &path->ptr[path->len - 1];
		ID *id;

		/* if we already have a (pinned) texture, we're done */
		if (RNA_struct_is_a(ptr->type, &RNA_Texture))
			return 1;

		if (!ct->user)
			return 0;
		
		id = ct->user->id;

		if (id) {
			if (GS(id->name) == ID_BR)
				buttons_context_path_brush(path);
			else if (GS(id->name) == ID_MA)
				buttons_context_path_material(path, false, true);
			else if (GS(id->name) == ID_WO)
				buttons_context_path_world(path);
			else if (GS(id->name) == ID_LA)
				buttons_context_path_data(path, OB_LAMP);
			else if (GS(id->name) == ID_PA)
				buttons_context_path_particle(path);
			else if (GS(id->name) == ID_OB)
				buttons_context_path_object(path);
			else if (GS(id->name) == ID_LS)
				buttons_context_path_linestyle(path);
		}

		if (ct->texture) {
			RNA_id_pointer_create(&ct->texture->id, &path->ptr[path->len]);
			path->len++;
		}

		return 1;
	}
	else {
		/* old shading system */
		Material *ma;
		Lamp *la;
		World *wo;
		ParticleSystem *psys;
		FreestyleLineStyle *ls;
		Tex *tex;
		PointerRNA *ptr = &path->ptr[path->len - 1];

		/* if we already have a (pinned) texture, we're done */
		if (RNA_struct_is_a(ptr->type, &RNA_Texture)) {
			return 1;
		}
		/* try world */
		else if ((path->tex_ctx == SB_TEXC_WORLD) && buttons_context_path_world(path)) {
			wo = path->ptr[path->len - 1].data;

			if (wo && GS(wo->id.name) == ID_WO) {
				tex = give_current_world_texture(wo);

				RNA_id_pointer_create(&tex->id, &path->ptr[path->len]);
				path->len++;
				return 1;
			}
		}
		/* try particles */
		else if ((path->tex_ctx == SB_TEXC_PARTICLES) && buttons_context_path_particle(path)) {
			if (path->ptr[path->len - 1].type == &RNA_ParticleSettings) {
				ParticleSettings *part = path->ptr[path->len - 1].data;

				tex = give_current_particle_texture(part);
				RNA_id_pointer_create(&tex->id, &path->ptr[path->len]);
				path->len++;
				return 1;
			}
			else {
				psys = path->ptr[path->len - 1].data;

				if (psys && psys->part && GS(psys->part->id.name) == ID_PA) {
					tex = give_current_particle_texture(psys->part);

					RNA_id_pointer_create(&tex->id, &path->ptr[path->len]);
					path->len++;
					return 1;
				}
			}
		}
		/* try material */
		else if ((path->tex_ctx == SB_TEXC_MATERIAL) && buttons_context_path_material(path, true, false)) {
			ma = path->ptr[path->len - 1].data;

			if (ma) {
				tex = give_current_material_texture(ma);

				RNA_id_pointer_create(&tex->id, &path->ptr[path->len]);
				path->len++;
				return 1;
			}
		}
		/* try lamp */
		else if ((path->tex_ctx == SB_TEXC_LAMP) && buttons_context_path_data(path, OB_LAMP)) {
			la = path->ptr[path->len - 1].data;

			if (la) {
				tex = give_current_lamp_texture(la);

				RNA_id_pointer_create(&tex->id, &path->ptr[path->len]);
				path->len++;
				return 1;
			}
		}
		/* try linestyle */
		else if ((path->tex_ctx == SB_TEXC_LINESTYLE) && buttons_context_path_linestyle(path)) {
			ls = path->ptr[path->len - 1].data;

			if (ls) {
				tex = give_current_linestyle_texture(ls);

				RNA_id_pointer_create(&tex->id, &path->ptr[path->len]);
				path->len++;
				return 1;
			}
		}
	}

	/* no path to a texture possible */
	return 0;
}