From 36a8f2367432dfcec6c236c90fa3f5aed6e2b222 Mon Sep 17 00:00:00 2001 From: Simon Wendsche Date: Sun, 24 Mar 2019 13:03:12 +0100 Subject: [PATCH] run compatibility code before each export (fixes #245) --- export/__init__.py | 6 ++ utils/compatibility.py | 240 ++++++++++++++++++----------------------- 2 files changed, 110 insertions(+), 136 deletions(-) diff --git a/export/__init__.py b/export/__init__.py index 69f245f0..58cfa8cf 100644 --- a/export/__init__.py +++ b/export/__init__.py @@ -3,6 +3,7 @@ from ..bin import pyluxcore from .. import utils from ..utils import render as utils_render +from ..utils import compatibility as utils_compatibility from . import ( blender_object, caches, camera, config, duplis, group_instance, imagepipeline, light, material, @@ -90,6 +91,11 @@ def create_session(self, context=None, engine=None): updated_objs_pre = self.object_cache.diff(scene) updated_mats_pre = self.material_cache.diff() + # We have to run the compatibility code before export because it could be that + # the user has linked/appended assets with node trees from previous versions of + # the addon since opening the .blend file. + utils_compatibility.run() + # Scene luxcore_scene = pyluxcore.Scene() scene_props = pyluxcore.Properties() diff --git a/utils/compatibility.py b/utils/compatibility.py index 9b1fa5c8..34983ea4 100644 --- a/utils/compatibility.py +++ b/utils/compatibility.py @@ -3,190 +3,158 @@ """ -Contains functions that are executed when a .blend is loaded. -They ensure backwards compatibility, +Contains functions that ensure backwards compatibility, e.g. replace old nodes with updated ones when socket names change. """ def run(): - update_output_nodes_volume_change() - update_glossy_nodes_ior_change() - update_volume_nodes_asymmetry_change() - update_smoke_nodes_add_color_output() - update_colormix_remove_min_max_sockets() - update_imagemap_remove_gamma_brightness_sockets() - update_cloth_remove_repeat_sockets() - update_imagemap_add_alpha_output() + for node_tree in bpy.data.node_groups: + update_output_nodes_volume_change(node_tree) + update_glossy_nodes_ior_change(node_tree) + update_volume_nodes_asymmetry_change(node_tree) + update_smoke_nodes_add_color_output(node_tree) + update_colormix_remove_min_max_sockets(node_tree) + update_imagemap_remove_gamma_brightness_sockets(node_tree) + update_cloth_remove_repeat_sockets(node_tree) + update_imagemap_add_alpha_output(node_tree) -def update_output_nodes_volume_change(): +def update_output_nodes_volume_change(node_tree): # commit 3078719a9a33a7e2a798965294463dce6c8b7749 - for node_tree in bpy.data.node_groups: - if node_tree.library: + for old_output in find_nodes(node_tree, "LuxCoreNodeMatOutput"): + if "Interior Volume" in old_output.inputs: continue - for old_output in find_nodes(node_tree, "LuxCoreNodeMatOutput"): - if "Interior Volume" in old_output.inputs: - continue + from_node = old_output.inputs[0].links[0].from_node - from_node = old_output.inputs[0].links[0].from_node + new_out = node_tree.nodes.new("LuxCoreNodeMatOutput") + new_out.location = old_output.location + node_tree.links.new(from_node.outputs[0], new_out.inputs[0]) - new_out = node_tree.nodes.new("LuxCoreNodeMatOutput") - new_out.location = old_output.location - node_tree.links.new(from_node.outputs[0], new_out.inputs[0]) + # Move the old volume node tree PointerProperties into Pointer nodes + try: + interior = old_output["interior_volume"] - # Move the old volume node tree PointerProperties into Pointer nodes - try: - interior = old_output["interior_volume"] + if interior: + volume_pointer = node_tree.nodes.new("LuxCoreNodeTreePointer") + volume_pointer.node_tree = interior + volume_pointer.location = (new_out.location.x - 250, new_out.location.y - 100) + node_tree.links.new(volume_pointer.outputs["Volume"], new_out.inputs["Interior Volume"]) + print("linked interior", node_tree.name) - if interior: - volume_pointer = node_tree.nodes.new("LuxCoreNodeTreePointer") - volume_pointer.node_tree = interior - volume_pointer.location = (new_out.location.x - 250, new_out.location.y - 100) - node_tree.links.new(volume_pointer.outputs["Volume"], new_out.inputs["Interior Volume"]) - print("linked interior", node_tree.name) + exterior = old_output["exterior_volume"] - exterior = old_output["exterior_volume"] + if exterior: + volume_pointer = node_tree.nodes.new("LuxCoreNodeTreePointer") + volume_pointer.node_tree = exterior + volume_pointer.location = (new_out.location.x - 250, new_out.location.y - 250) + node_tree.links.new(volume_pointer.outputs["Volume"], new_out.inputs["Exterior Volume"]) + except KeyError: + pass - if exterior: - volume_pointer = node_tree.nodes.new("LuxCoreNodeTreePointer") - volume_pointer.node_tree = exterior - volume_pointer.location = (new_out.location.x - 250, new_out.location.y - 250) - node_tree.links.new(volume_pointer.outputs["Volume"], new_out.inputs["Exterior Volume"]) - except KeyError: - pass + print('Updated output node "%s" in tree %s to new version' % (old_output.name, node_tree.name)) + node_tree.nodes.remove(old_output) - print('Updated output node "%s" in tree %s to new version' % (old_output.name, node_tree.name)) - node_tree.nodes.remove(old_output) - -def update_glossy_nodes_ior_change(): +def update_glossy_nodes_ior_change(node_tree): # commit c3152dec8e0e07e676a60be56ba4578dbe297df6 - for node_tree in bpy.data.node_groups: - if node_tree.library: - continue - - affected_nodes = find_nodes(node_tree, "LuxCoreNodeMatGlossy2") - affected_nodes += find_nodes(node_tree, "LuxCoreNodeMatGlossyCoating") + affected_nodes = find_nodes(node_tree, "LuxCoreNodeMatGlossy2") + affected_nodes += find_nodes(node_tree, "LuxCoreNodeMatGlossyCoating") - for node in affected_nodes: - if "IOR" not in node.inputs: - # Note: the IOR input will be at the very bottom, but at least the export works - node.add_input("LuxCoreSocketIOR", "IOR", 1.5) - node.inputs["IOR"].enabled = False - print('Updated %s node "%s" in tree "%s" to new version' % (node.bl_idname, node.name, node_tree.name)) + for node in affected_nodes: + if "IOR" not in node.inputs: + # Note: the IOR input will be at the very bottom, but at least the export works + node.add_input("LuxCoreSocketIOR", "IOR", 1.5) + node.inputs["IOR"].enabled = False + print('Updated %s node "%s" in tree "%s" to new version' % (node.bl_idname, node.name, node_tree.name)) -def update_volume_nodes_asymmetry_change(): +def update_volume_nodes_asymmetry_change(node_tree): # commit 2387d1c300b5a1f6931592efcdd0574d243356e7 - for node_tree in bpy.data.node_groups: - if node_tree.library: - continue - - if node_tree.bl_idname != "luxcore_volume_nodes": - continue + if node_tree.bl_idname != "luxcore_volume_nodes": + return - affected_nodes = find_nodes(node_tree, "LuxCoreNodeVolHeterogeneous") - affected_nodes += find_nodes(node_tree, "LuxCoreNodeVolHomogeneous") + affected_nodes = find_nodes(node_tree, "LuxCoreNodeVolHeterogeneous") + affected_nodes += find_nodes(node_tree, "LuxCoreNodeVolHomogeneous") - for node in affected_nodes: - asymmetry_socket = node.inputs["Asymmetry"] - if asymmetry_socket.bl_idname == "NodeSocketUndefined": - node.inputs.remove(asymmetry_socket) - node.add_input("LuxCoreSocketVolumeAsymmetry", "Asymmetry", (0, 0, 0)) - print('Updated %s node "%s" in tree "%s" to new version' % (node.bl_idname, node.name, node_tree.name)) + for node in affected_nodes: + asymmetry_socket = node.inputs["Asymmetry"] + if asymmetry_socket.bl_idname == "NodeSocketUndefined": + node.inputs.remove(asymmetry_socket) + node.add_input("LuxCoreSocketVolumeAsymmetry", "Asymmetry", (0, 0, 0)) + print('Updated %s node "%s" in tree "%s" to new version' % (node.bl_idname, node.name, node_tree.name)) -def update_smoke_nodes_add_color_output(): +def update_smoke_nodes_add_color_output(node_tree): # commit f31f3be5409df9866c9b7364ce79e8e7aee0e875 - for node_tree in bpy.data.node_groups: - if node_tree.library: - continue - - if node_tree.bl_idname != "luxcore_volume_nodes": - continue + if node_tree.bl_idname != "luxcore_volume_nodes": + return - for node in find_nodes(node_tree, "LuxCoreNodeTexSmoke"): - if "Color" not in node.outputs: - color = node.outputs.new("LuxCoreSocketColor", "Color") - color.enabled = False - print('Updated %s node "%s" in tree "%s" to new version' % (node.bl_idname, node.name, node_tree.name)) + for node in find_nodes(node_tree, "LuxCoreNodeTexSmoke"): + if "Color" not in node.outputs: + color = node.outputs.new("LuxCoreSocketColor", "Color") + color.enabled = False + print('Updated %s node "%s" in tree "%s" to new version' % (node.bl_idname, node.name, node_tree.name)) -def update_colormix_remove_min_max_sockets(): +def update_colormix_remove_min_max_sockets(node_tree): # commit 432b1ba020b07f46758fd19b4b3af91cca0c90ff - for node_tree in bpy.data.node_groups: - if node_tree.library: - continue - - for node in find_nodes(node_tree, "LuxCoreNodeTexColorMix"): - if node.mode == "clamp" and "Min" in node.inputs and "Max" in node.inputs: - socket_min = node.inputs["Min"] - socket_max = node.inputs["Max"] - node.mode_clamp_min = socket_min.default_value - node.mode_clamp_max = socket_max.default_value - node.inputs.remove(socket_min) - node.inputs.remove(socket_max) - print('Updated %s node "%s" in tree "%s" to new version' % (node.bl_idname, node.name, node_tree.name)) + for node in find_nodes(node_tree, "LuxCoreNodeTexColorMix"): + if node.mode == "clamp" and "Min" in node.inputs and "Max" in node.inputs: + socket_min = node.inputs["Min"] + socket_max = node.inputs["Max"] + node.mode_clamp_min = socket_min.default_value + node.mode_clamp_max = socket_max.default_value + node.inputs.remove(socket_min) + node.inputs.remove(socket_max) + print('Updated %s node "%s" in tree "%s" to new version' % (node.bl_idname, node.name, node_tree.name)) -def update_imagemap_remove_gamma_brightness_sockets(): +def update_imagemap_remove_gamma_brightness_sockets(node_tree): # commit 428110b2c1bdbf8c54a54030939b3c76cb018644 - for node_tree in bpy.data.node_groups: - if node_tree.library: - continue - - for node in find_nodes(node_tree, "LuxCoreNodeTexImagemap"): - updated = False - if "Gamma" in node.inputs: - socket_gamma = node.inputs["Gamma"] - node.gamma = socket_gamma.default_value - node.inputs.remove(socket_gamma) - updated = True + for node in find_nodes(node_tree, "LuxCoreNodeTexImagemap"): + updated = False + if "Gamma" in node.inputs: + socket_gamma = node.inputs["Gamma"] + node.gamma = socket_gamma.default_value + node.inputs.remove(socket_gamma) + updated = True - if "Brightness" in node.inputs: - socket_brightness = node.inputs["Brightness"] - node.brightness = socket_brightness.default_value - node.inputs.remove(socket_brightness) - updated = True + if "Brightness" in node.inputs: + socket_brightness = node.inputs["Brightness"] + node.brightness = socket_brightness.default_value + node.inputs.remove(socket_brightness) + updated = True - if updated: - print('Updated %s node "%s" in tree "%s" to new version' % (node.bl_idname, node.name, node_tree.name)) + if updated: + print('Updated %s node "%s" in tree "%s" to new version' % (node.bl_idname, node.name, node_tree.name)) -def update_cloth_remove_repeat_sockets(): +def update_cloth_remove_repeat_sockets(node_tree): # commit ec3fccdccb3e4c95a4230df8b38f6494bb8e4583 - for node_tree in bpy.data.node_groups: - if node_tree.library: - continue - - for node in find_nodes(node_tree, "LuxCoreNodeMatCloth"): - if "Repeat U" in node.inputs and "Repeat V" in node.inputs: - socket_repeat_u = node.inputs["Repeat U"] - socket_repeat_v = node.inputs["Repeat V"] - node.repeat_u = socket_repeat_u.default_value - node.repeat_v = socket_repeat_v.default_value - node.inputs.remove(socket_repeat_u) - node.inputs.remove(socket_repeat_v) - print('Updated %s node "%s" in tree "%s" to new version' % (node.bl_idname, node.name, node_tree.name)) + for node in find_nodes(node_tree, "LuxCoreNodeMatCloth"): + if "Repeat U" in node.inputs and "Repeat V" in node.inputs: + socket_repeat_u = node.inputs["Repeat U"] + socket_repeat_v = node.inputs["Repeat V"] + node.repeat_u = socket_repeat_u.default_value + node.repeat_v = socket_repeat_v.default_value + node.inputs.remove(socket_repeat_u) + node.inputs.remove(socket_repeat_v) + print('Updated %s node "%s" in tree "%s" to new version' % (node.bl_idname, node.name, node_tree.name)) -def update_imagemap_add_alpha_output(): +def update_imagemap_add_alpha_output(node_tree): # commit 09f23b0d758bce9383a0fa8c64ccbeb73706bccf - for node_tree in bpy.data.node_groups: - if node_tree.library: - continue - - for node in find_nodes(node_tree, "LuxCoreNodeTexImagemap"): - if "Alpha" not in node.outputs: - node.outputs.new("LuxCoreSocketFloatUnbounded", "Alpha") - print('Updated %s node "%s" in tree "%s" to new version' % (node.bl_idname, node.name, node_tree.name)) + for node in find_nodes(node_tree, "LuxCoreNodeTexImagemap"): + if "Alpha" not in node.outputs: + node.outputs.new("LuxCoreSocketFloatUnbounded", "Alpha") + print('Updated %s node "%s" in tree "%s" to new version' % (node.bl_idname, node.name, node_tree.name))