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