Author : jdvi


Reply
Reply
 
Thread Tools Display Modes
onionhead_o's Avatar
Old (#1)
Is it possible to create a simple script to make all selected vertices to snap to closest locators. I'm still new to mel scripting. any help is appreciated.
Offline , polygon, 695 Posts, Join Date Mar 2008, Location canada  
   Reply With Quote

onionhead_o's Avatar
Old (#2)
Forgot to include a image. my bad

here it is



what im trying to achieve is have all the selected vertices snap to nearby locators. Im assuming with xform or getAttr to retrieve the location of the locator and then test closest distance. But I have no idea how to do it with more then 2 objects.
Offline , polygon, 695 Posts, Join Date Mar 2008, Location canada  
   Reply With Quote

passerby's Avatar
Old (#3)
making a loop to snap to locaters per vert is pretty easy, the part im not sure about would be figuring out what locater is the closest the vertex.
Offline , card carrying polycounter, 2,236 Posts, Join Date Nov 2010, Location Halifax, NS, Canada  
   Reply With Quote

Drachis's Avatar
Old (#4)
I think you could make it happen by setting up a loop that checks each vertex against all the locators and then moves that vertex to the closest locator. My MEL is a bit rusty at the moment so I'm not going to hash together pseudocode till I get home.
Portfolio ; Logic^-1
// Life is just more fun that way
Offline , line, 96 Posts, Join Date Sep 2008,  
   Reply With Quote

haiddasalami's Avatar
Old (#5)
Pseudo code would be

Code:
locators = xform all locators
for vert in selectedVertices
    vertloc = xform vert, world space
    for int i = 0; i < size of locator array; i++
        locatorLOC = xform locator world space
        distanceTEMP = distance between locator(using locatorLOC and vert (vertloc)
        //First run so store the first distance
        if (i == 0)
            distance = distanceTEMP
            locator = locator[i]
        if distanceTEMP < distance
            distance = distanceTEMP
            locator = locator[i]
    //Eventually you'll get the closest distance and the appropriate locator
    move vert to locator
That should be the most straight forward method. I can try and write it up tomorrow in code if you're stuck on something.

Last edited by haiddasalami; 08-06-2012 at 05:22 PM..
WebGL Project - In a state of constant flux so might be down when you check it. Pretty old now.
Junior Technical Artist at Digital Extremes.
Offline , dedicated polycounter, 1,856 Posts, Join Date Nov 2009, Location Toronto  
   Reply With Quote

Drachis's Avatar
Old (#6)
that looks pretty clean
Portfolio ; Logic^-1
// Life is just more fun that way
Offline , line, 96 Posts, Join Date Sep 2008,  
   Reply With Quote

onionhead_o's Avatar
Old (#7)
haiddasalami: thanks man, you're a saviour. couldn't find anything close to this on google at all. Kinda still trying to understand your pseudo code tho. Im stuck on i++. what does that do? sry for being noob at coding
Offline , polygon, 695 Posts, Join Date Mar 2008, Location canada  
   Reply With Quote

haiddasalami's Avatar
Old (#8)
The i++ is a counter that increases so at the start its 0 and once it goes through one iteration of the loop it increases so we can iterate through an array. Hopefully I explained that well. Ill try and post some real code real soon. Also just noticed some errors I didnt catch like at the start you should be using the ls command to get all the locators.

Last edited by haiddasalami; 08-07-2012 at 06:47 AM..
WebGL Project - In a state of constant flux so might be down when you check it. Pretty old now.
Junior Technical Artist at Digital Extremes.
Offline , dedicated polycounter, 1,856 Posts, Join Date Nov 2009, Location Toronto  
   Reply With Quote

PolyHertz's Avatar
Old (#9)
It's also where C++ gets its name from ;)
(V) (;,,;) (V) woopwoopwoopwoop
Offline , dedicated polycounter, 1,678 Posts, Join Date Aug 2006, Location Minnesota Send a message via AIM to PolyHertz  
   Reply With Quote

marks's Avatar
Old (#10)
Yeah thats what I was gonna suggest.

By subtracting the vert position from the locator position, you get a vector. There should then be a length() function to determine the length of the vector. Loop that to find the shortest vector and that gives you the closest locator to the vert. Rinse and repeat.
www.marksneddon.net
Technical Artist
Offline , triangle, 485 Posts, Join Date May 2008, Location Brighton, UK  
   Reply With Quote

haiddasalami's Avatar
Old (#11)
Python:
Code:
import maya.cmds as cmds
import math
import sys

def closestVerticeToLoc():
    locators = cmds.listRelatives( cmds.ls(type="locator"), parent=True)
    
    try:
        selection = cmds.filterExpand(selectionMask =31)
        if len(selection) > 0:
            for vertice in selection:
                vertWS = cmds.xform(vertice, query=True, ws = True, t=True)
                for i in range(len(locators)):
                    locatorWS = cmds.xform(locators[i], query=True, ws=True, t=True)
                    distanceTEMP = distanceFUNC(vertWS[0],vertWS[1],vertWS[2],locatorWS[0],locatorWS[1],locatorWS[2])
            
                    if i == 0:
                        distance = distanceTEMP
                        closestLocator = locators[i] 
            
                    if distanceTEMP < distance: 
                        distance = distanceTEMP
                        closestLocator = locators[i]
    
            closestLocatorWS = cmds.xform(closestLocator, query=True, ws=True, t=True)
            cmds.move(closestLocatorWS[0],closestLocatorWS[1],closestLocatorWS[2],vertice, absolute=True)
    except:
        print "Please select vertices"
        
def distanceFUNC(x1,y1,z1, x2, y2, z2):
    return math.sqrt( (x1-x2) * (x1-x2) + (y1 - y2) * (y1 - y2) + (z1-z2) * (z1-z2))
    
closestVerticeToLoc()
To launch, just copy and paste into a python tab in the script editor window highlight all and drag to your shelf as button. Or you can save as closestVerticeToLoc.py put into Maya scripts and run using

import closestVerticeToLoc
reload(closestVerticeToLoc)

MEL:
Code:
global proc closestVerticeToLoc()
{
    string $selection[] = `filterExpand -sm 31`;
    if (size($selection)<1){
        warning("Nothing is selected");
    }
    select (listRelatives("-parent",`ls -type "locator"`));
    string $locators[] = `ls -selection`;
    select $selection;
    float $distance;
    string $closestLocator;
    for ($vertice in $selection) {
        vector $vertWS = `xform -query -worldSpace -translation $vertice`;
        int $i;
        for ($i=0; $i<`size($locators)`; $i++)
        {
           vector $locatorWS = `xform -query -worldSpace -translation $locators[$i]`;
           float $distanceTEMP = distanceFunc($vertWS.x,$vertWS.y,$vertWS.z,$locatorWS.x,$locatorWS.y,$locatorWS.z);
           if ($i == 0){
               $distance = $distanceTEMP;
               $closestLocator = $locators[$i];
           }
           
           if ($distanceTEMP < $distance){
               $distance = $distanceTEMP;
               $closestLocator = $locators[$i];
           } 
        }
        vector $closestLocatorWS = `xform -query -worldSpace -translation $closestLocator`;
        move -absolute ($closestLocatorWS.x) ($closestLocatorWS.y) ($closestLocatorWS.z) $vertice;
    } 
    
}

global proc float distanceFunc(float $x1, float $y1,float $z1,float $x2,float $y2,float $z2){
    return sqrt( ($x1-$x2) * ($x1-$x2) + ($y1 - $y2) * ($y1 - $y2) + ($z1-$z2) * ($z1-$z2) );
}

closestVerticeToLoc();
Probably comment this later for better understanding. Also feel free to take this and expand on it. For example right now there is no checking if there are locators or not.

Last edited by haiddasalami; 08-07-2012 at 02:24 PM..
WebGL Project - In a state of constant flux so might be down when you check it. Pretty old now.
Junior Technical Artist at Digital Extremes.
Offline , dedicated polycounter, 1,856 Posts, Join Date Nov 2009, Location Toronto  
   Reply With Quote

Denny's Avatar
Old (#12)
I suggest using

//Mel
string $vertices[] = `filterExpand -sm 31`;

for querying the selected vertices instead. You never know if the user might select something else which should not be selected for the script. filterExpand 31 ensures you get only selected vertices, see the docs for which number is used for other components.
Offline , spline, 129 Posts, Join Date Sep 2007, Location Europe  
   Reply With Quote

haiddasalami's Avatar
Old (#13)
hey Denny, yeah I caught that while converting the code to mel. Anywho updated the post with both mel and python.
WebGL Project - In a state of constant flux so might be down when you check it. Pretty old now.
Junior Technical Artist at Digital Extremes.
Offline , dedicated polycounter, 1,856 Posts, Join Date Nov 2009, Location Toronto  
   Reply With Quote

onionhead_o's Avatar
Old (#14)
Thanks a lot for everybodys help on this. The script works perfectly.

But now i run into another problem. First I must explain the purpose for requesting this script.


This is part of the main Script Im trying to write which is Quad fill (imitating Quad-cap max plugin by obliviboy). So far Ive been sampling many mel scripts to make this work since, I am a noob at mel. I know this is a complicated thing to do for a beginner.

Heres my Idea or concept for making the Quad Fill work. Feel free to comment and critique:

1)Get edge selection of the hole that needs to be filled
2)Create locators to store the xyz location of the vertices on the border. Which will later be used to snap the quad plane back to Main mesh.

This method might be too inefficient, but its the only way I can think of. Since I have no idea how to create a script that knows how to divide the Ngon into quads.

3)Test if the edges are even. reason being that solving quads need even edges.
Code:
global proc testEven () 
{
	int $edgeNum = `polyEvaluate -edge`;

	if ($edgeNum % 2 == 0)
	{
	checkEqualedge;
	}
4)checkEqualedge is to test if edges can be evenly distributed on 4 sides. Mainly is to store the Subdivisions of the width and height required to create the quad plane.

Code:
global proc checkEqualedge ()
{
	
	int $fmodNum =`fmod($edgeNum,4)`
	int $wholeNum =`$edgeNum[0] / 4`
	int $remainder;
	float $roundNum;`floor($edgeNum/4)`
	
	
	if ($fmodNum == 0)
	{
		$SubDH = $WholeNum //SubDH is Subdivision Height
		$SubDW = $WholeNum ////SubDH is Subdivision Width
	}

	else
	{
		$SubDH = $roundNum + 1
		$SubDW = $roundNum
	}
}
5) Get the rotation axis of the edge selection.

The following code I found off of this site http://xyz2.net/mel/mel.005.htm
Not sure how to get this to work. always run into invalid syntax#

Code:
proc vector translatePolyInfoNormal( string $pin )
{
  vector $normal;
  float $x;
  float $y;
  float $z;

  string $tokens[];
  int $numTokens = `tokenize $pin " " $tokens`;

  // Make sure we're looking at polyInfo data:
  if ( ( $numTokens > 3 ) && ( $tokens[0] == "FACE_NORMAL" ) )
  {
    // Maya performs data-type conversion here.
    $x = ($tokens[$numTokens-3]);
    $y = ($tokens[$numTokens-2]);
    $z = ($tokens[$numTokens-1]);

    $normal = << $x, $y, $z >>;

    // Normalize it.
    $normal = `unit $normal`;
  }

  // Return it.
  return $normal;
}

string $FaceInfo[0] = `polyInfo -fn pPlane6.f[0]`;

vector $FaceNormal = translatePolyInfoNormal( $FaceInfo[0]);
I need this code to get the values neccessary to move the Quad plane back to the original mesh that needed to be capped.

6)snap the border of the Quad plane to the Main Mesh with closestVerticeToLoc created by haiddasalami

7)Combine both Meshs and call it a day.

Hope this is not too confusing or long to read.
Offline , polygon, 695 Posts, Join Date Mar 2008, Location canada  
   Reply With Quote

TeZzy's Avatar
Old (#15)
Hey onionhead, any progress on the quad cap script that you are working on. Been looking for something like this for a while.
Offline , vertex, 44 Posts, Join Date Oct 2009, Location Auckland, NZ  
   Reply With Quote

onionhead_o's Avatar
Old (#16)
ive been stuck on some of the coding unfortunately.

I think someone beat me to quad script.

(Video Demo) wait till the asian ads finish..
http://v.youku.com/v_show/id_XMTc0Nj...html?f=4488599

Script page
http://www.creativecrash.com/maya/do...-2012-2013---2

Last edited by onionhead_o; 03-07-2013 at 06:59 PM..
Offline , polygon, 695 Posts, Join Date Mar 2008, Location canada  
   Reply With Quote

Saf's Avatar
Old (#17)
Please finish Quad fill script. I use ZhCG_PolyTools only because of this. But in Maya 2014, Python 2.7.3 is not compatible with ZhCG_PolyTools.
Offline , null, 9 Posts, Join Date Nov 2011, Location Russia, Moscow  
   Reply With Quote

onionhead_o's Avatar
Old (#18)
i appreciate your interest and support for this script. But i cannot guarantee that the finish version will work with maya 2014, as I dont have it yet.
Offline , polygon, 695 Posts, Join Date Mar 2008, Location canada  
   Reply With Quote

passerby's Avatar
Old (#19)
most code built on python 2.6.4 which is what previous versions of maya uses, will work on 2.7.3 which contains mostly minar changes to python Saf.

it is 2.x to 3.x that you got to watch out for in python, which is why a lot of people never moved away from 2.x.

Also if the upgrade to 2014 breaks parts of your workflow, why upgrade right away?

Last edited by passerby; 04-02-2013 at 02:11 PM..
Offline , card carrying polycounter, 2,236 Posts, Join Date Nov 2010, Location Halifax, NS, Canada  
   Reply With Quote

Saf's Avatar
Old (#20)
Yes, most scripts will work. But only if they are not the compiled.
I do not upgrade to 2014 version, just looked trial.
Quad fill a very cool thing. I just thought it would be nice to have a clean Quad fill script, not compiled ZhCG version.

Here the idea may come in handy:

Offline , null, 9 Posts, Join Date Nov 2011, Location Russia, Moscow  
   Reply With Quote

passerby's Avatar
Old (#21)
ah he was being stupid and distributed as pyc? instead of the py files?
Offline , card carrying polycounter, 2,236 Posts, Join Date Nov 2010, Location Halifax, NS, Canada  
   Reply With Quote

Saf's Avatar
Old (#22)
I upgraded to the 2014 version had to decompile .pyc. Somehow all even works. http://www.creativecrash.com/maya/do...maya-2012-2014
Offline , null, 9 Posts, Join Date Nov 2011, Location Russia, Moscow  
   Reply With Quote

rebb's Avatar
Old (#23)
Did you contact the original author and ask him if he's ok with you decompiling his code and making it publically available ?

I doubt people release .pyc plugins out of "stupidity", but because they are trying to protect their code ( which PYC isn't great for, as this example shows ).
Offline , triangle, 372 Posts, Join Date Jul 2006,  
   Reply With Quote

Saf's Avatar
Old (#24)
yes tried many times, but the author is gone from 2011
Offline , null, 9 Posts, Join Date Nov 2011, Location Russia, Moscow  
   Reply With Quote

Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

Copyright 1998-2012 A. Risch