Updated
445
Scripts/Modeling/Edit/CreasePlus/CreasePlusBase.py
Normal file
@ -0,0 +1,445 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
_____ _____ ______ _____ ______
|
||||
/ ____| __ \| ____| /\ / ____| ____|_
|
||||
| | | |__) | |__ / \ | (___ | |__ _| |_
|
||||
| | | _ /| __| / /\ \ \___ \| __|_ _|
|
||||
| |____| | \ \| |____ / ____ \ ____) | |____|_|
|
||||
\_____|_| \_\______/_/ \_\_____/|______|
|
||||
|
||||
"""
|
||||
|
||||
import maya.cmds as cmds
|
||||
import maya.api.OpenMaya as om
|
||||
|
||||
# uses python maya 2
|
||||
|
||||
maya_useNewAPI = True
|
||||
|
||||
class MayaVerObj():
|
||||
def __init__(self):
|
||||
self.num = None
|
||||
self.extnum = 0
|
||||
|
||||
def cPwhatmayaversion():
|
||||
verstring = cmds.about(v=True)
|
||||
|
||||
splited = verstring.split()
|
||||
num = None
|
||||
extnum = 0
|
||||
|
||||
for r in splited:
|
||||
if "20" in r:
|
||||
num = int(r)
|
||||
break
|
||||
|
||||
i = -1
|
||||
for r in splited:
|
||||
i += 1
|
||||
if r.lower() == "extension" or r.lower() == "ext":
|
||||
j = i+1
|
||||
for j in range(len(splited)):
|
||||
if splited[j].isdigit():
|
||||
extnum = int(splited[j])
|
||||
break
|
||||
break
|
||||
|
||||
if not num:
|
||||
raise Exception("can't get maya version")
|
||||
|
||||
mayavobj = MayaVerObj()
|
||||
mayavobj.num = num
|
||||
mayavobj.extnum = extnum
|
||||
return mayavobj
|
||||
|
||||
global_creasePlus_mayaver = cPwhatmayaversion()
|
||||
|
||||
def getmayaver():
|
||||
global global_creasePlus_mayaver
|
||||
return global_creasePlus_mayaver
|
||||
|
||||
class CpMsg:
|
||||
|
||||
kNoSel = 'nothing is selected'
|
||||
kNoSelCurve = 'no curve(s) selected'
|
||||
kNoSelMesh = 'no mesh(es) selected'
|
||||
kNoSelEdge = 'no edge(s) selected'
|
||||
kNoSelVert = 'no vertice(s) selected'
|
||||
kNoSelFace = 'no face(s) selected'
|
||||
|
||||
kSelOneMesh = 'select one mesh'
|
||||
kSelMesh = 'mesh(es) must be selected'
|
||||
kSelEdge = 'edge(s) must be selected'
|
||||
kSelFace = 'face(s) must be selected'
|
||||
kSelVert = 'vertice(s) must be selected'
|
||||
|
||||
kSelEdgeOrOneMesh = 'select edge(s) or a mesh'
|
||||
|
||||
kSelCurveCv = 'curve cv(s) must be selected'
|
||||
kWorksForOne = 'works just for one entity'
|
||||
|
||||
kNoHardEdges = 'no hard edge(s) were found'
|
||||
|
||||
kSelLeastTwoMesh = 'select at least two meshes'
|
||||
kSelLeastTwoCurve = 'select at least two curves'
|
||||
|
||||
kInvalidFuncArgs = 'function called with invalid arguments'
|
||||
|
||||
kRequModelView = 'you are required to be in a modeling view/pan'
|
||||
kWrongSel = 'wrong selection'
|
||||
|
||||
kcPnodePluginNotLoaded = \
|
||||
'creasePlus nodes plugin must be loaded to use this command'
|
||||
|
||||
# obj assumed to be a parent
|
||||
def cPgotoChild(obj, mfntyp):
|
||||
dagn = om.MFnDagNode(obj)
|
||||
for i in range(dagn.childCount()):
|
||||
cur = dagn.child(i)
|
||||
if cur.hasFn(mfntyp):
|
||||
return cur
|
||||
return om.MObject.kNullObj
|
||||
|
||||
def cPshapeDagPath(obj):
|
||||
dagn = om.MFnDagNode(obj)
|
||||
return dagn.getPath()
|
||||
|
||||
def cPhardEdgesStrings(shape):
|
||||
|
||||
sel = om.MSelectionList()
|
||||
sel.add(shape)
|
||||
|
||||
dagp = sel.getDagPath(0)
|
||||
|
||||
edgeIter = om.MItMeshEdge(dagp)
|
||||
selStrings = []
|
||||
shapeString = dagp.partialPathName()
|
||||
while not edgeIter.isDone():
|
||||
if edgeIter.isSmooth == False:
|
||||
selStrings.append(shapeString + '.e['
|
||||
+ str(edgeIter.index()) + ']')
|
||||
|
||||
edgeIter.next()
|
||||
|
||||
return selStrings
|
||||
|
||||
def cPgetShapeStringsFromSel(mfntyp):
|
||||
|
||||
sel = om.MGlobal.getActiveSelectionList()
|
||||
selIt = om.MItSelectionList(sel)
|
||||
|
||||
selStrings = []
|
||||
dagFn = om.MFnDagNode()
|
||||
while not selIt.isDone():
|
||||
|
||||
if selIt.itemType() != selIt.kDagSelectionItem:
|
||||
selIt.next()
|
||||
continue
|
||||
|
||||
obj = selIt.getDependNode()
|
||||
|
||||
if not obj.hasFn(mfntyp):
|
||||
|
||||
obj = cPgotoChild(obj, mfntyp)
|
||||
|
||||
if not obj.hasFn(mfntyp):
|
||||
selIt.next()
|
||||
continue
|
||||
|
||||
dagFn.setObject(obj)
|
||||
selStrings.append(dagFn.partialPathName())
|
||||
selIt.next()
|
||||
|
||||
return selStrings
|
||||
|
||||
def cPcameraDominantPlane():
|
||||
|
||||
activePan = cmds.getPanel(wf=True)
|
||||
|
||||
if cmds.getPanel(to=activePan) != 'modelPanel':
|
||||
cmds.error(CpMsg.kRequModelView)
|
||||
|
||||
camPos = cmds.camera(cmds.modelEditor(activePan, q=True, cam=True),
|
||||
q=True, p=True)
|
||||
camTarget = cmds.camera(cmds.modelEditor(activePan, q=True, cam=True),
|
||||
q=True, wci=True)
|
||||
|
||||
camDir = om.MVector(abs(camTarget[0] - camPos[0]), abs(camTarget[1]
|
||||
- camPos[1]), abs(camTarget[2] - camPos[2]))
|
||||
|
||||
maxv = 0
|
||||
ddir = 'x'
|
||||
if maxv < camDir.x:
|
||||
maxv = camDir.x
|
||||
ddir = 'x'
|
||||
if maxv < camDir.y:
|
||||
maxv = camDir.y
|
||||
ddir = 'y'
|
||||
if maxv < camDir.z:
|
||||
maxv = camDir.z
|
||||
ddir = 'z'
|
||||
|
||||
return ddir
|
||||
|
||||
# cmds.ls(sl=True)
|
||||
# get shape + v, e, f comps in a tuple
|
||||
|
||||
def cPgetShapeAndCoStrings(mselit):
|
||||
|
||||
shape = None
|
||||
v = None
|
||||
e = None
|
||||
f = None
|
||||
|
||||
if mselit.itemType() != mselit.kDagSelectionItem:
|
||||
return (shape, v, e, f)
|
||||
|
||||
hasComp = mselit.hasComponents()
|
||||
|
||||
if hasComp == True:
|
||||
|
||||
comp = mselit.getComponent()
|
||||
|
||||
if comp[0].node().hasFn(om.MFn.kMesh):
|
||||
shape = comp[0]
|
||||
|
||||
if comp[1].hasFn(om.MFn.kMeshPolygonComponent):
|
||||
f = comp[1]
|
||||
elif comp[1].hasFn(om.MFn.kMeshEdgeComponent):
|
||||
|
||||
e = comp[1]
|
||||
elif comp[1].hasFn(om.MFn.kMeshVertComponent):
|
||||
|
||||
v = comp[1]
|
||||
else:
|
||||
|
||||
obj = mselit.getDependNode()
|
||||
|
||||
if not obj.hasFn(om.MFn.kMesh):
|
||||
obj = cPgotoChild(obj, om.MFn.kMesh)
|
||||
|
||||
if obj.hasFn(om.MFn.kMesh):
|
||||
shape = cPshapeDagPath(obj)
|
||||
|
||||
return (shape, v, e, f)
|
||||
|
||||
def cPfaceToHardEdgeStrings(dagp, faceComps):
|
||||
|
||||
edgeIds = set()
|
||||
|
||||
faceIt = om.MItMeshPolygon(dagp, faceComps)
|
||||
meshFn = om.MFnMesh(dagp.node())
|
||||
|
||||
while not faceIt.isDone():
|
||||
|
||||
fEdges = faceIt.getEdges()
|
||||
|
||||
for idx in fEdges:
|
||||
if not meshFn.isEdgeSmooth(idx):
|
||||
edgeIds.add(idx)
|
||||
|
||||
faceIt.next(None) # maya api bug
|
||||
|
||||
shapeString = dagp.partialPathName()
|
||||
return [shapeString + '.e[' + str(idx) + ']' for idx in edgeIds]
|
||||
|
||||
def cPedgeToStrings(dagp, edgeComps):
|
||||
|
||||
edgeStrings = []
|
||||
edgeIt = om.MItMeshEdge(dagp, edgeComps)
|
||||
shapeString = dagp.partialPathName()
|
||||
while not edgeIt.isDone():
|
||||
|
||||
edgeStrings.append(shapeString + '.e[' + str(edgeIt.index())
|
||||
+ ']')
|
||||
edgeIt.next()
|
||||
|
||||
return edgeStrings
|
||||
|
||||
################################################################ CONTEXTS #################################################################
|
||||
|
||||
# draw curve ctx
|
||||
try:
|
||||
global_cPcurveCtxStr
|
||||
except:
|
||||
global_cPcurveCtxStr = cmds.curveCVCtx('cPcurveCtx', degree=1)
|
||||
|
||||
#
|
||||
|
||||
# booleanop context
|
||||
try:
|
||||
global_cPboolOpCtxStr
|
||||
except:
|
||||
global_cPboolOpCtxStr = cmds.dragAttrContext('cPboolOpCtx')
|
||||
|
||||
global_cPboolOpAttrCnt = 3
|
||||
global_cPboolOpAttrIter = 0
|
||||
|
||||
def cPboolOpIterSetVal(val):
|
||||
global global_cPboolOpAttrIter
|
||||
global_cPboolOpAttrIter = val
|
||||
return global_cPboolOpAttrIter % global_cPboolOpAttrCnt
|
||||
|
||||
def cPboolOpIterVal():
|
||||
global global_cPboolOpAttrIter
|
||||
return global_cPboolOpAttrIter % global_cPboolOpAttrCnt
|
||||
|
||||
def cPboolOpIterIncVal():
|
||||
global global_cPboolOpAttrIter
|
||||
global_cPboolOpAttrIter += 1
|
||||
return global_cPboolOpAttrIter % global_cPboolOpAttrCnt
|
||||
|
||||
#
|
||||
|
||||
# mirror context
|
||||
try:
|
||||
global_cPmirrorCtxStr
|
||||
except:
|
||||
global_cPmirrorCtxStr = cmds.dragAttrContext('cPmirrorCtx')
|
||||
|
||||
global_cPmirrorAttrCnt = None
|
||||
if getmayaver().num > 2016:
|
||||
global_cPmirrorAttrCnt = 1
|
||||
else:
|
||||
global_cPmirrorAttrCnt = 3
|
||||
|
||||
global_cPmirrorAttrIter = 0
|
||||
|
||||
def cPmirrorIterSetVal(val):
|
||||
global global_cPmirrorAttrIter
|
||||
global_cPmirrorAttrIter = val
|
||||
return global_cPmirrorAttrIter % global_cPmirrorAttrCnt
|
||||
|
||||
def cPmirrorIterVal():
|
||||
global global_cPmirrorAttrIter
|
||||
return global_cPmirrorAttrIter % global_cPmirrorAttrCnt
|
||||
|
||||
def cPmirrorIterIncVal():
|
||||
global global_cPmirrorAttrIter
|
||||
global_cPmirrorAttrIter += 1
|
||||
return global_cPmirrorAttrIter % global_cPmirrorAttrCnt
|
||||
|
||||
#
|
||||
|
||||
# hbevel context
|
||||
try:
|
||||
global_hBevelCtxStr
|
||||
except:
|
||||
global_hBevelCtxStr = cmds.dragAttrContext('hBevelCtx')
|
||||
|
||||
global_hBevelAttrCnt = 2
|
||||
global_hBevelAttrIter = 0
|
||||
|
||||
def cPhBevelIterSetVal(val):
|
||||
global global_hBevelAttrIter
|
||||
global_hBevelAttrIter = val
|
||||
return global_hBevelAttrIter % global_hBevelAttrCnt
|
||||
|
||||
def cPhBevelIterVal():
|
||||
global global_hBevelAttrIter
|
||||
return global_hBevelAttrIter % global_hBevelAttrCnt
|
||||
|
||||
def cPhBevelIterIncVal():
|
||||
global global_hBevelAttrIter
|
||||
global_hBevelAttrIter += 1
|
||||
return global_hBevelAttrIter % global_hBevelAttrCnt
|
||||
|
||||
#
|
||||
|
||||
# curvebevel context
|
||||
try:
|
||||
global_cPcurveBevelCtxStr
|
||||
except:
|
||||
global_cPcurveBevelCtxStr = cmds.dragAttrContext('cPcurveBvlCtx')
|
||||
|
||||
global_cPcurveBevelAttrCnt = 2
|
||||
global_cPcurveBevelAttrIter = 0
|
||||
|
||||
def cPcurveBevelIterSetVal(val):
|
||||
global global_cPcurveBevelAttrIter
|
||||
global_cPcurveBevelAttrIter = val
|
||||
return global_cPcurveBevelAttrIter % global_cPcurveBevelAttrCnt
|
||||
|
||||
def cPcurveBevelIterVal():
|
||||
global global_cPcurveBevelAttrIter
|
||||
return global_cPcurveBevelAttrIter % global_cPcurveBevelAttrCnt
|
||||
|
||||
def cPcurveBevelIterIncVal():
|
||||
global global_cPcurveBevelAttrIter
|
||||
global_cPcurveBevelAttrIter += 1
|
||||
return global_cPcurveBevelAttrIter % global_cPcurveBevelAttrCnt
|
||||
|
||||
#
|
||||
|
||||
# crease tool context
|
||||
try:
|
||||
global_cPcreaseCtxStr
|
||||
except:
|
||||
global_cPcreaseCtxStr = cmds.polyCreaseCtx('cPcreaseCtx', es=True, r=True)
|
||||
|
||||
#
|
||||
|
||||
# physical crease context
|
||||
try:
|
||||
global_pCreaseCtxStr
|
||||
except:
|
||||
global_pCreaseCtxStr = cmds.dragAttrContext('pCreaseCtx')
|
||||
|
||||
global_pCreaseAttrCnt = 2
|
||||
global_pCreaseAttrIter = 0
|
||||
|
||||
def cPpCreaseIterSetVal(val):
|
||||
global global_pCreaseAttrIter
|
||||
global_pCreaseAttrIter = val
|
||||
return global_pCreaseAttrIter % global_pCreaseAttrCnt
|
||||
|
||||
def cPpCreaseIterVal():
|
||||
global global_pCreaseAttrIter
|
||||
return global_pCreaseAttrIter % global_pCreaseAttrCnt
|
||||
|
||||
def cPpCreaseIterIncVal():
|
||||
global global_pCreaseAttrIter
|
||||
global_pCreaseAttrIter += 1
|
||||
return global_pCreaseAttrIter % global_pCreaseAttrCnt
|
||||
|
||||
#
|
||||
def cPcontextUndo():
|
||||
if cmds.currentCtx() == global_cPboolOpCtxStr:
|
||||
# cmds.setToolTo('moveSuperContext')
|
||||
cmds.dragAttrContext(global_cPboolOpCtxStr, e=True, reset=True)
|
||||
cmds.setToolTo(global_cPboolOpCtxStr)
|
||||
elif cmds.currentCtx() == global_hBevelCtxStr:
|
||||
|
||||
# cmds.setToolTo('moveSuperContext')
|
||||
cmds.dragAttrContext(global_hBevelCtxStr, e=True, reset=True)
|
||||
cmds.setToolTo(global_hBevelCtxStr)
|
||||
elif cmds.currentCtx() == global_cPmirrorCtxStr:
|
||||
|
||||
# cmds.setToolTo('moveSuperContext')
|
||||
cmds.dragAttrContext(global_cPmirrorCtxStr, e=True, reset=True)
|
||||
cmds.setToolTo(global_cPmirrorCtxStr)
|
||||
elif cmds.currentCtx() == global_cPcurveBevelCtxStr:
|
||||
|
||||
# cmds.setToolTo('moveSuperContext')
|
||||
cmds.dragAttrContext(global_cPcurveBevelCtxStr, e=True, reset=True)
|
||||
cmds.setToolTo(global_cPcurveBevelCtxStr)
|
||||
elif cmds.currentCtx() == global_pCreaseCtxStr:
|
||||
|
||||
# cmds.setToolTo('moveSuperContext')
|
||||
cmds.dragAttrContext(global_pCreaseCtxStr, e=True, reset=True)
|
||||
cmds.setToolTo(global_pCreaseCtxStr)
|
||||
|
||||
try:
|
||||
global_creasePlusCtxUndoJob
|
||||
except:
|
||||
global_creasePlusCtxUndoJob = cmds.scriptJob(event=['Undo', cPcontextUndo])
|
||||
|
||||
############################################################################################################
|
||||
|
||||
def main():
|
||||
return None
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
2049
Scripts/Modeling/Edit/CreasePlus/CreasePlusCore.py
Normal file
BIN
Scripts/Modeling/Edit/CreasePlus/CreasePlusEULA.pdf
Normal file
5
Scripts/Modeling/Edit/CreasePlus/CreasePlusExcept.py
Normal file
@ -0,0 +1,5 @@
|
||||
import maya.api.OpenMaya as om
|
||||
|
||||
def cPexcept(excepstr=""):
|
||||
om.MGlobal.displayError(excepstr)
|
||||
return Exception(excepstr)
|
1061
Scripts/Modeling/Edit/CreasePlus/CreasePlusMain.py
Normal file
497
Scripts/Modeling/Edit/CreasePlus/CreasePlusNodes.py
Normal file
@ -0,0 +1,497 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
_____ _____ ______ _____ ______
|
||||
/ ____| __ \| ____| /\ / ____| ____|_
|
||||
| | | |__) | |__ / \ | (___ | |__ _| |_
|
||||
| | | _ /| __| / /\ \ \___ \| __|_ _|
|
||||
| |____| | \ \| |____ / ____ \ ____) | |____|_|
|
||||
\_____|_| \_\______/_/ \_\_____/|______|
|
||||
|
||||
"""
|
||||
|
||||
# import maya.cmds as mc
|
||||
import maya.api.OpenMaya as om
|
||||
# import copy
|
||||
|
||||
# uses python maya 2
|
||||
|
||||
maya_useNewAPI = True
|
||||
|
||||
#################
|
||||
|
||||
def cPhardEdgeIds(mesh):
|
||||
edgeIter = om.MItMeshEdge(mesh)
|
||||
ids = []
|
||||
while not edgeIter.isDone():
|
||||
if not edgeIter.isSmooth:
|
||||
ids.append(edgeIter.index())
|
||||
edgeIter.next()
|
||||
return ids
|
||||
|
||||
def cPcompToIds(compdata, cptyp):
|
||||
compDataFn = om.MFnComponentListData(compdata)
|
||||
# compDataFn
|
||||
ids = []
|
||||
for i in range(compDataFn.length()):
|
||||
curcomp = compDataFn.get(i)
|
||||
if curcomp.hasFn(cptyp):
|
||||
sic = om.MFnSingleIndexedComponent(curcomp)
|
||||
for j in range(sic.elementCount):
|
||||
curIdx = sic.element(j)
|
||||
ids.append(curIdx)
|
||||
return ids
|
||||
|
||||
def cPidsToComp(ids, cptyp):
|
||||
sic = om.MFnSingleIndexedComponent()
|
||||
sic.create(cptyp) # om.MFn.kMeshEdgeComponent
|
||||
|
||||
sic.addElements(ids)
|
||||
|
||||
compData = om.MFnComponentListData()
|
||||
compObj = compData.create()
|
||||
compData.add(sic.object())
|
||||
return (sic.object(), compObj)
|
||||
|
||||
def cPtransformMeshPoints(mesh, mat):
|
||||
meshFn = om.MFnMesh(mesh)
|
||||
pts = meshFn.getPoints()
|
||||
for pt in pts:
|
||||
pt *= mat
|
||||
|
||||
meshFn.setPoints(pts)
|
||||
|
||||
"""
|
||||
input: mesh
|
||||
output: componentlist
|
||||
"""
|
||||
|
||||
MayaNodeT = om.MPxNode
|
||||
|
||||
class CpCurveBevel(MayaNodeT):
|
||||
|
||||
kNodeName = "creasePlusCurveBevel"
|
||||
kNodeId = om.MTypeId(0x1154)
|
||||
|
||||
aCvs = None
|
||||
aOffset = None
|
||||
aSeg = None
|
||||
aOffsetFrac = None
|
||||
aInputCurve = None
|
||||
aOutput = None
|
||||
|
||||
def __init__(self):
|
||||
super(CpCurveBevel, self).__init__()
|
||||
|
||||
@classmethod
|
||||
def creator(cls):
|
||||
return cls()
|
||||
|
||||
@classmethod
|
||||
def initialize(cls):
|
||||
|
||||
nAttr = om.MFnNumericAttribute()
|
||||
tAttr = om.MFnTypedAttribute()
|
||||
|
||||
cls.aCvs = tAttr.create("cvComponentList", "cvs",
|
||||
om.MFnComponentListData.kComponentList)
|
||||
|
||||
cls.aOffset = nAttr.create("offset", "off", om.MFnNumericData.kFloat)
|
||||
nAttr.setMin(0)
|
||||
nAttr.default = 0.5
|
||||
nAttr.keyable = True
|
||||
cls.aSeg = nAttr.create("segments", "seg", om.MFnNumericData.kInt)
|
||||
nAttr.setMin(1)
|
||||
nAttr.default = 1
|
||||
nAttr.keyable = True
|
||||
|
||||
cls.aOffsetFrac = nAttr.create("offsetAsFraction", "oaf",
|
||||
om.MFnNumericData.kBoolean)
|
||||
nAttr.default = False
|
||||
nAttr.keyable = True
|
||||
|
||||
cls.aInputCurve = tAttr.create("inCurve", "inc",
|
||||
om.MFnData.kNurbsCurve)
|
||||
cls.aOutput = tAttr.create("outCurve", "out", om.MFnData.kNurbsCurve)
|
||||
tAttr.storable = False
|
||||
tAttr.writable = False
|
||||
|
||||
MayaNodeT.addAttribute(cls.aCvs)
|
||||
MayaNodeT.addAttribute(cls.aOffset)
|
||||
MayaNodeT.addAttribute(cls.aSeg)
|
||||
MayaNodeT.addAttribute(cls.aOffsetFrac)
|
||||
MayaNodeT.addAttribute(cls.aInputCurve)
|
||||
MayaNodeT.addAttribute(cls.aOutput)
|
||||
|
||||
MayaNodeT.attributeAffects(cls.aCvs, cls.aOutput)
|
||||
MayaNodeT.attributeAffects(cls.aOffset, cls.aOutput)
|
||||
MayaNodeT.attributeAffects(cls.aSeg, cls.aOutput)
|
||||
MayaNodeT.attributeAffects(cls.aOffsetFrac, cls.aOutput)
|
||||
MayaNodeT.attributeAffects(cls.aInputCurve, cls.aOutput)
|
||||
|
||||
def setOutputToCopy(self, data):
|
||||
|
||||
inCurveHandle = data.inputValue(CpCurveBevel.aInputCurve)
|
||||
outHandle = data.outputValue(CpCurveBevel.aOutput)
|
||||
outHandle.copy(inCurveHandle)
|
||||
outHandle.setClean()
|
||||
|
||||
def compute(self, plug, data):
|
||||
|
||||
if plug != CpCurveBevel.aOutput:
|
||||
return None
|
||||
|
||||
inCurveHandle = data.inputValue(CpCurveBevel.aInputCurve)
|
||||
|
||||
inCurve = inCurveHandle.asNurbsCurveTransformed()
|
||||
|
||||
inCvsHandle = data.inputValue(CpCurveBevel.aCvs)
|
||||
compData = inCvsHandle.data()
|
||||
ids = cPcompToIds(compData, om.MFn.kCurveCVComponent)
|
||||
#
|
||||
inOffset = data.inputValue(CpCurveBevel.aOffset).asFloat()
|
||||
inSeg = data.inputValue(CpCurveBevel.aSeg).asInt()
|
||||
inFrac = data.inputValue(CpCurveBevel.aOffsetFrac).asBool()
|
||||
|
||||
if len(ids) == 0 or inOffset == 0:
|
||||
self.setOutputToCopy(data)
|
||||
return
|
||||
|
||||
curveFn = om.MFnNurbsCurve(inCurve)
|
||||
curveDegree = curveFn.degree
|
||||
curveForm = curveFn.form
|
||||
# curveKnots = curveFn.knots()
|
||||
curvePts = curveFn.cvPositions() # to be modified
|
||||
numcv = len(curvePts) # to be modified
|
||||
|
||||
bevelParam = 1 / float(inSeg)
|
||||
bevelPts = []
|
||||
|
||||
ids.sort()
|
||||
|
||||
for cvIdx in ids:
|
||||
|
||||
mpos = om.MVector(curvePts[cvIdx])
|
||||
|
||||
if curveForm == curveFn.kPeriodic:
|
||||
lpos = om.MVector(curvePts[(cvIdx + numcv -
|
||||
(1 + curveDegree)) %
|
||||
(numcv - curveDegree)])
|
||||
rpos = om.MVector(curvePts[(cvIdx + 1) %
|
||||
(numcv - curveDegree)])
|
||||
else:
|
||||
lpos = om.MVector(curvePts[(cvIdx + numcv - 1) % numcv])
|
||||
rpos = om.MVector(curvePts[(cvIdx + 1) % numcv])
|
||||
|
||||
lvec = lpos - mpos
|
||||
rvec = rpos - mpos
|
||||
|
||||
lanchor = None
|
||||
ranchor = None
|
||||
if inFrac:
|
||||
lanchor = mpos + (inOffset * lvec)
|
||||
ranchor = mpos + (inOffset * rvec)
|
||||
else:
|
||||
lanchor = mpos + (inOffset * lvec.normal())
|
||||
ranchor = mpos + (inOffset * rvec.normal())
|
||||
|
||||
bevelPts.append(lanchor)
|
||||
t = 1 * bevelParam
|
||||
for i in range(inSeg - 1):
|
||||
# (1-t)^2A+2t(1-t)B+t^2C
|
||||
res = (1 - t)**2 * lanchor + (2 * t * (1 - t) * mpos) + (
|
||||
t**2 * ranchor)
|
||||
bevelPts.append(res)
|
||||
t += bevelParam
|
||||
bevelPts.append(ranchor)
|
||||
|
||||
#
|
||||
i = len(bevelPts) - (inSeg + 1)
|
||||
ids.sort(reverse=True)
|
||||
for cvIdx in ids:
|
||||
curvePts[cvIdx] = bevelPts[i]
|
||||
curvePts[cvIdx + 1:cvIdx + 1] = bevelPts[i + 1:i + inSeg + 1]
|
||||
i -= (inSeg + 1)
|
||||
|
||||
numcv = len(curvePts)
|
||||
if curveForm == curveFn.kPeriodic:
|
||||
curvePts[-curveDegree:] = curvePts[:curveDegree]
|
||||
|
||||
if curveDegree == 1:
|
||||
knots = [float(i) for i in range(numcv)]
|
||||
|
||||
else:
|
||||
knots = [None] * (numcv - curveDegree + (2 * curveDegree) - 1)
|
||||
|
||||
if curveForm == curveFn.kPeriodic:
|
||||
knots[:curveDegree] = [
|
||||
float(i) for i in reversed(range(0, -curveDegree, -1))
|
||||
]
|
||||
knots[curveDegree:] = [
|
||||
float(i) for i in range(1,
|
||||
len(knots) - curveDegree + 1)
|
||||
]
|
||||
|
||||
else:
|
||||
knots[:curveDegree] = [float(0)] * curveDegree
|
||||
knots[-curveDegree:] = [float(numcv - curveDegree)
|
||||
] * curveDegree
|
||||
knots[curveDegree:-curveDegree] = [
|
||||
float(i)
|
||||
for i in range(1,
|
||||
len(knots) - (2 * curveDegree) + 1)
|
||||
]
|
||||
|
||||
curveDataFn = om.MFnNurbsCurveData()
|
||||
curveDataFn.create()
|
||||
|
||||
knots = om.MDoubleArray(knots)
|
||||
curveFn.create(
|
||||
curvePts,
|
||||
knots,
|
||||
curveDegree,
|
||||
curveForm,
|
||||
False,
|
||||
False,
|
||||
parent=curveDataFn.object())
|
||||
|
||||
out = data.outputValue(CpCurveBevel.aOutput)
|
||||
out.setMObject(curveDataFn.object())
|
||||
out.setClean()
|
||||
|
||||
class CpCurveToPoly(MayaNodeT):
|
||||
|
||||
kNodeName = "creasePlusCurveToPoly"
|
||||
kNodeId = om.MTypeId(0x12547)
|
||||
|
||||
aCount = None
|
||||
aRevNorm = None
|
||||
aControlPts = None
|
||||
aInputCurve = None
|
||||
aOutput = None
|
||||
|
||||
def __init__(self):
|
||||
super(CpCurveToPoly, self).__init__()
|
||||
|
||||
@classmethod
|
||||
def creator(cls):
|
||||
return cls()
|
||||
|
||||
@classmethod
|
||||
def initialize(cls):
|
||||
|
||||
nAttr = om.MFnNumericAttribute()
|
||||
tAttr = om.MFnTypedAttribute()
|
||||
|
||||
cls.aRevNorm = nAttr.create("reverse", "rev",
|
||||
om.MFnNumericData.kBoolean)
|
||||
nAttr.default = False
|
||||
nAttr.keyable = True
|
||||
|
||||
cls.aCount = nAttr.create("count", "cnt", om.MFnNumericData.kInt)
|
||||
nAttr.setMin(3)
|
||||
nAttr.default = 12
|
||||
nAttr.keyable = True
|
||||
|
||||
cls.aControlPts = nAttr.create("controlPts", "cv",
|
||||
om.MFnNumericData.kBoolean)
|
||||
nAttr.default = True
|
||||
nAttr.keyable = True
|
||||
|
||||
cls.aInputCurve = tAttr.create("inCurve", "inc",
|
||||
om.MFnData.kNurbsCurve)
|
||||
cls.aOutput = tAttr.create("outPoly", "out", om.MFnData.kMesh)
|
||||
tAttr.storable = False
|
||||
tAttr.writable = False
|
||||
|
||||
MayaNodeT.addAttribute(cls.aRevNorm)
|
||||
MayaNodeT.addAttribute(cls.aCount)
|
||||
MayaNodeT.addAttribute(cls.aControlPts)
|
||||
MayaNodeT.addAttribute(cls.aInputCurve)
|
||||
MayaNodeT.addAttribute(cls.aOutput)
|
||||
|
||||
MayaNodeT.attributeAffects(cls.aRevNorm, cls.aOutput)
|
||||
MayaNodeT.attributeAffects(cls.aCount, cls.aOutput)
|
||||
MayaNodeT.attributeAffects(cls.aControlPts, cls.aOutput)
|
||||
MayaNodeT.attributeAffects(cls.aInputCurve, cls.aOutput)
|
||||
|
||||
def setOutputToNull(self, data):
|
||||
out = data.outputValue(CpCurveToPoly.aOutput)
|
||||
out.setMObject(om.MObject.kNullObj)
|
||||
out.setClean()
|
||||
|
||||
def compute(self, plug, data):
|
||||
|
||||
if plug != CpCurveToPoly.aOutput:
|
||||
return None
|
||||
|
||||
reverseNormal = data.inputValue(CpCurveToPoly.aRevNorm).asBool()
|
||||
inCurveHandle = data.inputValue(CpCurveToPoly.aInputCurve)
|
||||
|
||||
inCurve = inCurveHandle.asNurbsCurveTransformed()
|
||||
|
||||
inCount = data.inputValue(CpCurveToPoly.aCount).asInt() #
|
||||
useCvs = data.inputValue(CpCurveToPoly.aControlPts).asBool()
|
||||
|
||||
curveFn = om.MFnNurbsCurve(inCurve)
|
||||
curveForm = curveFn.form
|
||||
curveDegree = curveFn.degree
|
||||
polyPts = None
|
||||
|
||||
meshDataFn = om.MFnMeshData()
|
||||
meshDataFn.create()
|
||||
|
||||
if useCvs:
|
||||
if curveForm == curveFn.kPeriodic:
|
||||
polyPts = curveFn.cvPositions()[:-curveDegree]
|
||||
else:
|
||||
polyPts = curveFn.cvPositions()
|
||||
else:
|
||||
polyPts = []
|
||||
domain = curveFn.knotDomain
|
||||
param = domain[1] / float(inCount)
|
||||
t = 0.0
|
||||
for i in range(inCount):
|
||||
polyPts.append(curveFn.getPointAtParam(t))
|
||||
t += param
|
||||
|
||||
if reverseNormal:
|
||||
polyPts = [pt for pt in reversed(polyPts)]
|
||||
# create(vertices, polygonCounts, polygonConnects, uValues=None, vValues=None, parent=kNullObj) -> MObject
|
||||
meshFn = om.MFnMesh()
|
||||
meshFn.create(
|
||||
polyPts, [len(polyPts)], [i for i in range(len(polyPts))],
|
||||
parent=meshDataFn.object())
|
||||
|
||||
out = data.outputValue(CpCurveToPoly.aOutput)
|
||||
out.setMObject(meshDataFn.object())
|
||||
out.setClean()
|
||||
|
||||
class CpHeIds(MayaNodeT):
|
||||
|
||||
kNodeName = "creasePlusBevelHe"
|
||||
kNodeId = om.MTypeId(0x1157)
|
||||
|
||||
aForceComp = None
|
||||
aInputMesh = None
|
||||
aIds = None
|
||||
|
||||
def __init__(self):
|
||||
|
||||
super(CpHeIds, self).__init__()
|
||||
|
||||
self.numVertices = 0
|
||||
self.numPolygons = 0
|
||||
self.numNormals = 0
|
||||
self.dummycompute = False
|
||||
|
||||
@classmethod
|
||||
def creator(cls):
|
||||
return cls()
|
||||
|
||||
@classmethod
|
||||
def initialize(cls):
|
||||
tAttr = om.MFnTypedAttribute()
|
||||
nAttr = om.MFnNumericAttribute()
|
||||
|
||||
cls.aForceComp = nAttr.create("forceCompute", "fc",
|
||||
om.MFnNumericData.kBoolean, 0)
|
||||
nAttr.default = False
|
||||
nAttr.keyable = True
|
||||
|
||||
cls.aInputMesh = tAttr.create("inMesh", "i", om.MFnData.kMesh)
|
||||
|
||||
cls.aIds = tAttr.create("componentList", "cl",
|
||||
om.MFnComponentListData.kComponentList)
|
||||
tAttr.storable = False
|
||||
tAttr.writable = False
|
||||
|
||||
MayaNodeT.addAttribute(cls.aForceComp)
|
||||
MayaNodeT.addAttribute(cls.aInputMesh)
|
||||
MayaNodeT.addAttribute(cls.aIds)
|
||||
|
||||
def attrToPlug(self, attr):
|
||||
return om.MPlug(self.thisMObject(), attr)
|
||||
|
||||
def setDependentsDirty(self, plug, affect):
|
||||
|
||||
if plug == CpHeIds.aForceComp:
|
||||
if self.dummycompute == False:
|
||||
self.dummycompute = True
|
||||
affect.append(self.attrToPlug(CpHeIds.aIds))
|
||||
else:
|
||||
self.dummycompute = False
|
||||
elif plug == CpHeIds.aInputMesh:
|
||||
affect.append(self.attrToPlug(CpHeIds.aIds))
|
||||
|
||||
def compute(self, plug, data):
|
||||
if plug != CpHeIds.aIds:
|
||||
return None
|
||||
|
||||
doingit = False
|
||||
|
||||
data.inputValue(CpHeIds.aForceComp)
|
||||
inMeshHandle = data.inputValue(CpHeIds.aInputMesh)
|
||||
inmesh = inMeshHandle.asMesh()
|
||||
meshFn = om.MFnMesh(inmesh)
|
||||
|
||||
if self.dummycompute == True:
|
||||
doingit = True
|
||||
elif (self.numVertices != meshFn.numVertices
|
||||
or self.numPolygons != meshFn.numPolygons
|
||||
or self.numNormals != meshFn.numNormals):
|
||||
doingit = True
|
||||
|
||||
if doingit == True:
|
||||
heIds = cPhardEdgeIds(inmesh)
|
||||
compObj = cPidsToComp(heIds, om.MFn.kMeshEdgeComponent)[1]
|
||||
|
||||
outIdsHandle = data.outputValue(CpHeIds.aIds)
|
||||
outIdsHandle.setMObject(compObj)
|
||||
outIdsHandle.setClean()
|
||||
|
||||
if self.dummycompute == True:
|
||||
forceCompplug = self.attrToPlug(CpHeIds.aForceComp)
|
||||
forceCompplug.setBool(False)
|
||||
|
||||
def initializePlugin(obj):
|
||||
|
||||
mplugin = om.MFnPlugin(obj, "Baidhir Hidair", "1.0")
|
||||
|
||||
nodeName = None
|
||||
|
||||
try:
|
||||
nodeName = CpHeIds.kNodeName
|
||||
mplugin.registerNode(CpHeIds.kNodeName, CpHeIds.kNodeId,
|
||||
CpHeIds.creator, CpHeIds.initialize)
|
||||
|
||||
nodeName = CpCurveBevel.kNodeName
|
||||
mplugin.registerNode(CpCurveBevel.kNodeName, CpCurveBevel.kNodeId,
|
||||
CpCurveBevel.creator, CpCurveBevel.initialize)
|
||||
|
||||
nodeName = CpCurveToPoly.kNodeName
|
||||
mplugin.registerNode(CpCurveToPoly.kNodeName, CpCurveToPoly.kNodeId,
|
||||
CpCurveToPoly.creator, CpCurveToPoly.initialize)
|
||||
|
||||
except:
|
||||
raise Exception('failed to register node: ' + nodeName)
|
||||
|
||||
def uninitializePlugin(obj):
|
||||
|
||||
mplugin = om.MFnPlugin(obj)
|
||||
|
||||
nodeName = None
|
||||
|
||||
try:
|
||||
nodeName = CpHeIds.kNodeName
|
||||
mplugin.deregisterNode(CpHeIds.kNodeId)
|
||||
|
||||
nodeName = CpCurveBevel.kNodeName
|
||||
mplugin.deregisterNode(CpCurveBevel.kNodeId)
|
||||
|
||||
nodeName = CpCurveToPoly.kNodeName
|
||||
mplugin.deregisterNode(CpCurveToPoly.kNodeId)
|
||||
|
||||
except:
|
||||
raise Exception('failed to deregister node: ' + nodeName)
|
BIN
Scripts/Modeling/Edit/CreasePlus/CreasePlus_def_sheet.pdf
Normal file
BIN
Scripts/Modeling/Edit/CreasePlus/Icons/crep_bevel_ico.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
Scripts/Modeling/Edit/CreasePlus/Icons/crep_bevellive_ico.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
Scripts/Modeling/Edit/CreasePlus/Icons/crep_bool_ico.png
Normal file
After Width: | Height: | Size: 2.7 KiB |
BIN
Scripts/Modeling/Edit/CreasePlus/Icons/crep_close_ico.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
Scripts/Modeling/Edit/CreasePlus/Icons/crep_crease_ico.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
Scripts/Modeling/Edit/CreasePlus/Icons/crep_curveattach_ico.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
Scripts/Modeling/Edit/CreasePlus/Icons/crep_curvebevel_ico.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
Scripts/Modeling/Edit/CreasePlus/Icons/crep_curveclose_ico.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
Scripts/Modeling/Edit/CreasePlus/Icons/crep_curvedraw_ico.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
Scripts/Modeling/Edit/CreasePlus/Icons/crep_curveint_ico.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
Scripts/Modeling/Edit/CreasePlus/Icons/crep_curvemult_ico.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
Scripts/Modeling/Edit/CreasePlus/Icons/crep_curvepoly_ico.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
Scripts/Modeling/Edit/CreasePlus/Icons/crep_displayhe_ico.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
Scripts/Modeling/Edit/CreasePlus/Icons/crep_eye_ico.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
Scripts/Modeling/Edit/CreasePlus/Icons/crep_hardedge_ico.png
Normal file
After Width: | Height: | Size: 1.9 KiB |
BIN
Scripts/Modeling/Edit/CreasePlus/Icons/crep_menu_ico.png
Normal file
After Width: | Height: | Size: 676 B |
BIN
Scripts/Modeling/Edit/CreasePlus/Icons/crep_meshslicer_ico.png
Normal file
After Width: | Height: | Size: 2.7 KiB |
BIN
Scripts/Modeling/Edit/CreasePlus/Icons/crep_mirror_ico.png
Normal file
After Width: | Height: | Size: 2.6 KiB |
BIN
Scripts/Modeling/Edit/CreasePlus/Icons/crep_next_ico.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
Scripts/Modeling/Edit/CreasePlus/Icons/crep_panelbool_ico.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
Scripts/Modeling/Edit/CreasePlus/Icons/crep_physcrease_ico.png
Normal file
After Width: | Height: | Size: 2.0 KiB |
BIN
Scripts/Modeling/Edit/CreasePlus/Icons/crep_shapeshifter_ico.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
Scripts/Modeling/Edit/CreasePlus/Icons/crep_smoothangle_ico.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
BIN
Scripts/Modeling/Edit/CreasePlus/Icons/crep_subd_ico.png
Normal file
After Width: | Height: | Size: 502 B |
BIN
Scripts/Modeling/Edit/CreasePlus/Icons/crep_uv_ico.png
Normal file
After Width: | Height: | Size: 769 B |
BIN
Scripts/Modeling/Edit/CreasePlus/Icons/crep_weighttool_ico.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
Scripts/Modeling/Edit/CreasePlus/Icons/crep_zbrush_ico.png
Normal file
After Width: | Height: | Size: 2.9 KiB |
17
Scripts/Modeling/Edit/CreasePlus/MayaUndoRun.py
Normal file
@ -0,0 +1,17 @@
|
||||
from functools import wraps
|
||||
import maya.cmds as cmds
|
||||
|
||||
def mayaUndoRun(func):
|
||||
""" Puts the wrapped `func` into a single Maya Undo action, then
|
||||
undoes it when the function enters the finally: block """
|
||||
@wraps(func)
|
||||
def _undofunc(*args, **kwargs):
|
||||
try:
|
||||
# start an undo chunk
|
||||
cmds.undoInfo(openChunk=True)
|
||||
return func(*args, **kwargs)
|
||||
finally:
|
||||
# after calling the func, end the undo chunk
|
||||
cmds.undoInfo(closeChunk=True)
|
||||
|
||||
return _undofunc
|
5
Scripts/Modeling/Edit/CreasePlus/__init__.py
Normal file
@ -0,0 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Empty Init file
|
||||
from . import *
|
2
Scripts/Modeling/Edit/CreasePlus/delpyc.bat
Normal file
@ -0,0 +1,2 @@
|
||||
@echo off
|
||||
del *.pyc
|
40
Scripts/Modeling/Edit/CreasePlus/readit.txt
Normal file
@ -0,0 +1,40 @@
|
||||
_____ _____ ______ _____ ______
|
||||
/ ____| __ \| ____| /\ / ____| ____|_
|
||||
| | | |__) | |__ / \ | (___ | |__ _| |_
|
||||
| | | _ /| __| / /\ \ \___ \| __|_ _|
|
||||
| |____| | \ \| |____ / ____ \ ____) | |____|_|
|
||||
\_____|_| \_\______/_/ \_\_____/|______|
|
||||
|
||||
This version of CreasePlus is rewritten entirely in python cmds(maya) and API's.
|
||||
thus there is no longer support for MayaLT. And the run-in lang is Python.
|
||||
|
||||
install :
|
||||
extract, then just place icon and main folders in documents/maya/(maya_version)/scripts/
|
||||
restart maya if opened.
|
||||
|
||||
#
|
||||
# attach it as python script / runtime command to hotkey:
|
||||
import maya.cmds as cmds
|
||||
from CreasePlus import CreasePlusMain
|
||||
CreasePlusMain.start()
|
||||
|
||||
if not cmds.pluginInfo("CreasePlusNodes", q=True, loaded=True):
|
||||
cmds.loadPlugin("CreasePlusNodes.py")
|
||||
|
||||
|
||||
# attach it as python script / runtime command to hotkey, for attribute iteration in context (optional):
|
||||
from CreasePlus import CreasePlusMain
|
||||
CreasePlusMain.crepcore.creasePlusLastCtx()
|
||||
|
||||
# attach it as python script / runtime command to hotkey, for edge soft/hard toggle (optional):
|
||||
from CreasePlus import CreasePlusMain
|
||||
CreasePlusMain.crepcore.creasePlusToggleEdgeSmooth()
|
||||
|
||||
# attach it as python script / runtime command to hotkey, for edge makeUV (optional):
|
||||
from CreasePlus import CreasePlusMain
|
||||
CreasePlusMain.crepcore.creasePlusMakeUv()
|
||||
|
||||
|
||||
# commands / defs for bindings / scripts can be found in def_sheet file
|
||||
|
||||
# thank you
|