From f02fd69934d377346e8a68bafbbda7aa0da9da90 Mon Sep 17 00:00:00 2001 From: Andrej730 Date: Wed, 22 Jan 2025 12:55:16 +0500 Subject: [PATCH] Bonsai - deprecate bpy.app.version checks As we support only Blender 4.2+ --- .../bonsai/bim/module/debug/operator.py | 6 +- src/bonsai/bonsai/bim/module/geometry/prop.py | 2 +- .../bonsai/bim/module/project/__init__.py | 8 +-- .../bonsai/bim/module/project/operator.py | 71 +++++++++---------- src/bonsai/bonsai/bim/operator.py | 29 +++----- src/bonsai/bonsai/tool/blender.py | 33 ++------- src/bonsai/bonsai/tool/web.py | 19 ++--- 7 files changed, 60 insertions(+), 108 deletions(-) diff --git a/src/bonsai/bonsai/bim/module/debug/operator.py b/src/bonsai/bonsai/bim/module/debug/operator.py index b75fb007cb..501b8dd987 100644 --- a/src/bonsai/bonsai/bim/module/debug/operator.py +++ b/src/bonsai/bonsai/bim/module/debug/operator.py @@ -379,11 +379,9 @@ class InspectFromObject(bpy.types.Operator): @classmethod def poll(cls, context): 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: - 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: return True diff --git a/src/bonsai/bonsai/bim/module/geometry/prop.py b/src/bonsai/bonsai/bim/module/geometry/prop.py index 8130e11565..8792585822 100644 --- a/src/bonsai/bonsai/bim/module/geometry/prop.py +++ b/src/bonsai/bonsai/bim/module/geometry/prop.py @@ -142,7 +142,7 @@ class ShapeAspect(PropertyGroup): "If applicable, shape aspect names should correlate with names of material constituents.\n" "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( name="Description", diff --git a/src/bonsai/bonsai/bim/module/project/__init__.py b/src/bonsai/bonsai/bim/module/project/__init__.py index 6d0eb432f9..051769336f 100644 --- a/src/bonsai/bonsai/bim/module/project/__init__.py +++ b/src/bonsai/bonsai/bim/module/project/__init__.py @@ -25,6 +25,7 @@ classes = ( operator.AppendLibraryElement, operator.AppendLibraryElementByQuery, operator.AssignLibraryDeclaration, + operator.BIM_FH_import_ifc, operator.BIM_OT_load_clipping_planes, operator.BIM_OT_save_clipping_planes, operator.ChangeLibraryElement, @@ -38,6 +39,7 @@ classes = ( operator.EnableEditingHeader, operator.ExportIFC, operator.FlipClippingPlane, + operator.IFCFileHandlerOperator, operator.LinkIfc, operator.LoadLink, operator.LoadLinkedProject, @@ -82,12 +84,6 @@ classes = ( gizmo.ClippingPlane, ) -if bpy.app.version >= (4, 1, 0): - classes += ( - operator.IFCFileHandlerOperator, - operator.BIM_FH_import_ifc, - ) - addon_keymaps = [] diff --git a/src/bonsai/bonsai/bim/module/project/operator.py b/src/bonsai/bonsai/bim/module/project/operator.py index 85d94a4941..fd2e9cf435 100644 --- a/src/bonsai/bonsai/bim/module/project/operator.py +++ b/src/bonsai/bonsai/bim/module/project/operator.py @@ -441,7 +441,7 @@ class AppendLibraryElement(bpy.types.Operator, tool.Ifc.Operator): @classmethod def poll(cls, context): 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.") return poll @@ -2328,47 +2328,46 @@ class BIM_OT_load_clipping_planes(bpy.types.Operator): 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): - bl_idname = "bim.load_project_file_handler" - bl_label = "Import .ifc file" - bl_options = {"REGISTER", "UNDO", "INTERNAL"} + directory: bpy.props.StringProperty(subtype="FILE_PATH", options={"SKIP_SAVE", "HIDDEN"}) + files: bpy.props.CollectionProperty(type=bpy.types.OperatorFileListElement, options={"SKIP_SAVE", "HIDDEN"}) - directory: bpy.props.StringProperty(subtype="FILE_PATH", options={"SKIP_SAVE", "HIDDEN"}) - files: bpy.props.CollectionProperty(type=bpy.types.OperatorFileListElement, options={"SKIP_SAVE", "HIDDEN"}) + def invoke(self, context, event): + # Keeping code in .invoke() as we'll probably add some + # popup windows later. - def invoke(self, context, event): - # Keeping code in .invoke() as we'll probably add some - # popup windows later. - - # `files` contain only .ifc files. - filepath = Path(self.directory) - # 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. - if event.alt: - # Passing self.files directly results in TypeError. - serialized_files = [{"name": f.name} for f in self.files] - return bpy.ops.bim.link_ifc(directory=self.directory, files=serialized_files) + # `files` contain only .ifc files. + filepath = Path(self.directory) + # 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. + if event.alt: + # Passing self.files directly results in TypeError. + serialized_files = [{"name": f.name} for f in self.files] + return bpy.ops.bim.link_ifc(directory=self.directory, files=serialized_files) + else: + if len(self.files) == 1: + return bpy.ops.bim.load_project(filepath=(filepath / self.files[0].name).as_posix()) else: - if len(self.files) == 1: - return bpy.ops.bim.load_project(filepath=(filepath / self.files[0].name).as_posix()) - else: - self.report( - {"INFO"}, - "To link multiple IFC files hold ALT while drag'n'dropping them.", - ) - return {"FINISHED"} + self.report( + {"INFO"}, + "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. - @classmethod - def poll_drop(cls, context): - return True +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. + @classmethod + def poll_drop(cls, context): + return True class MeasureTool(bpy.types.Operator, PolylineOperator): diff --git a/src/bonsai/bonsai/bim/operator.py b/src/bonsai/bonsai/bim/operator.py index 12b3c29ed8..af050803ac 100644 --- a/src/bonsai/bonsai/bim/operator.py +++ b/src/bonsai/bonsai/bim/operator.py @@ -493,21 +493,12 @@ class BIM_OT_add_section_plane(bpy.types.Operator): def create_section_compare_node(self): 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.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="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="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") + 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 + 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="Value", in_out="OUTPUT", socket_type="NodeSocketFloat") + group.interface.new_socket(name="Line Decorator", in_out="OUTPUT", socket_type="NodeSocketFloat") group_input = group.nodes.new(type="NodeGroupInput") 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): 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="OUTPUT", socket_type="NodeSocketShader") - else: - group.inputs.new("NodeSocketShader", "Shader") - group.outputs.new("NodeSocketShader", "Shader") + group.interface.new_socket(name="Shader", in_out="INPUT", socket_type="NodeSocketShader") + group.interface.new_socket(name="Shader", in_out="OUTPUT", socket_type="NodeSocketShader") links = group.links nodes = group.nodes diff --git a/src/bonsai/bonsai/tool/blender.py b/src/bonsai/bonsai/tool/blender.py index 3dfeacd1be..bd2d5c01e7 100644 --- a/src/bonsai/bonsai/tool/blender.py +++ b/src/bonsai/bonsai/tool/blender.py @@ -54,7 +54,7 @@ OBJECT_DATA_TYPE = Union[bpy.types.Mesh, bpy.types.Curve, bpy.types.Camera] class Blender(bonsai.core.tool.Blender): OBJECT_TYPES_THAT_SUPPORT_EDIT_MODE = ("MESH", "CURVE", "SURFACE", "META", "FONT", "LATTICE", "ARMATURE") 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]] """ @@ -331,16 +331,6 @@ class Blender(bonsai.core.tool.Blender): @classmethod 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() shader_editor = temp_override["space"] @@ -356,19 +346,13 @@ class Blender(bonsai.core.tool.Blender): # select all nodes and copy them to clipboard for node in material_from.node_tree.nodes: node.select = True - if use_temp_override: - with bpy.context.temp_override(**temp_override): - bpy.ops.node.clipboard_copy() - else: - bpy.ops.node.clipboard_copy(temp_override) + with bpy.context.temp_override(**temp_override): + bpy.ops.node.clipboard_copy() # back to original material shader_editor.node_tree = material_to.node_tree - if use_temp_override: - with bpy.context.temp_override(**temp_override): - bpy.ops.node.clipboard_paste(offset=(0, 0)) - else: - bpy.ops.node.clipboard_paste(temp_override, offset=(0, 0)) + with bpy.context.temp_override(**temp_override): + bpy.ops.node.clipboard_paste(offset=(0, 0)) # restore shader editor settings shader_editor.pin = previous_pin_setting @@ -1359,13 +1343,6 @@ class Blender(bonsai.core.tool.Blender): if 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(): if package_name.endswith(".sun_position"): try: diff --git a/src/bonsai/bonsai/tool/web.py b/src/bonsai/bonsai/tool/web.py index 03fcd98d2b..13f5ff7897 100644 --- a/src/bonsai/bonsai/tool/web.py +++ b/src/bonsai/bonsai/tool/web.py @@ -117,18 +117,13 @@ class Web(bonsai.core.tool.Web): py_version = sys.version_info - if bpy.app.version >= (4, 2, 0): - bonsai_lib_path = ( - Path(bpy.utils.user_resource("EXTENSIONS")) - / ".local" - / "lib" - / f"python{py_version.major}.{py_version.minor}" - / "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") + bonsai_lib_path = ( + Path(bpy.utils.user_resource("EXTENSIONS")) + / ".local" + / "lib" + / f"python{py_version.major}.{py_version.minor}" + / "site-packages" + ) env = os.environ.copy() env["BONSAI_LIB_PATH"] = str(bonsai_lib_path)