68 import maya.OpenMaya 
as OpenMaya
 
   69 import maya.OpenMayaMPx 
as OpenMayaMPx
 
   74 def statusError(message):
 
   75     fullMsg = 
"Status failed: %s\n" % message
 
   76     sys.stderr.write(fullMsg)
 
   81 kPluginCmdName = 
"spSplitUV" 
   82 kPluginNodeTypeName = 
"spSplitUVNode" 
   85 class splitUV(polyModifier.polyModifierCmd):
 
   87         polyModifier.polyModifierCmd.__init__(self)
 
   96         self.__fSplitUVFactory = splitUVFty()
 
  103     def doIt(self, args):
 
  105         implements the scripted splitUV command. 
  108             args - the argument list that was passes to the command from MEL 
  131         foundMultiple = 
False 
  133         while not selListIter.isDone():
 
  137             selListIter.getDagPath(dagPath, component)
 
  141             if itemMatches 
and (component.apiType() == OpenMaya.MFn.kMeshMapComponent):
 
  147                     compListFn.add(component)
 
  152                     self.__fComponentList = compListFn.object()
 
  159                     compFn.getElements(self.__fSelUVs)
 
  164                     dagPath.extendToShape()
 
  165                     self._setMeshNode(dagPath)
 
  178             self.displayWarning(
"Found more than one object with selected UVs - Only operating on first found object.")
 
  182         self._setModifierNodeType(kPluginNodeId)
 
  185             if self.__validateUVs():
 
  192                     self.displayError(
"splitUV command failed!")
 
  195                     self.setResult(
"splitUV command succeeded!")
 
  197                 self.displayError(
"splitUV command failed: Selected UVs are not splittable")
 
  199             self.displayError(
"splitUV command failed: Unable to find selected UVs")
 
  204         Implements redo for the scripted splitUV command.  
  206         This method is called when the user has undone a command of this type 
  207         and then redoes it.  No arguments are passed in as all of the necessary 
  208         information is cached by the doIt method. 
  211             self._redoModifyPoly()
 
  212             self.setResult(
"splitUV command succeeded!")
 
  214             self.displayError(
"splitUV command failed!")
 
  220         implements undo for the scripted splitUV command.   
  222         This method is called to undo a previous command of this type.  The  
  223         system should be returned to the exact state that it was it previous  
  224         to this command being executed.  That includes the selection state. 
  227             self._undoModifyPoly()
 
  228             self.setResult(
"splitUV undo succeeded!")
 
  230             self.displayError(
"splitUV undo failed!")
 
  234     def _initModifierNode(self, modifierNode):
 
  240         uvListAttr = depNodeFn.attribute(
"inputComponents")
 
  245         uvListPlug.setMObject(self.__fComponentList)
 
  248     def _directModifier(self, mesh):
 
  249         self.__fSplitUVFactory.setMesh(mesh)
 
  250         self.__fSplitUVFactory.setUVIds(self.__fSelUVs)
 
  254         self.__fSplitUVFactory.doIt()
 
  257     def __validateUVs(self):
 
  259         Validate the UVs for the splitUV operation. UVs are valid only if they are shared 
  260         by more than one face. While the splitUVNode is smart enough to not process the 
  261         split if a UV is not splittable, a splitUV node is still created by the polyModifierCmd. 
  262         So call this method to validate the UVs before calling _doModifyPoly(). 
  264         validateUVs() will return true so long as there is at least one valid UV. It will 
  265         also prune out any invalid UVs from both the component list and UVId array. 
  269         dagPath = self._getMeshNode()
 
  270         mesh = dagPath.node()
 
  278         indexParam = OpenMaya.MScriptUtil(0)
 
  279         indexPtr = indexParam.asIntPtr()
 
  282         selUVsCount = self.__fSelUVs.length()
 
  283         for i 
in range(selUVsCount):
 
  284             while not polyIter.isDone():
 
  285                 if polyIter.hasUVs():
 
  286                     polyVertCount = polyIter.polygonVertexCount()
 
  288                     for j 
in range(polyVertCount):
 
  289                         polyIter.getUVIndex(j, indexPtr)
 
  290                         UVIndex = indexParam.getInt(indexPtr)
 
  292                         if UVIndex == self.__fSelUVs[i]:
 
  296             selUVFaceCountArray.append(count)
 
  305         for i 
in range(selUVsCount):
 
  306             if selUVFaceCountArray[i] > 1:
 
  308                 validUVIndices.append(i)
 
  311             self.__pruneUVs(validUVIndices)
 
  316     def __pruneUVs(self, validUVIndices):
 
  318         This method will remove any invalid UVIds from the component list and UVId array. 
  319         The benefit of this is to reduce the amount of extra processing that the node would 
  320         have to perform. It will result in less iterations through the mesh as there are 
  321         less UVs to search for. 
  325         for i 
in range(validUVIndices.length()):
 
  326             uvIndex = validUVIndices[i]
 
  327             validUVIds.append(self.__fSelUVs[uvIndex])
 
  331         self.__fSelUVs.clear()
 
  332         self.__fSelUVs = validUVIds
 
  338             compFn.create(OpenMaya.MFn.kMeshMapComponent)
 
  340             statusError(
"compFn.create( MFn::kMeshMapComponent )")
 
  343             compFn.addElements(validUVIds)
 
  345             statusError(
"compFn.addElements( validUVIds )")
 
  349         component = compFn.object()
 
  353             compListFn.add(component)
 
  355             statusError(
"compListFn.add( component )")
 
  357         self.__fComponentList = compListFn.object()
 
  391 class splitUVFty(polyModifier.polyModifierFty):
 
  393         polyModifier.polyModifierFty.__init__(self)
 
  402         self.__fSelUVs.clear()
 
  405     def setMesh(self, mesh):
 
  409     def setUVIds(self, uvIds):
 
  410         self.__fSelUVs = uvIds
 
  415         Performs the actual splitUV operation on the given object and UVs 
  438         selUVSet = meshFn.currentUVSetName()
 
  440         indexParam = OpenMaya.MScriptUtil(0)
 
  441         indexPtr = indexParam.asIntPtr()
 
  444         selUVsCount = self.__fSelUVs.length()
 
  446         for i 
in range(selUVsCount):
 
  447             selUVFaceOffsetMap.append(offset)
 
  450             while not polyIter.isDone():
 
  451                 if polyIter.hasUVs():
 
  452                     polyVertCount = polyIter.polygonVertexCount()
 
  454                     for j 
in range(polyVertCount):
 
  455                         polyIter.getUVIndex(j, indexPtr)
 
  456                         UVIndex = indexParam.getInt(indexPtr)
 
  458                         if UVIndex == self.__fSelUVs[i]:
 
  459                             selUVFaceIdMap.append(polyIter.index())
 
  460                             selUVLocalVertIdMap.append(j)
 
  470         selUVFaceOffsetMap.append(offset)
 
  476         currentUVCount = meshFn.numUVs(selUVSet)
 
  478         for i 
in range(selUVsCount):
 
  481             offset = selUVFaceOffsetMap[i]
 
  485             uvId = self.__fSelUVs[i]
 
  487             uParam = OpenMaya.MScriptUtil(0.0)
 
  488             uPtr = uParam.asFloatPtr()
 
  489             vParam = OpenMaya.MScriptUtil(0.0)
 
  490             vPtr = vParam.asFloatPtr()
 
  491             meshFn.getUV(uvId, uPtr, vPtr, selUVSet)
 
  492             u = uParam.getFloat(uPtr)
 
  493             v = vParam.getFloat(vPtr)
 
  497             faceCount = selUVFaceOffsetMap[i + 1] - selUVFaceOffsetMap[i]
 
  502             for j 
in range(faceCount-1):
 
  503                 meshFn.setUV(currentUVCount, u, v, selUVSet)
 
  505                 localVertId = selUVLocalVertIdMap[offset]
 
  506                 faceId = selUVFaceIdMap[offset]
 
  508                 meshFn.assignUV(faceId, localVertId, currentUVCount, selUVSet)
 
  518 class splitUVNode(polyModifier.polyModifierNode):
 
  523         polyModifier.polyModifierNode.__init__(self)
 
  524         self.fSplitUVFactory = splitUVFty()
 
  527     def compute(self, plug, data):
 
  530             This method computes the value of the given output plug based 
  531             on the values of the input attributes. 
  534             plug - the plug to compute 
  535             data - object that provides access to the attributes for this node 
  538         state = OpenMayaMPx.cvar.MPxNode_state
 
  540             stateData = data.outputValue(state)
 
  542             statusError(
"ERROR getting state")
 
  553         if stateData.asShort() == 1:
 
  555                 inputData = data.inputValue(splitUVNode.inMesh)
 
  557                 statusError(
"ERROR getting inMesh")
 
  560                 outputData = data.outputValue(splitUVNode.outMesh)
 
  562                 statusError(
"ERROR getting outMesh")
 
  566             outputData.setMObject(inputData.asMesh())
 
  572             if plug == splitUVNode.outMesh:
 
  574                     inputData = data.inputValue(splitUVNode.inMesh)
 
  576                     statusError(
"ERROR getting inMesh")
 
  579                     outputData = data.outputValue(splitUVNode.outMesh)
 
  581                     statusError(
"ERROR getting outMesh") 
 
  587                     inputUVs = data.inputValue(splitUVNode.uvList)
 
  589                     statusError(
"ERROR getting uvList")
 
  594                 outputData.setMObject(inputData.asMesh())
 
  595                 mesh = outputData.asMesh()
 
  603                 compList = inputUVs.data()
 
  607                 for i 
in range(compListFn.length()):
 
  609                     if comp.apiType() == OpenMaya.MFn.kMeshMapComponent:
 
  611                         for j 
in range(uvComp.elementCount()):
 
  612                             uvId = uvComp.element(j)
 
  617                 self.fSplitUVFactory.setMesh(mesh)
 
  618                 self.fSplitUVFactory.setUVIds(uvIds)
 
  623                     self.fSplitUVFactory.doIt()
 
  625                     statusError(
"ERROR in splitUVFty.doIt()")
 
  629                 outputData.setClean()
 
  631                 return OpenMaya.kUnknownParameter
 
  641     return OpenMayaMPx.asMPxPtr(splitUV())
 
  645     return OpenMayaMPx.asMPxPtr(splitUVNode())
 
  648 def nodeInitializer():
 
  651     splitUVNode.uvList = attrFn.create(
"inputComponents", 
"ics", OpenMaya.MFnComponentListData.kComponentList)
 
  652     attrFn.setStorable(
True)    
 
  654     splitUVNode.inMesh = attrFn.create(
"inMesh", 
"im", OpenMaya.MFnMeshData.kMesh)
 
  655     attrFn.setStorable(
True)    
 
  659     splitUVNode.outMesh = attrFn.create(
"outMesh", 
"om", OpenMaya.MFnMeshData.kMesh)
 
  660     attrFn.setStorable(
False)
 
  661     attrFn.setWritable(
False)
 
  665     splitUVNode.addAttribute(splitUVNode.uvList)
 
  666     splitUVNode.addAttribute(splitUVNode.inMesh)
 
  667     splitUVNode.addAttribute(splitUVNode.outMesh)
 
  673     splitUVNode.attributeAffects(splitUVNode.inMesh, splitUVNode.outMesh)
 
  674     splitUVNode.attributeAffects(splitUVNode.uvList, splitUVNode.outMesh)
 
  677 def initializePlugin(mobject):
 
  678     mplugin = OpenMayaMPx.MFnPlugin(mobject, 
"Autodesk", 
"1.0", 
"Any")
 
  680         mplugin.registerCommand(kPluginCmdName, cmdCreator)
 
  682         sys.stderr.write( 
"Failed to register command: %s\n" % kPluginCmdName)
 
  686         mplugin.registerNode(kPluginNodeTypeName, kPluginNodeId, nodeCreator, nodeInitializer)
 
  688         sys.stderr.write( 
"Failed to register node: %s" % kPluginNodeTypeName)
 
  692 def uninitializePlugin(mobject):
 
  693     mplugin = OpenMayaMPx.MFnPlugin(mobject)
 
  695         mplugin.deregisterCommand(kPluginCmdName)
 
  697         sys.stderr.write(
"Failed to unregister command: %s\n" % kPluginCmdName)
 
  701         mplugin.deregisterNode(kPluginNodeId)
 
  703         sys.stderr.write(
"Failed to deregister node: %s" % kPluginNodeTypeName)