Made texture nodes accessible in the interface.
* Exposed Tex.use_nodes, Tex.nodetree, MTex.which_output in RNA * Added node controls to texture buttons (Use Nodes and Use Output) * Made new texture outputs have unique names by default, though unique names still aren't required. Note: The preview window in the texture buttons only takes which_output into account when in "material" mode, and in the material half of "both" mode; the plain texture display ignores the user's output choice. This is because ED_preview_draw draws a Tex* and not an MTex* -- still some work to do here.
This commit is contained in:
		@@ -7,7 +7,8 @@ class TextureButtonsPanel(bpy.types.Panel):
 | 
			
		||||
	__context__ = "texture"
 | 
			
		||||
	
 | 
			
		||||
	def poll(self, context):
 | 
			
		||||
		return (context.texture and context.texture.type != 'NONE')
 | 
			
		||||
		tex = context.texture
 | 
			
		||||
		return (tex and (tex.type != 'NONE' or tex.use_nodes))
 | 
			
		||||
		
 | 
			
		||||
class TEXTURE_PT_preview(TextureButtonsPanel):
 | 
			
		||||
	__label__ = "Preview"
 | 
			
		||||
@@ -61,24 +62,61 @@ class TEXTURE_PT_context_texture(TextureButtonsPanel):
 | 
			
		||||
		elif tex:
 | 
			
		||||
			split.template_ID(space, "pin_id")
 | 
			
		||||
 | 
			
		||||
		if (not space.pin_id) and (	context.sculpt_object or \
 | 
			
		||||
									context.vertex_paint_object or \
 | 
			
		||||
									context.weight_paint_object or \
 | 
			
		||||
									context.texture_paint_object \
 | 
			
		||||
		if (not space.pin_id) and (
 | 
			
		||||
			context.sculpt_object or
 | 
			
		||||
			context.vertex_paint_object or
 | 
			
		||||
			context.weight_paint_object or
 | 
			
		||||
			context.texture_paint_object
 | 
			
		||||
		):
 | 
			
		||||
			split.itemR(space, "brush_texture", text="Brush", toggle=True)
 | 
			
		||||
 | 
			
		||||
		if tex:
 | 
			
		||||
			layout.itemR(tex, "use_nodes")
 | 
			
		||||
			
 | 
			
		||||
			split = layout.split(percentage=0.2)
 | 
			
		||||
			
 | 
			
		||||
			if tex.use_nodes:
 | 
			
		||||
				slot = context.texture_slot
 | 
			
		||||
				split.itemL(text="Output:")
 | 
			
		||||
				split.itemR(slot, "output_node", text="")
 | 
			
		||||
 | 
			
		||||
			else:
 | 
			
		||||
				split.itemL(text="Type:")
 | 
			
		||||
				split.itemR(tex, "type", text="")
 | 
			
		||||
			
 | 
			
		||||
class TEXTURE_PT_mapping(TextureButtonsPanel):
 | 
			
		||||
	__label__ = "Mapping"
 | 
			
		||||
class TEXTURE_PT_colors(TextureButtonsPanel):
 | 
			
		||||
	__label__ = "Colors"
 | 
			
		||||
	__default_closed__ = True
 | 
			
		||||
 | 
			
		||||
	def draw(self, context):
 | 
			
		||||
		layout = self.layout
 | 
			
		||||
		
 | 
			
		||||
		tex = context.texture
 | 
			
		||||
 | 
			
		||||
		layout.itemR(tex, "use_color_ramp", text="Ramp")
 | 
			
		||||
		if tex.use_color_ramp:
 | 
			
		||||
			layout.template_color_ramp(tex.color_ramp, expand=True)
 | 
			
		||||
 | 
			
		||||
		split = layout.split()
 | 
			
		||||
		
 | 
			
		||||
		split.itemR(tex, "rgb_factor", text="Multiply RGB")
 | 
			
		||||
 | 
			
		||||
		col = split.column()
 | 
			
		||||
		col.itemL(text="Adjust:")
 | 
			
		||||
		col.itemR(tex, "brightness")
 | 
			
		||||
		col.itemR(tex, "contrast")
 | 
			
		||||
			
 | 
			
		||||
# Texture Slot Panels #
 | 
			
		||||
			
 | 
			
		||||
class TextureSlotPanel(TextureButtonsPanel):
 | 
			
		||||
	def poll(self, context):
 | 
			
		||||
		return (context.texture_slot and context.texture and context.texture.type != 'NONE')
 | 
			
		||||
		return (
 | 
			
		||||
			context.texture_slot and 
 | 
			
		||||
			TextureButtonsPanel.poll(self, context)
 | 
			
		||||
		)
 | 
			
		||||
				
 | 
			
		||||
class TEXTURE_PT_mapping(TextureSlotPanel):
 | 
			
		||||
	__label__ = "Mapping"
 | 
			
		||||
	
 | 
			
		||||
	def draw(self, context):
 | 
			
		||||
		layout = self.layout
 | 
			
		||||
@@ -150,12 +188,9 @@ class TEXTURE_PT_mapping(TextureButtonsPanel):
 | 
			
		||||
			row.column().itemR(tex, "offset")
 | 
			
		||||
			row.column().itemR(tex, "size")
 | 
			
		||||
 | 
			
		||||
class TEXTURE_PT_influence(TextureButtonsPanel):
 | 
			
		||||
class TEXTURE_PT_influence(TextureSlotPanel):
 | 
			
		||||
	__label__ = "Influence"
 | 
			
		||||
	
 | 
			
		||||
	def poll(self, context):
 | 
			
		||||
		return (context.texture_slot and context.texture and context.texture.type != 'NONE' and (not context.brush))
 | 
			
		||||
 | 
			
		||||
	def draw(self, context):
 | 
			
		||||
		layout = self.layout
 | 
			
		||||
		
 | 
			
		||||
@@ -235,36 +270,16 @@ class TEXTURE_PT_influence(TextureButtonsPanel):
 | 
			
		||||
		if ma or wo:
 | 
			
		||||
			col.itemR(tex, "default_value", text="DVar", slider=True)
 | 
			
		||||
 | 
			
		||||
class TEXTURE_PT_colors(TextureButtonsPanel):
 | 
			
		||||
	__label__ = "Colors"
 | 
			
		||||
	__default_closed__ = True
 | 
			
		||||
 | 
			
		||||
	def draw(self, context):
 | 
			
		||||
		layout = self.layout
 | 
			
		||||
		
 | 
			
		||||
		tex = context.texture
 | 
			
		||||
 | 
			
		||||
		layout.itemR(tex, "use_color_ramp", text="Ramp")
 | 
			
		||||
		if tex.use_color_ramp:
 | 
			
		||||
			layout.template_color_ramp(tex.color_ramp, expand=True)
 | 
			
		||||
 | 
			
		||||
		split = layout.split()
 | 
			
		||||
		
 | 
			
		||||
		split.itemR(tex, "rgb_factor", text="Multiply RGB")
 | 
			
		||||
 | 
			
		||||
		col = split.column()
 | 
			
		||||
		col.itemL(text="Adjust:")
 | 
			
		||||
		col.itemR(tex, "brightness")
 | 
			
		||||
		col.itemR(tex, "contrast")
 | 
			
		||||
		
 | 
			
		||||
# Texture Type Panels #
 | 
			
		||||
 | 
			
		||||
class TEXTURE_PT_clouds(TextureButtonsPanel):
 | 
			
		||||
	__label__ = "Clouds"
 | 
			
		||||
	
 | 
			
		||||
class TextureTypePanel(TextureButtonsPanel):
 | 
			
		||||
	def poll(self, context):
 | 
			
		||||
		tex = context.texture
 | 
			
		||||
		return (tex and tex.type == 'CLOUDS')
 | 
			
		||||
		return (tex and tex.type == self.tex_type and not tex.use_nodes)
 | 
			
		||||
 | 
			
		||||
class TEXTURE_PT_clouds(TextureTypePanel):
 | 
			
		||||
	__label__ = "Clouds"
 | 
			
		||||
	tex_type = 'CLOUDS'
 | 
			
		||||
 | 
			
		||||
	def draw(self, context):
 | 
			
		||||
		layout = self.layout
 | 
			
		||||
@@ -281,12 +296,9 @@ class TEXTURE_PT_clouds(TextureButtonsPanel):
 | 
			
		||||
		flow.itemR(tex, "noise_depth", text="Depth")
 | 
			
		||||
		flow.itemR(tex, "nabla", text="Nabla")
 | 
			
		||||
 | 
			
		||||
class TEXTURE_PT_wood(TextureButtonsPanel):
 | 
			
		||||
class TEXTURE_PT_wood(TextureTypePanel):
 | 
			
		||||
	__label__ = "Wood"
 | 
			
		||||
	
 | 
			
		||||
	def poll(self, context):
 | 
			
		||||
		tex = context.texture
 | 
			
		||||
		return (tex and tex.type == 'WOOD')
 | 
			
		||||
	tex_type = 'WOOD'
 | 
			
		||||
 | 
			
		||||
	def draw(self, context):
 | 
			
		||||
		layout = self.layout
 | 
			
		||||
@@ -308,12 +320,9 @@ class TEXTURE_PT_wood(TextureButtonsPanel):
 | 
			
		||||
		flow.itemR(tex, "turbulence")
 | 
			
		||||
		flow.itemR(tex, "nabla")
 | 
			
		||||
		
 | 
			
		||||
class TEXTURE_PT_marble(TextureButtonsPanel):
 | 
			
		||||
class TEXTURE_PT_marble(TextureTypePanel):
 | 
			
		||||
	__label__ = "Marble"
 | 
			
		||||
	
 | 
			
		||||
	def poll(self, context):
 | 
			
		||||
		tex = context.texture
 | 
			
		||||
		return (tex and tex.type == 'MARBLE')
 | 
			
		||||
	tex_type = 'MARBLE'
 | 
			
		||||
	
 | 
			
		||||
	def draw(self, context):
 | 
			
		||||
		layout = self.layout
 | 
			
		||||
@@ -332,12 +341,9 @@ class TEXTURE_PT_marble(TextureButtonsPanel):
 | 
			
		||||
		flow.itemR(tex, "turbulence")
 | 
			
		||||
		flow.itemR(tex, "nabla")
 | 
			
		||||
 | 
			
		||||
class TEXTURE_PT_magic(TextureButtonsPanel):
 | 
			
		||||
class TEXTURE_PT_magic(TextureTypePanel):
 | 
			
		||||
	__label__ = "Magic"
 | 
			
		||||
	
 | 
			
		||||
	def poll(self, context):
 | 
			
		||||
		tex = context.texture
 | 
			
		||||
		return (tex and tex.type == 'MAGIC')
 | 
			
		||||
	tex_type = 'MAGIC'
 | 
			
		||||
	
 | 
			
		||||
	def draw(self, context):
 | 
			
		||||
		layout = self.layout
 | 
			
		||||
@@ -348,12 +354,9 @@ class TEXTURE_PT_magic(TextureButtonsPanel):
 | 
			
		||||
		row.itemR(tex, "noise_depth", text="Depth")
 | 
			
		||||
		row.itemR(tex, "turbulence")
 | 
			
		||||
 | 
			
		||||
class TEXTURE_PT_blend(TextureButtonsPanel):
 | 
			
		||||
class TEXTURE_PT_blend(TextureTypePanel):
 | 
			
		||||
	__label__ = "Blend"
 | 
			
		||||
	
 | 
			
		||||
	def poll(self, context):
 | 
			
		||||
		tex = context.texture
 | 
			
		||||
		return (tex and tex.type == 'BLEND')
 | 
			
		||||
	tex_type = 'BLEND'
 | 
			
		||||
	
 | 
			
		||||
	def draw(self, context):
 | 
			
		||||
		layout = self.layout
 | 
			
		||||
@@ -363,12 +366,9 @@ class TEXTURE_PT_blend(TextureButtonsPanel):
 | 
			
		||||
		layout.itemR(tex, "progression")
 | 
			
		||||
		layout.itemR(tex, "flip_axis")
 | 
			
		||||
			
 | 
			
		||||
class TEXTURE_PT_stucci(TextureButtonsPanel):
 | 
			
		||||
class TEXTURE_PT_stucci(TextureTypePanel):
 | 
			
		||||
	__label__ = "Stucci"
 | 
			
		||||
	
 | 
			
		||||
	def poll(self, context):
 | 
			
		||||
		tex = context.texture
 | 
			
		||||
		return (tex and tex.type == 'STUCCI')
 | 
			
		||||
	tex_type = 'STUCCI'
 | 
			
		||||
	
 | 
			
		||||
	def draw(self, context):
 | 
			
		||||
		layout = self.layout
 | 
			
		||||
@@ -384,12 +384,9 @@ class TEXTURE_PT_stucci(TextureButtonsPanel):
 | 
			
		||||
		row.itemR(tex, "noise_size", text="Size")
 | 
			
		||||
		row.itemR(tex, "turbulence")
 | 
			
		||||
		
 | 
			
		||||
class TEXTURE_PT_image(TextureButtonsPanel):
 | 
			
		||||
class TEXTURE_PT_image(TextureTypePanel):
 | 
			
		||||
	__label__ = "Image"
 | 
			
		||||
	
 | 
			
		||||
	def poll(self, context):
 | 
			
		||||
		tex = context.texture
 | 
			
		||||
		return (tex and tex.type == 'IMAGE')
 | 
			
		||||
	tex_type = 'IMAGE'
 | 
			
		||||
	
 | 
			
		||||
	def draw(self, context):
 | 
			
		||||
		layout = self.layout
 | 
			
		||||
@@ -398,13 +395,10 @@ class TEXTURE_PT_image(TextureButtonsPanel):
 | 
			
		||||
 | 
			
		||||
		layout.template_texture_image(tex)
 | 
			
		||||
 | 
			
		||||
class TEXTURE_PT_image_sampling(TextureButtonsPanel):
 | 
			
		||||
class TEXTURE_PT_image_sampling(TextureTypePanel):
 | 
			
		||||
	__label__ = "Image Sampling"
 | 
			
		||||
	__default_closed__ = True
 | 
			
		||||
	
 | 
			
		||||
	def poll(self, context):
 | 
			
		||||
		tex = context.texture
 | 
			
		||||
		return (tex and tex.type == 'IMAGE')
 | 
			
		||||
	tex_type = 'IMAGE'
 | 
			
		||||
	
 | 
			
		||||
	def draw(self, context):
 | 
			
		||||
		layout = self.layout
 | 
			
		||||
@@ -449,13 +443,10 @@ class TEXTURE_PT_image_sampling(TextureButtonsPanel):
 | 
			
		||||
			else:
 | 
			
		||||
				col.itemR(tex, "filter_eccentricity", text="Eccentricity")
 | 
			
		||||
 | 
			
		||||
class TEXTURE_PT_image_mapping(TextureButtonsPanel):
 | 
			
		||||
class TEXTURE_PT_image_mapping(TextureTypePanel):
 | 
			
		||||
	__label__ = "Image Mapping"
 | 
			
		||||
	__default_closed__ = True
 | 
			
		||||
	
 | 
			
		||||
	def poll(self, context):
 | 
			
		||||
		tex = context.texture
 | 
			
		||||
		return (tex and tex.type == 'IMAGE')
 | 
			
		||||
	tex_type = 'IMAGE'
 | 
			
		||||
	
 | 
			
		||||
	def draw(self, context):
 | 
			
		||||
		layout = self.layout
 | 
			
		||||
@@ -499,12 +490,9 @@ class TEXTURE_PT_image_mapping(TextureButtonsPanel):
 | 
			
		||||
		col.itemR(tex, "crop_max_x", text="X")
 | 
			
		||||
		col.itemR(tex, "crop_max_y", text="Y")
 | 
			
		||||
	
 | 
			
		||||
class TEXTURE_PT_plugin(TextureButtonsPanel):
 | 
			
		||||
class TEXTURE_PT_plugin(TextureTypePanel):
 | 
			
		||||
	__label__ = "Plugin"
 | 
			
		||||
	
 | 
			
		||||
	def poll(self, context):
 | 
			
		||||
		tex = context.texture
 | 
			
		||||
		return (tex and tex.type == 'PLUGIN')
 | 
			
		||||
	tex_type = 'PLUGIN'
 | 
			
		||||
	
 | 
			
		||||
	def draw(self, context):
 | 
			
		||||
		layout = self.layout
 | 
			
		||||
@@ -513,12 +501,9 @@ class TEXTURE_PT_plugin(TextureButtonsPanel):
 | 
			
		||||
		
 | 
			
		||||
		layout.itemL(text="Nothing yet")
 | 
			
		||||
		
 | 
			
		||||
class TEXTURE_PT_envmap(TextureButtonsPanel):
 | 
			
		||||
class TEXTURE_PT_envmap(TextureTypePanel):
 | 
			
		||||
	__label__ = "Environment Map"
 | 
			
		||||
	
 | 
			
		||||
	def poll(self, context):
 | 
			
		||||
		tex = context.texture
 | 
			
		||||
		return (tex and tex.type == 'ENVIRONMENT_MAP')
 | 
			
		||||
	tex_type = 'ENVIRONMENT_MAP'
 | 
			
		||||
	
 | 
			
		||||
	def draw(self, context):
 | 
			
		||||
		layout = self.layout
 | 
			
		||||
@@ -527,12 +512,9 @@ class TEXTURE_PT_envmap(TextureButtonsPanel):
 | 
			
		||||
		
 | 
			
		||||
		layout.itemL(text="Nothing yet")
 | 
			
		||||
		
 | 
			
		||||
class TEXTURE_PT_musgrave(TextureButtonsPanel):
 | 
			
		||||
class TEXTURE_PT_musgrave(TextureTypePanel):
 | 
			
		||||
	__label__ = "Musgrave"
 | 
			
		||||
	
 | 
			
		||||
	def poll(self, context):
 | 
			
		||||
		tex = context.texture
 | 
			
		||||
		return (tex and tex.type == 'MUSGRAVE')
 | 
			
		||||
	tex_type = 'MUSGRAVE'
 | 
			
		||||
	
 | 
			
		||||
	def draw(self, context):
 | 
			
		||||
		layout = self.layout
 | 
			
		||||
@@ -563,12 +545,9 @@ class TEXTURE_PT_musgrave(TextureButtonsPanel):
 | 
			
		||||
		row.itemR(tex, "noise_size", text="Size")
 | 
			
		||||
		row.itemR(tex, "nabla")
 | 
			
		||||
 | 
			
		||||
class TEXTURE_PT_voronoi(TextureButtonsPanel):
 | 
			
		||||
class TEXTURE_PT_voronoi(TextureTypePanel):
 | 
			
		||||
	__label__ = "Voronoi"
 | 
			
		||||
	
 | 
			
		||||
	def poll(self, context):
 | 
			
		||||
		tex = context.texture
 | 
			
		||||
		return (tex and tex.type == 'VORONOI')
 | 
			
		||||
	tex_type = 'VORONOI'
 | 
			
		||||
 | 
			
		||||
	def draw(self, context):
 | 
			
		||||
		layout = self.layout
 | 
			
		||||
@@ -600,12 +579,9 @@ class TEXTURE_PT_voronoi(TextureButtonsPanel):
 | 
			
		||||
		row.itemR(tex, "noise_size", text="Size")
 | 
			
		||||
		row.itemR(tex, "nabla")
 | 
			
		||||
			
 | 
			
		||||
class TEXTURE_PT_distortednoise(TextureButtonsPanel):
 | 
			
		||||
class TEXTURE_PT_distortednoise(TextureTypePanel):
 | 
			
		||||
	__label__ = "Distorted Noise"
 | 
			
		||||
	
 | 
			
		||||
	def poll(self, context):
 | 
			
		||||
		tex = context.texture
 | 
			
		||||
		return (tex and tex.type == 'DISTORTED_NOISE')
 | 
			
		||||
	tex_type = 'DISTORTED_NOISE'
 | 
			
		||||
	
 | 
			
		||||
	def draw(self, context):
 | 
			
		||||
		layout = self.layout
 | 
			
		||||
 
 | 
			
		||||
@@ -36,6 +36,9 @@
 | 
			
		||||
#include "DNA_material_types.h"
 | 
			
		||||
#include "DNA_texture_types.h"
 | 
			
		||||
#include "DNA_world_types.h"
 | 
			
		||||
#include "DNA_node_types.h"
 | 
			
		||||
 | 
			
		||||
#include "BKE_node.h"
 | 
			
		||||
 | 
			
		||||
#include "WM_types.h"
 | 
			
		||||
 | 
			
		||||
@@ -107,6 +110,43 @@ static void rna_TextureSlot_name_get(PointerRNA *ptr, char *str)
 | 
			
		||||
		strcpy(str, "");
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static EnumPropertyItem *rna_TextureSlot_output_node_itemf(bContext *C, PointerRNA *ptr, int *free)
 | 
			
		||||
{
 | 
			
		||||
	MTex *mtex= ptr->data;
 | 
			
		||||
	Tex *tex= mtex->tex;
 | 
			
		||||
	EnumPropertyItem *item= NULL;
 | 
			
		||||
	int totitem= 0;
 | 
			
		||||
	
 | 
			
		||||
	if(tex)
 | 
			
		||||
	{
 | 
			
		||||
		bNodeTree *ntree= tex->nodetree;
 | 
			
		||||
		if(ntree)
 | 
			
		||||
		{
 | 
			
		||||
			EnumPropertyItem tmp= {0, "", 0, "", ""};
 | 
			
		||||
			bNode *node;
 | 
			
		||||
			
 | 
			
		||||
			tmp.value = 0;
 | 
			
		||||
			tmp.name = "Not Specified";
 | 
			
		||||
			tmp.identifier = "NOT_SPECIFIED";
 | 
			
		||||
			RNA_enum_item_add(&item, &totitem, &tmp);
 | 
			
		||||
			
 | 
			
		||||
			for(node= ntree->nodes.first; node; node= node->next) {
 | 
			
		||||
				if(node->type == TEX_NODE_OUTPUT) {
 | 
			
		||||
					tmp.value= node->custom1;
 | 
			
		||||
					tmp.name= ((TexNodeOutput*)node->storage)->name;
 | 
			
		||||
					tmp.identifier = tmp.name;
 | 
			
		||||
					RNA_enum_item_add(&item, &totitem, &tmp);
 | 
			
		||||
				}
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	RNA_enum_item_end(&item, &totitem);
 | 
			
		||||
	
 | 
			
		||||
	*free = 1;
 | 
			
		||||
	return item;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void rna_Texture_use_color_ramp_set(PointerRNA *ptr, int value)
 | 
			
		||||
{
 | 
			
		||||
	Tex *tex= (Tex*)ptr->data;
 | 
			
		||||
@@ -118,6 +158,18 @@ static void rna_Texture_use_color_ramp_set(PointerRNA *ptr, int value)
 | 
			
		||||
		tex->coba= add_colorband(0);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void rna_Texture_use_nodes_set(PointerRNA *ptr, int v)
 | 
			
		||||
{
 | 
			
		||||
	Tex *tex= (Tex*)ptr->data;
 | 
			
		||||
	
 | 
			
		||||
	tex->use_nodes = v;
 | 
			
		||||
	tex->type = 0;
 | 
			
		||||
	
 | 
			
		||||
	if(v && tex->nodetree==NULL) {
 | 
			
		||||
		node_texture_default(tex);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void rna_ImageTexture_mipmap_set(PointerRNA *ptr, int value)
 | 
			
		||||
{
 | 
			
		||||
	Tex *tex= (Tex*)ptr->data;
 | 
			
		||||
@@ -287,6 +339,10 @@ static void rna_def_mtex(BlenderRNA *brna)
 | 
			
		||||
		{MTEX_MAP_MODE_3D, "3D", 0, "3D", ""},
 | 
			
		||||
		{0, NULL, 0, NULL, NULL}};
 | 
			
		||||
 | 
			
		||||
	static EnumPropertyItem output_node_items[] = {
 | 
			
		||||
		{0, "DUMMY", 0, "Dummy", ""},
 | 
			
		||||
		{0, NULL, 0, NULL, NULL}};
 | 
			
		||||
		
 | 
			
		||||
	srna= RNA_def_struct(brna, "TextureSlot", NULL);
 | 
			
		||||
	RNA_def_struct_sdna(srna, "MTex");
 | 
			
		||||
	RNA_def_struct_ui_text(srna, "Texture Slot", "Texture slot defining the mapping and influence of a texture.");
 | 
			
		||||
@@ -373,6 +429,13 @@ static void rna_def_mtex(BlenderRNA *brna)
 | 
			
		||||
	RNA_def_property_ui_range(prop, 0, 5, 10, 3);
 | 
			
		||||
	RNA_def_property_ui_text(prop, "Normal Factor", "Amount texture affects normal values.");
 | 
			
		||||
	RNA_def_property_update(prop, NC_TEXTURE, NULL);
 | 
			
		||||
	
 | 
			
		||||
	prop= RNA_def_property(srna, "output_node", PROP_ENUM, PROP_NONE);
 | 
			
		||||
	RNA_def_property_enum_sdna(prop, NULL, "which_output");
 | 
			
		||||
	RNA_def_property_enum_items(prop, output_node_items);
 | 
			
		||||
	RNA_def_property_enum_funcs(prop, NULL, NULL, "rna_TextureSlot_output_node_itemf");
 | 
			
		||||
	RNA_def_property_ui_text(prop, "Output Node", "Which output node to use, for node-based textures.");
 | 
			
		||||
	RNA_def_property_update(prop, NC_TEXTURE, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void rna_def_filter_size_common(StructRNA *srna) 
 | 
			
		||||
@@ -1286,6 +1349,18 @@ static void rna_def_texture(BlenderRNA *brna)
 | 
			
		||||
	RNA_def_property_ui_text(prop, "RGB Factor", "");
 | 
			
		||||
	RNA_def_property_update(prop, NC_TEXTURE, NULL);
 | 
			
		||||
	
 | 
			
		||||
	/* nodetree */
 | 
			
		||||
	prop= RNA_def_property(srna, "use_nodes", PROP_BOOLEAN, PROP_NONE);
 | 
			
		||||
	RNA_def_property_boolean_sdna(prop, NULL, "use_nodes", 1);
 | 
			
		||||
	RNA_def_property_boolean_funcs(prop, NULL, "rna_Texture_use_nodes_set");
 | 
			
		||||
	RNA_def_property_ui_text(prop, "Use Nodes", "Make this a node-based texture");
 | 
			
		||||
	RNA_def_property_update(prop, NC_TEXTURE, NULL);
 | 
			
		||||
	
 | 
			
		||||
	prop= RNA_def_property(srna, "node_tree", PROP_POINTER, PROP_NONE);
 | 
			
		||||
	RNA_def_property_pointer_sdna(prop, NULL, "nodetree");
 | 
			
		||||
	RNA_def_property_ui_text(prop, "Node Tree", "Node tree for node-based textures");
 | 
			
		||||
	RNA_def_property_update(prop, NC_TEXTURE, NULL);
 | 
			
		||||
	
 | 
			
		||||
	rna_def_animdata_common(srna);
 | 
			
		||||
 | 
			
		||||
	/* specific types */
 | 
			
		||||
 
 | 
			
		||||
@@ -64,11 +64,64 @@ static void exec(void *data, bNode *node, bNodeStack **in, bNodeStack **out)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void init(bNode* node)
 | 
			
		||||
static void unique_name(bNode *node)
 | 
			
		||||
{
 | 
			
		||||
	TexNodeOutput *tno = (TexNodeOutput *)node->storage;
 | 
			
		||||
	char *new_name = 0;
 | 
			
		||||
	int new_len;
 | 
			
		||||
	int suffix;
 | 
			
		||||
	bNode *i;
 | 
			
		||||
	char *name = tno->name;
 | 
			
		||||
	
 | 
			
		||||
	i = node;
 | 
			
		||||
	while(i->prev) i = i->prev;
 | 
			
		||||
	for(; i; i=i->next) {
 | 
			
		||||
		if(
 | 
			
		||||
			i == node ||
 | 
			
		||||
			i->type != TEX_NODE_OUTPUT ||
 | 
			
		||||
			strcmp(name, ((TexNodeOutput*)(i->storage))->name)
 | 
			
		||||
		)
 | 
			
		||||
			continue;
 | 
			
		||||
		
 | 
			
		||||
		if(!new_name) {
 | 
			
		||||
			int len = strlen(name);
 | 
			
		||||
			if(len >= 4 && sscanf(name + len - 4, ".%03d", &suffix) == 1) {
 | 
			
		||||
				new_len = len;
 | 
			
		||||
			} else {
 | 
			
		||||
				suffix = 0;
 | 
			
		||||
				new_len = len + 4;
 | 
			
		||||
				if(new_len > 31)
 | 
			
		||||
					new_len = 31;
 | 
			
		||||
			}
 | 
			
		||||
			
 | 
			
		||||
			new_name = malloc(new_len + 1);
 | 
			
		||||
			strcpy(new_name, name);
 | 
			
		||||
			name = new_name;
 | 
			
		||||
		}
 | 
			
		||||
		sprintf(new_name + new_len - 4, ".%03d", ++suffix);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	if(new_name) {
 | 
			
		||||
		strcpy(tno->name, new_name);
 | 
			
		||||
		free(new_name);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void init(bNode *node)
 | 
			
		||||
{
 | 
			
		||||
	TexNodeOutput *tno = MEM_callocN(sizeof(TexNodeOutput), "TEX_output");
 | 
			
		||||
   strcpy(tno->name, "Default");
 | 
			
		||||
	node->storage= tno;
 | 
			
		||||
	
 | 
			
		||||
	strcpy(tno->name, "Default");
 | 
			
		||||
	unique_name(node);
 | 
			
		||||
	ntreeTexAssignIndex(0, node);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void copy(bNode *orig, bNode *new)
 | 
			
		||||
{
 | 
			
		||||
	node_copy_standard_storage(orig, new);
 | 
			
		||||
	unique_name(new);
 | 
			
		||||
	ntreeTexAssignIndex(0, new);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@@ -85,6 +138,6 @@ bNodeType tex_node_output= {
 | 
			
		||||
	/* butfunc         */  NULL,
 | 
			
		||||
	/* initfunc        */  init,
 | 
			
		||||
	/* freestoragefunc */  node_free_standard_storage,
 | 
			
		||||
	/* copystoragefunc */  node_copy_standard_storage,  
 | 
			
		||||
	/* copystoragefunc */  copy,  
 | 
			
		||||
	/* id              */  NULL
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -197,6 +197,10 @@ void ntreeTexExecTree(bNodeTree *nodes, TexResult *texres, float *coord, char do
 | 
			
		||||
	TexResult dummy_texres;
 | 
			
		||||
	TexCallData data;
 | 
			
		||||
	
 | 
			
		||||
	/* 0 means don't care, so just use first */
 | 
			
		||||
	if(which_output == 0)
 | 
			
		||||
		which_output = 1;
 | 
			
		||||
	
 | 
			
		||||
	if(!texres) texres = &dummy_texres;
 | 
			
		||||
	data.coord = coord;
 | 
			
		||||
	data.target = texres;
 | 
			
		||||
@@ -270,10 +274,17 @@ char* ntreeTexOutputMenu(bNodeTree *ntree)
 | 
			
		||||
void ntreeTexAssignIndex(struct bNodeTree *ntree, struct bNode *node)
 | 
			
		||||
{
 | 
			
		||||
	bNode *tnode;
 | 
			
		||||
	int index = 0;
 | 
			
		||||
	int index = 1;
 | 
			
		||||
	
 | 
			
		||||
	if(ntree) 
 | 
			
		||||
		tnode = ntree->nodes.first;
 | 
			
		||||
	else {
 | 
			
		||||
		tnode = node;
 | 
			
		||||
		while(tnode->prev) tnode = tnode->prev;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	check_index:
 | 
			
		||||
	for(tnode= ntree->nodes.first; tnode; tnode= tnode->next)
 | 
			
		||||
	for(; tnode; tnode= tnode->next)
 | 
			
		||||
		if(tnode->type == TEX_NODE_OUTPUT && tnode != node)
 | 
			
		||||
			if(tnode->custom1 == index) {
 | 
			
		||||
				index ++;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user