// 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 DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
// EVENT SHALL ALIAS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
//
//  Alias Script File
//  MODIFY THIS AT YOUR OWN RISK
//
//  Description:
//
//
//  Procedure Name:
//      performPolySmooth
//
//  Description:
//        perform a smooth of the selected polygon objects
//         
//  Input Arguments:
//        $option : Whether to set the options to default values.
//  Return Value:
//        command string iff $option==2
//

proc setOptionVars (int $forceFactorySettings)
{
// -mth/method option
	if ($forceFactorySettings || !`optionVar -exists polySmoothMethod`)
		optionVar -intValue polySmoothMethod 1;
//   -df/divisions option 
	if ($forceFactorySettings || !`optionVar -exists polyDivisions`)
		optionVar -intValue polyDivisions 1;
//   -c/continuity option 
	if ($forceFactorySettings || !`optionVar -exists polyContinuity`)
		optionVar -intValue polyContinuity 1;
// -kb/-keepBorder option: Keep edges on geometry border
	if ($forceFactorySettings || !`optionVar -exists polySmoothKeepBorder`)
		optionVar -intValue polySmoothKeepBorder 1;	
// -ksb/-keepSelectionBorder option: Keep edges on selection border
	if ($forceFactorySettings
			|| !`optionVar -exists polySmoothKeepSelectionBorder`)
		optionVar -intValue polySmoothKeepSelectionBorder 1;	
// -khe/-keepHardEdge option: Keep hard edges
	if ($forceFactorySettings
			|| !`optionVar -exists polySmoothKeepHardEdge`)
		optionVar -intValue polySmoothKeepHardEdge 0;	
// -kt/-keepTesselation option: Reuse initial subdivisions on animated objects
	if ($forceFactorySettings
			|| !`optionVar -exists polySmoothKeepTesselation`)
		optionVar -intValue polySmoothKeepTesselation 1;
// -suv/-smoothUVs option: Smooth UV values
		if ($forceFactorySettings
			|| !`optionVar -exists polySmoothSmoothUVs`)
		optionVar -intValue polySmoothSmoothUVs 1;
// -kmb/-keepMapBorders option: Perserve the UV Map Border (Smooth UVs on only)
	if ($forceFactorySettings || !`optionVar -exists polySmoothKeepMapBorders`)
		optionVar -intValue polySmoothKeepMapBorders 2;


// linear smooth options
	if ($forceFactorySettings
			|| !`optionVar -exists polySmoothNumIter`)
		optionVar -intValue polySmoothNumIter 1;	

	if ($forceFactorySettings
			|| !`optionVar -exists polySmoothEdivisions`)
		optionVar -intValue polySmoothEdivisions 1;	

	if ($forceFactorySettings
			|| !`optionVar -exists polySmoothVolume`)
		optionVar -floatValue polySmoothVolume 0.1;	

	if ($forceFactorySettings
			|| !`optionVar -exists polySmoothRoundness`)
		optionVar -floatValue polySmoothRoundness 1.0;	
}

global proc polySmoothVisibility()
//  Description:
//		Dim/show any bevel options as required by the output surface type
//
{
	//  smooth options
	int $method = `radioButtonGrp -q -select polySmoothMethod`;
	if(1 == $method) { // exponential options
		tabLayout -e -st polySmoothMethodExponential polySmoothOptions;
	} else if(2 == $method) { // linear options
		tabLayout -e -st polySmoothMethodLinear polySmoothOptions;
	}
}

global proc performPolySmoothSetup (string $parent, int $forceFactorySettings)
{
	setOptionVars($forceFactorySettings);
	setParent $parent;

// -mth/method option
	int $ival = `optionVar -query polySmoothMethod`;		
	radioButtonGrp -edit -select $ival polySmoothMethod;

// smooth options
	$ival = `optionVar -query polyDivisions`;
	intSliderGrp -edit -value $ival polyDivisions;

	float $fval = `optionVar -query polyContinuity`;
	floatSliderGrp -edit -value $fval polyContinuity;

	$ival = `optionVar -query polySmoothKeepBorder`;		
	checkBoxGrp -edit -value1 $ival polySmoothKeepBorder;

	$ival = `optionVar -query polySmoothKeepSelectionBorder`;		
	checkBoxGrp -edit -value1 $ival polySmoothKeepSelectionBorder;

	$ival = `optionVar -query polySmoothKeepHardEdge`;		
	checkBoxGrp -edit -value1 $ival polySmoothKeepHardEdge;

	$ival = `optionVar -query polySmoothKeepTesselation`;		
	checkBoxGrp -edit -value1 $ival polySmoothKeepTesselation;

	$ival = `optionVar -query polySmoothSmoothUVs`;
	checkBoxGrp -edit -value1 $ival polySmoothSmoothUVs;

	$ival = `optionVar -query polySmoothKeepMapBorders`;
	radioButtonGrp -edit -select $ival polySmoothKeepMapBorders;

	// linear options
	$ival = `optionVar -query polySmoothNumIter`;
	intSliderGrp -edit -value $ival polySmoothNumIter;

	$ival = `optionVar -query polySmoothEdivisions`;
	intSliderGrp -edit -value $ival polySmoothEdivisions;

	$fval = `optionVar -query polySmoothVolume`;
	floatSliderGrp -edit -value $fval polySmoothVolume;

	$fval = `optionVar -query polySmoothRoundness`;
	floatSliderGrp -edit -value $fval polySmoothRoundness;

	polySmoothVisibility();

}

global proc performPolySmoothCallback (string $parent, int $doIt)
{
	setParent $parent;
	optionVar -intValue polySmoothMethod
		`radioButtonGrp -q -select polySmoothMethod`;
	optionVar -intValue polyDivisions
		`intSliderGrp -query -value polyDivisions`;
	optionVar -floatValue polyContinuity
		`floatSliderGrp -query -value polyContinuity`;
	optionVar -intValue polySmoothKeepBorder
		`checkBoxGrp -query -value1 polySmoothKeepBorder`;
	optionVar -intValue polySmoothKeepSelectionBorder
		`checkBoxGrp -query -value1 polySmoothKeepSelectionBorder`;
	optionVar -intValue polySmoothKeepHardEdge
		`checkBoxGrp -query -value1 polySmoothKeepHardEdge`;
	optionVar -intValue polySmoothKeepTesselation
		`checkBoxGrp -query -value1 polySmoothKeepTesselation`;
	optionVar -intValue polySmoothSmoothUVs
		`checkBoxGrp -query -value1 polySmoothSmoothUVs`;
	optionVar -intValue polySmoothKeepMapBorders
		`radioButtonGrp -query -select polySmoothKeepMapBorders`;

	// linear options
	optionVar -intValue polySmoothNumIter
		`intSliderGrp -query -value polySmoothNumIter`;
	optionVar -intValue polySmoothEdivisions
		`intSliderGrp -query -value polySmoothEdivisions`;
	optionVar -floatValue polySmoothVolume
		`floatSliderGrp -query -value polySmoothVolume`;
	optionVar -floatValue polySmoothRoundness
		`floatSliderGrp -query -value polySmoothRoundness`;

	if ($doIt) {
		performPolySmooth 0;
		addToRecentCommandQueue "performPolySmooth 0" "PolySmooth";
	}
}

proc polySmoothOptions ()
{
	string $commandName = "performPolySmooth";
	string $callback = ($commandName + "Callback");
	string $setup = ($commandName + "Setup");
	   
	string $layout = getOptionBox();
	setParent $layout;
	setUITemplate -pushTemplate DefaultTemplate;
	
	string $parent = `columnLayout -adjustableColumn 1`;

	radioButtonGrp -nrb 2 -label "Subdivision Method"
		-label1 "Exponential" -da1 0
		-label2 "Linear" -da2 1 -select 1
		-cc1 "polySmoothVisibility()"
		-cc2 "polySmoothVisibility()"
		polySmoothMethod;

	string $tab = `tabLayout -tabsVisible false polySmoothOptions`;

    columnLayout polySmoothMethodExponential;

	frameLayout -label "Exponential Smoothing Controls" -labelAlign "center"
		-borderStyle "etchedIn" -cl false -cll false;
		columnLayout;

	  intSliderGrp -label "Subdivision Levels" -min 1 -max 4 -s 1 polyDivisions;
	  floatSliderGrp -label "Continuity" -min 0 -max 1 -s 1 polyContinuity;
	  checkBoxGrp -label1 "Smooth UVs"
	    -on1 ("disable -v false polySmoothKeepMapBorders;")
	    -of1 ("disable -v true polySmoothKeepMapBorders;")
		polySmoothSmoothUVs;

	  // Properties to preserve
	  //
      frameLayout -label "Preserve Properties" -labelAlign "center"
		  -borderStyle "etchedIn" -cl false -cll false;

        columnLayout;
	    checkBoxGrp -label1 "Keep Geometry Borders" polySmoothKeepBorder;
	    checkBoxGrp -label1 "Keep Selection Borders" polySmoothKeepSelectionBorder;
	    checkBoxGrp -label1 "Keep Hard Edges" polySmoothKeepHardEdge;
	    checkBoxGrp -label1 "Keep Tessellation" polySmoothKeepTesselation;
		radioButtonGrp -nrb 3 -label "Keep Map Borders"
		 		-label1 "None" -da1 0
		 		-label2 "Internal" -da2 1
		 		-label3 "All" -da3 2 -select 2
		polySmoothKeepMapBorders;

        //setUITemplate -popTemplate;

	setParent $tab;
    columnLayout polySmoothMethodLinear;

	frameLayout -label "Linear Smoothing Controls" -labelAlign "center"
		-borderStyle "etchedIn" -cl false -cll false;
		columnLayout;

	  intSliderGrp -label "Subdivision Levels"   -min 1 -max 4 -s 1 polySmoothNumIter;

	  // linear options
	  intSliderGrp -label "Divisions Per Face"   -min 1 -max 10 -s 1 polySmoothEdivisions;
	  floatSliderGrp -label "Push Strength"  -min -1 -max 1 -s 0.1  polySmoothVolume;
	  floatSliderGrp -label "Roundness" -min -10 -max 10 -s 1 polySmoothRoundness;

	setParent $parent;

	string $applyBtn = getOptionBoxApplyBtn();
	button -edit -label "Smooth"
	       -command ($callback + " " + $parent + " " + 1)
		$applyBtn;
	string $saveBtn = getOptionBoxSaveBtn();
	button -edit 
		-command ($callback + " " + $parent + " " + 0 + "; hideOptionBox")
		$saveBtn;
	string $resetBtn = getOptionBoxResetBtn();
	button -edit 
		-command ($setup + " " + $parent + " " + 1)
		$resetBtn;
			 

	setOptionBoxTitle("Polygon Smooth Options");

	//	Customize the 'Help' menu item text.
	//
	setOptionBoxHelpTag( "PolygonsSmooth" );

	eval (($setup + " " + $parent + " " + 0));      
	showOptionBox();
}

global proc string performPolySmooth (int $option)
{
	string $cmd="";

	switch ($option) {
	case 0:
		setOptionVars(false);
		int $mth = `optionVar -query polySmoothMethod` - 1;
		int $dv = `optionVar -query polyDivisions`;
		float $cont = `optionVar -query polyContinuity`;
		int $kb = `optionVar -query polySmoothKeepBorder`;
		int $ksb = `optionVar -query polySmoothKeepSelectionBorder`;
		int $khe = `optionVar -query polySmoothKeepHardEdge`;
		int $kt = `optionVar -query polySmoothKeepTesselation`;
		int $kmb = `optionVar -query polySmoothKeepMapBorders` -1;
		int $suvs = `optionVar -query polySmoothSmoothUVs`;

		// linear options
		int $niter = `optionVar -query polySmoothNumIter`;
		int $ediv = `optionVar -query polySmoothEdivisions`;
        float $volume = `optionVar -query polySmoothVolume`;
        float $roundness = `optionVar -query polySmoothRoundness`;

		$cmd = "polySmooth " + " -mth " + $mth  // + " -sd " + $sd + " -tr " + $tr
			+ " -dv " + $dv + " -c "
			+ $cont + " -kb " + $kb + " -ksb " + $ksb + " -khe " + $khe + " -kt " + $kt
			+ " -kmb " + $kmb + " -suv " + $suvs
			+ " -sl " + $niter + " -dpe " + $ediv + " -ps " + $volume + " -ro " + $roundness;

		// Get the current value of the "Convert Selection" option var. Then
		// set the value of the optionVar to do the selection conversion
		// and finally set it back to the original value, after the operation
		// has been performed. This is so that the operation succeeds even when
		// the object (not faces) is selected and "Convert Selection" is not
		// toggled on.
		//
		int $origConvertSelVarValue = `optionVar -query polyAutoConvertAction`;
		optionVar -intValue polyAutoConvertAction 1;
		
		// standard polySmooth
		polyPerformAction $cmd f 0;

		// Set the "Convert Selection" option var back to original state.
		//
		optionVar -intValue polyAutoConvertAction $origConvertSelVarValue;
		break;

	case 1:
		polySmoothOptions;
		break;

	default:
		setOptionVars(false);
		int $mth = `optionVar -query polySmoothMethod` - 1;
		int $dv = `optionVar -query polyDivisions`;
		float $cont = `optionVar -query polyContinuity`;
		int $kb = `optionVar -query polySmoothKeepBorder`;
		int $ksb = `optionVar -query polySmoothKeepSelectionBorder`;
		int $khe = `optionVar -query polySmoothKeepHardEdge`;
		int $kt = `optionVar -query polySmoothKeepTesselation`;
		int $kmb = `optionVar -query polySmoothKeepMapBorders` - 1;
		int $suvs = `optionVar -query polySmoothSmoothUVs`;

		// linear options
		int $niter = `optionVar -query polySmoothNumIter`;
		int $ediv = `optionVar -query polySmoothEdivisions`;
        float $volume = `optionVar -query polySmoothVolume`;
        float $roundness = `optionVar -query polySmoothRoundness`;

		// Get the current value of the "Convert Selection" option var. Then
		// set the value of the optionVar to do the selection conversion
		// and finally set it back to2 the original value, after the operation
		// has been performed. This is so that the operation succeeds even when
		// the object (not faces) is selected and "Convert Selection" is not
		// toggled on.
		//
		int $origConvertSelVarValue = `optionVar -query polyAutoConvertAction`;
		optionVar -intValue polyAutoConvertAction 1;

		// standard polySmooth
		$cmd = "polySmooth " + " -mth " + $mth
			+ " -dv " + $dv + " -c "
			+ $cont + " -kb " + $kb + " -ksb " + $ksb + " -khe "
			+ $khe + " -kt " + $kt + " -kmb " + $kmb + " -suv " + $suvs
			+ " -sl " + $niter + " -dpe " + $ediv + " -ps "
			+ $volume + " -ro " + $roundness;
		$cmd = ("polyPerformAction \"" + $cmd + "\" f 0");

		// Set the "Convert Selection" option var back to original state.
		//
		optionVar -intValue polyAutoConvertAction $origConvertSelVarValue;

	}

	return $cmd;
}

