/***************************************************\ migFractal ŻŻŻŻŻŻŻŻŻŻ Version 1.0 Author Mika Göös Updated 27.11.2005 Description ŻŻŻŻŻŻŻŻŻŻŻ This script generates a variety of fractal solids. Images of the fractals can be found from http://migugi.net/mel/fractalSolids/ Installation ŻŻŻŻŻŻŻŻŻŻŻŻ - Copy the migFractal.mel file to your ../My Documents/maya/[version]/scripts/ folder - Start Maya and execute the command migFractal; \***************************************************/ proc string[] fractals() { return { "7", "fractalScale", "fractalA", "fractalB", "fractalC", "fractalD", "fractalSeed", "SierpinskiPyramid", "", "", "", "", "", "", "MengerSponge", "", "", "", "", "", "", "SierpDodecahedron", "", "", "", "", "", "", "Tetrahedron", "Scale coeff:0.6", "", "", "", "", "", "Hexahedron", "Scale coeff:0.5", "", "", "", "", "", "Octahedron", "Scale coeff:0.4", "", "", "", "", "", "TaperedCube", "Scale coeff:0.62", "Width taper:1.64", "Depth taper:0.62", "", "", "", "Tree", "Scale coeff:0.65", "Min angle:0", "Max angle:80", "Branch offset:0.7","Branches:5", "Seed:0" }; } global proc migFractal() { if(`window -exists fractalWindow`) deleteUI -window fractalWindow; // if(`windowPref -exists fractalWindow`) // windowPref -remove fractalWindow; string $types[] = fractals(); window -title "Fractal Solids" -sizeable false -wh 300 199 fractalWindow; columnLayout; separator -h 4 -st "none"; rowLayout -nc 2 -cw2 75 200 -ct2 "both" "left" -cl2 "right" "left" -co2 0 5; text -l "Base name:" -font "boldLabelFont"; textField -w 200 -tx "Fractal_" fractalName; setParent ..; separator -h 4 -st "none"; rowLayout -nc 4 -cw4 75 48 40 100 -ct4 "both" "left" "both" "left" -cl4 "right" "left" "right" "left" -co4 0 5 0 5 migFractalRow; text -l "Iterations:" -font "boldLabelFont"; optionMenu fractalIterations; int $i; for($i=1; $i<=12; $i++) menuItem -l (""+$i); setParent migFractalRow; text -l "Type:" -font "boldLabelFont"; optionMenu -cc "migFractalTypeChanged()" fractalType; int $i; for($i=(int)$types[0]; $i 1) polyUnite -ch 0 -n $new $g; else { parent -world ($g+"|"+$children[0]); rename $children[0] $new; } if(`objExists $g`) delete $g; } else { int $n=0; for($child in $children) rename $child ("Sub_"+($n++)); rename $g $new; } if(`progressWindow -q -ic`) break; } progressWindow -ep; select -clear; print ($iterations+" iterations in "+`timerX -startTime $startTime`+"s."); } global proc migFractalGenerate() { int $iterations = (int)`optionMenu -q -v fractalIterations`; string $name = `textField -q -tx fractalName`; string $type = `optionMenu -q -v fractalType`; iterate($type, $name, $iterations); } proc float scaleCoeff() { string $types[] = fractals(); return `floatField -q -v $types[1]`; } proc float xCoeff() { string $types[] = fractals(); return `floatField -q -v $types[2]`; } proc float yCoeff() { string $types[] = fractals(); return `floatField -q -v $types[3]`; } proc float aCoeff() { string $types[] = fractals(); return `floatField -q -v $types[4]`; } proc float bCoeff() { string $types[] = fractals(); return `floatField -q -v $types[5]`; } proc int seedFloat() { string $types[] = fractals(); return (int)`floatField -q -v $types[6]`; } proc string firstName() { return (`textField -q -tx fractalName`+"00"); } // __________________________________________________________________________________ \\ // =========================== Generointi =========================== \\ // ŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻŻ \\ global proc migFractal_SierpDodecahedron(int $i, string $prev, string $g, float $s) { if(!`objExists $prev`) { polyPlatonicSolid -r 1 -st 0 -tx 1 -ch 0 -n $prev; scale -a $s $s $s $prev; move -r 0 ($s*sqrt(2)/8) 0 $prev; // select -r ($prev+".f[0]"); // delete; select -clear; polySetToFaceNormal -su $prev; } float $coeff = 0.5/(1+cos(deg_to_rad(72))); string $firstIter = firstName(); int $numVs[] = `polyEvaluate -v $firstIter`; int $n; for($n=0;$n<$numVs[0];$n++) { string $copy[] = `duplicate $prev`; string $sub = $copy[0]; parent $sub $g; float $coords[] = `xform -q -t -a -ws ($firstIter+".vtx["+$n+"]")`; print ("<<"+$coords[0]+",\t"+$coords[1]+",\t"+$coords[2]+">>\n"); move $coords[0] $coords[1] $coords[2] ($sub+".scalePivot") ($sub+".rotatePivot"); scale -r $coeff $coeff $coeff $sub; progressWindow -e -status ("Sierpinski Dodecahedron, Iteration "+$i+": "+($n+1)+"/"+$numVs[0]+".") -progress (($n+1)*100/$numVs[0]); if(`progressWindow -q -ic`) return; } hide $prev; } global proc migFractal_Tree(int $i, string $prev, string $g, float $s) { float $coeff = scaleCoeff(); string $cube[] = `polyCube`; string $base = $cube[0]; select -r ($base+".f[1]"); scale -r $coeff 1 $coeff; select -add ($base+".f[3]"); delete; scale -a 1 $s 1 $base; select -r ($base+".f[0:3]"); polyAverageNormal; move -r 0 ($s/2) 0; select -cl; parent $base $g; if(!`objExists $prev`) return; float $minAngle = xCoeff(); float $maxAngle = yCoeff(); float $offset = aCoeff(); int $numBranches = (int)bCoeff(); int $n; for($n=0;$n<$numBranches;$n++) { string $copy[] = `duplicate $prev`; string $sub = $copy[0]; parent $sub $g; scale -r $coeff $coeff $coeff $sub; float $c = `rand (1-$offset) 1`; if($n==0) $c = 1; move -r 0 ($c*$s-0.2) 0; rotate -r 0 `rand 0 360` 0; rotate -r 0 0 `rand $minAngle $maxAngle`; rotate -r 0 `rand 0 360` 0; progressWindow -e -status ("Tree, Iteration "+$i+": "+($n+1)+"/"+$numBranches+".") -progress (($n+1)*100/$numBranches); if(`progressWindow -q -ic`) return; } hide $prev; } global proc migFractal_Tetrahedron(int $i, string $prev, string $g, float $s) { if(!`objExists $prev`) { polyPyramid -n $prev -ns 3; scale -a $s $s $s $prev; select -r ($prev+".f[0]"); delete; select -r ($prev+".f[0:3]"); move -r -y ($s/sqrt(6)); select -clear; } float $d = sqrt(3.0)/9; float $posX[] = { $s*cos(deg_to_rad(60))*$d, $s*cos(deg_to_rad(-60))*$d, -$s*$d }; float $posZ[] = { $s*sin(deg_to_rad(60))*$d, $s*sin(deg_to_rad(-60))*$d, 0 }; float $posY = sqrt(2.0/27)*$s; float $coeff = scaleCoeff(); int $n; for($n=0;$n<3;$n++) { string $copy[] = `duplicate $prev`; string $sub = $copy[0]; parent $sub $g; scale -r $coeff $coeff $coeff $sub; move -a -xyz $posX[$n] $posY $posZ[$n] $sub; rotate -r 0 0 1.23095941rad $sub; if($n==0) rotate -r 0 120deg 0 $sub; if($n==1) rotate -r 0 -120deg 0 $sub; progressWindow -e -status ("Tetrahedron, Iteration "+$i+": "+($n+1)+"/3.") -progress (($n+1)*100/3); if(`progressWindow -q -ic`) return; } } global proc migFractal_Hexahedron(int $i, string $prev, string $g, float $s) { if(!`objExists $prev`) { polyCube -n $prev; scale -a $s $s $s $prev; select -r ($prev+".f[3]"); delete; select -r ($prev+".f[0:4]"); move -r -y ($s/2); select -clear; } float $coeff = scaleCoeff(); int $n; for($n=0;$n<5;$n++) { string $copy[] = `duplicate $prev`; string $sub = $copy[0]; parent $sub $g; scale -r $coeff $coeff $coeff $sub; vector $pos, $rot; switch($n) { case 0: $pos = << 0, $s, 0>>; $rot = << 0,0, 0>>; break; case 1: $pos = << $s/2, $s/2, 0>>; $rot = << 0,0,-90>>; break; case 2: $pos = <<-$s/2, $s/2, 0>>; $rot = << 0,0, 90>>; break; case 3: $pos = << 0, $s/2, $s/2>>; $rot = << 90,0, 0>>; break; case 4: $pos = << 0, $s/2,-$s/2>>; $rot = <<-90,0, 0>>; break; default: } move -a -xyz ($pos.x) ($pos.y) ($pos.z) $sub; rotate -r ($rot.x) ($rot.y) ($rot.z) $sub; progressWindow -e -status ("Hexahedron, Iteration "+$i+": "+($n+1)+"/5.") -progress (($n+1)*100/5); if(`progressWindow -q -ic`) return; } } global proc migFractal_Octahedron(int $i, string $prev, string $g, float $s) { vector $offset = <<$s/3, sqrt(2)/6*$s, 0>>; if(!`objExists $prev`) { polyPlatonicSolid -r (1/sqrt(2)) -st 2 -ch 0 -n $prev; scale -a $s $s $s $prev; rotate -r -ws 0 -45 0 $prev; select -r ($prev+".f[0:7]"); move -r -xyz ($offset.x) ($offset.y) ($offset.z); select -r ($prev+".f[6]"); delete; select -clear; polySetToFaceNormal -su $prev; } float $d = sqrt(3.0)/9; float $posX[] = { $s*cos(deg_to_rad(60))*$d, $s*cos(deg_to_rad(-60))*$d, -$s*$d }; float $posZ[] = { $s*sin(deg_to_rad(60))*$d, $s*sin(deg_to_rad(-60))*$d, 0 }; float $posY = sqrt(2.0/27)*$s; float $coeff = scaleCoeff(); int $n; for($n=0;$n<7;$n++) { string $copy[] = `duplicate $prev`; string $sub = $copy[0]; parent $sub $g; scale -r $coeff $coeff $coeff $sub; if($n<4) rotate -r 0 0 (180-2*35.2643896828) $sub; vector $pos, $rot; switch($n) { case 0: $pos = << 0, sqrt(2)/6*$s, $s/3>>; $rot = <<0,90,0>>; break; case 1: $pos = << 0, sqrt(2)/6*$s,-$s/3>>; $rot = <<0,-90,0>>; break; case 2: $pos = << $s/3, sqrt(2)/6*$s, 0>>; $rot = <<0,180,0>>; break; case 3: $pos = <<-$s/3, sqrt(2)/6*$s, 0>>; $rot = <<0,0,0>>; break; case 4: $pos = << 0,-sqrt(2)/6*$s, $s/3>>; $rot = <<0,-90,0>>; break; case 5: $pos = << 0,-sqrt(2)/6*$s,-$s/3>>; $rot = <<0,90,0>>; break; case 6: $pos = << $s/3,-sqrt(2)/6*$s, 0>>; $rot = <<0,0,0>>; break; default: $pos = <<0,0,0>>; $rot = <<0,0,0>>; } move -r -ws -xyz ($pos.x+$offset.x) ($pos.y+$offset.y) ($pos.z+$offset.z) $sub; rotate -r ($rot.x) ($rot.y) ($rot.z) $sub; if($n==4) rotate -r ( 2*35.2643896828) 0 0 $sub; if($n==5) rotate -r (-2*35.2643896828) 0 0 $sub; if($n==6) rotate -r 0 0 (-2*35.2643896828) $sub; progressWindow -e -status ("Octahedron, Iteration "+$i+": "+($n+1)+"/7.") -progress (($n+1)*100/7); if(`progressWindow -q -ic`) return; } } global proc migFractal_MengerSponge(int $i, string $prev, string $g, float $scale) { if(!`objExists $prev`) { polyCube -n $prev; scale -a $scale $scale $scale $prev; } float $coeff = 1.0/3; int $x, $y, $z, $n=0; for($x=0;$x<3;$x++) for($y=0;$y<3;$y++) for($z=0;$z<3;$z++) { if ( ($x == 1 && $y == 1) || ($z == 1 && $y == 1) || ($z == 1 && $x == 1) ) continue; $n++; string $copy[] = `duplicate $prev`; string $sub = $copy[0]; parent $sub $g; scale -r $coeff $coeff $coeff $sub; move -a -xyz (($x-1)*$scale/3) (($y-1)*$scale/3) (($z-1)*$scale/3) $sub; progressWindow -e -status ("Menger Sponge, Iteration "+$i+": "+($n)+"/20.") -progress (($n)*100/20); if(`progressWindow -q -ic`) return; } hide $prev; } global proc migFractal_SierpinskiPyramid(int $i, string $prev, string $g, float $s) { if(!`objExists $prev`) { polyPyramid -n $prev; rotate -a 0 45deg 0 $prev; scale -a $s $s $s $prev; move -r 0 ($s*sqrt(2)/8) 0 $prev; select -r ($prev+".f[0]"); delete; select -clear; } float $coeff = 0.5; int $n; for($n=0;$n<5;$n++) { string $copy[] = `duplicate $prev`; string $sub = $copy[0]; parent $sub $g; scale -r $coeff $coeff $coeff $sub; vector $pos; switch($n) { case 0: $pos = << $s/4, 0, $s/4>>; break; case 1: $pos = <<-$s/4, 0, $s/4>>; break; case 2: $pos = <<-$s/4, 0,-$s/4>>; break; case 3: $pos = << $s/4, 0,-$s/4>>; break; case 4: $pos = << 0,$s*sqrt(2)/4, 0>>; break; default: } move -r -xyz ($pos.x) ($pos.y) ($pos.z) $sub; progressWindow -e -status ("Sierpinski Pyramid, Iteration "+$i+": "+($n+1)+"/5.") -progress (($n+1)*100/4); if(`progressWindow -q -ic`) return; } hide $prev; } global proc migFractal_TaperedCube(int $i, string $prev, string $g, float $s) { float $dx = xCoeff(); float $dz = yCoeff(); if(!`objExists $prev`) { polyCube -n $prev; scale -a $s $s $s $prev; select -r ($prev+".f[1]"); scale -r $dx 1 $dz; select -clear; } float $coeff = scaleCoeff(); float $angleX = rad_to_deg(angle(<<1,0,0>>,<<1,1-$dx,0>>))/2 * sign(1-$dx); float $angleZ = rad_to_deg(angle(<<1,0,0>>,<<1,1-$dz,0>>))/2 * sign(1-$dz); int $n; for($n=0;$n<5;$n++) { string $copy[] = `duplicate $prev`; string $sub = $copy[0]; parent $sub $g; scale -r $coeff $coeff $coeff $sub; vector $pos, $rot, $pos2; switch($n) { case 0: $pos = <<0, $s*(1+$coeff)/2, 0>>; // Y $rot = <<0, 0, 0>>; $pos2 = <<0,0,0>>; break; case 1: $pos = <<$s*(1+$dx)/4,0,0>>; // X $rot = <<0, 0, $angleX*2>>; $pos2 = <<$s*(1+$dx)/4*$coeff,0,0>>; break; case 2: $pos = <<-$s*(1+$dx)/4,0,0>>; // -X $rot = <<0, 0, -$angleX*2>>; $pos2 = <<-$s*(1+$dx)/4*$coeff,0,0>>; break; case 3: $pos = <<0, 0,$s*(1+$dz)/4>>; // Z $rot = <<-$angleZ*2, 0, 0>>; $pos2 = <<0,0,$s*(1+$dz)/4*$coeff>>; break; case 4: $pos = <<0, 0,-$s*(1+$dz)/4>>; // -Z $rot = <<$angleZ*2, 0, 0>>; $pos2 = <<0,0,-$s*(1+$dz)/4*$coeff>>; break; default: $pos = $rot = $pos2 = <<0,0,0>>; } move -a -xyz ($pos.x) ($pos.y) ($pos.z) $sub; rotate -r ($rot.x) ($rot.y) ($rot.z) $sub; move -r -os -wd ($pos2.x) ($pos2.y) ($pos2.z) $sub; if($i==1) switch($n) { case 0: delete ($sub+".f[3]"); break; case 1: delete ($sub+".f[5]"); break; case 2: delete ($sub+".f[4]"); break; case 3: delete ($sub+".f[2]"); break; case 4: delete ($sub+".f[0]"); break; default: } progressWindow -e -status ("Hexahedron, Iteration "+$i+": "+($n+1)+"/5.") -progress (($n+1)*100/5); if(`progressWindow -q -ic`) return; } }