68 from builtins
import next
69 from builtins
import range
70 import maya.OpenMaya
as OpenMaya
71 import maya.OpenMayaMPx
as OpenMayaMPx
74 from py1PolyModifierCmd
import *
76 def statusError(message):
77 fullMsg =
"Status failed: %s\n" % message
78 sys.stderr.write(fullMsg)
83 kPluginCmdName =
"py1SplitUV"
84 kPluginNodeTypeName =
"py1SplitUVNode"
87 class splitUV(polyModifierCmd):
89 polyModifierCmd.__init__(self)
98 self.__fSplitUVFactory = splitUVFty()
101 def isUndoable(self):
105 def doIt(self, args):
107 implements the scripted splitUV command.
110 args - the argument list that was passes to the command from MEL
133 foundMultiple =
False
135 while not selListIter.isDone():
139 selListIter.getDagPath(dagPath, component)
143 if itemMatches
and (component.apiType() == OpenMaya.MFn.kMeshMapComponent):
149 compListFn.add(component)
154 self.__fComponentList = compListFn.object()
161 compFn.getElements(self.__fSelUVs)
166 dagPath.extendToShape()
167 self._setMeshNode(dagPath)
180 self.displayWarning(
"Found more than one object with selected UVs - Only operating on first found object.")
184 self._setModifierNodeType(kPluginNodeId)
187 if self.__validateUVs():
194 self.displayError(
"splitUV command failed!")
197 self.setResult(
"splitUV command succeeded!")
199 self.displayError(
"splitUV command failed: Selected UVs are not splittable")
201 self.displayError(
"splitUV command failed: Unable to find selected UVs")
206 Implements redo for the scripted splitUV command.
208 This method is called when the user has undone a command of this type
209 and then redoes it. No arguments are passed in as all of the necessary
210 information is cached by the doIt method.
213 self._redoModifyPoly()
214 self.setResult(
"splitUV command succeeded!")
216 self.displayError(
"splitUV command failed!")
222 implements undo for the scripted splitUV command.
224 This method is called to undo a previous command of this type. The
225 system should be returned to the exact state that it was it previous
226 to this command being executed. That includes the selection state.
229 self._undoModifyPoly()
230 self.setResult(
"splitUV undo succeeded!")
232 self.displayError(
"splitUV undo failed!")
236 def _initModifierNode(self, modifierNode):
242 uvListAttr = depNodeFn.attribute(
"inputComponents")
247 uvListPlug.setMObject(self.__fComponentList)
250 def _directModifier(self, mesh):
251 self.__fSplitUVFactory.setMesh(mesh)
252 self.__fSplitUVFactory.setUVIds(self.__fSelUVs)
256 self.__fSplitUVFactory.doIt()
259 def __validateUVs(self):
261 Validate the UVs for the splitUV operation. UVs are valid only if they are shared
262 by more than one face. While the splitUVNode is smart enough to not process the
263 split if a UV is not splittable, a splitUV node is still created by the polyModifierCmd.
264 So call this method to validate the UVs before calling _doModifyPoly().
266 validateUVs() will return true so long as there is at least one valid UV. It will
267 also prune out any invalid UVs from both the component list and UVId array.
271 dagPath = self._getMeshNode()
272 mesh = dagPath.node()
280 indexParam = OpenMaya.MScriptUtil(0)
281 indexPtr = indexParam.asIntPtr()
284 selUVsCount = self.__fSelUVs.length()
285 for i
in range(selUVsCount):
286 while not polyIter.isDone():
287 if polyIter.hasUVs():
288 polyVertCount = polyIter.polygonVertexCount()
290 for j
in range(polyVertCount):
291 polyIter.getUVIndex(j, indexPtr)
292 UVIndex = indexParam.getInt(indexPtr)
294 if UVIndex == self.__fSelUVs[i]:
298 selUVFaceCountArray.append(count)
307 for i
in range(selUVsCount):
308 if selUVFaceCountArray[i] > 1:
310 validUVIndices.append(i)
313 self.__pruneUVs(validUVIndices)
318 def __pruneUVs(self, validUVIndices):
320 This method will remove any invalid UVIds from the component list and UVId array.
321 The benefit of this is to reduce the amount of extra processing that the node would
322 have to perform. It will result in less iterations through the mesh as there are
323 less UVs to search for.
327 for i
in range(validUVIndices.length()):
328 uvIndex = validUVIndices[i]
329 validUVIds.append(self.__fSelUVs[uvIndex])
333 self.__fSelUVs.clear()
334 self.__fSelUVs = validUVIds
340 compFn.create(OpenMaya.MFn.kMeshMapComponent)
342 statusError(
"compFn.create( MFn::kMeshMapComponent )")
345 compFn.addElements(validUVIds)
347 statusError(
"compFn.addElements( validUVIds )")
351 component = compFn.object()
355 compListFn.add(component)
357 statusError(
"compListFn.add( component )")
359 self.__fComponentList = compListFn.object()
393 class splitUVFty(polyModifierFty):
395 polyModifierFty.__init__(self)
404 self.__fSelUVs.clear()
407 def setMesh(self, mesh):
411 def setUVIds(self, uvIds):
412 self.__fSelUVs = uvIds
417 Performs the actual splitUV operation on the given object and UVs
440 selUVSet = meshFn.currentUVSetName()
442 indexParam = OpenMaya.MScriptUtil(0)
443 indexPtr = indexParam.asIntPtr()
446 selUVsCount = self.__fSelUVs.length()
448 for i
in range(selUVsCount):
449 selUVFaceOffsetMap.append(offset)
452 while not polyIter.isDone():
453 if polyIter.hasUVs():
454 polyVertCount = polyIter.polygonVertexCount()
456 for j
in range(polyVertCount):
457 polyIter.getUVIndex(j, indexPtr)
458 UVIndex = indexParam.getInt(indexPtr)
460 if UVIndex == self.__fSelUVs[i]:
461 selUVFaceIdMap.append(polyIter.index())
462 selUVLocalVertIdMap.append(j)
472 selUVFaceOffsetMap.append(offset)
478 currentUVCount = meshFn.numUVs(selUVSet)
480 for i
in range(selUVsCount):
483 offset = selUVFaceOffsetMap[i]
487 uvId = self.__fSelUVs[i]
489 uParam = OpenMaya.MScriptUtil(0.0)
490 uPtr = uParam.asFloatPtr()
491 vParam = OpenMaya.MScriptUtil(0.0)
492 vPtr = vParam.asFloatPtr()
493 meshFn.getUV(uvId, uPtr, vPtr, selUVSet)
494 u = uParam.getFloat(uPtr)
495 v = vParam.getFloat(vPtr)
499 faceCount = selUVFaceOffsetMap[i + 1] - selUVFaceOffsetMap[i]
504 for j
in range(faceCount-1):
505 meshFn.setUV(currentUVCount, u, v, selUVSet)
507 localVertId = selUVLocalVertIdMap[offset]
508 faceId = selUVFaceIdMap[offset]
510 meshFn.assignUV(faceId, localVertId, currentUVCount, selUVSet)
520 class splitUVNode(polyModifierNode):
525 polyModifierNode.__init__(self)
526 self.fSplitUVFactory = splitUVFty()
529 def compute(self, plug, data):
532 This method computes the value of the given output plug based
533 on the values of the input attributes.
536 plug - the plug to compute
537 data - object that provides access to the attributes for this node
540 state = OpenMayaMPx.cvar.MPxNode_state
542 stateData = data.outputValue(state)
544 statusError(
"ERROR getting state")
555 if stateData.asShort() == 1:
557 inputData = data.inputValue(splitUVNode.inMesh)
559 statusError(
"ERROR getting inMesh")
562 outputData = data.outputValue(splitUVNode.outMesh)
564 statusError(
"ERROR getting outMesh")
568 outputData.setMObject(inputData.asMesh())
574 if plug == splitUVNode.outMesh:
576 inputData = data.inputValue(splitUVNode.inMesh)
578 statusError(
"ERROR getting inMesh")
581 outputData = data.outputValue(splitUVNode.outMesh)
583 statusError(
"ERROR getting outMesh")
589 inputUVs = data.inputValue(splitUVNode.uvList)
591 statusError(
"ERROR getting uvList")
596 outputData.setMObject(inputData.asMesh())
597 mesh = outputData.asMesh()
605 compList = inputUVs.data()
609 for i
in range(compListFn.length()):
611 if comp.apiType() == OpenMaya.MFn.kMeshMapComponent:
613 for j
in range(uvComp.elementCount()):
614 uvId = uvComp.element(j)
619 self.fSplitUVFactory.setMesh(mesh)
620 self.fSplitUVFactory.setUVIds(uvIds)
625 self.fSplitUVFactory.doIt()
627 statusError(
"ERROR in splitUVFty.doIt()")
631 outputData.setClean()
633 return OpenMaya.kUnknownParameter
643 return OpenMayaMPx.asMPxPtr(splitUV())
647 return OpenMayaMPx.asMPxPtr(splitUVNode())
650 def nodeInitializer():
653 splitUVNode.uvList = attrFn.create(
"inputComponents",
"ics", OpenMaya.MFnComponentListData.kComponentList)
654 attrFn.setStorable(
True)
656 splitUVNode.inMesh = attrFn.create(
"inMesh",
"im", OpenMaya.MFnMeshData.kMesh)
657 attrFn.setStorable(
True)
661 splitUVNode.outMesh = attrFn.create(
"outMesh",
"om", OpenMaya.MFnMeshData.kMesh)
662 attrFn.setStorable(
False)
663 attrFn.setWritable(
False)
667 splitUVNode.addAttribute(splitUVNode.uvList)
668 splitUVNode.addAttribute(splitUVNode.inMesh)
669 splitUVNode.addAttribute(splitUVNode.outMesh)
675 splitUVNode.attributeAffects(splitUVNode.inMesh, splitUVNode.outMesh)
676 splitUVNode.attributeAffects(splitUVNode.uvList, splitUVNode.outMesh)
679 def initializePlugin(mobject):
680 mplugin = OpenMayaMPx.MFnPlugin(mobject,
"Autodesk",
"1.0",
"Any")
682 mplugin.registerCommand(kPluginCmdName, cmdCreator)
684 sys.stderr.write(
"Failed to register command: %s\n" % kPluginCmdName)
688 mplugin.registerNode(kPluginNodeTypeName, kPluginNodeId, nodeCreator, nodeInitializer)
690 sys.stderr.write(
"Failed to register node: %s" % kPluginNodeTypeName)
694 def uninitializePlugin(mobject):
695 mplugin = OpenMayaMPx.MFnPlugin(mobject)
697 mplugin.deregisterCommand(kPluginCmdName)
699 sys.stderr.write(
"Failed to unregister command: %s\n" % kPluginCmdName)
703 mplugin.deregisterNode(kPluginNodeId)
705 sys.stderr.write(
"Failed to deregister node: %s" % kPluginNodeTypeName)