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.
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
Got rid of the
def draw
function in the operator which gives me nothing... Why is that? Typically with thebl_options = {'REGISTER', 'UNDO'}
I should get the properties in a small side panel.When I add
def draw
withtool = 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.
tools = context.scene.tools
Could you please add the code to define and register scene tools propertygroup. $\endgroup$draw function
to my operator class. Referencing the props bytool = context.scene.tools
the UNDO options shows everything correctly, but I just figured out it's not exactly frozen but a copy of themain_panel class
I can change the variables in the main side panel and it changes the 'UNDO' panel on the bottom left... $\endgroup$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$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$