Bonsai - deprecate bpy.app.version checks

As we support only Blender 4.2+
This commit is contained in:
Andrej730
2025-01-22 12:55:16 +05:00
parent 74a9669fa8
commit f02fd69934
7 changed files with 60 additions and 108 deletions
@@ -379,11 +379,9 @@ class InspectFromObject(bpy.types.Operator):
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
if not context.active_object: if not context.active_object:
if bpy.app.version >= (3, 0, 0): cls.poll_message_set("No Active Object")
cls.poll_message_set("No Active Object")
elif not context.active_object.BIMObjectProperties.ifc_definition_id: elif not context.active_object.BIMObjectProperties.ifc_definition_id:
if bpy.app.version >= (3, 0, 0): cls.poll_message_set("Active Object doesn't have an IFC definition")
cls.poll_message_set("Active Object doesn't have an IFC definition")
else: else:
return True return True
@@ -142,7 +142,7 @@ class ShapeAspect(PropertyGroup):
"If applicable, shape aspect names should correlate with names of material constituents.\n" "If applicable, shape aspect names should correlate with names of material constituents.\n"
"Click to see autocompletion for constituent names." "Click to see autocompletion for constituent names."
), ),
**({} if bpy.app.version < (3, 3, 0) else {"search": get_material_constituents}), search=get_material_constituents,
) )
description: StringProperty( description: StringProperty(
name="Description", name="Description",
@@ -25,6 +25,7 @@ classes = (
operator.AppendLibraryElement, operator.AppendLibraryElement,
operator.AppendLibraryElementByQuery, operator.AppendLibraryElementByQuery,
operator.AssignLibraryDeclaration, operator.AssignLibraryDeclaration,
operator.BIM_FH_import_ifc,
operator.BIM_OT_load_clipping_planes, operator.BIM_OT_load_clipping_planes,
operator.BIM_OT_save_clipping_planes, operator.BIM_OT_save_clipping_planes,
operator.ChangeLibraryElement, operator.ChangeLibraryElement,
@@ -38,6 +39,7 @@ classes = (
operator.EnableEditingHeader, operator.EnableEditingHeader,
operator.ExportIFC, operator.ExportIFC,
operator.FlipClippingPlane, operator.FlipClippingPlane,
operator.IFCFileHandlerOperator,
operator.LinkIfc, operator.LinkIfc,
operator.LoadLink, operator.LoadLink,
operator.LoadLinkedProject, operator.LoadLinkedProject,
@@ -82,12 +84,6 @@ classes = (
gizmo.ClippingPlane, gizmo.ClippingPlane,
) )
if bpy.app.version >= (4, 1, 0):
classes += (
operator.IFCFileHandlerOperator,
operator.BIM_FH_import_ifc,
)
addon_keymaps = [] addon_keymaps = []
@@ -441,7 +441,7 @@ class AppendLibraryElement(bpy.types.Operator, tool.Ifc.Operator):
@classmethod @classmethod
def poll(cls, context): def poll(cls, context):
poll = bool(IfcStore.get_file()) poll = bool(IfcStore.get_file())
if bpy.app.version > (3, 0, 0) and not poll: if not poll:
cls.poll_message_set("Please create or load a project first.") cls.poll_message_set("Please create or load a project first.")
return poll return poll
@@ -2328,47 +2328,46 @@ class BIM_OT_load_clipping_planes(bpy.types.Operator):
return {"FINISHED"} return {"FINISHED"}
if bpy.app.version >= (4, 1, 0): class IFCFileHandlerOperator(bpy.types.Operator):
bl_idname = "bim.load_project_file_handler"
bl_label = "Import .ifc file"
bl_options = {"REGISTER", "UNDO", "INTERNAL"}
class IFCFileHandlerOperator(bpy.types.Operator): directory: bpy.props.StringProperty(subtype="FILE_PATH", options={"SKIP_SAVE", "HIDDEN"})
bl_idname = "bim.load_project_file_handler" files: bpy.props.CollectionProperty(type=bpy.types.OperatorFileListElement, options={"SKIP_SAVE", "HIDDEN"})
bl_label = "Import .ifc file"
bl_options = {"REGISTER", "UNDO", "INTERNAL"}
directory: bpy.props.StringProperty(subtype="FILE_PATH", options={"SKIP_SAVE", "HIDDEN"}) def invoke(self, context, event):
files: bpy.props.CollectionProperty(type=bpy.types.OperatorFileListElement, options={"SKIP_SAVE", "HIDDEN"}) # Keeping code in .invoke() as we'll probably add some
# popup windows later.
def invoke(self, context, event): # `files` contain only .ifc files.
# Keeping code in .invoke() as we'll probably add some filepath = Path(self.directory)
# popup windows later. # If user is just drag'n'dropping a single file -> load it as a new project,
# if they're holding ALT -> link the file/files to the current project.
# `files` contain only .ifc files. if event.alt:
filepath = Path(self.directory) # Passing self.files directly results in TypeError.
# If user is just drag'n'dropping a single file -> load it as a new project, serialized_files = [{"name": f.name} for f in self.files]
# if they're holding ALT -> link the file/files to the current project. return bpy.ops.bim.link_ifc(directory=self.directory, files=serialized_files)
if event.alt: else:
# Passing self.files directly results in TypeError. if len(self.files) == 1:
serialized_files = [{"name": f.name} for f in self.files] return bpy.ops.bim.load_project(filepath=(filepath / self.files[0].name).as_posix())
return bpy.ops.bim.link_ifc(directory=self.directory, files=serialized_files)
else: else:
if len(self.files) == 1: self.report(
return bpy.ops.bim.load_project(filepath=(filepath / self.files[0].name).as_posix()) {"INFO"},
else: "To link multiple IFC files hold ALT while drag'n'dropping them.",
self.report( )
{"INFO"}, return {"FINISHED"}
"To link multiple IFC files hold ALT while drag'n'dropping them.",
)
return {"FINISHED"}
class BIM_FH_import_ifc(bpy.types.FileHandler):
bl_label = "IFC File Handler"
bl_import_operator = IFCFileHandlerOperator.bl_idname
bl_file_extensions = ".ifc"
# FileHandler won't work without poll_drop defined. class BIM_FH_import_ifc(bpy.types.FileHandler):
@classmethod bl_label = "IFC File Handler"
def poll_drop(cls, context): bl_import_operator = IFCFileHandlerOperator.bl_idname
return True bl_file_extensions = ".ifc"
# FileHandler won't work without poll_drop defined.
@classmethod
def poll_drop(cls, context):
return True
class MeasureTool(bpy.types.Operator, PolylineOperator): class MeasureTool(bpy.types.Operator, PolylineOperator):
+8 -21
View File
@@ -493,21 +493,12 @@ class BIM_OT_add_section_plane(bpy.types.Operator):
def create_section_compare_node(self): def create_section_compare_node(self):
group = bpy.data.node_groups.new("Section Compare", type="ShaderNodeTree") group = bpy.data.node_groups.new("Section Compare", type="ShaderNodeTree")
if bpy.app.version >= (4, 0, 0): input_value = group.interface.new_socket(name="Value", in_out="INPUT", socket_type="NodeSocketFloat")
input_value = group.interface.new_socket(name="Value", in_out="INPUT", socket_type="NodeSocketFloat") input_value.default_value = 1.0 # Mandatory multiplier for the last node group
input_value.default_value = 1.0 # Mandatory multiplier for the last node group group.interface.new_socket(name="Vector", in_out="INPUT", socket_type="NodeSocketVector")
group.interface.new_socket(name="Vector", in_out="INPUT", socket_type="NodeSocketVector") group.interface.new_socket(name="Line Decorator", in_out="INPUT", socket_type="NodeSocketFloat")
group.interface.new_socket(name="Line Decorator", in_out="INPUT", socket_type="NodeSocketFloat") group.interface.new_socket(name="Value", in_out="OUTPUT", socket_type="NodeSocketFloat")
group.interface.new_socket(name="Value", in_out="OUTPUT", socket_type="NodeSocketFloat") group.interface.new_socket(name="Line Decorator", in_out="OUTPUT", socket_type="NodeSocketFloat")
group.interface.new_socket(name="Line Decorator", in_out="OUTPUT", socket_type="NodeSocketFloat")
else:
group.inputs.new("NodeSocketFloat", "Value")
# Mandatory multiplier for the last node group
group.inputs["Value"].default_value = 1.0
group.inputs.new("NodeSocketVector", "Vector")
group.inputs.new("NodeSocketFloat", "Line Decorator")
group.outputs.new("NodeSocketFloat", "Value")
group.outputs.new("NodeSocketFloat", "Line Decorator")
group_input = group.nodes.new(type="NodeGroupInput") group_input = group.nodes.new(type="NodeGroupInput")
group_input.location = 0, 50 group_input.location = 0, 50
@@ -556,12 +547,8 @@ class BIM_OT_add_section_plane(bpy.types.Operator):
def create_section_override_node(self, obj, context): def create_section_override_node(self, obj, context):
group = bpy.data.node_groups.new("Section Override", type="ShaderNodeTree") group = bpy.data.node_groups.new("Section Override", type="ShaderNodeTree")
if bpy.app.version >= (4, 0, 0): group.interface.new_socket(name="Shader", in_out="INPUT", socket_type="NodeSocketShader")
group.interface.new_socket(name="Shader", in_out="INPUT", socket_type="NodeSocketShader") group.interface.new_socket(name="Shader", in_out="OUTPUT", socket_type="NodeSocketShader")
group.interface.new_socket(name="Shader", in_out="OUTPUT", socket_type="NodeSocketShader")
else:
group.inputs.new("NodeSocketShader", "Shader")
group.outputs.new("NodeSocketShader", "Shader")
links = group.links links = group.links
nodes = group.nodes nodes = group.nodes
+5 -28
View File
@@ -54,7 +54,7 @@ OBJECT_DATA_TYPE = Union[bpy.types.Mesh, bpy.types.Curve, bpy.types.Camera]
class Blender(bonsai.core.tool.Blender): class Blender(bonsai.core.tool.Blender):
OBJECT_TYPES_THAT_SUPPORT_EDIT_MODE = ("MESH", "CURVE", "SURFACE", "META", "FONT", "LATTICE", "ARMATURE") OBJECT_TYPES_THAT_SUPPORT_EDIT_MODE = ("MESH", "CURVE", "SURFACE", "META", "FONT", "LATTICE", "ARMATURE")
OBJECT_TYPES_THAT_SUPPORT_EDIT_GPENCIL_MODE = ("GPENCIL",) OBJECT_TYPES_THAT_SUPPORT_EDIT_GPENCIL_MODE = ("GPENCIL",)
TYPE_MANAGER_ICON = "LIGHTPROBE_VOLUME" if bpy.app.version >= (4, 1, 0) else "LIGHTPROBE_GRID" TYPE_MANAGER_ICON = "LIGHTPROBE_VOLUME"
BLENDER_ENUM_ITEM = Union[tuple[str, str, str], tuple[str, str, str, str], tuple[str, str, str, str, str]] BLENDER_ENUM_ITEM = Union[tuple[str, str, str], tuple[str, str, str, str], tuple[str, str, str, str, str]]
""" """
@@ -331,16 +331,6 @@ class Blender(bonsai.core.tool.Blender):
@classmethod @classmethod
def copy_node_graph(cls, material_to: bpy.types.Material, material_from: bpy.types.Material) -> None: def copy_node_graph(cls, material_to: bpy.types.Material, material_from: bpy.types.Material) -> None:
# https://projects.blender.org/blender/blender/issues/108763
if bpy.app.version[:2] == (4, 0):
print(
"WARNING. Copying node graph is not supported on Blender 4.0.x due Blender bug, "
f"copying node graph from {material_from.name} to {material_to.name} will be skipped"
)
return
use_temp_override = bpy.app.version >= (4, 0, 0)
temp_override = cls.get_shader_editor_context() temp_override = cls.get_shader_editor_context()
shader_editor = temp_override["space"] shader_editor = temp_override["space"]
@@ -356,19 +346,13 @@ class Blender(bonsai.core.tool.Blender):
# select all nodes and copy them to clipboard # select all nodes and copy them to clipboard
for node in material_from.node_tree.nodes: for node in material_from.node_tree.nodes:
node.select = True node.select = True
if use_temp_override: with bpy.context.temp_override(**temp_override):
with bpy.context.temp_override(**temp_override): bpy.ops.node.clipboard_copy()
bpy.ops.node.clipboard_copy()
else:
bpy.ops.node.clipboard_copy(temp_override)
# back to original material # back to original material
shader_editor.node_tree = material_to.node_tree shader_editor.node_tree = material_to.node_tree
if use_temp_override: with bpy.context.temp_override(**temp_override):
with bpy.context.temp_override(**temp_override): bpy.ops.node.clipboard_paste(offset=(0, 0))
bpy.ops.node.clipboard_paste(offset=(0, 0))
else:
bpy.ops.node.clipboard_paste(temp_override, offset=(0, 0))
# restore shader editor settings # restore shader editor settings
shader_editor.pin = previous_pin_setting shader_editor.pin = previous_pin_setting
@@ -1359,13 +1343,6 @@ class Blender(bonsai.core.tool.Blender):
if sun_position: if sun_position:
return sun_position return sun_position
# No extensions prior to 4.2.
if bpy.app.version < (4, 2, 0):
return sun_position
if sun_position:
return sun_position
for package_name in bpy.context.preferences.addons.keys(): for package_name in bpy.context.preferences.addons.keys():
if package_name.endswith(".sun_position"): if package_name.endswith(".sun_position"):
try: try:
+7 -12
View File
@@ -117,18 +117,13 @@ class Web(bonsai.core.tool.Web):
py_version = sys.version_info py_version = sys.version_info
if bpy.app.version >= (4, 2, 0): bonsai_lib_path = (
bonsai_lib_path = ( Path(bpy.utils.user_resource("EXTENSIONS"))
Path(bpy.utils.user_resource("EXTENSIONS")) / ".local"
/ ".local" / "lib"
/ "lib" / f"python{py_version.major}.{py_version.minor}"
/ f"python{py_version.major}.{py_version.minor}" / "site-packages"
/ "site-packages" )
)
else:
addon = [a for a in addon_utils.modules() if a.bl_info["name"] == "Bonsai"][0]
bonsai_path = os.path.dirname(addon.__file__)
bonsai_lib_path = os.path.join(bonsai_path, "libs", "site", "packages")
env = os.environ.copy() env = os.environ.copy()
env["BONSAI_LIB_PATH"] = str(bonsai_lib_path) env["BONSAI_LIB_PATH"] = str(bonsai_lib_path)