Blender 5.0 - avoid using deprecated use_nodes

This commit is contained in:
Andrej730
2025-11-04 14:23:55 +05:00
parent 3bdfbebc02
commit d2126e5929
12 changed files with 58 additions and 30 deletions
@@ -455,7 +455,7 @@ class ActivateExternalStyle(bpy.types.Operator):
return {"CANCELLED"}
self.copy_material_attributes(db["data_block"], material)
if material.use_nodes:
if tool.Style.get_use_nodes(material):
tool.Blender.copy_node_graph(material, db["data_block"])
bpy.data.materials.remove(db["data_block"])
return {"FINISHED"}
+2 -2
View File
@@ -786,7 +786,7 @@ class BIM_OT_add_section_plane(bpy.types.Operator):
material = bpy.data.materials.get("Section Override")
if not material:
material = bpy.data.materials.new("Section Override")
material.use_nodes = True
tool.Style.set_use_nodes(material, True)
props = tool.Blender.get_bim_props()
if props.should_section_selected_objects:
@@ -809,7 +809,7 @@ class BIM_OT_add_section_plane(bpy.types.Operator):
def override_materials(self):
override = bpy.data.node_groups.get("Section Override")
for material in bpy.data.materials:
material.use_nodes = True
tool.Style.set_use_nodes(material, True)
if material.node_tree.nodes.get("Section Override"):
continue
# In EEVEE rendering engine, `blend_mode` is deprecated and replaced by `surface_render_method`
+2 -1
View File
@@ -100,6 +100,7 @@ class Blender(bonsai.core.tool.Blender):
- (identifier, name, description, icon, number)
"""
BLENDER_ENUM_ITEMS = Iterable[BLENDER_ENUM_ITEM]
BLENDER_5 = bpy.app.version >= (5, 0, 0)
@classmethod
def activate_camera(cls, obj: bpy.types.Object) -> None:
@@ -416,7 +417,7 @@ class Blender(bonsai.core.tool.Blender):
cls, blender_material: bpy.types.Material, node_type: str, kwargs: Optional[dict] = {}
) -> Union[bpy.types.ShaderNode, None]:
"""returns first node from the `blender_material` shader graph with type `node_type`"""
if not blender_material.use_nodes:
if not tool.Style.get_use_nodes(blender_material):
return
nodes = blender_material.node_tree.nodes
for node in nodes:
+2 -2
View File
@@ -1262,7 +1262,7 @@ class Geometry(bonsai.core.tool.Geometry):
if tool.Ifc.get().schema == "IFC2X3":
return False
for slot in obj.material_slots:
if slot.material and slot.material.use_nodes:
if slot.material and tool.Style.get_use_nodes(slot.material):
for node in slot.material.node_tree.nodes:
if node.type == "TEX_COORD" and node.outputs["UV"].links:
return True
@@ -2021,7 +2021,7 @@ class Geometry(bonsai.core.tool.Geometry):
continue
if not (style := tool.Ifc.get_entity(material)):
style = ifcopenshell.api.style.add_style(ifc_file, name=material.name)
if material.use_nodes:
if tool.Style.get_use_nodes(material):
ifc_class = "IfcSurfaceStyleRendering"
attributes = tool.Style.get_surface_rendering_attributes(material)
else:
+3 -3
View File
@@ -116,7 +116,7 @@ class Loader(bonsai.core.tool.Loader):
if transparency := surface_style.get("Transparency", None):
alpha = 1 - transparency
blender_material.diffuse_color = surface_style["SurfaceColour"] + (alpha,)
blender_material.use_nodes = False
tool.Style.set_use_nodes(blender_material, False)
@classmethod
def restart_material_node_tree(cls, blender_material: bpy.types.Material) -> None:
@@ -204,7 +204,7 @@ class Loader(bonsai.core.tool.Loader):
# TODO: reset pins to default values if no values passed
if reflectance_method in ["PHYSICAL", "NOTDEFINED"]:
blender_material.use_nodes = True
tool.Style.set_use_nodes(blender_material, True)
cls.restart_material_node_tree(blender_material)
bsdf = tool.Blender.get_material_node(blender_material, "BSDF_PRINCIPLED")
assert bsdf
@@ -231,7 +231,7 @@ class Loader(bonsai.core.tool.Loader):
blender_material.blend_method = "BLEND"
elif reflectance_method == "FLAT":
blender_material.use_nodes = True
tool.Style.set_use_nodes(blender_material, True)
cls.restart_material_node_tree(blender_material)
output = tool.Blender.get_material_node(blender_material, "OUTPUT_MATERIAL")
+1 -1
View File
@@ -1020,7 +1020,7 @@ class Sequence(bonsai.core.tool.Sequence):
def set_material(name, r, g, b):
material = bpy.data.materials.new(name)
material.use_nodes = True
tool.Style.set_use_nodes(material, True)
tool.Blender.get_material_node(material, "BSDF_PRINCIPLED").inputs[0].default_value = (r, g, b, 1.0)
return material
+15 -1
View File
@@ -63,9 +63,23 @@ class Style(bonsai.core.tool.Style):
def get_material_style_props(cls, material: bpy.types.Material) -> BIMStyleProperties:
return material.BIMStyleProperties
@classmethod
def get_use_nodes(cls, obj: bpy.types.Material) -> bool:
"""Since Blender 5.0 ``use_nodes`` are always ``True`` and considered deprecated."""
if tool.Blender.BLENDER_5:
return True
return obj.use_nodes
@classmethod
def set_use_nodes(cls, obj: bpy.types.Material, use_nodes: bool) -> None:
"""Since Blender 5.0 ``use_nodes`` are always ``True`` and considered deprecated."""
if tool.Blender.BLENDER_5:
return
obj.use_nodes = use_nodes
@classmethod
def can_support_rendering_style(cls, obj: bpy.types.Material) -> bool:
return obj.use_nodes and hasattr(obj.node_tree, "nodes")
return tool.Blender.BLENDER_5 or (obj.use_nodes and hasattr(obj.node_tree, "nodes"))
@classmethod
def delete_object(cls, obj: bpy.types.Material) -> None:
@@ -89,10 +89,17 @@ class SectionCutawayManager:
SectionCutawayManager.offset_previous_nodes(previous_section_compare, offset_x, offset_y)
@staticmethod
def override_materials():
def set_use_nodes(obj: bpy.types.Material, use_nodes: bool) -> None:
if bpy.app.version >= (5, 0, 0):
# Since Blender 5.0 `use_nodes` are always `True` and considered deprecated.
return
obj.use_nodes = use_nodes
@classmethod
def override_materials(cls):
override = SectionCutawayManager.get_section_tree()
for material in bpy.data.materials:
material.use_nodes = True
cls.set_use_nodes(material, True)
if material.node_tree.nodes.get(override.name):
continue
material.blend_method = "HASHED"
@@ -261,12 +268,12 @@ class SectionCutawayManager:
section_compare.name = "Last Section Compare"
@staticmethod
def add_default_material_if_none_exists(context):
@classmethod
def add_default_material_if_none_exists(cls, context):
material = bpy.data.materials.get("Section Override")
if not material:
material = bpy.data.materials.new("Section Override")
material.use_nodes = True
cls.set_use_nodes(material, True)
if context.scene.SectionProperties.should_section_selected_objects:
objects = list(context.selected_objects)
+2 -2
View File
@@ -37,7 +37,7 @@ class TestImplementsTool(NewFile):
class TestCopyNodeGraph(NewFile):
def test_run(self):
material_to = bpy.data.materials.new("material_to")
material_to.use_nodes = True
tool.Style.set_use_nodes(material_to, True)
assert material_to.node_tree
material_to_nodes = material_to.node_tree.nodes
assert len(material_to_nodes) == 2
@@ -46,7 +46,7 @@ class TestCopyNodeGraph(NewFile):
assert len(material_to_nodes) == 0
material_from = bpy.data.materials.new("material_from")
material_from.use_nodes = True
tool.Style.set_use_nodes(material_from, True)
subject.copy_node_graph(material_to, material_from)
assert len(material_to_nodes) == 2
+3 -3
View File
@@ -488,7 +488,7 @@ class TestShouldGenerateUVs(NewFile):
obj = bpy.data.objects.new("Object", bpy.data.meshes.new("Mesh"))
material = bpy.data.materials.new("Material")
obj.data.materials.append(material)
material.use_nodes = False
tool.Style.set_use_nodes(material, False)
assert subject.should_generate_uvs(obj) is False
def test_needs_texture_coordinates_with_a_uv_output(self):
@@ -497,7 +497,7 @@ class TestShouldGenerateUVs(NewFile):
obj = bpy.data.objects.new("Object", bpy.data.meshes.new("Mesh"))
material = bpy.data.materials.new("Material")
obj.data.materials.append(material)
material.use_nodes = True
tool.Style.set_use_nodes(material, True)
bsdf = tool.Blender.get_material_node(material, "BSDF_PRINCIPLED")
node = material.node_tree.nodes.new(type="ShaderNodeTexImage")
@@ -513,7 +513,7 @@ class TestShouldGenerateUVs(NewFile):
obj = bpy.data.objects.new("Object", bpy.data.meshes.new("Mesh"))
material = bpy.data.materials.new("Material")
obj.data.materials.append(material)
material.use_nodes = True
tool.Style.set_use_nodes(material, True)
bsdf = tool.Blender.get_material_node(material, "BSDF_PRINCIPLED")
node = material.node_tree.nodes.new(type="ShaderNodeTexImage")
+13 -8
View File
@@ -22,6 +22,7 @@ import ifcopenshell
import ifcopenshell.api
import ifcopenshell.api.root
import ifcopenshell.util.representation
import pytest
import bonsai.core.tool
import bonsai.tool as tool
from test.bim.bootstrap import NewFile
@@ -37,12 +38,16 @@ class TestImplementsTool(NewFile):
class TestCanSupportRenderingStyle(NewFile):
def test_anything_with_nodes_can_support_a_rendering_style(self):
obj = bpy.data.materials.new("Material")
obj.use_nodes = True
tool.Style.set_use_nodes(obj, True)
assert subject.can_support_rendering_style(obj) is True
@pytest.mark.skipif(
tool.Blender.BLENDER_5,
reason="Since Blender 5.0 `use_nodes` are always `True` and deprecated.",
)
def test_without_nodes_we_do_not_support_rendering(self):
obj = bpy.data.materials.new("Material")
obj.use_nodes = False
tool.Style.set_use_nodes(obj, False)
assert subject.can_support_rendering_style(obj) is False
@@ -125,7 +130,7 @@ class TestGetSurfaceRenderingAttributes(NewFile):
def test_get_different_surface_and_diffuse_colours_from_a_principled_bsdf(self):
obj = bpy.data.materials.new("Material")
obj.diffuse_color = [1, 1, 1, 1]
obj.use_nodes = True
tool.Style.set_use_nodes(obj, True)
node = tool.Blender.get_material_node(obj, "BSDF_PRINCIPLED")
assert node
node.inputs["Alpha"].default_value = 0.8
@@ -153,7 +158,7 @@ class TestGetSurfaceRenderingAttributes(NewFile):
def test_get_rendering_styles_from_a_glossy_bsdf(self):
obj = bpy.data.materials.new("Material")
obj.diffuse_color = [1, 1, 1, 1]
obj.use_nodes = True
tool.Style.set_use_nodes(obj, True)
output = tool.Blender.get_material_node(obj, "OUTPUT_MATERIAL")
node = tool.Blender.get_material_node(obj, "BSDF_PRINCIPLED")
assert obj.node_tree and node
@@ -185,7 +190,7 @@ class TestGetSurfaceRenderingAttributes(NewFile):
def test_get_rendering_styles_from_a_diffuse_bsdf(self):
obj = bpy.data.materials.new("Material")
obj.diffuse_color = [1, 1, 1, 1]
obj.use_nodes = True
tool.Style.set_use_nodes(obj, True)
output = tool.Blender.get_material_node(obj, "OUTPUT_MATERIAL")
node = tool.Blender.get_material_node(obj, "BSDF_PRINCIPLED")
assert obj.node_tree and node and output
@@ -217,7 +222,7 @@ class TestGetSurfaceRenderingAttributes(NewFile):
def test_get_rendering_styles_from_a_glass_bsdf(self):
obj = bpy.data.materials.new("Material")
obj.diffuse_color = [1, 1, 1, 1]
obj.use_nodes = True
tool.Style.set_use_nodes(obj, True)
output = tool.Blender.get_material_node(obj, "OUTPUT_MATERIAL")
node = tool.Blender.get_material_node(obj, "BSDF_PRINCIPLED")
assert obj.node_tree and node and output
@@ -249,7 +254,7 @@ class TestGetSurfaceRenderingAttributes(NewFile):
def test_get_rendering_styles_from_a_emission_bsdf(self):
obj = bpy.data.materials.new("Material")
obj.diffuse_color = [1, 1, 1, 1]
obj.use_nodes = True
tool.Style.set_use_nodes(obj, True)
output = tool.Blender.get_material_node(obj, "OUTPUT_MATERIAL")
node = tool.Blender.get_material_node(obj, "BSDF_PRINCIPLED")
assert obj.node_tree and node and output
@@ -280,7 +285,7 @@ class TestGetSurfaceRenderingAttributes(NewFile):
def test_other_unsupported_bsdfs_copy_the_rendering_style_from_the_shading_colours_as_a_fallback(self):
obj = bpy.data.materials.new("Material")
obj.diffuse_color = [1, 1, 1, 1]
obj.use_nodes = True
tool.Style.set_use_nodes(obj, True)
output = tool.Blender.get_material_node(obj, "OUTPUT_MATERIAL")
node = tool.Blender.get_material_node(obj, "BSDF_PRINCIPLED")
assert obj.node_tree and node and output
@@ -176,7 +176,8 @@ def import_ifc(filename, use_names, process_relations, blender_booleans):
mat.blend_method = "HASHED"
mat.use_screen_refraction = True
mat.refraction_depth = 0.1
mat.use_nodes = True
if bpy.app.version >= (5, 0, 0):
mat.use_nodes = True
bsdf = next(n for n in mat.node_tree.nodes if n.type == "BSDF_PRINCIPLED")
bsdf.inputs[15].default_value = v
else: