link_definitions.py 27 KB

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