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)