/* This file downloaded from Highend3d.com '' '' Highend3d.com File Information: '' '' Script Name: ks_mapSpreadInstances '' Author: katisss '' Last Updated: Dec 08, 2007 '' Update/Change this file at: '' http://Highend3d.com/maya/downloads/mel_scripts/modeling/misc/1808.html '' '' Please do not alter any information above this line '' it is generated dynamically by Highend3d.com and will '' be changed automatically on any updates. */ /* // ks_mapSpreadInstances.mel (Beta) by Katrin Schmid 2007, http://www.lo-motion.de // A basic (rivet inspired) map spreader for arbitrary poly surfaces. Places maya hair follicles where ground objects texture is white or grey (treshold) and none where it is black. Constraints instaces of poly objects to follicles. Works with Maya Unlimed only. Ground surface can still be changed (i.e. smoothed) after spreading. Install: Put ks_mapSpreadInstances.mel in you script directory. Start the GUI by typing "ks_mapSpreadInstances" in the script editor. Features: Spreads und constrains instances of a poly objects on a poly ground object. Ground object UVs must be non-overlapping and in 0-1 range. Usage: 1)Place hair follicles: Select ground object. Assign a texture to the color channel of a maya shader (no mentalray shaders supported yet). The black and white values of your texture determinated object density. Choose UV-range and grid density and hit "Place follicles on selected". Repeat until you like the density. "Treshold" and "Falloff" control the placement of objects in grey areas. If "Randomize Placement" is off follicles are set in a regular grid. The best way to get random placement is to add several different grid densities with high random values. 2)Place spread poly objects: Select object to spread. Make sure pivot is set correctly. Choose to use all follicles (pick object to spread only) or selected only (pick object to spread last). Hit "place geometry". This will place an instance of the object at follicles in the scene. Set the up-axis and random scale and rotation for the spread objects. To do: still a lot (object intersection, better random placement, handle UVs outside 0 to 1…) // //////////////////////////////////////////////////////////////////// */ //////////////////////////////////////////////////////////////////// global proc ks_mapSpreadInstances() { global string $gl_frNameSpc; if (`window -query -exists ks_mapSprInstances`) deleteUI ks_mapSprInstances; // Strings declarations string $title = " ks_mapSpreadInstances"; string $sh = "showHelp -absolute \"http://www.lo-motion.de/scripts\" "; //UI-Window window -wh 550 420 -menuBar true -title $title -s 1 ks_mapSprInstances; // Help menue menu -label "Help" -helpMenu true; menuItem -label "About" -c $sh; // Layout string $form = `formLayout`; string $child1 = `columnLayout -adjustableColumn true`; frameLayout -label "Placement:" -li 7 -borderStyle "out" -marginHeight 7 -marginWidth 10 -labelAlign "bottom"; columnLayout; rowLayout -numberOfColumns 2 -columnWidth2 400 230 -columnAlign2 "left" "left"; columnLayout -rowSpacing 6 -cal left -cat left 1 col2 ; // text -w 100 -align "left" -fn boldLabelFont -l "Placement:"; floatSliderGrp -field true -l "Treshold:" -cw2 2 5 -cat 1 left 1 -minValue .1 -maxValue 1 -fieldMinValue .1 -fieldMaxValue 1 -precision 2-step .05 -value .5 fs_treshold; floatSliderGrp -field true -l "Fall off:" -cw2 2 5 -cat 1 left 1 -minValue .1 -maxValue 1 -fieldMinValue .1 -fieldMaxValue 1 -precision 2 -step .05 -value .5 fs_fallOff; setParent ..; columnLayout -rowSpacing 3 -cal left -cat left 1 col3; setParent ..; setParent ..; // rowLayout -numberOfColumns 1 ; columnLayout -rowSpacing 3 ; separator -w 400; text -w 100 -align "left" -fn boldLabelFont -l "UV range:"; setParent ..; setParent ..; // rowLayout -numberOfColumns 4 -columnWidth2 400 230 -columnAlign2 "left" "left"; columnLayout -rowSpacing 8 -cal left -cat left 1; text -label "U min: "; text -label "U max: "; setParent ..; columnLayout -rowSpacing 3 -cal left -cat left 1; textField -tx "0" -w 50 tx_minU; textField -tx "1" -w 50 tx_maxU; setParent ..; columnLayout -rowSpacing 8 -cal left -cat left 1; text -label "V min: "; text -label "V max: "; setParent ..; columnLayout -rowSpacing 3 -cal left -cat left 1; textField -tx "0" -w 50 tx_minV; textField -tx "1" -w 50 tx_maxV; setParent ..; setParent ..; // rowLayout -numberOfColumns 1 ; columnLayout -rowSpacing 3 ; separator -w 400; setParent ..; setParent ..; // rowLayout -numberOfColumns 2 -columnWidth2 400 230 -columnAlign2 "left" "left"; columnLayout -w 240 -rowSpacing 6 -cal left -cat left 1 col4 ; floatSliderGrp -field true -l "Density U:" -cat 1 left 1 -ct2 left left -minValue 1 -maxValue 150 -fieldMinValue 2 -fieldMaxValue 150 -precision 0 -step 1 -value 10 fs_countObjectsU; floatSliderGrp -field true -l "Density V:" -cw2 2 5 -cat 1 left 1 -minValue 1 -maxValue 150 -fieldMinValue 2.0 -fieldMaxValue 150 -precision 0 -step 1 -value 10 fs_countObjectsV; floatSliderGrp -field true -l "Randomize Placement:" -cw2 2 5 -cat 1 left 1 -minValue 0 -maxValue 1 -fieldMinValue 0 -fieldMaxValue 1 -precision 2 -step .01 -value 0 fs_randPlace; // checkBox -l "Auto-randomize grids" ch_autoRand; button -bgc .5 .7 .7 -align "left" -w 220 -l "Place follicles on selected" -c "ms_placeFol()"; setParent ..; columnLayout -w 110 -rowSpacing 3 -cal left -cat left 1 col5; setParent ..; setParent ..; //3 // rowLayout -numberOfColumns 1 ; columnLayout -rowSpacing 3 ; separator -w 400; text -w 200 -align "left" -fn boldLabelFont -l "Set up-axis for spread objects:"; setParent ..; setParent ..; // rowLayout -numberOfColumns 4 -columnWidth4 200 250 50 50 -columnAlign2 "left" "left"; columnLayout -rowSpacing 3 -cal left -cat left 1; string $collection1 = `radioCollection rc_upAxis`; string $rb1, $rb2, $rb3,$rb4, $rb5, $rb6; $rb1 = `radioButton -collection rc_upAxis -cc "ks_setUp(0)" -label "X" rb_UpX`; $rb2 = `radioButton -select -collection rc_upAxis -cc "ks_setUp(0)" -label "Y" rb_UpY`; $rb3 = `radioButton -collection rc_upAxis -label "Z" -cc "ks_setUp(0)" rb_UpZ`; string $collection2 = `radioCollection rc_fAll`; string $f1,$f2; text -l""; $f1 = `radioButton -select -collection rc_fAll -label "all follicles (pick only object to spread)" rb_af`; button -bgc .5 .7 .7 -align "left" -enable 1 -w 220 -l "Place geometry" -c "ms_placeGeo()" bu_makeGeo; setParent ..; columnLayout -rowSpacing 3 -cal left -cat left 1; $rb4 = `radioButton -collection rc_upAxis -cc "ks_setUp(0)" -label "-X" rb_UpmX`; $rb5 = `radioButton -collection rc_upAxis -cc "ks_setUp(0)" -label "-Y" rb_UpmY`; $rb6 = `radioButton -collection rc_upAxis -cc "ks_setUp(0)" -label "-Z" rb_UpmZ`; text -l""; $f2 = `radioButton -collection rc_fAll -label "selected follicles (pick object to spread last)" rb_sf`; setParent ..; columnLayout -rowSpacing 3 -cal left -cat left 1; setParent ..; columnLayout -rowSpacing 3 -cal left -cat left 1; setParent ..; setParent ..; // rowLayout -numberOfColumns 1 ; columnLayout -rowSpacing 3 ; separator -w 400; text -w 200 -align "left" -fn boldLabelFont -l "Set random:"; setParent ..; setParent ..; // rowLayout -numberOfColumns 3 -columnWidth2 150 400 -columnAlign2 "left" "left"; columnLayout -rowSpacing 3 -cal left -cat left 1 col7; floatSliderGrp -field true -l "Scale random (proportional):" //-cw2 2 5 -cc "ks_randomScale(1)" -cat 1 left 1 -minValue 0 -maxValue 1 -fieldMinValue 0 -fieldMaxValue 1 -precision 2 -step .05 -value 0 fs_scaleRandom; floatSliderGrp -field true -l "Rotate random (up axis):" // -cw2 2 5 -cc "ks_randomRotate(1)" -cat 1 left 1 -minValue 0 -maxValue 360 -fieldMinValue 0 -fieldMaxValue 360 -precision 2 -step .05 -value 0 fs_rotateRandom; checkBox -l "locators visible" -value 1 -cc "locVisibility()" ch_locVis; setParent ..; columnLayout -rowSpacing 6 -cal left -cat left 1 ; setParent ..; columnLayout -rowSpacing 6 -cal left -cat left 1 ; setParent ..; setParent ..; // setParent ..; setParent ..; setParent ..; setParent ..; showWindow ks_mapSprInstances; } ////////////////////////////////////////////////////////////// global proc ms_placeFol() { global int $gl_debug; if ($gl_debug) { print ("\n function: ms_placeFol()"); } global string $gl_flTopGrp; global string $gl_groundObj; /* float $uRange[] = `getAttr ($tmpSurf[0] + ".minMaxRangeU")`; float $vRange[] = `getAttr ($tmpSurf[0] + ".minMaxRangeV")`; */ // regular grids, random float $su= `floatSliderGrp -q -value fs_countObjectsU`; // rows float $sv= `floatSliderGrp -q -value fs_countObjectsV`; // cols in row float $randPlace=`floatSliderGrp -q -value fs_randPlace`; // float $minU=`textField -q -tx tx_minU`; float $maxU=`textField -q -tx tx_maxU`; float $minV=`textField -q -tx tx_minV`; float $maxV=`textField -q -tx tx_maxV`; float $uSteps = $maxU/($su -1); //div by zero float $vSteps = $maxV/($sv -1); float $color[]; clear $color; string $folicles[]; clear $folicles; string $sel[]=`ls -l -sl`; if(`size($sel)` > 0) { $gl_groundObj=$sel[0]; string $surf[]=`listRelatives -f -s $sel[0]`; string $sg[] = `listConnections -type "shadingEngine" $surf[0]`; string $shaderName= `connectionInfo -sfd ($sg[0]+".surfaceShader")`; //blinn1.outColor string $bufferG[]; tokenize $shaderName "." $bufferG; string $fileName= `connectionInfo -sfd ($bufferG[0]+".color")`;//file1.outColor string $bufferS[]; tokenize $fileName "." $bufferS; if (`objExists $bufferS[0]`==1) { //print ("Shader: $bufferS[0] " +$bufferS[0]+"\n"); $color= `colorAtPoint -minU $minU -minV $minV -maxU $maxU -maxV $maxV -su $su -sv $sv $bufferS[0]`; // Reihe (U), Spalte (V) vertical von unten nach oben float $u=$minU; float $v=$minV; if (`objExists $gl_flTopGrp`==0) { $gl_flTopGrp = `group -em -name ("fol_" + $surf[0])`; } progressWindow -min 0 -max `size($color)` -title "Placing follicles" -isInterruptable true; //sample grid for ($p= 0; $p < size($color); $p++) { catch(`progressWindow -e -step 1`); // print ($p+"# $u: " +$u +" $v: "+ $v +"\n"); if ($color[$p] > .3) { int $randCreate =`rand 0 ($color[$p]*10)`; if ($randCreate >= 4 ) //$randFactorV { // print (" $randCreate: " + $randCreate + "\n"); string $folTransf = eval("createNode transform -n \"follicle#\" -p " + $gl_flTopGrp); string $folShape = eval("createNode follicle -n \"follicleShape#\" -p " + $folTransf); $folicles[`size($folicles)`]=$folTransf; connectAttr -f ($surf[0] + ".worldMatrix[0]") ($folShape + ".inputWorldMatrix"); connectAttr -f ($surf[0] + ".worldMesh[0]") ($folShape + ".inputMesh"); connectAttr -f ($folShape + ".outRotate") ($folTransf+ ".rotate"); connectAttr -f ($folShape + ".outTranslate") ($folTransf+ ".translate"); string $transfGrp = `group -em -name ("constTrans_" +"#")`; parent -relative $transfGrp $folTransf; if (`objExists $folShape` && $u!=0) { setAttr ($folShape + ".parameterU") ($u); } if (`objExists $folShape` && $v!=0) { setAttr ($folShape + ".parameterV") ($v); } } } {$v=$v+ $vSteps;} // rows // print ("$u: " + $u +"\n"); if ($v > $maxV + .001) { $v=$minV; $u = $u+ $uSteps; // cols in row } progressWindow -endProgress; } } else { confirmDialog -title "Nothing selected" -message "Spread texture was not found." -button "Yes"; } } else { print ("Nothing selected."+"\n"); } select $sel[0]; } //////////////////////////////////////////////place objects global proc ms_placeGeo() { global int $gl_debug; if ($gl_debug) { print ("\n function: ms_placeGeo()"); } global string $gl_groundObj; global string $gl_flTopGrp; global string $gl_geoTopGrp; string $geo1; string $collection1 = `radioCollection -q -sl rc_upAxis`; string $collection2 = `radioCollection -q -sl rc_fAll`; float $randScale=`floatSliderGrp -q -value fs_scaleRandom`; float $randRotate=`floatSliderGrp -q -value fs_rotateRandom`; string $sel[]=`ls -l -sl`; string $folicles[]; //print ("$----------------gl_geoTopGrp: " +$gl_geoTopGrp+"\n"); if(`size($sel)` > 0) { if ($collection2 =="rb_af") { $geo1=$sel[0]; } else { $geo1=$sel[`size($sel)`-1]; } if (`objExists $gl_geoTopGrp`== 0) { $gl_geoTopGrp = `group -em -name ("geo_" + $geo1)`; } // get follicles if ($collection2 =="rb_af") { $folicles=`ls -l -type follicle`; } else { string $temp[] =`ls -l -sl`; for ($p= 0; $p < size($temp); $p++) { // print ($p+" $temp[$p]p: "+ $temp[$p] +"\n"); string $tempShape[]=`listRelatives -f -s -c $temp[$p]`; if (`nodeType $tempShape[0]`=="follicle") { $folicles[`size($folicles)`] = $tempShape[0]; } } } // parent to locator string $geo2[]=`duplicate $geo1`; string $geoCopy =$geo2[0]; xform -ws -t 0 0 0 $geoCopy; setAttr ($geoCopy+".rotateX") 0; setAttr ($geoCopy+".rotateY") 0; setAttr ($geoCopy+".rotateZ") 0; makeIdentity -apply true -t 0 -r 0 -s 1 -n 0 $geoCopy; float $geoRPivot[]=`xform -q -ws -rotatePivot $geoCopy`; string $geoLoc[]=`spaceLocator -n ("Loc_" + $geoCopy+"_#") -p $geoRPivot[0] $geoRPivot[1] $geoRPivot[2]`; parent -r $geoCopy $geoLoc[0]; catch(`waitCursor -state on`); progressWindow -min 0 -max `size($folicles)` -title "Placing objects" -isInterruptable true; for ($i= 0; $i < size($folicles); $i++) { catch(`progressWindow -e -step 1`); string $folTransf[] =`listRelatives -p $folicles[$i]`; string $obj[] =`duplicate -rr -un -instanceLeaf -name ("_spreadObj_#") $geoLoc[0]`; parent -relative $obj[0] $gl_geoTopGrp; string $constTransf[] =`listRelatives -f -c -type "transform" $folTransf[0]`; if (`objExists $gl_groundObj`) { geometryConstraint -weight .6 $gl_groundObj $obj[0]; } else if (`attributeExists "groundObj" $gl_geoTopGrp`) { $gl_groundObj= `getAttr ($gl_geoTopGrp+".groundObj")`; if (`objExists $gl_groundObj`) { geometryConstraint -weight .6 $gl_groundObj $obj[0]; } } parentConstraint -w .6 $constTransf[0] $obj[0]; string $geoObj[] =`listRelatives -c -type "mesh" $obj[0]`; } if (`attributeExists "groundObj" $gl_geoTopGrp`==0) { addAttr -ln groundObj -dt "string" $gl_geoTopGrp; } setAttr -type "string" ($gl_geoTopGrp + ".groundObj") $gl_groundObj; //-lock on select -d; ks_setUp(0); ks_randomScale(0); progressWindow -endProgress; catch(`waitCursor -state off`); } else { confirmDialog -title "Nothing selected" -message "Select object to spread." -button "Yes"; } } ////////////////////////////////////////////// global proc ks_setUp(int $setGeo) { global int $gl_debug; if ($gl_debug) { print ("\n function: ks_setUp()" + $setGeo); } global string $gl_geoTopGrp; if (`objExists $gl_geoTopGrp`== 0 && $setGeo==1) { string $sel[]=`ls -l -sl`; if (size($sel)>0) { $gl_geoTopGrp= $sel[0]; } else { confirmDialog -title "Nothing selected" -message "Select top group of geometry objects to set axis" -button "Yes"; } } // print ("$1----------------gl_geoTopGrp: " +$gl_geoTopGrp+"\n"); string $collection1 = `radioCollection -q -sl rc_upAxis`; if (`objExists $gl_geoTopGrp`) { string $loc[]=`listRelatives -f -c $gl_geoTopGrp`; for ($i= 0; $i < size($loc); $i++) { string $obj[] =`listRelatives -f -c -type "transform" $loc[$i]`; // print ("$obj[0]: "+ $obj[0]+"\n"); if (`objExists $obj[0]` && `nodeType $obj[0]`=="transform" ) { switch ($collection1) { case "rb_UpX": setAttr ($obj[0]+".rotateX") 0; setAttr ($obj[0]+".rotateY") 270; setAttr ($obj[0]+".rotateZ") 0; break; case "rb_UpmX": setAttr ($obj[0]+".rotateX") 0; setAttr ($obj[0]+".rotateY") 90; setAttr ($obj[0]+".rotateZ") 0; break; case "rb_UpY": setAttr ($obj[0]+".rotateX") 90; setAttr ($obj[0]+".rotateY") 0; setAttr ($obj[0]+".rotateZ") 0; break; case "rb_UpmY": setAttr ($obj[0]+".rotateX") 270; setAttr ($obj[0]+".rotateY") 0; setAttr ($obj[0]+".rotateZ") 0; break; case "rb_UpZ": setAttr ($obj[0]+".rotateX") 0; setAttr ($obj[0]+".rotateY") 0; setAttr ($obj[0]+".rotateZ") 0;// break; case "rb_UpmZ": setAttr ($obj[0]+".rotateX") 0; setAttr ($obj[0]+".rotateY") -180 ; setAttr ($obj[0]+".rotateZ") 0;// break; } } } } select -d; ks_randomRotate($setGeo); } ////////////////////////////////////////////// global proc ks_randomRotate(int $setGeo) { global int $gl_debug; if ($gl_debug) { print ("\n function: ks_randomRotate()"+ $setGeo); } global string $gl_geoTopGrp; if (`objExists $gl_geoTopGrp`== 0 && $setGeo==1) { string $sel[]=`ls -l -sl`; if (size($sel)>0 ) { $gl_geoTopGrp= $sel[0]; } else { confirmDialog -title "Nothing selected" -message "Select top group of geometry objects to set rotation" -button "Yes"; } } //print ("$2----------------gl_geoTopGrp: " +$gl_geoTopGrp+"\n"); if (`objExists $gl_geoTopGrp`) { string $loc[]=`listRelatives -f -c $gl_geoTopGrp`; float $randR =`floatSliderGrp -q -value fs_rotateRandom`; string $collection1 = `radioCollection -q -sl rc_upAxis`; float $rand; for ($i= 0; $i < size($loc); $i++) { string $obj[] =`listRelatives -f -c -type "transform" $loc[$i]`; if ($randR >0) { $rand= `rand (-360 * $randR/360) (360 * $randR/360)`; // print ("rand]: "+ $rand +"\n"); if(`objExists $obj[0]`) { switch ($collection1) { case "rb_UpX": case "rb_UpmX": setAttr ($obj[0]+".rotateX") $rand; // rotate -r -os $rand 0 0 $obj[0]; break; case "rb_UpY": case "rb_UpmY": setAttr ($obj[0]+".rotateY") $rand; // rotate -r -os 0 $rand 0 $obj[0]; break; case "rb_UpZ": case "rb_UpmZ": setAttr ($obj[0]+".rotateZ") $rand; //rotate -r -os 0 0 $rand $obj[0]; break; } } } else { string $collectionUp = `radioCollection -q -sl rc_upAxis`; if(`objExists $obj[0]`) { switch ($collectionUp) { case "rb_UpX": case "rb_UpmX": setAttr ($obj[0]+".rotateX") 0; break; case "rb_UpY": case "rb_UpmY": setAttr ($obj[0]+".rotateY") 0; break; case "rb_UpZ": case "rb_UpmZ": setAttr ($obj[0]+".rotateZ") 0;// break; } } } } } select -d; } //////////////////////// global proc ks_randomScale(int $setGeo) { global int $gl_debug; if ($gl_debug) { print ("\n function: ks_randomScale()"+ $setGeo); } global string $gl_geoTopGrp; if (`objExists $gl_geoTopGrp`== 0 && $setGeo==1) { string $sel[]=`ls -l -sl`; if (size($sel)>0 ) { $gl_geoTopGrp= $sel[0]; } else { confirmDialog -title "Nothing selected" -message "Select top group of geometry objects to set scale" -button "Yes"; } } // print ("3$----------------gl_geoTopGrp: " +$gl_geoTopGrp+"\n"); if (`objExists $gl_geoTopGrp`) { string $loc[]=`listRelatives -f -c $gl_geoTopGrp`; float $randScale=`floatSliderGrp -q -value fs_scaleRandom`; float $rand; for ($i= 0; $i < size($loc); $i++) { string $obj[] =`listRelatives -f -c -type "transform" $loc[$i]`; if ($randScale >0) { $rand= `rand (abs(1 - $randScale)) ($randScale+1)`; } else { $rand=1; } if (`objExists $obj[0]`) { setAttr ($obj[0]+".scaleX") $rand; setAttr ($obj[0]+".scaleY") $rand ; setAttr ($obj[0]+".scaleZ") $rand;// } } } select -d; } ////////////////////////////////////////////////////////// global proc locVisibility() { global int $gl_debug; if ($gl_debug) { print ("\n function: locVisibility()"); } string $panels[]= `getPanel -type modelPanel`; int $onOff= `checkBox -q -value ch_locVis`; for ($p = 0; $p < size($panels); $p++) { //print ("$panels[$p] "+$panels[$p]+"\n"); modelEditor -e -locators $onOff $panels[$p]; } }