Announcements

Between mid-October and November, the content on AREA will be relocated to the Autodesk Community M&E Hub and the Autodesk Community Gallery. Learn more HERE.

Trouble with writing a script that can create and constrain a joints

Trouble with writing a script that can create and constrain a joints

dh323
Explorer Explorer
1,528 Views
8 Replies
Message 1 of 9

Trouble with writing a script that can create and constrain a joints

dh323
Explorer
Explorer

Hey guys I am new to maya scripting. I am trying to write a script that can create and constrain joints at selected vertexes. I found someone already done the creating joints part and i tried to "point on poly" constrain each created joints to each corresponding vertex during the loop. However the joints will all ends up constraining at the same vertex. What am I doing wrong?

 

import maya.cmds as cmds


def componentToJoint():
    if cmds.objectType(cmds.ls(sl=1)[0]) != "mesh":
        return
    # return the selection as a list
    selList = getSelection()
    print selList
    componentType = selList[0][selList[0].index(".") + 1:selList[0].index("[")]
    componentCenters = []
    jointNum = 1
    for c in selList:
        cmds.select(cl=1)
        cmds.joint(n="joint" + str(jointNum), p=cmds.pointPosition(c), rad=.25)
#point on poly constraint - doesnt work cmds.pointOnPolyConstraint(c, "joint" + str(jointNum) ) jointNum += 1 cmds.select(cl=1) def getSelection(): components = cmds.ls(sl=1) selList = [] objName = components[0][0:components[0].index(".")] # go through every component in the list. If it is a single component ("pCube1.vtx[1]"), add it to the list. Else, # add each component in the index ("pCube1.vtx[1:5]") to the list for c in components: if ":" not in c: selList.append(c) else: print c startComponent = int(c[c.index("[") + 1: c.index(":")]) endComponent = int(c[c.index(":") + 1:c.index("]")]) componentType = c[c.index(".") + 1:c.index("[")] while startComponent <= endComponent: selList.append(objName + "." + componentType + "[" + str(startComponent) + "]") startComponent += 1 return selList componentToJoint()

Heres the screen shot

each vertexes are cramped into one single pointeach vertexes are cramped into one single point

0 Likes
1,529 Views
8 Replies
Replies (8)
Message 2 of 9

kevin.picott
Alumni
Alumni

The first thing you can do is eliminate the "getSelection()" method entirely as one of the flags to the "ls" command will do exactly what you've done here, but much more efficiently.

cmds.ls( selection=True, flatten=True )

Constraining the position is a trickier since the "pointOnPolyConstraint" doesn't do what you were hoping it does.I would first question why you want to constrain joint positions to vertex positions though, since that will effectively disable the IK solver. I found this video that does what you are trying to do for individual objects that illustrates how this is a bit more complex than it first appears - https://www.youtube.com/watch?v=BXjyznn1quo



Kevin "Father of the DG" Picott

Senior Principal Engineer
Message 3 of 9

dh323
Explorer
Explorer

https://www.youtube.com/watch?v=fUpTu-uMFRo

so basically i want to make this happen to a ghost model i have which looks like this

3.PNG

 

There is a guy posed a MEL script at the comment section, i tried it on a similar plane, and it works perfectly

1.PNG2.PNG

 

however, when i apply that script to my ghost model the constraint goes everywhere:

4.PNG

therefore i wanted to try to write some codes myself 

0 Likes
Message 4 of 9

kevin.picott
Alumni
Alumni

Ah, I see, that does make a difference then. You'll notice in the original script that there is a $uv value being generated, which you don't have in your script. Your script will default its values to 0,0, which will in effect constrain everything to the same point of your object. When applying the script in the tutorial the way the $uv value is used relies on a nice even distribution of U and V with respect to the vertices. That's usually true for a nice regular shape like a plane but never true for irregular shapes like your ghost.

 

I would suggest playing around with those values to see if you can't get something more reasonable.



Kevin "Father of the DG" Picott

Senior Principal Engineer
Message 5 of 9

dh323
Explorer
Explorer

i see.. that really out of my ability then, my programming knowledge stops at the entry level

by saying uv, does it means that the original MEL script is actually reading through the uv map to get the coordinates?  

0 Likes
Message 6 of 9

kevin.picott
Alumni
Alumni

Not exactly, it's just reading the converted UV values directly with these two lines

  $vtxuv = `polyListComponentConversion -fv -tuv`;
  $uv = `polyEditUV -q $vtxuv`;

It doesn't work in general since there can be multiple sets of UVs and they may change when doing other operations but it is okay for a first pass.



Kevin "Father of the DG" Picott

Senior Principal Engineer
0 Likes
Message 7 of 9

dh323
Explorer
Explorer

Nice! I got it! My original ghost model did not have a proper uv map, and after applying proper uv map on the script reads it. this is enough for my little project now since it will be a rather simplistic model. ty for the helping!

0 Likes
Message 8 of 9

ToreyAlvarez6545
Participant
Participant

Hello, Do you mind sharing the script, I can't find it in the comments, Thank you again!

0 Likes
Message 9 of 9

Kahylan
Advisor
Advisor

There you go:

//Joints on Vertices Tool

proc vrtJnt(){

//Query vertex selection
string $selVerts[] = `ls -sl -fl`;

//For Loop - applies the command to each selected vertex
for ($vrts in $selVerts){ 

	//select each vertex individually
    select $vrts;
	//create a cluster on each selected vertex
	string $cl[] = `newCluster " -relative -envelope 1"`;
	//clear selection so joint is not parented under cluster
	select -cl;
	//create a joint
	string $jnt = `joint`;
	//point constrain the joint TO the cluster
	string $ptCnJnt[] = `pointConstraint -offset 0 0 0 -weight 1 $cl $jnt`;
	//Query the point constrain tied to the joint
	string $findPtCn[] = `listRelatives -typ pointConstraint $jnt`;
	//select and delete the joint's point constrain
	select $findPtCn[0]; doDelete;
	//select and delete the cluster 
	select -replace $cl; doDelete;
	
	
	select $vrts;
	$uvMap = `polyListComponentConversion -fv -tuv`;
	float $uv[2]=`polyEditUV -q $uvMap`;
	
	select $vrts $jnt;
	doCreatePointOnPolyConstraintArgList 2 {   "0" ,"0" ,"0" ,"1" ,"" ,"1" ,"0" ,"0" ,"0" ,"0" };
    {string $constraint[]=`pointOnPolyConstraint -offset 0 0 0  -weight 1`; setAttr ($constraint[0]+".pCube1U0") $uv[0]; setAttr ($constraint[0]+".pCube1V0") $uv[1];};
	
	

	}
}
//run the procedure
vrtJnt;

It looks like the object name is Hardcoded in though. So you need to replace any mention of "pCube1" with the name of your object.

 

0 Likes