The original working code is here. Works fine by clicking a button (btn), it copies the color from the displacement to the viewport.
http://blendervisionpro.blogspot.be/2014/12/copy-cycles-color-to-viewport.html
I would like to do it automatically without having to click the button (btn).
So I tried to do an "update" but doesn't work. (onChange).
My level of python is nul. But I can see it detects the shader color: variable cyColor and assigns it to the viewport: obMat.diffuse_color = cyColor
At the bottom of this post,
https://stackoverflow.com/questions/41021920/blender-python-onchange-event
I see @sambler edited a function called onChange of Map type:
but I don't know how to make it work onChange of Displacement (Shader) color.
I don't even know if the function I created "def update_viewport_color" ( exact copy of the execute function ) is even correct.
bl_info = {
"name": "Copy Cycles ViewPort Color from Shader Automatically SBB",
"author": "BVP source blenderartists.org/forum/archive/index.php/t-357610.html",
"version": (1, 0),
"blender": (2, 6, 4),
"location": "Material > Settings > Copy Cycles Color to Viewport",
"description": "Copy Cycles ViewPort Color from Shader Automatically SBB",
"warning": "",
"wiki_url": "",
"tracker_url": "",
"category": "Material"
}
import bpy
import mathutils
class CopyCyclesColorToViewport(bpy.types.Operator):
'''Copies Color of first Cycles node with Color input to Viewport Color of the material'''
bl_idname = "object.copy_cycles_color_to_viewport"
bl_label = "Copy ViewPort Color from Shader"
bl_options = {"REGISTER", "UNDO", "INTERNAL"}
@classmethod
def poll(cls, context):
return context.active_object is not None
def execute(self, context):
if context.active_object.active_material != None:
obMat = context.active_object.active_material
if obMat.cycles.id_data.node_tree != None:
for node in obMat.cycles.id_data.node_tree.nodes:
for nodeInput in node.inputs:
if nodeInput.type == 'RGBA':
cyColor = mathutils.Color((nodeInput.default_value[0], nodeInput.default_value[1], nodeInput.default_value[2]))
# prevent the color from being too dark for viewport
# by using a minimum HSV Value of 0.1
cyColor.v = max(0.1,cyColor.v)
obMat.diffuse_color = cyColor
# update=update_viewport_color
break
return {'FINISHED'}
def update_viewport_color(self,context):
if context.active_object.active_material != None:
obMat = context.active_object.active_material
if obMat.cycles.id_data.node_tree != None:
for node in obMat.cycles.id_data.node_tree.nodes:
for nodeInput in node.inputs:
if nodeInput.type == 'RGBA':
cyColor = mathutils.Color((nodeInput.default_value[0], nodeInput.default_value[1], nodeInput.default_value[2]))
# prevent the color from being too dark for viewport
# by using a minimum HSV Value of 0.1
cyColor.v = max(0.1,cyColor.v)
obMat.diffuse_color = cyColor
break
return {'FINISHED'}
# HOW TO CALL THE FUNCTION ABOVE ???
# ONCHANGE OF COLOR DISPLACEMENT (SHADER).
# update=update_viewport_color
def btn_draw(self, context):
if context.scene.render.engine == "CYCLES":
layout = self.layout
row = layout.row()
row.operator("object.copy_cycles_color_to_viewport")
def register():
bpy.utils.register_module(__name__)
bpy.types.CYCLES_MATERIAL_PT_settings.append(btn_draw)
def unregister():
bpy.types.CYCLES_MATERIAL_PT_settings.append(btn_draw)
bpy.utils.unregister_module(__name__)
if __name__ == '__main__':
register()
bpy.types.CYCLES_MATERIAL_PT_settingsrather thanbpy.types.CyclesMaterial_PT_settings– batFINGER Oct 02 '17 at 23:12