Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

V3.0 #85

Merged
merged 80 commits into from
Jan 28, 2024
Merged

V3.0 #85

Changes from 1 commit
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
6e079d9
typo: fixed spelling of SelectMaterialMenu.bl_idname
BrendanParmer Aug 5, 2023
80d7a13
refactor: class renaming
BrendanParmer Aug 5, 2023
0409961
feat: added UI for compositor nodes
BrendanParmer Aug 5, 2023
cffd9ae
feat: add most compositor node settings
BrendanParmer Aug 6, 2023
486872d
feat: scene copying and setup
BrendanParmer Aug 13, 2023
3e9ebc9
refactor: add types to node settings
BrendanParmer Aug 25, 2023
7805bcf
refactor: switch dictionary format to use type enums instead of strings
BrendanParmer Aug 26, 2023
f1d85b6
refactor: changed set_settings_default() to use new types
BrendanParmer Aug 26, 2023
c0eb85d
style: better type hints for util functions
BrendanParmer Aug 26, 2023
38d3dfa
refactor: curve mappings and color ramps now handled with other node …
BrendanParmer Aug 27, 2023
cf38a9c
style: better type hinting
BrendanParmer Aug 27, 2023
c4e43d4
feat: basic compositor node tree regeneration
BrendanParmer Aug 27, 2023
ba3e4cb
feat: compositor nodes output socket default value settings
BrendanParmer Aug 27, 2023
0f49497
fix: initialize scene after creating a name to prevent conflicts
BrendanParmer Sep 2, 2023
12dcdbc
style: consistency of compositor names
BrendanParmer Sep 2, 2023
6825040
refactor: images and image users now use settings function
BrendanParmer Sep 3, 2023
f12189d
typo: material used_vars comment
BrendanParmer Sep 3, 2023
0921c25
fix: hue correction node removes excess points
BrendanParmer Sep 9, 2023
e5da196
fix: 0 settings now initialized
BrendanParmer Sep 10, 2023
d90b6d8
fix: color balance now only initializes needed members
BrendanParmer Sep 10, 2023
6e18e33
fix: add missing color correction attributes
BrendanParmer Sep 10, 2023
69e5b8d
Merge pull request #67 from BrendanParmer/compositing_nodes
BrendanParmer Sep 10, 2023
9a23883
docs: add downloads badge to README
BrendanParmer Sep 10, 2023
1c8f39c
refactor: started geo node refactor, broke operator into more functions
BrendanParmer Sep 10, 2023
f1b206a
refactor: UI node tree lists more standardized
BrendanParmer Sep 11, 2023
2a85b7d
refactor: geometry logic split into a subpackage
BrendanParmer Sep 11, 2023
b793e8c
refactor: material package creation
BrendanParmer Sep 13, 2023
1121841
refactor: split material operator into functions
BrendanParmer Sep 13, 2023
3140705
refactor: started moving common functionality to a base class
BrendanParmer Sep 18, 2023
2a36898
refactor: new compositor nodes structure
BrendanParmer Nov 18, 2023
41e33ea
refactor: compositor partial cleanup
BrendanParmer Nov 18, 2023
e2c7a67
refactor: moved a lot from the utils module to the base NTP_Operator …
BrendanParmer Nov 19, 2023
ce1a976
refactor: moved geo/shader nodes ui stuff into common module
BrendanParmer Nov 19, 2023
94df0cb
refactor: cleanup, group io stuff
BrendanParmer Nov 21, 2023
5449347
fix: material import typo
BrendanParmer Nov 21, 2023
03c40a2
refactor: abstracted write function
BrendanParmer Nov 21, 2023
01f5950
refactor: use NTP_NodeTree class in group_io_settings function
BrendanParmer Dec 2, 2023
7743d58
refactor: cleanup, removed child ntp_node_tree classes
BrendanParmer Dec 2, 2023
30b26dc
fix: removed imports for deleted modules
BrendanParmer Dec 2, 2023
cfe5a96
Merge pull request #71 from BrendanParmer/code_separation
BrendanParmer Dec 2, 2023
433d3b5
fix: cleaned up reference to old NTP_NodeTree
BrendanParmer Dec 2, 2023
b577857
Merge pull request #72 from BrendanParmer/code_separation
BrendanParmer Dec 2, 2023
f63b854
fix: restore necessary child NTP_GeoNodeTree class
BrendanParmer Dec 2, 2023
87dd46e
fix: import geo node tree module in package
BrendanParmer Dec 2, 2023
ede5ede
Merge pull request #73 from BrendanParmer/code_separation
BrendanParmer Dec 2, 2023
532ba17
feat: node names now copied also
BrendanParmer Dec 2, 2023
9b883cc
fix: NodeToPython now registers in v4.0
BrendanParmer Dec 9, 2023
23a863e
fix: compositing nodes now run, no group settings
BrendanParmer Dec 9, 2023
344e4c5
feat: support for rotation sockets
BrendanParmer Dec 9, 2023
89d9d48
feat: 4.0 node tree changes
BrendanParmer Jan 3, 2024
38553b5
feat: geo node modifier and tool setting
BrendanParmer Jan 6, 2024
2a9c545
fix: generic node types no longer warned about when trying to apply s…
BrendanParmer Jan 6, 2024
521be11
Merge pull request #78 from BrendanParmer/Blender-4.0-Breaking-Changes
BrendanParmer Jan 6, 2024
55f4190
feat: new geo node tree flags
BrendanParmer Jan 6, 2024
e6ad11c
feat: more robust variable name creation
BrendanParmer Jan 6, 2024
ae630f6
feat: only write geo node tool settings if tool
BrendanParmer Jan 6, 2024
a75050d
feat: new shader node settings
BrendanParmer Jan 6, 2024
a3975dd
feat: added settings for node frames and group outputs
BrendanParmer Jan 6, 2024
4135354
feat: added kuwahara, reorganized compositor node settings to align w…
BrendanParmer Jan 7, 2024
3287f2c
feat: repeat zones
BrendanParmer Jan 7, 2024
5dece56
feat: replace print statements with Blender reporting
BrendanParmer Jan 7, 2024
2528ec2
feat: add domain attribute to set shade smooth geo node
BrendanParmer Jan 7, 2024
8b5e4fe
fix: added array_to_py_str function
BrendanParmer Jan 14, 2024
86f6c0f
fix: group logic better accounts for dependencies
BrendanParmer Jan 14, 2024
630300a
feat: node panels
BrendanParmer Jan 15, 2024
43871de
refactor: cleanup
BrendanParmer Jan 15, 2024
2000967
fix: use variable creation function for nt interface item vars
BrendanParmer Jan 15, 2024
f0467dd
doc: added comments to new tree interface functions
BrendanParmer Jan 15, 2024
9da1d10
refactor: moved indent logic to write function, cleaned up functions
BrendanParmer Jan 21, 2024
5590f5e
refactor: group nodes now just use ST.NODE_TREE
BrendanParmer Jan 21, 2024
eca90aa
fix: typo
BrendanParmer Jan 22, 2024
6f1bf76
Merge pull request #79 from BrendanParmer/BlenderV4_0Nodes
BrendanParmer Jan 22, 2024
d846b8a
fix: introduced NTP reserved names to prevent possible node name conf…
BrendanParmer Jan 22, 2024
63f7377
fix: add don't allow index param globally
BrendanParmer Jan 22, 2024
fcf74a5
fix: indexing now matches other repeat variables
BrendanParmer Jan 22, 2024
50729ab
cleanup: minor import tweaks
BrendanParmer Jan 22, 2024
0166ed8
Merge pull request #82 from BrendanParmer/NameConflicts
BrendanParmer Jan 22, 2024
af1711f
feat: node settings now have version numbers
BrendanParmer Jan 23, 2024
20b8a98
Merge pull request #84 from BrendanParmer/SettingVersions
BrendanParmer Jan 28, 2024
8c6968f
docs: update README for v3.0, code comments
BrendanParmer Jan 28, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
feat: add most compositor node settings
  • Loading branch information
BrendanParmer committed Aug 6, 2023
commit cffd9aed8140613d9f2cb8d39f48e65628a97071
194 changes: 163 additions & 31 deletions compositor.py
Original file line number Diff line number Diff line change
@@ -5,14 +5,140 @@
from io import StringIO

node_settings = {
#Input
'CompositorNodeBokehImage' : ["flaps", "angle", "rounding", "catadioptric",
"shift"],
'CompositorNodeImage' : [], #TODO: handle image selection
'CompositorNodeMask' : ["use_feather", "size_source", "size_x", "size_y",
"use_motion_blur",
"motion_blur_samples", "motion_blur_shutter"], #TODO: handle mask selection
'CompositorNodeMovieClip' : [], #TODO: handle movie clip selection
'CompositorNodeRLayers' : ["name", "layer"],
'CompositorNodeRGB' : [], #should be handled by outputs
'CompositorNodeSceneTime' : [], #should be good
'CompositorNodeTexture' : [], #TODO: handle texture selection
'CompositorNodeTime' : ["frame_start", "frame_end"],
'CompositorNodeTrackPos' : [], #TODO: handle movie selection
'CompositorNodeValue' : [], #should be handled by outputs (why is this a separate class??)

#Output
'CompositorNodeComposite' : ["use_alpha"],
'CompositorNodeOutputFile' : ["base_path"], #TODO: doesn't seem portable
'CompositorNodeLevels' : ["channel"],
'CompositorNodeSplitViewer' : ["axis", "factor"],
'CompositorNodeViewer' : ["use_alpha"],

#Color
'CompositorNodeAlphaOver' : ["use_premultiply", "premul"],
'CompositorNodeBrightContrast' : ["use_premultiply"],
'CompositorNodeColorBalance' : ["correction_method", "lift", "gamma",
"gain", "offset", "power", "slope",
"offset_basis"],
'CompositorNodeColorCorrection' : ["red", "green", "blue",
"master_saturation", "master_contrast",
"master_gamma", "master_gain",
"master_lift",
"highlights_saturation", "highlights_contrast",
"highlights_gamma", "highlights_gain",
"highlights_lift",
"midtones_saturation", "midtones_contrast",
"midtones_gamma", "midtones_gain",
"midtones_lift",
"shadows_saturation", "shadows_contrast",
"shadows_gamma", "shadows_gain",
"shadows_lift",
"midtones_start", "midtones_end"],
'CompositorNodeExposure' : [],
'CompositorNodeGamma' : [],
'CompositorNodeHueCorrect' : [],
'CompositorNodeHueSat' : [],
'CompositorNodeInvert' : ["invert_rgb", "invert_alpha"],
'CompositorNodeMixRGB' : ["blend_type", "use_alpha", "use_clamp"], #TODO: has an update() method, may need to figure out why...
'CompositorNodePosterize' : [],
'CompositorNodeCurveRGB' : [],
'CompositorNodeTonemap' : ["tonemap_type", "intensity", "contrast", "adaptation", "correction", "key", "offset", "gamma"],
'CompositorNodeZcombine' : ["use_alpha", "use_antialias_z"],

#Converter
'CompositorNodePremulKey' : ["mapping"],
'CompositorNodeValToRGB' : [], #TODO: check to see if this'll work out of the box
'CompositorNodeConvertColorSpace' : ["from_color_space", "to_color_space"],
'CompositorNodeCombineColor' : ["mode", "ycc_mode"], #why isn't this standardized across blender?
'CompositorNodeCombineXYZ' : [],
'CompositorNodeIDMask' : ["index", "use_antialiasing"],
'CompositorNodeMath' : ["operation", "use_clamp"],
'CompositorNodeRGBToBW' : [],
'CompositorNodeSeparateColor' : ["mode", "ycc_mode"],
'CompositorNodeSeparateXYZ' : [],
'CompositorNodeSetAlpha' : ["mode"],
'CompositorNodeSwitchView' : [],

#Filter
'CompositorNodeAntiAliasing' : ["threshold", "contrast_limit", "corner_rounding"],
'CompositorNodeBilateralblur' : ["iterations", "sigma_color", "sigma_space"],
'CompositorNodeBlur' : ["filter_type", "use_variable_size", "use_gamma_correction", "use_relative", "aspect_correction", "factor", "factor_x", "factor_y", "use_extended_bounds"],
'CompositorNodeBokehBlur' : ["use_variable_size", "blur_max", "use_extended_bounds"],
'CompositorNodeDefocus' : ["bokeh", "angle", "use_gamma_correction", "f_stop", "blur_max", "threshold", "use_preview", "use_zbuffer", "z_scale"],
'CompositorNodeDespeckle' : ["threshold", "threshold_neighbor"],
'CompositorNodeDilateErode' : ["mode", "distance", "edge", "falloff"],
'CompositorNodeDBlur' : ["iterations", "center_x", "center_y", "distance", "angle", "spin", "zoom"],
'CompositorNodeFilter' : ["filter_type"],
'CompositorNodeGlare' : ["glare_type", "quality", "iterations", "color_modulation", "mix", "threshold", "streaks", "angle_offset", "fade", "size", "use_rotate_45"],
'CompositorNodeInpaint' : ["distance"],
'CompositorNodePixelate' : [],
'CompositorNodeSunBeams' : ["source", "ray_length"], #TODO: check that source doesn't freak out
'CompositorNodeVecBlur' : ["samples", "factor", "speed_min", "speed_max", "use_curved"],

#Vector
'CompositorNodeMapRange' : ["use_clamp"],
'CompositorNodeMapValue' : ["offset", "size", "use_min", "min", "use_max", "max"], #why are all these vectors?? TODO: check to make sure it doesn't flip
'CompositorNodeNormal' : [], #should be handled with io system
'CompositorNodeNormalize' : [],
'CompositorNodeCurveVec' : [],

#Matte
'CompositorNodeBoxMask' : ["x", "y", "width", "height", "rotation", "mask_type"],
'CompositorNodeChannelMatte' : ["color_space", "matte_channel", "limit_method", "limit_channel", "limit_max", "limit_min"],
'CompositorNodeChromaMatte' : ["tolerance", "threshold", "gain"],
'CompositorNodeColorMatte' : ["color_hue", "color_saturation", "color_value"],
'CompositorNodeColorSpill' : ["channel", "limit_method", "ratio", "use_unspill", "unspill_red", "unspill_green", "unspill_blue"],
'CompositorNodeCryptomatteV2' : ["source"], #TODO: will need a lot of special handling
'CompositorNodeCryptomatte' : [], #TODO: will likely need same handling as above
'CompositorNodeDiffMatte' : ["tolerance", "falloff"],
'CompositorNodeDistanceMatte' : ["tolerance", "falloff", "channel"],
'CompositorNodeDoubleEdgeMask' : ["inner_mode", "edge_mode"],
'CompositorNodeEllipseMask' : ["x", "y", "width", "height", "rotation", "mask_type"],
'CompositorNodeKeying' : ["blur_pre", "screen_balance", "despill_factor", "despill_balance", "edge_kernel_radius", "edge_kernel_tolerance", "clip_black", "clip_white", "dilate_distance", "feather_falloff", "feather_distance", "blur_post"],
'CompositorNodeKeyingScreen' : [], #TODO: movie stuff
'CompositorNodeLumaMatte' : ["limit_max", "limit_min"],

#Distort
'CompositorNodeCornerPin' : [],
'CompositorNodeCrop' : ["use_crop_size", "relative", "min_x", "max_x", "min_y", "max_y", "rel_min_x", "rel_max_x", "rel_min_y", "rel_max_y"],
'CompositorNodeDisplace' : [],
'CompositorNodeFlip' : ["axis"],
'CompositorNodeLensdist' : ["use_projector", "use_jitter", "use_fit"],
'CompositorNodeMapUV' : ["alpha"],
'CompositorNodeMovieDistortion' : [], #TODO: movie stuff
'CompositorNodePlaneTrackDeform' : ["use_motion_blur", "motion_blur_samples", "motion_blur_shutter"], #TODO: movie stuff
'CompositorNodeRotate' : ["filter_type"],
'CompositorNodeScale' : ["space", "frame_method", "offset_x", "offset_y"],
'CompositorNodeStablize' : [], #TODO: movie stuff
'CompositorNodeTransform' : ["filter_type"],
'CompositorNodeTranslate' : ["use_relative", "wrapping"],

#Layout
'CompositorNodeSwitch' : ["check"]
}

curve_nodes = {'ShaderNodeFloatCurve',
'ShaderNodeVectorCurve',
'ShaderNodeRGBCurve'}
curve_nodes = {
'CompositorNodeTime', #TODO: check this works
'CompositorNodeHueCorrect', #TODO: probbably will need custom work
'CompositorNodeCurveRGB', #may just work out of the box
'CompositorNodeCurveVec', #may just work out of the box
}

image_nodes = {'ShaderNodeTexEnvironment',
'ShaderNodeTexImage'}
image_nodes = {'CompositorNodeImage',}

class NTPCompositorOperator(bpy.types.Operator):
bl_idname = "node.compositor_to_python"
@@ -33,14 +159,19 @@ class NTPCompositorOperator(bpy.types.Operator):
def execute(self, context):
"""
#find node group to replicate
nt = bpy.data.materials[self.material_name].node_tree
if self.is_scene:
nt = bpy.data.scenes[self.compositor_name].node_tree
else:
nt = bpy.data.node_groups[self.compositor_name]
if nt is None:
#shouldn't happen
self.report({'ERROR'},("NodeToPython: This doesn't seem to be a "
"valid material. Is Use Nodes selected?"))
"valid compositor node tree. Is Use Nodes "
"selected?"))
return {'CANCELLED'}

#set up names to use in generated addon
mat_var = clean_string(self.material_name)
comp_var = clean_string(self.compositor_name)

if self.mode == 'ADDON':
dir = bpy.path.abspath(context.scene.ntp_options.dir_path)
@@ -50,29 +181,30 @@ def execute(self, context):
"NodeToPython!"))
return {'CANCELLED'}

zip_dir = os.path.join(dir, mat_var)
addon_dir = os.path.join(zip_dir, mat_var)
zip_dir = os.path.join(dir, comp_var)
addon_dir = os.path.join(zip_dir, comp_var)
if not os.path.exists(addon_dir):
os.makedirs(addon_dir)
file = open(f"{addon_dir}/__init__.py", "w")

create_header(file, self.material_name)
class_name = clean_string(self.material_name, lower=False)
init_operator(file, class_name, mat_var, self.material_name)
create_header(file, self.compositor_name)
class_name = clean_string(self.compositor_name, lower=False)
init_operator(file, class_name, comp_var, self.compositor_name)

file.write("\tdef execute(self, context):\n")
else:
file = StringIO("")

def create_material(indent: str):
file.write((f"{indent}mat = bpy.data.materials.new("
f"name = {str_to_py_str(self.material_name)})\n"))
file.write(f"{indent}mat.use_nodes = True\n")

if self.mode == 'ADDON':
create_material("\t\t")
elif self.mode == 'SCRIPT':
create_material("")
if self.is_scene:
def create_scene(indent: str):
file.write((f"{indent}scene = bpy.data.scenes.new(" #TODO: see if using scene as name effects nodes named scene
f"name = {str_to_py_str(self.compositor_name)})\n"))
file.write(f"{indent}scene.use_nodes = True\n")

if self.mode == 'ADDON':
create_scene("\t\t")
elif self.mode == 'SCRIPT':
create_scene("")

#set to keep track of already created node trees
node_trees = set()
@@ -90,10 +222,10 @@ def is_outermost_node_group(level: int) -> bool:
return True
return False

def process_mat_node_group(node_tree, level, node_vars, used_vars):
def process_comp_node_group(node_tree, level, node_vars, used_vars):
if is_outermost_node_group(level):
nt_var = create_var(self.material_name, used_vars)
nt_name = self.material_name
nt_var = create_var(self.compositor_name, used_vars)
nt_name = self.compositor_name
else:
nt_var = create_var(node_tree.name, used_vars)
nt_name = node_tree.name
@@ -105,14 +237,14 @@ def process_mat_node_group(node_tree, level, node_vars, used_vars):
file.write(f"{outer}def {nt_var}_node_group():\n")

if is_outermost_node_group(level): #outermost node group
file.write(f"{inner}{nt_var} = mat.node_tree\n")
file.write(f"{inner}{nt_var} = scene.node_tree\n")
file.write(f"{inner}#start with a clean node tree\n")
file.write(f"{inner}for node in {nt_var}.nodes:\n")
file.write(f"{inner}\t{nt_var}.nodes.remove(node)\n")
else:
file.write((f"{inner}{nt_var}"
f"= bpy.data.node_groups.new("
f"type = \'ShaderNodeTree\', "
f"type = \'CompositorNodeTree\', "
f"name = {str_to_py_str(nt_name)})\n"))
file.write("\n")

@@ -126,10 +258,10 @@ def process_mat_node_group(node_tree, level, node_vars, used_vars):
node_vars = {}

for node in node_tree.nodes:
if node.bl_idname == 'ShaderNodeGroup':
if node.bl_idname == 'CompositorNodeGroup':
node_nt = node.node_tree
if node_nt is not None and node_nt not in node_trees:
process_mat_node_group(node_nt, level + 1, node_vars,
process_comp_node_group(node_nt, level + 1, node_vars,
used_vars)
node_trees.add(node_nt)

@@ -139,7 +271,7 @@ def process_mat_node_group(node_tree, level, node_vars, used_vars):
set_settings_defaults(node, node_settings, file, inner, node_var)
hide_sockets(node, file, inner, node_var)

if node.bl_idname == 'ShaderNodeGroup':
if node.bl_idname == 'CompositorNodeGroup':
if node.node_tree is not None:
file.write((f"{inner}{node_var}.node_tree = "
f"bpy.data.node_groups"
@@ -183,7 +315,7 @@ def process_mat_node_group(node_tree, level, node_vars, used_vars):
level = 2
else:
level = 0
process_mat_node_group(nt, level, node_vars, used_vars)
process_comp_node_group(nt, level, node_vars, used_vars)

if self.mode == 'ADDON':
file.write("\t\treturn {'FINISHED'}\n\n")
6 changes: 3 additions & 3 deletions materials.py
Original file line number Diff line number Diff line change
@@ -125,7 +125,7 @@ def execute(self, context):
file = StringIO("")

def create_material(indent: str):
file.write((f"{indent}mat = bpy.data.materials.new("
file.write((f"{indent}mat = bpy.data.materials.new(" #TODO: see if using mat effects nodes named mat
f"name = {str_to_py_str(self.material_name)})\n"))
file.write(f"{indent}mat.use_nodes = True\n")

@@ -282,7 +282,7 @@ def poll(cls, context):
def draw(self, context):
layout = self.layout.column_flow(columns=1)
layout.operator_context = 'INVOKE_DEFAULT'
for mat in bpy.data.materials:
for mat in bpy.data.materials: #TODO: filter by node tree exists
op = layout.operator(NTPMaterialOperator.bl_idname, text=mat.name)
op.material_name = mat.name

@@ -306,7 +306,7 @@ def draw(self, context):
row = layout.row()

# Disables menu when there are no materials
materials = bpy.data.materials
materials = bpy.data.materials #TODO: filter by node tree exist
materials_exist = len(materials) > 0
row.enabled = materials_exist