Skip to content

Instantly share code, notes, and snippets.

@TSCG
Last active September 20, 2020 13:34
Show Gist options
  • Save TSCG/24da9d1f056efc93b0346d7c03b39cf8 to your computer and use it in GitHub Desktop.
Save TSCG/24da9d1f056efc93b0346d7c03b39cf8 to your computer and use it in GitHub Desktop.
選択頂点をカーブにスナップ。均等or近似
#-*- coding:UTF-8 -*-
## usage
# Select and execute a vertex.
#
# argument
# TsSnapCurve().main( curveName, Type )
# curveName : snap curve name
# Type : 1=closest ,2=average
#
# e.x.
# TsSnapCurve().main("curve1",1)
###### Tool Modules
import maya.cmds as cmds
import pymel.core as pm
class TsSnapCurve:
def closest( self, curveName ):
#curveName = self.UI.selectCurve_Tx.text()
selVtx = cmds.ls(sl=True, fl=True)
cmds.undoInfo( openChunk=True )
closestTmp = cmds.createNode( 'nearestPointOnCurve', n='TsTmp_nearestPointOnCurve' )
sphereObject = pm.ls( curveName )[0]
shapes = sphereObject.getShapes()
cmds.connectAttr( shapes[0] + ".worldSpace[0]", closestTmp + ".inputCurve" )
for tmp in selVtx:
get_m = cmds.pointPosition(tmp, w=True)
cmds.setAttr( closestTmp + '.inPosition', get_m[0], get_m[1], get_m[2],type="double3")
get_m = cmds.getAttr( closestTmp + '.result.position' )
cmds.xform( tmp, worldSpace=True, translation=get_m[0])
cmds.delete( closestTmp )
cmds.undoInfo( closeChunk=True )
def fill_pointList( self, curve, numsegment, cordLength ):
curvePoint_List = []
lengthNode = cmds.arclen( curve, ch=True )
curveSampler = cmds.pointOnCurve( curve, ch=True )
motionSampler = cmds.createNode( 'motionPath' )
curveShape = cmds.listRelatives( curve, shapes=True, noIntermediate=True )
cmds.connectAttr( curveShape[0]+".worldSpace[0]", motionSampler+".geometryPath", force=True )
cmds.setAttr( curveSampler + ".turnOnPercentage", 1 )
cmds.setAttr( motionSampler + ".fractionMode", 1 )
numberOfCV = len( cmds.getAttr( curve + ".cv[*]" ) ) / 3
firstPoint = cmds.getAttr( curve + ".cv[0]" )
lastPoint = cmds.getAttr( curve + ".cv[" + str(numberOfCV-1) + "]" )
curveLenght = cmds.getAttr( lengthNode + ".arcLength" )
i = 0
currentDistance = 0.0
nPosition = []
tangentSize = 0.0
cmds.setAttr( curveSampler+".parameter", 1.0 )
for i in range( numsegment +1 ):
currentDistance = (float(i)*cordLength)/curveLenght
if( currentDistance <= 1.0 ):
cmds.setAttr( motionSampler +".uValue", currentDistance )
nPosition = cmds.getAttr( motionSampler+".allCoordinates" )
curvePoint_List.extend( [nPosition[0]] )
else:
cmds.setAttr( motionSampler +".uValue", 1.0 )
nPosition = cmds.getAttr( motionSampler+".allCoordinates" )
curvePoint_List.extend( [nPosition[0]] )
# cleanup
cmds.delete( lengthNode, curveSampler, motionSampler )
return curvePoint_List
def averageOpen( self, curveName ):
cmds.undoInfo( openChunk=True )
#curveName = self.UI.selectCurve_Tx.text()
sel = cmds.ls(os=True, fl=True)
curveLen = cmds.arclen( curveName )
numsegment = len(sel) - 1
cordLength = curveLen / numsegment
list = self.fill_pointList ( curveName, numsegment, cordLength )
i=0
for tmp in sel:
cmds.xform( tmp, worldSpace=True, translation = list[i] )
i+=1
cmds.undoInfo( closeChunk=True )
def main(self, curveName, Type=1):
if Type == 1:
self.closest(curveName)
else:
self.averageOpen(curveName)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment