Skip to content

Commit a69ab25

Browse files
Hand initial commit
1 parent dbdd98e commit a69ab25

File tree

2 files changed

+275
-0
lines changed

2 files changed

+275
-0
lines changed

Piston_plugin.py

+215
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
from maya.api import OpenMaya
2+
import math
3+
import pymel.core as pm
4+
maya_useNewAPI = True
5+
6+
def check_for_intermediate_joint(joint_1_dag, joint_2_dag):
7+
dagModifer_1 = OpenMaya.MFnDagNode(joint_1_dag)
8+
dagModifer_2 = OpenMaya.MFnDagNode(joint_2_dag)
9+
joint_1_child = dagModifer_1.child(0)
10+
joint_2_parent = dagModifer_2.parent(0)
11+
if joint_1_child and joint_2_dag :
12+
if joint_1_child == joint_2_parent :
13+
joint_3_dag = OpenMaya.MDagPath.getAPathTo(joint_1_child)
14+
return joint_1_child, joint_3_dag
15+
else :
16+
OpenMaya.MGlobal.displayError('There is no intermediate child beetween {} and {}'.format(joint_1_dag.partialPathName(),
17+
joint_2_dag.partialPathName()))
18+
19+
def build_translate_joints(start, end) :
20+
print(start)
21+
print(end)
22+
start_joint = pm.PyNode(start)
23+
end_joint = pm.PyNode(end)
24+
start_pos = (pm.getAttr(start_joint.translateX),
25+
pm.getAttr(start_joint.translateY),
26+
pm.getAttr(start_joint.translateZ))
27+
end_pos = pm.xform(end_joint,q=True,t=True,ws=True)
28+
'''end_pos = (pm.getAttr(end_joint.translateX)+pm.getAttr(mid_joint.translateX),
29+
pm.getAttr(end_joint.translateY)+pm.getAttr(mid_joint.translateY),
30+
pm.getAttr(end_joint.translateZ) + pm.getAttr(mid_joint.translateZ))'''
31+
print(start_pos)
32+
pm.select(cl = True)
33+
effector_start = pm.joint(name = 'TranslationStartJoint', p = start_pos)
34+
effectort_end = pm.joint(name= 'TranslateEndJoint', p= end_pos)
35+
pm.joint(effector_start, edit=True, oj = 'xyz', sao='yup')
36+
pm.joint(effectort_end,edit = True, o= (0, 0, 0))
37+
return effector_start, effectort_end
38+
39+
def select_joints():
40+
#selection = OpenMaya.MSelectionList()
41+
OpenMaya.MGlobal.setTrackSelectionOrderEnabled(True)
42+
selection = OpenMaya.MGlobal.getActiveSelectionList()
43+
print(OpenMaya.MGlobal.trackSelectionOrderEnabled())
44+
if selection.length() == 2 :
45+
crank_rotation_joint_dag = selection.getDagPath(0)
46+
crank_rotation_joint_node = crank_rotation_joint_dag.node()
47+
shaft_end_dag = selection.getDagPath(1)
48+
shaft_end_node = shaft_end_dag.node()
49+
shaft_start_node, shaft_start_dag = check_for_intermediate_joint(crank_rotation_joint_dag,shaft_end_dag)
50+
return crank_rotation_joint_dag, shaft_start_dag, shaft_end_dag
51+
52+
53+
else :
54+
OpenMaya.MGlobal.displayError('You need to select 2 joints : {} selected'.format(selection.length()))
55+
56+
def build_setup() :
57+
rotate_center,crank_end, shaft_end = select_joints()
58+
effector_start, effectort_end = build_translate_joints(rotate_center, shaft_end)
59+
return rotate_center,crank_end, shaft_end, effector_start, effectort_end
60+
61+
class pistonNode(OpenMaya.MPxNode):
62+
''' New solver for piston rig'''
63+
type_id = OpenMaya.MTypeId(0x00000001)
64+
type_name = 'pistonNode'
65+
# Attribute
66+
input_crank_lenght = None
67+
input_shaft_lenght = None
68+
input_angle = None
69+
output = None
70+
71+
def __init__(self):
72+
OpenMaya.MPxNode.__init__(self)
73+
74+
@classmethod
75+
def creator(cls):
76+
'''Create a node instance'''
77+
return cls()
78+
79+
@classmethod
80+
def initialize(cls):
81+
'''Create plugin attributes with dependencies'''
82+
print('Plugin init : {} '.format(pistonNode.type_name))
83+
# Type of attribute to create
84+
numeric_attribute = OpenMaya.MFnNumericAttribute()
85+
86+
# first attribute of the node
87+
cls.input_crank_lenght = numeric_attribute.create(
88+
'crankLenght', # longname
89+
'crank_l', # shortname
90+
OpenMaya.MFnNumericData.kFloat # attribute type
91+
)
92+
numeric_attribute.readable = False
93+
numeric_attribute.writable = True
94+
numeric_attribute.keyable = True
95+
cls.addAttribute(cls.input_crank_lenght)
96+
97+
# second attribute of the node
98+
cls.input_shaft_lenght = numeric_attribute.create(
99+
'shaftLenght', # longname
100+
'shaft_R', # shortname
101+
OpenMaya.MFnNumericData.kFloat # attribute type
102+
)
103+
numeric_attribute.readable = False
104+
numeric_attribute.writable = True
105+
numeric_attribute.keyable = True
106+
cls.addAttribute(cls.input_shaft_lenght)
107+
108+
# third attribute of the node
109+
cls.input_angle = numeric_attribute.create(
110+
'inputAngle', # longname
111+
'i_angle', # shortname
112+
OpenMaya.MFnNumericData.kFloat # attribute type
113+
)
114+
numeric_attribute.readable = False
115+
numeric_attribute.writable = True
116+
numeric_attribute.keyable = True
117+
cls.addAttribute(cls.input_angle)
118+
119+
# output attribute of the node
120+
cls.output = numeric_attribute.create(
121+
'output', # longname
122+
'o', # shortname
123+
OpenMaya.MFnNumericData.kFloat # attribute type
124+
)
125+
numeric_attribute.readable = True
126+
numeric_attribute.writable = False
127+
cls.addAttribute(cls.output)
128+
129+
# add dependencies
130+
cls.attributeAffects(cls.input_angle, cls.output)
131+
cls.attributeAffects(cls.input_shaft_lenght, cls.output)
132+
cls.attributeAffects(cls.input_crank_lenght, cls.output)
133+
134+
def compute(self, plug, data_block):
135+
'''
136+
Compute the output of the node
137+
138+
:param plug: MPlug representing the attributes to recompute
139+
:param data_block: MDataBlockis the storage of datas for the node's attribute
140+
:return:
141+
'''
142+
if plug == self.output:
143+
angle_value = data_block.inputValue(self.input_angle).asFloat() + 90
144+
shaft_lenght_value = data_block.inputValue(self.input_shaft_lenght).asFloat()
145+
crank_lenght_value = data_block.inputValue(self.input_crank_lenght).asFloat()
146+
147+
piston_move = math.sin(math.radians(angle_value)) * crank_lenght_value + math.sqrt(
148+
pow(shaft_lenght_value, 2) - pow(math.cos(math.radians(angle_value )), 2) * pow(crank_lenght_value, 2))
149+
print(piston_move)
150+
# get the output handdle, set its new value and set it as clean
151+
output_handle = data_block.outputValue(self.output)
152+
output_handle.setFloat(piston_move)
153+
output_handle.setClean()
154+
155+
156+
class generatePiston(OpenMaya.MPxCommand):
157+
kPluginCmdName = 'generatePistonCmd'
158+
159+
def __init__(self):
160+
OpenMaya.MPxCommand.__init__(self)
161+
162+
@classmethod
163+
def cmdCreator(cls):
164+
return generatePiston()
165+
166+
def doIt(self, args):
167+
print('Done')
168+
rotate_center, crank_end, shaft_end, effector_start, effector_end = build_setup()
169+
piston_solver = pm.createNode('pistonNode')
170+
pm.connectAttr(rotate_center.rotateZ, piston_solver.input_angle)
171+
172+
173+
174+
def initializePlugin(plugin):
175+
'''
176+
Called when the plugin is initialized
177+
178+
:param Plugin: MObject the plugin to initialize
179+
:return:
180+
'''
181+
182+
plugin_fn = OpenMaya.MFnPlugin(plugin, 'Baptiste Fraboul', '0.0.1')
183+
184+
try:
185+
plugin_fn.registerCommand(generatePiston.kPluginCmdName,
186+
generatePiston.cmdCreator)
187+
plugin_fn.registerNode(
188+
pistonNode.type_name,
189+
pistonNode.type_id,
190+
pistonNode.creator,
191+
pistonNode.initialize,
192+
OpenMaya.MPxNode.kDependNode
193+
)
194+
195+
except:
196+
print('Failed to initialize the plugin : {} !'.format(pistonNode.type_name))
197+
raise
198+
199+
200+
def uninitializePlugin(plugin):
201+
'''
202+
Called when the plugin is unloaded in Maya
203+
204+
:param plugin: the MObject plugin to uninitialize
205+
:return:
206+
'''
207+
208+
plugin_fn = OpenMaya.MFnPlugin(plugin)
209+
210+
try:
211+
plugin_fn.deregisterCommand(generatePiston.kPluginCmdName)
212+
plugin_fn.deregisterNode(pistonNode.type_id)
213+
except:
214+
print('Failed to uninitialize the plugin : {} !'.format(pistonNode.type_name))
215+
raise

test_math.py

+60
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
import math
2+
import pymel.core as pm
3+
4+
from maya.api import OpenMaya
5+
maya_useNewAPI = True
6+
7+
def check_for_intermediate_joint(joint_1_dag, joint_2_dag):
8+
dagModifer_1 = OpenMaya.MFnDagNode(joint_1_dag)
9+
dagModifer_2 = OpenMaya.MFnDagNode(joint_2_dag)
10+
joint_1_child = dagModifer_1.child(0)
11+
joint_2_parent = dagModifer_2.parent(0)
12+
if joint_1_child and joint_2_dag :
13+
if joint_1_child == joint_2_parent :
14+
joint_3_dag = OpenMaya.MDagPath.getAPathTo(joint_1_child)
15+
return joint_1_child, joint_3_dag
16+
else :
17+
OpenMaya.MGlobal.displayError('There is no intermediate child beetween {} and {}'.format(joint_1_dag.partialPathName(),
18+
joint_2_dag.partialPathName()))
19+
20+
def build_translate_joints(start, end) :
21+
print(start)
22+
print(end)
23+
start_joint = pm.PyNode(start)
24+
end_joint = pm.PyNode(end)
25+
start_pos = (pm.getAttr(start_joint.translateX),
26+
pm.getAttr(start_joint.translateY),
27+
pm.getAttr(start_joint.translateZ))
28+
end_pos = pm.xform(end_joint,q=True,t=True,ws=True)
29+
'''end_pos = (pm.getAttr(end_joint.translateX)+pm.getAttr(mid_joint.translateX),
30+
pm.getAttr(end_joint.translateY)+pm.getAttr(mid_joint.translateY),
31+
pm.getAttr(end_joint.translateZ) + pm.getAttr(mid_joint.translateZ))'''
32+
print(start_pos)
33+
pm.select(cl = True)
34+
effector_start = pm.joint(name = 'TranslationStartJoint', p = start_pos)
35+
effectort_end = pm.joint(name= 'TranslateEndJoint', p= end_pos)
36+
pm.joint(effector_start, edit=True, oj = 'xyz', sao='yup')
37+
pm.joint(effectort_end,edit = True, o= (0, 0, 0))
38+
39+
def select_joints():
40+
#selection = OpenMaya.MSelectionList()
41+
OpenMaya.MGlobal.setTrackSelectionOrderEnabled(True)
42+
selection = OpenMaya.MGlobal.getActiveSelectionList()
43+
print(OpenMaya.MGlobal.trackSelectionOrderEnabled())
44+
if selection.length() == 2 :
45+
crank_rotation_joint_dag = selection.getDagPath(0)
46+
crank_rotation_joint_node = crank_rotation_joint_dag.node()
47+
shaft_end_dag = selection.getDagPath(1)
48+
shaft_end_node = shaft_end_dag.node()
49+
shaft_start_node, shaft_start_dag = check_for_intermediate_joint(crank_rotation_joint_dag,shaft_end_dag)
50+
return crank_rotation_joint_dag, shaft_start_dag, shaft_end_dag
51+
52+
53+
else :
54+
OpenMaya.MGlobal.displayError('You need to select 2 joints : {} selected'.format(selection.length()))
55+
56+
def build_setup() :
57+
rotate_center,crank_end, shaft_end = select_joints()
58+
build_translate_joints(rotate_center, shaft_end)
59+
60+
build_setup()

0 commit comments

Comments
 (0)