// Copyright (C) 1997-2004 Alias Systems Corp.
// 
// The information in this file is provided for the exclusive use of the
// licensees of Alias.  Such users have the right to use, modify,
// and incorporate this code into other products for purposes authorized
// by the Alias license agreement, without fee.
// 
// ALIAS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
// INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
// EVENT SHALL ALIAS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
// CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
// DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
// TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.

//
//  Alias Script File
//  MODIFY THIS AT YOUR OWN RISK
//
//  Creation Date:  2000
//
// Description:	Creates strokes of selected paint effects brush
//			on selected surfaces in a grid layout. The grid can be
// 			randomized with 2dnoise
//	

global proc paintGrid(
int $uspans, int $vspans, int $uedge, int $vedge, int $degree,  
int $strokesPerSpan, int $pointsPerCurve,
float $noiseScale, float $noiseFrequency, 
float $sampleDensity, int $arcLengthDensity,
float $surfaceOffsetMin, float $surfaceOffsetMax,
int $shareOneBrush )
{
	string $selected[] = `ls -sl -dag -type nurbsSurface -type mesh`;
	string $sel;

	if( size( $selected ) <= 0  )
	{
		warning( "No Nurbs or Mesh surfaces are currently selected for painting.");
		return;
	}	
	int $uspan, $vspan, $segment, $point;
	float $u,$v,$startU, $startV, $minU, $minV, $rangeU, $rangeV, $nScale;
	float $noiseFrequency2, $nScale2;
	$pointFac = 1.0/($strokesPerSpan * ($pointsPerCurve-1));
	string $cmdK = "";
	// create the knot vectors for the command based on the curve degree
	for( $i = 0; $i < ($degree - 1); $i++ )
	{
		$cmdK += ("-k 0 ");
	}
	for( $point = 0; $point < ($pointsPerCurve -( $degree - 1)); $point++ )
	{
		$cmdK += ("-k " + $point + " ");
	}
	$point--;
	for( $i = 0; $i < ($degree - 1); $i++ )
	{
		$cmdK += ("-k " + $point + " ");
	}
	$noiseFrequency = $noiseFrequency;
	$noiseFrequency2 = $noiseFrequency * 3;
	if( $uedge )
	{
		$uspans += 2;
	}
	if( $vedge )
	{
		$vspans += 2;
	}
	string $newStrokes[], $newCurves[], $newStroke[];
	int $numNewStrokes = 0;
	for( $sel in $selected )
	{
		if(`objectType -isType nurbsSurface $sel`)
		{
			$minU = getAttr( $sel+".minValueU" );
			$minV = getAttr( $sel+".minValueV" );
			$rangeU = getAttr( $sel+".maxValueU" ) - $minU;
			$rangeV = getAttr( $sel+".maxValueV" ) - $minV;
		}
		else
		{
			$minU = 0.0;
			$minV = 0.0;
			$rangeU = 1.0;
			$rangeV = 1.0;
		}

		if( $uspans > 0 )
		{
			$nScale = $noiseScale * 0.5/(float)$uspans;
			$nScale2 = $nScale * 0.3;
		}
		for( $uspan = 0; $uspan < $uspans; $uspan++ ) 
		{
			for( $segment = 0; $segment < $strokesPerSpan; $segment++ )
			{
				if( $uedge ) 
				{
					$startU = (float)($uspan)/(float)($uspans-1);
				}
				else
				{
					$startU = (float)($uspan+1)/(float)($uspans+1);
				}
				$startV = (float)$segment/(float)$strokesPerSpan;
				string $cmd = ("curveOnSurface -d " + $degree );
				for( $point = 0; $point < $pointsPerCurve || $point < 2; $point++ )
				{
					$v = $startV + (float)$point * $pointFac;
					$u = $startU + (noise( $startU*$noiseFrequency, $v*$noiseFrequency ))*$nScale
								 + (noise( $startU*$noiseFrequency2, $v*$noiseFrequency2 ))*$nScale2;
					$cmd += (" -uv "+ ($u*$rangeU + $minU) +" "+ ($v*$rangeV + $minV));
				}
				$cmd += (" "+ $cmdK + $sel);
				$newCurves[$numNewStrokes] = `eval($cmd)`;
				convertCurvesToStrokes;
				$newStroke =  `ls -sl -dag -type stroke`;
				$newStrokes[ $numNewStrokes ] = $newStroke[0];
				$numNewStrokes++;
			}
		}
		if( $vspans > 0 )
		{
			$nScale = $noiseScale * 0.5/(float)$vspans;
			$nScale2 = $nScale * 0.3;
		}
		for( $vspan = 0; $vspan < $vspans; $vspan++ ) 
		{
			for( $segment = 0; $segment < $strokesPerSpan; $segment++ )
			{
				if( $vedge ) 
				{
					$startV = (float)($vspan)/(float)($vspans-1);
				}
				else
				{
					$startV = (float)($vspan+1)/(float)($vspans+1);
				}
				$startU = (float)$segment/(float)$strokesPerSpan;
				string $cmd = ("curveOnSurface -d " + $degree );
				for( $point = 0; $point < $pointsPerCurve || $point < 2; $point++ )
				{
					$u = $startU + (float)$point * $pointFac;
					$v = $startV + (noise( $u*$noiseFrequency, $startV*$noiseFrequency ))*$nScale
								 + (noise( $u*$noiseFrequency2, $startV*$noiseFrequency2 ))*$nScale2;
					$cmd += (" -uv "+ ($u*$rangeU + $minU) +" "+ ($v*$rangeV + $minV));
				}
				$cmd += (" "+ $cmdK + $sel);
				$newCurves[$numNewStrokes] = `eval($cmd)`;
				convertCurvesToStrokes;
				$newStroke =  `ls -sl -dag -type stroke`;
				$newStrokes[ $numNewStrokes ] = $newStroke[0];
				$numNewStrokes++;
			}
		}

	}
	float $offsetRange = $surfaceOffsetMax -$surfaceOffsetMin;
	rand( $offsetRange ); // the first rand is sometimes bad
	float $maxCurveLength = 0;
	float $curveLengths[];
	for( $i = 0; $i < $numNewStrokes; $i++)
	{
		if( $arcLengthDensity )
		{
			$curveLengths[$i] = arclen ($newCurves[$i]);
			if( $curveLengths[$i] > $maxCurveLength )
			{
				$maxCurveLength = $curveLengths[$i];
			}
		}
		hide $newCurves[$i];
	}
	float $sDense = $sampleDensity;
	for( $i = 0; $i < $numNewStrokes; $i++)
	{

		if( $arcLengthDensity && $maxCurveLength > 0)
		{
			$sDense = $sampleDensity * $curveLengths[$i]/$maxCurveLength;
		}
		setAttr ( $newStrokes[$i] + ".sampleDensity" ) $sDense;
		setAttr ( $newStrokes[$i] + ".seed" ) $i;
		setAttr ( $newStrokes[$i] + ".surfaceOffset" ) ($surfaceOffsetMin + rand( $offsetRange ));
		select -add $newStrokes[$i];
	}
	if( $shareOneBrush )
	{
		useSameBrush;
	}
}
