import unreal
import re




#RigGraphDisplaySettings = selectedAsset.get_editor_property('rig_graph_display_settings')
#RigGraphDisplaySettings.set_editor_property('node_run_limit',256)

class ControllRig(object):
	
	def __init__(self) -> None:
		engineVersion = unreal.SystemLibrary.get_engine_version()
		self.utilityBase = unreal.GlobalEditorUtilityBase.get_default_object()
		
		self.get_select_controll_rig()
		self.ASCtrlNr = 0
		self.GizmoRotation = [0,0,0]

	def get_select_controll_rig(self):
		
		selectedAssets = self.utilityBase.get_selected_assets()
		#要选中 controlrig 资产
		if len(selectedAssets)<1:
			raise Exception('Nothing selected, you must select a ControlRig')
		self.selectedAsset = selectedAssets[0]

		if self.selectedAsset.get_class().get_name() != 'ControlRigBlueprint':
			raise Exception('Selected object is not a ControlRigBlueprint, you must select a ControlRigBlueprint')

		blueprint = self.selectedAsset
		library = self.selectedAsset.get_local_function_library()

		library_controller = self.selectedAsset.get_controller(library)
		self.hierarchy =self.selectedAsset.hierarchy

		#创建的控制器
		self.hierarchy_controller =self. hierarchy.get_controller()
		self.RigVMController =self.selectedAsset.get_controller() #UE5
		
		#for i in dir(self.RigVMController):
		#	print(i)

		self.sp = '/Script/ControlRig.RigUnit_'
		self.PreviousEndPlug = 'RigUnit_BeginExecution.ExecuteContext'
		self.PreviousEndPlugInv = 'RigUnit_InverseExecution.ExecuteContext'
		self.PreviousYInv = -110
		self.RigElementKeys = self.asGetRigElementKeys()
		self.RigVMGraph = self.selectedAsset.get_model()

	def asAddNode(self,script_struct_path, method_name, node_name):
		#RigVMController.
		#add_struct_node_from_struct_path UE4
		#add_unit_node_from_struct_path UE5
		try:
			node = self.RigVMController.add_struct_node_from_struct_path(script_struct_path,method_name,node_name=node_name) #UE4
		except:
			node = self.RigVMController.add_unit_node_from_struct_path(script_struct_path,method_name,node_name=node_name) #UE5
		return node

	#拿到 各种绑定元素，如 骨骼，控制器，空节点
	def asGetRigElementKeys(self):
		try:
			RigElementKeys = self.hierarchy_controller.get_elements() #UE4
		except:
			RigElementKeys = self.hierarchy.get_all_keys() #UE5
		return RigElementKeys

	#按名字查找元素
	def asGetKeyFromName (self,name):
		all_keys = self.hierarchy.get_all_keys(traverse = True)
		for key in all_keys:
			if key.name == name:
				return key
		return ''
	
	#打印全部元素
	def print_keys(self):
		for key in self.RigElementKeys:
			print(f"{key.name} -> {key.type}")
	
	#移除所有节点 
	def clean_node(self):
		
		self.RigVMGraph = self.selectedAsset.get_model()
		##controllrig 蓝图中的全部节点
		nodes = self.RigVMGraph.get_nodes()
		for node in nodes:
			print(f"remove node -> {node.get_name()}")
			self.RigVMController.remove_node(node)
   
    #清楚蓝图中所有创建的绑定元素，恢复成空白蓝图
	def clean_keys(self):
		#所有创建的 控制器，骨骼，空对象等 
		for key in self.RigElementKeys:
			#print(f"{key.name} -> {key.type}")
			if key.name == 'MotionSystem':
				#pass
				print(f"remove -> {key.name}")
				self.hierarchy_controller.remove_element(key)
			#elif not (key.type==1 or key.type==8): 
			elif not (key.type ==1 ): 
				#移除所有非BONE对象 ，https://docs.unrealengine.com/5.1/en-US/PythonAPI/class/RigElementType.html
				try:
					print(f"remove -> {key.name}")
					self.hierarchy_controller.remove_element(key)
				except:
					pass

	def events(self):
		#创建正向计算 节点
		self.BeginExecutionNode = self.asAddNode(self.sp +'BeginExecution','Execute',node_name='RigUnit_BeginExecution')
		self.RigVMController.set_node_position(self.BeginExecutionNode, [-300, -100])

		#创建反向计算 节点
		self.InverseExecutionNode = self.asAddNode ( self.sp+'InverseExecution','Execute',node_name='RigUnit_InverseExecution')
		self.RigVMController.set_node_position (self.InverseExecutionNode, [-1900, self.PreviousYInv])
	
	def asAddCtrl (self,name, parent, joint, type, arrayInfo, gizmoName, ws, size, offT, color):
		#
		self.endPlug = self.PreviousEndPlug

		keyctr = self.asAddController (name, parent, joint, type, gizmoName, ws, size, offT, color)
		
		y = self.ASCtrlNr*400
		self.ASCtrlNr += 1
		RootScale = unreal.Vector(x=1.0, y=1.0, z=1.0)

		if type == "Normal" :
			#都是简单的 GetTransform SetTransform
			#GT
			GT = self.asAddNode (self.sp+'GetTransform','Execute',node_name=name+'_GT')
			self.RigVMController.set_node_position (GT, [-500, y])
			self.RigVMController.set_pin_default_value(name+'_GT.Item.Type','Control')
			self.RigVMController.set_pin_default_value(name+'_GT.Item.Name',name)

			#ST
			ST = self.asAddNode (self.sp+'SetTransform','Execute',node_name=name+'_ST')
			self.RigVMController.set_node_position (ST, [100, y])
			self.RigVMController.set_pin_default_value(name+'_ST.Item.Type','Bone')
			self.RigVMController.set_pin_default_value(name+'_ST.Item.Name',joint)
			self.RigVMController.add_link(name+'_GT.Transform' , name+'_ST.Transform')
			self.RigVMController.set_pin_default_value(name+'_ST.bPropagateToChildren','True')
			self.RigVMController.add_link(self.endPlug , name+'_ST.ExecuteContext')
			self.endPlug = name+'_ST.ExecuteContext'
		
		if type == "IK":
			#ik 极向量 控制
			pole = self.asAddController ('Pole'+name, parent, joint, type, 'Sphere_Solid', ws, size/5.0, offT, color)
			#ik 极向量 控制的位置
			pole_tm = unreal.Transform(location=[float(arrayInfo["ppX"])*RootScale.x,float(arrayInfo["ppY"])*RootScale.y,float(arrayInfo["ppZ"])*RootScale.z],scale=RootScale)
		
			self.hierarchy.set_control_offset_transform(pole,pole_tm , True, True)
			# 把IK极向量 链接到 IK 控制器
			self.hierarchy_controller.set_parent(pole,keyctr,maintain_global_transform=True)


			IK_Effect =  self.asAddNode (self.sp+'GetTransform','Execute',node_name=name+'_GT')
			self.RigVMController.set_node_position (IK_Effect, [200, y-130])
			self.RigVMController.set_pin_default_value(name+'_GT.Item.Type','Control')
			self.RigVMController.set_pin_default_value(name+'_GT.Item.Name',name)

			#IK(Basic IK)
			IK = self.asAddNode (self.sp+'TwoBoneIKSimplePerItem','Execute',node_name=name+'_IK')
			self.RigVMController.set_node_position (IK, [600, y-130])
			self.RigVMController.set_pin_default_value(name+'_IK.ItemA.Name',arrayInfo["startJoint"])
			self.RigVMController.set_pin_default_value(name+'_IK.ItemB.Name',arrayInfo["middleJoint"])
			self.RigVMController.set_pin_default_value(name+'_IK.EffectorItem.Name',arrayInfo["endJoint"])
			
			#IK 第二节骨骼的 极向量 参数，
			p_ik_axis = {'x':'1','y':'0','z':'0'}
			s_ik_axis = {'x':'0','y':'-1','z':'0'}

			if arrayInfo['ikType'] == 'leg':
				pass
			elif arrayInfo['ikType'] == 'arm':
				s_ik_axis = {'x':'0','y':'1','z':'0'}

			self.RigVMController.set_pin_default_value(name+'_IK.PrimaryAxis.X',p_ik_axis['x']) # 那个轴向指向下一节骨骼
			self.RigVMController.set_pin_default_value(name+'_IK.PrimaryAxis.Y',p_ik_axis['y'])
			self.RigVMController.set_pin_default_value(name+'_IK.PrimaryAxis.Z',p_ik_axis['z'])
				
			self.RigVMController.set_pin_default_value(name+'_IK.SecondaryAxis.X',s_ik_axis['x']) # 哪个轴向指向极向量控制器
			self.RigVMController.set_pin_default_value(name+'_IK.SecondaryAxis.Y',s_ik_axis['y'])
			self.RigVMController.set_pin_default_value(name+'_IK.SecondaryAxis.Z',s_ik_axis['z'])
			
			self.RigVMController.set_pin_default_value(name+'_IK.PoleVectorKind','Location')
			self.RigVMController.set_pin_default_value(name+'_IK.PoleVectorSpace.Type','Control')
			self.RigVMController.set_pin_default_value(name+'_IK.PoleVectorSpace.Name','Pole'+name)
			self.RigVMController.set_pin_default_value(name+'_IK.bPropagateToChildren','True')
			self.RigVMController.add_link(name+'_GT.Transform' , name+'_IK.Effector')
			self.RigVMController.add_link(self.endPlug , name+'_IK.ExecuteContext')
			self.endPlug = name+'_IK.ExecuteContext'

			#GTPole
			GTPole = self.asAddNode (self.sp+'GetTransform','Execute',node_name=name+'_GTPole')
			self.RigVMController.set_node_position (GTPole, [1000, y])
			self.RigVMController.set_pin_default_value(name+'_GTPole.Item.Type','Control')
			self.RigVMController.set_pin_default_value(name+'_GTPole.Item.Name','Pole'+name)

			#GTMidJoint
			GTMidJoint = self.asAddNode (self.sp+'GetTransform','Execute',node_name=name+'_GTMidJoint')
			self.RigVMController.set_node_position (GTMidJoint, [1000, y+200])
			self.RigVMController.set_pin_default_value(name+'_GTMidJoint.Item.Type','Bone')
			self.RigVMController.set_pin_default_value(name+'_GTMidJoint.Item.Name',arrayInfo["middleJoint"])

			PoleLine = self.asAddNode (self.sp+'DebugLineItemSpace','Execute',node_name=name+'_PoleLine')
			self.RigVMController.set_node_position (PoleLine, [1350, y])
			self.RigVMController.add_link(name+'_GTPole.Transform.Translation' , name+'_PoleLine.A')
			self.RigVMController.add_link(name+'_GTMidJoint.Transform.Translation' , name+'_PoleLine.B')
			self.RigVMController.add_link(self.endPlug , name+'_PoleLine.ExecuteContext')
			self.endPlug = name+'_PoleLine.ExecuteContext'

			# 这里会在IK 处创建 子级控制
			control_value = self.hierarchy.make_control_value_from_euler_transform(unreal.EulerTransform(scale=[1, 1, 1]))
			control_settings = unreal.RigControlSettings()
			control_settings.shape_visible = False
			self.hierarchy_controller.add_control (name+'LS','', control_settings,control_value)
			self.hierarchy_controller.set_parent(self.asGetKeyFromName(name+'LS'),self.asGetKeyFromName(name),maintain_global_transform=False)
			self.RigVMController.set_pin_default_value(name+'_GT.Item.Name',name+'LS')

			# for key in self.RigElementKeys:
			# 	if (key.name == arrayInfo["endJoint"]):
			# 		endJointKey = key
			# EndJointTransform = self.hierarchy.get_global_transform(endJointKey, initial = False)
			# Rotation = EndJointTransform.rotation.rotator()
			# Transform = unreal.Transform(location=[0,0,0],rotation=Rotation,scale=[1,1,1])
			# self.hierarchy.set_control_offset_transform(self.asGetKeyFromName(name+'LS'), Transform, True, True)
			#Backwards solve nodes (IK)
			PNPinvIK = self.asAddNode (self.sp+'ProjectTransformToNewParent','Execute',node_name=name+'_PNPinvIK')
			self.RigVMController.set_node_position (PNPinvIK, [-2900, y])
			self.RigVMController.set_pin_default_value(name+'_PNPinvIK.Child.Type','Control')
			self.RigVMController.set_pin_default_value(name+'_PNPinvIK.Child.Name',name)
			self.RigVMController.set_pin_default_value(name+'_PNPinvIK.OldParent.Type','Control')
			self.RigVMController.set_pin_default_value(name+'_PNPinvIK.OldParent.Name',name+'LS')
			self.RigVMController.set_pin_default_value(name+'_PNPinvIK.NewParent.Type','Bone')
			self.RigVMController.set_pin_default_value(name+'_PNPinvIK.NewParent.Name',joint)

			#STinvIK
			STinvIK = self.asAddNode (self.sp+'SetTransform','Execute',node_name=name+'_STinvIK')
			self.RigVMController.set_node_position (STinvIK, [-2500, y])
			self.RigVMController.set_pin_default_value(name+'_STinvIK.Item.Type','Control')
			self.RigVMController.set_pin_default_value(name+'_STinvIK.Item.Name',name)
			self.RigVMController.set_pin_default_value(name+'_STinvIK.bPropagateToChildren','True')
			self.RigVMController.add_link(name+'_PNPinvIK.Transform' , name+'_STinvIK.Transform')
			self.RigVMController.add_link(self.PreviousEndPlugInv , name+'_STinvIK.ExecuteContext')

			#GTinvPole
			GTinvPole = self.asAddNode (self.sp+'GetTransform','Execute',node_name=name+'_GTinvPole')
			self.RigVMController.set_node_position (GTinvPole, [-1700, y])
			self.RigVMController.set_pin_default_value(name+'_GTinvPole.Item.Type','Bone')
			self.RigVMController.set_pin_default_value(name+'_GTinvPole.Item.Name',arrayInfo["middleJoint"])

			#STinvPole
			STinvPole = self.asAddNode (self.sp+'SetTransform','Execute',node_name=name+'_STinvPole')
			self.RigVMController.set_node_position (STinvPole, [-1300, y])
			self.RigVMController.set_pin_default_value(name+'_STinvPole.Item.Type','Control')
			self.RigVMController.set_pin_default_value(name+'_STinvPole.Item.Name','Pole'+name)
			self.RigVMController.set_pin_default_value(name+'_STinvPole.bPropagateToChildren','True')
			self.RigVMController.add_link(name+'_GTinvPole.Transform' , name+'_STinvPole.Transform')
			self.RigVMController.add_link(name+'_STinvIK.ExecuteContext' , name+'_STinvPole.ExecuteContext')
			self.endPlugInv = name+'_STinvPole.ExecuteContext'
			self.PreviousEndPlugInv = self.endPlugInv
			self.PreviousYInv = y

		
		if ("twistJoints" in arrayInfo) :
			count = arrayInfo['twistJoints']
			
			GT2 = self.asAddNode (self.sp+'GetTransform','Execute',node_name=name+'_GT2')
			self.RigVMController.set_node_position (GT2, [500, y+10])
			self.RigVMController.set_pin_default_value(name+'_GT2.Item.Type','Control')
			self.RigVMController.set_pin_default_value(name+'_GT2.Item.Name',name)
			self.RigVMController.set_pin_default_value(name+'_GT2.Space','GlobalSpace')
			
			TWSW = self.asAddNode (self.sp+'MathQuaternionSwingTwist','Execute',node_name=name+'_TWSW')
			self.RigVMController.set_node_position (TWSW, [850, y+160])
			
			TwSw_out = name+'_INV.Result'
			tw_effset = arrayInfo['twistEffset']
			if (tw_effset == name):
				print("大臂过渡 骨骼 => {0} = {1}".format(tw_effset,name))
				self.RigVMController.add_link(name+'_GT2.Transform.Rotation' , name+'_TWSW.Input')
			
				#大臂位置的过渡骨骼
				INV = self.asAddNode (self.sp+'MathQuaternionInverse','Execute',node_name=name+'_INV')
				self.RigVMController.set_node_position (INV, [940, y+160])
				self.RigVMController.add_link(name+'_TWSW.Twist' , name+'_INV.Value')
			
			else:
				#小臂位置的
				TwSw_out = name+'_TWSW.Twist'
				

				GT3 = self.asAddNode(self.sp+'GetTransform','Execute',node_name=tw_effset+'_GT3')
				self.RigVMController.set_node_position (GT3, [500, y+240])
				self.RigVMController.set_pin_default_value(tw_effset+'_GT3.Item.Type','Control')
				self.RigVMController.set_pin_default_value(tw_effset+'_GT3.Item.Name',tw_effset)
				self.RigVMController.set_pin_default_value(tw_effset+'_GT3.Space','LocalSpace')

				self.RigVMController.add_link(tw_effset+'_GT3.Transform.Rotation' , name+'_TWSW.Input')

				
				

			for i in range(count):
				twist_joint = arrayInfo[str(i)]
				
				#原始错误链接的 过渡骨骼
				if arrayInfo['bendType'] == 1 and i == 0 :
					print("第一节 => {0}".format(twist_joint))

					ST = self.asAddNode(self.sp + "SetTransform",'Execute',node_name=twist_joint+'_ST')
					self.RigVMController.set_node_position(ST,[850, y-90])
					self.RigVMController.set_pin_default_value(twist_joint+'_ST.Item.Type','Bone')
					self.RigVMController.set_pin_default_value(twist_joint+'_ST.Item.Name',twist_joint)
					self.RigVMController.set_pin_default_value(twist_joint+'_ST.Space','GlobalSpace')
					self.RigVMController.add_link(name+'_GT2.Transform' , twist_joint+'_ST.Transform')
					self.RigVMController.add_link(self.endPlug , twist_joint+'_ST.ExecuteContext')
					self.endPlug = twist_joint+'_ST.ExecuteContext'
				else:
					pass
				
				OFF= self.asAddNode (self.sp+'OffsetTransformForItem','Execute',node_name=twist_joint+'_OFF')
				self.RigVMController.set_node_position (OFF, [1200, y])
				self.RigVMController.set_pin_default_value(twist_joint+'_OFF.Item.Type','Bone')
				self.RigVMController.set_pin_default_value(twist_joint+'_OFF.Item.Name',twist_joint)
				self.RigVMController.set_pin_default_value(twist_joint+'_OFF.Weight',str(1.0 / (i + 1)))

				
				#self.RigVMController.add_link(name+'_INV.Result' , twist_joint+'_OFF.OffsetTransform.Rotation')
				self.RigVMController.add_link(TwSw_out , twist_joint+'_OFF.OffsetTransform.Rotation')

				self.RigVMController.add_link(self.endPlug , twist_joint+'_OFF.ExecuteContext')
				self.endPlug = twist_joint+'_OFF.ExecuteContext'


		self.PreviousEndPlug = self.endPlug

	def asAddController (self,name, parent, joint, type, gizmoName, ws, size, offT, color):
		
		if gizmoName =='Gizmo':
			gizmoName ='Default'
		
		#控制器样式设置
		control_settings = unreal.RigControlSettings()
		if type =='ctrlBox':
			control_settings.control_type = unreal.RigControlType.VECTOR2D
			control_settings.primary_axis = unreal.RigControlAxis.Y
			control_settings.limit_enabled = [unreal.RigControlLimitEnabled(True, True), unreal.RigControlLimitEnabled(True, True)]
		else:
			control_settings.control_type = unreal.RigControlType.EULER_TRANSFORM

		control_settings.shape_name = gizmoName #类型的名字

		control_settings.shape_color = unreal.LinearColor(color[0], color[1], color[2], 1.0)
		#控制器 形状 设置 
		control_value = self.hierarchy.make_control_value_from_euler_transform(unreal.EulerTransform(scale=[1, 1, 1]))
		key = self.hierarchy_controller.add_control (name,'', control_settings,control_value)

		#拿到控制器对应的骨骼
		jointKey = self.asGetKeyFromName(joint)
		#拿骨骼的tm
		jointTransform = self.hierarchy.get_global_transform(jointKey, initial = True)
		
		if ws == 1:
			#控制器不跟随骨骼旋转
			#jointTransform.rotation = [0,0,0]
			pass

		parentTransform = unreal.Transform()
		if parent != '':
			parentTransform = self.hierarchy.get_global_transform(self.asGetKeyFromName(parent), initial = True)

		OffsetTransform = jointTransform.make_relative(parentTransform)
		
		if parent!='':
			self.hierarchy_controller.set_parent(self.asGetKeyFromName(name),self.asGetKeyFromName(parent),maintain_global_transform=False)
		
		
		self.hierarchy.set_control_offset_transform(key, OffsetTransform, True, True)

		GizmoLocation = [offT[0],offT[2],offT[1]]
		
		if re.search("Pelvis", name) or re.search("Spine", name) or re.search("-Toe", name):
			#print(f"特殊骨骼 {name}")
			self.GizmoRotation = [90,0,0]

		if ws == 0:
			#@GizmoRotation = [90,0,0]
			#GizmoLocation = [offT[0],offT[1]*-1,offT[2]]
			pass

		s = 0.1*size
		Scale = [s,s,s]
		#设置控制形状的大小
		self.hierarchy.set_control_shape_transform(key, unreal.Transform(location=GizmoLocation,rotation=self.GizmoRotation,scale=Scale), True)
		
		return key 
	
	#反向计算节点
	def asBackwardsSolveNodes(self,ctr_name,bone_name):
		
		self.PreviousYInv+=400

		GTinv = self.asAddNode (self.sp+'GetTransform','Execute',node_name=bone_name+'GTinv')
		self.RigVMController.set_node_position (GTinv, [-1500, self.PreviousYInv+100])
		self.RigVMController.set_pin_default_value(bone_name+'GTinv.Item.Type','Bone')
		self.RigVMController.set_pin_default_value(bone_name+'GTinv.Item.Name',bone_name)

		STInv = self.asAddNode (self.sp+'SetTransform','Execute',node_name=ctr_name+'_STInv')
		self.RigVMController.set_node_position (STInv, [-1200, self.PreviousYInv])
		self.RigVMController.set_pin_default_value(ctr_name+'_STInv.Item.Type','Control')
		self.RigVMController.set_pin_default_value(ctr_name+'_STInv.Item.Name',ctr_name)
		
		self.RigVMController.add_link(bone_name+'GTinv.Transform' , ctr_name + '_STInv.Transform')
		self.RigVMController.add_link(self.PreviousEndPlugInv , ctr_name + '_STInv.ExecuteContext')

		self.PreviousEndPlugInv = ctr_name + '_STInv.ExecuteContext'

	def asBackwardsSolveNodes_CollectionLoop(self,loop_bone_name):
		
		CCinv = self.asAddNode (self.sp+'CollectionChildren','Execute',node_name='CCinv')
		self.RigVMController.set_node_position (CCinv, [-2600, self.PreviousYInv+1000])
		self.RigVMController.set_pin_default_value('CCinv.Parent.Type','Bone')
		self.RigVMController.set_pin_default_value('CCinv.Parent.Name',loop_bone_name)
		self.RigVMController.set_pin_default_value('CCinv.bRecursive','True')
		self.RigVMController.set_pin_default_value('CCinv.TypeToSearch','Bone')

		CLinv = self.asAddNode (self.sp+'CollectionLoop','Execute',node_name='CLinv')
		self.RigVMController.set_node_position (CLinv, [-2150, self.PreviousYInv+1000])
		self.RigVMController.add_link(self.PreviousEndPlugInv , 'CLinv.ExecuteContext')
		self.RigVMController.add_link('CCinv.Collection' , 'CLinv.Collection')
		self.PreviousEndPlugInv = 'CLinv.Completed'

		NCinv = self.asAddNode (self.sp+'NameConcat','Execute',node_name='NCinv')
		self.RigVMController.set_node_position (NCinv, [-1900, self.PreviousYInv+900])
		self.RigVMController.set_pin_default_value('NCinv.A','FK')
		self.RigVMController.add_link('CLinv.Item.Name' , 'NCinv.B')

		GTinv = self.asAddNode (self.sp+'GetTransform','Execute',node_name='GTinv')
		self.RigVMController.set_node_position (GTinv, [-1900, self.PreviousYInv+1000])
		self.RigVMController.add_link('CLinv.Item.Name' , 'GTinv.Item.Name')

		IEinv = self.asAddNode (self.sp+'ItemExists','Execute',node_name='IEinv')
		self.RigVMController.set_node_position (IEinv, [-1700, self.PreviousYInv+700])
		self.RigVMController.set_pin_default_value('IEinv.Item.Type','Control')
		self.RigVMController.add_link('NCinv.Result' , 'IEinv.Item.Name')

		BRinv = self.RigVMController.add_branch_node(node_name='BRinv')
		self.RigVMController.set_node_position (BRinv, [-1650, self.PreviousYInv+850])
		self.RigVMController.add_link('IEinv.Exists' , 'BRinv.Condition')
		self.RigVMController.add_link('CLinv.ExecuteContext' , 'BRinv.ExecuteContext')

		STinv = self.asAddNode (self.sp+'SetTransform','Execute',node_name='STinv')
		self.RigVMController.set_node_position (STinv, [-1500, self.PreviousYInv+1000])
		self.RigVMController.set_pin_default_value('STinv.Item.Type','Control')
		self.RigVMController.add_link('NCinv.Result' , 'STinv.Item.Name')
		self.RigVMController.add_link('GTinv.Transform' , 'STinv.Transform')
		self.RigVMController.add_link('BRinv.True' , 'STinv.ExecuteContext')

	def asAddIK(self):

		pass


	def test(self):

		self.asAddCtrl ('Root','','Root_Bip001','FK',{},'Circle_Thick',1,51.1027,[0, 0, 0],[176,26,26])
		#创建的控制器
		# controls = hierarchy.get_controls()
		# for key in controls:
		# 	print(f"{key.name}")
		# 	#hierarchy_controller.remove_element(key)
		

		# nulls = hierarchy.get_nulls()
		# for key in nulls:
		# 	hierarchy_controller.remove_element(key)

		#所有bone 
		# bones = hierarchy.get_bones()
		# for key in bones:
		# 	print(key.name)
		#  	#x = re.search("UnTwist", str(key.name))
		
		#test_rig.print_keys()
		
		#for i in dir(test_rig.RigVMController):
		#	print(i)
		#textstring = test_rig.RigVMController.export_selected_nodes_to_text()
		#创建空节点
		#MainSystemKey =  self.hierarchy_controller.add_null('MainSystem','',unreal.Transform())
		pass


if __name__ == "__main__":
	test_rig = ControllRig()
	test_rig.clean_node()
	test_rig.clean_keys()
	test_rig.events()
	#//-- ASControllers Starts Here --//

