Difference between revisions of "Hexbased CA ScriptKokkugia"
From scripting
(Created page with "http://www.kokkugia.com/wiki/scriptLibrary/mel/CA_Script.mel https://webbeta.archive.org/web/20100401000000*/http://www.kokkugia.com/wiki/scriptLibrary/mel/CA_Script.mel...") 
(No difference)

Latest revision as of 20:33, 24 April 2017
http://www.kokkugia.com/wiki/scriptLibrary/mel/CA_Script.mel
/* this series of scripts creates a hexgrid cellular automaton and a springs net which can be driven by the 'brains' of the cellular automaton. these two things were created in order to then act as an input for the distortion of far more complex geometries in the formation of a facade or screen wall element. created by roland snooks and dave pigram fall 2005 (parts of the code use the logic of cory clarke's  life.mel  nthd.org) this version last modified: 28 october 2005 procedures: there are four main procedures which can be run independantly. each of these main procedures calls a second series of procedures shown indented below (a full description of all procedures follws):  hexCA_create  hexCA_run  hexCA_check  life_keyframe  hexCA_status  springCA_create  springCA_attach  hex_associate example of appropriate inputs: hexCA_create 20 10 1 30; (int $xSize, int $ySize, float $hexSize, float $randCut) hexCA_run 20 10 20 1; (int $xSize, int $ySize, int $steps, int $proliferate) springCA_create 20 10 1; (int $xSize, int $ySize, float $hexSize) hex_associate 0.08; (float $scale) description of input variables: $xSize = the number of hexagons in the xaxis numbered left to right $ySize = the number of hexagons in the yaxis numbered top to bottom $hexSize = the shortest distance from edge to edge of the chosen hexagon size $randCut = the percentage (as an integer between 1 and 100) of the hexgrid that starts at full size (the remainding cells start at the minimum size) $proliferate = 0 or 1 switches between modes of proliferation (of copies of generations): 0 = no proliferation (any other integer besides 1 will also result in no proliferation) 1 = proliferation in a stack along the z axis (perpendicular to the 2 CA dimensions x and y) $scale = a scale factor to tune the spring length inputs of the hex_associate procedure to the particular characteristics of the springs net full descriptions of all procedures:  hexCA_create creates a hexgrid $xSize by $ySize with each hexagon $hexSize wide and numbers all the cells logically. an initial state is also generated by randomly switching a percentage ($randCut) of cells to the maximum size. this procedure must be run before the hexCA_run or the life_keyframe, or else these procedures will have no meaning.  hexCA_run as the name indicates, this procedure uses a predetermined ruleset to calculate and represent future generational states for the the hexgrid (from its initial state) generated by the hexCA_create procedure. for each hexcell in turn this procedure calls the hexCA_check procedure which checks the size of all adjacent cells (its 'neigbours'  including itself) the average size is returned and then compared against a series of axiomatic conditions. if the average of the result is too high the cell 'dies' due to 'overcrowding'; if it is too low the cell 'dies' of 'loneliness'. in this case 'dying' means becoming zero scale, there is nothing to prevent the cell being 'reborn' in a future generation. if the cell survives the initial culling process it then adopts the average size of its neighbours and itself. all calculations are done on a pergeneration basis i.e the calcualtions for all cells are completed before any size changes are made, then the process is repeated after all scaling is complete. lastly, as the above described system has a tendency towards an even distribution of middlesized cells, an additional 'switch' has been added as a means of reinjecting 'energy' or disequilibrium into the system. when the average size of a hexcells neighbours approaches the middle of the possible range that cell is either given a maximum or minimum scale in the next generation. if the avaerage is slightly less than the middle the cell gets a maximum size; when the average is slightly higher it receives a minimum scale.  hexCA_check as described above this procedure is called by the hexCArun procedure, with the average of all neighbouring cell sizes returned (becoming $tmp) to the the hexCA_run script.  life_keyframe this procedure is also called by the hexCArun procedure, it adds keyframes so that the CA can be watched changing states as an animation. the keyframes occur at set intervals and represent each complete generation. the set interval between keyfames is equal to the $frameNoPerCalc variable which can be found at the beginning of the hexCA_run procedure.  hexCA_status a very simple procedure which literally returns the value of the .status attribute for a particular hexcell when called by the hexCA_run procedure.  springCA_create this procedure creates a cube on every node of an $xSize x $ySize hexgrid. each cube is named according to the adjacent hexcells from top to bottom and from left to right. the hexcells are also named from top to bottom and from left to right in the form: hex_$y_$x where $y is the row number and $x is the cell number within that row. example: the cube named: "cube1_1__1_2__2_1" is between heccells: "hex_1_1" , "hex_1_2" and "hex_2_1"  springCA_attach this procedure is called by the springCA_create procedure and attaches springs to cubes that represent each vertex of a $xSize x $ySize hexgrid the cubes are created by the springCA_create script  the inputs are $xSize and $ySize. for every spring a line is drawn in the same place for later use in diagrams and animations.  hex_associate this procedure calculates the average scale of the two hexes which are adjacent to all internal springs and then uses this value to set that springs rest length. when the simulation is played the springs attempt to find the new equilibrium state for network thus distorting the previously regular hexgrid geometry. through experience this operation is most successful when the cubes on the outside edge of the springs net are set to active = 0 (off). note: the programming style adopted priveledges readablility and maintainability rather than pure code efficiency this approach was selected both because the script is being created and edited by two people and because the intention is that certain sections of code can be cut out as modules for use in future projects. */ //____________________________________________________________________________________________________________________ global proc hexCA_create (int $xSize, int $ySize, float $hexSize, float $randCut){ // if uncommented these lines select and delete all objects and keyframes remaining from previous iterations /* select all; delete; */ //loop for each cell row following $ySize int $y = 0; while ($y < $ySize){ //loop for each cell column following $xSize int $x = 0; while ($x < $xSize){ // set up values for moving each created hexgrid object to its correct place in the hexgrid // a check of oddness, fascilitates the staggering of every second row to the right // $stagger will equal zero for the even rows, and half $hexSize for the odd rows int $isOdd = $y%2; float $stagger = $isOdd * $hexSize/2; float $moveX = $x*$hexSize + $stagger; float $moveY = $y*$hexSize*cosd(30); //create a unique name for each object that refers to its position $name = "hex_" + $y + "_" + $x; //create the object, give it the unique name and then move it into position float $radius = abs(($hexSize/2)/cosd(30)); $tmp = `circle n $name c 0 0 0 nr 0 0 1 sw 360 r $radius d 1 ut 0 tol 0.1 s 6 ch 1`; move $moveX $moveY 0; // add custom attributes that will store information about the hexgrid object addAttr ln status at double $name; addAttr ln oncount at double $name; // the following section of code was used to connect the CA to different geometry based on clusters earlier // in the project  it remains (commented out) to facilitate a possible renewal of the exploration into that // type of geometry // set driven keys  assign the scale of the hex cell to the scale of the clusters /* setAttr ($name + ".scaleX") 1; setAttr ("cluster_" + $y + "_" + $x + ".scaleX") 1; setAttr ("cluster_" + $y + "_" + $x + ".scaleY") 1; setAttr ("cluster_" + $y + "_" + $x + ".scaleZ") 1; setDrivenKeyframe cd ($name + ".scaleX") ("cluster_" + $y + "_" + $x + ".scaleX"); setDrivenKeyframe cd ($name + ".scaleX") ("cluster_" + $y + "_" + $x + ".scaleY"); setDrivenKeyframe cd ($name + ".scaleX") ("cluster_" + $y + "_" + $x + ".scaleZ"); setAttr ($name + ".scaleX") 0; setAttr ("cluster_" + $y + "_" + $x + ".scaleX") 0; setAttr ("cluster_" + $y + "_" + $x + ".scaleY") 0; setAttr ("cluster_" + $y + "_" + $x + ".scaleZ") 0; setDrivenKeyframe cd ($name + ".scaleX") ("cluster_" + $y + "_" + $x + ".scaleX"); setDrivenKeyframe cd ($name + ".scaleX") ("cluster_" + $y + "_" + $x + ".scaleY"); setDrivenKeyframe cd ($name + ".scaleX") ("cluster_" + $y + "_" + $x + ".scaleZ"); */ //randomly turn some on $random = rand(0,100); if($random < $randCut) { //setAttr ($tmp[0] + ".visibility") on; setAttr ($tmp[0] + ".status") 1; setAttr ($tmp[0] + ".scale") 1 1 1; setAttr ($tmp[0] + ".oncount") 1; setKeyframe ($tmp[0] + ".scale"); setKeyframe ($tmp[0] + ".status"); }else{ //setAttr ($tmp[0] + ".visibility") off; setAttr ($tmp[0] + ".status") 0; setAttr ($tmp[0] + ".scale") 0 0 0; setAttr ($tmp[0] + ".oncount") 0; setKeyframe ($tmp[0] + ".scale"); setKeyframe ($tmp[0] + ".status"); } $x++; } $y++; } //keyframe all at 0 currentTime 0; //life_keyframe(); } print("hexCA_create loaded ..... Enjoy!\n"); ; //____________________________________________________________________________________________________________________ global proc hexCA_run(int $xSize, int $ySize, int $steps, int $proliferate){ int $step = 1; float $maxoncount = 1.0; int $frameNoPerCalc = 20; while($step < $steps){ //check each box and store in list to turn on or off int $x; int $y; int $check; string $onarray[]; string $offarray[]; string $onset; string $offset; select cl; $onset = `sets`; select cl; $offset = `sets`; $y =0; while($y < $ySize){ $x = 0; while($x < $xSize){ // this is where the axioms of the cellular automata appear and determine the behaviour of the system // the first rule determines if the cell being checked is 'lonely' float $tmp = hexCA_check($x,$y,$xSize,$ySize); print("this is the temp" + $tmp + "!"); if($tmp > 0 && $tmp < 0.45){ $string = "hex_" + $y + "_" + $x; print("on " + $string); sets add $onset $string; setAttr ("hex_" + $y + "_" + $x + ".status") $tmp; setAttr ("hex_" + $y + "_" + $x + ".scale") $tmp $tmp $tmp; setKeyframe ("hex_" + $y + "_" + $x + ".scale"); setKeyframe ("hex_" + $y + "_" + $x + ".status"); } else if ($tmp >= 0.45 && $tmp < 0.55){ $string = "hex_" + $y + "_" + $x; print("middle " + $string); sets add $onset $string; setAttr ("hex_" + $y + "_" + $x + ".status") 1; setAttr ("hex_" + $y + "_" + $x + ".scale") 1 1 1; setKeyframe ("hex_" + $y + "_" + $x + ".scale") ; setKeyframe ("hex_" + $y + "_" + $x + ".status"); } else if ($tmp >= 0.55 && $tmp < 0.65){ $string = "hex_" + $y + "_" + $x; sets add $offset $string; setAttr ("hex_" + $y + "_" + $x + ".status") 0; setAttr ("hex_" + $y + "_" + $x + ".scale") 0 0 0; setKeyframe ("hex_" + $y + "_" + $x + ".scale") ; setKeyframe ("hex_" + $y + "_" + $x + ".status"); } else if ($tmp >= 0.65 && $tmp <= 0.9){ $string = "hex_" + $y + "_" + $x; print("on " + $string); sets add $onset $string; setAttr ("hex_" + $y + "_" + $x + ".status") $tmp; setAttr ("hex_" + $y + "_" + $x + ".scale") $tmp $tmp $tmp; setKeyframe ("hex_" + $y + "_" + $x + ".scale") ; setKeyframe ("hex_" + $y + "_" + $x + ".status"); }else{ $string = "hex_" + $y + "_" + $x; sets add $offset $string; setAttr ("hex_" + $y + "_" + $x + ".status") 0; setAttr ("hex_" + $y + "_" + $x + ".scale") 0 0 0; setKeyframe ("hex_" + $y + "_" + $x + ".scale") ; setKeyframe ("hex_" + $y + "_" + $x + ".status"); } $x++; } $y++; } $onarray = `sets q $onset`; $offarray = `sets q $offset`; print("Frame: " + ($step * 20) + "\n"); currentTime ($step * 20); // this part of the script creates copies of each state/generation that are then distributed as a // layered history of the life of the CA  or in order to be laser cut if (and only if) $proliferate // is set to 1 or 2 respectively. // check $proliferate state if($proliferate == 1  $proliferate == 12){ // first create a new group for each genaration ready to receive copies of each cell in that genearation string $genGroupName = "gen_" + $step; group n $genGroupName em; // loop to select each hexcell in turn, // then duplicate it and name its copy. // and then parent the copy to the group named according to its generation $y =0; while($y < $ySize){ $x = 0; while($x < $xSize){ string $hexCopyName = $genGroupName + "_hex_" + $y + "_" + $x; select ("hex_" + $y + "_" + $x); duplicate n $hexCopyName; parent $hexCopyName $genGroupName; $x++; } $y++; } // test which proliferation mode and move entire generation accordingly // first test is for direct proliferation of each generation along the zaxis if($proliferate == 1){ nurbsSquare c 9.6 4 2 nr 0 0 1 sl1 12 sl2 24 sps 1 d 3 ch 1 ; select add $genGroupName; move 0 0 (2*$step); } } $step++; } } //____________________________________________________________________________________________________________________ global proc life_keyframe(){ select all; $list = `ls sl tr`; $j = 0; while($j < size($list)){ setKeyframe ($list[$j] + ".v"); $j++; } } //____________________________________________________________________________________________________________________ global proc float hexCA_check(int $x, int $y,int $xSize, int $ySize){ float $total; float $lowerLimit = 0.1; float $upperLimit = 0.9; $plusx = (($x+1) % $xSize); if($x >= 1) $minusx = ($x1); if($x < 1) $minusx = ($xSize1); $plusy = (($y+1) % $ySize); if($y >= 1) $minusy = ($y1); if($y < 1) $minusy = ($ySize1); // calculate the neighbours of the hex cell $a = "hex_" + $minusy + "_" + $plusx; $b = "hex_" + $y + "_" + $plusx; $c = "hex_" + $plusy + "_" + $plusx; $d = "hex_" + $plusy + "_" + $x; $e = "hex_" + $y + "_" + $minusx; $f = "hex_" + $minusy + "_" + $x; $g = "hex_" + $y + "_" + $x; // rules for hex cell life // rule 01  based on how many neighbours are on or off float $total = (hexCA_status($a) + hexCA_status($b) + hexCA_status($c) + hexCA_status($d) + hexCA_status($e) + hexCA_status($f) + hexCA_status($g))/7; if($total > $lowerLimit && $total < $upperLimit){ //print("total" + ($total) + "\n"); return $total; }else{ return 0; } return 0; } //____________________________________________________________________________________________________________________ global proc float hexCA_status(string $hexCell){ // this global procedure returns the status of each hexcell float $v = `getAttr ($hexCell + ".status")`; return $v; } //__________________________________________________________________________________________________________________ global proc springCA_create (int $xSize, int $ySize, float $hexSize){ // if uncommented these lines select and delete all objects and keyframes remaining from previous iterations /* select all; delete; */ // loop for each cell row following $ySize (note that the cell rows referred to here are the hexcells // for this orientation of the hexcells (point up) there are actually four rows of cubes (which make // up the vertices of each hex) for each row of hexcells, but because two overlap, after the first row // of hexcells the rest have only two rows of cubes each int $y = 1; while ($y <= $ySize) { //int $modulor = $y%2; //print("row" + $y + //loop for each cell column following $xSize int $x = 1; while ($x <= $xSize + 1) { // create a cube for each vertex of the hex grid and name it according to the three adjacent hex_cells // trigonometry is used to calculate the movement of each cube relative to the entered $hexSize // calculate trigonometric values for movement float $adj = $hexSize * 0.5; float $hyp = $adj / (cosd(30)); float $opp = $adj * tand(30); // calculate a stagger value (again for movement) that includes a test and allowance for odd rows float $stagger = (($y+1)%2) * 0.5 * $hexSize; // set up naming variables  minus signs will be represented by an underscore // as spacers: "_" appears between y and x, and "__" appears between hexcell pairs string $cellRef = $y + "_" + $x; string $cellLeftRef = $y + "_" + ($x1); string $cellRightRef = $y + "_" + ($x+1); string $cellBelowLeftRef = ($y+1) + "_" + ($x1); string $cellBelowRightRef = ($y+1) + "_" + $x; string $cellAboveLeftRef = ($y1) + "_" + ($x1); string $cellAboveRightRef = ($y1) + "_" + $x; // the first two rows of cubes (occuring on hexcell row zero) have no neighbouring cells // above and so are created first as special cases // make the first 'special' row  there is one less cube in this row so exclude x = $xSize if ($y == 1 && $x != $xSize + 1){ string $cubeName = "cube" + $cellAboveLeftRef + "__" + $cellAboveRightRef + "__" + $cellRef; float $moveX = $x * $hexSize  $hexSize; float $moveY = $y * cosd(30) * $hexSize + $hyp + $hexSize; $tmp = `polyCube n $cubeName w .1 h .1 d .1`; move $moveX $moveY 0; print("first row" + $x + "\n"); } // make the second 'special' row if ($y == 1){ $cubeName = "cube" + $cellAboveLeftRef + "__" + $cellLeftRef + "__" + $cellRef; $moveX = ($x  0.5) * $hexSize  $hexSize; $moveY = $y * cosd(30) * $hexSize + $opp + $hexSize; $tmp = `polyCube n $cubeName w .1 h .1 d .1`; move $moveX $moveY 0; } // now that the 'special cases' of the first two rows are done, make the rest of the rows of cubes // make the first standard row // the if stagger > 0 statement establishes whether the row is odd and changes the name if necessary $cubeName = "cube" + $cellLeftRef + "__" + $cellRef + "__" + $cellBelowLeftRef; if ($stagger > 0){ print("row is even" + $y + "\n"); $cubeName = "cube" + $cellLeftRef + "__" + $cellRef + "__" + $cellBelowRightRef; } $moveX = ($x  0.5) * $hexSize + $stagger  $hexSize; $moveY = $y * cosd(30) * $hexSize  $opp + $hexSize; $tmp = `polyCube n $cubeName w .1 h .1 d .1`; move $moveX $moveY 0; // next make the second standard row of cubes // the if/else statement prevents the additional cube that would be created in the last row int $lastRow = ($ySize); if(($y == $lastRow) && ($x == 1)){ print ("skipping cube!\n"); }else{ $cubeName = "cube" + $cellRef + "__" + $cellBelowLeftRef + "__" + $cellBelowRightRef; if ($stagger > 0){ print("row is even" + $y + "\n"); $cubeName = "cube" + $cellLeftRef + "__" + $cellBelowLeftRef + "__" + $cellBelowRightRef; } $moveX = $x * $hexSize  $stagger  $hexSize; $moveY = $y * cosd(30) * $hexSize  $hyp + $hexSize; $tmp = `polyCube n $cubeName w .1 h .1 d .1`; move $moveX $moveY 0; } $x++; } $y++; } print ("springCA_create loaded ..... \n"); print ("\n"); print ("loading: springCA_attach .....\n"); print ("\n"); // call springCA_attach global procedure to attach springs to the cubes just created springCA_attach $xSize $ySize; } //__________________________________________________________________________________________________________________ global proc springCA_attach (int $xSize, int $ySize){ float $damping = 40; float $stiffness = 50; int $y = 1; while ($y <= $ySize) { //loop for each cell column following $xSize int $x = 1; while ($x <= $xSize+1) { // set up naming variables  minus signs will be represented by an underscore // as spacers: "_" appears between y and x, and "__" appears between hexcell pairs string $cellRef = $y + "_" + $x; string $cellLeftRef = $y + "_" + ($x1); string $cellRightRef = $y + "_" + ($x+1); string $cellBelowLeftRef = ($y+1) + "_" + ($x1); string $cellBelowRightRef = ($y+1) + "_" + $x; string $cellAboveLeftRef = ($y1) + "_" + ($x1); string $cellAboveRightRef = ($y1) + "_" + $x; string $cellBelowFarRightRef = ($y1) + "_" + ($x+1); int $oddness = $y%2; // the first row of springs has no neighbours above it and so is added first as a special case // attach first special row of springs to existing cubes // there are two springs per cell in the first special row so exclude last loop ($x = $xSize + 1) if ($y == 1 && $x != $xSize + 1){ // in each loop connect spring for top left side of hex until all springs are added for the row string $cube01 = "cube" + $cellAboveLeftRef + "__" + $cellLeftRef + "__" + $cellRef; string $cube02 = "cube" + $cellAboveLeftRef + "__" + $cellAboveRightRef + "__" + $cellRef; string $cube03 = "cube" + $cellAboveRightRef + "__" + $cellRef + "__" + $cellRightRef; string $springName01 = "spring_" + $cellAboveLeftRef + "__" + $cellRef; string $springName02 = "spring_" + $cellAboveRightRef + "__" + $cellRef; select r $cube01 $cube02; constrain spring st $stiffness d $damping i 0 n $springName01; // do the same for the top right side of each hex select r $cube02 $cube03; constrain spring st $stiffness d $damping i 0 n $springName02; } // now attach the first standard row of springs // they run vertically and there is one more spring than there are hexes in each row (loop $x = $xSize remains) // reference names following conventions for odd rows $cube01 = "cube" + $cellAboveLeftRef + "__" + $cellLeftRef + "__" + $cellRef; $cube02 = "cube" + $cellLeftRef + "__" + $cellRef + "__" + $cellBelowLeftRef; $springName01 = "spring_" + $cellLeftRef + "__" + $cellRef; // test if row is even and if so rename cube references so that the right cubes are joined by the springs if($oddness == 0){ $cube01 = "cube" + $cellAboveRightRef + "__" + $cellLeftRef + "__" + $cellRef; $cube02 = "cube" + $cellLeftRef + "__" + $cellRef + "__" + $cellBelowRightRef; } select r $cube01 $cube02; constrain spring st $stiffness d $damping i 0 n $springName01; // now attach the second standard row of springs // there are two springs per cell this row so again exclude last loop ($x = $xSize) if($x != $xSize + 1){ // references for cubes in odd rows $cube01 = "cube" + $cellLeftRef + "__" + $cellRef + "__" + $cellBelowLeftRef; $cube02 = "cube" + $cellRef + "__" + $cellBelowLeftRef + "__" + $cellBelowRightRef; $cube03 = "cube" + $cellRef + "__" + $cellRightRef + "__" + $cellBelowRightRef; $springName01 = "spring_" + $cellRef + "__" + $cellBelowLeftRef; $springName02 = "spring_" + $cellRef + "__" + $cellBelowRightRef; // test if row is even and if so rename cube references so that the right cubes are joined by the springs if($oddness == 0){ $cube01 = "cube" + $cellLeftRef + "__" + $cellRef + "__" + $cellBelowRightRef; $cube02 = "cube" + $cellRef + "__" + $cellBelowRightRef + "__" + ($y+1) + "_" + ($x+1); $cube03 = "cube" + $cellRef + "__" + $cellRightRef + "__" + ($y+1) + "_" + ($x+1); $springName01 = "spring_" + $cellRef + "__" + $cellBelowRightRef; $springName02 = "spring_" + $cellRef + "__" + $cellBelowFarRightRef; } select r $cube01 $cube02; constrain spring st $stiffness d $damping i 0 n $springName01; select r $cube02 $cube03; constrain spring st $stiffness d $damping i 0 n $springName02; } // there is one spring that is not added at either end depending on whether the row is even or odd // add this spring if($oddness == 1 && $x == $xSize + 1){ $cube01 = "cube" + $cellLeftRef + "__" + $cellRef + "__" + $cellBelowLeftRef; $cube02 = "cube" + $cellRef + "__" + $cellBelowLeftRef + "__" + $cellBelowRightRef; $springName01 = "spring_" + $cellRef + "__" + $cellBelowLeftRef; select r $cube01 $cube02; constrain spring st $stiffness d $damping i 0 n $springName01; } if($oddness == 0 && $x == 1 && $y != $ySize){ $cube01 = "cube" + $cellLeftRef + "__" + $cellBelowLeftRef + "__" + $cellBelowRightRef; $cube02 = "cube" + $cellLeftRef + "__" + $cellRef + "__" + $cellBelowRightRef; $springName01 = "spring_" + $cellLeftRef + "__" + $cellBelowRightRef; select r $cube01 $cube02; constrain spring st $stiffness d $damping i 0 n $springName01; } $x++; } $y++; } select r "cluster*"; group n allClusters; select r "curve*"; group n allCurves; print ("springCA_attach loaded ..... Enjoy!\n"); } //____________________________________________________________________________________________________________________ global proc hex_associate(float $scale){ // this procedure associates the scale of the adjacent hexes to the spring length int $numOfTokens; string $springName[]; string $springNameArray[]; float $hexScale01; float $hexScale02; float $hexValue; string $hex01; string $hex02; // get an array of the springs select r "spring*"; $springName = `ls sl`; print $springName; $i = 0; while( $i < size($springName)){ // tokenise $numOfTokens = tokenize ($springName[$i], "_", $springNameArray); print $springNameArray; // if it isn't on the edge then assign a rest length $hex01 = ("hex_" + $springNameArray[1] + "_" + $springNameArray[2]); $hex02 = ("hex_" + $springNameArray[3] + "_" + $springNameArray[4]); if(`objExists $hex01` && `objExists $hex02`){ // get hex scales $hexScale01 = `getAttr ("hex_" + $springNameArray[1] + "_" + $springNameArray[2] + ".scaleX")`; $hexScale02 = `getAttr ("hex_" + $springNameArray[3] + "_" + $springNameArray[4] + ".scaleX")`; $hexValue = ($scale*(($hexScale01 + $hexScale02) / 2)); // assign hex scale to spring rest length setAttr ($springName[$i] + ".springRestLength") $hexValue; } $i++; } print ("hex_associate loaded ..... Enjoy!\n"); } print ("hex_CA suite loaded ..... Enjoy!\n"); //____________________________________________________________________________________________________________________ // uncomment the next lines to allow the scripts to run automatically /* hexCA_create 20 10 1 35; hexCA_run 20 10 50 0; */ //or /* springCA_create 20 10 1; */ //or /* hex_associate 1; */