/* chain_maker.txt */ /* This script builds an interlocking chain of torii that follows selected paths. Each link is a separate mesh to allow easier tweaks. Adjust the four parameters below to customize the chain. The script uses the techniques shown in R. Steven Glanville's demo script "spine.txt". It also borrows from Tyson Collins's "torus_plugin.an8" NickE */ object $curObject; shape $shape, $shapes[0], $childShapes[1]; int $numSplines,$ii,$jj; point3 $p0, $p1; quaternion $q0; shape $link; int $sides[2],$segments[2],$swap,$segment,$lastsegment,$cursegment,$i; int $numlinks,$ll,$holdpoint; int $elongation[2],$halfsegments[2]; float $segradius[2],$innerradius[2],$angle,$linkoffset; point3 $vertex[100]; point3 $p; int $vertexindex[80]; int $mod; $sides[0] = 12; /* more makes smoother walled links */ $segments[0] = 12; /* more makes more circular links */ $halfsegments[0] = $segments[0] / 2; $segradius[0] = 2; /* the thickness of the link */ $innerradius[0] = 5; /* from the center of walls across the "hole" of the link */ $elongation[0]=5; /* the elongation factor */ $sides[1] = 12; $segments[1] = 12; $halfsegments[1] = $segments[1] / 2; $segradius[1] = 2; $innerradius[1] = 6; $elongation[1]=0; /* actual hole radius is $innerradius[] - $segradius[] Make sure to set ($innerradius[] - $segradius[] + $elongation[]) >= (2 * $segradius[]) or you will have overlap If the difference between the $innerradius[] and the $segradius[] is large and the path length is low, you will get links spacing overlap */ $curObject = project.curObject; $curObject.GetShapes($childShapes); $shapes.size = 0; while ($childShapes.size > 0) $shapes.push($childShapes.pop()); while ($shapes.size > 0) { $shape = $shapes.pop(); if ($shape.GetKind() == SHAPE_KIND_PATH && $shape.Selected) { $numSplines = $shape.GetNumSplines(); for $ii = 0 to $numSplines - 1 do { spline $spline; float $length, $t; int $num, $prev; float4x4 $xformMat; $spline = $shape.GetSpline($ii); $length = $spline.GetLength(); $num = 2*($length / (((2*$innerradius[0]) - (2*$segradius[0]) + ($elongation[0])) + ((2*$innerradius[1]) - (2*$segradius[1]) + ($elongation[1])))); /* the denominator above sets the relationship of the links */ for $jj = 0 to $num do { $link=mesh(); $link.Open(); $mod = ($jj % 2); $t = $jj/($num*1.0); $p0 = $spline.Eval($t); $q0 = $spline.Orientation($t); $xformMat = toFloat4x4($q0); for $i = 0 to $sides[$mod]-1 do { if (($mod) == 0) { $vertex[$i].x = cos((2*3.14159*$i)/$sides[$mod])*$segradius[$mod] + $innerradius[$mod]; $vertex[$i].y = sin((2*3.14159*$i)/$sides[$mod])*$segradius[$mod]; $vertex[$i].z = 0.0; } else { $vertex[$i].z = cos((2*3.14159*(($sides[$mod]-1)-$i))/$sides[$mod])*$segradius[$mod] + $innerradius[$mod]; $vertex[$i].x = sin((2*3.14159*(($sides[$mod]-1)-$i))/$sides[$mod])*$segradius[$mod]; $vertex[$i].y = 0.0; } } $vertexindex[$sides[$mod]+1] = $vertexindex[0]; $lastsegment = 0; $cursegment = $segments[$mod]+1; for $segment = 0 to $halfsegments[$mod] do { $angle = (2*3.14159)*($segment * (1.0/$segments[$mod])); for $i = 0 to $sides[$mod]-1 do { if (($jj % 2) == 0) { $p.y = $vertex[$i].y; $p.z = cos($angle)*$vertex[$i].z + sin($angle)*$vertex[$i].x + ($elongation[$mod]/2.0); $p.x = -sin($angle)*$vertex[$i].z + cos($angle)*$vertex[$i].x; $p1 = $xformMat.Project($p) + $p0; } else { $p.x = $vertex[$i].x; $p.z = cos($angle)*$vertex[$i].y + sin($angle)*$vertex[$i].z + ($elongation[$mod]/2.0); $p.y = -sin($angle)*$vertex[$i].y+ cos($angle)*$vertex[$i].z; $p1 = $xformMat.Project($p) + $p0; } $vertexindex[$cursegment + $i] = $link.AddPoint($p1); } $vertexindex[$cursegment + $sides[$mod]] = $vertexindex[$cursegment]; if ($segment != 0) { for $i = 0 to $sides[$mod] - 1 do { $link.OpenFace(0, 0); $link.VertexN($vertexindex[$lastsegment + $i]); $link.VertexN($vertexindex[$cursegment + $i]); $link.VertexN($vertexindex[$cursegment + $i + 1]); $link.VertexN($vertexindex[$lastsegment + $i + 1]); $link.CloseFace(); } } $swap = $lastsegment; $lastsegment = $cursegment; $cursegment = $swap; } for $segment = $halfsegments[$mod] to $segments[$mod] do { $angle = (2*3.14159)*($segment * (1.0/$segments[$mod])); for $i = 0 to $sides[$mod]-1 do { if (($jj % 2) == 0) { $p.y = $vertex[$i].y; $p.z = cos($angle)*$vertex[$i].z + sin($angle)*$vertex[$i].x - ($elongation[$mod]/2.0); $p.x = -sin($angle)*$vertex[$i].z + cos($angle)*$vertex[$i].x; $p1 = $xformMat.Project($p) + $p0; } else { $p.x = $vertex[$i].x; $p.z = cos($angle)*$vertex[$i].y + sin($angle)*$vertex[$i].z - ($elongation[$mod]/2.0); $p.y = -sin($angle)*$vertex[$i].y + cos($angle)*$vertex[$i].z; $p1 = $xformMat.Project($p) + $p0; } $vertexindex[$cursegment + $i] = $link.AddPoint($p1); } $vertexindex[$cursegment + $sides[$mod]] = $vertexindex[$cursegment]; if ($segment != 0) { for $i = 0 to $sides[$mod] - 1 do { $link.OpenFace(0, 0); $link.VertexN($vertexindex[$lastsegment + $i]); $link.VertexN($vertexindex[$cursegment + $i]); $link.VertexN($vertexindex[$cursegment + $i + 1]); $link.VertexN($vertexindex[$lastsegment + $i + 1]); $link.CloseFace(); } } $swap = $lastsegment; $lastsegment = $cursegment; $cursegment = $swap; } for $i = 0 to $sides[$mod]-2 do { $link.OpenFace(0, 0); $link.VertexN($vertexindex[$lastsegment + $i]); $link.VertexN($i); $link.VertexN($i+1); $link.VertexN($vertexindex[$lastsegment + $i+1]); $link.CloseFace(); } $link.OpenFace(0, 0); $link.VertexN(0); $link.VertexN($vertexindex[$lastsegment]); $link.VertexN($vertexindex[$lastsegment + $sides[$mod]-1]); $link.VertexN($sides[$mod]-1); $link.CloseFace(); $link.Close(); } } } }