Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
import bpy
import random
from mathutils import Vector
'''
text should be something like this (int or float, should add up to 100)
- either provide three color components (rgb)
- provide one, automatic greyscale is made
- provide none, random color is returned.
20.0, 0.2, 0.5, 0.2
20, 0.3, 0.2, 0.5
20.0, 0.1, 0.4, 0.1
20, 0.5
20
'''
def get_random_color():
RAN = random.random
return RAN(), RAN(), RAN(), 1.0
def greyscale(ft):
ft = float(ft)
return (ft, ft, ft, 1.0)
def generate_pie_nodes(context, nodes):
def new_node(t):
return nodes.new(type=t)
TextureCoordinate = new_node("ShaderNodeTexCoord")
GradientTexture = new_node("ShaderNodeTexGradient")
ColorRamp = new_node("ShaderNodeValToRGB")
DiffuseBSDF = new_node("ShaderNodeBsdfDiffuse")
x, y = context.space_data.cursor_location
TextureCoordinate.location = Vector((0.0000+x, 0.0000+y))
GradientTexture.location = Vector((175.1804+x, 3.6965+y))
ColorRamp.location = Vector((353.9348+x, 2.7287+y))
DiffuseBSDF.location = Vector((609.6481+x, 6.6672+y))
''' hook up nodes '''
node_tree = context.space_data.node_tree
a = TextureCoordinate.outputs['Object']
b = GradientTexture.inputs['Vector']
node_tree.links.new(a, b)
a = GradientTexture.outputs['Fac']
GradientTexture.gradient_type = 'RADIAL'
b = ColorRamp.inputs['Fac']
node_tree.links.new(a, b)
a = ColorRamp.outputs['Color']
ColorRamp.color_ramp.interpolation = 'CONSTANT'
b = DiffuseBSDF.inputs[0]
node_tree.links.new(a, b)
a = DiffuseBSDF.outputs[0]
b = nodes.get("Material Output").inputs[0]
node_tree.links.new(a, b)
def make_slices(ctx, nodes):
cRamp = nodes.get('ColorRamp')
if not cRamp:
generate_pie_nodes(ctx, nodes)
elements = nodes['ColorRamp'].color_ramp.elements
else:
elements = cRamp.color_ramp.elements
pitems_str = bpy.data.texts[ctx.scene.PIE_CHART_pcts_name].as_string()
pitems = pitems_str.split('\n')
pc = []
for i in pitems:
temp = []
psplit = i.split(',')
splits = len(psplit)
if splits == 1:
temp.extend([float(psplit[0]), get_random_color()])
elif splits == 2:
temp.extend([float(psplit[0]), greyscale(psplit[1])])
elif splits == 4:
r, g, b = [float(psplit[c]) for c in range(1,4)]
temp.extend([float(psplit[0]), (r, g, b, 1.0)])
else:
temp.extend([float(i.strip()), get_random_color()])
pc.append(temp)
procents_and_colors = pc
# this sections adds or removes elements if you update your
# procents_and_colors list with more / fewer elements
diff = len(elements) - len(procents_and_colors)
if diff > 0:
for i in range(abs(diff)):
elements.remove(elements[-1])
elif diff < 0:
for i in range(abs(diff)):
elements.new(position=0.0)
# --------------------
position = 0
for idx, section in enumerate(procents_and_colors):
elements[idx].color = section[1]
elements[idx].position = position
# instead of 100 , if you precalc the sum it would produce the relative
# splits for you...
position += (section[0] / 100.0)
class PieChartDemoOps(bpy.types.Operator):
bl_label = "Pie Chart Operator"
bl_idname = "scene.piechart_pusher"
@classmethod
def poll(self, context):
return context.scene.PIE_CHART_pcts_name in bpy.data.texts
def execute(self, context):
space = context.space_data
node_tree = space.node_tree
nodes = node_tree.nodes
make_slices(context, nodes)
return {'FINISHED'}
class PieChartDemoPanel(bpy.types.Panel):
"""Creates a Panel in the scene context of the properties editor"""
bl_label = "Pie Chart Demo"
bl_idname = "PIECHART_PT_loader"
bl_space_type = 'NODE_EDITOR'
bl_region_type = 'UI'
@classmethod
def poll(self, context):
try:
return context.space_data.edit_tree.name == 'Shader Nodetree'
except:
return false
def draw(self, context):
layout = self.layout
scn = context.scene
layout.label(text=" Use text file: ( .pts )")
layout.prop_search(scn, "PIE_CHART_pcts_name", bpy.data, "texts", text="")
if context.scene.PIE_CHART_pcts_name:
f = layout.operator("scene.piechart_pusher", text='make me!')
def register():
bpy.types.Scene.PIE_CHART_pcts_name = bpy.props.StringProperty()
bpy.utils.register_class(PieChartDemoPanel)
bpy.utils.register_class(PieChartDemoOps)
def unregister():
bpy.utils.unregister_class(PieChartDemoOps)
bpy.utils.unregister_class(PieChartDemoPanel)
del bpy.types.Scene.PIE_CHART_pcts_name
if __name__ == "__main__":
register()
@zeffii

This comment has been minimized.

Copy link
Owner Author

zeffii commented Aug 8, 2015

notes.. this will attache the relative nodes to the mouse cursor position. This means if you use the button to 'Make me!'' the nodes will appear where you probably don't want them. A current solution is to pick the text file, then navigate to the nodeview, then hit space and type 'Pie C', it will autofill to Pie Chart Operator, hit enter and BAM! it make the nodes,, connected, and also reads the text file and makes the coloramp elements.

None, dynamically ofcourse, but this could be done with relative ease -- but not by me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.