from .common import * from . import lib def get_modifier_channel_type(mod, return_non_color=False): yp = mod.id_data.yp match1 = re.match(r'yp\.layers\[(\d+)\]\.channels\[(\d+)\]\.modifiers\[(\d+)\]', mod.path_from_id()) match2 = re.match(r'yp\.channels\[(\d+)\]\.modifiers\[(\d+)\]', mod.path_from_id()) match3 = re.match(r'yp\.layers\[(\d+)\]\.modifiers\[(\d+)\]', mod.path_from_id()) match4 = re.match(r'yp\.layers\[(\d+)\]\.channels\[(\d+)\]\.modifiers_1\[(\d+)\]', mod.path_from_id()) if match1: root_ch = yp.channels[int(match1.group(2))] # Get non color flag and channel type non_color = root_ch.colorspace == 'LINEAR' channel_type = root_ch.type elif match2: root_ch = yp.channels[int(match2.group(1))] # Get non color flag and channel type non_color = root_ch.colorspace == 'LINEAR' channel_type = root_ch.type elif match3: # Image layer modifiers always use srgb colorspace layer = yp.layers[int(match3.group(1))] non_color = layer.type != 'IMAGE' channel_type = 'RGB' elif match4: non_color = True channel_type = 'RGB' else: non_color = True channel_type = 'VALUE' if return_non_color: return channel_type, non_color return channel_type def save_rgb2i_props(tree, m): rgb2i = tree.nodes.get(m.rgb2i) root_tree = m.id_data if rgb2i: for fcs in get_action_and_driver_fcurves(tree): for fc in fcs: match = re.match(r'^nodes\["' + m.rgb2i + '"\]\.inputs\[(\d+)\]\.default_value$', fc.data_path) if match: index = int(match.group(1)) if index == 3: if root_tree != tree: copy_fcurves(fc, root_tree, m, 'rgb2i_col') else: fc.data_path = m.path_from_id() + '.rgb2i_col' m.rgb2i_col = rgb2i.inputs['RGB To Intensity Color'].default_value def load_rgb2i_anim_props(tree, m): rgb2i = tree.nodes.get(m.rgb2i) root_tree = m.id_data if rgb2i: for fcs in get_action_and_driver_fcurves(root_tree): for fc in reversed(fcs): if root_tree != tree: # Copy fcurve if the tree is different if fc.data_path == m.path_from_id() + '.rgb2i_col': copy_fcurves(fc, tree, rgb2i.inputs[3], 'default_value') fcs.remove(fc) else: # Rename data path if the tree is the same if fc.data_path == m.path_from_id() + '.rgb2i_col': fc.data_path = 'nodes["' + m.rgb2i + '"].inputs[3].default_value' def save_huesat_props(tree, m): huesat = tree.nodes.get(m.huesat) root_tree = m.id_data if huesat: for fcs in get_action_and_driver_fcurves(tree): for fc in fcs: match = re.match(r'^nodes\["' + m.huesat + '"\]\.inputs\[(\d+)\]\.default_value$', fc.data_path) if match: index = int(match.group(1)) if root_tree != tree: # Copy fcurve to yp attributes if the tree is different if index == 0: copy_fcurves(fc, root_tree, m, 'huesat_hue_val') elif index == 1: copy_fcurves(fc, root_tree, m, 'huesat_saturation_val') elif index == 2: copy_fcurves(fc, root_tree, m, 'huesat_value_val') else: # Rename data path if the tree is the same if index == 0: fc.data_path = m.path_from_id() + '.huesat_hue_val' elif index == 1: fc.data_path = m.path_from_id() + '.huesat_saturation_val' elif index == 2: fc.data_path = m.path_from_id() + '.huesat_value_val' m.huesat_hue_val = huesat.inputs['Hue'].default_value m.huesat_saturation_val = huesat.inputs['Saturation'].default_value m.huesat_value_val = huesat.inputs['Value'].default_value def load_huesat_anim_props(tree, m): huesat = tree.nodes.get(m.huesat) root_tree = m.id_data if huesat: for fcs in get_action_and_driver_fcurves(root_tree): for fc in reversed(fcs): if root_tree != tree: # Copy fcurve if the tree is different if fc.data_path == m.path_from_id() + '.huesat_hue_val': copy_fcurves(fc, tree, huesat.inputs[0], 'default_value') fcs.remove(fc) elif fc.data_path == m.path_from_id() + '.huesat_saturation_val': copy_fcurves(fc, tree, huesat.inputs[1], 'default_value') fcs.remove(fc) elif fc.data_path == m.path_from_id() + '.huesat_value_val': copy_fcurves(fc, tree, huesat.inputs[2], 'default_value') fcs.remove(fc) else: # Rename data path if the tree is the same if fc.data_path == m.path_from_id() + '.huesat_hue_val': fc.data_path = 'nodes["' + m.huesat + '"].inputs[0].default_value' elif fc.data_path == m.path_from_id() + '.huesat_saturation_val': fc.data_path = 'nodes["' + m.huesat + '"].inputs[1].default_value' elif fc.data_path == m.path_from_id() + '.huesat_value_val': fc.data_path = 'nodes["' + m.huesat + '"].inputs[2].default_value' def save_brightcon_props(tree, m): brightcon = tree.nodes.get(m.brightcon) root_tree = m.id_data if brightcon: for fcs in get_action_and_driver_fcurves(tree): for fc in fcs: match = re.match(r'^nodes\["' + m.brightcon + '"\]\.inputs\[(\d+)\]\.default_value$', fc.data_path) if match: index = int(match.group(1)) if root_tree != tree: # Copy fcurve to yp attributes if the tree is different if index == 1: copy_fcurves(fc, root_tree, m, 'brightness_value') elif index == 2: copy_fcurves(fc, root_tree, m, 'contrast_value') else: # Rename data path if the tree is the same if index == 1: fc.data_path = m.path_from_id() + '.brightness_value' elif index == 2: fc.data_path = m.path_from_id() + '.contrast_value' m.brightness_value = brightcon.inputs['Bright'].default_value m.contrast_value = brightcon.inputs['Contrast'].default_value def load_brightcon_anim_props(tree, m): brightcon = tree.nodes.get(m.brightcon) root_tree = m.id_data if brightcon: for fcs in get_action_and_driver_fcurves(root_tree): for fc in reversed(fcs): if root_tree != tree: # Copy fcurve if the tree is different if fc.data_path == m.path_from_id() + '.brightness_value': copy_fcurves(fc, tree, brightcon.inputs[1], 'default_value') fcs.remove(fc) elif fc.data_path == m.path_from_id() + '.contrast_value': copy_fcurves(fc, tree, brightcon.inputs[2], 'default_value') fcs.remove(fc) else: # Rename data path if the tree is the same if fc.data_path == m.path_from_id() + '.brightness_value': fc.data_path = 'nodes["' + m.brightcon + '"].inputs[1].default_value' elif fc.data_path == m.path_from_id() + '.contrast_value': fc.data_path = 'nodes["' + m.brightcon + '"].inputs[2].default_value' def save_math_props(tree, m, channel_type): math = tree.nodes.get(m.math) root_tree = m.id_data if math: for fcs in get_action_and_driver_fcurves(tree): for fc in fcs: match = re.match(r'^nodes\["' + m.math + '"\]\.inputs\[(\d+)\]\.default_value$', fc.data_path) if match: index = int(match.group(1)) if root_tree != tree: # Copy fcurve to yp attributes if the tree is different if channel_type == 'VALUE': if index == 2: copy_fcurves(fc, root_tree, m, 'math_r_val') elif index == 3: copy_fcurves(fc, root_tree, m, 'math_a_val') else: if index == 2: copy_fcurves(fc, root_tree, m, 'math_r_val') elif index == 3: copy_fcurves(fc, root_tree, m, 'math_g_val') elif index == 4: copy_fcurves(fc, root_tree, m, 'math_b_val') elif index == 5: copy_fcurves(fc, root_tree, m, 'math_a_val') else: # Rename data path if the tree is the same if channel_type == 'VALUE': if index == 2: fc.data_path = m.path_from_id() + '.math_r_val' elif index == 3: fc.data_path = m.path_from_id() + '.math_a_val' else: if index == 2: fc.data_path = m.path_from_id() + '.math_r_val' elif index == 3: fc.data_path = m.path_from_id() + '.math_g_val' elif index == 4: fc.data_path = m.path_from_id() + '.math_b_val' elif index == 5: fc.data_path = m.path_from_id() + '.math_a_val' m.math_r_val = math.inputs[2].default_value if channel_type == 'VALUE': m.math_a_val = math.inputs[3].default_value else: m.math_g_val = math.inputs[3].default_value m.math_b_val = math.inputs[4].default_value m.math_a_val = math.inputs[5].default_value def load_math_anim_props(tree, m, channel_type): math = tree.nodes.get(m.math) root_tree = m.id_data if math: for fcs in get_action_and_driver_fcurves(root_tree): for fc in reversed(fcs): if root_tree != tree: # Copy fcurve if the tree is different if channel_type == 'VALUE': if fc.data_path == m.path_from_id() + '.math_r_val': copy_fcurves(fc, tree, math.inputs[2], 'default_value') fcs.remove(fc) elif fc.data_path == m.path_from_id() + '.math_a_val': copy_fcurves(fc, tree, math.inputs[3], 'default_value') fcs.remove(fc) else: if fc.data_path == m.path_from_id() + '.math_r_val': copy_fcurves(fc, tree, math.inputs[2], 'default_value') fcs.remove(fc) elif fc.data_path == m.path_from_id() + '.math_g_val': copy_fcurves(fc, tree, math.inputs[3], 'default_value') fcs.remove(fc) elif fc.data_path == m.path_from_id() + '.math_b_val': copy_fcurves(fc, tree, math.inputs[4], 'default_value') fcs.remove(fc) elif fc.data_path == m.path_from_id() + '.math_a_val': copy_fcurves(fc, tree, math.inputs[5], 'default_value') fcs.remove(fc) else: # Rename data path if the tree is the same if channel_type == 'VALUE': if fc.data_path == m.path_from_id() + '.math_r_val': fc.data_path = 'nodes["' + m.math + '"].inputs[2].default_value' elif fc.data_path == m.path_from_id() + '.math_a_val': fc.data_path = 'nodes["' + m.math + '"].inputs[3].default_value' else: if fc.data_path == m.path_from_id() + '.math_r_val': fc.data_path = 'nodes["' + m.math + '"].inputs[2].default_value' elif fc.data_path == m.path_from_id() + '.math_g_val': fc.data_path = 'nodes["' + m.math + '"].inputs[3].default_value' elif fc.data_path == m.path_from_id() + '.math_b_val': fc.data_path = 'nodes["' + m.math + '"].inputs[4].default_value' elif fc.data_path == m.path_from_id() + '.math_a_val': fc.data_path = 'nodes["' + m.math + '"].inputs[5].default_value' def check_modifier_nodes(m, tree, ref_tree=None): yp = m.id_data.yp nodes = tree.nodes # Get channel type and non color status channel_type, non_color = get_modifier_channel_type(m, True) # Check the nodes if m.type == 'INVERT': if not m.enable: remove_node(tree, m, 'invert') else: if ref_tree: invert_ref = ref_tree.nodes.get(m.invert) if invert_ref: ref_tree.nodes.remove(invert_ref) invert = new_node(tree, m, 'invert', 'ShaderNodeGroup', 'Invert') dirty = True else: invert, dirty = check_new_node(tree, m, 'invert', 'ShaderNodeGroup', 'Invert', True) if dirty: if channel_type == 'VALUE': invert.node_tree = get_node_tree_lib(lib.MOD_INVERT_VALUE) else: invert.node_tree = get_node_tree_lib(lib.MOD_INVERT) invert.inputs[2].default_value = 1.0 if m.invert_r_enable else 0.0 if channel_type == 'VALUE': invert.inputs[3].default_value = 1.0 if m.invert_a_enable else 0.0 else: invert.inputs[3].default_value = 1.0 if m.invert_g_enable else 0.0 invert.inputs[4].default_value = 1.0 if m.invert_b_enable else 0.0 invert.inputs[5].default_value = 1.0 if m.invert_a_enable else 0.0 elif m.type == 'RGB_TO_INTENSITY': if not m.enable: save_rgb2i_props(tree, m) remove_node(tree, m, 'rgb2i') else: if ref_tree: save_rgb2i_props(tree, m) rgb2i_ref = ref_tree.nodes.get(m.rgb2i) if rgb2i_ref: ref_tree.nodes.remove(rgb2i_ref) rgb2i = new_node(tree, m, 'rgb2i', 'ShaderNodeGroup', 'RGB to Intensity') dirty = True else: rgb2i, dirty = check_new_node(tree, m, 'rgb2i', 'ShaderNodeGroup', 'RGB to Intensity', True) if dirty: rgb2i.node_tree = get_node_tree_lib(lib.MOD_RGB2INT) rgb2i.inputs['RGB To Intensity Color'].default_value = m.rgb2i_col if non_color: rgb2i.inputs['Gamma'].default_value = 1.0 else: rgb2i.inputs['Gamma'].default_value = 1.0 / GAMMA load_rgb2i_anim_props(tree, m) elif m.type == 'INTENSITY_TO_RGB': if not m.enable: remove_node(tree, m, 'i2rgb') else: if ref_tree: i2rgb_ref = ref_tree.nodes.get(m.i2rgb) if i2rgb_ref: ref_tree.nodes.remove(i2rgb_ref) i2rgb = new_node(tree, m, 'i2rgb', 'ShaderNodeGroup', 'Intensity to RGB') dirty = True else: i2rgb, dirty = check_new_node(tree, m, 'i2rgb', 'ShaderNodeGroup', 'Intensity to RGB', True) if dirty: i2rgb.node_tree = get_node_tree_lib(lib.MOD_INT2RGB) elif m.type == 'OVERRIDE_COLOR': if not m.enable: remove_node(tree, m, 'oc') else: if ref_tree: oc_ref = ref_tree.nodes.get(m.oc) if oc_ref: ref_tree.nodes.remove(oc_ref) oc = new_node(tree, m, 'oc', 'ShaderNodeGroup', 'Override Color') dirty = True else: oc, dirty = check_new_node(tree, m, 'oc', 'ShaderNodeGroup', 'Override Color', True) if dirty: oc.node_tree = get_node_tree_lib(lib.MOD_OVERRIDE_COLOR) if channel_type == 'VALUE': col = (m.oc_val, m.oc_val, m.oc_val, 1.0) else: col = m.oc_col oc.inputs['Override Color'].default_value = col if non_color: oc.inputs['Gamma'].default_value = 1.0 else: oc.inputs['Gamma'].default_value = 1.0 / GAMMA elif m.type == 'COLOR_RAMP': if not m.enable: if ref_tree: color_ramp = new_node(tree, m, 'color_ramp', 'ShaderNodeValToRGB', 'ColorRamp') color_ramp_ref = ref_tree.nodes.get(m.color_ramp) if color_ramp_ref: copy_node_props(color_ramp_ref, color_ramp) ref_tree.nodes.remove(color_ramp_ref) remove_node(tree, m, 'color_ramp_linear_start') remove_node(tree, m, 'color_ramp_linear') remove_node(tree, m, 'color_ramp_alpha_multiply') remove_node(tree, m, 'color_ramp_mix_rgb') remove_node(tree, m, 'color_ramp_mix_alpha') else: if ref_tree: color_ramp_alpha_multiply_ref = ref_tree.nodes.get(m.color_ramp_alpha_multiply) color_ramp_linear_start_ref = ref_tree.nodes.get(m.color_ramp_linear_start) color_ramp_ref = ref_tree.nodes.get(m.color_ramp) color_ramp_linear_ref = ref_tree.nodes.get(m.color_ramp_linear) color_ramp_mix_alpha_ref = ref_tree.nodes.get(m.color_ramp_mix_alpha) color_ramp_mix_rgb_ref = ref_tree.nodes.get(m.color_ramp_mix_rgb) # Create new nodes if reference is used color_ramp_alpha_multiply = new_mix_node(tree, m, 'color_ramp_alpha_multiply', 'ColorRamp Alpha Multiply') color_ramp_linear_start = new_node(tree, m, 'color_ramp_linear_start', 'ShaderNodeGamma', 'ColorRamp Linear Start') color_ramp = new_node(tree, m, 'color_ramp', 'ShaderNodeValToRGB', 'ColorRamp') color_ramp_linear = new_node(tree, m, 'color_ramp_linear', 'ShaderNodeGamma', 'ColorRamp Linear') color_ramp_mix_alpha = new_mix_node(tree, m, 'color_ramp_mix_alpha', 'ColorRamp Mix Alpha') color_ramp_mix_rgb = new_mix_node(tree, m, 'color_ramp_mix_rgb', 'ColorRamp Mix RGB') dirty = True ramp_dirty = False else: color_ramp_alpha_multiply, dirty = check_new_mix_node(tree, m, 'color_ramp_alpha_multiply', 'ColorRamp Alpha Multiply', True) color_ramp_linear_start = check_new_node(tree, m, 'color_ramp_linear_start', 'ShaderNodeGamma', 'ColorRamp Linear Start') color_ramp, ramp_dirty = check_new_node(tree, m, 'color_ramp', 'ShaderNodeValToRGB', 'ColorRamp', True) color_ramp_linear = check_new_node(tree, m, 'color_ramp_linear', 'ShaderNodeGamma', 'ColorRamp Linear') color_ramp_mix_alpha = check_new_mix_node(tree, m, 'color_ramp_mix_alpha', 'ColorRamp Mix Alpha') color_ramp_mix_rgb = check_new_mix_node(tree, m, 'color_ramp_mix_rgb', 'ColorRamp Mix RGB') if ref_tree: if color_ramp_alpha_multiply_ref: copy_node_props(color_ramp_alpha_multiply_ref, color_ramp_alpha_multiply) ref_tree.nodes.remove(color_ramp_alpha_multiply_ref) if color_ramp_linear_start_ref: copy_node_props(color_ramp_linear_start_ref, color_ramp_linear_start) ref_tree.nodes.remove(color_ramp_linear_start_ref) if color_ramp_ref: copy_node_props(color_ramp_ref, color_ramp) ref_tree.nodes.remove(color_ramp_ref) if color_ramp_linear_ref: copy_node_props(color_ramp_linear_ref, color_ramp_linear) ref_tree.nodes.remove(color_ramp_linear_ref) if color_ramp_mix_alpha_ref: copy_node_props(color_ramp_mix_alpha_ref, color_ramp_mix_alpha) ref_tree.nodes.remove(color_ramp_mix_alpha_ref) if color_ramp_mix_rgb_ref: copy_node_props(color_ramp_mix_rgb_ref, color_ramp_mix_rgb) ref_tree.nodes.remove(color_ramp_mix_rgb_ref) if dirty: color_ramp_alpha_multiply.inputs[0].default_value = 1.0 color_ramp_alpha_multiply.blend_type = 'MULTIPLY' color_ramp_mix_alpha.inputs[0].default_value = 1.0 color_ramp_mix_rgb.inputs[0].default_value = 1.0 if non_color or yp.use_linear_blending: remove_node(tree, m, 'color_ramp_linear_start') remove_node(tree, m, 'color_ramp_linear') else: color_ramp_linear_start.inputs[1].default_value = GAMMA color_ramp_linear.inputs[1].default_value = 1.0 / GAMMA if ramp_dirty: # Set default color if ramp just created color_ramp.color_ramp.elements[0].color = (0, 0, 0, 0) elif m.type == 'RGB_CURVE': if ref_tree: rgb_curve_ref = ref_tree.nodes.get(m.rgb_curve) rgb_curve = new_node(tree, m, 'rgb_curve', 'ShaderNodeRGBCurve', 'RGB Curve') if rgb_curve_ref: # Copy from reference copy_node_props(rgb_curve_ref, rgb_curve) ref_tree.nodes.remove(rgb_curve_ref) else: rgb_curve = check_new_node(tree, m, 'rgb_curve', 'ShaderNodeRGBCurve', 'RGB Curve') elif m.type == 'HUE_SATURATION': if not m.enable: save_huesat_props(tree, m) remove_node(tree, m, 'huesat') else: if ref_tree: save_huesat_props(tree, m) # Remove previous nodes huesat_ref = ref_tree.nodes.get(m.huesat) if huesat_ref: ref_tree.nodes.remove(huesat_ref) huesat = new_node(tree, m, 'huesat', 'ShaderNodeHueSaturation', 'Hue Saturation') dirty = True else: huesat, dirty = check_new_node(tree, m, 'huesat', 'ShaderNodeHueSaturation', 'Hue Saturation', True) if dirty: huesat.inputs['Hue'].default_value = m.huesat_hue_val huesat.inputs['Saturation'].default_value = m.huesat_saturation_val huesat.inputs['Value'].default_value = m.huesat_value_val load_huesat_anim_props(tree, m) elif m.type == 'BRIGHT_CONTRAST': if not m.enable: save_brightcon_props(tree, m) remove_node(tree, m, 'brightcon') else: if ref_tree: save_brightcon_props(tree, m) # Remove previous nodes brightcon_ref = ref_tree.nodes.get(m.brightcon) if brightcon_ref: ref_tree.nodes.remove(brightcon_ref) brightcon = new_node(tree, m, 'brightcon', 'ShaderNodeBrightContrast', 'Brightness Contrast') dirty = True else: brightcon, dirty = check_new_node(tree, m, 'brightcon', 'ShaderNodeBrightContrast', 'Brightness Contrast', True) if dirty: brightcon.inputs['Bright'].default_value = m.brightness_value brightcon.inputs['Contrast'].default_value = m.contrast_value load_brightcon_anim_props(tree, m) elif m.type == 'MULTIPLIER': if not m.enable: remove_node(tree, m, 'multiplier') else: if ref_tree: # Remove previous nodes multiplier_ref = ref_tree.nodes.get(m.multiplier) if multiplier_ref: ref_tree.nodes.remove(multiplier_ref) multiplier = new_node(tree, m, 'multiplier', 'ShaderNodeGroup', 'Multiplier') dirty = True else: multiplier, dirty = check_new_node(tree, m, 'multiplier', 'ShaderNodeGroup', 'Multiplier', True) if dirty: if channel_type == 'VALUE': multiplier.node_tree = get_node_tree_lib(lib.MOD_MULTIPLIER_VALUE) else: multiplier.node_tree = get_node_tree_lib(lib.MOD_MULTIPLIER) multiplier.inputs[2].default_value = 1.0 if m.use_clamp else 0.0 multiplier.inputs[3].default_value = m.multiplier_r_val if channel_type == 'VALUE': multiplier.inputs[4].default_value = m.multiplier_a_val else: multiplier.inputs[4].default_value = m.multiplier_g_val multiplier.inputs[5].default_value = m.multiplier_b_val multiplier.inputs[6].default_value = m.multiplier_a_val elif m.type == 'MATH': if not m.enable: save_math_props(tree, m, channel_type) remove_node(tree, m, 'math') else: if ref_tree: save_math_props(ref_tree, m, channel_type) # Remove previous nodes math_ref = ref_tree.nodes.get(m.math) if math_ref: ref_tree.nodes.remove(math_ref) math = new_node(tree, m, 'math', 'ShaderNodeGroup', 'Math') dirty = True else: math, dirty = check_new_node(tree, m, 'math', 'ShaderNodeGroup', 'Math', True) if dirty: if channel_type == 'VALUE': math.node_tree = get_node_tree_lib(lib.MOD_MATH_VALUE) else : math.node_tree = get_node_tree_lib(lib.MOD_MATH) duplicate_lib_node_tree(math) math.inputs[2].default_value = m.math_r_val math.node_tree.nodes.get('Math.R').operation = m.math_meth math.node_tree.nodes.get('Math.A').operation = m.math_meth math.node_tree.nodes.get('Math.R').use_clamp = m.use_clamp math.node_tree.nodes.get('Math.A').use_clamp = m.use_clamp math.node_tree.nodes.get('Mix.A').mute = not m.affect_alpha if channel_type == 'VALUE': math.inputs[3].default_value = m.math_a_val else: math.inputs[3].default_value = m.math_g_val math.inputs[4].default_value = m.math_b_val math.inputs[5].default_value = m.math_a_val math.node_tree.nodes.get('Math.G').operation = m.math_meth math.node_tree.nodes.get('Math.B').operation = m.math_meth math.node_tree.nodes.get('Math.G').use_clamp = m.use_clamp math.node_tree.nodes.get('Math.B').use_clamp = m.use_clamp load_math_anim_props(tree, m, channel_type) def delete_modifier_nodes(tree, mod): # Delete the nodes remove_node(tree, mod, 'frame') if mod.type == 'RGB_TO_INTENSITY': remove_node(tree, mod, 'rgb2i') elif mod.type == 'INTENSITY_TO_RGB': remove_node(tree, mod, 'i2rgb') elif mod.type == 'OVERRIDE_COLOR': remove_node(tree, mod, 'oc') elif mod.type == 'INVERT': remove_node(tree, mod, 'invert') elif mod.type == 'COLOR_RAMP': remove_node(tree, mod, 'color_ramp_linear_start') remove_node(tree, mod, 'color_ramp') remove_node(tree, mod, 'color_ramp_linear') remove_node(tree, mod, 'color_ramp_alpha_multiply') remove_node(tree, mod, 'color_ramp_mix_rgb') remove_node(tree, mod, 'color_ramp_mix_alpha') elif mod.type == 'RGB_CURVE': remove_node(tree, mod, 'rgb_curve') elif mod.type == 'HUE_SATURATION': remove_node(tree, mod, 'huesat') elif mod.type == 'BRIGHT_CONTRAST': remove_node(tree, mod, 'brightcon') elif mod.type == 'MULTIPLIER': remove_node(tree, mod, 'multiplier') elif mod.type == 'MATH': remove_node(tree, mod, 'math')