Skip to content

Commit

Permalink
new chameleon socket type
Browse files Browse the repository at this point in the history
  • Loading branch information
Durman committed Jan 7, 2020
1 parent f91d940 commit 7aceff7
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 26 deletions.
58 changes: 45 additions & 13 deletions core/sockets.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,6 @@ class SvSocketCommon:
expanded: 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")
sv_is_linked: BoolProperty(description="Socket is linked if (socket.is_linked or socket.sv_is_linked). "
"`Sv_is_linked` should be set manually. "
"Useful for socket created dynamically during update event.")

quicklink_func_name: StringProperty(default="", name="quicklink_func_name")

Expand Down Expand Up @@ -285,7 +282,7 @@ def draw(self, context, layout, node, text):
layout.label(text=text)

def sv_get(self, default=sentinel, deepcopy=True, implicit_conversions=None):
if (self.is_linked or self.sv_is_linked) and not self.is_output:
if self.is_linked and not self.is_output:
return self.convert_data(SvGetSocket(self, deepcopy), implicit_conversions)
elif self.object_ref:
obj_ref = bpy.data.objects.get(self.object_ref)
Expand Down Expand Up @@ -313,7 +310,7 @@ def draw_color(self, context, node):
return (0.68, 0.85, 0.90, 1)

def sv_get(self, default=sentinel, deepcopy=True, implicit_conversions=None):
if (self.is_linked or self.sv_is_linked) and not self.is_output:
if self.is_linked and not self.is_output:
return self.convert_data(SvGetSocket(self, deepcopy), implicit_conversions)
elif self.text:
return [self.text]
Expand Down Expand Up @@ -344,7 +341,7 @@ def get_prop_data(self):

def sv_get(self, default=sentinel, deepcopy=True, implicit_conversions=None):
self.num_matrices = 0
if (self.is_linked or self.sv_is_linked) and not self.is_output:
if self.is_linked and not self.is_output:
source_data = SvGetSocket(self, deepcopy = True if self.needs_data_conversion() else deepcopy)
return self.convert_data(source_data, implicit_conversions)

Expand Down Expand Up @@ -372,7 +369,7 @@ def get_prop_data(self):
return {}

def sv_get(self, default=sentinel, deepcopy=True, implicit_conversions=None):
if (self.is_linked or self.sv_is_linked) and not self.is_output:
if self.is_linked and not self.is_output:
source_data = SvGetSocket(self, deepcopy = True if self.needs_data_conversion() else deepcopy)
return self.convert_data(source_data, implicit_conversions)

Expand Down Expand Up @@ -404,7 +401,7 @@ def get_prop_data(self):
return {}

def sv_get(self, default=sentinel, deepcopy=True, implicit_conversions=None):
if (self.is_linked or self.sv_is_linked) and not self.is_output:
if self.is_linked and not self.is_output:
source_data = SvGetSocket(self, deepcopy = True if self.needs_data_conversion() else deepcopy)
return self.convert_data(source_data, implicit_conversions)

Expand Down Expand Up @@ -436,7 +433,7 @@ def get_prop_data(self):
return {}

def sv_get(self, default=sentinel, deepcopy=True, implicit_conversions=None):
if (self.is_linked or self.sv_is_linked) and not self.is_output:
if self.is_linked and not self.is_output:
return self.convert_data(SvGetSocket(self, deepcopy), implicit_conversions)

if self.prop_name:
Expand All @@ -461,7 +458,7 @@ def get_prop_data(self):
return self.other.get_prop_data()

def sv_get(self):
if (self.sv_linked or self.sv_is_linked):
if self.sv_linked:
return self.links[0].bl_idname

def sv_type_conversion(self, new_self):
Expand Down Expand Up @@ -503,7 +500,7 @@ def sv_get(self, default=sentinel, deepcopy=True, implicit_conversions=None):
# debug("Node %s, socket %s, is_linked: %s, is_output: %s",
# self.node.name, self.name, self.is_linked, self.is_output)

if (self.is_linked or self.sv_is_linked) and not self.is_output:
if self.is_linked and not self.is_output:
return self.convert_data(SvGetSocket(self, deepcopy), implicit_conversions)
elif self.prop_name:
# to deal with subtype ANGLE, this solution should be considered temporary...
Expand Down Expand Up @@ -532,7 +529,7 @@ def get_prop_data(self):
return {}

def sv_get(self, default=sentinel, deepcopy=True, implicit_conversions=None):
if (self.is_linked or self.sv_is_linked) and not self.is_output:
if self.is_linked and not self.is_output:
source_data = SvGetSocket(self, deepcopy=True if self.needs_data_conversion() else deepcopy)
return self.convert_data(source_data, implicit_conversions)

Expand All @@ -544,6 +541,41 @@ def sv_get(self, default=sentinel, deepcopy=True, implicit_conversions=None):
return default


class SvChameleonSocket(NodeSocket, SvSocketCommon):
'''Using as input socket with color of other connected socket'''
bl_idname = "SvChameleonSocket"
bl_label = "Chameleon Socket"

dynamic_color: FloatVectorProperty(default=(0.0, 0.0, 0.0, 0.0), size=4)

def get_prop_data(self):
if self.prop_name:
return {"prop_name": self.prop_name}
else:
return {}

def sv_get(self, default=sentinel, deepcopy=True):
if self.is_linked and not self.is_output:
return SvGetSocket(self, deepcopy=True if self.needs_data_conversion() else deepcopy)

if self.prop_name:
return [[getattr(self.node, self.prop_name)[:]]]
elif default is sentinel:
raise SvNoDataError(self)
else:
return default

def set_color(self):
other = self.other
if other:
self.dynamic_color = socket_colors[other.bl_idname]
else:
self.dynamic_color = (0.0, 0.0, 0.0, 0.0)

def draw_color(self, context, node):
return self.dynamic_color


"""
type_map_to/from are used to get the bl_idname from a single letter
Expand Down Expand Up @@ -573,7 +605,7 @@ def sv_get(self, default=sentinel, deepcopy=True, implicit_conversions=None):
classes = [
SvVerticesSocket, SvMatrixSocket, SvStringsSocket,
SvColorSocket, SvQuaternionSocket, SvDummySocket, SvSeparatorSocket,
SvTextSocket, SvObjectSocket, SvDictionarySocket
SvTextSocket, SvObjectSocket, SvDictionarySocket, SvChameleonSocket
]

register, unregister = bpy.utils.register_classes_factory(classes)
22 changes: 9 additions & 13 deletions nodes/dictionary/dictionary_in.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,28 +93,24 @@ def down_item(self, context):
key_9: bpy.props.StringProperty(name="", default='Key 10', update=update_node)

def sv_init(self, context):
self.inputs.new('SvSeparatorSocket', 'Empty')
self.inputs.new('SvChameleonSocket', 'Data')
self.outputs.new('SvDictionarySocket', 'Dict')
self['update_event'] = False # if True the node does not update upon properties changes

def update(self):
# Remove unused sockets
[self.inputs.remove(sock) for sock in list(self.inputs)[:-1] if not sock.is_linked]
[sock.set_color() for sock in self.inputs if sock.links]

# add property to new socket and add extra empty socket
free_keys = self.keys - set(sock.prop_name for sock in list(self.inputs)[:-1])
if list(self.inputs)[-1].is_linked and len(self.inputs) < 11:
socket_from = self.inputs[-1].other
self.inputs.remove(list(self.inputs)[-1])
re_socket = self.inputs.new(socket_from.bl_idname, 'Data')
re_socket.sv_is_linked = True
re_socket.prop_name = free_keys.pop()
re_socket.custom_draw = 'draw_socket'
re_link = self.id_data.links.new(socket_from, re_socket)
re_link.is_valid = True
self.inputs.new('SvSeparatorSocket', 'Empty')
free_keys = self.keys - set(sock.prop_name for sock in list(self.inputs)[:-1])
last_sock = list(self.inputs)[-1]
last_sock.prop_name = free_keys.pop()
last_sock.custom_draw = 'draw_socket'
self.inputs.new('SvChameleonSocket', 'Data')
self['update_event'] = True
setattr(self, re_socket.prop_name, re_socket.other.name)
setattr(self, last_sock.prop_name, last_sock.other.name)
self['update_event'] = False

def draw_socket(self, socket, context, layout):
Expand Down Expand Up @@ -154,7 +150,7 @@ def process(self):
out_dict = SvDict({getattr(self, key): prop for key, prop in zip(keys, props) if prop is not None})
for sock in list(self.inputs)[:-1]:
out_dict.inputs[sock.identifier] = {
'type': sock.bl_idname,
'type': sock.other.bl_idname,
'name': getattr(self, sock.prop_name),
'nest': sock.sv_get()[0].inputs if sock.bl_idname == 'SvDictionarySocket' else None}
out.append(out_dict)
Expand Down

0 comments on commit 7aceff7

Please sign in to comment.