// =========================================================================== // 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. // =========================================================================== // Reparameterize all selected surfaces into the range 0->1 // UNSUPPORTED SCRIPT, USE AT OWN RISK // // Description : // A script to reparameterize the knot sequence along U&V of 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. // 4. DOES NOT WORK WITH PERIODIC SURFACES // // Usage: select nurbs Surfaces and enter these commands to // reparameterize all the surface from 0 to 10: // // reparameterizeNurbsSurfaces -10 10; // performs the reparameterization // proc float[] rescale( float $knots[], float $startParm, float $endParm ) // // Description : // To rescale the knots to lie in the range [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 which will be used by // rebuild -matchKnots // { 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 : // Rebuild $srf to have the same knot seqence as $matchSrf // { 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_reparamSurfaces.kUandV")) ; if ($dir == 0 ) $dirStr = (uiRes("m_reparamSurfaces.kU")) ; if( $dir == 1 ) $dirStr = (uiRes("m_reparamSurfaces.kV")) ; if( $dir == 2 ) $dirStr = (uiRes("m_reparamSurfaces.kUV")) ; string $wstr = (uiRes("m_reparamSurfaces.kWarningRebuildFailed")) ; warning `format -s $dirStr $wstr` ; $ok = 0 ; } return $ok ; } global proc int reparameterizeNurbsSurface( string $srf, float $startParmU, float $endParmU, float $startParmV, float $endParmV ) // // Description : // To reparametrize the knot sequence of a single nurbs surface // along U&V to be in the range [$startParm, $endParam]. // { // valid parameters ? // if( ($startParmU >= $endParmU) || ($startParmV >= $endParmV)) { error (uiRes("m_reparamSurfaces.kErrorStartParamBiggerThanEnd")) ; return 0 ; } // 2.0 Check if surface has history. May be a problem if it has // string $hist[] = `listHistory -gl true -pdo true -lf true -f false $srf` ; if( size($hist) > 0 ) { print (`format -s $srf (uiRes("m_reparamSurfaces.kWarningSurfaceHasHistory"))` ); return 0; } // 2.1 Get the degree. // int $degu ; string $inAttr = $srf + ".degreeU" ; $degu = `getAttr $inAttr` ; int $degv ; $inAttr = $srf + ".degreeV" ; $degv = `getAttr $inAttr` ; int $nsu ; $inAttr = $srf + ".su" ; $nsu = `getAttr $inAttr` ; int $nsv ; $inAttr = $srf + ".sv" ; $nsv = `getAttr $inAttr` ; int $fu ; $inAttr = $srf + ".fu" ; $fu = `getAttr $inAttr` ; int $fv ; $inAttr = $srf + ".fv" ; $fv = `getAttr $inAttr` ; // 3. Extract the Knots. // float $knotsU[] ; float $knotsV[] ; select -r $srf ; $knotsU = nurbsSurfaceKnotsAlongU() ; $knotsV = nurbsSurfaceKnotsAlongV() ; // 4. Scale the Knot Sequence to lie in between [$startParm, $endParm]. // float $sKnotsU[] ; $sKnotsU = rescale( $knotsU, $startParmU, $endParmU ) ; float $sKnotsV[] ; $sKnotsV = rescale( $knotsV, $startParmV, $endParmV ) ; // 5. Build a temporary surface with the scaled Knots // int $okay = 1 ; string $tmpSurface ; $tmpSurface = buildTemporarySurface( $sKnotsU, $degu, $nsu, $fu, $sKnotsV, $degv, $nsv, $fv ) ; if( $tmpSurface == " " ) { $okay = 0 ; } // 6. Rebuild surface inplace to match knots in the U&V directions. // if( $okay == 1 ) { int $dir = 2 ; // rebuild in both U & V directions $okay = rebuildSurfaceToMatchKnots( $srf, $tmpSurface, $dir ) ; delete $tmpSurface ; // get rid of the surface to be matched } // 7. select surface for which knots are reparameterized. // select -r $srf ; return $okay ; } global proc reparamSurfaces() // // Description: // Loop over all NURBS surfaces in the selection list and // reparameterize to the range 0->1 in U and V // { // Get the selection list. string $selList[] = `ls -sl`; // Run filter to select only the NURBS surfaces global int $gSelectNurbsSurfacesBit ; string $srfList[] = `filterExpand -ex true -sm $gSelectNurbsSurfacesBit`; int $len = size($srfList) ; if( $len == 0 ) { print (uiRes("m_reparamSurfaces.kNoSurfaceSelected")) ; return; } // Loop over surfaces reparameterizing them for($srfNum = 0; $srfNum < $len; $srfNum++) { string $srf = $srfList[$srfNum] ; // surface name print (`format -s $srf (uiRes("m_reparamSurfaces.kDoingSurface"))` ); reparameterizeNurbsSurface($srf, 0, 1, 0, 1); } print ((uiRes("m_reparamSurfaces.kDone")) ); // reselect surface for which information was returned select -r $selList; }