// create a 3d rafter from a single selected curve // the three beams of the rafter, in section, form the ends of a T, // where the selected curve forms the junction of the T // the beam at the bottom of the T is slightly shortened // the given offset vector is the direction vector of the long stroke of the T // the given height equals the length of both the long stroke and the transverse stroke of the T // the given number of divisions is one less than the number of nodes on the two beams at the top of the T // the given radius is the radius of extrusion of the beams and bars // e.g., rafter3dv(<< 0, -1, 0 >>, 1, 15, 0.02); global proc rafter3dv(vector $offv, float $height, int $divisions, float $radius) { // retrieve the selected curve string $objects[] = `ls -sl`; string $curve = $objects[0]; // reparametrize the curve from 0 to 1 rebuildCurve -replaceOriginal 1 -keepRange 0 -spans 0 -tolerance 0.0001 $curve; // the distance between two nodes equals one over the number of nodes when the curve is parametrized from 0 to 1 float $distance = 1.0/$divisions; // determine the beginning and end point of the curve $objects = `listRelatives -shapes $curve`; string $shape = $objects[0]; int $cvcount = getAttr($shape + ".degree") + getAttr($shape + ".spans"); float $begin[] = pointPosition($curve + ".cv[0]"); float $end[] = pointPosition($curve + ".cv[" + ($cvcount - 1) + "]"); // determine the normal vector to the first offset plane vector $dirv = << ($end[0] - $begin[0]), ($end[1] - $begin[1]), ($end[2] - $begin[2]) >>; //vector $offv = << 0, -1, 0 >>; vector $normal = unit(cross($dirv, $offv)); print $normal; print "\n"; // create a first curve offset from the reference curve $objects = `offsetCurve -ch on -range true -useGivenNormal true -normal ($normal.x) ($normal.y) ($normal.z) -d $height -cutLoop true -cutRadius 0.001 -connectBreaks 1 $curve`; string $curve1 = $objects[0]; // trim second curve string $offsetcurve = $objects[1]; $objects = `listConnections -d off -s on ($offsetcurve + ".inputCurve")`; string $subcurve = $objects[0]; setAttr($subcurve + ".minValue", $distance / 2); setAttr($subcurve + ".maxValue", ($divisions - .5) * $distance); // determine the normal vector to the second offset plane //$normal = cosd(30) * $norm + sind(30) * $offv; //$normal = cosd(30) * $norm - sind(30) * $offv; // create a second curve offset from the reference curve $normal = unit(cross($dirv, $normal)); print $normal; print "\n"; $height = $height / 2; $objects = `offsetCurve -ch off -range true -useGivenNormal true -normal ($normal.x) ($normal.y) ($normal.z) -d $height -cutLoop true -cutRadius 0.001 -connectBreaks 1 $curve`; string $curve2 = $objects[0]; // create a third curve offset from the reference curve $normal = -1 * $normal; print $normal; print "\n"; $objects = `offsetCurve -ch off -range true -useGivenNormal true -normal ($normal.x) ($normal.y) ($normal.z) -d $height -cutLoop true -cutRadius 0.001 -connectBreaks 1 $curve`; string $curve3 = $objects[0]; // keep a list of all curves string $curves[] = {$curve1, $curve2, $curve3}; // determine a number of points on all three curves and connect these // the number of points on the first curve is equal to the number of divisions // the number of points on the second and third curve is for each equal to the number of divisions plus one float $pos1prev[]; int $i; for ($i = 0; $i < $divisions + 1; $i = $i + 1) { float $pos1[] = pointOnCurve("-pr", (($i + .5) * $distance), "-p", $curve1); float $pos2[] = pointOnCurve("-pr", ($i * $distance), "-p", $curve2); float $pos3[] = pointOnCurve("-pr", ($i * $distance), "-p", $curve3); if ($i > 0) { $curves[size($curves)] = `curve -d 1 -p $pos1prev[0] $pos1prev[1] $pos1prev[2] -p $pos2[0] $pos2[1] $pos2[2]`; // from curve1 to curve2 $curves[size($curves)] = `curve -d 1 -p $pos1prev[0] $pos1prev[1] $pos1prev[2] -p $pos3[0] $pos3[1] $pos3[2]`; // from curve1 to curve3 } if ($i < $divisions) { $curves[size($curves)] = `curve -d 1 -p $pos1[0] $pos1[1] $pos1[2] -p $pos2[0] $pos2[1] $pos2[2]`; // from curve1 to curve2 $curves[size($curves)] = `curve -d 1 -p $pos1[0] $pos1[1] $pos1[2] -p $pos3[0] $pos3[1] $pos3[2]`; // from curve1 to curve3 } $curves[size($curves)] = `curve -d 1 -p $pos2[0] $pos2[1] $pos2[2] -p $pos3[0] $pos3[1] $pos3[2]`; // from curve2 to curve3 $pos1prev = $pos1; } // extrude all collected curves string $objects[] = `circle -r $radius`; string $circle = $objects[0]; for ($curve in $curves) extrude -ch off -polygon 0 -useComponentPivot 1 -fixedPath true -useProfileNormal true -reverseSurfaceIfPathReversed 1 $circle $curve; // clean up delete $circle; select -cl; }