link_definitions.py 29 KB

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