3
$\begingroup$

I'm back again with a code problem that's probably obvious to everyone else. I'm trying to make a one-stop menu for the initial setup of a texture system I've developed, and I'm having trouble getting things to show up on the menu. I'm using a UI code template from another post here, I forget which one, but the author is listed as 'p2or'.

I managed to make a property that my first script can read and use, now I need a way to control other aspects from the menu I'm making. Ideally I'd like to have all the colours and important options available in the menu.

but for now I'm just trying to figure out how to get the Texture >Coordinate Object Property menu To show up as a menu item.

# ------------------------------------------------------------------------
#    Menus
# ------------------------------------------------------------------------

class OBJECT_MT_CustomMenu(bpy.types.Menu):
    bl_label = "Character Object"
    bl_idname = "OBJECT_MT_custom_menu"

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

        # Built-in operators
        layout.operator("object.select", bpy.data.materials["Skin"].node_tree.nodes["Texture Coordinate"].object)
 #       layout.operator("object.select_all", text="Select/Deselect All").action = 'TOGGLE'
 #       layout.operator("object.select_all", text="Inverse").action = 'INVERT'
 #       layout.operator("object.select_random", text="Random")

Hasn't worked, and I know it has to be something I'm not calling, but I have no idea what.

Gorgious helped me with the object selection one, turns out I needed to call it as layout.prop

Since that works, I'm now curious what other pieces of syntax I'm not aware of.

I would also like to make a button to execute the image generation script, if anyone has advice on that.

class WM_OT_HelloWorld(Operator):
    bl_label = "Populate Masks"
    bl_idname = "wm.hello_world"

    def execute(self, context):
#        scene = context.scene
#        mytool = scene.my_tool
#        filename = "//imggen.py"
        exec(bpy.data.texts["imggen"].name)

        # print the values to the console
#        print("Hello World")
#        print("bool state:", mytool.my_bool)
#        print("int value:", mytool.my_int)
#        print("float value:", mytool.my_float)
#        print("string value:", mytool.my_string)
#        print("enum state:", mytool.my_enum)

        return {'FINISHED'}

I've tried calling it as a file, and from within Blender, same result. Currently the button just tells me:

line 105, in execute File "", line 1, in NameError: name 'imggen' is not defined

Update: So I managed to get the color function linked to the node map and visible in the menu I'm making.

my_float_vector: FloatVectorProperty(
        name = "Interior 1",
        subtype = "COLOR",
        size = 4,
        description="Should be Red or Pink",
        default=(0.0, 0.0, 0.0, 1.0), 
        min= 0.0, # float
        max = 1.0
        ) 

mat = bpy.data.materials['Skin']
nodes = mat.node_tree.nodes
node = nodes.get("RGB.005")
# change the color
node.outputs[0].default_value = (bpy.data.scenes["Scene"].my_tool.my_float_vector) 

This presents a new minor problem, where when I change the color in the new menu, it doesn't update in the node map unless I run the script again. I'm thinking of making an Update Button for the colors, but if anyone knows a way to get it to update live, that would be better.

Still haven't managed to get the other button to run the image generator script.

Update

So I got back to it today and tried to run the script so I could try the update solution posted earlier, and now I'm getting this:

AttributeError: 'Scene' object has no attribute 'my_tool'

It's choking on this:

node.outputs[0].default_value = (bpy.data.scenes["Scene"].my_tool.my_float_vector)  

If I comment it out then run the script it works, then I can uncomment it, run it again and then it takes. Some quick searching indicates I need to register 'my_tool' at some point, but when I try, it chokes on that, so clearly I'm not doing it right.

I also tried the update function in the float vector group, and it also chokes on that.

line 70, in MyProperties
NameError: name 'self' is not defined
my_float_vector: FloatVectorProperty(
        name = "Interior 1",
        subtype = "COLOR",
        size = 4,
        description="Should be Red or Pink",
        default=(0.0, 0.0, 0.0, 1.0), 
        min= 0.0, # float
        max = 1.0,
        update = (self,context)
        ) 

I've tried it as different lines in that group, same result.

Update

As I've been experimenting with functions, I've decided that several of my functions would be best served by placing the colorramp interfaces right in the addon menu.

I found this little snippet:

cr_node = bpy.data.node_groups["NodeGroup.002"].nodes["ColorRamp"].name
layout.template_color_ramp(cr_node, "color_ramp", expand=True)

But I don't know what class of zone it needs, and I can't find a list of them anywhere. If there is one on the Blender API I'd appreciate a link. It gave me this error:

NameError: name 'layout' is not defined

Update

I fixed that, more or less, it was in the wrong place. Now it's giving me this:

TypeError: UILayout.template_color_ramp(): error with argument 1, "data" -  Function.data expected a AnyType type, not str
$\endgroup$
4
  • $\begingroup$ layout.prop(bpy.data.materials["Skin"].node_tree.nodes["Texture Coordinate"], "object") ? $\endgroup$
    – Gorgious
    Jun 19, 2022 at 21:24
  • $\begingroup$ I see! layout.prop That makes sense! Ok, now to see if I can recreate that success with other properties. Now, are there other types of property for that context I should be aware of? $\endgroup$ Jun 19, 2022 at 21:28
  • $\begingroup$ It depends on what you want the user to be able to tweak. You can display pretty much any property that's displayed on the node $\endgroup$
    – Gorgious
    Jun 20, 2022 at 6:40
  • $\begingroup$ re your update : you should look into prop definition update callback docs.blender.org/api/current/… that lets you run code when you change a property value $\endgroup$
    – Gorgious
    Jun 20, 2022 at 6:47

1 Answer 1

1
$\begingroup$

Well I finally found the answer to this, in another post.

I had found this before, but it didn't work for me, and I finally figured out why.

cr_node = bpy.data.materials['Material'].node_tree.nodes['ColorRamp']
layout.template_color_ramp(cr_node, "color_ramp", expand=True)

This works if the node in on the base layer, but my system has a lot of frames and groups, which I didn't realize before was an important distinction. My final code for this function looks more like this:

cr_node = bpy.data.node_groups["NodeGroup.002"].nodes["ColorRamp"]
layout.template_color_ramp(cr_node, "color_ramp", expand=True)

The only problem with this is I can't put a label on it the same way I did the RGB fields.

$\endgroup$

You must log in to answer this question.

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