0
$\begingroup$

How to make changes in the last action menu affect the operation with properties passed in, like if I change them in the MainPanel menu before the Operator execution? I want to make PropertyGroup could be changed after any blender operation (extrusion, bevelling, etc. - after accepting these operations user can change their props)

For a better understanding of what I'd like to do watch these 2 gifs:

Example. Action still can be modified after it's accepted.

My problem: action cannot be modified. Even properties stay still and when I try to change them, they return back to their previous values.

import bpy
from bpy.types import Operator, Panel, Mesh, PropertyGroup
from bpy.props import *


class FBGenProperties(PropertyGroup):
    def update_root_subdiv(self, context):
        pass

    def update_bone_length(self, context):
        pass

    root_subdiv : IntProperty(
        name = "Chains Amount",
        description = "Amount of bone chains",
        default = 3, min = 1, max = 100,
        soft_min = 3, soft_max = 20,
        subtype = "FACTOR",
        update = update_root_subdiv
    )

    bone_length : FloatProperty(
        name = "Segments Length",
        description = "Length of each segment in chain",
        default = .1, min = 0.001, max = 100,
        subtype = "DISTANCE",
        update = update_bone_length
    )


# object.fabric_bones_gen(root_subdiv = 10, bone_length = .1)
class FabricBonesGen(Operator):
    """Tooltip"""
    bl_idname = "object.fabric_bones_gen"
    bl_label = "Generate Fabric Bones"
    bl_options = { 'REGISTER', 'UNDO' }

    root_subdiv : IntProperty()
    bone_length : FloatProperty()

    def execute(self, context) -> set:
        self.obj = context.active_object
        self.selected = self.obj.select_get() if self.obj is not None else False
        props = self.obj.FB_gen_props
        self.root_subdiv = props.root_subdiv
        self.bone_length = props.bone_length

        bpy.ops.mesh.primitive_cylinder_add(
            radius = self.root_subdiv,
            depth = self.bone_length,
            location = (0, 0, 0),
            rotation = (0, 0, 0)
        )

        return {'FINISHED'}


class MainPanel(Panel):
    bl_label = "Fabric Bones"
    bl_space_type = "VIEW_3D"
    bl_region_type = "UI"
    bl_category = "FB"

    def draw(self, context):
        layout = self.layout
        obj = context.active_object
        selected = obj.select_get() if obj!= None else False
        name = obj.name if selected else ""

        layout.label(text="Active is: " + name)

        if name != "":
            props = obj.FB_gen_props
            col = layout.column()
            col.prop(props, 'root_subdiv')
            col.prop(props, 'bone_length')

            layout.operator(operator = "object.fabric_bones_gen", text = "Generate Bones")
        # TODO: Other op
        # layout.operator(operator = "object.fabric_bones_gen", text = "Setup Constraints")


classes = (
    FBGenProperties,
    FabricBonesGen,
    MainPanel,
)


def register():
    for cls in classes:
        bpy.utils.register_class(cls)
    bpy.types.Object.FB_gen_props = PointerProperty(type=FBGenProperties)


def unregister():
    for cls in reversed(classes):
        bpy.utils.unregister_class(cls)


if __name__ == "__main__":
    register()
$\endgroup$
3
  • $\begingroup$ Hey, the question is very confusing. please write the code as one script instead of multiple sections and then explain what your goal is based on your code. $\endgroup$
    – Karan
    Commented Jul 30, 2023 at 18:12
  • $\begingroup$ what is the last action menu? $\endgroup$
    – Karan
    Commented Jul 30, 2023 at 18:13
  • $\begingroup$ @Karan hello there! Thank you for paying attention to my problem! I've updated the code and added few GIFs to make my question be clear) $\endgroup$
    – Void
    Commented Jul 31, 2023 at 7:08

1 Answer 1

1
$\begingroup$
import bpy
from bpy.types import Operator, Panel, Mesh, PropertyGroup
from bpy.props import *


class FB_PG_properties(PropertyGroup):

    root_subdiv : IntProperty(
        name = "Chains Amount",
        description = "Amount of bone chains",
        subtype = "FACTOR",
        min = 1, soft_min = 3, soft_max = 20, max = 100,
        default = 3,
    )

    bone_length : FloatProperty(
        name = "Segments Length",
        description = "Length of each segment in chain",
        subtype = "DISTANCE",
        min = 0.001, max = 100,
        default = 0.1,
    )


# object.fabric_bones_gen(root_subdiv = 10, bone_length = .1)
class FB_OT_fabric_bones_gen(Operator):
    """Tooltip"""
    bl_idname = "object.fabric_bones_gen"
    bl_label = "Generate Fabric Bones"
    bl_options = { 'REGISTER', 'UNDO' }

    root_subdiv : IntProperty(
        default = bpy.context.object.FB_gen_props.root_subdiv
    )

    bone_length : FloatProperty(
        default = bpy.context.object.FB_gen_props.bone_length
    )

    def execute(self, context):

        bpy.ops.mesh.primitive_cylinder_add(
            radius = self.root_subdiv,
            depth = self.bone_length,
            location = (0, 0, 0),
            rotation = (0, 0, 0)
        )

        return {'FINISHED'}


class FB_PT_main_panel(Panel):
    bl_label = "Fabric Bones"
    bl_space_type = "VIEW_3D"
    bl_region_type = "UI"
    bl_category = "FB"

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

        name = context.active_object.name if context.active_object else ""
        layout.label(text=f"Active is: {name}")

        if context.object:
            props = context.object.FB_gen_props

            col = layout.column()
            col.prop(props, 'root_subdiv')
            col.prop(props, 'bone_length')

            layout.operator("object.fabric_bones_gen", text="Generate Bones")
        # TODO: Other op
        # layout.operator("object.fabric_bones_gen", text="Setup Constraints")


classes = (
    FB_PG_properties,
    FB_OT_fabric_bones_gen,
    FB_PT_main_panel,
)


def register():
    for cls in classes:
        bpy.utils.register_class(cls)

    bpy.types.Object.FB_gen_props = PointerProperty(type=FB_PG_properties)


def unregister():
    for cls in reversed(classes):
        bpy.utils.unregister_class(cls)


if __name__ == "__main__":
    register()
$\endgroup$
1
  • $\begingroup$ Thank you so much, you solved my problem and did pretty good code review <3 Can you recommend any bpy wiki or smth? Cause official doc is pretty poor in examples and youtube guides level is not enough for understanding $\endgroup$
    – Void
    Commented Jul 31, 2023 at 10:51

You must log in to answer this question.

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