link_definitions.py 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703
  1. import bpy
  2. from bpy.types import NodeTree, Node, NodeSocket
  3. from .base_definitions import LinkNode, GraphError
  4. from .utilities import (prRed, prGreen, prPurple, prWhite,
  5. prOrange,
  6. wrapRed, wrapGreen, wrapPurple, wrapWhite,
  7. wrapOrange,)
  8. from .base_definitions import get_signature_from_edited_tree
  9. def TellClasses():
  10. return [ LinkInheritNode,
  11. LinkInverseKinematics,
  12. LinkCopyLocationNode,
  13. LinkCopyRotationNode,
  14. LinkCopyScaleNode,
  15. LinkInheritConstraintNode,
  16. LinkCopyTransformNode,
  17. LinkStretchToNode,
  18. LinkDampedTrackNode,
  19. LinkLockedTrackNode,
  20. LinkTrackToNode,
  21. LinkLimitLocationNode,
  22. LinkLimitScaleNode,
  23. LinkLimitRotationNode,
  24. LinkLimitDistanceNode,
  25. LinkDrivenParameterNode,
  26. LinkArmatureNode,
  27. LinkSplineIKNode,
  28. LinkTransformationNode,
  29. ]
  30. def default_traverse(self, socket):
  31. if (socket == self.outputs["Output Relationship"]):
  32. return self.inputs["Input Relationship"]
  33. if (socket == self.inputs["Input Relationship"]):
  34. return self.outputs["Output Relationship"]
  35. return None
  36. from mathutils import Color # these colors were sampled from Blender's UI
  37. # TODO: maybe read the relevant colors from the Theme
  38. linkColor = Color((0.028034, 0.093164, 0.070379)).from_scene_linear_to_srgb()
  39. inheritColor = Color((0.083213, 0.131242, 0.116497)).from_scene_linear_to_srgb()
  40. trackingColor = Color((0.033114, 0.049013, 0.131248)).from_scene_linear_to_srgb()
  41. ikColor = Color((0.131117, 0.131248, 0.006971)).from_scene_linear_to_srgb()
  42. driverColor = Color((0.043782, 0.014745, 0.131248,)).from_scene_linear_to_srgb()
  43. class LinkInheritNode(Node, LinkNode):
  44. '''A node representing inheritance'''
  45. # cuss, messed this up
  46. bl_idname = 'linkInherit' # l should be L
  47. # need to fix this
  48. bl_label = "Inherit"
  49. bl_icon = 'CONSTRAINT_BONE'
  50. initialized : bpy.props.BoolProperty(default = False)
  51. mantis_node_class_name="LinkInherit"
  52. # bone_prev : bpy.props.BoolProperty(default=False)
  53. # bone_next : bpy.props.BoolProperty(default=False)
  54. def init(self, context):
  55. from .link_containers import LinkInheritSockets
  56. self.init_sockets(LinkInheritSockets)
  57. # set default values...
  58. self.initialized = True
  59. self.use_custom_color = True
  60. self.color = inheritColor
  61. def traverse(self, socket):
  62. if (socket == self.outputs["Inheritance"]):
  63. return self.inputs["Parent"]
  64. if (socket == self.inputs["Parent"]):
  65. return self.outputs["Inheritance"]
  66. return None
  67. def display_update(self, parsed_tree, context):
  68. node_tree = context.space_data.path[0].node_tree
  69. nc = parsed_tree.get(get_signature_from_edited_tree(self, context))
  70. if nc:
  71. bone_prev, bone_next = False, False
  72. if (inp := nc.inputs["Parent"]).is_connected:
  73. if from_node := inp.links[0].from_node:
  74. if from_node.__class__.__name__ in ["xFormBone"]:
  75. bone_prev=True
  76. bone_next=True
  77. try:
  78. xForm = nc.GetxForm()
  79. if xForm.__class__.__name__ not in "xFormBone":
  80. bone_next=False
  81. except GraphError:
  82. bone_next=False
  83. # print(bone_prev, bone_next )
  84. if bone_next and bone_prev:
  85. self.inputs["Inherit Rotation"].hide = False
  86. self.inputs["Inherit Scale"].hide = False
  87. self.inputs["Connected"].hide = False
  88. else:
  89. self.inputs["Inherit Rotation"].hide = True or self.inputs["Inherit Rotation"].is_connected
  90. self.inputs["Inherit Scale"].hide = True or self.inputs["Inherit Scale"].is_connected
  91. self.inputs["Connected"].hide = True or self.inputs["Connected"].is_connected
  92. # the node_groups on the way here ought to be active if there
  93. # is no funny business going on.
  94. # DO: make another node for ITASC IK, eh?
  95. class LinkInverseKinematics(Node, LinkNode):
  96. '''A node representing inverse kinematics'''
  97. bl_idname = 'LinkInverseKinematics'
  98. bl_label = "Inverse Kinematics"
  99. bl_icon = 'CON_KINEMATIC'
  100. initialized : bpy.props.BoolProperty(default = False)
  101. mantis_node_class_name=bl_idname
  102. def init(self, context):
  103. self.inputs.new('RelationshipSocket', "Input Relationship")
  104. self.inputs.new ('xFormSocket', "Target")
  105. self.inputs.new ('xFormSocket', "Pole Target")
  106. self.inputs.new ('IKChainLengthSocket', "Chain Length")
  107. self.inputs.new ('BooleanSocket', "Use Tail")
  108. self.inputs.new ('BooleanSocket', "Stretch")
  109. self.inputs.new ('FloatFactorSocket', "Position")
  110. self.inputs.new ('FloatFactorSocket', "Rotation")
  111. self.inputs.new ('FloatFactorSocket', "Influence")
  112. self.inputs.new ('EnableSocket', "Enable")
  113. #Well, it turns out that this has to be a constraint like
  114. # everything else, because of course, there can be more than one.
  115. #self.outputs.new('RelationshipSocket', "Inheritance")
  116. self.outputs.new('RelationshipSocket', "Output Relationship")
  117. self.initialized = True
  118. # color
  119. self.use_custom_color = True
  120. self.color = ikColor
  121. class LinkCopyLocationNode(Node, LinkNode):
  122. '''A node representing Copy Location'''
  123. bl_idname = 'LinkCopyLocation'
  124. bl_label = "Copy Location"
  125. bl_icon = 'CON_LOCLIKE'
  126. initialized : bpy.props.BoolProperty(default = False)
  127. mantis_node_class_name=bl_idname
  128. def init(self, context):
  129. self.inputs.new ('RelationshipSocket', "Input Relationship")
  130. self.inputs.new ('FloatFactorSocket', "Head/Tail")
  131. self.inputs.new ('BooleanSocket', "UseBBone")
  132. self.inputs.new ('BooleanThreeTupleSocket', "Axes")
  133. self.inputs.new ('BooleanThreeTupleSocket', "Invert")
  134. self.inputs.new ('TransformSpaceSocket', "Target Space")
  135. self.inputs.new ('TransformSpaceSocket', "Owner Space")
  136. self.inputs.new ('BooleanSocket', "Offset")
  137. self.inputs.new ('FloatFactorSocket', "Influence")
  138. self.inputs.new ('xFormSocket', "Target")
  139. self.inputs.new ('EnableSocket', "Enable")
  140. #
  141. self.outputs.new('RelationshipSocket', "Output Relationship")
  142. # color
  143. self.use_custom_color = True
  144. self.color = linkColor
  145. self.initialized = True
  146. class LinkCopyRotationNode(Node, LinkNode):
  147. '''A node representing Copy Rotation'''
  148. bl_idname = 'LinkCopyRotation'
  149. bl_label = "Copy Rotation"
  150. bl_icon = 'CON_ROTLIKE'
  151. initialized : bpy.props.BoolProperty(default = False)
  152. mantis_node_class_name=bl_idname
  153. def init(self, context):
  154. self.inputs.new ('RelationshipSocket', "Input Relationship")
  155. self.inputs.new ('RotationOrderSocket', "RotationOrder")
  156. self.inputs.new ('EnumRotationMix', "Rotation Mix")
  157. self.inputs.new ('BooleanThreeTupleSocket', "Axes")
  158. self.inputs.new ('BooleanThreeTupleSocket', "Invert")
  159. self.inputs.new ('TransformSpaceSocket', "Target Space")
  160. self.inputs.new ('TransformSpaceSocket', "Owner Space")
  161. self.inputs.new ('FloatFactorSocket', "Influence")
  162. self.inputs.new ('xFormSocket', "Target")
  163. self.inputs.new ('EnableSocket', "Enable")
  164. #
  165. self.outputs.new('RelationshipSocket', "Output Relationship")
  166. # color
  167. self.use_custom_color = True
  168. self.color = linkColor
  169. self.initialized = True
  170. class LinkCopyScaleNode(Node, LinkNode):
  171. '''A node representing Copy Scale'''
  172. bl_idname = 'LinkCopyScale'
  173. bl_label = "Copy Scale"
  174. bl_icon = 'CON_SIZELIKE'
  175. initialized : bpy.props.BoolProperty(default = False)
  176. mantis_node_class_name=bl_idname
  177. def init(self, context):
  178. self.inputs.new ('RelationshipSocket', "Input Relationship")
  179. self.inputs.new ('BooleanSocket', "Offset")
  180. self.inputs.new ('BooleanSocket', "Average")
  181. self.inputs.new ('BooleanThreeTupleSocket', "Axes")
  182. #self.inputs.new ('BooleanThreeTupleSocket', "Invert")
  183. # dingus, this one doesn't have inverts
  184. self.inputs.new ('TransformSpaceSocket', "Target Space")
  185. self.inputs.new ('TransformSpaceSocket', "Owner Space")
  186. self.inputs.new ('FloatFactorSocket', "Influence")
  187. self.inputs.new ('xFormSocket', "Target")
  188. self.inputs.new ('EnableSocket', "Enable")
  189. #
  190. self.outputs.new('RelationshipSocket', "Output Relationship")
  191. # color
  192. self.use_custom_color = True
  193. self.color = linkColor
  194. self.initialized = True
  195. class LinkInheritConstraintNode(Node, LinkNode):
  196. # === Basics ===
  197. # Description string
  198. '''A node representing a parent constraint'''
  199. bl_idname = 'LinkInheritConstraint'
  200. bl_label = "Inherit (constraint)"
  201. bl_icon = 'CON_CHILDOF'
  202. initialized : bpy.props.BoolProperty(default = False)
  203. mantis_node_class_name=bl_idname
  204. # === Optional Functions ===
  205. def init(self, context):
  206. self.inputs.new ('RelationshipSocket', "Input Relationship")
  207. self.inputs.new ('BooleanThreeTupleSocket', "Location")
  208. self.inputs.new ('BooleanThreeTupleSocket', "Rotation")
  209. self.inputs.new ('BooleanThreeTupleSocket', "Scale")
  210. self.inputs.new ('FloatFactorSocket', "Influence")
  211. self.inputs.new ('xFormSocket', "Target")
  212. self.inputs.new ('EnableSocket', "Enable")
  213. #
  214. self.outputs.new('RelationshipSocket', "Output Relationship")
  215. # color
  216. self.use_custom_color = True
  217. self.color = inheritColor
  218. self.initialized = True
  219. class LinkCopyTransformNode(Node, LinkNode):
  220. # === Basics ===
  221. # Description string
  222. '''A node representing Copy Transform'''
  223. bl_idname = 'LinkCopyTransforms'
  224. bl_label = "Copy Transform"
  225. bl_icon = 'CON_TRANSLIKE'
  226. initialized : bpy.props.BoolProperty(default = False)
  227. mantis_node_class_name=bl_idname
  228. # === Optional Functions ===
  229. def init(self, context):
  230. self.inputs.new ('RelationshipSocket', "Input Relationship")
  231. self.inputs.new ('FloatFactorSocket', "Head/Tail")
  232. self.inputs.new ('BooleanSocket', "UseBBone")
  233. self.inputs.new ('EnumRotationMixCopyTransforms', "Mix")
  234. self.inputs.new ('TransformSpaceSocket', "Target Space")
  235. self.inputs.new ('TransformSpaceSocket', "Owner Space")
  236. self.inputs.new ('FloatFactorSocket', "Influence")
  237. self.inputs.new ('xFormSocket', "Target")
  238. self.inputs.new ('EnableSocket', "Enable")
  239. #
  240. self.outputs.new('RelationshipSocket', "Output Relationship")
  241. # color
  242. self.use_custom_color = True
  243. self.color = linkColor
  244. self.initialized = True
  245. class LinkStretchToNode(Node, LinkNode):
  246. '''A node representing Stretch-To'''
  247. bl_idname = 'LinkStretchTo'
  248. bl_label = "Stretch To"
  249. bl_icon = 'CON_STRETCHTO'
  250. initialized : bpy.props.BoolProperty(default = False)
  251. mantis_node_class_name=bl_idname
  252. def init(self, context):
  253. self.inputs.new ('RelationshipSocket', "Input Relationship")
  254. self.inputs.new ('FloatFactorSocket', "Head/Tail")
  255. self.inputs.new ('BooleanSocket', "UseBBone")
  256. self.inputs.new ('FloatSocket', "Original Length")
  257. self.inputs.new ('FloatSocket', "Volume Variation")
  258. self.inputs.new ('BoolUpdateParentNode', "Use Volume Min")
  259. self.inputs.new ('FloatSocket', "Volume Min")
  260. self.inputs.new ('BoolUpdateParentNode', "Use Volume Max")
  261. self.inputs.new ('FloatSocket', "Volume Max")
  262. self.inputs.new ('FloatFactorSocket', "Smooth")
  263. self.inputs.new ('EnumMaintainVolumeStretchToSocket', "Maintain Volume")
  264. self.inputs.new ('EnumRotationStretchTo', "Rotation")
  265. self.inputs.new ('FloatFactorSocket', "Influence")
  266. self.inputs.new ('xFormSocket', "Target")
  267. self.inputs.new ('EnableSocket', "Enable")
  268. #
  269. self.outputs.new('RelationshipSocket', "Output Relationship")
  270. self.initialized = True
  271. # color
  272. self.use_custom_color = True
  273. self.color = trackingColor
  274. class LinkDampedTrackNode(Node, LinkNode):
  275. '''A node representing Stretch-To'''
  276. bl_idname = 'LinkDampedTrack'
  277. bl_label = "Damped Track"
  278. bl_icon = 'CON_TRACKTO'
  279. initialized : bpy.props.BoolProperty(default = False)
  280. mantis_node_class_name=bl_idname
  281. def init(self, context):
  282. self.inputs.new ('RelationshipSocket', "Input Relationship")
  283. self.inputs.new ('FloatFactorSocket', "Head/Tail")
  284. self.inputs.new ('BooleanSocket', "UseBBone")
  285. self.inputs.new ('EnumTrackAxis', "Track Axis")
  286. self.inputs.new ('FloatFactorSocket', "Influence")
  287. self.inputs.new ('xFormSocket', "Target")
  288. self.inputs.new ('EnableSocket', "Enable")
  289. #
  290. self.outputs.new('RelationshipSocket', "Output Relationship")
  291. self.initialized = True
  292. # color
  293. self.use_custom_color = True
  294. self.color = trackingColor
  295. class LinkLockedTrackNode(Node, LinkNode):
  296. '''A node representing Stretch-To'''
  297. bl_idname = 'LinkLockedTrack'
  298. bl_label = "Locked Track"
  299. bl_icon = 'CON_LOCKTRACK'
  300. initialized : bpy.props.BoolProperty(default = False)
  301. mantis_node_class_name=bl_idname
  302. def init(self, context):
  303. self.inputs.new ('RelationshipSocket', "Input Relationship")
  304. self.inputs.new ('FloatFactorSocket', "Head/Tail")
  305. self.inputs.new ('BooleanSocket', "UseBBone")
  306. self.inputs.new ('EnumTrackAxis', "Track Axis")
  307. self.inputs.new ('EnumLockAxis', "Lock Axis")
  308. self.inputs.new ('FloatFactorSocket', "Influence")
  309. self.inputs.new ('xFormSocket', "Target")
  310. self.inputs.new ('EnableSocket', "Enable")
  311. #
  312. self.outputs.new('RelationshipSocket', "Output Relationship")
  313. self.initialized = True
  314. # color
  315. self.use_custom_color = True
  316. self.color = trackingColor
  317. class LinkTrackToNode(Node, LinkNode):
  318. '''A node representing Stretch-To'''
  319. bl_idname = 'LinkTrackTo'
  320. bl_label = "Track To"
  321. bl_icon = 'CON_TRACKTO'
  322. initialized : bpy.props.BoolProperty(default = False)
  323. mantis_node_class_name=bl_idname
  324. def init(self, context):
  325. self.inputs.new ('RelationshipSocket', "Input Relationship")
  326. self.inputs.new ('FloatFactorSocket', "Head/Tail")
  327. self.inputs.new ('BooleanSocket', "UseBBone")
  328. self.inputs.new ('EnumTrackAxis', "Track Axis")
  329. self.inputs.new ('EnumUpAxis', "Up Axis")
  330. self.inputs.new ('BooleanSocket', "Use Target Z")
  331. self.inputs.new ('TransformSpaceSocket', "Target Space")
  332. self.inputs.new ('TransformSpaceSocket', "Owner Space")
  333. self.inputs.new ('FloatFactorSocket', "Influence")
  334. self.inputs.new ('xFormSocket', "Target")
  335. self.inputs.new ('EnableSocket', "Enable")
  336. #
  337. self.outputs.new('RelationshipSocket', "Output Relationship")
  338. self.initialized = True
  339. # color
  340. self.use_custom_color = True
  341. self.color = trackingColor
  342. class LinkLimitLocationNode(Node, LinkNode):
  343. '''A node representing Limit Location'''
  344. bl_idname = 'LinkLimitLocation'
  345. bl_label = "Limit Location"
  346. bl_icon = 'CON_LOCLIMIT'
  347. mantis_node_class_name=bl_idname
  348. initialized : bpy.props.BoolProperty(default = False)
  349. def init(self, context):
  350. self.inputs.new ('RelationshipSocket', "Input Relationship")
  351. self.inputs.new ('BoolUpdateParentNode', "Use Max X")
  352. self.inputs.new ('FloatSocket', "Max X")
  353. self.inputs.new ('BoolUpdateParentNode', "Use Min X")
  354. self.inputs.new ('FloatSocket', "Min X")
  355. self.inputs.new ('BoolUpdateParentNode', "Use Max Y")
  356. self.inputs.new ('FloatSocket', "Max Y")
  357. self.inputs.new ('BoolUpdateParentNode', "Use Min Y")
  358. self.inputs.new ('FloatSocket', "Min Y")
  359. self.inputs.new ('BoolUpdateParentNode', "Use Max Z")
  360. self.inputs.new ('FloatSocket', "Max Z")
  361. self.inputs.new ('BoolUpdateParentNode', "Use Min Z")
  362. self.inputs.new ('FloatSocket', "Min Z")
  363. self.inputs.new ('BooleanSocket', "Affect Transform")
  364. self.inputs.new ('TransformSpaceSocket', "Owner Space")
  365. self.inputs.new ('FloatFactorSocket', "Influence")
  366. self.inputs.new ('EnableSocket', "Enable")
  367. #
  368. self.outputs.new('RelationshipSocket', "Output Relationship")
  369. self.initialized = True
  370. # color
  371. self.use_custom_color = True
  372. self.color = linkColor
  373. class LinkLimitScaleNode(Node, LinkNode):
  374. '''A node representing Limit Scale'''
  375. bl_idname = 'LinkLimitScale'
  376. bl_label = "Limit Scale"
  377. bl_icon = 'CON_SIZELIMIT'
  378. initialized : bpy.props.BoolProperty(default = False)
  379. mantis_node_class_name=bl_idname
  380. def init(self, context):
  381. self.inputs.new ('RelationshipSocket', "Input Relationship")
  382. self.inputs.new ('BoolUpdateParentNode', "Use Max X")
  383. self.inputs.new ('FloatSocket', "Max X")
  384. self.inputs.new ('BoolUpdateParentNode', "Use Min X")
  385. self.inputs.new ('FloatSocket', "Min X")
  386. self.inputs.new ('BoolUpdateParentNode', "Use Max Y")
  387. self.inputs.new ('FloatSocket', "Max Y")
  388. self.inputs.new ('BoolUpdateParentNode', "Use Min Y")
  389. self.inputs.new ('FloatSocket', "Min Y")
  390. self.inputs.new ('BoolUpdateParentNode', "Use Max Z")
  391. self.inputs.new ('FloatSocket', "Max Z")
  392. self.inputs.new ('BoolUpdateParentNode', "Use Min Z")
  393. self.inputs.new ('FloatSocket', "Min Z")
  394. self.inputs.new ('BooleanSocket', "Affect Transform")
  395. self.inputs.new ('TransformSpaceSocket', "Owner Space")
  396. self.inputs.new ('FloatFactorSocket', "Influence")
  397. self.inputs.new ('EnableSocket', "Enable")
  398. #
  399. self.outputs.new('RelationshipSocket', "Output Relationship")
  400. self.initialized = True
  401. # color
  402. self.use_custom_color = True
  403. self.color = linkColor
  404. class LinkLimitRotationNode(Node, LinkNode):
  405. # === Basics ===
  406. # Description string
  407. '''A node representing Limit Rotation'''
  408. bl_idname = 'LinkLimitRotation'
  409. bl_label = "Limit Rotation"
  410. bl_icon = 'CON_ROTLIMIT'
  411. initialized : bpy.props.BoolProperty(default = False)
  412. mantis_node_class_name=bl_idname
  413. # === Optional Functions ===
  414. def init(self, context):
  415. self.inputs.new ('RelationshipSocket', "Input Relationship")
  416. self.inputs.new ('BoolUpdateParentNode', "Use X")
  417. self.inputs.new ('FloatAngleSocket', "Min X")
  418. self.inputs.new ('FloatAngleSocket', "Max X")
  419. self.inputs.new ('BoolUpdateParentNode', "Use Y")
  420. self.inputs.new ('FloatAngleSocket', "Min Y")
  421. self.inputs.new ('FloatAngleSocket', "Max Y")
  422. self.inputs.new ('BoolUpdateParentNode', "Use Z")
  423. self.inputs.new ('FloatAngleSocket', "Min Z")
  424. self.inputs.new ('FloatAngleSocket', "Max Z")
  425. self.inputs.new ('BooleanSocket', "Affect Transform")
  426. self.inputs.new ('TransformSpaceSocket', "Owner Space")
  427. self.inputs.new ('FloatFactorSocket', "Influence")
  428. self.inputs.new ('EnableSocket', "Enable")
  429. #
  430. self.outputs.new('RelationshipSocket', "Output Relationship")
  431. self.initialized = True
  432. # color
  433. self.use_custom_color = True
  434. self.color = linkColor
  435. class LinkLimitDistanceNode(Node, LinkNode):
  436. '''A node representing Limit Distance'''
  437. bl_idname = 'LinkLimitDistance'
  438. bl_label = "Limit Distance"
  439. bl_icon = 'CON_DISTLIMIT'
  440. initialized : bpy.props.BoolProperty(default = False)
  441. mantis_node_class_name=bl_idname
  442. def init(self, context):
  443. self.inputs.new ('RelationshipSocket', "Input Relationship")
  444. self.inputs.new ('FloatFactorSocket', "Head/Tail")
  445. self.inputs.new ('BooleanSocket', "UseBBone")
  446. self.inputs.new ('FloatSocket', "Distance")
  447. self.inputs.new ('EnumLimitMode', "Clamp Region")
  448. self.inputs.new ('BooleanSocket', "Affect Transform")
  449. self.inputs.new ('TransformSpaceSocket', "Owner Space")
  450. self.inputs.new ('TransformSpaceSocket', "Target Space")
  451. self.inputs.new ('FloatFactorSocket', "Influence")
  452. self.inputs.new ('xFormSocket', "Target")
  453. self.inputs.new ('EnableSocket', "Enable")
  454. #
  455. self.outputs.new('RelationshipSocket', "Output Relationship")
  456. # color
  457. self.use_custom_color = True
  458. self.color = linkColor
  459. self.initialized = True
  460. class LinkTransformationNode(Node, LinkNode):
  461. '''A node representing Transformation (Constraint)'''
  462. bl_idname = 'LinkTransformation'
  463. bl_label = "Transformation"
  464. bl_icon = 'CON_TRANSFORM'
  465. initialized : bpy.props.BoolProperty(default = False)
  466. mantis_node_class_name=bl_idname
  467. def init(self, context):
  468. hide_me = []
  469. self.inputs.new ('RelationshipSocket', "Input Relationship")
  470. self.inputs.new ('xFormSocket', "Target")
  471. self.inputs.new ('TransformSpaceSocket', "Owner Space")
  472. self.inputs.new ('TransformSpaceSocket', "Target Space")
  473. self.inputs.new ('BooleanSocket', "Extrapolate")
  474. self.inputs.new ('EnumTransformationMap', "Map From")
  475. hide_me.append( self.inputs.new ('EnumTransformationRotationMode', "Rotation Mode"))
  476. self.inputs.new ('FloatSocket', "X Min From")
  477. self.inputs.new ('FloatSocket', "X Max From")
  478. self.inputs.new ('FloatSocket', "Y Min From")
  479. self.inputs.new ('FloatSocket', "Y Max From")
  480. self.inputs.new ('FloatSocket', "Z Min From")
  481. self.inputs.new ('FloatSocket', "Z Max From")
  482. self.inputs.new ('EnumTransformationMap', "Map To")
  483. hide_me.append( self.inputs.new ('EnumTransformationRotationOrder', "Rotation Order"))
  484. self.inputs.new ('EnumTransformationAxes', "X Source Axis")
  485. self.inputs.new ('FloatSocket', "X Min To")
  486. self.inputs.new ('FloatSocket', "X Max To")
  487. self.inputs.new ('EnumTransformationAxes', "Y Source Axis")
  488. self.inputs.new ('FloatSocket', "Y Min To")
  489. self.inputs.new ('FloatSocket', "Y Max To")
  490. self.inputs.new ('EnumTransformationAxes', "Z Source Axis")
  491. self.inputs.new ('FloatSocket', "Z Min To")
  492. self.inputs.new ('FloatSocket', "Z Max To")
  493. self.inputs.new ('EnumTransformationTranslationMixMode', "Mix Mode (Translation)")
  494. hide_me.append( self.inputs.new ('EnumTransformationRotationMixMode', "Mix Mode (Rotation)"))
  495. hide_me.append( self.inputs.new ('EnumTransformationScaleMixMode', "Mix Mode (Scale)"))
  496. self.inputs.new ('FloatFactorSocket', "Influence")
  497. self.inputs.new ('EnableSocket', "Enable")
  498. #
  499. self.outputs.new('RelationshipSocket', "Output Relationship")
  500. for s in hide_me:
  501. s.hide = True
  502. # color
  503. self.use_custom_color = True
  504. self.color = linkColor
  505. self.initialized = True
  506. def display_update(self, parsed_tree, context):
  507. node_tree = context.space_data.path[0].node_tree
  508. nc = parsed_tree.get(get_signature_from_edited_tree(self, context))
  509. if nc:
  510. if nc.evaluate_input("Map From") == "ROTATION":
  511. self.inputs["Rotation Mode"].hide=False
  512. else:
  513. self.inputs["Rotation Mode"].hide=True
  514. if nc.evaluate_input("Map To") == "TRANSLATION":
  515. self.inputs["Rotation Order"].hide=True
  516. self.inputs["Mix Mode (Translation)"].hide=False
  517. self.inputs["Mix Mode (Rotation)"].hide=True
  518. self.inputs["Mix Mode (Scale)"].hide=True
  519. elif nc.evaluate_input("Map To") == "ROTATION":
  520. self.inputs["Rotation Order"].hide=False
  521. self.inputs["Mix Mode (Translation)"].hide=True
  522. self.inputs["Mix Mode (Rotation)"].hide=False
  523. self.inputs["Mix Mode (Scale)"].hide=True
  524. elif nc.evaluate_input("Map To") == "SCALE":
  525. self.inputs["Rotation Order"].hide=True
  526. self.inputs["Mix Mode (Translation)"].hide=True
  527. self.inputs["Mix Mode (Rotation)"].hide=True
  528. self.inputs["Mix Mode (Scale)"].hide=False
  529. class LinkArmatureNode(Node, LinkNode):
  530. """A node representing Blender's Armature Constraint"""
  531. bl_idname = "LinkArmature"
  532. bl_label = "Armature (Constraint)"
  533. bl_icon = "CON_ARMATURE"
  534. initialized : bpy.props.BoolProperty(default = False)
  535. mantis_node_class_name=bl_idname
  536. def init(self, context):
  537. self.inputs.new ("RelationshipSocket", "Input Relationship")
  538. self.inputs.new("BooleanSocket", "Preserve Volume")
  539. self.inputs.new("BooleanSocket", "Use Envelopes")
  540. self.inputs.new("BooleanSocket", "Use Current Location")
  541. self.inputs.new("FloatFactorSocket", "Influence")
  542. self.inputs.new ('EnableSocket', "Enable")
  543. self.outputs.new("RelationshipSocket", "Output Relationship")
  544. # color
  545. self.use_custom_color = True
  546. self.color = inheritColor
  547. self.initialized = True
  548. def traverse(self, socket):
  549. return default_traverse(self,socket)
  550. def draw_buttons(self, context, layout):
  551. # return
  552. layout.operator( 'mantis.link_armature_node_add_target' )
  553. if (len(self.inputs) > 6):
  554. layout.operator( 'mantis.link_armature_node_remove_target' )
  555. else:
  556. layout.label(text="")
  557. class LinkSplineIKNode(Node, LinkNode):
  558. """"A node representing Spline IK"""
  559. bl_idname = "LinkSplineIK"
  560. bl_label = "Spline IK"
  561. bl_icon = "CON_SPLINEIK"
  562. initialized : bpy.props.BoolProperty(default = False)
  563. mantis_node_class_name=bl_idname
  564. def init(self, context):
  565. self.inputs.new ("RelationshipSocket", "Input Relationship")
  566. self.inputs.new("xFormSocket", "Target")
  567. self.inputs.new("IntSocket", "Chain Length")
  568. self.inputs.new("BooleanSocket", "Even Divisions")
  569. self.inputs.new("BooleanSocket", "Chain Offset")
  570. self.inputs.new("BooleanSocket", "Use Curve Radius")
  571. self.inputs.new("EnumYScaleMode", "Y Scale Mode")
  572. self.inputs.new("EnumXZScaleMode", "XZ Scale Mode")
  573. self.inputs.new("BooleanSocket", "Use Original Scale")
  574. self.inputs.new("FloatFactorSocket", "Influence")
  575. self.outputs.new("RelationshipSocket", "Output Relationship")
  576. # color
  577. self.use_custom_color = True
  578. self.color = ikColor
  579. self.initialized = True
  580. def traverse(self, socket):
  581. return default_traverse(self,socket)
  582. # DRIVERS!!
  583. class LinkDrivenParameterNode(Node, LinkNode):
  584. """Represents a driven parameter in the downstream xForm node."""
  585. bl_idname = "LinkDrivenParameter"
  586. bl_label = "Driven Parameter"
  587. bl_icon = "CONSTRAINT_BONE"
  588. initialized : bpy.props.BoolProperty(default = False)
  589. mantis_node_class_name=bl_idname
  590. def init(self, context):
  591. self.inputs.new ( "RelationshipSocket", "Input Relationship" )
  592. self.inputs.new ( "FloatSocket", "Value" )
  593. self.inputs.new ( "ParameterStringSocket", "Parameter" )
  594. self.inputs.new ( "IntSocket", "Index" )
  595. self.inputs.new ('EnableSocket', "Enable")
  596. #
  597. self.outputs.new( "RelationshipSocket", "Output Relationship" )
  598. self.initialized = True
  599. def traverse(self, socket):
  600. return default_traverse(self,socket)
  601. # color
  602. self.use_custom_color = True
  603. self.color = driverColor
  604. # Set up the class property that ties the UI classes to the Mantis classes.
  605. for cls in TellClasses():
  606. cls.set_mantis_class()