// =========================================================================== // 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. // =========================================================================== // // // // Creation Date: Feb 1999 // // // Attach the template brush to the selected nurbs curves. // proc float convertToCmFactor() { string $unit = `currentUnit -q -linear`; if( $unit == "mm" ){ return( 0.1 ); } else if( $unit == "cm" ){ return( 1.0 ); } else if( $unit == "m" ){ return( 100.0 ); } else if( $unit == "in" ){ return( 2.54 ); } else if( $unit == "ft" ){ return( 30.48 ); } else if( $unit == "yd" ){ return( 91.44 ); } else { return( 1.0 ); } } proc string addCurveKnots( string $cmd, int $deg, int $numCvs ) { if( $deg==1 ){ return $cmd; } int $i; for( $i = 1; $i < $deg; $i++ ){ $cmd = ($cmd + " -k 0"); } for( $i = 0; $i <= $numCvs-$deg; $i++ ){ $cmd = ($cmd + " -k "+$i); } for( $i = 1; $i < $deg; $i++ ){ $cmd = ($cmd + " -k "+($numCvs-1)); } return $cmd; } proc string makeCosIfNear( string $curve, string $obj ) { float $maxCOSdist = 0.5; string $newCurve = ""; string $clPos = `createNode closestPointOnSurface`; connectAttr ($obj + ".worldSpace[0]") ($clPos + ".inputSurface"); /* float $minU = `getAttr ($obj+".mnu")`; float $maxU = `getAttr ($obj+".mxu")`; float $sizeU = $maxU - $minU; float $minV = `getAttr ($obj+".mnv")`; float $maxV = `getAttr ($obj+".mxv")`; float $sizeV = $maxV - $minV; */ int $numCvs = `getAttr -size( $curve + ".cp")`; string $curveCv = ($curve + ".cv["); int $degree = getAttr($curve + ".degree"); string $cmd = "curveOnSurface -d "+$degree; int $i; for( $i = 0; $i < $numCvs; $i++ ){ float $cv[] = `xform -q -ws -t ($curveCv + $i + "]")`; setAttr ($clPos + ".inPosition") -type double3 $cv[0] $cv[1] $cv[2]; $closestU = getAttr( $clPos + ".parameterU"); $closestV = getAttr( $clPos + ".parameterV"); if( $i == 0 ){ // test if point near float $pos[] = getAttr ($clPos + ".position"); float $xd = $pos[0] - $cv[0]; float $yd = $pos[1] - $cv[1]; float $zd = $pos[2] - $cv[2]; float $dist = sqrt( $xd * $xd + $yd * $yd + $zd * $zd ); if( $dist > $maxCOSdist ){ delete $clPos; return ""; } } $closestU = getAttr( $clPos + ".parameterU"); $closestV = getAttr( $clPos + ".parameterV"); // $closestU = ($closestU + $minU)/$sizeU; // $closestV = ($closestV + $minV)/$sizeV; $cmd = ($cmd + " -uv "+$closestU+" "+$closestV); } $cmd = addCurveKnots( $cmd, $degree, $numCvs ); $cmd = ($cmd + " " + $obj); $newCurve = eval( $cmd ); delete $clPos; return $newCurve; } proc string makeComIfNear( string $curve, string $obj ) { float $maxCOMdist = 0.5; string $newCurve = ""; int $pomLoaded = `pluginInfo -query -l nearestPointOnMesh`; if( !$pomLoaded ){ loadPlugin nearestPointOnMesh; $pomLoaded = `pluginInfo -query -l nearestPointOnMesh`; if( !$pomLoaded ){ warning( (uiRes("m_convertCurvesToStrokes.kCantLoadPlugin"))); return ""; } } // The following is to overcome a units bug in the nearestPointOnMesh plugin // If at some point it correctly handles units, then we need to take out the // following conversion factor. $convertFac = convertToCmFactor(); $clPom = `createNode nearestPointOnMesh`; connectAttr ($obj + ".worldMesh") ($clPom + ".inMesh"); int $numCvs = `getAttr -size( $curve + ".cp")`; string $curveCv = ($curve + ".cv["); int $degree = getAttr($curve + ".degree"); string $cmd = "curveOnSurface -d "+$degree; int $i; for( $i = 0; $i < $numCvs; $i++ ){ float $cv[] = `xform -q -ws -t ($curveCv + $i + "]")`; setAttr ($clPom + ".inPosition") -type double3 ($cv[0]*$convertFac) ($cv[1]*$convertFac) ($cv[2]*$convertFac); if( $i == 0 ){ // test if point near float $pos[] = getAttr ($clPom + ".position"); float $xd = $pos[0] - $cv[0]; float $yd = $pos[1] - $cv[1]; float $zd = $pos[2] - $cv[2]; float $dist = sqrt( $xd * $xd + $yd * $yd + $zd * $zd ); if( $dist > $maxCOMdist ){ delete $clPom; return ""; } } $closestU = getAttr( $clPom + ".parameterU"); $closestV = getAttr( $clPom + ".parameterV"); $cmd = ($cmd + " -uv "+$closestU+" "+$closestV); } $cmd = addCurveKnots( $cmd, $degree, $numCvs ); $cmd = ($cmd + " " + $obj); $newCurve = eval( $cmd ); delete $clPom; return $newCurve; } global proc convertCurvesToStrokes() { int $i, $j, $k; string $brush = `getDefaultBrush`; string $curves[] = `ls -dag -sl -typ nurbsCurve`; string $surfaces[] = `ls -dag -sl -typ nurbsSurface`; string $meshes[] = `ls -dag -sl -typ mesh`; string $parent = ""; // Loop through every selected curve, create a stroke, and duplicate a brush. for( $i = 0; $i < size( $curves ); $i++ ) { // First, determine if the curve is a COS or just a regular curve. int $COS = 0; int $COM = 0; string $relatives[] = `listRelatives -ap -p -pa $curves[$i]`; for ($j = 0; $j < size( $relatives ); $j++) { string $testMe = $relatives[$j]; if (`nodeType $testMe` == "transform") { string $testList[] = `listRelatives -ap -p -pa $testMe`; for ($k = 0; $k < size( $testList ); $k++) { string $subTest = $testList[$k]; if (`nodeType $subTest` == "curveVarGroup") { string $testList2[] = `listRelatives -ap -p -pa $subTest`; for ($l = 0; $l < size( $testList2 ); $l++) { if (`nodeType $testList2[$l]` == "nurbsSurface") { $COS = 1; $parent = $testList2[$l]; $j = size( $relatives ); $k = size( $testList ); $l = size( $testList2 ); } else if (`nodeType $testList2[$l]` == "mesh") { $COM = 1; $parent = $testList2[$l]; $j = size( $relatives ); $k = size( $testList ); $l = size( $testList2 ); } } } else if(`nodeType $testList[$k]` == "mesh") { $COM = 1; $parent = $testList[$k]; $j = size( $relatives); $k = size( $testList ); } else { if (`nodeType $testList[$k]` == "nurbsSurface") { $COS = 1; $parent = $testList[$k]; $j = size( $relatives); $k = size( $testList ); } } } } else if (`nodeType $testMe` == "nurbsSurface") { $parent = $testMe; $COS = 1; $j = size( $relatives); } else if(`nodeType $testMe` == "mesh") { $parent = $testMe; $COM = 1; $j = size( $relatives); } } $intermediateObject = `getAttr ($curves[$i] + ".io")`; if ( $intermediateObject == 0 ) { // NOT an intermediate object. // Create a stroke. if( !$COS && !$COM ){ // If it is a 3d curve and it is near a selected object // then we make a curve on surface or poly. string $obj; for( $obj in $surfaces ){ string $crv = makeCosIfNear( $curves[$i], $obj ); if( $crv != "" ){ $COS = 1; $curves[$i] = $crv; $parent = $obj; break; } } if( !$COS ){ for( $obj in $meshes ){ string $crv = makeComIfNear( $curves[$i], $obj ); if( $crv != "" ){ $COM = 1; $curves[$i] = $crv; $parent = $obj; break; } } } } // Set the new stroke's random number seed to the loop index. This is not an ideal seed, but // this group of curves will all have different seeds at least. APP 15feb99 string $newStroke = `stroke -seed $i -pressure true`; string $newBrush[] = `duplicate -ic $brush`; brushStartSetup( $newBrush[0], 1 ); connectAttr ($newBrush[0] + ".outBrush") ($newStroke + ".brush"); connectAttr time1.outTime ($newBrush[0] + ".time"); $k = `getAttr ($curves[$i]+ ".spans")`; $k *= 6; // Scaling factor for the smoothness of the curve once converted. Currently 6 samples per span. setAttr ($newStroke + ".pathCurve[0].samples") $k; setAttr ($newStroke + ".useNormal") 0; setAttr ($newStroke + ".normalY") 1.0; setAttr ($newStroke + ".minimalTwist") true; if ( $COS == 1 ) { // the name in $curves is something like nurbsPlane->curve1: this // has illegal characters for a name so we use the default naming // string $cFS = `createNode "curveFromSurfaceCoS" -name ($curves[$i] + "cFS")`; string $cFS = `createNode "curveFromSurfaceCoS"`; // Do we need to check the index of the WS connections? connectAttr ($curves[$i] + ".ws[0]") ($cFS + ".curveOnSurface"); connectAttr ($parent + ".ws[0]") ($cFS + ".inputSurface"); connectAttr ($cFS + ".oc") ($newStroke + ".pathCurve[0].curve"); setAttr ($newStroke + ".perspective") 1; } else if( $COM == 1) { string $cFM = `createNode "curveFromMeshCoM"`; connectAttr ($curves[$i] + ".ws[0]") ($cFM + ".curveOnMesh"); connectAttr ($parent + ".worldMesh[0]") ($cFM + ".inputMesh"); connectAttr ($cFM + ".oc") ($newStroke + ".pathCurve[0].curve"); setAttr ($newStroke + ".perspective") 1; } else { connectAttr ($curves[$i] + ".ws") ($newStroke + ".pathCurve[0].curve"); setAttr ($newStroke + ".perspective") 1; } setAttr ($newStroke + ".displayPercent") 100.0; // hide $curves[$i]; // Commented out so that we do NOT hide the NURBS curves we have just converted to strokes. select $newStroke; } } }