link_definitions.py 28 KB

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