link_containers.py 71 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601
  1. from .node_container_common import *
  2. from bpy.types import Node
  3. from .base_definitions import MantisNode, GraphError
  4. #TODO: get rid of this, it's unnecesary here, we always want to import
  5. # all classes in this file
  6. def TellClasses():
  7. return [
  8. # special
  9. LinkInherit,
  10. # copy
  11. LinkCopyLocation,
  12. LinkCopyRotation,
  13. LinkCopyScale,
  14. LinkCopyTransforms,
  15. LinkTransformation,
  16. # limit
  17. LinkLimitLocation,
  18. LinkLimitRotation,
  19. LinkLimitScale,
  20. LinkLimitDistance,
  21. # tracking
  22. LinkStretchTo,
  23. LinkDampedTrack,
  24. LinkLockedTrack,
  25. LinkTrackTo,
  26. #misc
  27. LinkInheritConstraint,
  28. LinkArmature,
  29. # IK
  30. LinkInverseKinematics,
  31. LinkSplineIK,
  32. # Drivers
  33. LinkDrivenParameter,
  34. ]
  35. def default_evaluate_input(nc, input_name):
  36. # should catch 'Target', 'Pole Target' and ArmatureConstraint targets, too
  37. if ('Target' in input_name) and input_name != "Target Space":
  38. socket = nc.inputs.get(input_name)
  39. if socket.is_linked:
  40. return socket.links[0].from_node
  41. return None
  42. else:
  43. return evaluate_input(nc, input_name)
  44. #*#-------------------------------#++#-------------------------------#*#
  45. # L I N K N O D E S
  46. #*#-------------------------------#++#-------------------------------#*#
  47. def GetxForm(nc):
  48. trace = trace_single_line_up(nc, "Output Relationship")
  49. for node in trace[0]:
  50. if (node.node_type == 'XFORM'):
  51. return node
  52. raise GraphError("%s is not connected to a downstream xForm" % nc)
  53. class LinkInherit:
  54. '''A node representing inheritance'''
  55. def __init__(self, signature, base_tree):
  56. self.base_tree=base_tree
  57. self.signature = signature
  58. self.inputs = {
  59. "Parent" : NodeSocket(is_input = True, name = "Parent", node = self,),
  60. # bone only:
  61. "Inherit Rotation" : NodeSocket(is_input = True, name = "Inherit Rotation", node = self,),
  62. "Inherit Scale" : NodeSocket(is_input = True, name = "Inherit Scale", node = self,),
  63. "Connected" : NodeSocket(is_input = True, name = "Connected", node = self,),
  64. }
  65. self.outputs = { "Inheritance" : NodeSocket(name = "Inheritance", node = self) }
  66. self.parameters = {
  67. "Parent":None,
  68. # bone only:
  69. "Inherit Rotation":None,
  70. "Inherit Scale":None,
  71. "Connected":None,
  72. }
  73. self.links = {} # leave this empty for now!
  74. # now set up the traverse target...
  75. self.inputs["Parent"].set_traverse_target(self.outputs["Inheritance"])
  76. self.outputs["Inheritance"].set_traverse_target(self.inputs["Parent"])
  77. self.node_type = 'LINK'
  78. def evaluate_input(self, input_name):
  79. return default_evaluate_input(self, input_name)
  80. def GetxForm(self): # DUPLICATED, TODO fix this
  81. trace = trace_single_line_up(self, "Inheritance")
  82. for node in trace[0]:
  83. if (node.node_type == 'XFORM'):
  84. return node
  85. raise GraphError("%s is not connected to a downstream xForm" % self)
  86. def bExecute(self, bContext = None,):
  87. # this is handled by the xForm objects, since it isn't really
  88. # a constraint.
  89. pass
  90. def __repr__(self):
  91. return self.signature.__repr__()
  92. def fill_parameters(self):
  93. fill_parameters(self)
  94. class LinkCopyLocation:
  95. '''A node representing Copy Location'''
  96. def __init__(self, signature, base_tree):
  97. self.base_tree=base_tree
  98. self.signature = signature
  99. self.inputs = {
  100. "Input Relationship" : NodeSocket(is_input = True, name = "Input Relationship", node = self,),
  101. "Head/Tail" : NodeSocket(is_input = True, name = "Head/Tail", node = self,),
  102. "UseBBone" : NodeSocket(is_input = True, name = "UseBBone", node = self,),
  103. "Axes" : NodeSocket(is_input = True, name = "Axes", node = self,),
  104. "Invert" : NodeSocket(is_input = True, name = "Invert", node = self,),
  105. "Target Space" : NodeSocket(is_input = True, name = "Target Space", node = self,),
  106. "Owner Space" : NodeSocket(is_input = True, name = "Owner Space", node = self,),
  107. "Influence" : NodeSocket(is_input = True, name = "Influence", node = self,),
  108. "Target" : NodeSocket(is_input = True, name = "Target", node = self,),
  109. "Enable" : NodeSocket(is_input = True, name = "Enable", node = self,), }
  110. self.outputs = {
  111. "Output Relationship" : NodeSocket(name = "Output Relationship", node=self) }
  112. self.parameters = {
  113. "Name":None,
  114. "Input Relationship":None,
  115. "Head/Tail":None,
  116. "UseBBone":None,
  117. "Axes":None,
  118. "Invert":None,
  119. "Target Space":None,
  120. "Owner Space":None,
  121. "Influence":None,
  122. "Target":None,
  123. "Enable":None, }
  124. # now set up the traverse target...
  125. self.inputs["Input Relationship"].set_traverse_target(self.outputs["Output Relationship"])
  126. self.outputs["Output Relationship"].set_traverse_target(self.inputs["Input Relationship"])
  127. self.node_type = 'LINK'
  128. def evaluate_input(self, input_name):
  129. return default_evaluate_input(self, input_name)
  130. def GetxForm(self):
  131. return GetxForm(self)
  132. def bExecute(self, context):
  133. prepare_parameters(self)
  134. c = self.GetxForm().bGetObject().constraints.new('COPY_LOCATION')
  135. get_target_and_subtarget(self, c)
  136. print(wrapGreen("Creating ")+wrapWhite("Copy Location")+
  137. wrapGreen(" Constraint for bone: ") +
  138. wrapOrange(self.GetxForm().bGetObject().name))
  139. c.name = self.evaluate_input("Name")
  140. self.bObject = c
  141. props_sockets = {
  142. 'head_tail' : ("Head/Tail", 0),
  143. 'use_bbone_shape' : ("UseBBone", False),
  144. 'invert_x' : ( ("Invert", 0), False),
  145. 'invert_y' : ( ("Invert", 1), False),
  146. 'invert_z' : ( ("Invert", 2), False),
  147. 'use_x' : ( ("Axes", 0), False),
  148. 'use_y' : ( ("Axes", 1), False),
  149. 'use_z' : ( ("Axes", 2), False),
  150. 'owner_space' : ("Owner Space", 'WORLD'),
  151. 'target_space' : ("Target Space", 'WORLD'),
  152. 'influence' : ("Influence", 1),
  153. 'mute' : ("Enable", True),
  154. }
  155. evaluate_sockets(self, c, props_sockets)
  156. def bFinalize(self, bContext = None):
  157. finish_drivers(self)
  158. def __repr__(self):
  159. return self.signature.__repr__()
  160. def fill_parameters(self):
  161. fill_parameters(self)
  162. class LinkCopyRotation:
  163. '''A node representing Copy Rotation'''
  164. def __init__(self, signature, base_tree):
  165. self.base_tree=base_tree
  166. self.signature = signature
  167. self.inputs = {
  168. "Input Relationship" : NodeSocket(is_input = True, name = "Input Relationship", node = self,),
  169. "RotationOrder" : NodeSocket(is_input = True, name = "RotationOrder", node = self,),
  170. "Rotation Mix" : NodeSocket(is_input = True, name = "Rotation Mix", node = self,),
  171. "Axes" : NodeSocket(is_input = True, name = "Axes", node = self,),
  172. "Invert" : NodeSocket(is_input = True, name = "Invert", node = self,),
  173. "Target Space" : NodeSocket(is_input = True, name = "Target Space", node = self,),
  174. "Owner Space" : NodeSocket(is_input = True, name = "Owner Space", node = self,),
  175. "Influence" : NodeSocket(is_input = True, name = "Influence", node = self,),
  176. "Target" : NodeSocket(is_input = True, name = "Target", node = self,),
  177. "Enable" : NodeSocket(is_input = True, name = "Enable", node = self,), }
  178. self.outputs = {
  179. "Output Relationship" : NodeSocket(name = "Output Relationship", node=self) }
  180. self.parameters = {
  181. "Name":None,
  182. "Input Relationship":None,
  183. "RotationOrder":None,
  184. "Rotation Mix":None,
  185. "Axes":None,
  186. "Invert":None,
  187. "Target Space":None,
  188. "Owner Space":None,
  189. "Influence":None,
  190. "Target":None,
  191. "Enable":None, }
  192. # now set up the traverse target...
  193. self.inputs["Input Relationship"].set_traverse_target(self.outputs["Output Relationship"])
  194. self.outputs["Output Relationship"].set_traverse_target(self.inputs["Input Relationship"])
  195. self.node_type = 'LINK'
  196. def evaluate_input(self, input_name):
  197. return default_evaluate_input(self, input_name)
  198. def GetxForm(self):
  199. return GetxForm(self)
  200. def bExecute(self, context):
  201. prepare_parameters(self)
  202. c = self.GetxForm().bGetObject().constraints.new('COPY_ROTATION')
  203. get_target_and_subtarget(self, c)
  204. print(wrapGreen("Creating ")+wrapWhite("Copy Rotation")+
  205. wrapGreen(" Constraint for bone: ") +
  206. wrapOrange(self.GetxForm().bGetObject().name))
  207. if self.parameters["Enable"]:
  208. c.enabled = True; c.mute = False
  209. rotation_order = self.evaluate_input("RotationOrder")
  210. if ((rotation_order == 'QUATERNION') or (rotation_order == 'AXIS_ANGLE')):
  211. c.euler_order = 'AUTO'
  212. else:
  213. try:
  214. c.euler_order = rotation_order
  215. except TypeError: # it's a driver or incorrect
  216. c.euler_order = 'AUTO'
  217. c.name = self.evaluate_input("Name")
  218. self.bObject = c
  219. props_sockets = {
  220. 'euler_order' : ("RotationOrder", 'AUTO'),
  221. 'mix_mode' : ("Rotation Mix", 'REPLACE'),
  222. 'invert_x' : ( ("Invert", 0), False),
  223. 'invert_y' : ( ("Invert", 1), False),
  224. 'invert_z' : ( ("Invert", 2), False),
  225. 'use_x' : ( ("Axes", 0), False),
  226. 'use_y' : ( ("Axes", 1), False),
  227. 'use_z' : ( ("Axes", 2), False),
  228. 'owner_space' : ("Owner Space", 'WORLD'),
  229. 'target_space' : ("Target Space", 'WORLD'),
  230. 'influence' : ("Influence", 1),
  231. 'mute' : ("Enable", True),
  232. }
  233. evaluate_sockets(self, c, props_sockets)
  234. def bFinalize(self, bContext = None):
  235. finish_drivers(self)
  236. def __repr__(self):
  237. return self.signature.__repr__()
  238. def fill_parameters(self):
  239. fill_parameters(self)
  240. class LinkCopyScale:
  241. '''A node representing Copy Scale'''
  242. def __init__(self, signature, base_tree):
  243. self.base_tree=base_tree
  244. self.signature = signature
  245. self.inputs = {
  246. "Input Relationship" : NodeSocket(is_input = True, name = "Input Relationship", node = self,),
  247. "Offset" : NodeSocket(is_input = True, name = "Offset", node = self,),
  248. "Average" : NodeSocket(is_input = True, name = "Average", node = self,),
  249. "Additive" : NodeSocket(is_input = True, name = "Additive", node = self,),
  250. "Axes" : NodeSocket(is_input = True, name = "Axes", node = self,),
  251. #"Invert" : NodeSocket(is_input = True, name = "Invert", node = self,),
  252. "Target Space" : NodeSocket(is_input = True, name = "Target Space", node = self,),
  253. "Owner Space" : NodeSocket(is_input = True, name = "Owner Space", node = self,),
  254. "Influence" : NodeSocket(is_input = True, name = "Influence", node = self,),
  255. "Target" : NodeSocket(is_input = True, name = "Target", node = self,),
  256. "Enable" : NodeSocket(is_input = True, name = "Enable", node = self,), }
  257. self.outputs = {
  258. "Output Relationship" : NodeSocket(name = "Output Relationship", node=self) }
  259. self.parameters = {
  260. "Name":None,
  261. "Input Relationship":None,
  262. "Offset":None,
  263. "Average":None,
  264. "Axes":None,
  265. #"Invert":None,
  266. "Target Space":None,
  267. "Owner Space":None,
  268. "Influence":None,
  269. "Target":None,
  270. "Enable":None,}
  271. # now set up the traverse target...
  272. self.inputs["Input Relationship"].set_traverse_target(self.outputs["Output Relationship"])
  273. self.outputs["Output Relationship"].set_traverse_target(self.inputs["Input Relationship"])
  274. self.node_type = 'LINK'
  275. def evaluate_input(self, input_name):
  276. return default_evaluate_input(self, input_name)
  277. def GetxForm(self):
  278. return GetxForm(self)
  279. def bExecute(self, context):
  280. prepare_parameters(self)
  281. c = self.GetxForm().bGetObject().constraints.new('COPY_SCALE')
  282. get_target_and_subtarget(self, c)
  283. print(wrapGreen("Creating ")+wrapWhite("Copy Scale")+
  284. wrapGreen(" Constraint for bone: ") +
  285. wrapOrange(self.GetxForm().bGetObject().name))
  286. c.name = self.evaluate_input("Name")
  287. self.bObject = c
  288. props_sockets = {
  289. 'use_offset' : ("Offset", False),
  290. 'use_make_uniform' : ("Average", False),
  291. 'owner_space' : ("Owner Space", 'WORLD'),
  292. 'target_space' : ("Target Space", 'WORLD'),
  293. 'use_x' : ( ("Axes", 0), False),
  294. 'use_y' : ( ("Axes", 1), False),
  295. 'use_z' : ( ("Axes", 2), False),
  296. 'influence' : ("Influence", 1),
  297. 'mute' : ("Enable", True),
  298. }
  299. evaluate_sockets(self, c, props_sockets)
  300. def bFinalize(self, bContext = None):
  301. finish_drivers(self)
  302. def __repr__(self):
  303. return self.signature.__repr__()
  304. def fill_parameters(self):
  305. fill_parameters(self)
  306. class LinkCopyTransforms:
  307. '''A node representing Copy Transfoms'''
  308. def __init__(self, signature, base_tree):
  309. self.base_tree=base_tree
  310. self.signature = signature
  311. self.inputs = {
  312. "Input Relationship" : NodeSocket(is_input = True, name = "Input Relationship", node = self,),
  313. "Head/Tail" : NodeSocket(is_input = True, name = "Head/Tail", node = self,),
  314. "UseBBone" : NodeSocket(is_input = True, name = "UseBBone", node = self,),
  315. "Additive" : NodeSocket(is_input = True, name = "Additive", node = self,),
  316. "Mix" : NodeSocket(is_input = True, name = "Mix", node = self,),
  317. "Target Space" : NodeSocket(is_input = True, name = "Target Space", node = self,),
  318. "Owner Space" : NodeSocket(is_input = True, name = "Owner Space", node = self,),
  319. "Influence" : NodeSocket(is_input = True, name = "Influence", node = self,),
  320. "Target" : NodeSocket(is_input = True, name = "Target", node = self,),
  321. "Enable" : NodeSocket(is_input = True, name = "Enable", node = self,), }
  322. self.outputs = {
  323. "Output Relationship" : NodeSocket(name = "Output Relationship", node=self) }
  324. self.parameters = {
  325. "Name":None,
  326. "Input Relationship":None,
  327. "Head/Tail":None,
  328. "UseBBone":None,
  329. "Mix":None,
  330. "Target Space":None,
  331. "Owner Space":None,
  332. "Influence":None,
  333. "Target":None,
  334. "Enable":None,}
  335. # now set up the traverse target...
  336. self.inputs["Input Relationship"].set_traverse_target(self.outputs["Output Relationship"])
  337. self.outputs["Output Relationship"].set_traverse_target(self.inputs["Input Relationship"])
  338. self.node_type = 'LINK'
  339. def evaluate_input(self, input_name):
  340. return default_evaluate_input(self, input_name)
  341. def GetxForm(self):
  342. return GetxForm(self)
  343. def bExecute(self, context):
  344. prepare_parameters(self)
  345. c = self.GetxForm().bGetObject().constraints.new('COPY_TRANSFORMS')
  346. get_target_and_subtarget(self, c)
  347. print(wrapGreen("Creating ")+wrapWhite("Copy Transforms")+
  348. wrapGreen(" Constraint for bone: ") +
  349. wrapOrange(self.GetxForm().bGetObject().name))
  350. c.name = self.evaluate_input("Name")
  351. self.bObject = c
  352. props_sockets = {
  353. 'head_tail' : ("Head/Tail", 0),
  354. 'use_bbone_shape' : ("UseBBone", False),
  355. 'mix_mode' : ("Mix", 'REPLACE'),
  356. 'owner_space' : ("Owner Space", 'WORLD'),
  357. 'target_space' : ("Target Space", 'WORLD'),
  358. 'influence' : ("Influence", 1),
  359. 'mute' : ("Enable", False)
  360. }
  361. evaluate_sockets(self, c, props_sockets)
  362. def bFinalize(self, bContext = None):
  363. finish_drivers(self)
  364. def __repr__(self):
  365. return self.signature.__repr__()
  366. def fill_parameters(self):
  367. fill_parameters(self)
  368. transformation_props_sockets = {
  369. 'use_motion_extrapolate' : ("Extrapolate", False),
  370. 'map_from' : ("Map From", 'LOCATION'),
  371. 'from_rotation_mode' : ("Rotation Mode", 'AUTO'),
  372. 'from_min_x' : ("X Min From", 0.0),
  373. 'from_max_x' : ("X Max From", 0.0),
  374. 'from_min_y' : ("Y Min From", 0.0),
  375. 'from_max_y' : ("Y Max From", 0.0),
  376. 'from_min_z' : ("Z Min From", 0.0),
  377. 'from_max_z' : ("Z Max From", 0.0),
  378. 'from_min_x_rot' : ("X Min From", 0.0),
  379. 'from_max_x_rot' : ("X Max From", 0.0),
  380. 'from_min_y_rot' : ("Y Min From", 0.0),
  381. 'from_max_y_rot' : ("Y Max From", 0.0),
  382. 'from_min_z_rot' : ("Z Min From", 0.0),
  383. 'from_max_z_rot' : ("Z Max From", 0.0),
  384. 'from_min_x_scale' : ("X Min From", 0.0),
  385. 'from_max_x_scale' : ("X Max From", 0.0),
  386. 'from_min_y_scale' : ("Y Min From", 0.0),
  387. 'from_max_y_scale' : ("Y Max From", 0.0),
  388. 'from_min_z_scale' : ("Z Min From", 0.0),
  389. 'from_max_z_scale' : ("Z Max From", 0.0),
  390. 'map_to' : ("Map To", "LOCATION"),
  391. 'map_to_x_from' : ("X Source Axis", "X"),
  392. 'map_to_y_from' : ("Y Source Axis", "Y"),
  393. 'map_to_z_from' : ("Z Source Axis", "Z"),
  394. 'to_min_x' : ("X Min To", 0.0),
  395. 'to_max_x' : ("X Max To", 0.0),
  396. 'to_min_y' : ("Y Min To", 0.0),
  397. 'to_max_y' : ("Y Max To", 0.0),
  398. 'to_min_z' : ("Z Min To", 0.0),
  399. 'to_max_z' : ("Z Max To", 0.0),
  400. 'to_min_x_rot' : ("X Min To", 0.0),
  401. 'to_max_x_rot' : ("X Max To", 0.0),
  402. 'to_min_y_rot' : ("Y Min To", 0.0),
  403. 'to_max_y_rot' : ("Y Max To", 0.0),
  404. 'to_min_z_rot' : ("Z Min To", 0.0),
  405. 'to_max_z_rot' : ("Z Max To", 0.0),
  406. 'to_min_x_scale' : ("X Min To", 0.0),
  407. 'to_max_x_scale' : ("X Max To", 0.0),
  408. 'to_min_y_scale' : ("Y Min To", 0.0),
  409. 'to_max_y_scale' : ("Y Max To", 0.0),
  410. 'to_min_z_scale' : ("Z Min To", 0.0),
  411. 'to_max_z_scale' : ("Z Max To", 0.0),
  412. 'to_euler_order' : ("Rotation Mode", "AUTO"),
  413. 'mix_mode' : ("Mix Mode (Translation)", "ADD"),
  414. 'mix_mode_rot' : ("Mix Mode (Rotation)", "ADD"),
  415. 'mix_mode_scale' : ("Mix Mode (Scale)", "MULTIPLY"),
  416. 'owner_space' : ("Owner Space", 'WORLD'),
  417. 'target_space' : ("Target Space", 'WORLD'),
  418. 'influence' : ("Influence", 1),
  419. 'mute' : ("Enable", False),
  420. }
  421. class LinkTransformation:
  422. '''A node representing Copy Transfoms'''
  423. def __init__(self, signature, base_tree):
  424. self.base_tree=base_tree
  425. self.signature = signature
  426. self.inputs = {
  427. "Input Relationship" : NodeSocket(is_input = True, name = "Input Relationship", node = self,),
  428. "Target Space" : NodeSocket(is_input = True, name = "Target Space", node = self,),
  429. "Owner Space" : NodeSocket(is_input = True, name = "Owner Space", node = self,),
  430. "Influence" : NodeSocket(is_input = True, name = "Influence", node = self,),
  431. "Target" : NodeSocket(is_input = True, name = "Target", node = self,),
  432. "Enable" : NodeSocket(is_input = True, name = "Enable", node = self,),
  433. "Extrapolate" : NodeSocket(is_input = True, name = "Extrapolate", node = self,),
  434. "Map From" : NodeSocket(is_input = True, name = "Map From", node = self,),
  435. "Rotation Mode" : NodeSocket(is_input = True, name = "Rotation Mode", node = self,),
  436. "X Min From" : NodeSocket(is_input = True, name = "X Min From", node = self,),
  437. "X Max From" : NodeSocket(is_input = True, name = "X Max From", node = self,),
  438. "Y Min From" : NodeSocket(is_input = True, name = "Y Min From", node = self,),
  439. "Y Max From" : NodeSocket(is_input = True, name = "Y Max From", node = self,),
  440. "Z Min From" : NodeSocket(is_input = True, name = "Z Min From", node = self,),
  441. "Z Max From" : NodeSocket(is_input = True, name = "Z Max From", node = self,),
  442. "Map To" : NodeSocket(is_input = True, name = "Map To", node = self,),
  443. "X Source Axis" : NodeSocket(is_input = True, name = "X Source Axis", node = self,),
  444. "X Min To" : NodeSocket(is_input = True, name = "X Min To", node = self,),
  445. "X Max To" : NodeSocket(is_input = True, name = "X Max To", node = self,),
  446. "Y Source Axis" : NodeSocket(is_input = True, name = "Y Source Axis", node = self,),
  447. "Y Min To" : NodeSocket(is_input = True, name = "Y Min To", node = self,),
  448. "Y Max To" : NodeSocket(is_input = True, name = "Y Max To", node = self,),
  449. "Z Source Axis" : NodeSocket(is_input = True, name = "Z Source Axis", node = self,),
  450. "Z Min To" : NodeSocket(is_input = True, name = "Z Min To", node = self,),
  451. "Z Max To" : NodeSocket(is_input = True, name = "Z Max To", node = self,),
  452. "Rotation Mode" : NodeSocket(is_input = True, name = "Rotation Mode", node = self,),
  453. "Mix Mode (Translation)" : NodeSocket(is_input = True, name = "Mix Mode (Translation)", node = self,),
  454. "Mix Mode (Rotation)" : NodeSocket(is_input = True, name = "Mix Mode (Rotation)", node = self,),
  455. "Mix Mode (Scale)" : NodeSocket(is_input = True, name = "Mix Mode (Scale)", node = self,),
  456. }
  457. self.outputs = {
  458. "Output Relationship" : NodeSocket(name = "Output Relationship", node=self) }
  459. self.parameters = {
  460. "Name" : None,
  461. "Input Relationship" : None,
  462. "Target Space" : None,
  463. "Owner Space" : None,
  464. "Influence" : None,
  465. "Target" : None,
  466. "Enable" : None,
  467. "Extrapolate" : None,
  468. "Map From" : None,
  469. "Rotation Mode" : None,
  470. "X Min From" : None,
  471. "X Max From" : None,
  472. "Y Min From" : None,
  473. "Y Max From" : None,
  474. "Z Min From" : None,
  475. "Z Max From" : None,
  476. "Map To" : None,
  477. "X Source Axis" : None,
  478. "X Min To" : None,
  479. "X Max To" : None,
  480. "Y Source Axis" : None,
  481. "Y Min To" : None,
  482. "Y Max To" : None,
  483. "Z Source Axis" : None,
  484. "Z Min To" : None,
  485. "Z Max To" : None,
  486. "Rotation Order" : None,
  487. "Mix Mode (Translation)" : None,
  488. "Mix Mode (Rotation)" : None,
  489. "Mix Mode (Scale)" : None,}
  490. # now set up the traverse target...
  491. self.inputs["Input Relationship"].set_traverse_target(self.outputs["Output Relationship"])
  492. self.outputs["Output Relationship"].set_traverse_target(self.inputs["Input Relationship"])
  493. self.node_type = 'LINK'
  494. def evaluate_input(self, input_name):
  495. return default_evaluate_input(self, input_name)
  496. def GetxForm(self):
  497. return GetxForm(self)
  498. def bExecute(self, context):
  499. prepare_parameters(self)
  500. c = self.GetxForm().bGetObject().constraints.new('TRANSFORM')
  501. get_target_and_subtarget(self, c)
  502. print(wrapGreen("Creating ")+wrapWhite("Transformation")+
  503. wrapGreen(" Constraint for bone: ") +
  504. wrapOrange(self.GetxForm().bGetObject().name))
  505. c.name = self.evaluate_input("Name")
  506. self.bObject = c
  507. props_sockets = transformation_props_sockets
  508. evaluate_sockets(self, c, props_sockets)
  509. def bFinalize(self, bContext = None):
  510. finish_drivers(self)
  511. def __repr__(self):
  512. return self.signature.__repr__()
  513. def fill_parameters(self):
  514. fill_parameters(self)
  515. class LinkLimitLocation:
  516. def __init__(self, signature, base_tree):
  517. self.base_tree=base_tree
  518. self.signature = signature
  519. self.inputs = {
  520. "Input Relationship" : NodeSocket(is_input = True, name = "Input Relationship", node = self,),
  521. "Use Max X" : NodeSocket(is_input = True, name = "Use Max X", node = self,),
  522. "Max X" : NodeSocket(is_input = True, name = "Max X", node = self,),
  523. "Use Max Y" : NodeSocket(is_input = True, name = "Use Max Y", node = self,),
  524. "Max Y" : NodeSocket(is_input = True, name = "Max Y", node = self,),
  525. "Use Max Z" : NodeSocket(is_input = True, name = "Use Max Z", node = self,),
  526. "Max Z" : NodeSocket(is_input = True, name = "Max Z", node = self,),
  527. "Use Min X" : NodeSocket(is_input = True, name = "Use Min X", node = self,),
  528. "Min X" : NodeSocket(is_input = True, name = "Min X", node = self,),
  529. "Use Min Y" : NodeSocket(is_input = True, name = "Use Min Y", node = self,),
  530. "Min Y" : NodeSocket(is_input = True, name = "Min Y", node = self,),
  531. "Use Min Z" : NodeSocket(is_input = True, name = "Use Min Z", node = self,),
  532. "Min Z" : NodeSocket(is_input = True, name = "Min Z", node = self,),
  533. "Affect Transform" : NodeSocket(is_input = True, name = "Affect Transform", node = self,),
  534. "Owner Space" : NodeSocket(is_input = True, name = "Owner Space", node = self,),
  535. "Influence" : NodeSocket(is_input = True, name = "Influence", node = self,),
  536. "Enable" : NodeSocket(is_input = True, name = "Enable", node = self,), }
  537. self.outputs = {
  538. "Output Relationship" : NodeSocket(name = "Output Relationship", node=self) }
  539. self.parameters = {
  540. "Name":None,
  541. "Input Relationship":None,
  542. "Use Max X":None,
  543. "Max X":None,
  544. "Use Max Y":None,
  545. "Max Y":None,
  546. "Use Max Z":None,
  547. "Max Z":None,
  548. "Use Min X":None,
  549. "Min X":None,
  550. "Use Min Y":None,
  551. "Min Y":None,
  552. "Use Min Z":None,
  553. "Min Z":None,
  554. "Affect Transform":None,
  555. "Owner Space":None,
  556. "Influence":None,
  557. "Enable":None,}
  558. # now set up the traverse target...
  559. self.inputs["Input Relationship"].set_traverse_target(self.outputs["Output Relationship"])
  560. self.outputs["Output Relationship"].set_traverse_target(self.inputs["Input Relationship"])
  561. self.node_type = 'LINK'
  562. def evaluate_input(self, input_name):
  563. return default_evaluate_input(self, input_name)
  564. def GetxForm(self):
  565. return GetxForm(self)
  566. def bExecute(self, context):
  567. prepare_parameters(self)
  568. c = self.GetxForm().bGetObject().constraints.new('LIMIT_LOCATION')
  569. #
  570. print(wrapGreen("Creating ")+wrapWhite("Limit Location")+
  571. wrapGreen(" Constraint for bone: ") +
  572. wrapOrange(self.GetxForm().bGetObject().name))
  573. c.name = self.evaluate_input("Name")
  574. self.bObject = c
  575. props_sockets = {
  576. 'use_transform_limit' : ("Affect Transform", False),
  577. 'use_max_x' : ("Use Max X", False),
  578. 'use_max_y' : ("Use Max Y", False),
  579. 'use_max_z' : ("Use Max Z", False),
  580. 'use_min_x' : ("Use Min X", False),
  581. 'use_min_y' : ("Use Min Y", False),
  582. 'use_min_z' : ("Use Min Z", False),
  583. 'max_x' : ("Max X", 0),
  584. 'max_y' : ("Max Y", 0),
  585. 'max_z' : ("Max Z", 0),
  586. 'min_x' : ("Min X", 0),
  587. 'min_y' : ("Min Y", 0),
  588. 'min_z' : ("Min Z", 0),
  589. 'owner_space' : ("Owner Space", 'WORLD'),
  590. 'influence' : ("Influence", 1),
  591. 'mute' : ("Enable", True),
  592. }
  593. evaluate_sockets(self, c, props_sockets)
  594. def bFinalize(self, bContext = None):
  595. finish_drivers(self)
  596. def __repr__(self):
  597. return self.signature.__repr__()
  598. def fill_parameters(self):
  599. fill_parameters(self)
  600. class LinkLimitRotation:
  601. def __init__(self, signature, base_tree):
  602. self.base_tree=base_tree
  603. self.signature = signature
  604. self.inputs = {
  605. "Input Relationship" : NodeSocket(is_input = True, name = "Input Relationship", node = self,),
  606. "Use X" : NodeSocket(is_input = True, name = "Use X", node = self,),
  607. "Use Y" : NodeSocket(is_input = True, name = "Use Y", node = self,),
  608. "Use Z" : NodeSocket(is_input = True, name = "Use Z", node = self,),
  609. "Max X" : NodeSocket(is_input = True, name = "Max X", node = self,),
  610. "Max Y" : NodeSocket(is_input = True, name = "Max Y", node = self,),
  611. "Max Z" : NodeSocket(is_input = True, name = "Max Z", node = self,),
  612. "Min X" : NodeSocket(is_input = True, name = "Min X", node = self,),
  613. "Min Y" : NodeSocket(is_input = True, name = "Min Y", node = self,),
  614. "Min Z" : NodeSocket(is_input = True, name = "Min Z", node = self,),
  615. "Affect Transform" : NodeSocket(is_input = True, name = "Affect Transform", node = self,),
  616. "Owner Space" : NodeSocket(is_input = True, name = "Owner Space", node = self,),
  617. "Influence" : NodeSocket(is_input = True, name = "Influence", node = self,),
  618. "Enable" : NodeSocket(is_input = True, name = "Enable", node = self,), }
  619. self.outputs = {
  620. "Output Relationship" : NodeSocket(name = "Output Relationship", node=self) }
  621. self.parameters = {
  622. "Name":None,
  623. "Input Relationship":None,
  624. "Use X":None,
  625. "Use Y":None,
  626. "Use Z":None,
  627. "Max X":None,
  628. "Max Y":None,
  629. "Max Z":None,
  630. "Min X":None,
  631. "Min Y":None,
  632. "Min Z":None,
  633. "Affect Transform":None,
  634. "Owner Space":None,
  635. "Influence":None,
  636. "Enable":None,}
  637. # now set up the traverse target...
  638. self.inputs["Input Relationship"].set_traverse_target(self.outputs["Output Relationship"])
  639. self.outputs["Output Relationship"].set_traverse_target(self.inputs["Input Relationship"])
  640. self.node_type = 'LINK'
  641. def evaluate_input(self, input_name):
  642. return default_evaluate_input(self, input_name)
  643. def GetxForm(self):
  644. return GetxForm(self)
  645. def bExecute(self, context):
  646. prepare_parameters(self)
  647. c = self.GetxForm().bGetObject().constraints.new('LIMIT_ROTATION')
  648. print(wrapGreen("Creating ")+wrapWhite("Limit Rotation")+
  649. wrapGreen(" Constraint for bone: ") +
  650. wrapOrange(self.GetxForm().bGetObject().name))
  651. c.name = self.evaluate_input("Name")
  652. self.bObject = c
  653. props_sockets = {
  654. 'use_transform_limit' : ("Affect Transform", False),
  655. 'use_limit_x' : ("Use X", False),
  656. 'use_limit_y' : ("Use Y", False),
  657. 'use_limit_z' : ("Use Z", False),
  658. 'max_x' : ("Max X", 0),
  659. 'max_y' : ("Max Y", 0),
  660. 'max_z' : ("Max Z", 0),
  661. 'min_x' : ("Min X", 0),
  662. 'min_y' : ("Min Y", 0),
  663. 'min_z' : ("Min Z", 0),
  664. 'owner_space' : ("Owner Space", 'WORLD'),
  665. 'influence' : ("Influence", 1),
  666. 'mute' : ("Enable", True),
  667. }
  668. evaluate_sockets(self, c, props_sockets)
  669. def bFinalize(self, bContext = None):
  670. finish_drivers(self)
  671. def __repr__(self):
  672. return self.signature.__repr__()
  673. def fill_parameters(self):
  674. fill_parameters(self)
  675. class LinkLimitScale:
  676. def __init__(self, signature, base_tree):
  677. self.base_tree=base_tree
  678. self.signature = signature
  679. self.inputs = {
  680. "Input Relationship" : NodeSocket(is_input = True, name = "Input Relationship", node = self,),
  681. "Use Max X" : NodeSocket(is_input = True, name = "Use Max X", node = self,),
  682. "Max X" : NodeSocket(is_input = True, name = "Max X", node = self,),
  683. "Use Max Y" : NodeSocket(is_input = True, name = "Use Max Y", node = self,),
  684. "Max Y" : NodeSocket(is_input = True, name = "Max Y", node = self,),
  685. "Use Max Z" : NodeSocket(is_input = True, name = "Use Max Z", node = self,),
  686. "Max Z" : NodeSocket(is_input = True, name = "Max Z", node = self,),
  687. "Use Min X" : NodeSocket(is_input = True, name = "Use Min X", node = self,),
  688. "Min X" : NodeSocket(is_input = True, name = "Min X", node = self,),
  689. "Use Min Y" : NodeSocket(is_input = True, name = "Use Min Y", node = self,),
  690. "Min Y" : NodeSocket(is_input = True, name = "Min Y", node = self,),
  691. "Use Min Z" : NodeSocket(is_input = True, name = "Use Min Z", node = self,),
  692. "Min Z" : NodeSocket(is_input = True, name = "Min Z", node = self,),
  693. "Affect Transform" : NodeSocket(is_input = True, name = "Affect Transform", node = self,),
  694. "Owner Space" : NodeSocket(is_input = True, name = "Owner Space", node = self,),
  695. "Influence" : NodeSocket(is_input = True, name = "Influence", node = self,),
  696. "Enable" : NodeSocket(is_input = True, name = "Enable", node = self,), }
  697. self.outputs = {
  698. "Output Relationship" : NodeSocket(name = "Output Relationship", node=self) }
  699. self.parameters = {
  700. "Name":None,
  701. "Input Relationship":None,
  702. "Use Max X":None,
  703. "Max X":None,
  704. "Use Max Y":None,
  705. "Max Y":None,
  706. "Use Max Z":None,
  707. "Max Z":None,
  708. "Use Min X":None,
  709. "Min X":None,
  710. "Use Min Y":None,
  711. "Min Y":None,
  712. "Use Min Z":None,
  713. "Min Z":None,
  714. "Affect Transform":None,
  715. "Owner Space":None,
  716. "Influence":None,
  717. "Enable":None,}
  718. # now set up the traverse target...
  719. self.inputs["Input Relationship"].set_traverse_target(self.outputs["Output Relationship"])
  720. self.outputs["Output Relationship"].set_traverse_target(self.inputs["Input Relationship"])
  721. self.node_type = 'LINK'
  722. def evaluate_input(self, input_name):
  723. return default_evaluate_input(self, input_name)
  724. def GetxForm(self):
  725. return GetxForm(self)
  726. def bExecute(self, context):
  727. prepare_parameters(self)
  728. c = self.GetxForm().bGetObject().constraints.new('LIMIT_SCALE')
  729. print(wrapGreen("Creating ")+wrapWhite("Limit Scale")+
  730. wrapGreen(" Constraint for bone: ") +
  731. wrapOrange(self.GetxForm().bGetObject().name))
  732. c.name = self.evaluate_input("Name")
  733. self.bObject = c
  734. props_sockets = {
  735. 'use_transform_limit' : ("Affect Transform", False),
  736. 'use_max_x' : ("Use Max X", False),
  737. 'use_max_y' : ("Use Max Y", False),
  738. 'use_max_z' : ("Use Max Z", False),
  739. 'use_min_x' : ("Use Min X", False),
  740. 'use_min_y' : ("Use Min Y", False),
  741. 'use_min_z' : ("Use Min Z", False),
  742. 'max_x' : ("Max X", 0),
  743. 'max_y' : ("Max Y", 0),
  744. 'max_z' : ("Max Z", 0),
  745. 'min_x' : ("Min X", 0),
  746. 'min_y' : ("Min Y", 0),
  747. 'min_z' : ("Min Z", 0),
  748. 'owner_space' : ("Owner Space", 'WORLD'),
  749. 'influence' : ("Influence", 1),
  750. 'mute' : ("Enable", True),
  751. }
  752. evaluate_sockets(self, c, props_sockets)
  753. def bFinalize(self, bContext = None):
  754. finish_drivers(self)
  755. def __repr__(self):
  756. return self.signature.__repr__()
  757. def fill_parameters(self):
  758. fill_parameters(self)
  759. class LinkLimitDistance:
  760. def __init__(self, signature, base_tree):
  761. self.base_tree=base_tree
  762. self.signature = signature
  763. self.inputs = {
  764. "Input Relationship" : NodeSocket(is_input = True, name = "Input Relationship", node = self,),
  765. "Head/Tail" : NodeSocket(is_input = True, name = "Head/Tail", node = self,),
  766. "UseBBone" : NodeSocket(is_input = True, name = "UseBBone", node = self,),
  767. "Distance" : NodeSocket(is_input = True, name = "Distance", node = self,),
  768. "Clamp Region" : NodeSocket(is_input = True, name = "Clamp Region", node = self,),
  769. "Affect Transform" : NodeSocket(is_input = True, name = "Affect Transform", node = self,),
  770. "Owner Space" : NodeSocket(is_input = True, name = "Owner Space", node = self,),
  771. "Target Space" : NodeSocket(is_input = True, name = "Target Space", node = self,),
  772. "Influence" : NodeSocket(is_input = True, name = "Influence", node = self,),
  773. "Target" : NodeSocket(is_input = True, name = "Target", node = self,),
  774. "Enable" : NodeSocket(is_input = True, name = "Enable", node = self,), }
  775. self.outputs = {
  776. "Output Relationship" : NodeSocket(name = "Output Relationship", node=self) }
  777. self.parameters = {
  778. "Name":None,
  779. "Input Relationship":None,
  780. "Head/Tail":None,
  781. "UseBBone":None,
  782. "Distance":None,
  783. "Clamp Region":None,
  784. "Affect Transform":None,
  785. "Owner Space":None,
  786. "Target Space":None,
  787. "Influence":None,
  788. "Target":None,
  789. "Enable":None,}
  790. # now set up the traverse target...
  791. self.inputs["Input Relationship"].set_traverse_target(self.outputs["Output Relationship"])
  792. self.outputs["Output Relationship"].set_traverse_target(self.inputs["Input Relationship"])
  793. self.node_type = 'LINK'
  794. def evaluate_input(self, input_name):
  795. return default_evaluate_input(self, input_name)
  796. def GetxForm(self):
  797. return GetxForm(self)
  798. def bExecute(self, context):
  799. prepare_parameters(self)
  800. print(wrapGreen("Creating ")+wrapWhite("Limit Distance")+
  801. wrapGreen(" Constraint for bone: ") +
  802. wrapOrange(self.GetxForm().bGetObject().name))
  803. c = self.GetxForm().bGetObject().constraints.new('LIMIT_DISTANCE')
  804. get_target_and_subtarget(self, c)
  805. c.name = self.evaluate_input("Name")
  806. self.bObject = c
  807. #
  808. # TODO: set distance automagically
  809. # IMPORTANT TODO BUG
  810. props_sockets = {
  811. 'distance' : ("Distance", 0),
  812. 'head_tail' : ("Head/Tail", 0),
  813. 'limit_mode' : ("Clamp Region", "LIMITDIST_INSIDE"),
  814. 'use_bbone_shape' : ("UseBBone", False),
  815. 'use_transform_limit' : ("Affect Transform", 1),
  816. 'owner_space' : ("Owner Space", 1),
  817. 'target_space' : ("Target Space", 1),
  818. 'influence' : ("Influence", 1),
  819. 'mute' : ("Enable", True),
  820. }
  821. evaluate_sockets(self, c, props_sockets)
  822. def bFinalize(self, bContext = None):
  823. finish_drivers(self)
  824. def __repr__(self):
  825. return self.signature.__repr__()
  826. def fill_parameters(self):
  827. fill_parameters(self)
  828. # Tracking
  829. class LinkStretchTo:
  830. def __init__(self, signature, base_tree):
  831. self.base_tree=base_tree
  832. self.signature = signature
  833. self.inputs = {
  834. "Input Relationship" : NodeSocket(is_input = True, name = "Input Relationship", node = self,),
  835. "Head/Tail" : NodeSocket(is_input = True, name = "Head/Tail", node = self,),
  836. "UseBBone" : NodeSocket(is_input = True, name = "UseBBone", node = self,),
  837. "Original Length" : NodeSocket(is_input = True, name = "Original Length", node = self,),
  838. "Volume Variation" : NodeSocket(is_input = True, name = "Volume Variation", node = self,),
  839. "Use Volume Min" : NodeSocket(is_input = True, name = "Use Volume Min", node = self,),
  840. "Volume Min" : NodeSocket(is_input = True, name = "Volume Min", node = self,),
  841. "Use Volume Max" : NodeSocket(is_input = True, name = "Use Volume Max", node = self,),
  842. "Volume Max" : NodeSocket(is_input = True, name = "Volume Max", node = self,),
  843. "Smooth" : NodeSocket(is_input = True, name = "Smooth", node = self,),
  844. "Maintain Volume" : NodeSocket(is_input = True, name = "Maintain Volume", node = self,),
  845. "Rotation" : NodeSocket(is_input = True, name = "Rotation", node = self,),
  846. "Influence" : NodeSocket(is_input = True, name = "Influence", node = self,),
  847. "Target" : NodeSocket(is_input = True, name = "Target", node = self,),
  848. "Enable" : NodeSocket(is_input = True, name = "Enable", node = self,), }
  849. self.outputs = {
  850. "Output Relationship" : NodeSocket(name = "Output Relationship", node=self) }
  851. self.parameters = {
  852. "Name":None,
  853. "Input Relationship":None,
  854. "Head/Tail":None,
  855. "UseBBone":None,
  856. "Original Length":None,
  857. "Volume Variation":None,
  858. "Use Volume Min":None,
  859. "Volume Min":None,
  860. "Use Volume Max":None,
  861. "Volume Max":None,
  862. "Smooth":None,
  863. "Maintain Volume":None,
  864. "Rotation":None,
  865. "Influence":None,
  866. "Target":None,
  867. "Enable":None,}
  868. # now set up the traverse target...
  869. self.inputs["Input Relationship"].set_traverse_target(self.outputs["Output Relationship"])
  870. self.outputs["Output Relationship"].set_traverse_target(self.inputs["Input Relationship"])
  871. self.node_type = 'LINK'
  872. def evaluate_input(self, input_name):
  873. return default_evaluate_input(self, input_name)
  874. def GetxForm(self):
  875. return GetxForm(self)
  876. def bExecute(self, context):
  877. prepare_parameters(self)
  878. print(wrapGreen("Creating ")+wrapWhite("Stretch-To")+
  879. wrapGreen(" Constraint for bone: ") +
  880. wrapOrange(self.GetxForm().bGetObject().name))
  881. c = self.GetxForm().bGetObject().constraints.new('STRETCH_TO')
  882. get_target_and_subtarget(self, c)
  883. c.name = self.evaluate_input("Name")
  884. self.bObject = c
  885. props_sockets = {
  886. 'head_tail' : ("Head/Tail", 0),
  887. 'use_bbone_shape' : ("UseBBone", False),
  888. 'bulge' : ("Volume Variation", 0),
  889. 'use_bulge_min' : ("Use Volume Min", False),
  890. 'bulge_min' : ("Volume Min", 0),
  891. 'use_bulge_max' : ("Use Volume Max", False),
  892. 'bulge_max' : ("Volume Max", 0),
  893. 'bulge_smooth' : ("Smooth", 0),
  894. 'volume' : ("Maintain Volume", 'VOLUME_XZX'),
  895. 'keep_axis' : ("Rotation", 'PLANE_X'),
  896. 'rest_length' : ("Original Length", self.GetxForm().bGetObject().bone.length),
  897. 'influence' : ("Influence", 1),
  898. 'mute' : ("Enable", True),
  899. }
  900. evaluate_sockets(self, c, props_sockets)
  901. if (self.evaluate_input("Original Length") == 0):
  902. # this is meant to be set automatically.
  903. c.rest_length = self.GetxForm().bGetObject().bone.length
  904. def bFinalize(self, bContext = None):
  905. finish_drivers(self)
  906. def __repr__(self):
  907. return self.signature.__repr__()
  908. def fill_parameters(self):
  909. fill_parameters(self)
  910. class LinkDampedTrack:
  911. def __init__(self, signature, base_tree):
  912. self.base_tree=base_tree
  913. self.signature = signature
  914. self.inputs = {
  915. "Input Relationship" : NodeSocket(is_input = True, name = "Input Relationship", node = self,),
  916. "Head/Tail" : NodeSocket(is_input = True, name = "Head/Tail", node = self,),
  917. "UseBBone" : NodeSocket(is_input = True, name = "UseBBone", node = self,),
  918. "Track Axis" : NodeSocket(is_input = True, name = "Track Axis", node = self,),
  919. "Influence" : NodeSocket(is_input = True, name = "Influence", node = self,),
  920. "Target" : NodeSocket(is_input = True, name = "Target", node = self,),
  921. "Enable" : NodeSocket(is_input = True, name = "Enable", node = self,), }
  922. self.outputs = {
  923. "Output Relationship" : NodeSocket(name = "Output Relationship", node=self) }
  924. self.parameters = {
  925. "Name":None,
  926. "Input Relationship":None,
  927. "Head/Tail":None,
  928. "UseBBone":None,
  929. "Track Axis":None,
  930. "Influence":None,
  931. "Target":None,
  932. "Enable":None,}
  933. # now set up the traverse target...
  934. self.inputs["Input Relationship"].set_traverse_target(self.outputs["Output Relationship"])
  935. self.outputs["Output Relationship"].set_traverse_target(self.inputs["Input Relationship"])
  936. self.node_type = 'LINK'
  937. def evaluate_input(self, input_name):
  938. return default_evaluate_input(self, input_name)
  939. def GetxForm(self):
  940. return GetxForm(self)
  941. def bExecute(self, context):
  942. prepare_parameters(self)
  943. print(wrapGreen("Creating ")+wrapWhite("Damped Track")+
  944. wrapGreen(" Constraint for bone: ") +
  945. wrapOrange(self.GetxForm().bGetObject().name))
  946. c = self.GetxForm().bGetObject().constraints.new('DAMPED_TRACK')
  947. get_target_and_subtarget(self, c)
  948. c.name = self.evaluate_input("Name")
  949. self.bObject = c
  950. props_sockets = {
  951. 'head_tail' : ("Head/Tail", 0),
  952. 'use_bbone_shape' : ("UseBBone", False),
  953. 'track_axis' : ("Track Axis", 'TRACK_Y'),
  954. 'influence' : ("Influence", 1),
  955. 'mute' : ("Enable", True),
  956. }
  957. evaluate_sockets(self, c, props_sockets)
  958. def bFinalize(self, bContext = None):
  959. finish_drivers(self)
  960. def __repr__(self):
  961. return self.signature.__repr__()
  962. def fill_parameters(self):
  963. fill_parameters(self)
  964. class LinkLockedTrack:
  965. def __init__(self, signature, base_tree):
  966. self.base_tree=base_tree
  967. self.signature = signature
  968. self.inputs = {
  969. "Input Relationship" : NodeSocket(is_input = True, name = "Input Relationship", node = self,),
  970. "Head/Tail" : NodeSocket(is_input = True, name = "Head/Tail", node = self,),
  971. "UseBBone" : NodeSocket(is_input = True, name = "UseBBone", node = self,),
  972. "Track Axis" : NodeSocket(is_input = True, name = "Track Axis", node = self,),
  973. "Lock Axis" : NodeSocket(is_input = True, name = "Lock Axis", node = self,),
  974. "Influence" : NodeSocket(is_input = True, name = "Influence", node = self,),
  975. "Target" : NodeSocket(is_input = True, name = "Target", node = self,),
  976. "Enable" : NodeSocket(is_input = True, name = "Enable", node = self,), }
  977. self.outputs = {
  978. "Output Relationship" : NodeSocket(name = "Output Relationship", node=self) }
  979. self.parameters = {
  980. "Name":None,
  981. "Input Relationship":None,
  982. "Head/Tail":None,
  983. "UseBBone":None,
  984. "Track Axis":None,
  985. "Lock Axis":None,
  986. "Influence":None,
  987. "Target":None,
  988. "Enable":None,}
  989. # now set up the traverse target...
  990. self.inputs["Input Relationship"].set_traverse_target(self.outputs["Output Relationship"])
  991. self.outputs["Output Relationship"].set_traverse_target(self.inputs["Input Relationship"])
  992. self.node_type = 'LINK'
  993. def evaluate_input(self, input_name):
  994. return default_evaluate_input(self, input_name)
  995. def GetxForm(self):
  996. return GetxForm(self)
  997. def bExecute(self, context):
  998. prepare_parameters(self)
  999. print(wrapGreen("Creating ")+wrapWhite("Locked Track")+
  1000. wrapGreen(" Constraint for bone: ") +
  1001. wrapOrange(self.GetxForm().bGetObject().name))
  1002. c = self.GetxForm().bGetObject().constraints.new('LOCKED_TRACK')
  1003. get_target_and_subtarget(self, c)
  1004. c.name = self.evaluate_input("Name")
  1005. self.bObject = c
  1006. props_sockets = {
  1007. 'head_tail' : ("Head/Tail", 0),
  1008. 'use_bbone_shape' : ("UseBBone", False),
  1009. 'track_axis' : ("Track Axis", 'TRACK_Y'),
  1010. 'lock_axis' : ("Lock Axis", 'UP_X'),
  1011. 'influence' : ("Influence", 1),
  1012. 'mute' : ("Enable", True),
  1013. }
  1014. evaluate_sockets(self, c, props_sockets)
  1015. def bFinalize(self, bContext = None):
  1016. finish_drivers(self)
  1017. def __repr__(self):
  1018. return self.signature.__repr__()
  1019. def fill_parameters(self):
  1020. fill_parameters(self)
  1021. class LinkTrackTo:
  1022. def __init__(self, signature, base_tree):
  1023. self.base_tree=base_tree
  1024. self.signature = signature
  1025. self.inputs = {
  1026. "Input Relationship" : NodeSocket(is_input = True, name = "Input Relationship", node = self,),
  1027. "Head/Tail" : NodeSocket(is_input = True, name = "Head/Tail", node = self,),
  1028. "UseBBone" : NodeSocket(is_input = True, name = "UseBBone", node = self,),
  1029. "Track Axis" : NodeSocket(is_input = True, name = "Track Axis", node = self,),
  1030. "Up Axis" : NodeSocket(is_input = True, name = "Up Axis", node = self,),
  1031. "Use Target Z" : NodeSocket(is_input = True, name = "Use Target Z", node = self,),
  1032. "Influence" : NodeSocket(is_input = True, name = "Influence", node = self,),
  1033. "Target" : NodeSocket(is_input = True, name = "Target", node = self,),
  1034. "Enable" : NodeSocket(is_input = True, name = "Enable", node = self,), }
  1035. self.outputs = {
  1036. "Output Relationship" : NodeSocket(name = "Output Relationship", node=self) }
  1037. self.parameters = {
  1038. "Name":None,
  1039. "Input Relationship":None,
  1040. "Head/Tail":None,
  1041. "UseBBone":None,
  1042. "Track Axis":None,
  1043. "Up Axis":None,
  1044. "Use Target Z":None,
  1045. "Influence":None,
  1046. "Target":None,
  1047. "Enable":None,}
  1048. # now set up the traverse target...
  1049. self.inputs["Input Relationship"].set_traverse_target(self.outputs["Output Relationship"])
  1050. self.outputs["Output Relationship"].set_traverse_target(self.inputs["Input Relationship"])
  1051. self.node_type = 'LINK'
  1052. def evaluate_input(self, input_name):
  1053. return default_evaluate_input(self, input_name)
  1054. def GetxForm(self):
  1055. return GetxForm(self)
  1056. def bExecute(self, context):
  1057. prepare_parameters(self)
  1058. print(wrapGreen("Creating ")+wrapWhite("Track-To")+
  1059. wrapGreen(" Constraint for bone: ") +
  1060. wrapOrange(self.GetxForm().bGetObject().name))
  1061. c = self.GetxForm().bGetObject().constraints.new('TRACK_TO')
  1062. get_target_and_subtarget(self, c)
  1063. c.name = self.evaluate_input("Name")
  1064. self.bObject = c
  1065. props_sockets = {
  1066. 'head_tail' : ("Head/Tail", 0),
  1067. 'use_bbone_shape' : ("UseBBone", False),
  1068. 'track_axis' : ("Track Axis", "TRACK_Y"),
  1069. 'up_axis' : ("Up Axis", "UP_Z"),
  1070. 'use_target_z' : ("Use Target Z", False),
  1071. 'influence' : ("Influence", 1),
  1072. 'mute' : ("Enable", True),
  1073. }
  1074. evaluate_sockets(self, c, props_sockets)
  1075. def __repr__(self):
  1076. return self.signature.__repr__()
  1077. def fill_parameters(self):
  1078. fill_parameters(self)
  1079. def bFinalize(self, bContext = None):
  1080. finish_drivers(self)
  1081. # relationships & misc.
  1082. class LinkInheritConstraint:
  1083. def __init__(self, signature, base_tree):
  1084. self.base_tree=base_tree
  1085. self.signature = signature
  1086. self.inputs = {
  1087. "Input Relationship" : NodeSocket(is_input = True, name = "Input Relationship", node = self,),
  1088. "Location" : NodeSocket(is_input = True, name = "Location", node = self,),
  1089. "Rotation" : NodeSocket(is_input = True, name = "Rotation", node = self,),
  1090. "Scale" : NodeSocket(is_input = True, name = "Scale", node = self,),
  1091. "Influence" : NodeSocket(is_input = True, name = "Influence", node = self,),
  1092. "Target" : NodeSocket(is_input = True, name = "Target", node = self,),
  1093. "Enable" : NodeSocket(is_input = True, name = "Enable", node = self,), }
  1094. self.outputs = {
  1095. "Output Relationship" : NodeSocket(name = "Output Relationship", node=self) }
  1096. self.parameters = {
  1097. "Name":None,
  1098. "Input Relationship":None,
  1099. "Location":None,
  1100. "Rotation":None,
  1101. "Scale":None,
  1102. "Influence":None,
  1103. "Target":None,
  1104. "Enable":None,}
  1105. self.drivers = {}
  1106. # now set up the traverse target...
  1107. self.inputs["Input Relationship"].set_traverse_target(self.outputs["Output Relationship"])
  1108. self.outputs["Output Relationship"].set_traverse_target(self.inputs["Input Relationship"])
  1109. self.node_type = 'LINK'
  1110. def evaluate_input(self, input_name):
  1111. return default_evaluate_input(self, input_name)
  1112. def GetxForm(self):
  1113. return GetxForm(self)
  1114. def bExecute(self, context):
  1115. prepare_parameters(self)
  1116. print(wrapGreen("Creating ")+wrapWhite("Child-Of")+
  1117. wrapGreen(" Constraint for bone: ") +
  1118. wrapOrange(self.GetxForm().bGetObject().name))
  1119. c = self.GetxForm().bGetObject().constraints.new('CHILD_OF')
  1120. get_target_and_subtarget(self, c)
  1121. c.name = self.evaluate_input("Name")
  1122. self.bObject = c
  1123. props_sockets = {
  1124. 'use_location_x' : (("Location", 0) , 1),
  1125. 'use_location_y' : (("Location", 1) , 1),
  1126. 'use_location_z' : (("Location", 2) , 1),
  1127. 'use_rotation_x' : (("Rotation", 0) , 1),
  1128. 'use_rotation_y' : (("Rotation", 1) , 1),
  1129. 'use_rotation_z' : (("Rotation", 2) , 1),
  1130. 'use_scale_x' : (("Scale" , 0) , 1),
  1131. 'use_scale_y' : (("Scale" , 1) , 1),
  1132. 'use_scale_z' : (("Scale" , 2) , 1),
  1133. 'influence' : ( "Influence" , 1),
  1134. 'mute' : ("Enable", True),
  1135. }
  1136. evaluate_sockets(self, c, props_sockets)
  1137. c.set_inverse_pending
  1138. def __repr__(self):
  1139. return self.signature.__repr__()
  1140. def fill_parameters(self):
  1141. fill_parameters(self)
  1142. def bFinalize(self, bContext = None):
  1143. finish_drivers(self)
  1144. class LinkInverseKinematics:
  1145. def __init__(self, signature, base_tree):
  1146. self.base_tree=base_tree
  1147. self.signature = signature
  1148. self.inputs = {
  1149. "Input Relationship" : NodeSocket(is_input = True, name = "Input Relationship", node = self,),
  1150. "Chain Length" : NodeSocket(is_input = True, name = "Chain Length", node = self,),
  1151. "Use Tail" : NodeSocket(is_input = True, name = "Use Tail", node = self,),
  1152. "Stretch" : NodeSocket(is_input = True, name = "Stretch", node = self,),
  1153. "Position" : NodeSocket(is_input = True, name = "Position", node = self,),
  1154. "Rotation" : NodeSocket(is_input = True, name = "Rotation", node = self,),
  1155. "Influence" : NodeSocket(is_input = True, name = "Influence", node = self,),
  1156. "Target" : NodeSocket(is_input = True, name = "Target", node = self,),
  1157. "Pole Target" : NodeSocket(is_input = True, name = "Pole Target", node = self,),
  1158. "Enable" : NodeSocket(is_input = True, name = "Enable", node = self,), }
  1159. self.outputs = {
  1160. "Output Relationship" : NodeSocket(name = "Output Relationship", node=self) }
  1161. self.parameters = {
  1162. "Name":None,
  1163. "Connected":None,
  1164. "Chain Length":None,
  1165. "Use Tail":None,
  1166. "Stretch":None,
  1167. "Position":None,
  1168. "Rotation":None,
  1169. "Influence":None,
  1170. "Target":None,
  1171. "Pole Target":None,
  1172. "Enable":None,}
  1173. # now set up the traverse target...
  1174. self.inputs["Input Relationship"].set_traverse_target(self.outputs["Output Relationship"])
  1175. self.outputs["Output Relationship"].set_traverse_target(self.inputs["Input Relationship"])
  1176. self.node_type = 'LINK'
  1177. self.bObject = None
  1178. self.drivers = {}
  1179. def evaluate_input(self, input_name):
  1180. return default_evaluate_input(self, input_name)
  1181. def GetxForm(self):
  1182. return GetxForm(self)
  1183. def bExecute(self, context):
  1184. prepare_parameters(self)
  1185. print(wrapGreen("Creating ")+wrapOrange("Inverse Kinematics")+
  1186. wrapGreen(" Constraint for bone: ") +
  1187. wrapOrange(self.GetxForm().bGetObject().name))
  1188. myOb = self.GetxForm().bGetObject()
  1189. c = self.GetxForm().bGetObject().constraints.new('IK')
  1190. get_target_and_subtarget(self, c)
  1191. get_target_and_subtarget(self, c, input_name = 'Pole Target')
  1192. c.name = self.evaluate_input("Name")
  1193. self.bObject = c
  1194. if (c.pole_target): # Calculate the pole angle, the user shouldn't have to.
  1195. pole_object = c.pole_target
  1196. pole_location = pole_object.matrix_world.decompose()[0]
  1197. if (c.pole_subtarget):
  1198. pole_object = c.pole_target.pose.bones[c.pole_subtarget]
  1199. pole_location = pole_object.matrix.decompose()[0]
  1200. #HACK HACK
  1201. handle_location = myOb.bone.tail_local if (self.evaluate_input("Use Tail")) else myOb.bone.head_local
  1202. counter = 0
  1203. parent = myOb
  1204. base_bone = myOb
  1205. while (parent is not None):
  1206. if ((self.evaluate_input("Chain Length") != 0) and (counter > self.evaluate_input("Chain Length"))):
  1207. break
  1208. base_bone = parent
  1209. parent = parent.parent
  1210. counter+=1
  1211. head_location = base_bone.bone.head_local
  1212. pole_normal = (handle_location - head_location).cross(pole_location - head_location)
  1213. vector_u = myOb.bone.x_axis
  1214. vector_v = pole_normal.cross(base_bone.bone.y_axis)
  1215. angle = -1 * vector_u.angle(vector_v)
  1216. # TODO: create warnings for edge cases that fail such as pole target in the same place as handle
  1217. # if (vector_u.cross(vector_v).angle(base_bone.bone.y_axis) < 1):
  1218. # angle = angle
  1219. c.pole_angle = angle
  1220. props_sockets = {
  1221. 'chain_count' : ("Chain Length", 1),
  1222. 'use_tail' : ("Use Tail", True),
  1223. 'use_stretch' : ("Stretch", True),
  1224. "weight" : ("Position", 1.0),
  1225. "orient_weight" : ("Rotation", 0.0),
  1226. "influence" : ("Influence", 1.0),
  1227. 'mute' : ("Enable", True),
  1228. }
  1229. evaluate_sockets(self, c, props_sockets)
  1230. # TODO: handle drivers
  1231. # (it should be assumed we want it on if it's plugged
  1232. # into a driver).
  1233. c.use_location = self.evaluate_input("Position") > 0
  1234. c.use_rotation = self.evaluate_input("Rotation") > 0
  1235. def __repr__(self):
  1236. return self.signature.__repr__()
  1237. def bFinalize(self, bContext = None):
  1238. finish_drivers(self)
  1239. def fill_parameters(self):
  1240. fill_parameters(self)
  1241. # This is kinda a weird design decision?
  1242. class LinkDrivenParameter:
  1243. '''A node representing an armature object'''
  1244. def __init__(self, signature, base_tree):
  1245. self.base_tree=base_tree
  1246. self.executed = False
  1247. self.signature = signature
  1248. self.inputs = {
  1249. "Input Relationship" : NodeSocket(is_input = True, name = "Input Relationship", node = self,),
  1250. "Driver" : NodeSocket(is_input = True, name = "Driver", node = self),
  1251. "Parameter" : NodeSocket(is_input = True, name = "Parameter", node = self),
  1252. "Index" : NodeSocket(is_input = True, name = "Index", node = self),
  1253. }
  1254. self.outputs = {
  1255. "Output Relationship" : NodeSocket(name = "Output Relationship", node=self), }
  1256. self.parameters = {
  1257. "Input Relationship":None,
  1258. "Driver":None,
  1259. "Parameter":None,
  1260. "Index":None,
  1261. }
  1262. # now set up the traverse target...
  1263. self.inputs["Input Relationship"].set_traverse_target(self.outputs["Output Relationship"])
  1264. self.outputs["Output Relationship"].set_traverse_target(self.inputs["Input Relationship"])
  1265. self.node_type = "LINK"
  1266. def GetxForm(self):
  1267. return GetxForm(self)
  1268. def evaluate_input(self, input_name):
  1269. return default_evaluate_input(self, input_name)
  1270. def bExecute(self, bContext = None,):
  1271. prepare_parameters(self)
  1272. prGreen("Executing Driven Parameter node")
  1273. # example_ driver ={
  1274. # "owner":None,
  1275. # "prop":None, # will be filled out in the node that uses the driver
  1276. # "ind":-1, # same here
  1277. # "type": self.evaluate_input("Driver Type"),
  1278. # "vars": my_vars,
  1279. # "keys": self.evaluate_input("fCurve"),}
  1280. driver = self.evaluate_input("Driver")
  1281. driver["owner"] = self.GetxForm().bGetObject()
  1282. driver["prop"] = self.evaluate_input("Parameter")
  1283. driver["ind"] = self.evaluate_input("Index")
  1284. self.parameters["Driver"] = driver
  1285. def bFinalize(self, bContext = None):
  1286. # TODO HACK BUG
  1287. # This probably no longer works
  1288. from .drivers import CreateDrivers
  1289. CreateDrivers( [ self.parameters["Driver"] ] )
  1290. def __repr__(self):
  1291. return self.signature.__repr__()
  1292. def fill_parameters(self):
  1293. fill_parameters(self)
  1294. class LinkArmature:
  1295. '''A node representing an armature object'''
  1296. def __init__(self, signature, base_tree):
  1297. self.base_tree=base_tree
  1298. self.executed = False
  1299. self.signature = signature
  1300. self.inputs = {
  1301. "Input Relationship" : NodeSocket(is_input = True, name = "Input Relationship", node = self,),
  1302. "Preserve Volume" : NodeSocket(is_input = True, name = "Preserve Volume", node = self),
  1303. "Use Envelopes" : NodeSocket(is_input = True, name = "Use Envelopes", node = self),
  1304. "Use Current Location" : NodeSocket(is_input = True, name = "Use Current Location", node = self),
  1305. "Influence" : NodeSocket(is_input = True, name = "Influence", node = self),
  1306. "Enable" : NodeSocket(is_input = True, name = "Enable", node = self),
  1307. }
  1308. self.outputs = {
  1309. "Output Relationship" : NodeSocket(name = "Output Relationship", node=self), }
  1310. self.parameters = {
  1311. "Name":None,
  1312. "Input Relationship":None,
  1313. "Preserve Volume":None,
  1314. "Use Envelopes":None,
  1315. "Use Current Location":None,
  1316. "Influence":None,
  1317. "Enable":None,
  1318. }
  1319. # now set up the traverse target...
  1320. self.inputs["Input Relationship"].set_traverse_target(self.outputs["Output Relationship"])
  1321. self.outputs["Output Relationship"].set_traverse_target(self.inputs["Input Relationship"])
  1322. self.node_type = "LINK"
  1323. setup_custom_props(self)
  1324. def GetxForm(self):
  1325. return GetxForm(self)
  1326. def evaluate_input(self, input_name):
  1327. return default_evaluate_input(self, input_name)
  1328. def bExecute(self, bContext = None,):
  1329. prGreen("Creating Armature Constraint for bone: \""+ self.GetxForm().bGetObject().name + "\"")
  1330. prepare_parameters(self)
  1331. c = self.GetxForm().bGetObject().constraints.new('ARMATURE')
  1332. c.name = self.evaluate_input("Name")
  1333. self.bObject = c
  1334. # get number of targets
  1335. num_targets = len( list(self.inputs.values())[6:] )//2
  1336. props_sockets = {
  1337. 'use_deform_preserve_volume' : ("Preserve Volume", 0),
  1338. 'use_bone_envelopes' : ("Use Envelopes", 0),
  1339. 'use_current_location' : ("Use Current Location", 0),
  1340. 'influence' : ( "Influence" , 1),
  1341. 'mute' : ("Enable", True),
  1342. }
  1343. targets_weights = {}
  1344. for i in range(num_targets):
  1345. target = c.targets.new()
  1346. target_input_name = list(self.inputs.keys())[i*2+6 ]
  1347. weight_input_name = list(self.inputs.keys())[i*2+6+1]
  1348. get_target_and_subtarget(self, target, target_input_name)
  1349. targets_weights[i]=self.evaluate_input(weight_input_name)
  1350. # props_sockets["targets[%d].weight" % i] = (weight_input_name, 0)
  1351. # targets_weights.append({"weight":(weight_input_name, 0)})
  1352. evaluate_sockets(self, c, props_sockets)
  1353. for target, value in targets_weights.items():
  1354. c.targets[target].weight=value
  1355. # for i, (target, weight) in enumerate(zip(c.targets, targets_weights)):
  1356. # evaluate_sockets(self, target, weight)
  1357. def bFinalize(self, bContext = None):
  1358. finish_drivers(self)
  1359. def __repr__(self):
  1360. return self.signature.__repr__()
  1361. def fill_parameters(self):
  1362. fill_parameters(self)
  1363. class LinkSplineIK:
  1364. '''A node representing an armature object'''
  1365. def __init__(self, signature, base_tree):
  1366. self.base_tree=base_tree
  1367. self.executed = False
  1368. self.signature = signature
  1369. self.inputs = {
  1370. "Input Relationship" : NodeSocket(is_input = True, name = "Input Relationship", node = self,),
  1371. "Target" : NodeSocket(is_input = True, name = "Target", node = self),
  1372. "Chain Length" : NodeSocket(is_input = True, name = "Chain Length", node = self),
  1373. "Even Divisions" : NodeSocket(is_input = True, name = "Even Divisions", node = self),
  1374. "Chain Offset" : NodeSocket(is_input = True, name = "Chain Offset", node = self),
  1375. "Use Curve Radius" : NodeSocket(is_input = True, name = "Use Curve Radius", node = self),
  1376. "Y Scale Mode" : NodeSocket(is_input = True, name = "Y Scale Mode", node = self),
  1377. "XZ Scale Mode" : NodeSocket(is_input = True, name = "XZ Scale Mode", node = self),
  1378. "Use Original Scale" : NodeSocket(is_input = True, name = "Use Original Scale", node = self),
  1379. "Influence" : NodeSocket(is_input = True, name = "Influence", node = self),
  1380. }
  1381. self.outputs = {
  1382. "Output Relationship" : NodeSocket(is_input = False, name = "Output Relationship", node=self), }
  1383. self.parameters = {
  1384. "Name":None,
  1385. "Input Relationship":None,
  1386. "Target":None,
  1387. "Chain Length":None,
  1388. "Even Divisions":None,
  1389. "Chain Offset":None,
  1390. "Use Curve Radius":None,
  1391. "Y Scale Mode":None,
  1392. "XZ Scale Mode":None,
  1393. "Use Original Scale":None,
  1394. "Influence":None,
  1395. }
  1396. # now set up the traverse target...
  1397. self.inputs["Input Relationship"].set_traverse_target(self.outputs["Output Relationship"])
  1398. self.outputs["Output Relationship"].set_traverse_target(self.inputs["Input Relationship"])
  1399. self.node_type = "LINK"
  1400. def evaluate_input(self, input_name):
  1401. return default_evaluate_input(self, input_name)
  1402. def GetxForm(self):
  1403. return GetxForm(self)
  1404. def bExecute(self, bContext = None,):
  1405. prepare_parameters(self)
  1406. prGreen("Creating Spline-IK Constraint for bone: \""+ self.GetxForm().bGetObject().name + "\"")
  1407. c = self.GetxForm().bGetObject().constraints.new('SPLINE_IK')
  1408. get_target_and_subtarget(self, c)
  1409. c.name = self.evaluate_input("Name")
  1410. self.bObject = c
  1411. props_sockets = {
  1412. 'chain_count' : ("Chain Length", 0),
  1413. 'use_even_divisions' : ("Even Divisions", False),
  1414. 'use_chain_offset' : ("Chain Offset", False),
  1415. 'use_curve_radius' : ("Use Curve Radius", False),
  1416. 'y_scale_mode' : ("Y Scale Mode", "FIT_CURVE"),
  1417. 'xz_scale_mode' : ("XZ Scale Mode", "NONE"),
  1418. 'use_original_scale' : ("Use Original Scale", False),
  1419. 'influence' : ("Influence", 1),
  1420. }
  1421. evaluate_sockets(self, c, props_sockets)
  1422. def __repr__(self):
  1423. return self.signature.__repr__()
  1424. def fill_parameters(self):
  1425. fill_parameters(self)