Looking for a way in mel to constrain a transform to a vert.

Looking for a way in mel to constrain a transform to a vert.

malcolm_341
Collaborator Collaborator
2,314 Views
29 Replies
Message 1 of 30

Looking for a way in mel to constrain a transform to a vert.

malcolm_341
Collaborator
Collaborator

Hi there, I'm looking for a way to constrain a locator or other transform to a vert, I've tried all the constraints, but those only work on meshes that have non-overlapping UVs, I need this to work on meshes with overlapping UVs. Is there some secret mel trick to get the vert to drive the locator's transform?

Accepted solutions (1)
2,315 Views
29 Replies
Replies (29)
Message 21 of 30

mcw0
Advisor
Advisor

Did you look at the emitter approach?  Maybe that's a simpler solution?  I do the edge approach all the time so I think nothing of it.  🙂 

0 Likes
Message 22 of 30

mcw0
Advisor
Advisor

There's also "surfaceAttach" under Maya muscles that will allow you to constrain to a point on a mesh.  Can't remember if that one uses UV values or not.  My edge approach is UV independent.

0 Likes
Message 23 of 30

mcw0
Advisor
Advisor

While you can't parent a locator under a vert, you can parent it under a curve.  That's what happens when you intersect curves.  Maya places a locator at the intersection location.  And that locator is parented under the curve shape node.  I've never had to do that myself so I'm not familiar with what's involved.  But since Maya does it, it can be done.  Just another option.

Message 24 of 30

malcolm_341
Collaborator
Collaborator

I'm writing code to detect if the locator lands in the wrong spot on the motion path, hopefully I don't run into any other unforeseen issues.

0 Likes
Message 25 of 30

mcw0
Advisor
Advisor

that depends on how the motion path is created...the start and end frames and the current frame on the timeline.  That's why I think the pointOnCurveInfo node is a better approach.

0 Likes
Message 26 of 30

malcolm_341
Collaborator
Collaborator
Accepted solution

I got it working with the curve method, it's a bit of code, but it works and it's robust because no UVs needed.

I think I also need to put some error checking in for if the edge is actually attached to the initial vert you select. Thanks for your help.

 

//Store vert position
float $vertPOS[];
MoveTool;
$vertPOS = `manipMoveContext -q -position "Move"`;

//Convert to edges
ConvertSelectionToEdges;
string $edges[] = `ls -sl -fl`;
select $edges[0];
//Check if edge has correct vert attached to it

string $curveAttach[] = `polyToCurve -form 0 -degree 1`;
CreateLocator;
string $locator[] = `ls -sl`;
scale 10 10 10;
select $curveAttach;
select -add $locator;
pathAnimation -fractionMode true -follow true -followAxis x -upAxis y -worldUpType "vector" -worldUpVector 0 1 0 -inverseUp false -inverseFront false -bank false -startTimeU 0 -endTimeU 1;
select $locator;

//Find motion path name
string $motionPath[] = `listConnections -type motionPath`;
//print ($motionPath[0] + "_uValue");
selectKey -k -t 0 -t 1 ($motionPath[0] + "_uValue");
cutKey -clear;

//Store locator position
float $locatorPOS[];
$locatorPOS = `manipMoveContext -q -position "Move"`;
//If locator lands at wrong end of curve move it back
if ($vertPOS[0] != $locatorPOS[0] || $vertPOS[1] != $locatorPOS[1] || $vertPOS[2] != $locatorPOS[2])
{
    float $uValue = `getAttr ($motionPath[0] + ".uValue")`;
    if ($uValue == 0)
    {
        setAttr ($motionPath[0] + ".uValue") 1;        
    }
    
    else
    {
        setAttr ($motionPath[0] + ".uValue") 0;   
    }
}

 

0 Likes
Message 27 of 30

mcw0
Advisor
Advisor

Glad it's working for you.  Here are some pointers to streamline your code.

 

With the vertex selected, you can get the edges with the following:

 

string $edges[] = ls("-flatten", `polyListComponentConversion -fv -te`);

This will alleviate the need to verify that the edge is attached to the curve since you are converting the vertex to edges.

 

Cast the motion path as a variable at the time of creation (saves looking for a motion path later):

 

string $mp = `pathAnimation....`;

 

Since you created the motionPath with "pathAnimation", there will definitely be an animCurve attached.  So...

 

delete `listConnections -s 1 -d 0 -type "animCurve" ($mp+".uValue")`;

Message 28 of 30

malcolm_341
Collaborator
Collaborator

My test for if the locator lands at the wrong spot would sometimes fail even if the float value of the locator and vert were exactly the same? I think this is a bug, the way I think I've gotten around it was to toggle the uValue of the motion path even if it was in the right spot adden to the code above

     //Refresh locator position to fix bug below
        float $uValue = `getAttr ($motionPath[0] + ".uValue")`;
        if ($uValue == 0)
        {
            setAttr ($motionPath[0] + ".uValue") 1;
        }
        else
        {
            setAttr ($motionPath[0] + ".uValue") 0;
        }

        //Store locator position
        $locatorPOS = `manipMoveContext -q -position "Move"`;
        //If locator lands at wrong end of curve move it back
        if ($vertPOS[0] != $locatorPOS[0] || $vertPOS[1] != $locatorPOS[1] || $vertPOS[2] != $locatorPOS[2])
        {
            float $uValue = `getAttr ($motionPath[0] + ".uValue")`;
            if ($uValue == 0)
            {
                setAttr ($motionPath[0] + ".uValue") 1;        
            }
    
            if ($uValue == 1)
            {
                setAttr ($motionPath[0] + ".uValue") 0;   
            }
            print "Not the same;";
        }
0 Likes
Message 29 of 30

malcolm_341
Collaborator
Collaborator

Oh does the point on curve make it zero or one always rather than part of the curve length?

0 Likes
Message 30 of 30

mcw0
Advisor
Advisor

If you'll note on the curve that was converted from an edge, the minMaxRange is 0:1.  So it's either at the start of the curve or at the end that the locator will be at the desired vertex.  And float values are tricky.  When checking to see which end of the curve you want, just get the minimum distance between the locator and the 2 vertices.  The larger distance will obviously be the wrong vertex.