// =========================================================================== // 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 along V of a NURBS Surface to // the specified range [a,b]. // LIMITATIONS : // 1. The NURBS surface should have NO history. // 2. The "reparametrize" keeps no history. // 3. a < b. // How to use: select a nurbs Surface (eg. surface1) and enter these commands to // reparameterize the surface along V from 0 to 10: // // reparameterizeNurbsSurfaceAlongV -10 10; // performs the reparameterization // getAttr surface1.minValueV; // will return -10 // getAttr surface1.maxValueV; // will return 10 // nurbsSurfaceKnotsAlongV; // will print knot vector of selected surface along V // // 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 buildTemporarySurface( float $knotsU[], int $degu, int $nsu, int $fu, float $knotsV[], int $degv, int $nsv, int $fv) // // Description : // To build a temporary surface // { int $nu = size($knotsU) ; if( $nu == 0 || $nsu == 0 ) return " " ; int $nv = size($knotsV) ; if( $nv == 0 || $nsv == 0 ) return " " ; int $i, $j ; // append degree. // string $args ; $args = "surface " ; $args = $args + " -du " + $degu ; $args = $args + " -dv " + $degv ; // knot sequence along U. // for( $i = 0 ; $i < $nu ; $i++ ) { $args = $args + " -ku " + $knotsU[$i] ; } // knot sequence along V. // for( $i = 0 ; $i < $nv ; $i++ ) { $args = $args + " -kv " + $knotsV[$i] ; } // form u. // string $formU ; if( $fu == 0 ) $formU = " open " ; else if( $fu == 1 ) $formU = " closed " ; else $formU = " periodic " ; $args = $args + " -fu " + $formU ; // form v. // string $formV ; if( $fv == 0 ) $formV = " open " ; else if( $fv == 1 ) $formV = " closed " ; else $formV = " periodic " ; $args = $args + " -fv " + $formV ; // control points // int $ncvu = $degu + $nsu ; int $ncvv = $degv + $nsv ; for( $i = 0 ; $i < $ncvu ; $i++ ) { for( $j = 0 ; $j < $ncvv ; $j++ ) { float $v = 0.0 ; $args = $args + " -p " + $v ; $args = $args + " " + $v ; $args = $args + " " + $v ; } // for $j } // for $i. string $srfName = eval($args) ; return $srfName ; } proc int rebuildSurfaceToMatchKnots( string $srf, string $matchSrf, int $dir ) // // Description : // { int $ok = 1 ; string $nodes[] ; if( catch( $nodes = `rebuildSurface -ch false -rpo true -fr false -dir $dir -rt 2 $srf $matchSrf` ) ) { string $dirStr = (uiRes("m_reparameterizeNurbsSurfaceAlongV.kUandV")) ; if ($dir == 0 ) $dirStr = (uiRes("m_reparameterizeNurbsSurfaceAlongV.kU")) ; if( $dir == 1 ) $dirStr = (uiRes("m_reparameterizeNurbsSurfaceAlongV.kV")) ; string $wstr = (uiRes("m_reparameterizeNurbsSurfaceAlongV.kWarningRebuildFailed")) ; warning `format -s $dirStr $wstr` ; $ok = 0 ; } return $ok ; } global proc int reparameterizeNurbsSurfaceAlongV( float $startParm, float $endParm ) // // Description : // To reparametrize the knot sequence of the nurbs surface // along U to be in the range [$startParm, $endParam]. // NOTE : works on a NURBS surface of the selection list. // { // valid parameters ? // if( $startParm >= $endParm ) { error (uiRes("m_reparameterizeNurbsSurfaceAlongV.kErrorStartParamBiggerThanEnd")) ; return 0 ; } // 0. Grab the select list. // string $selList[] ; $selList = `ls -sl` ; // 1. Run filter to select only the NURBS curves. // global int $gSelectNurbsSurfacesBit ; string $srfList[] ; $srfList = `filterExpand -ex true -sm $gSelectNurbsSurfacesBit $selList` ; if( size($srfList) == 0 ) { warning (uiRes("m_reparameterizeNurbsSurfaceAlongV.kWarningNoSurfaceSelected")) ; return 1; } // 2. Work on the last item if more than one NURBS surface in list. // int $len = size($srfList) ; string $lastSrf = $srfList[$len-1] ; if( $len != 1 ) { string $w = (uiRes("m_reparameterizeNurbsSurfaceAlongV.kWarningReparameterizingKnots")); warning `format -s $lastSrf $w` ; } // 2.0 Check if surface has history. // string $hist[] = `listHistory -gl true -pdo true -lf true -f false $lastSrf` ; if( size($hist) > 0 ) { error (uiRes("m_reparameterizeNurbsSurfaceAlongV.kErrorSurfaceHasHistory")) ; return 1 ; } // 2.1 Get the degree. // int $degu ; string $inAttr = $lastSrf + ".degreeU" ; $degu = `getAttr $inAttr` ; int $degv ; $inAttr = $lastSrf + ".degreeV" ; $degv = `getAttr $inAttr` ; int $nsu ; $inAttr = $lastSrf + ".su" ; $nsu = `getAttr $inAttr` ; int $nsv ; $inAttr = $lastSrf + ".sv" ; $nsv = `getAttr $inAttr` ; int $fu ; $inAttr = $lastSrf + ".fu" ; $fu = `getAttr $inAttr` ; int $fv ; $inAttr = $lastSrf + ".fv" ; $fv = `getAttr $inAttr` ; // 3. Extract the Knots. // float $knotsU[] ; float $knotsV[] ; select -r $lastSrf ; $knotsU = nurbsSurfaceKnotsAlongU() ; $knotsV = nurbsSurfaceKnotsAlongV() ; // 4. Scale the Knot Sequence to lie in between [$startParm, $endParm]. // float $sKnotsV[] ; $sKnotsV = rescale( $knotsV, $startParm, $endParm ) ; // 5. Build a temporary surface with the scaled Knots // int $okay = 1 ; string $tmpSurface ; $tmpSurface = buildTemporarySurface( $knotsU, $degu, $nsu, $fu, $sKnotsV, $degv, $nsv, $fv ) ; if( $tmpSurface == " " ) { $okay = 0 ; } // 6. Rebuild surface inplace to match knots in the V direction. // if( $okay == 1 ) { int $dir = 1 ; // rebuild in V. $okay = rebuildSurfaceToMatchKnots( $lastSrf, $tmpSurface, $dir ) ; delete $tmpSurface ; } // 7. select surface for which knots are reparameterized. // select -r $lastSrf ; return $okay ; }