__init__.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. from . import ( ops_nodegroup,
  2. base_definitions,
  3. socket_definitions,
  4. link_definitions,
  5. xForm_definitions,
  6. nodes_generic,
  7. primitives_definitions,
  8. deformer_definitions,
  9. math_definitions,
  10. i_o,
  11. schema_definitions,
  12. )
  13. from .ops_generate_tree import GenerateMantisTree
  14. from bpy.types import NodeSocket
  15. from .utilities import prRed
  16. MANTIS_VERSION_MAJOR=0
  17. MANTIS_VERSION_MINOR=9
  18. MANTIS_VERSION_SUB=4
  19. classLists = [module.TellClasses() for module in [
  20. link_definitions,
  21. xForm_definitions,
  22. base_definitions,
  23. nodes_generic,
  24. socket_definitions,
  25. ops_nodegroup,
  26. primitives_definitions,
  27. deformer_definitions,
  28. math_definitions,
  29. i_o,
  30. schema_definitions,
  31. ]]
  32. classLists.append( [GenerateMantisTree] )
  33. #
  34. classes = []
  35. while (classLists):
  36. classes.extend(classLists.pop())
  37. interface_classes = []
  38. from bpy import app
  39. import nodeitems_utils
  40. from nodeitems_utils import NodeCategory, NodeItem
  41. class MantisNodeCategory(NodeCategory):
  42. @classmethod
  43. def poll(cls, context):
  44. return (context.space_data.tree_type in ['MantisTree', 'SchemaTree'])
  45. class SchemaNodeCategory(NodeCategory):
  46. @classmethod
  47. def poll(cls, context):
  48. return (context.space_data.path[len(context.space_data.path)-1].node_tree.bl_idname == 'SchemaTree')
  49. class MantisGroupCategory(NodeCategory):
  50. @classmethod
  51. def poll(cls, context):
  52. return (context.space_data.path[len(context.space_data.path)-1].node_tree.bl_idname in ['MantisTree'] and len(context.space_data.path)>1)
  53. input_category=[
  54. NodeItem("InputFloatNode"),
  55. NodeItem("InputVectorNode"),
  56. NodeItem("InputBooleanNode"),
  57. NodeItem("InputStringNode"),
  58. NodeItem("InputIntNode"),
  59. NodeItem("InputMatrixNode"),
  60. NodeItem("InputExistingGeometryObject"),
  61. NodeItem("InputExistingGeometryData"),
  62. ]
  63. link_transform_category = [
  64. NodeItem("LinkCopyLocation"),
  65. NodeItem("LinkCopyRotation"),
  66. NodeItem("LinkCopyScale"),
  67. NodeItem("LinkCopyTransforms"),
  68. NodeItem("LinkLimitLocation"),
  69. NodeItem("LinkLimitScale"),
  70. NodeItem("LinkLimitRotation"),
  71. NodeItem("LinkLimitDistance"),
  72. NodeItem("LinkTransformation"),
  73. ]
  74. link_tracking_category = [
  75. NodeItem("LinkInverseKinematics"),
  76. NodeItem("LinkSplineIK"),
  77. NodeItem("LinkStretchTo"),
  78. NodeItem("LinkDampedTrack"),
  79. NodeItem("LinkLockedTrack"),
  80. NodeItem("LinkTrackTo"),
  81. ]
  82. link_relationship_category = [
  83. NodeItem("linkInherit"),
  84. NodeItem("LinkInheritConstraint"),
  85. NodeItem("LinkArmature"),
  86. ]
  87. deformer_category=[NodeItem(cls.bl_idname) for cls in deformer_definitions.TellClasses()]
  88. xForm_category = [
  89. NodeItem("xFormGeometryObject"),
  90. NodeItem("xFormBoneNode"),
  91. NodeItem("xFormArmatureNode"),
  92. ]
  93. driver_category = [
  94. NodeItem("LinkDrivenParameter"),
  95. NodeItem("UtilityFCurve"),
  96. NodeItem("UtilityBoneProperties"),
  97. NodeItem("UtilityDriverVariable"),
  98. NodeItem("UtilitySwitch"),
  99. NodeItem("UtilityDriver"),
  100. NodeItem("UtilityKeyframe"),
  101. ]
  102. geometry_category = [
  103. NodeItem("GeometryCirclePrimitive"),
  104. ]
  105. utility_category = [
  106. NodeItem("MathStaticInt"),
  107. NodeItem("MathStaticFloat"),
  108. NodeItem("MathStaticVector"),
  109. NodeItem("UtilityCatStrings"),
  110. NodeItem("UtilityCombineThreeBool"),
  111. NodeItem("UtilityCombineVector"),
  112. NodeItem("UtilityIntToString"),
  113. NodeItem("UtilityArrayGet"),
  114. NodeItem("UtilityChoose"),
  115. NodeItem("UtilityCompare"),
  116. NodeItem("UtilityPrint"),
  117. ]
  118. matrix_category = [
  119. NodeItem("UtilityMetaRig"),
  120. NodeItem("UtilityMatrixFromCurve"),
  121. NodeItem("UtilityMatricesFromCurve"),
  122. NodeItem("UtilityPointFromCurve"),
  123. NodeItem("UtilityPointFromBoneMatrix"),
  124. NodeItem("UtilitySetBoneLength"),
  125. NodeItem("UtilityGetBoneLength"),
  126. NodeItem("UtilityBoneMatrixHeadTailFlip"),
  127. NodeItem("UtilityMatrixSetLocation"),
  128. NodeItem("UtilityMatrixFromXForm"),
  129. NodeItem("UtilityAxesFromMatrix"),
  130. NodeItem("UtilityMatrixTransform"),
  131. NodeItem("UtilityTransformationMatrix"),
  132. NodeItem("UtilitySetBoneMatrixTail"),
  133. ]
  134. groups_category = [
  135. NodeItem("MantisNodeGroup"),
  136. NodeItem("MantisSchemaGroup"),
  137. ]
  138. group_interface_category = [
  139. NodeItem("NodeGroupInput"),
  140. NodeItem("NodeGroupOutput"),
  141. ]
  142. node_categories = [
  143. # identifier, label, items list
  144. MantisNodeCategory('INPUT', "Input", items=input_category),
  145. MantisNodeCategory('LINK_TRANSFORM', "Link (Transform)", items=link_transform_category),
  146. MantisNodeCategory('LINK_TRACKING', "Link (Tracking)", items=link_tracking_category),
  147. MantisNodeCategory('LINK_RELATIONSHIP', "Link (Inheritance)", items=link_relationship_category),
  148. MantisNodeCategory('DEFORMER', "Deformer", items=deformer_category),
  149. MantisNodeCategory('XFORM', "Transform", items=xForm_category),
  150. MantisNodeCategory('DRIVER', "Driver", items=driver_category),
  151. MantisNodeCategory('GEOMETRY', "Geometry", items =geometry_category),
  152. MantisNodeCategory('UTILITIES', "Utility", items=utility_category),
  153. MantisNodeCategory('MATRIX', "Matrix", items=matrix_category),
  154. MantisNodeCategory('GROUPS', "Groups", items=groups_category),
  155. MantisGroupCategory('GROUP_INTERFACE', "Group In/Out", items=group_interface_category),
  156. ]
  157. schema_category=[NodeItem(cls.bl_idname) for cls in schema_definitions.TellClasses()]
  158. schema_categories = [
  159. SchemaNodeCategory('SCHEMA_SCHEMA', "Schema", items=schema_category),
  160. ]
  161. import bpy
  162. def init_keymaps():
  163. kc = bpy.context.window_manager.keyconfigs.addon
  164. km = kc.keymaps.new(name="Node Generic", space_type='NODE_EDITOR')
  165. kmi = [
  166. # Normal operation
  167. km.keymap_items.new("mantis.group_nodes", 'G', 'PRESS', ctrl=True),
  168. km.keymap_items.new("mantis.edit_group", 'TAB', 'PRESS'),
  169. km.keymap_items.new("mantis.execute_node_tree", 'E', 'PRESS'),
  170. km.keymap_items.new("mantis.mute_node", 'M', 'PRESS'),
  171. km.keymap_items.new("mantis.nodes_cleanup", "C", 'PRESS', shift=True,),
  172. # Testing
  173. km.keymap_items.new("mantis.query_sockets", 'Q', 'PRESS'),
  174. km.keymap_items.new("mantis.test_operator", 'T', 'PRESS'),
  175. km.keymap_items.new("mantis.visualize_output", 'V', 'PRESS'),
  176. # Saving, Loading, Reloading, etc.
  177. km.keymap_items.new("mantis.export_save_choose", "S", 'PRESS', alt=True,),
  178. km.keymap_items.new("mantis.export_save_as", "S", 'PRESS', alt=True, shift=True),
  179. km.keymap_items.new("mantis.reload_tree", "R", 'PRESS', alt=True,),
  180. km.keymap_items.new("mantis.import_tree", "O", 'PRESS', ctrl=True,),
  181. ]
  182. return km, kmi
  183. addon_keymaps = []
  184. # handlers! these have to be persistent
  185. from bpy.app.handlers import persistent
  186. @persistent
  187. def update_handler(scene):
  188. context=bpy.context
  189. if context.space_data:
  190. if not hasattr(context.space_data, "path"):
  191. return
  192. trees = [p.node_tree for p in context.space_data.path]
  193. if not trees: return
  194. if (node_tree := trees[0]).bl_idname in ['MantisTree']:
  195. if node_tree.do_live_update and not (node_tree.is_executing or node_tree.is_exporting):
  196. prev_links = node_tree.num_links
  197. node_tree.num_links = len(node_tree.links)
  198. if (prev_links == -1):
  199. return
  200. if prev_links != node_tree.num_links:
  201. node_tree.tree_valid = False
  202. if node_tree.tree_valid == False:
  203. scene.render.use_lock_interface = True
  204. node_tree.update_tree(context)
  205. scene.render.use_lock_interface = False
  206. @persistent
  207. def execute_handler(scene):
  208. context = bpy.context
  209. if context.space_data:
  210. if not hasattr(context.space_data, "path"):
  211. return
  212. trees = [p.node_tree for p in context.space_data.path]
  213. if not trees: return
  214. if (node_tree := trees[0]).bl_idname in ['MantisTree']:
  215. if node_tree.tree_valid and node_tree.do_live_update and not (node_tree.is_executing or node_tree.is_exporting):
  216. scene.render.use_lock_interface = True
  217. node_tree.execute_tree(context)
  218. scene.render.use_lock_interface = False
  219. node_tree.tree_valid = False
  220. @persistent
  221. def version_update_handler(filename):
  222. from .base_definitions import NODES_REMOVED, SOCKETS_REMOVED
  223. for node_tree in bpy.data.node_groups:
  224. if node_tree.bl_idname in ["MantisTree", "SchemaTree"]:
  225. if (node_tree.mantis_version[0] < MANTIS_VERSION_MAJOR) or \
  226. (node_tree.mantis_version[1] < MANTIS_VERSION_MINOR) or \
  227. (node_tree.mantis_version[2] < MANTIS_VERSION_SUB):
  228. print (f"Updating tree {node_tree.name} to {MANTIS_VERSION_MAJOR}.{MANTIS_VERSION_MINOR}.{MANTIS_VERSION_SUB}")
  229. node_tree.mantis_version[0] = MANTIS_VERSION_MAJOR
  230. node_tree.mantis_version[1] = MANTIS_VERSION_MINOR
  231. node_tree.mantis_version[2] = MANTIS_VERSION_SUB
  232. for n in node_tree.nodes:
  233. if n.bl_idname in NODES_REMOVED:
  234. print(f"INFO: removing node {n.name} of type {n.bl_idname} because it has been deprecated.")
  235. n.inputs.remove(socket)
  236. continue
  237. for socket in n.inputs.values():
  238. if (n.bl_idname, socket.identifier) in SOCKETS_REMOVED:
  239. print(f"INFO: removing socket {socket.identifier} of node {n.name} of type {n.bl_idname} because it has been deprecated.")
  240. n.inputs.remove(socket)
  241. for socket in n.outputs.values():
  242. if (n.bl_idname, socket.identifier) in SOCKETS_REMOVED:
  243. print(f"INFO: removing socket {socket.identifier} of node {n.name} of type {n.bl_idname} because it has been deprecated.")
  244. n.outputs.remove(socket)
  245. def register():
  246. if bpy.app.version >= (4, 4):
  247. raise NotImplementedError("Blender 4.4 is not supported at this time.")
  248. from bpy.utils import register_class
  249. for cls in classes:
  250. try:
  251. register_class(cls)
  252. except RuntimeError as e:
  253. prRed(cls.__name__)
  254. raise e
  255. nodeitems_utils.register_node_categories('MantisNodeCategories', node_categories)
  256. nodeitems_utils.register_node_categories('SchemaNodeCategories', schema_categories)
  257. km, kmi = init_keymaps()
  258. for k in kmi:
  259. k.active = True
  260. addon_keymaps.append((km, k))
  261. # add the handlers
  262. bpy.app.handlers.depsgraph_update_pre.append(update_handler)
  263. bpy.app.handlers.depsgraph_update_post.append(execute_handler)
  264. bpy.app.handlers.load_post.append(version_update_handler)
  265. def unregister():
  266. nodeitems_utils.unregister_node_categories('MantisNodeCategories')
  267. nodeitems_utils.unregister_node_categories('SchemaNodeCategories')
  268. from bpy.utils import unregister_class
  269. for cls in reversed(classes):
  270. unregister_class(cls)
  271. for km, kmi in addon_keymaps:
  272. km.keymap_items.remove(kmi)
  273. addon_keymaps.clear()