1
$\begingroup$

I have a custom panel with a bunch of things doing various stuff. They're all linked to custom properties that are linked to other things, it was just easier for me to understand, I'm a beginner python programer!. The issue is, when I change the values from the custom property itself, it changes the values that they're all linked to and everything works perfectly. But the problem is that when I use the custom panel, it changes the custom property values, but thats it. For example, in the linked code below, the iSight Camera Indicator is linked to an emission node. When I use the custom property, it changes the emission from 0 to 1, but when I use the panel, it doesn't...

Here is my code:

import bpy
from bpy.types import (Menu, PropertyGroup)
from bpy.props import (BoolProperty, FloatProperty, EnumProperty)

def update_after_enum(self, context):
    print ("place holder")
    D = bpy.data

    if colors == 'Gold':
        D.objects['Macbook'].material_slots[0].material = D.materials['Gold']
        D.objects['Macbook'].material_slots[9].material = D.materials['Gold Apple Logo']
    elif colors == 'Silver':
        D.objects['Macbook'].material_slots[0].material = D.materials['Silver']
        D.objects['Macbook'].material_slots[9].material = D.materials['Silver']
    elif colors == 'Space Grey':
        D.objects['Macbook'].material_slots[0].material = D.materials['Space Grey']
        D.objects['Macbook'].material_slots[9].material = D.materials['Space Grey Apple Logo']


def common_update(self, context, origin):
    obj = bpy.data.objects.get("Macbook")
    if not obj:
        return

    if origin == 'isight_camera_indicator':
        obj["00_iSight Camera Indicator"] = getattr(self, origin)

        node_tree = bpy.data.materials['iSight Camera Indicator'].node_tree
        node = node_tree.nodes["Emission"]

        if getattr(self, origin):
            emission_value = 5.0
        else:
            emission_value = 0.0

        nodes["Emission"].inputs[1].default_value = emission_value

    elif origin == 'dirt_and_dust':
        obj["01_Dirt and Dust"] = getattr(self, origin)
    elif origin == 'menubar_and_dock':
        obj["02_Menubar and Dock"] = getattr(self, origin)
    elif origin == 'screen_rotation':
        obj["03_Screen Rotation"] = getattr(self, origin)


class IgnitProperties(bpy.types.PropertyGroup):

    isight_camera_indicator = BoolProperty(
        name = "iSight Camera Indicator",
        description = "Toggles the iSight Camera Indicator ON and OFF",
        default = False,
        update = lambda self, context: common_update(self, context, 'isight_camera_indicator')
    )

    dirt_and_dust = BoolProperty(
        name = "Dirt and Dust",
        description = "Toggles the Dirt and Dust ON and OFF",
        default = False,
        update = lambda self, context: common_update(self, context, 'dirt_and_dust')
    )

    menubar_and_dock = BoolProperty(
        name = "Menubar and Dock",
        description = "Toggles the Menubar and Dock ON and OFF",
        default = False,
        update = lambda self, context: common_update(self, context, 'menubar_and_dock')
    )

    screen_rotation = FloatProperty(
        name = "Screen Rotation",
        description = "Rotates the screen",
        default = 0.0,
        min = 0.0,
        max = 1.0,
        update = lambda self, context: common_update(self, context, 'screen_rotation')
    )

    #MacBook Colors
    colors = EnumProperty(
        name = "MacBook Colors",
        description = "Changes the color of the MacBook",
        items = [
            ("Silver", "Silver", "Silver"),
            ("Gold", "Gold", "Gold"),
            ("Space Grey", "Space Grey", "Space Grey")
        ],
        update = update_after_enum
    )

class IGLayoutDemoPanel(bpy.types.Panel):
    """Creates a Panel in the scene context of the properties editor"""
    bl_label = "MacBook Controller"
    bl_idname = "object_mode.macbook_controller"
    bl_space_type = 'PROPERTIES'
    bl_region_type = 'WINDOW'
    bl_context = "object"

    def draw(self, context):
        layout = self.layout

        layout.label(text = "Main Features:")

        scene = context.scene
        split = layout.split()
        scene = context.scene
        camera = scene.camera.data

        # First column
        col = split.column()
        col.prop(scene.ignit_panel, "isight_camera_indicator")
        col.prop(scene.ignit_panel, "dirt_and_dust")

        # Second Column
        col = split.column()
        col.prop(scene.ignit_panel, "menubar_and_dock")
        col.prop(scene.ignit_panel, "screen_rotation")

        # MacBook Colors
        layout.label(text = "MacBook Color:")

        row = layout.row(align=True)

        row.prop(scene.ignit_panel, "colors", expand = True)



def register():
    bpy.utils.register_module(__name__)
    bpy.types.Scene.ignit_panel = bpy.props.PointerProperty(type=IgnitProperties)


def unregister():
    bpy.utils.unregister__module(__name__)
    del bpy.types.Scene.ignit_panel


if __name__ == "__main__":
    register()
$\endgroup$
1
  • 1
    $\begingroup$ nodes["Emission"].inputs[1].default_value = emission_value is wrong. nodes reference doesn't exist. (tidying up comments this comment should be here, not under my code) $\endgroup$
    – zeffii
    Dec 28, 2015 at 9:38

1 Answer 1

2
$\begingroup$

The update function just updates the values stored in the ID properties of the object. Changing them doesn't automagically affect your emission shader.

You have this, and that's fine. But you probably want something else.

def common_update(self, context, origin):
    obj = bpy.data.objects.get("Macbook_Gold")
    if not obj:
        return

    if origin == 'isight_camera_indicator':
        obj["00_iSight Camera Indicator"] = getattr(self, origin)
    elif origin == 'dirt_and_dust':
        obj["01_Dirt and Dust"] = getattr(self, origin)
    elif origin == 'menubar_and_dock':
        obj["02_Menubar and Dock"] = getattr(self, origin)
    elif origin == 'screen_rotation':
        obj["03_Screen Rotation"] = getattr(self, origin)

To do something with a shader depending on a boolean value you have to reference the shader.

I'll just show the isight_camera_indicator, this snippet would update the emission value in the emission node called "Emission" for the material specified:

def common_update(self, context, origin):
    obj = bpy.data.objects.get("Macbook_Gold")
    if not obj:
        return

    if origin == 'isight_camera_indicator':
        obj["00_iSight Camera Indicator"] = getattr(self, origin)
        # then update your material emission
        node_tree = bpy.data.materials['iSight Camera Indicator'].node_tree
        node = node_tree.nodes["Emission"]

        if getattr(self, origin):
            emission_value = 30.0
        else:
            emission_value = 0.1

        node.inputs[1].default_value = emission_value

regarding :

obj["00_iSight Camera Indicator"] = getattr(self, origin)

All this line does is update the ID property you made for the object. Useful if you want to keep track of the state of some parameters within the Object. However, you still need to generate some effect from the switching on and off of the BoolProperty. (shown above)

$\endgroup$
5
  • $\begingroup$ So will changing the node itself mean I don't need the custom properties? $\endgroup$
    – mr-matt
    Dec 27, 2015 at 22:24
  • $\begingroup$ Not working, updated the code... $\endgroup$
    – mr-matt
    Dec 28, 2015 at 3:43
  • $\begingroup$ and yes, the custom properties are a little redundant for your immediate scenario. $\endgroup$
    – zeffii
    Dec 28, 2015 at 9:07
  • $\begingroup$ Oh well, I'll leave them in there, seeing as though I went to the trouble of making all of them... $\endgroup$
    – mr-matt
    Dec 28, 2015 at 9:07
  • $\begingroup$ Awesome, all working, your the man dude! $\endgroup$
    – mr-matt
    Dec 28, 2015 at 9:16

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .