Skip to content

Commit

Permalink
Merge pull request #4118 from nortikin/node_groups_to_json
Browse files Browse the repository at this point in the history
New structure for JSON files and new approach of adding changes into the JSON format
  • Loading branch information
Durman authored Jun 7, 2021
2 parents a2b5b0c + c3bbde8 commit 2c1026c
Show file tree
Hide file tree
Showing 34 changed files with 1,368 additions and 6,013 deletions.
2 changes: 1 addition & 1 deletion core/monad.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ def monad_make_unique(node):

# the new tree dict will contain information about 1 node only, and
# the node_group too (at the moment) but the node_group data can be ignored.
layout_json = JSONExporter.get_nodes_structure([node])
layout_json = JSONExporter._get_nodes_structure([node])

# do not restore links this way. wipe this entry and restore at a later stage.
layout_json['update_lists'] = []
Expand Down
38 changes: 34 additions & 4 deletions core/node_group.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,17 @@ class SvGroupTree(bpy.types.NodeTree):

handler = MainHandler

group_node_name: bpy.props.StringProperty() # should be updated by "Go to edit group tree" operator
tree_id_memory: bpy.props.StringProperty(default="") # identifier of the tree, should be used via `tree_id`
skip_tree_update: bpy.props.BoolProperty() # useless for API consistency # todo should be removed later
# should be updated by "Go to edit group tree" operator
group_node_name: bpy.props.StringProperty(options={'SKIP_SAVE'})

# identifier of the tree, should be used via `tree_id`
tree_id_memory: bpy.props.StringProperty(default="", options={'SKIP_SAVE'})

# useless for API consistency # todo should be removed later
skip_tree_update: bpy.props.BoolProperty(options={'SKIP_SAVE'})

# Always False, does not have sense to have for nested trees, sine of draft mode refactoring
sv_draft: bpy.props.BoolProperty()
sv_draft: bpy.props.BoolProperty(options={'SKIP_SAVE'})

@property
def tree_id(self):
Expand Down Expand Up @@ -95,6 +100,9 @@ def can_be_linked(self):
def update(self):
"""trigger on links or nodes collections changes, on assigning tree to a group node"""
# When group input or output nodes are connected some extra work should be done
if 'init_tree' in self.id_data: # tree is building by a script - let it do this
return

self.check_last_socket() # Should not be too expensive to call it each update

if self.name not in bpy.data.node_groups: # load new file event
Expand Down Expand Up @@ -197,6 +205,11 @@ def update_nodes(self, nodes: list):
1. Node property of was changed
2. ???
"""
# the method can be called during tree reconstruction from JSON file
# in this case we does not intend doing any updates
if not self.group_node_name: # initialization tree
return

self.handler.send(GroupEvent(GroupEvent.NODES_UPDATE, self.get_update_path(), updated_nodes=nodes))

def parent_nodes(self) -> Iterator['SvGroupTreeNode']:
Expand Down Expand Up @@ -240,6 +253,20 @@ def throttle_update(self):
"""useless, for API consistency here"""
yield self

@contextmanager
def init_tree(self):
"""It suppresses calling the update method of nodes,
main usage of it is during generating tree with python (JSON import)"""
is_already_initializing = 'init_tree' in self
if is_already_initializing:
yield self
else:
self['init_tree'] = ''
try:
yield self
finally:
del self['init_tree']

def get_update_path(self) -> List['SvGroupTreeNode']:
"""
Should be called only during tree or node update events
Expand Down Expand Up @@ -416,6 +443,9 @@ def active_input(self) -> Optional[bpy.types.Node]:
return node

def update(self):
if 'init_tree' in self.id_data: # tree is building by a script - let it do this
return

# this code should work only first time a socket was added
if self.node_tree:
for n_in_s, t_in_s in zip(self.inputs, self.node_tree.inputs):
Expand Down
21 changes: 11 additions & 10 deletions core/sockets.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,16 @@

def process_from_socket(self, context):
"""Update function of exposed properties in Sockets"""
self.node.process_node(context)
if self.node is not None: # https://developer.blender.org/T88587
self.node.process_node(context)


def update_interface(self, context):
"""Update group node sockets and update it"""
# For now I don't think that `hide value` property should call this function, but in some cases it could be useful
# if interface socket will get min and max value parameter then probably Sv sockets also should get it
if not self.id_data.group_node_name: # initialization tree
return
self.id_data.update_sockets()
group_tree = self.id_data
group_node = group_tree.get_update_path()[-1]
Expand Down Expand Up @@ -313,15 +316,13 @@ class SvSocketCommon(SvSocketProcessing):
color = (1, 0, 0, 1) # base color, other sockets should override the property, use FloatProperty for dynamic
label: StringProperty() # It will be drawn instead of name if given
quick_link_to_node = str() # sockets which often used with other nodes can fill its `bl_idname` here
link_menu_handler : StringProperty(default='', options={'SKIP_SAVE'}) # To specify additional entries in the socket link menu
enable_input_link_menu : BoolProperty(default = True, options={'SKIP_SAVE'})
link_menu_handler : StringProperty(default='') # To specify additional entries in the socket link menu
enable_input_link_menu : BoolProperty(default = True)

# set True to use default socket property if it has got it
use_prop: BoolProperty(default=False, options={'SKIP_SAVE'})
custom_draw: StringProperty(description="For name of method which will draw socket UI (optionally)",
options={'SKIP_SAVE'})
prop_name: StringProperty(default='', description="For displaying node property in socket UI",
options={'SKIP_SAVE'})
use_prop: BoolProperty(default=False)
custom_draw: StringProperty(description="For name of method which will draw socket UI (optionally)")
prop_name: StringProperty(default='', description="For displaying node property in socket UI")

# utility field for showing number of objects in sockets data
objects_number: IntProperty(min=0, options={'SKIP_SAVE'})
Expand Down Expand Up @@ -598,7 +599,7 @@ def filter_kinds(self, objs):
return True

color = (0.69, 0.74, 0.73, 1.0)
use_prop: BoolProperty(default=True, options={'SKIP_SAVE'})
use_prop: BoolProperty(default=True)

object_kinds: StringProperty(default='ALL') # use for filtering objects, see filter_kinds method
object_ref: StringProperty(update=process_from_socket)
Expand Down Expand Up @@ -894,7 +895,7 @@ def get_prop_data(self):
else:
return {}

quick_link_to_node: StringProperty(options={'SKIP_SAVE'}) # this can be overridden by socket instances
quick_link_to_node: StringProperty() # this can be overridden by socket instances

default_property_type: bpy.props.EnumProperty(items=[(i, i, '') for i in ['float', 'int']])
default_float_property: bpy.props.FloatProperty(update=process_from_socket)
Expand Down
Loading

0 comments on commit 2c1026c

Please sign in to comment.