// create a 3d rafter from a single selected curve // the given height is the distance between the top and bottom beams // the angle between both bottom beams is 60 degrees // the given number of divisions is one less than the number of nodes on the top beam // the given radius is the radius of extrusion of the beams and bars global proc rafter3d(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 $norm = unit(cross($dirv, $offv)); vector $normal = cosd(30) * $norm + sind(30) * $offv; // create a second curve offset from the first $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 $curve2 = $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; // create a third curve offset from the first $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 $curve3 = $objects[0]; // trim third curve $offsetcurve = $objects[1]; $objects = `listConnections -d off -s on ($offsetcurve + ".inputCurve")`; $subcurve = $objects[0]; setAttr($subcurve + ".minValue", $distance / 2); setAttr($subcurve + ".maxValue", ($divisions - .5) * $distance); // keep a list of all curves string $curves[] = {$curve, $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 plus one // the number of points on the second and third curve is for each equal to the number of divisions float $pos2prev[]; float $pos3prev[]; int $i; for ($i = 0; $i < $divisions + 1; $i = $i + 1) { float $pos1[] = pointOnCurve("-pr", ($i * $distance), "-p", $curve); float $pos2[] = pointOnCurve("-pr", (($i + .5) * $distance), "-p", $curve2); float $pos3[] = pointOnCurve("-pr", (($i + .5) * $distance), "-p", $curve3); if ($i > 0) { $curves[size($curves)] = `curve -d 1 -p $pos2prev[0] $pos2prev[1] $pos2prev[2] -p $pos1[0] $pos1[1] $pos1[2]`; // from curve2 to curve $curves[size($curves)] = `curve -d 1 -p $pos3prev[0] $pos3prev[1] $pos3prev[2] -p $pos1[0] $pos1[1] $pos1[2]`; // from curve3 to curve } if ($i < $divisions) { $curves[size($curves)] = `curve -d 1 -p $pos1[0] $pos1[1] $pos1[2] -p $pos2[0] $pos2[1] $pos2[2]`; // from curve to curve2 $curves[size($curves)] = `curve -d 1 -p $pos1[0] $pos1[1] $pos1[2] -p $pos3[0] $pos3[1] $pos3[2]`; // from curve 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 } $pos2prev = $pos2; $pos3prev = $pos3; } // 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; delete $circle; select -cl; }