13 import maya.api.OpenMaya
as om
17 The presence of this function tells Maya that the plugin produces, and
18 expects to be passed, objects created using the Maya Python API 2.0.
23 def getPointAndNormal(meshDagPath, faceIndex, relative, parameterU, parameterV, point, normal, theMesh):
25 if not theMesh.isNull():
28 faceIter = om.MItMeshPolygon(polyObj)
29 faceIter.setIndex(faceIndex)
36 uvs = faceIter.getUVs()
43 for i
in range(len(uArray)):
53 u = minU + parameterU * (maxU - minU)
54 v = minV + parameterV * (maxV - minV)
59 newPoint = faceIter.getPointAtUV(UV, om.MSpace.kWorld)
68 meshFn = om.MFnMesh(meshDagPath)
69 if not theMesh.isNull():
70 meshFn.setObject(theMesh)
71 newNormal = meshFn.getClosestNormal(point, om.MSpace.kWorld)
72 normal.x = newNormal[0].x
73 normal.y = newNormal[0].y
74 normal.z = newNormal[0].z
79 class pointOnMeshCommand(om.MPxCommand):
81 positionSpecified =
False
82 normalSpecified =
False
83 faceIndexSpecified =
False
84 relativeSpecified =
False
85 parameterUSpecified =
False
86 parameterVSpecified =
False
88 pointOnMeshInfoName =
""
95 om.MPxCommand.__init__(self)
100 return pointOnMeshCommand()
103 def isUndoable(self):
107 def doIt(self, args):
109 for i
in range(len(args)):
110 if (
"-name" == args.asString(i))
or (
"-na" == args.asString(i)):
112 self.pointOnMeshInfoName = args.asString(i)
114 elif (
"-position" == args.asString(i))
or (
"-p" == args.asString(i)):
115 self.positionSpecified =
True
117 elif (
"-normal" == args.asString(i))
or (
"-nr" == args.asString(i)):
118 self.normalSpecified =
True
120 elif (
"-faceIndex" == args.asString(i))
or (
"-f" == args.asString(i)):
121 self.faceIndexSpecified =
True
125 raise ValueError(
"Invalid faceIndex!")
128 elif (
"-relative" == args.asString(i))
or (
"-r" ==args.asString(i)):
129 self.relativeSpecified =
True
131 self.relative = args.asBool(i)
133 elif (
"-parameterU" == args.asString(i))
or (
"-u" == args.asString(i)):
134 self.parameterUSpecified =
True
136 temp = args.asDouble(i)
137 if temp < 0
or temp > 1:
138 raise ValueError(
"Invalid parameterU!")
139 self.parameterU = temp
141 elif (
"-parameterV" == args.asString(i))
or (
"-v" == args.asString(i)):
142 self.parameterVSpecified =
True
144 temp = args.asDouble(i)
145 if temp < 0
or temp > 1:
146 raise ValueError(
"Invalid parameterV!")
147 self.parameterV = temp
149 elif i == (len(args)-1):
150 self.meshNodeName = args.asString(i)
153 raise ValueError(
"Invalid flag:" + args.asString(i))
156 if not self.faceIndexSpecified:
158 if not self.relativeSpecified:
160 if not self.parameterUSpecified:
162 if not self.parameterVSpecified:
163 self.parameterV = 0.5
171 sList = om.MSelectionList()
172 if self.meshNodeName ==
"":
173 sList = om.MGlobal.getActiveSelectionList()
174 if sList.length() == 0:
175 raise ValueError(
"No mesh or mesh transform specified!")
179 sList.add(self.meshNodeName)
182 meshDagPath = sList.getDagPath(0)
188 normal = om.MVector()
190 if meshDagPath.node().hasFn(om.MFn.kMesh):
192 if not self.positionSpecified
and not self.normalSpecified:
194 self.nodeCreated =
True
195 depNodeFn = om.MFnDependencyNode()
197 if self.pointOnMeshInfoName ==
"":
198 depNodeFn.create(
"pointOnMeshInfo")
200 depNodeFn.create(
"pointOnMeshInfo", self.pointOnMeshInfoName)
201 self.pointOnMeshInfoName = depNodeFn.name()
204 if self.faceIndexSpecified:
205 faceIndexPlug = depNodeFn.findPlug(
"faceIndex",
True)
206 faceIndexPlug.setValue(self.faceIndex)
209 if self.relativeSpecified:
210 relativePlug = depNodeFn.findPlug(
"relative",
True)
211 relativePlug.setValue(self.relative)
214 if self.parameterUSpecified:
215 parameterUPlug = depNodeFn.findPlug(
"parameterU",
True)
216 parameterUPlug.setValue(self.parameterU)
219 if self.parameterVSpecified:
220 parameterVPlug = depNodeFn.findPlug(
"parameterV",
True)
221 parameterVPlug.setValue(self.parameterV)
224 inMeshPlug = depNodeFn.findPlug(
"inMesh",
True)
225 depNodeFn.setObject(meshDagPath.node())
226 worldMeshPlug = depNodeFn.findPlug(
"worldMesh",
True)
227 worldMeshPlug = worldMeshPlug.elementByLogicalIndex(0)
229 dgModifier = om.MDGModifier()
230 dgModifier.connect(worldMeshPlug, inMeshPlug)
234 om.MPxCommand.setResult(self.pointOnMeshInfoName)
238 getPointAndNormal(meshDagPath, self.faceIndex, self.relative, self.parameterU, self.parameterV, point, normal)
241 elif meshDagPath.node().hasFn(om.MFn.kTransform)
and meshDagPath.hasFn(om.MFn.kMesh):
243 if not self.positionSpecified
and not self.normalSpecified:
245 self.nodeCreated =
True
246 meshDagPath.extendToShape()
247 depNodeFn = om.MFnDependencyNode()
249 if self.pointOnMeshInfoName ==
"":
250 depNodeFn.create(
"pointOnMeshInfo")
252 depNodeFn.create(
"pointOnMeshInfo", self.pointOnMeshInfoName)
253 self.pointOnMeshInfoName = depNodeFn.name()
256 if self.faceIndexSpecified:
257 faceIndexPlug = depNodeFn.findPlug(
"faceIndex",
True)
258 faceIndexPlug.setValue(self.faceIndex)
261 if self.relativeSpecified:
262 relativePlug = depNodeFn.findPlug(
"relative",
True)
263 relativePlug.setValue(self.relative)
266 if self.parameterUSpecified:
267 parameterUPlug = depNodeFn.findPlug(
"parameterU",
True)
268 parameterUPlug.setValue(self.parameterU)
271 if self.parameterVSpecified:
272 parameterVPlug = depNodeFn.findPlug(
"parameterV",
True)
273 parameterVPlug.setValue(self.parameterV)
276 inMeshPlug = depNodeFn.findPlug(
"inMesh",
True)
277 depNodeFn.setObject(meshDagPath.node())
278 worldMeshPlug = depNodeFn.findPlug(
"worldMesh",
True)
279 worldMeshPlug = worldMeshPlug.elementByLogicalIndex(meshDagPath.instanceNumber())
281 dgModifier = om.MDGModifier()
282 dgModifier.connect(worldMeshPlug, inMeshPlug)
286 om.MPxCommand.setResult(self.pointOnMeshInfoName)
290 getPointAndNormal(meshDagPath, self.faceIndex, self.relative, self.parameterU, self.parameterV, point, normal)
294 raise ValueError(
"Invalid type! Only a mesh or its transform can be specified!")
297 result = om.MDoubleArray()
298 if self.positionSpecified:
299 result.append(point.x)
300 result.append(point.y)
301 result.append(point.z)
302 if self.normalSpecified:
303 result.append(normal.x)
304 result.append(normal.y)
305 result.append(normal.z)
307 om.MPxCommand.setResult(result)
313 deleteCmd =
"delete " + self.pointOnMeshInfoName
314 om.MGlobal.executeCommand(deleteCmd)
319 class pointOnMeshInfoNode(om.MPxNode):
320 id = om.MTypeId(0x00105480)
338 om.MPxNode.__init__(self)
343 return pointOnMeshInfoNode()
349 inMeshAttrFn = om.MFnTypedAttribute()
350 pointOnMeshInfoNode.aInMesh = inMeshAttrFn.create(
"inMesh",
"im", om.MFnData.kMesh)
351 inMeshAttrFn.storable =
True
352 inMeshAttrFn.keyable =
False
353 inMeshAttrFn.readable =
True
354 inMeshAttrFn.writable =
True
355 inMeshAttrFn.cached =
False
356 om.MPxNode.addAttribute(pointOnMeshInfoNode.aInMesh)
359 faceIndexAttrFn = om.MFnNumericAttribute()
360 pointOnMeshInfoNode.aFaceIndex = faceIndexAttrFn.create(
"faceIndex",
"f", om.MFnNumericData.kLong, 0)
361 faceIndexAttrFn.storable =
True
362 faceIndexAttrFn.keyable =
True
363 faceIndexAttrFn.readable =
True
364 faceIndexAttrFn.writable =
True
365 faceIndexAttrFn.setMin(0)
366 om.MPxNode.addAttribute(pointOnMeshInfoNode.aFaceIndex)
369 relativeAttrFn = om.MFnNumericAttribute()
370 pointOnMeshInfoNode.aRelative = relativeAttrFn.create(
"relative",
"r", om.MFnNumericData.kBoolean, 1)
371 relativeAttrFn.storable = True
372 relativeAttrFn.keyable =
True
373 relativeAttrFn.readable =
True
374 relativeAttrFn.writable =
True
375 om.MPxNode.addAttribute(pointOnMeshInfoNode.aRelative)
378 parameterUAttrFn = om.MFnNumericAttribute()
379 pointOnMeshInfoNode.aParameterU = parameterUAttrFn.create(
"parameterU",
"u", om.MFnNumericData.kDouble, 0.5)
380 parameterUAttrFn.storable = True
381 parameterUAttrFn.keyable =
True
382 parameterUAttrFn.readable =
True
383 parameterUAttrFn.writable =
True
384 om.MPxNode.addAttribute(pointOnMeshInfoNode.aParameterU)
387 parameterVAttrFn = om.MFnNumericAttribute()
388 pointOnMeshInfoNode.aParameterV = parameterVAttrFn.create(
"parameterV",
"v", om.MFnNumericData.kDouble, 0.5)
389 parameterVAttrFn.storable =
True
390 parameterVAttrFn.keyable =
True
391 parameterVAttrFn.readable =
True
392 parameterVAttrFn.writable =
True
393 om.MPxNode.addAttribute(pointOnMeshInfoNode.aParameterV)
396 pointXAttrFn = om.MFnNumericAttribute()
397 pointOnMeshInfoNode.aPositionX = pointXAttrFn.create(
"positionX",
"px", om.MFnNumericData.kDouble, 0.0)
398 pointXAttrFn.storable =
False
399 pointXAttrFn.keyable =
False
400 pointXAttrFn.readable =
True
401 pointXAttrFn.writable =
False
402 om.MPxNode.addAttribute(pointOnMeshInfoNode.aPositionX)
405 pointYAttrFn = om.MFnNumericAttribute()
406 pointOnMeshInfoNode.aPositionY = pointYAttrFn.create(
"positionY",
"py", om.MFnNumericData.kDouble, 0.0)
407 pointYAttrFn.storable =
False
408 pointYAttrFn.keyable =
False
409 pointYAttrFn.readable =
True
410 pointYAttrFn.writable =
False
411 om.MPxNode.addAttribute(pointOnMeshInfoNode.aPositionY)
414 pointZAttrFn = om.MFnNumericAttribute()
415 pointOnMeshInfoNode.aPositionZ = pointZAttrFn.create(
"positionZ",
"pz", om.MFnNumericData.kDouble, 0.0)
416 pointZAttrFn.storable =
False
417 pointZAttrFn.keyable =
False
418 pointZAttrFn.readable =
True
419 pointZAttrFn.writable =
False
420 om.MPxNode.addAttribute(pointOnMeshInfoNode.aPositionZ)
423 pointAttrFn = om.MFnNumericAttribute()
424 pointOnMeshInfoNode.aPosition = pointAttrFn.create(
"position",
"p", pointOnMeshInfoNode.aPositionX, pointOnMeshInfoNode.aPositionY, pointOnMeshInfoNode.aPositionZ)
425 pointAttrFn.storable =
False
426 pointAttrFn.keyable =
False
427 pointAttrFn.readable =
True
428 pointAttrFn.writable =
False
429 om.MPxNode.addAttribute(pointOnMeshInfoNode.aPosition)
432 normalXAttrFn = om.MFnNumericAttribute()
433 pointOnMeshInfoNode.aNormalX = normalXAttrFn.create(
"normalX",
"nx", om.MFnNumericData.kDouble, 0.0)
434 normalXAttrFn.storable =
False
435 normalXAttrFn.keyable =
False
436 normalXAttrFn.readable =
True
437 normalXAttrFn.writable =
False
438 om.MPxNode.addAttribute(pointOnMeshInfoNode.aNormalX)
441 normalYAttrFn = om.MFnNumericAttribute()
442 pointOnMeshInfoNode.aNormalY = normalYAttrFn.create(
"normalY",
"ny", om.MFnNumericData.kDouble, 0.0)
443 normalYAttrFn.storable =
False
444 normalYAttrFn.keyable =
False
445 normalYAttrFn.readable =
True
446 normalYAttrFn.writable =
False
447 om.MPxNode.addAttribute(pointOnMeshInfoNode.aNormalY)
450 normalZAttrFn = om.MFnNumericAttribute()
451 pointOnMeshInfoNode.aNormalZ = normalZAttrFn.create(
"normalZ",
"nz", om.MFnNumericData.kDouble, 0.0)
452 normalZAttrFn.storable =
False
453 normalZAttrFn.keyable =
False
454 normalZAttrFn.readable =
True
455 normalZAttrFn.writable =
False
456 om.MPxNode.addAttribute(pointOnMeshInfoNode.aNormalZ)
459 normalAttrFn = om.MFnNumericAttribute()
460 pointOnMeshInfoNode.aNormal = normalAttrFn.create(
"normal",
"n", pointOnMeshInfoNode.aNormalX, pointOnMeshInfoNode.aNormalY, pointOnMeshInfoNode.aNormalZ)
461 normalAttrFn.storable =
False
462 normalAttrFn.keyable =
False
463 normalAttrFn.readable =
True
464 normalAttrFn.writable =
False
465 om.MPxNode.addAttribute(pointOnMeshInfoNode.aNormal)
468 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aInMesh, pointOnMeshInfoNode.aPosition)
469 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aInMesh, pointOnMeshInfoNode.aPositionX)
470 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aInMesh, pointOnMeshInfoNode.aPositionY)
471 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aInMesh, pointOnMeshInfoNode.aPositionZ)
472 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aInMesh, pointOnMeshInfoNode.aNormal)
473 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aInMesh, pointOnMeshInfoNode.aNormalX)
474 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aInMesh, pointOnMeshInfoNode.aNormalY)
475 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aInMesh, pointOnMeshInfoNode.aNormalZ)
478 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aFaceIndex, pointOnMeshInfoNode.aPosition)
479 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aFaceIndex, pointOnMeshInfoNode.aPositionX)
480 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aFaceIndex, pointOnMeshInfoNode.aPositionY)
481 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aFaceIndex, pointOnMeshInfoNode.aPositionZ)
482 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aFaceIndex, pointOnMeshInfoNode.aNormal)
483 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aFaceIndex, pointOnMeshInfoNode.aNormalX)
484 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aFaceIndex, pointOnMeshInfoNode.aNormalY)
485 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aFaceIndex, pointOnMeshInfoNode.aNormalZ)
488 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aRelative, pointOnMeshInfoNode.aPosition)
489 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aRelative, pointOnMeshInfoNode.aPositionX)
490 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aRelative, pointOnMeshInfoNode.aPositionY)
491 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aRelative, pointOnMeshInfoNode.aPositionZ)
492 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aRelative, pointOnMeshInfoNode.aNormal)
493 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aRelative, pointOnMeshInfoNode.aNormalX)
494 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aRelative, pointOnMeshInfoNode.aNormalY)
495 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aRelative, pointOnMeshInfoNode.aNormalZ)
498 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aParameterU, pointOnMeshInfoNode.aPosition)
499 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aParameterU, pointOnMeshInfoNode.aPositionX)
500 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aParameterU, pointOnMeshInfoNode.aPositionY)
501 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aParameterU, pointOnMeshInfoNode.aPositionZ)
502 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aParameterU, pointOnMeshInfoNode.aNormal)
503 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aParameterU, pointOnMeshInfoNode.aNormalX)
504 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aParameterU, pointOnMeshInfoNode.aNormalY)
505 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aParameterU, pointOnMeshInfoNode.aNormalZ)
508 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aParameterV, pointOnMeshInfoNode.aPosition)
509 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aParameterV, pointOnMeshInfoNode.aPositionX)
510 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aParameterV, pointOnMeshInfoNode.aPositionY)
511 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aParameterV, pointOnMeshInfoNode.aPositionZ)
512 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aParameterV, pointOnMeshInfoNode.aNormal)
513 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aParameterV, pointOnMeshInfoNode.aNormalX)
514 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aParameterV, pointOnMeshInfoNode.aNormalY)
515 om.MPxNode.attributeAffects(pointOnMeshInfoNode.aParameterV, pointOnMeshInfoNode.aNormalZ)
518 def compute(self, plug, data):
519 assert(isinstance(data.context(), om.MDGContext))
520 assert(data.setContext(data.context()) == data)
523 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:
525 inMeshDataHandle = data.inputValue(pointOnMeshInfoNode.aInMesh)
526 inMesh = inMeshDataHandle.asMesh()
529 faceIndexDataHandle = data.inputValue(pointOnMeshInfoNode.aFaceIndex)
530 faceIndex = faceIndexDataHandle.asInt()
533 relativeDataHandle = data.inputValue(pointOnMeshInfoNode.aRelative)
534 relative = relativeDataHandle.asBool()
537 parameterUDataHandle = data.inputValue(pointOnMeshInfoNode.aParameterU)
538 parameterU = parameterUDataHandle.asDouble()
541 parameterVDataHandle = data.inputValue(pointOnMeshInfoNode.aParameterV)
542 parameterV = parameterVDataHandle.asDouble()
546 normal = om.MVector()
547 dummyDagPath = om.MDagPath()
548 getPointAndNormal(dummyDagPath, faceIndex, relative, parameterU, parameterV, point, normal, inMesh)
551 pointDataHandle = data.outputValue(pointOnMeshInfoNode.aPosition)
552 pointDataHandle.set3Double(point.x, point.y, point.z)
556 normalDataHandle = data.outputValue(pointOnMeshInfoNode.aNormal)
557 normalDataHandle.set3Double(normal.x, normal.y, normal.z)
565 def initializePlugin(obj):
566 plugin = om.MFnPlugin(obj)
568 plugin.registerCommand(
"pointOnMesh", pointOnMeshCommand.cmdCreator)
570 sys.stderr.write(
"Failed to register command\n")
574 plugin.registerNode(
"pointOnMeshInfo", pointOnMeshInfoNode.id, pointOnMeshInfoNode.cmdCreator, pointOnMeshInfoNode.initialize)
576 sys.stderr.write(
"Failed to register node\n")
582 def uninitializePlugin(obj):
583 plugin = om.MFnPlugin(obj)
585 plugin.deregisterCommand(
"pointOnMesh")
587 sys.stderr.write(
"Failed to deregister command\n")
591 plugin.deregisterNode(pointOnMeshInfoNode.id)
593 sys.stderr.write(
"Failed to deregister node\n")