// deformBySurface // v1.0beta2 // March 6 2000 // Soren 'kurgan' Jacobsen // kurgan@kurgan.dk (suggestions/bugreports welcome) // http://www.kurgan.dk/ // // History: // March 6: // Fixed problems with non-degree 3 deformer surfaces // **Note!: it is the CV's that are being deformed, that // means that fx. deforming a nurbs plane to a sphere // will only result in the multiknot edge CV's sticking // to de deformer surface, I havent yet found a way to // deform the editpoints of a surface, this would fix // the problem. // March 5: // Initial version released // // Usage: // Align the surfaces to be deformed with the X-Z plane // Select surfaces to deform, // and select the surface to deform by last (this _must_ // be NURB's surface!!!! // >deformBySurface // now moving the surface in the X-Z plane will move // them across the surface, moving them i Y will // move them to/from the surface. // // Description: // Basic implementation of a function similar to SI's deformbysurface // and Houdini's pastesurface. // The deformed surfaces can be moved across the surface // Construction history is preserved // The deformer surface can be deformed // Can be used as a modelling and/or animation tool // // Known bugs and limitations: // No chordlength correction // Doesnt handle moving across/too close to seams // // Future enhancements: // -Code cleanup, this script has a lot of 'garbage' code // because it is a direct dump of my work-in-progress. // -Chordlength correction // -I've got an idea to a fix for move across seams // -A on-surface locator is implemented, but I disabled it // since 'it doesnt feel right' // You can enable the codepieces if you like proc string assembleCmd () { string $cmd; $cmd = "doWrapArgList \"2\" { \"1\","; float $thresh = `optionVar -query weightThreshold`; $cmd = $cmd + "\"" + $thresh + "\","; int $limitInfl = `optionVar -q limitInfluence`; if ($limitInfl == 1) $cmd = $cmd + "\"" + `optionVar -query maxDistance` + "\""; else $cmd = $cmd + "\"0.0\""; $cmd = $cmd + " }"; return $cmd; } global proc deformBySurface() { // setting up variables etc string $sellist[]=`ls -sl`; int $numsurfaces = size($sellist) -1; string $wrapper = $sellist[$numsurfaces]; select -tgl $wrapper; string $newsellist[]=`ls -sl`; select $sellist; // creating and connecting surfaceInfoNode, so we can access its properties string $informationnode = `createNode surfaceInfo`; string $one = $sellist[$numsurfaces] + ".worldSpace"; string $two = $informationnode + ".is"; connectAttr -f $one $two; // get properties float $kulist[] = `getAttr($informationnode + ".ku")`; float $kvlist[] = `getAttr($informationnode + ".kv")`; int $Uform = getAttr($sellist[$numsurfaces] + ".formU"); int $Vform = getAttr($sellist[$numsurfaces] + ".formV"); int $Uspans = getAttr($sellist[$numsurfaces] + ".spansU"); int $Vspans = getAttr($sellist[$numsurfaces] + ".spansV"); int $Udegree = getAttr($sellist[$numsurfaces] + ".degreeU"); int $Vdegree = getAttr($sellist[$numsurfaces] + ".degreeV"); float $UminValue = getAttr($sellist[$numsurfaces] + ".minValueU"); float $UmaxValue = getAttr($sellist[$numsurfaces] + ".maxValueU"); float $VminValue = getAttr($sellist[$numsurfaces] + ".minValueV"); float $VmaxValue = getAttr($sellist[$numsurfaces] + ".maxValueV"); // prepare knotlists int $numUpoints = $Uspans + $Udegree; int $numVpoints = $Vspans + $Vdegree; float $kucenteroffset = (float($kulist[0] + $kulist[`size($kulist)`-1]))/2.0; float $kvcenteroffset = (float($kvlist[0] + $kvlist[`size($kvlist)`-1]))/2.0; // the following is for on-surface locator // float $kucenteroffset = 0; // float $kvcenteroffset = 0; // on-surface locator end float $kucenteroffset = (float($numUpoints-1.0)/2)+$Udegree-1; float $kvcenteroffset = (float($numVpoints-1.0)/2)+$Vdegree-1; string $skvlist=" "; for ($n in $kvlist) { $skvlist += " -kv " + $n; } string $skulist=" "; for ($n in $kulist) { $skulist += " -ku " + $n; } // prepare pointlist string $pointlist=" "; // for ($nu=$Udegree-2;$nu<($numUpoints+$Udegree-2);$nu++) for ($nu=$Udegree-1;$nu<($numUpoints+$Udegree-1);$nu++) { // for ($nv=($numVpoints+$Vdegree-3);$nv>$Vdegree-3;$nv--) for ($nv=$Vdegree-1;$nv<($numVpoints+$Vdegree-1);$nv++) { // $pointlist += " -p " + float(-$kucenteroffset+$kulist[$nu]) + " " + 0 +" "+ float(-$kvcenteroffset+$kvlist[$nv]); $pointlist += " -p " + (float($nu)-$kucenteroffset) + " " + 0 +" "+ ($kvcenteroffset - float($nv)); } } // create the base (undeformed) surface string $formHolder[] = {"open", "closed", "periodic"}; string $mycommand = "surface -degreeU " + $Udegree + " -degreeV " + $Vdegree + " -formU " + $formHolder[0] + " -formV " + $formHolder[0] + $pointlist + $skulist + $skvlist; string $newdeformsurf = eval($mycommand); setAttr ($newdeformsurf + ".intermediateObject") 1; // we no longer need the surfaceInfoNode, get rid of it delete $informationnode; // do the deformation(s) for ($wrp in $newsellist) { select -r $wrp; select -add $wrapper; string $doWrap = `assembleCmd`; string $wraplst[] = `eval($doWrap)`; string $wrap = $wraplst[0]; string $tmp1 = $newdeformsurf + ".worldSpace[0]"; string $tmp2 = $wrap + ".basePoints[0]"; connectAttr -f $tmp1 $tmp2; // the following is for on-surface locator // string $curveOnsurf = curveOnSurface -d 2 -uv 0.0 0.0 -k 0 -k 0 $wrapper ; // sting $expressionString = $wrp + ".translateX=" + $curveOnsurf + ".translateX;\n" + $wrp + ".translateZ=" + $curveOnsurf + ".translateY;"; // expression -s $expressionString -o $wrp -ae 1 -uc all ; // on-surface locator end } }