Last active
October 22, 2022 11:11
-
-
Save Onefabis/cf343e43de3098f08f9c19862f81f917 to your computer and use it in GitHub Desktop.
create Custom Shape polygon
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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