/*
Glass along curve
Sander Mulders
(c)2006
XXL-Workshop

Start met glassCurve();
*/


global proc glassCurve() {

	if ( `window -exists glassCurveUI` ) {
    deleteUI glassCurveUI; // window verwijderen als deze al bestaat
	}

	window -t "Glass along curve Creator" -widthHeight 400 300 glassCurveUI;

	columnLayout -rowSpacing 6 -columnWidth 400;
	
	rowLayout -numberOfColumns 1;
	separator -w 400;
	setParent ..;
	
	rowLayout -numberOfColumns 1;
	text -l "Global Dimensions";
	setParent ..;

	rowLayout -numberOfColumns 1;
	floatSliderGrp -l "Height" -pre 2 -field true -minValue 0.1 -fieldMinValue 0.1 -value 2.8  height;
	setParent ..;
	
	rowLayout -numberOfColumns 1;
	floatSliderGrp -l "maxWidth" -pre 2 -field true -minValue 0.10 -maxValue 5.00 -fieldMinValue 0.10 -fieldMaxValue 10.00 -value 1.2  maxWidth;
	setParent ..;

	rowLayout -numberOfColumns 2 -columnWidth2 130 200 ;
	button -label "Use selected curve" -command "selCurve()";
	textFieldGrp -l "curve:" -enable 0 -text "" -cw2 60 190 selectedCurve;
	setParent ..;
	
	rowLayout -numberOfColumns 1;
	separator -w 400;
	setParent ..;

	rowLayout -numberOfColumns 1;
	text -l "Specific glass Dimensions";
	setParent ..;
	
	rowLayout -numberOfColumns 1;
		checkBoxGrp -l "Has thickness?" -value1 0 thicknessYN;
	setParent ..;
	
	rowLayout -numberOfColumns 1;
	floatSliderGrp -l "Specify thickness of vin" -pre 3 -field true -minValue 0.001 -fieldMinValue 0.01 -value .021 thickness;
	setParent ..;

	
	rowLayout -numberOfColumns 1;
	separator -w 400;
	setParent ..;

	rowLayout -numberOfColumns 1;
	text -l "Vin Dimensions";
	setParent ..;
	
	rowLayout -numberOfColumns 1;
		checkBoxGrp -l "Has vin?" -value1 0 vinYN;
	setParent ..;

	
	rowLayout -numberOfColumns 1;
	floatSliderGrp -l "Specify thickness of vin" -pre 3 -field true -minValue 0.001 -fieldMinValue 0.01 -value .021 vinThickness;
	setParent ..;
	
	rowLayout -numberOfColumns 1;
	floatSliderGrp -l "Specify depth of vin" -pre 2 -field true -minValue 0.05 -maxValue 1.00 -fieldMinValue 0.05  -value .2 vinDepth;
	setParent ..;

		rowLayout -numberOfColumns 1 -columnAlign1 "center";
		button -label "Create" -w 400 -align "center" -command "findPoints()";
		setParent ..; 
		

showWindow glassCurveUI;
	
}


global proc selCurve() {


	string $sl[] = `ls -sl`;
	string $curve = $sl[0];
	
	string $objType;
	string $shapes[];


	$shapes = `listRelatives -children -shapes $curve`;
	$objType = `objectType $shapes[0]`;
	
	
	if ( $objType == "nurbsCurve" ) {
		textFieldGrp -e -text $curve selectedCurve;
	} else {
		error("No curve selected");
	}
	
}


global proc calculateDimensions() {
	string $curve = `textFieldGrp -q -text selectedCurve`; // Selected Curve
	float $maxWidth = `floatSliderGrp -q -value maxWidth`; // Maximum glass width
	//float $hoogtetrap = `floatSliderGrp -q -value hoogte`; // hoogte van de trap in meters

	//Curve Length
	$curveLength = `arclen $curve`;
	
	//calculate number of panels
	int $temp1 = ($curveLength/$maxWidth); // num of panels INT
	float $temp2 = ($curveLength/$maxWidth); // num of panels FLOAT
	
	int $numPanels;
	
	if (($temp2 - $temp1) == 0) {
		$numPanels = $temp1;
	} else {
		$numPanels = $temp2+1;
	}
	
	float $width = ($curveLength/$numPanels);	


	floatField  -edit -v $curveLength curveLength;
	floatField  -edit -v $width width;
	intField  -edit -v $numPanels numPanels;

}

global proc findPoints() {
	
	// get info from the UI
	string $curve = `textFieldGrp -q -text selectedCurve`; // Selected Curve
	float $maxWidth = `floatSliderGrp -q -value maxWidth`; // Maximum glass width
	float $height = `floatSliderGrp -q -value height`; // Maximum glass width


	// first we need to rebuild the curve to a 0-1 curve
	
	int $degree; // current degree of the curve
	$degree = `getAttr ($curve+".degree")`;
	
	rebuildCurve -replaceOriginal 1 -end 1 -degree $degree -keepRange 0 -keepControlPoints 1 $curve;

	// find the first point which is at p=0 on the curve
	
	float $points[];
	$points[0] = 0;

	
	// in order to start with the loop to find the rest of the points we need to establish the second point
	// we start by creating a circle with radius of the maxWidth of the panel, 
	// then we find the intersection point between the curve and the circle
	
	$circle = `circle -nrx 0 -nry 1 -nrz 0 -r $maxWidth`;
	
	moveToParameter ($curve, $points[0], $circle[0]);
	//createPoint ($curve, $points[0]);
	
	//intersect
	string $node = `curveIntersect -ch on $circle[0] $curve`;
	// get intersection points on the curve
	float $p2[] = `getAttr ($node + ".parameter2")`;    
	
	
	if ( $p2[0] < $p2[1]) {
			$points[1] = $p2[0];
		} else {
			$points[1] = $p2[1];
		}
	
	
	moveToParameter ($curve, $points[1], $circle[0]);

	string $lines[];
	
	$lines[0] = drawCurve ($curve, $points[0], $points[1]) ;

	int $i=1;
	// loop beginnen om punten te maken
	
	float $par = $points[1];
	
	while ($par < 1.0 ) {
		
			
		int $number = size($points);

		$node = `curveIntersect -ch on $circle[0] $curve`;
		float $p2[] = `getAttr ($node + ".parameter2")`;    
		
		int $bla = size($p2);
		
		float $ps_sort[];
		
		$p2_sort = `sort $p2`;
		
		if ($p2_sort[1] - $p2_sort[0] > 0.5) {
			break;
		}
		
		if ($p2_sort[0] == 0 && $p2_sort[2] == 1) {
			$pointPos = `pointOnCurve -position -pr $p2_sort[1] $curve`;
			$points[$number] = $p2_sort[1];
		} else {
			$pointPos = `pointOnCurve -position -pr $p2_sort[$bla-1] $curve`;
			$points[$number] = $p2_sort[1];
		}
		
	
	
		// createPoint ($curve, $points[$number]);
		moveToParameter ($curve, $points[$number], $circle[0]);

		$par = $points[$number];

		//create a straight line between this point and the last one;
		
		$lines[$i] = drawCurve ($curve, $points[$number -1], $points[$number]) ;
		$i++;
		
	}

	
	//create the last line
	int $number = size($points);
	$lines[$number-1] = drawCurve ($curve, $points[$number -1], $points[0]) ;
	
	$groupGlass = `group -em -name glass`;
	
	 for ( $line in $lines) {
	 // extrude curve
		$glass = createPanel ( $line, $height);
		delete $line;
		parent $glass $groupGlass;
	 }
	
	int   $vinYN = `checkBoxGrp -q -value1 vinYN`;// thickness yes or no

	 if ($vinYN == 1) {
		 
		$groupVin = `group -em -name vinnen`;
	 	
		for ($point in $points) {
	 		$vin = createVin ($curve, $point);
			parent $vin $groupVin;
		}
	 }
	 
	 delete $circle;
}

global proc moveToParameter (string $curve, float $parameter, string $object) {
	$position = `pointOnCurve -position -pr $parameter $curve`;
	move -spr $position[0] $position[1] $position[2] $object; 
}

global proc createPoint (string $curve, float $parameter) {
	$position = `pointOnCurve -position -pr $parameter $curve`;
	curve -degree 1 -p $position[0] $position[1] $position[2];
	}

global proc string drawCurve (string $curve, float $point1, float $point2) {
	$pos1 = `pointOnCurve -position -pr $point1 $curve`;
	$pos2 = `pointOnCurve -position -pr $point2 $curve`;

	$lijn = `curve -degree 1 -p $pos1[0] $pos1[1] $pos1[2] -p $pos2[0] $pos2[1] $pos2[2]`;
	return $lijn;
}

global proc string createPanel (string $line, float $height) {
	
	nurbsToPolygonsPref -pc 1 -pt 1;
	
	$vlak = `extrude -ch true -rn false -po 1 -et 0 -upn 0 -d 0 1 0 -length $height -rotation 0 -scale 1 -dl 3 $line `;
	
	int   $thicknessYN = `checkBoxGrp -q -value1 thicknessYN`;// thickness yes or no
	float $thickness = `floatSliderGrp -q -value thickness`; // glass thickness

	if ($thicknessYN == 1 ) {
		polyExtrudeFacet -ch 1 -ltz $thickness $vlak.f[0];
	}
	
	delete -ch $vlak;
	return $vlak[0];
}

global proc string createVin (string $curve, float $origin) {

	float $height = `floatSliderGrp -q -value height`; // Maximum glass height
	float $width = `floatSliderGrp -q -value vinThickness`; // Vin width
	float $depth = `floatSliderGrp -q -value vinDepth`; // Vin depth

	
	//extrude surface to act as constraint object
	$tmp_vlak = `extrude -ch true -rn false -po 0 -et 0 -upn 0 -d 0 1 0 -length $height -dl 3 $curve` ;
	
	//make vin
	$cube = `polyCube -w $depth -h $height -d $width`;
	move ($depth/2) (-$height/2) 0 ($cube[0] + ".scalePivot") ($cube[0] + ".rotatePivot") ;
	
	moveToParameter ($curve, $origin , $cube[0]);
	
	//constrain object to the surface
	normalConstraint -weight 1 -aimVector 1 0 0 -upVector 0 1 0 -worldUpType "vector" -worldUpVector 0 1 0 $tmp_vlak $cube ;
	
	delete -ch $cube;
	delete $tmp_vlak;
	return $cube[0];
}
