// =========================================================================== // Copyright 2018 Autodesk, Inc. All rights reserved. // // Use of this software is subject to the terms of the Autodesk license // agreement provided at the time of installation or download, or which // otherwise accompanies this software in either electronic or hard copy form. // =========================================================================== // // Description : // A script to reparameterize the knot sequence of a selected NURBS Curve to // the specified range [a,b]. // // LIMITATIONS : // 1. The NURBS curve should have NO history. // 2. The "rescale" keeps no history. // 3. a < b. // // How to use: select a curve (eg. curve1) and enter these commands to // reparameterize the curve from 0 to 10: // // reparameterizeNurbsCurve 0 10; // performs the reparameterization // getAttr curve1.minValue; // will return 0 // getAttr curve1.maxValue; // will return 10 // nurbsCurveKnots; // will print knot vector of selected curve // proc float[] rescale( float $knots[], float $startParm, float $endParm ) // // Description : // To rescale the knots to lie inbetween [0,1] // { float $scaledKnots[] ; int $n = size($knots) ; if( $n == 0 ) return $scaledKnots ; float $minKnot = $knots[0] ; float $maxKnot = $knots[0] ; int $i ; // get min, max knot. // for( $i = 1 ; $i < $n ; $i++ ) { $minKnot = `min $minKnot $knots[$i]` ; $maxKnot = `max $minKnot $knots[$i]` ; } float $newMin = $startParm ; float $newMax = $endParm ; float $diff = $maxKnot - $minKnot ; float $scaleFactor = $endParm - $startParm ; float $scale = $scaleFactor / $diff ; for( $i = 0 ; $i < $n ; $i++ ) { float $v = ( $knots[$i] - $minKnot ) ; $scaledKnots[$i] = $newMin + ($v * $scale) ; } return $scaledKnots ; } proc string buildTemporaryCurve( float $knots[], int $deg, int $ns ) // // Description : // To build a temporary curve, multiple end Knots ! // { int $n = size($knots) ; if( $n == 0 || $ns == 0 ) return " " ; // append degree. // string $args ; $args = "curve" + " -d " + $deg ; int $ncv = $deg + $ns ; int $i ; // append dummy x, y, z values. // for( $i = 0 ; $i < $ncv ; $i++ ) { float $v = 0.0 ; $args = $args + " -p " + $v ; $args = $args + " " + $v ; $args = $args + " " + $v ; } // append knots. // for( $i = 0 ; $i < $n ; $i++ ) { $args = $args + " -k " ; $args = $args + $knots[$i] ; } $args = $args + " ; " ; string $crvName ; $crvName = eval($args) ; return $crvName ; } proc int rebuildCurveToMatchKnots( string $crv, string $matchCrv ) // // Description : // { int $ok = 1 ; string $nodes[] ; if( catch( $nodes = `rebuildCurve -ch false -rpo true -rt 2 -kr 1 -kcp 1 -kep 1 -kt 0 $crv $matchCrv` ) ) { warning (uiRes("m_reparameterizeNurbsCurve.kWarningRebuildToMatchKnotsFailed")) ; $ok = 0 ; } return $ok ; } global proc int reparameterizeNurbsCurve( float $startParm, float $endParm ) // // Description : // To reparametrize the knot sequence of the nurbs curve // to be in the range [$startParm, $endParam]. // NOTE : works on a NURBS curve of the selection list. // { // valid parameters ? // if( $startParm >= $endParm ) { error (uiRes("m_reparameterizeNurbsCurve.kErrorStartParamBiggerThanEnd")) ; return 0 ; } float $knotSeq[] ; // 0. Grab the select list. // string $selList[] ; $selList = `ls -sl` ; // 1. Run filter to select only the NURBS curves. // global int $gSelectNurbsCurvesBit ; string $crvList[] ; $crvList = `filterExpand -ex true -sm $gSelectNurbsCurvesBit $selList` ; if( size($crvList) == 0 ) { warning (uiRes("m_reparameterizeNurbsCurve.kWarningNoCurveSelected")) ; return 1; } // 2. Work on the last item if more than one NURBS curve in list. // int $len = size($crvList) ; string $lastCrv = $crvList[$len-1] ; if( $len != 1 ) { string $w = `format -s $lastCrv (uiRes("m_reparameterizeNurbsCurve.kReturningKnotsForLastCurve"))`; warning $w ; } // 2.0 Check if curve has history. // string $hist[] = `listHistory -gl true -pdo true -lf true -f false $lastCrv` ; if( size($hist) > 0 ) { error (uiRes("m_reparameterizeNurbsCurve.kErrorCurveHasHistory")) ; return 1 ; } // 2.1 Get the degree. // int $deg ; string $inAttr = $lastCrv + ".degree" ; $deg = `getAttr $inAttr` ; int $nspans ; $inAttr = $lastCrv + ".spans" ; $nspans = `getAttr $inAttr` ; // 3. Extract the Knots. // select -r $lastCrv ; $knotSeq = nurbsCurveKnots() ; // 4. Scale the Knot Sequence to lie in between [0,1]. // float $sKnots[] ; $sKnots = rescale( $knotSeq, $startParm, $endParm ) ; // 5. Build a temporary curve with the scaled Knots // int $okay = 1 ; string $tmpCurve ; $tmpCurve = buildTemporaryCurve( $sKnots, $deg, $nspans ) ; if( $tmpCurve == " " ) { $okay = 0 ; } // 6. Rebuild curve inplace to match knots. // if( $okay == 1 ) { $okay = rebuildCurveToMatchKnots( $lastCrv, $tmpCurve ) ; delete $tmpCurve ; } // 7. select curve for which knots are returned. // select -r $lastCrv ; return $okay ; }