0
$\begingroup$

So I managed to get this:

RGBCurves window in custom UI

Into my Custom UI yesterday. Now I need the bool checkbox above it to turn it on and off. I've seen a few posts here that ask a similar question, but the solutions didn't work for this.

Specifically I can't figure out how to have the curves widget show right under the bool checkbox.

curve = bpy.data.materials["Skin"].node_tree.nodes["DarkCurve"]

def dark_switch(self, context):
    for tex in bpy.data.materials:
        if (self.my_bool == True):
            #print ("Property Enabled")
            mat.node_tree.links.new(curve.outputs[0], BSDF.inputs[0])
            bpy.data.materials["Skin"].node_tree.nodes["DarkLight"].blend_type = 'LIGHTEN'
        else:
            #print ("Property Disabled")
            mat.node_tree.links.new(mainmix.outputs[0], BSDF.inputs[0])
            bpy.data.materials["Skin"].node_tree.nodes["DarkLight"].blend_type = 'DARKEN'

class MyProperties(PropertyGroup):

    my_bool: BoolProperty(
        name="DarkSkin",
        description="Tick for Dark Skin",
        default = False,
        update = dark_switch
        )

That's the curve definition, and the bool code, which works perfectly in the node map. Except currently 'update = dark_switch' does nothing. I was wondering if that would work to call the curves widget into being, but IDK.

def draw(self, context):
        layout = self.layout
        scene = context.scene
        mytool = scene.my_tool
        
        
        layout.prop(mytool, "my_bool")
        layout.template_curve_mapping(curve, "mapping", type='COLOR')

This is the operator code for the bool and curve, I've cut out the operators, labels, and templates above and below them to save space. Suffice it to say, they all work, as do these two, in their current form.

I tried using an if statement in the layout stack to tie it to the bool, but it didn't work.

Update for recent comment my Gorgius

The darkswitch def is separate from the class.

def dark_switch(self, context):
    for tex in bpy.data.materials:
        if (self.my_bool == True):
            #print ("Property Enabled")
            mat.node_tree.links.new(curve.outputs[0], BSDF.inputs[0])
            bpy.data.materials["Skin"].node_tree.nodes["DarkLight"].blend_type = 'LIGHTEN'
            bpy.types.Panel.append(curves_menu)
        else:
            #print ("Property Disabled")
            mat.node_tree.links.new(mainmix.outputs[0], BSDF.inputs[0])
            bpy.data.materials["Skin"].node_tree.nodes["DarkLight"].blend_type = 'DARKEN'
            bpy.types.Panel.remove(curves_menu)


            
            
# ------------------------------------------------------------------------
#    Scene Properties
# ------------------------------------------------------------------------

class MyProperties(PropertyGroup):

    my_bool: BoolProperty(
        name="DarkSkin",
        description="Tick for Dark Skin",
        default = False,
        update = self.dark_switch
        )

Still throws:

line 94, in MyProperties NameError: name 'self' is not defined

I'm wondering if I can create the widget swap as a def, put that in the layout stack, then use the bool to change the def.

I'm going to try that after I get some coffee in me.

Update

That didn't work, but this morning I found this question which led me to this code:

col = layout.column()
        col.template_curve_mapping(curve, "mapping", type='COLOR')
        col.enabled = bpy.data.scenes["Scene"].my_tool.my_bool

Which is about half way to where I want it to be. It deactivates (greys out) the curve interface when the bool is off, but it's still there.

$\endgroup$
2
  • 1
    $\begingroup$ So you're trying to get it to where clicking the checkbox is what causes the curves menu to appear in your UI setup? $\endgroup$
    – Jakemoyo
    Jun 27, 2022 at 1:02
  • $\begingroup$ Exactly, yes. It's only connected to the rest of the node map when you're doing dark skin tones, cause they need more finesse to get right. So there's no use having it up on the menu otherwise. $\endgroup$ Jun 27, 2022 at 1:07

2 Answers 2

1
$\begingroup$

The solution is, as usual, much simpler than I'd originally assumed.

I have discovered in this question that 'if' functions work in layout!

if bpy.data.scenes["Scene"].my_tool.my_bool:
       layout.template_curve_mapping(curve, "mapping", type='COLOR')

Now it not only assigns the correct nodes together in the node map, but also doesn't present the curve unless you've selected dark skin mode.

$\endgroup$
0
$\begingroup$

So this is definitely not tested, and likely won't work out of the box, but I'm fairly sure this will get you 95% of the way to what you're trying to accomplish.

I can't exactly tell how you have everything organized from the snippets you've posted but...

Try reorganizing your code to resemble something like this.


# standalone function that draws  the curve menu 
def curves_menu(self, context):
    layout = self.layout
    scene = context.scene
    mytool = scene.my_tool
    layout.template_curve_mapping(curve, "mapping", type='COLOR')

class MyProperties(PropertyGroup):

    my_bool: BoolProperty(
        name="DarkSkin",
        description="Tick for Dark Skin",
        default = False,
        update = self.dark_switch
        )
    
    # this method is the callback function that enables or disables the
    # not tested, kind of pseudo code, it probably won't work as is
    # but i'm pretty sure it's at least pointed in the right direction 
    
    def dark_switch(self, context):
        # (btw python protip: you don't have to type 
        # if (self.my_bool == True):
        # you can just say: 
        # "if self.my_bool:" for truthy statements
        # or 
        # "if not self.my_bool:" to check for Falsy values.
        
        if self.my_bool:
            # this would be whatever panel menu class you wrote 
            bpy.types.MyToolPanel.append(curves_menu)
        else:
            bpy.types.MyToolPanel.remove(curves_menu)
    
    
# then put the stuff that changes you materials and node stuff into 
# an operator of it's own, like this. 

class MyToolOperator(bpy.types.Operator):
    bl_idname = "MyTool"
    bl_label = "MyTool Stuff"
    bl_options = {'REGISTER', 'UNDO'}

    @classmethod
    def poll(cls, context):
        return True 
        
    # the execute method is like the main "meat" of 
    # what you want your operator to do
    # put the contents of your current "dark_switch"
    # function in that 
    def execute(self, context):
        for tex in bpy.data.materials:
            if (self.my_bool == True):
                #print ("Property Enabled")
                mat.node_tree.links.new(curve.outputs[0], BSDF.inputs[0])
                bpy.data.materials["Skin"].node_tree.nodes["DarkLight"].blend_type = 'LIGHTEN'
            else:
                #print ("Property Disabled")
                mat.node_tree.links.new(mainmix.outputs[0], BSDF.inputs[0])
                bpy.data.materials["Skin"].node_tree.nodes["DarkLight"].blend_type = 'DARKEN'

Again, definitely work this around a bit but you seem like you're capable of figuring it out on your own.

$\endgroup$
10
  • $\begingroup$ I've been trying this out, and I keep getting this error: line 94, in MyProperties # subtype='DIR_PATH' NameError: name 'self' is not defined Or some variation of it. The consistent issue seems to be the bool doesn't like 'self'. Which I've noticed before, but haven't found why yet. $\endgroup$ Jun 27, 2022 at 3:26
  • 1
    $\begingroup$ It's because at the time of the definition of the annotation you can't reference self, put def dark_switch(self, context): and subsequent lines outside of the class definition. Also it seems you're iterating over text in the for loop but accessing mat which is undefined and I'm pretty sure will throw an error $\endgroup$
    – Gorgious
    Jun 27, 2022 at 6:02
  • $\begingroup$ @Gorgious Yeah I was 50/50 on the dark_switch method being it's own function or inside the class ¯_(ツ)_/¯ . We'll all get there the end, I guess. $\endgroup$
    – Jakemoyo
    Jun 27, 2022 at 8:43
  • $\begingroup$ Yeah I wish it would work like that it would be neater to encompass it into the class but unfortunately it doesn't work :p $\endgroup$
    – Gorgious
    Jun 27, 2022 at 8:56
  • $\begingroup$ It's not in the class though. See my latest update for the actual section of code. I'm also wondering how I'm meant to put it into the layout stack. $\endgroup$ Jun 27, 2022 at 20:56

You must log in to answer this question.

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