Skip to content

Instantly share code, notes, and snippets.

@Onefabis
Last active October 22, 2022 11:11
Show Gist options
  • Save Onefabis/cf343e43de3098f08f9c19862f81f917 to your computer and use it in GitHub Desktop.
Save Onefabis/cf343e43de3098f08f9c19862f81f917 to your computer and use it in GitHub Desktop.
create Custom Shape polygon
import sys
import maya.api.OpenMaya as om2
import maya.cmds as mc
def maya_useNewAPI():
pass
##########################################################
# csPoly Node.
##########################################################
class csPoly( om2.MPxNode ):
kPluginNodeName = 'csPoly'
kPluginNodeClassify = 'utility/general'
kPluginNodeId = om2.MTypeId( 0x86027 )
@staticmethod
def nodeCreator():
""" Creates an instance of our node class and delivers it to Maya as a pointer. """
return csPoly()
@staticmethod
def nodeInitializer():
tAttr = om2.MFnTypedAttribute()
nAttr = om2.MFnGenericAttribute()
# Input connections
csPoly.inMesh = tAttr.create('inMesh', 'inm', om2.MFnMeshData.kMesh)
tAttr.readable = False
tAttr.keyable = False
csPoly.addAttribute(csPoly.inMesh)
csPoly.inPoints = tAttr.create( 'inPoints', 'inpt', om2.MFnData.kPointArray )
csPoly.addAttribute(csPoly.inPoints)
csPoly.faceIDs = tAttr.create("faceIDs", "fid", om2.MFnData.kString)
csPoly.addAttribute(csPoly.faceIDs)
# Output connections
csPoly.outMesh = tAttr.create('outMesh', 'onm', om2.MFnMeshData.kMesh)
tAttr.writable = False
tAttr.storable = False
tAttr.keyable = False
csPoly.addAttribute(csPoly.outMesh)
csPoly.attributeAffects( csPoly.inMesh, csPoly.outMesh )
def __init__( self ):
om2.MPxNode.__init__( self )
self.checkflag = 1
self.collectFlag = 1
def setDependentsDirty(self, dirtyPlug, plugArray):
self.checkflag = 1
# Run every time before evaluation manager process this node in DG
def preEvaluation( self, context, evalNode ):
if evalNode.dirtyPlugExists(csPoly.inPoints):
self.checkflag = 1
def postEvaluation( self, context, evalNode, kEvaluatedIndirectly ):
if evalNode.dirtyPlugExists(csPoly.inPoints):
self.checkflag = 1
def connectionMade(self, plug, otherPlug, asSrc):
self.checkflag = 1
def postConstructor(self):
self.checkflag = 1
def collectData( self ):
inFaceIDs = om2.MPlug( self.thisMObject(), self.faceIDs ).asString()
listStrIDs = inFaceIDs.split(',')
listIDs = [ int(x) for x in listStrIDs ]
mFnMeshSrc = om2.MFnMesh( om2.MPlug( self.thisMObject(), self.inMesh ).asMDataHandle().asMesh() )
outVertConects = [ x for p in listIDs for x in list(mFnMeshSrc.getPolygonVertices(p)) ]
self.faceVertsId = list(set(outVertConects))
listSequental = range(len(self.faceVertsId))
outVertConectsOrdered = [ x + ( listSequental[self.faceVertsId.index(x)] - self.faceVertsId[self.faceVertsId.index(x)] ) for x in outVertConects]
outVertCounts = [ mFnMeshSrc.getPolygonVertices(p).__len__() for p in listIDs]
vValues = [ 0.0 ] * len(listIDs)
self.resultMesh = om2.MFnMeshData().create()
outFnMesh = om2.MFnMesh()
inMeshPointArray = mFnMeshSrc.getPoints(om2.MSpace.kObject )
outPoints = [ inMeshPointArray[k] for k in self.faceVertsId ]
outFnMesh.create( outPoints, outVertCounts, outVertConectsOrdered, vValues, vValues, self.resultMesh)
self.resultMeshData = om2.MFnMesh().setObject( self.resultMesh )
def compute( self, plug, data ):
if self.checkflag == 1:
if self.collectFlag:
self.collectData()
self.collectFlag = 0
inMeshPoints = om2.MFnPointArrayData(data.inputValue(self.inPoints).data()).array()
outPoints = ( inMeshPoints[k] for k in self.faceVertsId )
self.resultMeshData.setPoints( outPoints, om2.MSpace.kObject )
data.outputValue(self.outMesh).setMObject(self.resultMesh)
##########################################################
# csPoints Node.
##########################################################
class csPoints(om2.MPxNode):
a_Points = om2.MObject()
a_Amount = om2.MObject()
csPointsNodeId = om2.MTypeId(0x87053)
@staticmethod
def nodeCreator():
return csPoints()
@staticmethod
def nodeInitializer():
tAttr = om2.MFnTypedAttribute()
# Create input connection attribute
csPoints.inMesh = tAttr.create('inMesh', 'im', om2.MFnMeshData.kMesh)
csPoints.addAttribute(csPoints.inMesh)
# -----------------------------------------------------------------
# Create Output attribute of type MPointArray
csPoints.a_Points = tAttr.create("outPoints", "opnt", om2.MFnData.kPointArray)
csPoints.addAttribute(csPoints.a_Points)
# -----------------------------------------------------------------
# Create affect relationship a_Amount(input)->a_Points(output)
csPoints.attributeAffects(csPoints.inMesh, csPoints.a_Points)
def __init__(self):
om2.MPxNode.__init__(self)
self.computeFlag = 1
self.computePoints = 1
self.ptArray = om2.MFnPointArrayData()
def setDependentsDirty(self, dirtyPlug, plugArray):
if dirtyPlug == csPoints.a_Points:
self.computeFlag = 1
# Run every time before evaluation manager process this node in DG
def preEvaluation( self, context, evalNode ):
if evalNode.dirtyPlugExists(csPoints.a_Points):
self.computeFlag = 1
def postEvaluation( self, context, evalNode, kEvaluatedIndirectly ):
if evalNode.dirtyPlugExists(csPoints.a_Points):
self.computeFlag = 1
##################################################################
# ----------------------------------COMPUTE----------------------#
def compute( self, plug, data ):
if self.computeFlag:
h_aAmount = data.inputValue(csPoints.inMesh).asMesh()
o_aPoints = self.ptArray.create(om2.MFnMesh(h_aAmount).getPoints(om2.MSpace.kObject))
data.outputValue(csPoints.a_Points).setMObject(o_aPoints)
self.computeFlag = 0
##########################################################
# createcsPoly vars.
##########################################################
controller_flag_short = '-c'
controller_flag_long = '-controller'
name = 'createCsPoly'
##########################################################
# createcsPoly Command.
##########################################################
class createcsPolyPoly(om2.MPxCommand):
# The command used to create csPoly node
def __init__(self):
om2.MPxCommand.__init__(self)
self.nameCsPoints = 'csPoints'
self.namecsPoly = 'csPoly'
self.csPoints = om2.MObject()
self.csPoly = om2.MObject()
self.dgmod = om2.MDGModifier()
self.dagmod = om2.MDagModifier()
self.connectedNodes = None
self.optimized = 1
def doIt(self, args):
sel = om2.MGlobal.getActiveSelectionList()
if sel.length() == 0:
return
argData = om2.MArgParser(self.syntax(), args)
dp = om2.MDagPath()
comp = om2.MObject()
dp, comp = sel.getComponent( 0 )
argData.getObjectStrings()
# Get the controller
if argData.isFlagSet(controller_flag_short):
self.controller = argData.flagArgumentString(controller_flag_short, 0)
selLength = sel.length()
if selLength == 2:
try:
mItVtx = om2.MItMeshPolygon( dp, comp )
parentController = sel.getDagPath( 1 )
parentCntMobject = sel.getDependNode(1)
mesh = dp.extendToShape(0)
except:
dp, comp = sel.getComponent( 1 )
mItVtx = om2.MItMeshPolygon( dp, comp )
parentController = sel.getDagPath( 0 )
parentCntMobject = sel.getDependNode(0)
mesh = dp.extendToShape(0)
else:
mItVtx = om2.MItMeshPolygon( dp, comp )
mesh = dp.extendToShape(0)
selList = om2.MSelectionList()
selList.add(self.controller)
parentController = selList.getDagPath(0)
parentCntMobject = selList.getDependNode(0)
idx = []
while not mItVtx.isDone():
point = mItVtx.index()
idx.append(int(point))
mItVtx.next(0)
componentList = list( sorted( set( idx ) ) )
mats = mc.ls( typ='lambert')
if 'polyCubeShader' not in mats:
lambert = mc.shadingNode( 'lambert', n='polyCubeShader', asShader=1 )
shadingGroup = mc.sets( renderable=1, noSurfaceShader=1, empty=1, name=lambert + "SG" )
mc.connectAttr( lambert + '.outColor', shadingGroup + '.surfaceShader', f=1 )
else:
matPolys = [ m for m in mats if 'polyCubeShader' in m ]
lambert = matPolys[0]
mc.setAttr( lambert + '.transparency', 1, 1, 1, type='double3' )
if len( componentList ) > 0 and len( str( parentController ) ) > 0:
outMeshPlig = om2.MFnDependencyNode( mesh.node() ).findPlug( 'outMesh', 1 )
self.connectedNodes = [ x for x in outMeshPlig.connectedTo( 1, 1 ) if self.nameCsPoints in x.name() ]
if not self.connectedNodes:
# Create csPoints node
self.csPoints = self.dgmod.createNode( om2.MTypeId( 0x87053 ) )
fn_Points_node = om2.MFnDependencyNode( self.csPoints )
else:
csPointsNodes = [ x.node() for x in outMeshPlig.connectedTo( 1, 1 ) if 'csPoints' in x.name() ]
fn_Points_node = om2.MFnDependencyNode( csPointsNodes[0] )
fnTrGeo = om2.MFnDependencyNode()
fnTrGeo_node = fnTrGeo.create("transformGeometry")
# Create csPoly node
self.csPoly = self.dgmod.createNode( om2.MTypeId(0x86027 ) )
fn_Poly_node = om2.MFnDependencyNode( self.csPoly )
self.dgmod.connect(fn_Points_node.findPlug( 'outPoints', 0 ), fn_Poly_node.findPlug( 'inPoints', 0 ) )
self.dgmod.connect( outMeshPlig, fn_Points_node.findPlug( 'inMesh', 0 ) )
fn_Poly_node.findPlug( 'faceIDs', 0 ).setString( (", ".join(str(i) for i in componentList) ) )
self.dgmod.connect( outMeshPlig, fn_Poly_node.findPlug( 'inMesh', 0 ) )
objPolyShp = om2.MFnDagNode().create("mesh", None, parentCntMobject)
#name = om2.MFnDependencyNode(objPolyShp).setName('polyCube')
#print name
selSG = om2.MSelectionList()
selSG.add( lambert + 'SG' )
shader = selSG.getDependNode(0)
plugLen = om2.MFnDependencyNode(shader).findPlug( 'dagSetMembers', 0 ).getExistingArrayAttributeIndices()
#print plugLen
#if not plugLen:
# plugLen = 0
self.dgmod.connect( om2.MFnDependencyNode(objPolyShp).findPlug( 'instObjGroups', 0 ).elementByLogicalIndex(0), om2.MFnDependencyNode(shader).findPlug( 'dagSetMembers', 0 ).elementByLogicalIndex(len(plugLen)) )
self.dgmod.connect( fn_Poly_node.findPlug( 'outMesh', 0 ), om2.MFnDependencyNode(fnTrGeo_node).findPlug( 'inputGeometry', 0 ) )
self.dgmod.connect( om2.MFnDependencyNode(parentCntMobject).findPlug( 'worldInverseMatrix', 0 ).elementByLogicalIndex(0), om2.MFnDependencyNode(fnTrGeo_node).findPlug( 'transform', 0 ) )
self.dgmod.connect( om2.MFnDependencyNode(fnTrGeo_node).findPlug( 'outputGeometry', 0 ), om2.MFnDependencyNode(objPolyShp).findPlug( 'inMesh', 0 ) )
return self.redoIt()
def redoIt(self):
self.clearResult()
self.dgmod.doIt()
try:
fn_csPoints_node = om2.MFnDependencyNode(self.csPoints)
if self.nameCsPoints and self.nameCsPoints != 'csPoints#':
name = fn_csPoints_node.setName(self.nameCsPoints)
else:
name = fn_csPoints_node.name()
self.setResult(name)
except: pass
fn_csPoly_node = om2.MFnDependencyNode(self.csPoly)
if self.namecsPoly and self.namecsPoly != 'csPoly#':
name2 = fn_csPoly_node.setName(self.namecsPoly)
else:
name2 = fn_csPoly_node.name()
self.setResult(name2)
def undoIt(self):
if not self.connectedNodes:
self.dgmod.undoIt()
#self.dagmod.doIt()
def isUndoable(self):
return True
def hasSyntax(self):
return True
##########################################################
# Plug-in initialization.
##########################################################
def creator():
return createcsPolyPoly()
def syntaxCreator():
syntax = om2.MSyntax()
syntax.setObjectType( om2.MSyntax.kStringObjects )
syntax.addFlag( controller_flag_short, controller_flag_long, om2.MSyntax.kString )
return syntax
def initializePlugin( mobject ):
""" Initialize the plug-in """
mplugin = om2.MFnPlugin( mobject, "Alex Smirnov", "1.0", "Any" )
""" Initialize the createcsPoly command """
try:
mplugin.registerCommand( name, creator, syntaxCreator )
except:
sys.stderr.write( "Failed to register command: " + name )
raise
""" Initialize the csPoints node """
try:
mplugin.registerNode( "csPoints", csPoints.csPointsNodeId, csPoints.nodeCreator, csPoints.nodeInitializer, om2.MPxNode.kDependNode )
#om2.MGlobal.executeCommand( csPoints.AEtemplateString('csPoints') )
except:
sys.stderr.write( 'Failed to register node csPoints' )
raise
""" Initialize the csPoly node """
try:
mplugin.registerNode( csPoly.kPluginNodeName, csPoly.kPluginNodeId, csPoly.nodeCreator, csPoly.nodeInitializer )
except:
sys.stderr.write( "Failed to register node: " + csPoly.kPluginNodeName )
raise
def uninitializePlugin( mobject ):
""" Uninitialize the plug-in """
mplugin = om2.MFnPlugin( mobject )
""" Uninitialize the createcsPoly command """
try:
mplugin.deregisterCommand( name )
except:
sys.stderr.write( 'Failed to deregister command: ' + name )
""" Uninitialize the csPoints node """
try:
mplugin.deregisterNode( csPoints.csPointsNodeId )
except:
sys.stderr.write( 'Failed to register node csPoints' )
raise
""" Uninitialize the csPoly node """
try:
mplugin.deregisterNode( csPoly.kPluginNodeId )
except:
sys.stderr.write( 'Failed to deregister node: ' + csPoly.kPluginNodeName )
raise
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment