4
$\begingroup$

I have an add-on split into multiple files.

Here is my file structure:

blueprint
    │   main_operator.py
    │   main_panel.py
    │   main_properties.py
    │   __init__.py
    │
    ├───buildings
    │       Apartment.py
    │       grid_build.py
    │       Office.py
    │       Skyscrappers.py
    │       small_shops.py
    │
    └───tools
            blender_tools.py

In my main_operator.py file I have this option in the class enabled: bl_options = {'REGISTER', 'UNDO'} Although when I run the add-on, all works but I get no 'Undo Panel' on the bottom left hand side once the add-on is run.

Typically in a simple file I would have the props variables defined inside the operator class.

bpy.props.BoolProperty()
bpy.props.FloatProperty()
bpy.props.IntProperty()
bpy.props.PointerProperty()
bpy.props.StringProperty()

All inside the Operator Class.

But in my complex file system I have successfully split them into a main_properties.py and main_operator.py

Here is my __init__.py:

bl_info = {
    "name": "Blueprint",
    "author": "Davi Silveira <[email protected]>",
    "version": (1, 0, 8),
    "blender": (2, 90, 1),
    "category": "Add Mesh",
    "location": "VIEW3D > BLueprint > UI",
    "description": "We Built This City",
    "warning": "Still under development",
    "doc_url": "",
    "tracker_url": "",
}

import bpy

from . main_operator import VIEW3D_OT_Blueprint
from . main_panel import OBJECT_PT_Blueprint
from . main_properties import Blueprint_Properties

classes = (
    OBJECT_PT_Blueprint,
    VIEW3D_OT_Blueprint,
    Blueprint_Properties,
    )

#### -----------------------------------------
#### Register Classes
def register():
    for cls in classes:
        bpy.utils.register_class(cls)
    bpy.types.Scene.tools = bpy.props.PointerProperty(type=Blueprint_Properties)

def unregister():
    for cls in classes:
        bpy.utils.unregister_class(cls)
    del bpy.types.Scene.tools
#### -----------------------------------------

I link in my main_panel.py to my Properties in my main_properties.py file by using: scene = context.scene.tools It all works as it should I guess. But in my main_operator.py file this scene = context.scene.tools does not work. All variables are frozen... They only change when I change the main add-on panel, the UNDO panel in the bottom will not change, only mirrors the main one. enter image description here

Here is my '''main_operator```:

import bpy

from .tools.blender_tools import move_it, re_size, hide, de_select, dimension
from .buildings.grid_build import grid
from . main_properties import Blueprint_Properties

class VIEW3D_OT_Blueprint(bpy.types.Operator):
    """Blueprint we built this city"""
    bl_label    = "Building Options".upper()
    bl_idname   = "mesh.blueprint"
    bl_category = "View"
    bl_context  = "objectmode"
    bl_options  = {'REGISTER', 'UNDO'}

    ####--Execute
    ####------------------------------------------------------
    def execute(self, context):
        ####--Pre Start
        de_select(True, 'OBJECT') # Select All Objs
        hide(True)
        # deactivate others
        for obj in bpy.data.objects:
            if obj.select_get() is True:
                obj.select_set(False)

        current_coll = bpy.context.collection # list of all collections
        new_coll = bpy.data.collections.new('Buildings') # new collection
        bpy.context.scene.collection.children.link(new_coll) # show in OUTLINER
        ####-----------------------------------------------------

        ####--Call Functions to Run Script
        scene = bpy.context.scene
        tool  = scene.tools
        
        # bpy.context.scene.tool_settings.use_snap = True
        grid(tool.x_location, tool.y_location, current_coll, new_coll)
        ####-----------------------------------------------------
        
        return {'FINISHED'}
    
    #def draw(self, context):
        #layout = self.layout
        #scene = context.scene.tools

        #row = layout.row()
        #box = row.box()

        #box.label(text='The Grid Blueprint', icon='LIGHTPROBE_GRID')
        
        #layout.separator()

        #col = layout.column(align=True)
        #box = col.box()
        #box.prop(scene, "density", icon='GROUP_VERTEX')
        
        #box.label(text='Location Options')
        #box.prop(scene, "random_placement", icon='SNAP_GRID')
        #box.prop(scene, "rotation_variation", icon='DRIVER_ROTATIONAL_DIFFERENCE')
        
        #col = layout.column(align=True)  
        #col.label(text='Grid Properties', icon='SNAP_GRID')
        #col.prop(scene, "x_location", icon='AXIS_SIDE')
        #col.prop(scene, "y_location", icon='AXIS_FRONT')

        #col = layout.column()
        #box = col.box()
        #box.prop(scene, "random_memory", icon='MEMORY')

Here is my main_properties.py:

import bpy

from bpy.props import IntProperty, StringProperty, BoolProperty, FloatProperty

class Blueprint_Properties(bpy.types.PropertyGroup):
    density: IntProperty(
        name = "City Density",
        description = "How far apart building are to each other",
        default = 45,
        min = 1,
        max = 100
    )

####---------------------------------------------------
####---Buildings
    apartment_building: BoolProperty(
        name = "Apartment Buildings",
        description = "Variety of Apartment Complexes",
        default = True
    )

    office_building: BoolProperty(
        name = "Office Buildings",
        description = "Variety of Office Buildings",
        default = False
    )
    
    skyscraper_building: BoolProperty(
        name = "Skyscraper Buildings",
        description = "Variety of Skyscrapers",
        default = False
    ) 
####---------------------------------------------------

####---------------------------------------------------
####---Buildings Floors
    apartment_floors: IntProperty(
        name = "Maximum Floors",
        description = "How many floors per Apartment",
        default = 14,
        min = 3,
        max = 100
    )

    office_floors: IntProperty(
        name = "Maximum Floors",
        description = "How many floors per Office Building",
        default = 25,
        min = 5,
        max = 100
    )

    skyscraper_floors: IntProperty(
        name = "Maximum Floors",
        description = "How many floors per Skyscraper",
        default = 53,
        min = 30,
        max = 100
    )
####---------------------------------------------------

    random_placement: BoolProperty(
        name = "Random Placement",
        description = "Randomize whether a building will be placed",
        default = False
    )

    rotation_variation: BoolProperty(
        name = "Rotation Variation",
        description = "Allow variation in the rotation of objects",
        default = True
    )

    x_location: IntProperty(
        name= "X Location",
        description="Number of buildings to build in X axis",
        default=4, min=1, soft_max=10, max=20
    )

    y_location: IntProperty(
        name= "Y Location",
        description="Number of buildings to build in X axis",
        default=4, min=1, soft_max=10, max=20
    )

    random_memory: IntProperty(
        name = "Random Memory",
        description = "Random Versions",
        default = 1,
        min = 1,
        max = 100
    )

THINGS I'VE TRIED

  1. Got rid of the def draw function in the operator which gives me nothing... Why is that? Typically with the bl_options = {'REGISTER', 'UNDO'} I should get the properties in a small side panel.

  2. When I add def draw with tool = context.scene.tools I can see everything in the UNDO but nothing works. All variables are frozen... anytime I try changing anything in the console it runs the script but nothing changes. ** What I do to the main panel shows up in the 'UNDO' Panel in the bottom of the screen like a mirror.

$\endgroup$
7
  • $\begingroup$ going to be far less confusing if you use tools = context.scene.tools Could you please add the code to define and register scene tools propertygroup. $\endgroup$
    – batFINGER
    Commented Feb 3, 2021 at 19:39
  • $\begingroup$ Sure, thing. Thanks Adding it now $\endgroup$ Commented Feb 3, 2021 at 20:58
  • $\begingroup$ I just found out that when I add a draw function to my operator class. Referencing the props by tool = context.scene.tools the UNDO options shows everything correctly, but I just figured out it's not exactly frozen but a copy of the main_panel class I can change the variables in the main side panel and it changes the 'UNDO' panel on the bottom left... $\endgroup$ Commented Feb 3, 2021 at 21:14
  • $\begingroup$ You need to register your property group and then refer to it by the name(space) you've registered it under. This line looks wrong to me: box.prop(Blueprint_Properties, "density", icon='GROUP_VERTEX'). Blender should already give you a hint at the source of the issue. Check the console/terminal for error messages (Linux, macOS - start Blender from a terminal; Window - Use Window > Toggle System Console). $\endgroup$ Commented Feb 3, 2021 at 22:00
  • $\begingroup$ Robert G. Thanks, that line was totally wrong... it should of been scene but you know when I fix that I get a duplicate of the main_panel on the 'UNDO' panel in the bottom left. It's frozen and only changes when I change the main Panel add-on. Like it's linked to it... I've been using the terminal this whole time, the "toggle_system_console" from Blender. I'll try starting Blender from the Terminal but I really don't know what it will tell me. Thanks again $\endgroup$ Commented Feb 4, 2021 at 0:58

1 Answer 1

3
$\begingroup$

I figured it out,

I needed to add all of the Properties I used in my main_properties.py file into my Operator. Then reference those as self instead of using the scene = bpy.context.scene; tool = scene.tools. I was referencing tool which was routing back to my side panel addon Properties Attributes. It should look like this.

class VIEW3D_OT_Blueprint(bpy.types.Operator):
    """Blueprint we built this city"""
    bl_label    = "Building Options".upper()
    bl_idname   = "mesh.blueprint"
    bl_category = "View"
    bl_context  = "objectmode"
    bl_options  = {'REGISTER', 'UNDO'}
    
    ####---------------------------------------------------
    ####---
    Buildings
    apartment_building: BoolProperty(
        name = "Apartment Buildings",
        description = "Variety of Apartment Complexes",
        default = True
    )

    office_building: BoolProperty(
        name = "Office Buildings",
        description = "Variety of Office Buildings",
        default = False
    )
    
    skyscraper_building: BoolProperty(
        name = "Skyscraper Buildings",
        description = "Variety of Skyscrapers",
        default = False
    ) 
    ####---------------------------------------------------
    ####--Execute
    ####------------------------------------------------------
    def execute(self, context):
        ####code###

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

        col = layout.column()
        col.prop(self, "apartment_building")
```
$\endgroup$

You must log in to answer this question.

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