1
$\begingroup$

I'm trying to create a PropertyGroup so that I can share my addon's properties between several different panels and operators. The below is the best I came up with based on the info I could find, but it's not working, but none of the properties I'm adding in my draw() method are displaying. How should I go about doing this?

import bpy
from bpy_extras import view3d_utils


class NormalToolSettings(bpy.types.PropertyGroup):
    brush_type : bpy.props.EnumProperty(
        items=(
            ('FIXED', "Fixed", "Normals are in a fixed direction"),
            ('ATTRACT', "Attract", "Normals point toward target object"),
            ('REPEL', "Repel", "Normals point away from target object")
        ),
        default='FIXED'
    )
    
    strength : bpy.props.FloatProperty(
        name="Strength", description="Amount to adjust mesh normal", default = 1, min=0, max = 1
    )

    normal : bpy.props.FloatVectorProperty(name="Normal", description="Direction of normal in Fixed mode", default = (0, 1, 0))
    target : bpy.props.StringProperty(name="Target", description="Object Attract and Repel mode reference", default="")
        

#---------------------------

class NormalToolPropsPanel(bpy.types.Panel):

    """Properties Panel for the Normal Tool on tool shelf"""
    bl_label = "Normal Tool Properties Panel"
    bl_idname = "3D_VIEW_PT_normal_tool_props"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
        

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

        settings = bpy.props.PointerProperty(type=NormalToolSettings)

        obj = context.object

        row = layout.row()
        row.prop(bpy.context.scene.my_tool.brush_type)

        row = layout.row()
        row.prop(bpy.context.scene.my_tool.strength)

        row = layout.row()
        row.prop(bpy.context.scene.my_tool.normal)

        row = layout.row()
        row.prop(bpy.context.scene.my_tool.target)

#---------------------------


def register():
    bpy.utils.register_class(NormalToolSettings)
    bpy.utils.register_class(NormalToolPropsPanel)

    bpy.types.Scene.my_tool = bpy.props.PointerProperty(type=NormalToolSettings)


def unregister():
    bpy.utils.unregister_class(NormalToolSettings)
    bpy.utils.unregister_class(NormalToolPropsPanel)
    


if __name__ == "__main__":
    register()


----Edit Was able to fix the code. Appending it here, since the question has been closed:

import bpy


class PG_NormalToolSettings(bpy.types.PropertyGroup):
    brush_type : bpy.props.EnumProperty(
        items=(
            ('FIXED', "Fixed", "Normals are in a fixed direction"),
            ('ATTRACT', "Attract", "Normals point toward target object"),
            ('REPEL', "Repel", "Normals point away from target object")
        ),
        default='FIXED'
    )
    
    strength : bpy.props.FloatProperty(
        name="Strength", description="Amount to adjust mesh normal", default = 1, min=0, max = 1
    )

    normal : bpy.props.FloatVectorProperty(name="Normal", description="Direction of normal in Fixed mode", default = (0, 1, 0))
    target : bpy.props.StringProperty(name="Target", description="Object Attract and Repel mode reference", default="")
        

#---------------------------

class PT_NormalToolPropsPanel(bpy.types.Panel):

    """Properties Panel for the Normal Tool on tool shelf"""
    bl_label = "Normal Tool Properties Panel"
    bl_idname = "3D_VIEW_PT_normal_tool_props"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'
        

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

#        settings = bpy.props.PointerProperty(type=PG_NormalToolSettings)

#        obj = context.object

        row = layout.row()
        row.prop(my_tool, "brush_type")

        row = layout.row()
        row.prop(my_tool, "strength")

        row = layout.row()
        row.prop(my_tool, "normal")

        row = layout.row()
        row.prop(my_tool, "target")

#---------------------------


def register():
    bpy.utils.register_class(PG_NormalToolSettings)
    bpy.utils.register_class(PT_NormalToolPropsPanel)

    bpy.types.Scene.my_tool = bpy.props.PointerProperty(type=PG_NormalToolSettings)


def unregister():
    bpy.utils.unregister_class(PG_NormalToolSettings)
    bpy.utils.unregister_class(PT_NormalToolPropsPanel)
    
    del bpy.types.Scene.my_tool
    


if __name__ == "__main__":
    register()

$\endgroup$
5
  • $\begingroup$ Always keep an eye on system console. blender.stackexchange.com/questions/6173/… Would say at error above is ModalDrawOperator.bl_idname since the operator class is not defined here. If the op is registered elsewhere use its bl_idname for example "kitfox.normal_tool" Will never wire up props in a draw method (only in rego) , in draw get an instance eg settings = context.scene.my_tool .. then layout.prop(settings, "normal") ... Feel this has been well covered see blender.stackexchange.com/questions/57306/… $\endgroup$
    – batFINGER
    Commented Jan 23, 2021 at 12:11
  • $\begingroup$ .. as with python'sgetattr(ob, property_name) the object is settings its attribute name is one of "brush_type", "normal", "target" $\endgroup$
    – batFINGER
    Commented Jan 23, 2021 at 12:16
  • $\begingroup$ I've deleted the line with ModalDrawOperator. Strangely, it did not report any error on my console. $\endgroup$
    – kitfox
    Commented Jan 23, 2021 at 12:19
  • $\begingroup$ Congrats on working it out, trust you see why it was closed. btw always check console for errors and warnings register_class(...): Warning: '3D_VIEW_PT_normal_tool_props' doesn't have upper case alpha-numeric prefix Do not start an id name with a number. Cannot have register to desired name eg if bl_idname = "3FOO_PT_bar" issue with bpy.types.3FOO_PT_bar $\endgroup$
    – batFINGER
    Commented Jan 23, 2021 at 12:59
  • $\begingroup$ I was wondering what that error meant. I had copied the 3D_VIEW_ from another script. Won't do that again. $\endgroup$
    – kitfox
    Commented Jan 23, 2021 at 13:28

0

Browse other questions tagged .