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)
 
  568 def initializePlugin(obj):
 
  569     plugin = om.MFnPlugin(obj)
 
  571         plugin.registerCommand(
"pointOnMesh", pointOnMeshCommand.cmdCreator)
 
  573         sys.stderr.write(
"Failed to register command\n")
 
  577         plugin.registerNode(
"pointOnMeshInfo", pointOnMeshInfoNode.id, pointOnMeshInfoNode.cmdCreator, pointOnMeshInfoNode.initialize)
 
  579         sys.stderr.write(
"Failed to register node\n")
 
  585 def uninitializePlugin(obj):
 
  586     plugin = om.MFnPlugin(obj)
 
  588         plugin.deregisterCommand(
"pointOnMesh")
 
  590         sys.stderr.write(
"Failed to deregister command\n")
 
  594         plugin.deregisterNode(pointOnMeshInfoNode.id)
 
  596         sys.stderr.write(
"Failed to deregister node\n")