0

I've been trying to set up some custom enum flags. In my situation, there are two variables that I want to share the same enum type setup. So I would like the flags to be interchangeable between them. This is how I currently have it set up. For some reason, the controls do not show up when I draw them after moving the items into their own definition. They seemed to be fine when they defined their own items. Can anyone see where I'm doing this wrong? Or does a UI element just fail to draw when it uses "external" enum items?

def FBXG_Mode(self,context):
    items=[ ('GA', "Asset", "Game Asset"),
            ('LP', "Low", "Low Poly"),
            ('HP', "High", "High Poly"),
            ]
    return items

bpy.types.collection.FBXGSpawner : EnumProperty(
    name="File Spawners",
    options={'ENUM_FLAG'},
    items=FBXG_Mode,
    description="Info",
    )

bpy.types.object.FBXGBlocker : EnumProperty(
    name="Object Blockers",
    options={'ENUM_FLAG'},
    items=FBXG_Mode,
    description="Info",
    )
Robert
  • 1,265
  • 1
  • 13
  • 29
  • 2
    Consult the docs https://docs.blender.org/api/blender2.8/bpy.props.html#bpy.props.EnumProperty Using ENUM_FLAG allows multi-select of enum items and requires the item number to be set. Is this what you want? to for example have ability to mark item as both low and high poly? (Probably not). Appears there is no need for the dynamic items method here either, could define the items list items = [(a, b, c), ..] then in defining prop items=items – batFINGER Sep 08 '19 at 02:49
  • Yes, they are intended to allow toggling all three states independently. For example, an object can be exported as both an asset and low poly for baking. I'm having trouble understanding your advice. I'm also not clear on what the item "number" would represent? The number of enum entries? I'm very new to python, so its likely my lack of knowledge. My goal here is to just have the two variables have interchangeable flags. So, for example, I can use a flag I detected enabled for collection-spawners in a function that activates object-blockers, without having to manually translate. – Robert Sep 08 '19 at 03:14
  • 1
    Consult the docs https://docs.blender.org/api/blender2.8/bpy.props.html#bpy.props.EnumProperty items = [(identifier, name, description, icon, number ), ...]. – batFINGER Sep 08 '19 at 03:41
  • Wow, I didn't notice the little scrollbars for each entry until just now. All this time, I assumed the docs only explained the first few elements and moved on. – Robert Sep 08 '19 at 14:44
  • 1
    Unfortunately, the docs didn't help much even after finally finding the description of the numbers attribute. I don't understand why I would need a unique identifier for a variable that already has one? I tried setting the number attribute of both EnumProperty entries. I tried 7 (bit 1, 2, and 3 all turned on), 8 (the next available bit), and 16 (for kicks). Nothing seems to change. My properties are still invisible with no errors. I appreciate your extreme efforts, though – Robert Sep 08 '19 at 15:03
  • After messing around some more, it looks like my problem has nothing to do with enums. All of my properties that relate to the scene or objects are not drawing, but also not showing any errors. Apparently, something I did recently caused this. If anyone has a good guess as to what it might be, I appreciate it. EDIT: I figured it out 5 seconds after posting this. It is because I used ':' operator instead of '=' when defining the properties. Weird. I read that Blender 2.8+ should use ':'. – Robert Sep 08 '19 at 17:01

1 Answers1

-1

The reason my enums were not showing up was due to me changing my property definitions to use the ':' operator instead of '=', such as..

bpy.types.Collection.FBXGSpawner : EnumProperty(

instead of..

bpy.types.Collection.FBXGSpawner = EnumProperty(

I read that we are supposed to use the ':' operator in Blender 2.8+. If this is the case, maybe someone can help point out what else I may have done wrong to prevent properties from drawing. One of my simple drawing functions..

# draw object settings
def draw(self, contex):
    aobject = bpy.context.object
    layout = self.layout
    box = layout.box()
    con = box.row()
    con.prop(aobject, "MergeWith")

If anyone knows the reason they were not rendering, post and I will accept it as the answer. Thanks!

Edit: After playing around with the code, I believe this is (at least close) to the correct way to set up a custom enum:

class FBXG_MappingPanel(bpy.types.Panel):
# define enum flags
EnumTypes=[ ('GA', "Asset", "tooltip"),
            ('LP', "Low", "tooltip"),
            ('HP', "High", "tooltip"),
            ]

# define enum variable
EnumVariable= bpy.props.EnumProperty(
    name="Title",
    options={'ENUM_FLAG'},
    items=EnumTypes,
    description="tooltip",
    )

# define drawing section
def draw(self, context):

    # draw
    layout = self.layout
    row = layout.row()
    row.prop_enum(self, "EnumVariable", 'GA', text='Asset')
    row.prop_enum(self, "EnumVariable", 'LP', text='Low')
    row.prop_enum(self, "EnumVariable", 'HP', text='High')

The biggest mistake I made was not realizing that you need an individual prop_enum() call for each individual flag allowed to be selected. I was trying to use it as a single call. If anyone notices any issues here, that would be appreciated. Also, if anyone can help newcomers understand what the number property is intended for and what purpose it serves, that would also be great. Thanks!

Gorgious
  • 30,723
  • 2
  • 44
  • 101
Robert
  • 1,265
  • 1
  • 13
  • 29
  • 3
    The : is for a type annotation when declaring the properties (you want to tell Python that your variable is supposed to be of a certain type), not when you want to perform an assignment like here to bpy.types. See: https://www.python.org/dev/peps/pep-0526/ https://wiki.blender.org/wiki/Reference/Release_Notes/2.80/Python_API/Addons in Section Class Property Registration – Robert Gützkow Sep 08 '19 at 17:31
  • 2
    Ugh, don't declare properties in a panel class. – brockmann Sep 08 '19 at 17:41
  • 1
    Here you go: https://pastebin.com/yNKaF1V5 (used the template I suggested yesterday from here: https://blender.stackexchange.com/questions/57306/how-to-create-a-custom-ui/57332#57332) Note: Usually you want to use an ExportHelper in order to display the properties as part of the Export Dialog rather than using an extra panel. In this case you have to declare all properties within the operator class, see my example 2 days ago: https://blender.stackexchange.com/a/150922/31447 or have a look into Templates > Python > Operator File Export. – brockmann Sep 08 '19 at 18:15
  • 1
    Sorry, I'm not sure what you're pointing out to me? Is the point to not define properties inside of panel classes? I was just trying to keep the example code as simple as possible. I'm using PropertyGroup in my code, and adding/deleting the groups in register() and unregister(). – Robert Sep 08 '19 at 19:23
  • Yeah, just try to help :) Pointing you to a "correct" version I made out of your code, see the pastebin. And yes, bad example. Defining properties in a panel is no good... Also if you want to get rid of the warnings in the console (when running your code), use annotations :, correct version is: enum_variable : bpy.props.EnumProperty(... (notice: lower case variables). And the main question is: Why you want to display the properties in a panel somewhere? You can define your properties in the operator and display them as part of the File Dialog. @Robert – brockmann Sep 08 '19 at 19:57
  • I appreciate it. I'm less than a week old at this (python and Blender dev), so I'm stumbling all over the place. Your main question: I'm placing these in the panel because the user changes properties that relate to specific collections and objects. A collection can be tagged as "high poly", which (later) triggers that collection to export to a specific asset file with its own user options. If a mesh object inside of one of its child collections is a collision mesh object, it can be tagged as "not high poly" to have the exporter skip it. Hopefully that makes sense. Scene <-> batch export map – Robert Sep 08 '19 at 21:34
  • Absolutely. I changed the code for this case @Robert PointerProperty per Object: https://pastebin.com/ERv4P354 instead of registering per Scene. – brockmann Sep 08 '19 at 21:49
  • My current setup is almost exactly like this. One of the biggest differences I can notice is how you placed the enum flags in a function, where I defined mine directly inside the property group. Would using the function do something different? Or just two ways to do the same thing? Thanks again for your advice. Edit: Oops, actually mine are global. Maybe that is the point of the function? – Robert Sep 09 '19 at 00:41
  • You can use prop instead of a prop_enum per value: row.prop(self, "EnumVariable") – brita_ Sep 09 '20 at 20:01