39 import maya.OpenMaya
as OpenMaya
40 import maya.OpenMayaMPx
as OpenMayaMPx
45 def statusError(message):
46 fullMsg =
"Status failed: %s\n" % message
47 sys.stderr.write(fullMsg)
48 OpenMaya.MGlobal.displayError(fullMsg)
52 kPluginCmdName =
"spSplitUV"
53 kPluginNodeTypeName =
"spSplitUVNode"
54 kPluginNodeId = OpenMaya.MTypeId(0x87013)
81 class splitUV(polyModifier.polyModifierCmd):
83 polyModifier.polyModifierCmd.__init__(self)
90 self.__fComponentList = OpenMaya.MObject()
91 self.__fSelUVs = OpenMaya.MIntArray()
92 self.__fSplitUVFactory = splitUVFty()
101 implements the scripted splitUV command.
104 args - the argument list that was passes to the command from MEL
113 selList = OpenMaya.MSelectionList()
114 OpenMaya.MGlobal.getActiveSelectionList(selList)
115 selListIter = OpenMaya.MItSelectionList(selList)
124 compListFn = OpenMaya.MFnComponentListData()
127 foundMultiple =
False
129 while not selListIter.isDone():
130 dagPath = OpenMaya.MDagPath()
131 component = OpenMaya.MObject()
133 selListIter.getDagPath(dagPath, component)
137 if itemMatches
and (component.apiType() == OpenMaya.MFn.kMeshMapComponent):
143 compListFn.add(component)
148 self.__fComponentList = compListFn.object()
154 compFn = OpenMaya.MFnSingleIndexedComponent(component)
155 compFn.getElements(self.__fSelUVs)
160 dagPath.extendToShape()
161 self._setMeshNode(dagPath)
174 self.displayWarning(
"Found more than one object with selected UVs - Only operating on first found object.")
178 self._setModifierNodeType(kPluginNodeId)
181 if self.__validateUVs():
188 self.displayError(
"splitUV command failed!")
191 self.setResult(
"splitUV command succeeded!")
193 self.displayError(
"splitUV command failed: Selected UVs are not splittable")
195 self.displayError(
"splitUV command failed: Unable to find selected UVs")
200 Implements redo for the scripted splitUV command.
202 This method is called when the user has undone a command of this type
203 and then redoes it. No arguments are passed in as all of the necessary
204 information is cached by the doIt method.
207 self._redoModifyPoly()
208 self.setResult(
"splitUV command succeeded!")
210 self.displayError(
"splitUV command failed!")
216 implements undo for the scripted splitUV command.
218 This method is called to undo a previous command of this type. The
219 system should be returned to the exact state that it was it previous
220 to this command being executed. That includes the selection state.
223 self._undoModifyPoly()
224 self.setResult(
"splitUV undo succeeded!")
226 self.displayError(
"splitUV undo failed!")
230 def _initModifierNode(self, modifierNode):
235 depNodeFn = OpenMaya.MFnDependencyNode(modifierNode)
236 uvListAttr = depNodeFn.attribute(
"inputComponents")
240 uvListPlug = OpenMaya.MPlug(modifierNode, uvListAttr)
241 uvListPlug.setMObject(self.__fComponentList)
244 def _directModifier(self, mesh):
245 self.__fSplitUVFactory.setMesh(mesh)
246 self.__fSplitUVFactory.setUVIds(self.__fSelUVs)
250 self.__fSplitUVFactory.doIt()
253 def __validateUVs(self):
255 Validate the UVs for the splitUV operation. UVs are valid only if they are shared
256 by more than one face. While the splitUVNode is smart enough to not process the
257 split if a UV is not splittable, a splitUV node is still created by the polyModifierCmd.
258 So call this method to validate the UVs before calling _doModifyPoly().
260 validateUVs() will return true so long as there is at least one valid UV. It will
261 also prune out any invalid UVs from both the component list and UVId array.
265 dagPath = self._getMeshNode()
266 mesh = dagPath.node()
270 meshFn = OpenMaya.MFnMesh(mesh)
271 polyIter = OpenMaya.MItMeshPolygon(mesh)
272 selUVFaceCountArray = OpenMaya.MIntArray()
274 indexParam = OpenMaya.MScriptUtil(0)
275 indexPtr = indexParam.asIntPtr()
278 selUVsCount = self.__fSelUVs.length()
279 for i
in range(selUVsCount):
280 while not polyIter.isDone():
281 if polyIter.hasUVs():
282 polyVertCount = polyIter.polygonVertexCount()
284 for j
in range(polyVertCount):
285 polyIter.getUVIndex(j, indexPtr)
286 UVIndex = indexParam.getInt(indexPtr)
288 if UVIndex == self.__fSelUVs[i]:
292 selUVFaceCountArray.append(count)
299 validUVIndices = OpenMaya.MIntArray()
301 for i
in range(selUVsCount):
302 if selUVFaceCountArray[i] > 1:
304 validUVIndices.append(i)
307 self.__pruneUVs(validUVIndices)
312 def __pruneUVs(self, validUVIndices):
314 This method will remove any invalid UVIds from the component list and UVId array.
315 The benefit of this is to reduce the amount of extra processing that the node would
316 have to perform. It will result in less iterations through the mesh as there are
317 less UVs to search for.
319 validUVIds = OpenMaya.MIntArray()
321 for i
in range(validUVIndices.length()):
322 uvIndex = validUVIndices[i]
323 validUVIds.append(self.__fSelUVs[uvIndex])
327 self.__fSelUVs.clear()
328 self.__fSelUVs = validUVIds
332 compFn = OpenMaya.MFnSingleIndexedComponent()
334 compFn.create(OpenMaya.MFn.kMeshMapComponent)
336 statusError(
"compFn.create( MFn::kMeshMapComponent )")
339 compFn.addElements(validUVIds)
341 statusError(
"compFn.addElements( validUVIds )")
345 component = compFn.object()
346 compListFn = OpenMaya.MFnComponentListData()
349 compListFn.add(component)
351 statusError(
"compListFn.add( component )")
353 self.__fComponentList = compListFn.object()
387 class splitUVFty(polyModifier.polyModifierFty):
389 polyModifier.polyModifierFty.__init__(self)
396 self.__fMesh = OpenMaya.MObject()
397 self.__fSelUVs = OpenMaya.MIntArray()
398 self.__fSelUVs.clear()
401 def setMesh(self, mesh):
405 def setUVIds(self, uvIds):
406 self.__fSelUVs = uvIds
411 Performs the actual splitUV operation on the given object and UVs
419 selUVFaceIdMap = OpenMaya.MIntArray()
420 selUVFaceOffsetMap = OpenMaya.MIntArray()
424 selUVLocalVertIdMap = OpenMaya.MIntArray()
433 meshFn = OpenMaya.MFnMesh(self.__fMesh)
434 selUVSet = meshFn.currentUVSetName()
436 indexParam = OpenMaya.MScriptUtil(0)
437 indexPtr = indexParam.asIntPtr()
440 selUVsCount = self.__fSelUVs.length()
441 polyIter = OpenMaya.MItMeshPolygon(self.__fMesh)
442 for i
in range(selUVsCount):
443 selUVFaceOffsetMap.append(offset)
446 while not polyIter.isDone():
447 if polyIter.hasUVs():
448 polyVertCount = polyIter.polygonVertexCount()
450 for j
in range(polyVertCount):
451 polyIter.getUVIndex(j, indexPtr)
452 UVIndex = indexParam.getInt(indexPtr)
454 if UVIndex == self.__fSelUVs[i]:
455 selUVFaceIdMap.append(polyIter.index())
456 selUVLocalVertIdMap.append(j)
466 selUVFaceOffsetMap.append(offset)
472 currentUVCount = meshFn.numUVs(selUVSet)
474 for i
in range(selUVsCount):
477 offset = selUVFaceOffsetMap[i]
481 uvId = self.__fSelUVs[i]
483 uParam = OpenMaya.MScriptUtil(0.0)
484 uPtr = uParam.asFloatPtr()
485 vParam = OpenMaya.MScriptUtil(0.0)
486 vPtr = vParam.asFloatPtr()
487 meshFn.getUV(uvId, uPtr, vPtr, selUVSet)
488 u = uParam.getFloat(uPtr)
489 v = vParam.getFloat(vPtr)
493 faceCount = selUVFaceOffsetMap[i + 1] - selUVFaceOffsetMap[i]
498 for j
in range(faceCount-1):
499 meshFn.setUV(currentUVCount, u, v, selUVSet)
501 localVertId = selUVLocalVertIdMap[offset]
502 faceId = selUVFaceIdMap[offset]
504 meshFn.assignUV(faceId, localVertId, currentUVCount, selUVSet)
514 class splitUVNode(polyModifier.polyModifierNode):
515 uvList = OpenMaya.MObject()
519 polyModifier.polyModifierNode.__init__(self)
520 self.fSplitUVFactory = splitUVFty()
523 def compute(self, plug, data):
526 This method computes the value of the given output plug based
527 on the values of the input attributes.
530 plug - the plug to compute
531 data - object that provides access to the attributes for this node
534 state = OpenMayaMPx.cvar.MPxNode_state
536 stateData = data.outputValue(state)
538 statusError(
"ERROR getting state")
549 if stateData.asShort() == 1:
551 inputData = data.inputValue(splitUVNode.inMesh)
553 statusError(
"ERROR getting inMesh")
556 outputData = data.outputValue(splitUVNode.outMesh)
558 statusError(
"ERROR getting outMesh")
562 outputData.setMObject(inputData.asMesh())
568 if plug == splitUVNode.outMesh:
570 inputData = data.inputValue(splitUVNode.inMesh)
572 statusError(
"ERROR getting inMesh")
575 outputData = data.outputValue(splitUVNode.outMesh)
577 statusError(
"ERROR getting outMesh")
583 inputUVs = data.inputValue(splitUVNode.uvList)
585 statusError(
"ERROR getting uvList")
590 outputData.setMObject(inputData.asMesh())
591 mesh = outputData.asMesh()
599 compList = inputUVs.data()
600 compListFn = OpenMaya.MFnComponentListData(compList)
602 uvIds = OpenMaya.MIntArray()
603 for i
in range(compListFn.length()):
605 if comp.apiType() == OpenMaya.MFn.kMeshMapComponent:
606 uvComp = OpenMaya.MFnSingleIndexedComponent(comp)
607 for j
in range(uvComp.elementCount()):
608 uvId = uvComp.element(j)
613 self.fSplitUVFactory.setMesh(mesh)
614 self.fSplitUVFactory.setUVIds(uvIds)
619 self.fSplitUVFactory.doIt()
621 statusError(
"ERROR in splitUVFty.doIt()")
625 outputData.setClean()
627 return OpenMaya.kUnknownParameter
637 return OpenMayaMPx.asMPxPtr(splitUV())
641 return OpenMayaMPx.asMPxPtr(splitUVNode())
644 def nodeInitializer():
645 attrFn = OpenMaya.MFnTypedAttribute()
647 splitUVNode.uvList = attrFn.create(
"inputComponents",
"ics", OpenMaya.MFnComponentListData.kComponentList)
648 attrFn.setStorable(
True)
650 splitUVNode.inMesh = attrFn.create(
"inMesh",
"im", OpenMaya.MFnMeshData.kMesh)
651 attrFn.setStorable(
True)
655 splitUVNode.outMesh = attrFn.create(
"outMesh",
"om", OpenMaya.MFnMeshData.kMesh)
656 attrFn.setStorable(
False)
657 attrFn.setWritable(
False)
661 splitUVNode.addAttribute(splitUVNode.uvList)
662 splitUVNode.addAttribute(splitUVNode.inMesh)
663 splitUVNode.addAttribute(splitUVNode.outMesh)
669 splitUVNode.attributeAffects(splitUVNode.inMesh, splitUVNode.outMesh)
670 splitUVNode.attributeAffects(splitUVNode.uvList, splitUVNode.outMesh)
673 def initializePlugin(mobject):
674 mplugin = OpenMayaMPx.MFnPlugin(mobject,
"Autodesk",
"1.0",
"Any")
676 mplugin.registerCommand(kPluginCmdName, cmdCreator)
678 sys.stderr.write(
"Failed to register command: %s\n" % kPluginCmdName)
682 mplugin.registerNode(kPluginNodeTypeName, kPluginNodeId, nodeCreator, nodeInitializer)
684 sys.stderr.write(
"Failed to register node: %s" % kPluginNodeTypeName)
688 def uninitializePlugin(mobject):
689 mplugin = OpenMayaMPx.MFnPlugin(mobject)
691 mplugin.deregisterCommand(kPluginCmdName)
693 sys.stderr.write(
"Failed to unregister command: %s\n" % kPluginCmdName)
697 mplugin.deregisterNode(kPluginNodeId)
699 sys.stderr.write(
"Failed to deregister node: %s" % kPluginNodeTypeName)