-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcenter_point_node.py
136 lines (92 loc) · 4.24 KB
/
center_point_node.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
import maya.api.OpenMaya as om
import maya.cmds as cmds
maya_useNewAPI = True
class CenterPointNode(om.MPxNode):
kTypeName = "centerPoint"
kTypeId = om.MTypeId(0x0007f7f9)
inputObjectsAttr = None
outputPosAttr = None
@classmethod
def defineAttributes(cls):
numericFn = om.MFnMatrixAttribute()
cls.inputObjectsAttr = numericFn.create("input", "in", om.MFnMatrixAttribute.kDouble)
numericFn.array = True
numericFn.storable = True
numericFn.keyable = True
numericFn.readable = False
numericFn.writable = True
cls.addAttribute(cls.inputObjectsAttr)
numericAttrFn = om.MFnNumericAttribute()
cls.outputPosAttr = numericAttrFn.create("outputPosition", "op", om.MFnNumericData.k3Double)
numericAttrFn.storable = False
numericAttrFn.writable = False
numericAttrFn.readable = True
cls.addAttribute(cls.outputPosAttr)
cls.attributeAffects(cls.inputObjectsAttr, cls.outputPosAttr)
def __init__(self):
super().__init__()
@classmethod
def creator(cls):
return CenterPointNode()
@classmethod
def initialize(cls):
cls.defineAttributes()
def compute(self, plug, dataBlock):
if not self._is_dirty(plug):
pass
inputDataHandle = dataBlock.inputArrayValue(CenterPointNode.inputObjectsAttr)
positions = []
while not inputDataHandle.isDone():
matrixDataHandle = inputDataHandle.inputValue()
worldMatrix = matrixDataHandle.asMatrix()
transformationMatrix = om.MTransformationMatrix(worldMatrix)
translation = transformationMatrix.translation(om.MSpace.kWorld)
positions.append(translation)
inputDataHandle.next()
center_point = self._find_center_point(positions)
outputHandle = dataBlock.outputValue(self.outputPosAttr)
outputHandle.set3Double(center_point.x, center_point.y, center_point.z)
dataBlock.setClean(plug)
def _is_dirty(self, plug):
return plug == self.outputPosAttr
def _find_center_point(self, positions):
sum_vector = om.MVector(0, 0, 0)
for pos in positions:
sum_vector += pos
center_point = sum_vector / len(positions)
center_point = om.MVector(round(center_point.x, 3), round(center_point.y, 3), round(center_point.z, 3))
return center_point
def initializePlugin(plugin):
vendor = "Adriano Domeniconi"
version = "0.0.1"
plugin_fn = om.MFnPlugin(plugin, vendor, version)
try:
plugin_fn.registerNode(CenterPointNode.kTypeName,
CenterPointNode.kTypeId,
CenterPointNode.creator,
CenterPointNode.initialize,
om.MPxNode.kDependNode)
except Exception as e:
om.MGlobal.displayError(f"Failed to register node: {CenterPointNode.kTypeName}: {e}")
def uninitializePlugin(plugin):
plugin_fn = om.MFnPlugin(plugin)
try:
plugin_fn.deregisterNode(CenterPointNode.kTypeId)
except Exception as e:
om.MGlobal.displayError(f"Failed to de-register node: {CenterPointNode.kTypeName}: {e}")
if __name__ == "__main__":
def __setup_test_scene():
centerPointNode = cmds.createNode("centerPoint")
sphere1 = cmds.polySphere()[0]
sphere2 = cmds.polySphere()[0]
sphere3 = cmds.polySphere()[0]
sphere4 = cmds.polySphere()[0]
cmds.connectAttr(f"{sphere1}.worldMatrix[0]", f"{centerPointNode}.input[0]")
cmds.connectAttr(f"{sphere2}.worldMatrix[0]", f"{centerPointNode}.input[1]")
cmds.connectAttr(f"{sphere3}.worldMatrix[0]", f"{centerPointNode}.input[2]")
cmds.connectAttr(f"{centerPointNode}.outputPosition", f"{sphere4}.t")
plugin_name = "center_point_node.py"
cmds.file(new=True, force=True)
cmds.evalDeferred('if cmds.pluginInfo("{0}", q=True, loaded=True): cmds.unloadPlugin("{0}")'.format(plugin_name))
cmds.evalDeferred('if not cmds.pluginInfo("{0}", q=True, loaded=True): cmds.loadPlugin("{0}")'.format(plugin_name))
cmds.evalDeferred('__setup_test_scene()')