PDA

View Full Version : Grid


qkuotidian
01-04-2011, 09:53 AM
Hi,
I want to create a grid based on subdivided poly plane. At each vertex should be placed one locator. The problem is Ė I cannot force this grid to update when I change subdivisionsWidth or subdivisionsHeight attributes of underlying plane. Donít understand how to connect these attributes so that they would affect locator count and position.
Here's what Iíve got:


polyPlane -axis 0 0 1 -height 10 -width 10
-subdivisionsHeight 10 -subdivisionsWidth 10;
int $VertCount[]= `polyEvaluate -vertex pPlane1`;

int $i;
for ($i=0; $i < $VertCount[0]; $i=$i+1)
{
float $position[] = `xform -q -worldSpace -translation pPlane1.vtx[$i]`;
spaceLocator -position $position[0] $position[1] $position[2];
int $num=$i+1;
connectAttr -force pPlane1.vtx[$i] ("locator"+$num+".translate") ;
}

NaughtyNathan
01-04-2011, 03:19 PM
you can't connect those attributes to anything because you are going to have to create and destroy new nodes, so you don't have attributes to connect.

Possibly the simplest way to do this would be to write a standalone function that generates the array of locators from a given plane hitsory node (similar to what you've already got) and then simply attach it to one of the plane node attributes using the scriptJob -attributeChanged flag.

:nathaN

qkuotidian
01-04-2011, 04:41 PM
NaughtyNathan, thanks for reply.
Frankly, I have a very dim idea of how that can be translated in mel.
I read about scriptJob and got this non-working rubbish.


proc grid( int $subH, int $subW)
{
polyPlane -axis 0 0 1 -height 10 -width 10
-subdivisionsHeight $subH -subdivisionsWidth $subW;
int $VertCount[]= `polyEvaluate -vertex pPlane1`;

int $i;
for ($i=0; $i < $VertCount[0]; $i=$i+1)
{
float $position[] = `xform -q -worldSpace -translation pPlane1.vtx[$i]`;
spaceLocator -position $position[0] $position[1] $position[2];
int $num=$i+1;
connectAttr -force pPlane1.vtx[$i] ("locator"+$num+".translate") ;
}
}
grid (20,10);

scriptJob -ac polyPlane1.subdivisionsWidth grid;
scriptJob -ac polyPlane1.subdivisionsHeight grid;


Iíd be most grateful if you'll show me how to translate it in working code.

pixelranger
01-05-2011, 04:27 AM
Here's a script you can try.
It creates a plane (if no plane is already selected) and creates a locator for every vertex.
Then it creates an expression to control the position of the locators (one expression for all of them).
And last, it creates a scriptNode containing the vertex count monitoring scriptJobs
and the procedure for re-creating the locators.
Be aware that this might cause trouble if you're planning on using the locators for anything, as they are
deleted and re-created.
It is possible to work around, though, but the smartest way of doing it depends on what exactly you're planning on using the locators for.

// Get current selection enabling running this script on a pre made polyPlane
//
string $sel[] = `ls -sl`;
string $plane[] = {};
string $polyPlane[] = {};
string $allLocs[] = {};
string $allExpressions[] = {};

// If nothing is selected, create a plane
//
if (`size($sel)` > 0){
if (`size($sel)` > 1){
warning "only works with one object. Using first selection ONLY.\n";
}

// Determine if the selection is a plane and if so, find the polyPlane node
//
string $shapes[] = `listRelatives -s $sel[0]`;
if ( nodeType($shapes[0]) == "mesh"){
$polyPlane = `listConnections -t "polyPlane" $shapes[0]`;

// If it didn't find a polyPlane node (if the selected plane's history had been deleted)
//
if (!`size($polyPlane)`){
print "No polyPlane node was found. Creating a new plane.\n";
$plane = `polyPlane -axis 0 0 1 -height 10 -width 10 -subdivisionsHeight 10 -subdivisionsWidth 10 -n "locCtrlPlane"`;
$polyPlane[0] = $plane[1];
}else{
// polyPlane node was found which means that $sel[0] is a plane
//
$plane[0] = $sel[0];
}
}
}else{
$plane = `polyPlane -axis 0 0 1 -height 10 -width 10 -subdivisionsHeight 10 -subdivisionsWidth 10 -n "locCtrlPlane"`;
$polyPlane[0] = $plane[1];
}

int $VertCount[]= `polyEvaluate -vertex $plane[0]`;

string $group = `group -em -n "locGroup"`;

for ( $i=0; $i < $VertCount[0]; $i++){
string $loc[] = `spaceLocator -position 0 0 0`;
parent -r $loc[0] $group;
$allLocs[size($allLocs)] = $loc[0];
}

string $expr = `createNode expression -n "locPosUpdateExpr"`;
string $exprValue = "";
int $i=0;
for ($locator in $allLocs){
$exprValue = $exprValue + ("float $pos[] =`xform -q -ws -t " + $plane[0] + ".vtx[" + $i + "]`;\n" + $locator + ".translateX = $pos[0];\n" + $locator + ".translateY = $pos[1];\n" + $locator + ".translateZ = $pos[2];\n\n") ;
$i++;
}
expression -e -s $exprValue -o $group -ae 1 -uc all $expr;

string $scriptNode = `scriptNode -beforeScript "global proc string getLocatorUpdateProcScriptNode(){\n\tstring $scripts[] = `ls -type \"script\"`;\n\tfor ($script in $scripts) {\n\t\tif (`attributeQuery -node $script -ex \"group\"`) {\n\t\t\treturn $script;\n\t\t}\n\t}\n}\n\nglobal proc updateLocCount(){\n\tstring $script = `getLocatorUpdateProcScriptNode`;\n\tstring $polyPlane[] = `listConnections ($script + \".polyPlane\")`;\n\tstring $plane[] = `listConnections ($script + \".plane\")`;\n\tstring $groups[] = `listConnections ($script + \".group\")`;\n\tstring $exprs[] = `listConnections ($script + \".expr\")`;\n\n\t// Cleanup: delete the old locators and expression\n\t//\n\tselect -r $groups[0];\n\tdoDelete;\n\tselect -r $exprs[0];\n\tdoDelete;\n\t\n\t//Now, create new stuff\n\t//\n\tstring $allLocs[] = {};\n\tstring $group = `group -em -n \"locGroup\"`;\n\tint $VertCount[]= `polyEvaluate -vertex $plane[0]`;\n\n\tfor ( $i=0; $i < $VertCount[0]; $i=$i+1){\n\t\tstring $loc[] = `spaceLocator -position 0 0 0`;\n\t\n\t\tparent -r $loc[0] $group;\n\t\t\n\t\t$allLocs[size($allLocs)] = $loc[0];\n\t}\n\t\n\t$expr = `createNode expression -n \"locPosUpdateExpr\"`; \n\tstring $exprValue = \"\";\n\tint $vtx = 0;\n\tfor ( $locator in $allLocs){\n\t\t$exprValue = $exprValue + (\"float $pos[] =`xform -q -ws -t \" + $plane[0] + \".vtx[\" + $vtx + \"]`;\\n\" + $locator + \".translateX = $pos[0];\\n\" + $locator + \".translateY = $pos[1];\\n\" + $locator + \".translateZ = $pos[2];\\n\\n\") ;\n\t\t$vtx++;\n\t}\n\texpression -e -s $exprValue -o $group -ae 1 -uc all $expr;\n\t\n\tconnectAttr -f ($group + \".message\") ($script + \".group\");\n\tconnectAttr -f ($expr + \".message\") ($script + \".expr\");\n}\n\nglobal int $jobNum = 0;\n$jobNum = `scriptJob -ac ($polyPlane[0] + \".subdivisionsWidth\") \"updateLocCount\"`;\n$jobNum = `scriptJob -ac ($polyPlane[0] + \".subdivisionsHeight\") \"updateLocCount\"`;" -st 1 -n "locatorUpdateProcScriptNode"`;

select -r $scriptNode ;
addAttr -ln "group" -at "message" ;
addAttr -ln "polyPlane" -at "message" ;
addAttr -ln "plane" -at "message" ;
addAttr -ln "expr" -at "message" ;

connectAttr -f ($group + ".message") ($scriptNode + ".group");
connectAttr -f ($polyPlane[0] + ".message") ($scriptNode + ".polyPlane");
connectAttr -f ($plane[0] + ".message") ($scriptNode + ".plane");
connectAttr -f ($expr + ".message") ($scriptNode + ".expr");

scriptNode -eb $scriptNode;
select -r $plane[0];

edit: You could also create a scriptJob for automatically updating the locator positions (monitoring the plane's transform attributes, the polyPlane node's width/height attributes or any attribute influencing the plane's vertices' world position), eliminating the need for the extra step of changing the current frame (that triggers the expression).
But that would slow the setup down quite a bit, as the scriptJobs are generally slow...

CGTalk Moderation
01-05-2011, 04:27 AM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.