// =========================================================================== // 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: 2001 // // Description: // dynExecFluidEmitterCommands executes the emitter command, createFluid // command (to create the emission object) and connectDynamic command. // // Input Arguments(): // int $isCreate -- create or add mode // isCreate == 0: try to emit from object // isCreate == 1: create emitter and fluid // isCreate == 2: create emtter and attach to existing fluid // // string $emitterCmd -- the emitter command string // // int $is2D -- 2D or 3D fluid. // // Return Value: // None. // proc string fluidFromObject( string $object ) { string $fluidShape; string $type = `objectType $object`; if ( "fluidShape" == $type || "fluidTexture3D" == $type || "fluidTexture2D" == $type) { return $object; } else { if ( "transform" == $type ) { string $shapes[] = `listRelatives -s $object`; for ( $shape in $shapes ) { $fluidShape = fluidFromObject( $shape ); if ( $fluidShape != "" ) { return $fluidShape; } } string $children[] = `listRelatives -c $object`; for ( $child in $children ) { $fluidShape = fluidFromObject( $child ); if ( $fluidShape != "" ) { return $fluidShape; } } } } return ""; } proc string firstShapeFromObject( string $object ) { string $fluidShape; string $type = `objectType $object`; if ( "transform" != $type ) { return $object; } else { string $shapes[] = `listRelatives -s $object`; return $shapes[0]; } } proc string getFluid( string $objects[] ) { string $retArray[]; for ( $obj in $objects ) { string $fluidShape = fluidFromObject( $obj ); if ( $fluidShape != "" ) { return $fluidShape; } } return ""; } proc int removeAttrsFromChannelBox( string $emitterNames[] ) // // Description: // Helper proc to remove the attrs we inherited from parent // emitter class (but don't use) from the channel box. // { int $allRemoved = true; string $attrs[] = { ".scaleRateByObjectSize" ,".useRatePP" ,".needParentUV" ,".speed" ,".spread" ,".speedRandom" ,".awayFromAxis" ,".awayFromCenter" ,".randomDirection" ,".scaleSpeedBySize" ,".displaySpeed" }; for( $e in $emitterNames ) { if( `nodeType $e` != "fluidEmitter" ) { continue; } for( $a in $attrs ) { // Try to avoid the user seeing an error message // if our attr list is out of date and the attr // doesn't exist. // string $listAttr[] = `listAttr ($e + $a)`; if( size( $listAttr ) == 0 ) { $allRemoved = false; continue; } // The attribute exists, but let's wrap this in // a catch, just in case... // if( catch( eval( "setAttr -k false " + $e + $a ) ) ) { $allRemoved = false; } } } return $allRemoved; } // // ============== dynExecFluidEmitterCommands ============== // // SYNOPSIS // Execute the fluidEmitter command and connectDynamic command. // If executing a "Create"/positional emitter command, create // one emitter, create a fluid and connect it to the emitter. // If executing an "Add" emitter command, add the emitter to // all items in the selection list, create a fluid and connect // it to the emitters. // isCreate == 0: try to emit from object // isCreate == 1: create emitter and fluid // isCreate == 2: create emtter and attach to existing fluid // global proc dynExecFluidEmitterCommands( int $version, string $args[] ) { if(( $version < 1 ) || ( size( $args ) < 17 )) { error(uiRes("m_doAppendHairCache.kIncorrectVersion")); return; } int $isCreate = $args[0]; string $emitterCmd = $args[1]; int $is2D = $args[2]; int $res2dX = $args[3]; int $res2dY = $args[4]; float $size2dX = $args[5]; float $size2dY = $args[6]; float $size2dZ = $args[7]; int $res3dX = $args[8]; int $res3dY = $args[9]; int $res3dZ = $args[10]; float $size3dX = $args[11]; float $size3dY = $args[12]; float $size3dZ = $args[13]; int $emitterParent = $args[14]; int $emitter2DParent = $args[15]; int $emitter3DParent = $args[16]; int $doParent = 0; string $selected[] = `ls -sl`; // new emitter, new fluid: // unselect anything that was selected cause we'll replace // it with the new emitter anyway if ($isCreate == 1 && size($selected) > 0) { select -cl; $selected = `ls -sl`; } // new emitter into selected fluid if ($isCreate == 2 && size($selected) == 0) { error (uiRes("m_dynExecFluidEmitterCommands.kNoFluidSelected")); return; } string $objectEmitters[]; string $fluid = getFluid( $selected ); // emit from object into selected fluid; if($isCreate == 0) { string $badSelErr = (uiRes("m_dynExecFluidEmitterCommands.kSelectContainerAndMesh")); if($fluid == "") { error $badSelErr; return; } $objectEmitters = `listRelatives -ni -s -type "nurbsSurface" -type "nurbsCurve" -type "mesh" -type "particle" $selected`; if(size($objectEmitters) == 0 ) { // maybe the user selected shapes for some reason $objectEmitters = `ls -type "nurbsSurface" -type "nurbsCurve" -type "mesh" - type "particle" $selected`; $objectEmitters = `listRelatives -p $objectEmitters`; if(size($objectEmitters) == 0 ) { error $badSelErr; return; } } select -r $objectEmitters; } string $emitterNames[] = evalEcho($emitterCmd); string $shapeToConnect; if ( $fluid == "" ) { $shapeToConnect = createFluid($is2D); if($is2D) { setAttr ($shapeToConnect + ".resolutionW") $res2dX; setAttr ($shapeToConnect + ".resolutionH") $res2dY; setAttr ($shapeToConnect + ".dimensionsW") $size2dX; setAttr ($shapeToConnect + ".dimensionsH") $size2dY; setAttr ($shapeToConnect + ".dimensionsD") $size2dZ; // If the input resolution is proportional we can enable square voxels without changing the effective resolution int $res = $res2dX; float $maxDim = $size2dX; if( $size2dY > $maxDim ){ $res = $res2dY; $maxDim = $size2dY; } setAttr( $shapeToConnect + ".baseResolution") $res; if( $res2dX == (int)((float)$res * $size2dX/$maxDim) && $res2dY == (int)((float)$res * $size2dY/$maxDim) ){ setAttr( $shapeToConnect + ".squareVoxels" ) true; } } else { setAttr ($shapeToConnect + ".resolutionW") $res3dX; setAttr ($shapeToConnect + ".resolutionH") $res3dY; setAttr ($shapeToConnect + ".resolutionD") $res3dZ; setAttr ($shapeToConnect + ".dimensionsW") $size3dX; setAttr ($shapeToConnect + ".dimensionsH") $size3dY; setAttr ($shapeToConnect + ".dimensionsD") $size3dZ; // If the input resolution is proportional we can enable square voxels without changing the effective resolution int $res = $res3dX; float $maxDim = $size3dX; if( $size3dY > $maxDim ){ $res = $res3dY; $maxDim = $size3dY; } if( $size3dZ > $maxDim ){ $res = $res3dZ; $maxDim = $size3dZ; } setAttr( $shapeToConnect + ".baseResolution") $res; if( $res3dX == (int)((float)$res * $size3dX/$maxDim) && $res3dY == (int)((float)$res * $size3dY/$maxDim) && $res3dZ == (int)((float)$res * $size3dZ/$maxDim) ){ setAttr( $shapeToConnect + ".squareVoxels" ) true; } } } else { $shapeToConnect = $fluid; } // make sure that the shape has density and velocity grids; if( `getAttr ($shapeToConnect + ".densityMethod")` != 1) { setAttr ($shapeToConnect + ".densityMethod") 2; setAttr ($shapeToConnect + ".velocityMethod") 2; } // If creating a positional emitter, connect it to the fluid // just created. // if ($isCreate > 0) { evalEcho connectDynamic -em $emitterNames[0] $shapeToConnect; // either parent the emitter to the fluid, or place // it at the world space center of the fluid, whichever // the user prefers (for the object emitter, we assume // that the user has positioned it where they want it // and we don't mess with it) if($isCreate == 2) { // adding emitter $doParent = $emitterParent; } else { // creating fluid and emitter if($is2D) $doParent = $emitter2DParent; else $doParent = $emitter3DParent; } if($doParent > 0) { string $par[]=`listRelatives -parent $shapeToConnect`; if( size($par[0])) { parent -r $emitterNames[0] $par[0]; } } else { setAttr ($emitterNames[0] + ".translateX") `objectCenter -gl -x $shapeToConnect`; setAttr ($emitterNames[0] + ".translateY") `objectCenter -gl -y $shapeToConnect`; setAttr ($emitterNames[0] + ".translateZ") `objectCenter -gl -z $shapeToConnect`; } } else { // If adding emitters to geometry, connect them all to the // fluid just created. Emitter command returns name of // owner and actual emitter. We want to use the emitter's name // in the connect command, so as to connect only that emitter // and not any others it may own. // string $connectCmd; for ($i = 0; $i < size($emitterNames)/2; $i++) { $connectCmd = $connectCmd + "connectDynamic "; $connectCmd = $connectCmd + "-em "+$emitterNames[$i*2+1]+" "; $connectCmd = $connectCmd + $shapeToConnect + "; "; // Fluids will only emit from geometry if the type is curve or surface // so look at each piece of geometry and set the type appropriately string $emitterShape = firstShapeFromObject($emitterNames[$i*2]); if(`objectType($emitterShape)` == "nurbsSurface" || `objectType($emitterShape)` == "mesh") { $connectCmd = $connectCmd + "setAttr " + $emitterNames[$i*2+1] + ".emitterType 2;"; } else if (`objectType($emitterShape)` == "nurbsCurve") { $connectCmd = $connectCmd + "setAttr " + $emitterNames[$i*2+1] + ".emitterType 3;"; } } evalEcho ($connectCmd); } // Make the new emitters selected. // The result of the "create emitter" command is // newlyCreatedFluid emitter1 // // The result of the add emitter command is // object1 emitter1 object2 emitter2 ... object_n emitter_n // select -cl; if ($isCreate > 0) { if ( $fluid == "" && size($shapeToConnect)) { // This means that a fluid shape was created // We want to add the fluid transform to the selection list // string $par[]=`listRelatives -parent $shapeToConnect`; if( size($par[0])) { select -add $par[0]; } } // Add the emitter(s) to the selection list // we want to select the emitter except when we just // created the fluid and the emitter is parented to the fluid // in which case we just want the whole thing selected once. if($isCreate != 1 || $doParent == 0) select -add $emitterNames; } else { // We want to add the fluid transform to the selection list // string $par[]=`listRelatives -parent $shapeToConnect`; if( size($par[0])) { select -add $par[0]; } for ($i = 1; $i < (size($emitterNames)); $i += 2) { select -add $emitterNames[$i]; } } removeAttrsFromChannelBox( $emitterNames ); }