12 from builtins
import range
14 import maya.api.OpenMaya
as om
18 The presence of this function tells Maya that the plugin produces, and
19 expects to be passed, objects created using the Maya Python API 2.0.
24 def getPointAndNormal(meshDagPath, faceIndex, relative, parameterU, parameterV, point, normal, theMesh):
26 if not theMesh.isNull():
29 faceIter = om.MItMeshPolygon(polyObj)
30 faceIter.setIndex(faceIndex)
37 uvs = faceIter.getUVs()
44 for i
in range(len(uArray)):
54 u = minU + parameterU * (maxU - minU)
55 v = minV + parameterV * (maxV - minV)
60 newPoint = faceIter.getPointAtUV(UV, om.MSpace.kWorld)
69 meshFn = om.MFnMesh(meshDagPath)
70 if not theMesh.isNull():
71 meshFn.setObject(theMesh)
72 newNormal = meshFn.getClosestNormal(point, om.MSpace.kWorld)
73 normal.x = newNormal[0].x
74 normal.y = newNormal[0].y
75 normal.z = newNormal[0].z
80 class pointOnMeshCommand(om.MPxCommand):
82 positionSpecified =
False
83 normalSpecified =
False
84 faceIndexSpecified =
False
85 relativeSpecified =
False
86 parameterUSpecified =
False
87 parameterVSpecified =
False
89 pointOnMeshInfoName =
""
96 om.MPxCommand.__init__(self)
101 return pointOnMeshCommand()
104 def isUndoable(self):
108 def doIt(self, args):
110 for i
in range(len(args)):
111 if (
"-name" == args.asString(i))
or (
"-na" == args.asString(i)):
113 self.pointOnMeshInfoName = args.asString(i)
115 elif (
"-position" == args.asString(i))
or (
"-p" == args.asString(i)):
116 self.positionSpecified =
True
118 elif (
"-normal" == args.asString(i))
or (
"-nr" == args.asString(i)):
119 self.normalSpecified =
True
121 elif (
"-faceIndex" == args.asString(i))
or (
"-f" == args.asString(i)):
122 self.faceIndexSpecified =
True
126 raise ValueError(
"Invalid faceIndex!")
129 elif (
"-relative" == args.asString(i))
or (
"-r" ==args.asString(i)):
130 self.relativeSpecified =
True
132 self.relative = args.asBool(i)
134 elif (
"-parameterU" == args.asString(i))
or (
"-u" == args.asString(i)):
135 self.parameterUSpecified =
True
137 temp = args.asDouble(i)
138 if temp < 0
or temp > 1:
139 raise ValueError(
"Invalid parameterU!")
140 self.parameterU = temp
142 elif (
"-parameterV" == args.asString(i))
or (
"-v" == args.asString(i)):
143 self.parameterVSpecified =
True
145 temp = args.asDouble(i)
146 if temp < 0
or temp > 1:
147 raise ValueError(
"Invalid parameterV!")
148 self.parameterV = temp
150 elif i == (len(args)-1):
151 self.meshNodeName = args.asString(i)
154 raise ValueError(
"Invalid flag:" + args.asString(i))
157 if not self.faceIndexSpecified:
159 if not self.relativeSpecified:
161 if not self.parameterUSpecified:
163 if not self.parameterVSpecified:
164 self.parameterV = 0.5
172 sList = om.MSelectionList()
173 if self.meshNodeName ==
"":
174 sList = om.MGlobal.getActiveSelectionList()
175 if sList.length() == 0:
176 raise ValueError(
"No mesh or mesh transform specified!")
180 sList.add(self.meshNodeName)
183 meshDagPath = sList.getDagPath(0)
189 normal = om.MVector()
191 if meshDagPath.node().hasFn(om.MFn.kMesh):
193 if not self.positionSpecified
and not self.normalSpecified:
195 self.nodeCreated =
True
196 depNodeFn = om.MFnDependencyNode()
198 if self.pointOnMeshInfoName ==
"":
199 depNodeFn.create(
"pointOnMeshInfo")
201 depNodeFn.create(
"pointOnMeshInfo", self.pointOnMeshInfoName)
202 self.pointOnMeshInfoName = depNodeFn.name()
205 if self.faceIndexSpecified:
206 faceIndexPlug = depNodeFn.findPlug(
"faceIndex",
True)
207 faceIndexPlug.setValue(self.faceIndex)
210 if self.relativeSpecified:
211 relativePlug = depNodeFn.findPlug(
"relative",
True)
212 relativePlug.setValue(self.relative)
215 if self.parameterUSpecified:
216 parameterUPlug = depNodeFn.findPlug(
"parameterU",
True)
217 parameterUPlug.setValue(self.parameterU)
220 if self.parameterVSpecified:
221 parameterVPlug = depNodeFn.findPlug(
"parameterV",
True)
222 parameterVPlug.setValue(self.parameterV)
225 inMeshPlug = depNodeFn.findPlug(
"inMesh",
True)
226 depNodeFn.setObject(meshDagPath.node())
227 worldMeshPlug = depNodeFn.findPlug(
"worldMesh",
True)
228 worldMeshPlug = worldMeshPlug.elementByLogicalIndex(0)
230 dgModifier = om.MDGModifier()
231 dgModifier.connect(worldMeshPlug, inMeshPlug)
235 om.MPxCommand.setResult(self.pointOnMeshInfoName)
239 getPointAndNormal(meshDagPath, self.faceIndex, self.relative, self.parameterU, self.parameterV, point, normal)
242 elif meshDagPath.node().hasFn(om.MFn.kTransform)
and meshDagPath.hasFn(om.MFn.kMesh):
244 if not self.positionSpecified
and not self.normalSpecified:
246 self.nodeCreated =
True
247 meshDagPath.extendToShape()
248 depNodeFn = om.MFnDependencyNode()
250 if self.pointOnMeshInfoName ==
"":
251 depNodeFn.create(
"pointOnMeshInfo")
253 depNodeFn.create(
"pointOnMeshInfo", self.pointOnMeshInfoName)
254 self.pointOnMeshInfoName = depNodeFn.name()
257 if self.faceIndexSpecified:
258 faceIndexPlug = depNodeFn.findPlug(
"faceIndex",
True)
259 faceIndexPlug.setValue(self.faceIndex)
262 if self.relativeSpecified:
263 relativePlug = depNodeFn.findPlug(
"relative",
True)
264 relativePlug.setValue(self.relative)
267 if self.parameterUSpecified:
268 parameterUPlug = depNodeFn.findPlug(
"parameterU",
True)
269 parameterUPlug.setValue(self.parameterU)
272 if self.parameterVSpecified:
273 parameterVPlug = depNodeFn.findPlug(
"parameterV",
True)
274 parameterVPlug.setValue(self.parameterV)
277 inMeshPlug = depNodeFn.findPlug(
"inMesh",
True)
278 depNodeFn.setObject(meshDagPath.node())
279 worldMeshPlug = depNodeFn.findPlug(
"worldMesh",
True)
280 worldMeshPlug = worldMeshPlug.elementByLogicalIndex(meshDagPath.instanceNumber())
282 dgModifier = om.MDGModifier()
283 dgModifier.connect(worldMeshPlug, inMeshPlug)
287 om.MPxCommand.setResult(self.pointOnMeshInfoName)
291 getPointAndNormal(meshDagPath, self.faceIndex, self.relative, self.parameterU, self.parameterV, point, normal)
295 raise ValueError(
"Invalid type! Only a mesh or its transform can be specified!")
298 result = om.MDoubleArray()
299 if self.positionSpecified:
300 result.append(point.x)
301 result.append(point.y)
302 result.append(point.z)
303 if self.normalSpecified:
304 result.append(normal.x)
305 result.append(normal.y)
306 result.append(normal.z)
308 om.MPxCommand.setResult(result)
314 deleteCmd =
"delete " + self.pointOnMeshInfoName
315 om.MGlobal.executeCommand(deleteCmd)
320 class pointOnMeshInfoNode(om.MPxNode):
321 id = om.MTypeId(0x00105480)
339 om.MPxNode.__init__(self)
344 return pointOnMeshInfoNode()
350 inMeshAttrFn = om.MFnTypedAttribute()
351 pointOnMeshInfoNode.aInMesh = inMeshAttrFn.create(
"inMesh",
"im", om.MFnData.kMesh)
352 inMeshAttrFn.storable =
True
353 inMeshAttrFn.keyable =
False
354 inMeshAttrFn.readable =
True
355 inMeshAttrFn.writable =
True
356 inMeshAttrFn.cached =
False
357 om.MPxNode.addAttribute(pointOnMeshInfoNode.aInMesh)
360 faceIndexAttrFn = om.MFnNumericAttribute()
361 pointOnMeshInfoNode.aFaceIndex = faceIndexAttrFn.create(
"faceIndex",
"f", om.MFnNumericData.kLong, 0)
362 faceIndexAttrFn.storable =
True
363 faceIndexAttrFn.keyable =
True
364 faceIndexAttrFn.readable =
True
365 faceIndexAttrFn.writable =
True
366 faceIndexAttrFn.setMin(0)
367 om.MPxNode.addAttribute(pointOnMeshInfoNode.aFaceIndex)
370 relativeAttrFn = om.MFnNumericAttribute()
371 pointOnMeshInfoNode.aRelative = relativeAttrFn.create(
"relative",
"r", om.MFnNumericData.kBoolean, 1)
372 relativeAttrFn.storable = True
373 relativeAttrFn.keyable =
True
374 relativeAttrFn.readable =
True
375 relativeAttrFn.writable =
True
376 om.MPxNode.addAttribute(pointOnMeshInfoNode.aRelative)
379 parameterUAttrFn = om.MFnNumericAttribute()
380 pointOnMeshInfoNode.aParameterU = parameterUAttrFn.create(
"parameterU",
"u", om.MFnNumericData.kDouble, 0.5)
381 parameterUAttrFn.storable = True
382 parameterUAttrFn.keyable =
True
383 parameterUAttrFn.readable =
True
384 parameterUAttrFn.writable =
True
385 om.MPxNode.addAttribute(pointOnMeshInfoNode.aParameterU)
388 parameterVAttrFn = om.MFnNumericAttribute()
389 pointOnMeshInfoNode.aParameterV = parameterVAttrFn.create(
"parameterV",
"v", om.MFnNumericData.kDouble, 0.5)
390 parameterVAttrFn.storable =
True
391 parameterVAttrFn.keyable =
True
392 parameterVAttrFn.readable =
True
393 parameterVAttrFn.writable =
True
394 om.MPxNode.addAttribute(pointOnMeshInfoNode.aParameterV)
397 pointXAttrFn = om.MFnNumericAttribute()
398 pointOnMeshInfoNode.aPositionX = pointXAttrFn.create(
"positionX",
"px", om.MFnNumericData.kDouble, 0.0)
399 pointXAttrFn.storable =
False
400 pointXAttrFn.keyable =
False
401 pointXAttrFn.readable =
True
402 pointXAttrFn.writable =
False
403 om.MPxNode.addAttribute(pointOnMeshInfoNode.aPositionX)
406 pointYAttrFn = om.MFnNumericAttribute()
407 pointOnMeshInfoNode.aPositionY = pointYAttrFn.create(
"positionY",
"py", om.MFnNumericData.kDouble, 0.0)
408 pointYAttrFn.storable =
False
409 pointYAttrFn.keyable =
False
410 pointYAttrFn.readable =
True
411 pointYAttrFn.writable =
False
412 om.MPxNode.addAttribute(pointOnMeshInfoNode.aPositionY)
415 pointZAttrFn = om.MFnNumericAttribute()
416 pointOnMeshInfoNode.aPositionZ = pointZAttrFn.create(
"positionZ",
"pz", om.MFnNumericData.kDouble, 0.0)
417 pointZAttrFn.storable =
False
418 pointZAttrFn.keyable =
False
419 pointZAttrFn.readable =
True
420 pointZAttrFn.writable =
False
421 om.MPxNode.addAttribute(pointOnMeshInfoNode.aPositionZ)
424 pointAttrFn = om.MFnNumericAttribute()
425 pointOnMeshInfoNode.aPosition = pointAttrFn.create(
"position",
"p", pointOnMeshInfoNode.aPositionX, pointOnMeshInfoNode.aPositionY, pointOnMeshInfoNode.aPositionZ)
426 pointAttrFn.storable =
False
427 pointAttrFn.keyable =
False
428 pointAttrFn.readable =
True
429 pointAttrFn.writable =
False
430 om.MPxNode.addAttribute(pointOnMeshInfoNode.aPosition)
433 normalXAttrFn = om.MFnNumericAttribute()
434 pointOnMeshInfoNode.aNormalX = normalXAttrFn.create(
"normalX",
"nx", om.MFnNumericData.kDouble, 0.0)
435 normalXAttrFn.storable =
False
436 normalXAttrFn.keyable =
False
437 normalXAttrFn.readable =
True
438 normalXAttrFn.writable =
False
439 om.MPxNode.addAttribute(pointOnMeshInfoNode.aNormalX)
442 normalYAttrFn = om.MFnNumericAttribute()
443 pointOnMeshInfoNode.aNormalY = normalYAttrFn.create(
"normalY",
"ny", om.MFnNumericData.kDouble, 0.0)
444 normalYAttrFn.storable =
False
445 normalYAttrFn.keyable =
False
446 normalYAttrFn.readable =
True
447 normalYAttrFn.writable =
False
448 om.MPxNode.addAttribute(pointOnMeshInfoNode.aNormalY)
451 normalZAttrFn = om.MFnNumericAttribute()
452 pointOnMeshInfoNode.aNormalZ = normalZAttrFn.create(
"normalZ",
"nz", om.MFnNumericData.kDouble, 0.0)
453 normalZAttrFn.storable =
False
454 normalZAttrFn.keyable =
False
455 normalZAttrFn.readable =
True
456 normalZAttrFn.writable =
False
457 om.MPxNode.addAttribute(pointOnMeshInfoNode.aNormalZ)
460 normalAttrFn = om.MFnNumericAttribute()
461 pointOnMeshInfoNode.aNormal = normalAttrFn.create(
"normal",
"n", pointOnMeshInfoNode.aNormalX, pointOnMeshInfoNode.aNormalY, pointOnMeshInfoNode.aNormalZ)
462 normalAttrFn.storable =
False
463 normalAttrFn.keyable =
False
464 normalAttrFn.readable =
True
465 normalAttrFn.writable =
False
466 om.MPxNode.addAttribute(pointOnMeshInfoNode.aNormal)
469 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aInMesh, pointOnMeshInfoNode.aPosition)
470 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aInMesh, pointOnMeshInfoNode.aPositionX)
471 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aInMesh, pointOnMeshInfoNode.aPositionY)
472 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aInMesh, pointOnMeshInfoNode.aPositionZ)
473 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aInMesh, pointOnMeshInfoNode.aNormal)
474 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aInMesh, pointOnMeshInfoNode.aNormalX)
475 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aInMesh, pointOnMeshInfoNode.aNormalY)
476 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aInMesh, pointOnMeshInfoNode.aNormalZ)
479 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aFaceIndex, pointOnMeshInfoNode.aPosition)
480 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aFaceIndex, pointOnMeshInfoNode.aPositionX)
481 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aFaceIndex, pointOnMeshInfoNode.aPositionY)
482 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aFaceIndex, pointOnMeshInfoNode.aPositionZ)
483 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aFaceIndex, pointOnMeshInfoNode.aNormal)
484 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aFaceIndex, pointOnMeshInfoNode.aNormalX)
485 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aFaceIndex, pointOnMeshInfoNode.aNormalY)
486 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aFaceIndex, pointOnMeshInfoNode.aNormalZ)
489 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aRelative, pointOnMeshInfoNode.aPosition)
490 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aRelative, pointOnMeshInfoNode.aPositionX)
491 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aRelative, pointOnMeshInfoNode.aPositionY)
492 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aRelative, pointOnMeshInfoNode.aPositionZ)
493 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aRelative, pointOnMeshInfoNode.aNormal)
494 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aRelative, pointOnMeshInfoNode.aNormalX)
495 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aRelative, pointOnMeshInfoNode.aNormalY)
496 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aRelative, pointOnMeshInfoNode.aNormalZ)
499 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aParameterU, pointOnMeshInfoNode.aPosition)
500 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aParameterU, pointOnMeshInfoNode.aPositionX)
501 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aParameterU, pointOnMeshInfoNode.aPositionY)
502 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aParameterU, pointOnMeshInfoNode.aPositionZ)
503 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aParameterU, pointOnMeshInfoNode.aNormal)
504 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aParameterU, pointOnMeshInfoNode.aNormalX)
505 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aParameterU, pointOnMeshInfoNode.aNormalY)
506 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aParameterU, pointOnMeshInfoNode.aNormalZ)
509 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aParameterV, pointOnMeshInfoNode.aPosition)
510 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aParameterV, pointOnMeshInfoNode.aPositionX)
511 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aParameterV, pointOnMeshInfoNode.aPositionY)
512 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aParameterV, pointOnMeshInfoNode.aPositionZ)
513 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aParameterV, pointOnMeshInfoNode.aNormal)
514 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aParameterV, pointOnMeshInfoNode.aNormalX)
515 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aParameterV, pointOnMeshInfoNode.aNormalY)
516 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aParameterV, pointOnMeshInfoNode.aNormalZ)
519 def compute(self, plug, data):
520 assert(isinstance(data.context(), om.MDGContext))
521 assert(data.setContext(data.context()) == data)
524 if plug == pointOnMeshInfoNode.aPosition
or plug == pointOnMeshInfoNode.aPositionX
or plug == pointOnMeshInfoNode.aPositionY
or plug == pointOnMeshInfoNode.aPositionZ
or plug == pointOnMeshInfoNode.aNormal
or plug == pointOnMeshInfoNode.aNormalX
or plug == pointOnMeshInfoNode.aNormalY
or plug == pointOnMeshInfoNode.aNormalZ:
526 inMeshDataHandle = data.inputValue(pointOnMeshInfoNode.aInMesh)
527 inMesh = inMeshDataHandle.asMesh()
530 faceIndexDataHandle = data.inputValue(pointOnMeshInfoNode.aFaceIndex)
531 faceIndex = faceIndexDataHandle.asInt()
534 relativeDataHandle = data.inputValue(pointOnMeshInfoNode.aRelative)
535 relative = relativeDataHandle.asBool()
538 parameterUDataHandle = data.inputValue(pointOnMeshInfoNode.aParameterU)
539 parameterU = parameterUDataHandle.asDouble()
542 parameterVDataHandle = data.inputValue(pointOnMeshInfoNode.aParameterV)
543 parameterV = parameterVDataHandle.asDouble()
547 normal = om.MVector()
548 dummyDagPath = om.MDagPath()
549 getPointAndNormal(dummyDagPath, faceIndex, relative, parameterU, parameterV, point, normal, inMesh)
552 pointDataHandle = data.outputValue(pointOnMeshInfoNode.aPosition)
553 pointDataHandle.set3Double(point.x, point.y, point.z)
557 normalDataHandle = data.outputValue(pointOnMeshInfoNode.aNormal)
558 normalDataHandle.set3Double(normal.x, normal.y, normal.z)
569 def initializePlugin(obj):
570 plugin = om.MFnPlugin(obj)
572 plugin.registerCommand(
"py2PointOnMesh", pointOnMeshCommand.cmdCreator)
574 sys.stderr.write(
"Failed to register command\n")
578 plugin.registerNode(
"pointOnMeshInfo", pointOnMeshInfoNode.id, pointOnMeshInfoNode.cmdCreator, pointOnMeshInfoNode.initialize)
580 sys.stderr.write(
"Failed to register node\n")
586 def uninitializePlugin(obj):
587 plugin = om.MFnPlugin(obj)
589 plugin.deregisterCommand(
"py2PointOnMesh")
591 sys.stderr.write(
"Failed to deregister command\n")
595 plugin.deregisterNode(pointOnMeshInfoNode.id)
597 sys.stderr.write(
"Failed to deregister node\n")