diff options
| author | Ben Marsh <[email protected]> | 2019-10-22 09:07:59 -0400 |
|---|---|---|
| committer | Ben Marsh <[email protected]> | 2019-10-22 09:07:59 -0400 |
| commit | bd0027e737c6512397f841c22786274ed74b927f (patch) | |
| tree | f7ffbdb8f3741bb7f24635616cc189cba5cb865c /scripts/shaveRenderman.mel | |
| download | shave-and-a-haircut-bd0027e737c6512397f841c22786274ed74b927f.tar.xz shave-and-a-haircut-bd0027e737c6512397f841c22786274ed74b927f.zip | |
Adding Shave-and-a-Haircut 9.6
Diffstat (limited to 'scripts/shaveRenderman.mel')
| -rw-r--r-- | scripts/shaveRenderman.mel | 528 |
1 files changed, 528 insertions, 0 deletions
diff --git a/scripts/shaveRenderman.mel b/scripts/shaveRenderman.mel new file mode 100644 index 0000000..192ea29 --- /dev/null +++ b/scripts/shaveRenderman.mel @@ -0,0 +1,528 @@ +// Shave and a Haircut +// (c) 2019 Epic Games +// US Patent 6720962 + +global string $shaveRenderman_fileVersion = "$Revision$"; + + +// WARNING: The rman plugin may not be loaded when this script gets +// sourced so all references to commands from that plugin +// (e.g. 'rman', 'rmanGetGlobals', 'RiReadArchive') must be +// executed within an 'eval' otherwise the results will be +// unpredictable. + +global int $gShave_rmanPluginIsLoaded = false; +global int $gShave_rmanWaitingForPlugin = false; +global string $gShave_rmanArchiveFiles[]; + + +// Local Procedures + +// We need this because all of Maya's native string search commands take +// some kind of pattern and we don't want any "special chars" in our +// search. +proc int strIndex(string $needle, string $haystack) +{ + int $needleLen = size($needle); + int $haystackLen = size($haystack); + int $i; + + for ($i = 1; $i <= ($haystackLen - $needleLen) + 1; $i++) + { + if (substring($haystack, $i, $i + $needleLen - 1) == $needle) + return $i; + } + + return 0; +} + + +proc string getRManGlobals() +{ + string $globals = ""; + + if (exists("rmanGetGlobals")) { + $globals = rmanGetGlobals(); + } + + return $globals; +} + + +// Returns the version of RenderMan for Maya as a float. +// +proc float getRfMVersion() +{ + float $version = 0.0; + + if (`pluginInfo -q -loaded RenderMan_for_Maya`) { + string $versionStr = eval("rman getversion"); + + // The version string will be of the form "5.5 (@1457856 Mar 16 2015)". + // We want just the version number part. + // + $version = float(match("^[0-9.]+", $versionStr)); + } + + return $version; +} + + +// Returns the version of Renderman as a float. +// +// NOTE: As of RenderMan Studio 18 the RMS version is the same as the +// Renderman version. +// +proc float getRManVersion() +{ + float $version = 0.0; + + if (`pluginInfo -q -loaded RenderMan_for_Maya`) { + string $versionStr = eval("rman getversion prman"); + + // The version string will be of the form "prman 19.0 @1457856". + // We want just the version number part. + // + $version = float(match("[0-9.]+", $versionStr)); + } + + return $version; +} + + +proc addShaderPath() +{ + // Our SLIM shader sits in the 'prman/shaders' directory beneath the + // same directory as our plugin was loaded from. Update RenderMan's shader + // path to include this directory. + // + string $pluginDir = dirname(`pluginInfo -q -path shaveNode`); + RiOption("searchpath", "string shader", $pluginDir + "/prman/shaders:&"); + + // Our Bxdf lies in the 'prman/RMSnn' directory beneath the same + // directory as our plugin was loaded from, where 'nn' is the + // version of the RMS plugin currently loaded into Maya. Update + // RenderMan's rixplugin path to include this directory. + // + int $rmsVersion = int(getRManVersion()); + + if ($rmsVersion >= 19) { + RiOption("searchpath", "string rixplugin", $pluginDir + "/prman/RMS" + $rmsVersion + ":&:@"); + } +} + + +proc removeCallback(string $node, string $attr, string $callback) +{ + if (objExists($node) && `attributeExists $attr $node`) + { + string $val = getAttr($node + "." + $attr); + + // The callback might be one command buried in a string of + // semi-colon separate commands. So let's strip out all the + // possible permutations. + $val = substitute((";[ \t]*" + $callback + "[ \t]*"), $val, ""); + $val = substitute(("[ \t]*" + $callback + "[ \t]*;"), $val, ""); + $val = substitute(("[ \t]*" + $callback + "[ \t]*"), $val, ""); + + setAttr -type "string" ($node + "." + $attr) $val; + } +} + + +proc addCallback(string $node, string $attr, string $callback) +{ + if (objExists($node) && `attributeExists $attr $node`) + { + // Make sure that we're not creating multiple entries for the same + // callback by first removing any existing ones. + removeCallback($node, $attr, $callback); + + string $val = getAttr($node + "." + $attr); + + if (($val == "") || (size(`match "^[ \t]*$" $val`) > 0)) + $val = $callback; + else + $val += "; " + $callback; + + setAttr -type "string" ($node + "." + $attr) $val; + } + else + warning("Shave: can not add callback, attribute not found."); +} + + +proc waitForPlugin() +{ + global int $gShave_rmanWaitingForPlugin; + + if (!$gShave_rmanWaitingForPlugin) + { + pluginInfo -cc shave_rmanCheckNewPlugin; + $gShave_rmanWaitingForPlugin = true; + } +} + + +// Global procedures +global proc shave_rmanInit() +{ + // we do not want to set callbacks in defaultRenderGlobals when loading renderman plugin - dub|22Jun2012 + // not clear why its handled diffent way then for other renderers + //shave_rmanSetupCallbacks(); +} + +global proc shave_rmanCleanup() +{ + //aslo we want to let these get saved with the scene - dub|22Jun2012 + // not clear why its handled diffent way then for other renderers + //shave_rmanRemoveCallbacks(); +} + + +global proc shave_rmanSetupCallbacks() +{ + //print "tryint to set renderMan callbacks\n"; + + // If there's no shaveGlobals node yet then there can't be any hair in + // the scene so there's no reason to set up callbacks yet. + + //no we can not do this cut off because render will fail with this steps: + //set renderer to prman, create hair, render + //if (!objExists("shaveGlobals")) + //{ + // //warning("Shave: shaveGlobals not found "); + // return; + //} + + // If the rman plugin isn't loaded yet, we'll need to wait for it. + if (!shave_rmanPluginIsLoaded()) + { + waitForPlugin(); + //warning("Shave: renderMan is not loaded."); + return; + } + + string $globals = getRManGlobals(); + + if ($globals == "") + { + warning("Shave: renderMan globals not found. Giving up."); + return; + } + + addCallback( + $globals, + "rman__torattr___renderBeginScript", + "shave_rmanRenderStart" + ); + + addCallback( +// $globals, + "defaultRenderGlobals", +// "rman__torattr___preRenderScript", + "preRenderMel", + "shave_rmanFrameStart" + ); + + // RMS 19 and onward use an external prman instance which runs as a + // separate process. As a result all of the 'Post * MEL' scripts fire + // before the render has completed, making them basically useless. + // + // At the moment all that we do post render is to delete temp files + // generated for that render. We can instead do that using system + // commands injected into the rman stream. + // + if (getRManVersion() >= 19) { + addCallback( + $globals, + "rman__torattr___preRenderScript", + "shave_rmanSetOptions" + ); + + addCallback( + $globals, + "rman__torattr___postRenderScript", + "shave_rmanInjectCleanup" + ); + } else { + addCallback( + "defaultRenderGlobals", + "postRenderMel", + "shave_rmanFrameEnd" + ); + } + + addCallback( + $globals, + "rman__torattr___postTransformScript", + "shave_rmanInsertArchive" + ); + + //print "done.\n"; +} + + +global proc shave_rmanRemoveCallbacks() +{ + //print "renderMan callbacks removed\n"; + + string $globals = getRManGlobals(); + + removeCallback( + $globals, + "rman__torattr___renderBeginScript", + "shave_rmanRenderStart" + ); + + removeCallback( +// $globals, + "defaultRenderGlobals", +// "rman__torattr___preRenderScript", + "preRenderMel", + "shave_rmanFrameStart" + ); + + if (getRManVersion() >= 19) { + addCallback( + $globals, + "rman__torattr___preRenderScript", + "shave_rmanSetOptions" + ); + + removeCallback( + $globals, + "rman__torattr___postRenderScript", + "shave_rmanInjectCleanup" + ); + } else { + removeCallback( + "defaultRenderGlobals", + "postRenderMel", + "shave_rmanFrameEnd" + ); + } + + removeCallback( + $globals, + "rman__torattr___postTransformScript", + "shave_rmanInsertArchive" + ); +} + + +global proc shave_rmanRenderStart() +{ + global int $gShave_rmanArchiveInserted; + $gShave_rmanArchiveInserted = false; +} + + +global proc shave_rmanSetOptions() +{ + addShaderPath(); +} + + +global proc string shave_rmanFrameStart() +{ + ///////////////// dumps ////////////// + /* + string $globals = getRManGlobals(); + + $mob =`getAttr ($globals + ".rman__torattr___motionBlur")`; + print "prman: Motion Blur:"; print $mob; print "\n"; + + $cab =`getAttr ($globals + ".rman__torattr___cameraBlur")`; + print "prman: Motion Blur:"; print $cab; print "\n"; + + + $a =`getAttr ($globals + ".rman__toropt___shutterAngle")`; + print "prman: Sutter Angle:"; print $a; print "\n"; + + $o =`getAttr ($globals + ".rman__riopt__Camera_shutteropening0")`; + print "prman: Sutter Open:"; print $o; print "\n"; + + + $c =`getAttr ($globals + ".rman__riopt__Camera_shutteropening1")`; + print "prman: Sutter Close:"; print $c; print "\n"; + + + $t =`getAttr ($globals + ".rman__toropt___shutterTiming")`; + print "prman: Sutter Timing:"; print $t; print "\n"; + + + $k =`getAttr ($globals + ".rman__toropt___motionBlurType")`; + print "prman: Blur Type:"; print $k; print "\n"; + */ + ////////////////////////////////////// + + global string $gShave_rmanArchiveFiles[]; + + float $frame = `currentTime -q`; + string $dir = shaveGetTempDir(); + string $ribFile = `shaveUtil -makeTempFileName $dir "shave" ("." + $frame + ".rib")`; + + $gShave_rmanArchiveFiles = `shaveWriteRib -fullPaths $ribFile`; + + if (size($gShave_rmanArchiveFiles) == 0) return ""; + + return $gShave_rmanArchiveFiles[0]; +} + + +global proc shave_rmanFrameEnd() +{ + global string $gShave_rmanArchiveFiles[]; + + if (objExists("shaveGlobals") && !getAttr("shaveGlobals.ribKeepRibFiles")) + { + string $file; + + for ($file in $gShave_rmanArchiveFiles) + sysFile -del $file; + } + + clear $gShave_rmanArchiveFiles; +} + + +// We no longer need this but some people have it embedded in their +// renderManGlobals now so we keep it around to prevent errors. +global proc shave_rmanRenderEnd() +{ +} + + +global proc string shave_rmanGetReadArchiveCmd() +{ + global string $gShave_rmanArchiveFiles[]; + + if (size($gShave_rmanArchiveFiles) > 0) + return ("ReadArchive \"" + $gShave_rmanArchiveFiles[0] + "\""); + + return ""; +} + + +global proc shave_rmanInsertArchive() +{ + global int $gShave_rmanArchiveInserted; + + if (!$gShave_rmanArchiveInserted) { + global string $gShave_rmanArchiveFiles[]; + + // We need to insert our archive under a suitable transform node. + // Shave's group node would be fine for that, however we cannot + // guarantee that it will be named 'shaveDisplayGroup': the user may + // have renamed it or it may be prefaced by a namespace if loaded from + // a reference. + // + // Instead we'll use the group of the first hairnode to get rendered. + // + string $groups[] = shave_getDisplayGroups(); + string $group; + string $curObj = eval("rman ctxGetObject"); + + for ($group in $groups) { + if ($curObj == $group) { + // If there are multiple files the first one is the base file + // which includes all the others. So we always just want to + // emit the first one into the RIB stream. + // + if (size($gShave_rmanArchiveFiles) > 0) + { + eval("RiReadArchive(\"" + $gShave_rmanArchiveFiles[0] + "\")"); + } + + $gShave_rmanArchiveInserted = true; + break; + } + } + } +} + + +global proc shave_rmanInjectCleanup() +{ + global string $gShave_rmanArchiveFiles[]; + + if (objExists("shaveGlobals") && !getAttr("shaveGlobals.ribKeepRibFiles")) + { + string $file; + + for ($file in $gShave_rmanArchiveFiles) { + if (`about -win`) { + // Convert the file path to a Windows-friendly form. + // + $file = toNativePath($file); + + // All backslashes in the path must be escaped so that they + // don't get misinterpreted by rman's 'System' command. + // + $file = substituteAllString($file, "\\", "\\\\"); + + string $cmd = "System \"cmd.exe /x /a /c del \\\"" + $file + "\\\"\""; + RiArchiveRecord("verbatim", $cmd); + } else { + string $cmd = "System \"rm \\\"" + $file + "\\\"\""; + RiArchiveRecord("verbatim", $cmd); + } + } + } + + clear $gShave_rmanArchiveFiles; +} + + +global proc int shave_rmanPluginIsLoaded() +{ + if (`pluginInfo -q -loaded RenderMan_for_Maya`) + { + // Only the 'Pro' version supports RIB insertion so make sure that + // this is Pro. +// string $version = `pluginInfo -q -version RenderMan_for_Maya`; + +// return endsWith($version, "Pro"); + string $isProVersion = eval("exists(\"RiAttribute\")"); + + return $isProVersion; + } + + return false; +} + + +global proc shave_rmanCheckNewPlugin() +{ + print "shave_rmanCheckNewPlugin\n"; + + // There's no way to remove a pluginInfo callback if Shave is unloaded + // so let's first make sure that Shave is still loaded. + if (`pluginInfo -q -loaded shaveNode`) + { + //print "plugInfo - OK\n"; + + global int $gShave_rmanPluginIsLoaded; + + // Is the rman plugin loaded? + if (shave_rmanPluginIsLoaded()) + { + //print "rmanPluginIsLoaded - OK\n"; + + // If it wasn't loaded before then do our rman initialization. + if (!$gShave_rmanPluginIsLoaded) + { + //print "gShave_rmanPluginIsLoaded - OK\n"; + + $gShave_rmanPluginIsLoaded = true; + shave_rmanInit(); + } + } + else + { + $gShave_rmanPluginIsLoaded = false; + } + } +} + |