// =========================================================================== // 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: // Given a selected periodic curve, move the seam to the selected // point // // Limitations: // Does not reorder weights on rational curves // Requires uniform knot sequences // The created curve has no history proc float[] getNurbsCurveKnots( string $crvName ) // // Description : // { float $knots[] ; string $infoNode ; // create info Node. if( catch( $infoNode = `createNode curveInfo` ) ) { return $knots ; } // connect curve on to the info node. // string $outAttr = $crvName + ".local" ; string $inAttr = $infoNode + ".ic" ; connectAttr $outAttr $inAttr ; // read the knots. // $outAttr = $infoNode + ".knots" ; $knots = `getAttr $outAttr` ; // delete curve info node. // delete $infoNode ; // return the knots. // return $knots; } proc doMoveCurveSeam(string $crv, int $nspansToMove) { // get the curve size int $spans = eval("getAttr " + $crv + ".spans"); int $degree = eval("getAttr " + $crv + ".degree"); int $form = eval("getAttr " + $crv + ".form"); // get number of CVs int $ncvs = $spans; // array to hold shifted CVs float $cvs[]; // array to hold a single CV float $cv[3]; // move CVs and store in array int $u = 0; for($u = 0; $u<$ncvs; $u++) { $cv = eval("xform -q -ws -t " + $crv + ".cv[" + $u + "]"); int $newU = $u - $nspansToMove; if($newU < 0) $newU = $newU + $ncvs; for($dim=0; $dim<3; $dim++) { $cvs[3*$newU + $dim] = $cv[$dim]; } } // copy reordered CVs from array back to curve for($u = 0; $u<$ncvs; $u++) { for($dim=0; $dim<3; $dim++) { $cv[$dim] = $cvs[3*$u + $dim]; } eval("xform -ws -t " + $cv[0] + " " + $cv[1] + " " + $cv[2] + " " + $crv + ".cv[" + $u + "]"); } return; } global proc moveNurbsCurveSeam() { // get all selected items string $items[] = `ls -sl`; // Run filter to select only NURBS curve points global int $gSelectCurveParmPointsBit ; string $crvList[] = `filterExpand -ex true -fullPath true -sm $gSelectCurveParmPointsBit`; int $len = size($crvList) ; if( $len != 1 ) { string $msg = (uiRes("m_moveNurbsCurveSeam.kSelectSingleError")); error ($msg); return; } // get curve from selection string $crv[] = `listRelatives -fullPath -parent $items[0]`; // get the knot value of the selected isoparm string $buffer[]; tokenize $crvList[0] "[|]" $buffer; float $selectedKnot = $buffer[size($buffer) - 1]; // get degree (U or V) int $deg = eval("getAttr " + $crv[0] + ".degree"); int $form = eval("getAttr " + $crv[0] + ".form"); // check that the curve is really periodic!! if(2 != $form) { string $msg = (uiRes("m_moveNurbsCurveSeam.kNotPeriodicError")); error ($msg); return; } // get the knots float $knots[] = getNurbsCurveKnots($crv[0]); int $numKnots = size($knots); string $knotsError = (uiRes("m_moveNurbsCurveSeam.kKnotsNotUniformError")); // check that the knots are indeed uniform int $i; float $interval = $knots[1] - $knots[0]; for($i=2; $i<$numKnots; $i++) { float $newInterval = $knots[$i] - $knots[$i-1]; if(abs($newInterval - $interval) > 0.01*$interval) { error ($knotsError); } } // find the closest surface knot to the selected isoparm int $closestKnot = $deg-1; float $closestDistance = abs($selectedKnot - $knots[$deg-1]); for($i=$deg; $i<=($numKnots-$deg); $i++) { float $distance = abs($knots[$i] - $selectedKnot); if($distance < $closestDistance) { $closestDistance = $distance; $closestKnot = $i; } } // check for zero move if(($deg-1) == $closestKnot || ($numKnots-$deg) == $closestKnot) { string $msg = (uiRes("m_moveNurbsCurveSeam.kSeamLocationError")); error ($msg); return; } // do the move int $numSpansToMove = $closestKnot - ($deg-1); doMoveCurveSeam($crv[0], $numSpansToMove); return; }