Reputation: 2962
I want to snap / align an object A
to vertex of object B
. I have tried using below script but its not snapping exactly to the vertex but snapping with an offset. Can any one suggest me a solution. Here are the snapshots.
import maya.cmds as cmds
vertices = [];
srcObj = "pCone1";
def snapToVertex(vertex,object):
cmds.select(vertex);
x,y,z = cmds.pointPosition();
cmds.select(object);
cmds.duplicate();
cmds.move(x,y,z);
def processTask():
cmds.select( cmds.polyListComponentConversion( tv=True ) );
vertices = cmds.ls(sl = True);
print vertices;
for vrtx in vertices:
snapToVertex(vrtx,srcObj);
processTask();
Snapped with my above Script, Which didn't snap exactly to vertex.
But it should be snapped exactly to the Vervex's as below image.
Upvotes: 3
Views: 5043
Reputation: 58063
It's better not to use Reset Transformations
command for your Cone
from Modify
main menu, 'cause pivot point goes back to its initial place. The analog for useful Freeze Transformations
command in Python is cmds.makeIdentity()
. Even if you've moved you pivot point by 1
unit (for example) along +Y
axis, do not forget to subtract that 1
from variable y
cause Maya somehow remembers pivot's position. Offset of the Cone's pivot point (for snapping pivot to a vertex) depends on the Cone's size itself. By default it's 1
.
Add this snippet to your code to move the duplicates in World Space
:
# cmds.makeIdentity( 'pCone1', apply=True )
pivSnap = 1
cmds.xform( 'pCone1', piv=[ 0, pivSnap, 0 ] )
cmds.move( x, y-pivSnap, z, a=True, ws=True, wd=True )
You can test this code (here I moved pivot up by 0.5
):
import maya.cmds as cmds
cmds.polyCube( sx=1, sy=15, sz=1, w=1, h=15, d=1 )
cmds.polyCone( r=.5, h=1, sx=10 )
cmds.move( 10, x=True )
pivSnap = .5
cmds.xform( 'pCone1', piv=[ 0, pivSnap, 0 ] )
cmds.rotate( 0, 0, '45deg' )
cmds.select( 'pCube1.e[33]','pCube1.e[37]','pCube1.e[41]','pCube1.e[45]','pCube1.e[49]','pCube1.e[53]','pCube1.e[57]','pCube1.e[61]' )
vertices = []
srcObj = "pCone1"
def snapToVertex( vertex, object ):
cmds.select( vertex )
x,y,z = cmds.pointPosition()
print( x,y,z )
cmds.select( object )
cmds.manipMoveContext( m=2 )
cmds.delete( 'pCube1', ch=True )
cmds.duplicate()
cmds.move( x, y-pivSnap, z, a=True, ws=True, wd=True )
def processTask():
cmds.select( cmds.polyListComponentConversion( tv=True ) )
vertices = cmds.ls( sl=True )
print( vertices )
for vrtx in vertices:
snapToVertex( vrtx, srcObj )
processTask()
Upvotes: 3
Reputation: 502
you could greatly simplify your code and only use a few commands
import maya.cmds as mc
verts = mc.ls(os=True)
src = 'pCone1'
base_name = 'fancy_cone'
for i, vert in enumerate(verts):
dup = mc.duplicate(src, n='%s_%s' %(base_name, i))[0]
mc.xform(dup, ws=True, t=mc.xform(vert, q=True, ws=True, t=True))
keep in mind a few caveats:
1) this is assuming that the pivot of your source cone is at the tip with the tip at the origin... so it requires setting up that source cone the way you want it as if the origin point is a vertex you will be snapping it to. This would also be beneficial if the object you're 'pinning' to is rotated (no need to do any kind of vector math to determine the positional offset that way)
2) to use the orderedSelection (os) flag in the ls command, you need to be sure track selection order is turned on in your maya preferences under the selection sub section - this way you can select the verts you want in the order you want them to be created (top-down, bottum-up, whatever) instead of the vert index order
This should also be significantly faster - by tracking any created objects, you don't actually need to select anything and can manipulate the objects directly. I also put it all into one loop without any function calls which would be faster (although, you probably won't notice it unless you're making a LOOOOOOT of these).
Depending on your needs though, you may actually want to utilize a snapping function multiple places; However, I would suggest keeping the duplication out of it in case there are situations you want to snap without duplicating.
Something like this (subject to same caveats as above):
import maya.cmds as mc
def snapToVertex(vertex, object):
pos = mc.xform(vertex, q=True, ws=True, t=True)
mc.xform(object, ws=True, t=pos) # combine to single line if prefered
def processTask():
verts = mc.ls(os=True)
src = 'pCone1'
base_name = 'fancy_cone'
for i, vert in enumerate(verts):
dup = mc.duplicate(src, n='%s_%s' %(base_name, i))[0]
snapToVertex(vert, dup)
processTask()
Upvotes: 1