schema_definitions.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324
  1. import bpy
  2. from .base_definitions import SchemaNode
  3. from bpy.types import Node
  4. from .utilities import (prRed, prGreen, prPurple, prWhite,
  5. prOrange,
  6. wrapRed, wrapGreen, wrapPurple, wrapWhite,
  7. wrapOrange,)
  8. from bpy.props import BoolProperty
  9. from .utilities import get_socket_maps, relink_socket_map, do_relink
  10. def TellClasses():
  11. return [
  12. # tree i/o
  13. SchemaIndex,
  14. SchemaArrayInput,
  15. SchemaArrayInputGet,
  16. SchemaArrayOutput,
  17. SchemaConstInput,
  18. SchemaConstOutput,
  19. SchemaOutgoingConnection,
  20. SchemaIncomingConnection,
  21. # # iterators
  22. # SchemaIntMath,
  23. # SchemaDeclarationValidWhen,
  24. ]
  25. # IMPORTANT TODO:
  26. # - check what happens when these get plugged into each other
  27. # - probably disallow all or most of these connections in insert_link or update
  28. class SchemaIndex(Node, SchemaNode):
  29. '''The current index of the schema execution'''
  30. bl_idname = 'SchemaIndex'
  31. bl_label = "Index"
  32. bl_icon = 'GIZMO'
  33. initialized : bpy.props.BoolProperty(default = False)
  34. def init(self, context):
  35. self.outputs.new("IntSocket", "Index")
  36. self.outputs.new("IntSocket", "Schema Length")
  37. self.initialized = True
  38. class SchemaArrayInput(Node, SchemaNode):
  39. '''Array Inputs'''
  40. bl_idname = 'SchemaArrayInput'
  41. bl_label = "Array Input"
  42. bl_icon = 'GIZMO'
  43. initialized : bpy.props.BoolProperty(default = False)
  44. def init(self, context):
  45. self.update()
  46. def update(self):
  47. # self.initialized = False
  48. output_map = get_socket_maps(self)[1]
  49. self.outputs.clear()
  50. for item in self.id_data.interface.items_tree:
  51. if item.item_type == 'PANEL': continue
  52. if item.parent and item.in_out == 'INPUT' and item.parent.name == 'Array':
  53. relink_socket_map(self, self.outputs, output_map, item, in_out='OUTPUT')
  54. if '__extend__' in output_map.keys() and output_map['__extend__']:
  55. do_relink(self, None, output_map, in_out='OUTPUT', parent_name='Array' )
  56. if len(self.inputs)<1 or self.inputs[-1].bl_idname not in ["WildcardSocket"]:
  57. self.outputs.new('WildcardSocket', '', identifier='__extend__')
  58. # self.initialized = True
  59. class SchemaArrayInputGet(Node, SchemaNode):
  60. '''Array Inputs'''
  61. bl_idname = 'SchemaArrayInputGet'
  62. bl_label = "Array Input at Index"
  63. bl_icon = 'GIZMO'
  64. initialized : bpy.props.BoolProperty(default = False)
  65. def init(self, context):
  66. self.inputs.new('EnumArrayGetOptions', 'OoB Behaviour')
  67. self.inputs.new("IntSocket", "Index")
  68. self.update()
  69. def update(self):
  70. # self.initialized = False
  71. output_map = get_socket_maps(self)[1]
  72. self.outputs.clear()
  73. for item in self.id_data.interface.items_tree:
  74. if item.item_type == 'PANEL': continue
  75. if item.parent and item.in_out == 'INPUT' and item.parent.name == 'Array':
  76. relink_socket_map(self, self.outputs, output_map, item, in_out='OUTPUT')
  77. if '__extend__' in output_map.keys() and output_map['__extend__']:
  78. do_relink(self, None, output_map, in_out='OUTPUT', parent_name='Array' )
  79. if len(self.inputs)<1 or self.inputs[-1].bl_idname not in ["WildcardSocket"]:
  80. self.outputs.new('WildcardSocket', '', identifier='__extend__')
  81. # self.initialized = True
  82. class SchemaArrayOutput(Node, SchemaNode):
  83. '''Array Inputs'''
  84. bl_idname = 'SchemaArrayOutput'
  85. bl_label = "Array Output"
  86. bl_icon = 'GIZMO'
  87. initialized : bpy.props.BoolProperty(default = False)
  88. def init(self, context):
  89. self.update()
  90. def update(self):
  91. self.initialized = False
  92. input_map = get_socket_maps(self)[0]
  93. self.inputs.clear()
  94. for item in self.id_data.interface.items_tree:
  95. if item.item_type == 'PANEL': continue
  96. if item.parent and item.in_out == 'OUTPUT' and item.parent.name == 'Array':
  97. relink_socket_map(self, self.inputs, input_map, item, in_out='INPUT')
  98. if '__extend__' in input_map.keys() and input_map['__extend__']:
  99. do_relink(self, None, input_map, in_out='INPUT', parent_name='Array' )
  100. if len(self.inputs)<1 or self.inputs[-1].bl_idname not in ["WildcardSocket"]:
  101. self.inputs.new('WildcardSocket', '', identifier='__extend__')
  102. for s in self.outputs:
  103. s.input= True
  104. self.initialized = True
  105. class SchemaConstInput(Node, SchemaNode):
  106. '''Constant Inputs'''
  107. bl_idname = 'SchemaConstInput'
  108. bl_label = "Constant Input"
  109. bl_icon = 'GIZMO'
  110. initialized : bpy.props.BoolProperty(default = False)
  111. def init(self, context):
  112. self.update()
  113. def update(self):
  114. self.initialized = False
  115. output_map = get_socket_maps(self)[1]
  116. self.outputs.clear()
  117. for item in self.id_data.interface.items_tree:
  118. if item.item_type == 'PANEL': continue
  119. if item.parent and item.in_out == 'INPUT' and item.parent.name == 'Constant':
  120. relink_socket_map(self, self.outputs, output_map, item, in_out='OUTPUT')
  121. if '__extend__' in output_map.keys() and output_map['__extend__']:
  122. do_relink(self, None, output_map, in_out='OUTPUT', parent_name='Constant' )
  123. if len(self.inputs)<1 or self.inputs[-1].bl_idname not in ["WildcardSocket"]:
  124. self.outputs.new('WildcardSocket', '', identifier='__extend__')
  125. self.initialized = True
  126. class SchemaConstOutput(Node, SchemaNode):
  127. '''Constant Outputs'''
  128. bl_idname = 'SchemaConstOutput'
  129. bl_label = "Constant Output"
  130. bl_icon = 'GIZMO'
  131. initialized : bpy.props.BoolProperty(default = False)
  132. def init(self, context):
  133. self.update()
  134. def update(self):
  135. self.initialized = False
  136. input_map = get_socket_maps(self)[0]
  137. self.inputs.clear()
  138. s = self.inputs.new('IntSocket', "Expose when N==")
  139. for item in self.id_data.interface.items_tree:
  140. if item.item_type == 'PANEL': continue
  141. if item.parent and item.in_out == 'OUTPUT' and item.parent.name == 'Constant':
  142. relink_socket_map(self, self.inputs, input_map, item, in_out='INPUT')
  143. if '__extend__' in input_map.keys() and input_map['__extend__']:
  144. do_relink(self, None, input_map, in_out='INPUT', parent_name='Constant' )
  145. if len(self.inputs)<1 or self.inputs[-1].bl_idname not in ["WildcardSocket"]:
  146. self.inputs.new('WildcardSocket', '', identifier='__extend__')
  147. do_relink(self, s, input_map, in_out='INPUT')
  148. for s in self.outputs:
  149. s.input= True
  150. self.initialized = True
  151. class SchemaOutgoingConnection(Node, SchemaNode):
  152. '''Outgoing Connections'''
  153. bl_idname = 'SchemaOutgoingConnection'
  154. bl_label = "Outgoing Connection"
  155. bl_icon = 'GIZMO'
  156. initialized : bpy.props.BoolProperty(default = False)
  157. def init(self, context):
  158. # self.inputs.new('IntSocket', 'Valid From')
  159. # self.inputs.new('IntSocket', 'Valid Until')
  160. self.update()
  161. def update(self):
  162. self.initialized = False
  163. input_map = get_socket_maps(self)[0]
  164. self.inputs.clear()
  165. for item in self.id_data.interface.items_tree:
  166. if item.item_type == 'PANEL': continue
  167. if item.parent and item.in_out == 'OUTPUT' and item.parent.name == 'Connection':
  168. relink_socket_map(self, self.inputs, input_map, item, in_out='INPUT')
  169. if '__extend__' in input_map.keys() and input_map['__extend__']:
  170. do_relink(self, None, input_map, in_out='INPUT', parent_name='Connection' )
  171. if len(self.inputs)<1 or self.inputs[-1].bl_idname not in ["WildcardSocket"]:
  172. self.inputs.new('WildcardSocket', '', identifier='__extend__')
  173. for s in self.outputs:
  174. s.input= True
  175. self.initialized = True
  176. class SchemaIncomingConnection(Node, SchemaNode):
  177. '''Incoming Connections'''
  178. bl_idname = 'SchemaIncomingConnection'
  179. bl_label = "Incoming Connection"
  180. bl_icon = 'GIZMO'
  181. initialized : bpy.props.BoolProperty(default = False)
  182. def init(self, context):
  183. self.update()
  184. def update(self):
  185. self.initialized = False
  186. output_map = get_socket_maps(self)[1]
  187. self.outputs.clear()
  188. for item in self.id_data.interface.items_tree:
  189. if item.item_type == 'PANEL': continue
  190. if item.parent and item.in_out == 'INPUT' and item.parent.name == 'Connection':
  191. relink_socket_map(self, self.outputs, output_map, item, in_out='OUTPUT')
  192. if '__extend__' in output_map.keys() and output_map['__extend__']:
  193. do_relink(self, None, output_map, in_out='OUTPUT', parent_name='Connection' )
  194. if len(self.inputs)<1 or self.inputs[-1].bl_idname not in ["WildcardSocket"]:
  195. self.outputs.new('WildcardSocket', '', identifier='__extend__')
  196. self.initialized = True
  197. # have a string for name
  198. # assign/get
  199. # and a fallback if none
  200. # get should take an integer: 0 = index, -1 = index -1, etc., no positive ints allowed
  201. # class SchemaLocalVariable(Node, SchemaNode):
  202. # '''Constant Inputs'''
  203. # bl_idname = 'SchemaIncomingConnection'
  204. # bl_label = "Incoming Connection"
  205. # bl_icon = 'GIZMO'
  206. # def init(self, context):
  207. # # self.outputs.new("IntSocket", "Index")
  208. # pass
  209. # class SchemaIntMath(Node, SchemaNode):
  210. # '''Int Math'''
  211. # bl_idname = 'SchemaIntMath'
  212. # bl_label = "Int Math"
  213. # bl_icon = 'GIZMO'
  214. # # def init(self, context):
  215. # # self.update()
  216. # class SchemaDeclarationValidWhen(Node, SchemaNode):
  217. # '''Declaration Valid When'''
  218. # bl_idname = 'SchemaDeclarationValidWhen'
  219. # bl_label = "Declaration Valid When"
  220. # bl_icon = 'GIZMO'
  221. # def init(self, context):
  222. # self.inputs.new('IntSocket', 'Valid From')
  223. # self.inputs.new('IntSocket', 'Valid Until')
  224. # self.inputs.new('IntSocket', 'Add to N') # +
  225. # self.inputs.new('IntSocket', 'Multiply N') # *
  226. # self.inputs.new('IntSocket', 'Modulo of N') # %
  227. # # self.inputs.new('IntSocket', 'n')
  228. # I need to figure out what to do with this right here...
  229. # There are a few options:
  230. # - an actual control flow (if, then) -- but I don' like that because it's not declarative
  231. # - "declaration valid when" statement that is basically a range with simple math rules
  232. # - this is funcionally almost entirely the same
  233. # - perhaps this sort of range plugs into the end of the schema?
  234. # - but I want it to operate kind of like a frame or simulation zone
  235. # - Begin / End declaration makes it more like a framed region
  236. # - hypothetically I don't need to have any begin and I can just imply it
  237. # - I don't wanna have to develop a bunch of code for dealing with new links that are only there for the sake of schema
  238. # - then I ran into the problem that the in/out connections are relevant to a specific declaration
  239. # - what I need is a way to modify the declaration in the loop, not a way to construct a bunch of different iterators....
  240. # - so maybe I can get away with basic maths only
  241. # so I need a way to control a declaration by the index
  242. # - a switch node, maybe one with an arbitrary socket type like wildcard that just adapts
  243. # - it should be possible to do math with the index and len(schema)
  244. # - example, for naming a bone 'Center' if index == len(schema)//2
  245. # - the "if" is what annoys me about this
  246. # - making numbers and chiral identifiers for names
  247. # - array gets
  248. # -
  249. # class SchemaChoose(Node, SchemaNode):
  250. # '''Choose'''
  251. # bl_idname = 'SchemaChoose'
  252. # bl_label = "Choose"
  253. # bl_icon = 'GIZMO'
  254. # initialized : bpy.props.BoolProperty(default = False)
  255. # def init(self, context):
  256. # self.inputs.new('IntSocket', 'Number of Choices')
  257. # self.inputs.new('IntSocket', 'Choose Index')
  258. # self.outputs.new('WildcardSocket', 'Choice')
  259. # self.update()
  260. # def update(self):
  261. # self.initialized = False
  262. # input_map = get_socket_maps(self)[0]
  263. # # print (input_map)
  264. # self.inputs.clear()
  265. # self.inputs.new('IntSocket', 'Number of Choices')
  266. # self.inputs.new('IntSocket', 'Choose Index')
  267. # #
  268. # # update on this one requires being able to read the tree!
  269. # # self.inputs.new("WildcardSocket", "")
  270. # self.initialized = True