aboutsummaryrefslogtreecommitdiff
path: root/mayaPlug/shaveVrayRenderer.cpp
diff options
context:
space:
mode:
authorBen Marsh <[email protected]>2019-10-22 09:07:59 -0400
committerBen Marsh <[email protected]>2019-10-22 09:07:59 -0400
commitbd0027e737c6512397f841c22786274ed74b927f (patch)
treef7ffbdb8f3741bb7f24635616cc189cba5cb865c /mayaPlug/shaveVrayRenderer.cpp
downloadshave-and-a-haircut-bd0027e737c6512397f841c22786274ed74b927f.tar.xz
shave-and-a-haircut-bd0027e737c6512397f841c22786274ed74b927f.zip
Adding Shave-and-a-Haircut 9.6
Diffstat (limited to 'mayaPlug/shaveVrayRenderer.cpp')
-rw-r--r--mayaPlug/shaveVrayRenderer.cpp621
1 files changed, 621 insertions, 0 deletions
diff --git a/mayaPlug/shaveVrayRenderer.cpp b/mayaPlug/shaveVrayRenderer.cpp
new file mode 100644
index 0000000..28aa3bb
--- /dev/null
+++ b/mayaPlug/shaveVrayRenderer.cpp
@@ -0,0 +1,621 @@
+// Shave and a Haircut
+// (c) 2019 Epic Games
+// US Patent 6720962
+
+#include <ctype.h>
+#include <maya/MTypes.h>
+#include <string.h>
+
+#include "shaveIO.h"
+
+#include <maya/MAnimControl.h>
+#include <maya/MFileIO.h>
+#include <maya/MFileObject.h>
+#include <maya/MFnAttribute.h>
+#include <maya/MFnDependencyNode.h>
+#include <maya/MFnMesh.h>
+#include <maya/MFnNonAmbientLight.h>
+#include <maya/MFnSet.h>
+#include <maya/MFnTypedAttribute.h>
+#include <maya/MFnVectorArrayData.h>
+#include <maya/MGlobal.h>
+#include <maya/MItDependencyNodes.h>
+#include <maya/MSceneMessage.h>
+#include <maya/MString.h>
+#include <maya/MStringArray.h>
+#include <maya/MTime.h>
+#include <maya/MTypeId.h>
+#include <maya/MVectorArray.h>
+
+#include <time.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#ifdef _WIN32
+#define fileno _fileno
+#define fstat _fstat
+typedef struct _stat StatType;
+#include <process.h>
+#else
+#include <unistd.h>
+typedef struct stat StatType;
+#endif
+
+#include "shaveConstant.h"
+#include "shaveDebug.h"
+#include "shaveGlobals.h"
+#include "shaveHairShape.h"
+#include "shaveMaya.h"
+#include "shaveVrayRenderer.h"
+#include "shaveRender.h"
+#include "shaveRenderer.h"
+#include "shaveSDK.h"
+#include "shaveUtil.h"
+#include "shaveVraySharedFunctions.h"
+
+#if defined(OSMac_)
+#include "shaveMacCarbon.h"
+#endif
+
+#ifdef USE_VRAY
+
+static MString draFile;
+
+
+shaveVrayRenderer::shaveVrayRenderer()
+: mTimeState(shaveVrayRenderer::kAwaitingNothing)
+{
+ //MGlobal::displayInfo(" new shaveVrayRenderer");
+ exportOK = false;
+}
+
+
+shaveVrayRenderer::~shaveVrayRenderer()
+{}
+
+void shaveVrayRenderer::renderStart()
+{
+#ifdef _DEBUG
+ MGlobal::displayInfo("shaveVrayRenderer::renderStart");
+#endif
+
+ ENTER();
+
+ MGlobal::getActiveSelectionList( list );
+
+
+ char buf[200];
+ time_t t;
+ time(&t);
+ srand((unsigned int)t);
+ int r1 = rand();
+ int r2 = rand();
+ sprintf(buf,"vrayHair_%i%i.dra",r1,r2);
+ tempDra = buf;
+
+ MString fileDir;
+ MGlobal::executeCommand("eval(\"internalVar -userTmpDir\")",fileDir);
+ //MString fileName = fileDir + "vrayHair.dra";
+ MString tempFile;
+ MGlobal::executeCommand("eval(\"getAttr shaveGlobals.vrayDraFile\");",tempFile);
+ if(tempFile == "" )
+ tempFile = tempDra;
+
+ fileName = fileDir + tempFile;
+
+#if defined(OSMac_) && !defined(OSMac_MachO_)
+ MString testFile = shaveMacCarbon::makeMacFilename(fileDir + MString("vray_Shave.tmp"));
+#else
+ MString testFile = fileDir + MString("vray_Shave.tmp");
+#endif
+ ioError = true;
+ FILE* testFileH = fopen(testFile.asChar(),"w");
+ if(testFileH)
+ {
+ int nb = fprintf(testFileH,"hello");
+ if(nb == strlen("hello"))
+ ioError = false;
+
+ fclose(testFileH);
+ }
+ if(ioError)
+ {
+ MGlobal::displayError(MString("shaveVrayRenderer: can not write to dir ")+fileDir+MString(". Giving up."));
+ LEAVE();
+ return;
+ }
+ else
+ MGlobal::displayInfo(MString("shaveVrayRenderer: ")+fileDir+MString(" is writable."));
+
+ // not neeeded any more
+ //mIsAnimation = false;
+ //mFirstFrame;
+ //mIsFirstFrame= true;
+ //MSelectionList renderGlobalsList;
+ //renderGlobalsList.clear();
+ //renderGlobalsList.add("defaultRenderGlobals");
+ //if (renderGlobalsList.length() > 0)
+ //{
+ // MObject rgNode;
+ // renderGlobalsList.getDependNode(0, rgNode);
+
+ // MFnDependencyNode depFn(rgNode);
+
+ // int animOn = 0;
+ // MPlug animOnPlug = depFn.findPlug("animation");
+ // if(!animOnPlug.isNull())
+ // {
+ // animOnPlug.getValue(animOn);
+ // MGlobal::displayInfo(MString("anim ") + animOn);
+
+ // mIsAnimation = (animOn == 1);
+ // if(mIsAnimation)
+ // {
+ // MTime startF;
+ // MPlug startFPlug = depFn.findPlug("startFrame");
+ // if(!animOnPlug.isNull())
+ // {
+ // startFPlug.getValue(startF);
+ // mFirstFrame = startF;
+ // MGlobal::displayInfo(MString("start frame ") + startF.value());
+
+ // }
+ // }
+ // }
+ // else
+ // MGlobal::displayError("shave: can find plug.");
+ //}
+ //else
+ // MGlobal::displayError("shave: can not get defaultRenderGlobals.");
+
+
+ //set up vraySettings.preKeyframeMel
+ MStatus stat;
+ MSelectionList vraySettingsList;
+ vraySettingsList.add("vraySettings");
+
+ bool doCreate = false;
+ if (vraySettingsList.length() > 0)
+ {
+ MObject vraySettingsNode;
+ vraySettingsList.getDependNode(0, vraySettingsNode);
+
+ MFnDependencyNode depFn(vraySettingsNode);
+ MPlug preKeyframeMelPlug = depFn.findPlug("preKeyframeMel");
+ if(!preKeyframeMelPlug.isNull())
+ {
+ MString kf("shaveRender -vrayKeyframe");
+ stat = preKeyframeMelPlug.setValue(kf);
+ if(stat != MStatus::kSuccess)
+ MGlobal::displayError("shave: can not set vraySettings.preKeyframeMel");
+
+ }
+ else
+ MGlobal::displayError("shave: can not find vraySettings.preKeyframeMel");
+
+ }
+ else
+ {
+ //MGlobal::executeCommand("createNode -name vraySettings VRaySettingsNode");
+ //
+ //it is better to use the procedure - vrayCreateVRaySettingsNode()
+ //It will check whether the node has already been created and create it if not.
+ //It will also register vraySettings as a global node for the V-Ray renderer.
+ //This is important for render settings presets (although V-Ray will register the
+ //node even if you created it manually, but still). vrayCreateVRaySettingsNode()
+ //also creates the vraySettings node as shared which is important when referencing
+ //the particular scene in another one.
+ MGlobal::executeCommand("vrayCreateVRaySettingsNode");
+ doCreate = true;
+ }
+ if(doCreate)
+ {
+ vraySettingsList.add("vraySettings");
+ if (vraySettingsList.length() > 0)
+ {
+ MObject vraySettingsNode;
+ vraySettingsList.getDependNode(0, vraySettingsNode);
+
+ MFnDependencyNode depFn(vraySettingsNode);
+ MPlug preKeyframeMelPlug = depFn.findPlug("preKeyframeMel");
+ if(!preKeyframeMelPlug.isNull())
+ {
+ MString kf("shaveRender -vrayKeyframe");
+ stat = preKeyframeMelPlug.setValue(kf);
+ if(stat != MStatus::kSuccess)
+ MGlobal::displayError("shave: can not set vraySettings.preKeyframeMel");
+
+ }
+ else
+ MGlobal::displayError("shave: can not find vraySettings.preKeyframeMel");
+
+ }
+ else
+ MGlobal::displayError("shave: can not get vraySettings.");
+
+ }
+ //execute shave stuff
+ shaveRenderer::renderStart();
+
+ ///create shaders
+ MGlobal::executeCommand("shaveVrayShader -create -all");
+ //MGlobal::executeCommand("shaveVrayShader -addCallback");
+
+ ////forse to set stack ids
+ MObjectArray shaveShapes;
+ getRenderableShaveNodesByRenderMode(NULL, &shaveShapes);
+ for(unsigned int i = 0; i < shaveShapes.length(); i++)
+ {
+ MFnDependencyNode nodeFn(shaveShapes[i]);
+ shaveHairShape* hairShape = (shaveHairShape*)nodeFn.userNode();
+ hairShape->setStackIndex(i);
+ }
+ shaveShapes.clear();
+
+
+ LEAVE();
+}
+
+void shaveVrayRenderer::vrayKeyframeCallback()
+{
+#ifdef _DEBUG
+ MGlobal::displayInfo("shaveVrayRenderer::vrayKeyframeCallback");
+#endif
+
+ if(ioError)
+ return;
+
+ ENTER();
+
+ MStatus stat;
+ bool isFirstSample = false;
+ bool isLastSample = false;
+ int numS = 0;
+ int curS = 0;
+ stat = MGlobal::executeCommand("eval(\"vrayRenderInfo -numKeyframes\")",numS);
+ stat = MGlobal::executeCommand("eval(\"vrayRenderInfo -currentKeyframe\")",curS);
+ MTime curTime = MAnimControl::currentTime();
+
+ MString dbgStr = MString("preKeyframeMel numKeyframes: ") + numS +
+ MString(" currentKeyframe: ") + curS +
+ MString(" currentTime: ") + curTime.value();
+
+ if(numS == 1)
+ {
+ isFirstSample = true;
+ isLastSample = true;
+ }
+ else
+ {
+ shaveMaya::doMotionBlur = true;
+
+ if(curS == 0)
+ isFirstSample = true;
+
+ if(curS == numS-1)
+ isLastSample = true;
+ }
+ if(isFirstSample)
+ {
+ //not good place at all, prmitieves do not render
+ //MGlobal::executeCommand("shaveVrayShader -delete -all");
+ //MGlobal::executeCommand("shaveVrayShader -create -all");
+
+ dbgStr += MString(" << firstSample");
+ //
+ // Get the nodes to be rendered as geometry, and those to be rendered
+ // not as geometry, into two separate lists.
+ //
+ mGeometryNodes.clear();
+ mNonGeometryNodes.clear();
+
+ getRenderableShaveNodesByRenderMode(&mGeometryNodes, &mNonGeometryNodes);
+
+ //
+ // Changes in animated attributes may have changed the list of
+ // renderable shaveHairShapes. Let's update the flags telling us which
+ // types of shaveHairShapes we have.
+ //
+ bool tempHaveHair;
+ bool tempHaveInstances;
+
+ shaveUtil::classifyShaveNodes(mGeometryNodes, tempHaveHair, tempHaveInstances);
+ shaveUtil::classifyShaveNodes(mNonGeometryNodes, mHaveHair, mHaveInstances);
+
+ mHaveHair = (mHaveHair || tempHaveHair);
+ mHaveInstances = (mHaveInstances || tempHaveInstances);
+
+ //do shutter
+ //
+ //
+ // If motion blur is on, do shutter open and wait for shutter close.
+ // If motion blur is off, do both shutter open and shutter close now.
+ //
+ if (shaveMaya::doMotionBlur)
+ {
+ doShutter(curTime, shaveConstant::kShutterOpen);
+ mTimeState = kAwaitingShutterClose;
+
+ }
+ else
+ {
+ //doShutter(curTime, shaveConstant::kShutterBoth);
+ //mTimeState = kAwaitingNothing;
+ mTimeState = kAwaitingShutterBoth;
+ }
+ }
+ if(isLastSample)
+ {
+ dbgStr += MString(" << lastSample");
+
+ switch (mTimeState)
+ {
+ case kAwaitingShutterClose:
+ doShutter(curTime, shaveConstant::kShutterClose);
+
+ mTimeState = kAwaitingNothing;
+ break;
+
+ case kAwaitingShutterBoth:
+ doShutter(curTime, shaveConstant::kShutterBoth);
+
+ mTimeState = kAwaitingNothing;
+ break;
+
+ default:
+ break;
+ }
+ // joexxx
+ // SHAVEclear_stack();
+
+ //gr, too late
+ //MGlobal::executeCommand("shaveVrayShader -delete -all");
+ //MGlobal::executeCommand("shaveVrayShader -create -all");
+ }
+
+ //joexxxxxx SHAVEclear_stack();
+ //MGlobal::displayInfo(dbgStr);
+
+ LEAVE();
+}
+
+
+void shaveVrayRenderer::frameStart(const shaveGlobals::Globals& g)
+{
+#ifdef _DEBUG
+ MGlobal::displayInfo("shaveVrayRenderer::frameStart");
+#endif
+ if(ioError)
+ return;
+
+ //here it's confused at all only the last layer renders correctly
+ //MGlobal::executeCommand("shaveVrayShader -delete -all");
+ //MGlobal::executeCommand("shaveVrayShader -create -all");
+
+#if 0 //do nothing - vrayKeyframeCallback is used instead
+
+ ENTER();
+
+ shaveRenderer::frameStart(g);
+
+ //
+ // If motion blur is on, do shutter open and wait for shutter close.
+ // If motion blur is off, do both shutter open and shutter close now.
+ //
+ MTime curTime = MAnimControl::currentTime();
+
+ MGlobal::displayInfo(MString("blur ") + shaveMaya::doMotionBlur + " time " + curTime.value());
+
+ if (shaveMaya::doMotionBlur)
+ {
+ //if(mIsAnimation && mIsFirstFrame)
+ //{
+ // curTime = mFirstFrame - 0.5;//+ 1.0;
+ // MAnimControl::setCurrentTime(curTime);
+ //}
+ doShutter(curTime, shaveConstant::kShutterOpen);
+ mTimeState = kAwaitingShutterClose;
+
+ }
+ else
+ {
+ //doShutter(curTime, shaveConstant::kShutterBoth);
+ //mTimeState = kAwaitingNothing;
+
+ mTimeState = kAwaitingShutterBoth;
+ }
+ mIsFirstFrame = false;
+ LEAVE();
+
+#endif
+}
+
+void shaveVrayRenderer::render(
+ float frame, shaveConstant::ShutterState shutter,
+ const MDagPath& camera
+)
+{
+#ifdef _DEBUG
+ MGlobal::displayInfo("shaveVrayRenderer::render");
+#endif
+
+ if(ioError)
+ return;
+
+ ENTER();
+
+ bool isShutterClose = (shutter == shaveConstant::kShutterClose)
+ ||(shutter == shaveConstant::kShutterBoth);
+
+ if(isShutterClose)
+ {
+ //MString fileDir;
+ //MGlobal::executeCommand("eval(\"internalVar -userTmpDir\")",fileDir);
+ ////MString fileName = fileDir + "vrayHair.dra";
+ //MString tempFile;
+ //MGlobal::executeCommand("eval(\"getAttr shaveGlobals.vrayDraFile\");",tempFile);
+ //MGlobal::displayInfo(MString("tempFile :") + tempFile);
+ //if(tempFile == "" )
+ // tempFile = tempDra;
+
+ //fileName = fileDir + tempFile;
+
+ //MGlobal::displayInfo(MString("export :") + fileName);
+ //MGlobal::displayInfo(MString("tempDra :") + tempDra);
+
+ //SHAVEmult_vox_size(g.voxelScaling);
+
+#if defined(OSMac_) && !defined(OSMac_MachO_)
+ hfsFileName = shaveMacCarbon::makeMacFilename(fileName);
+ int res = SHAVEexport_archive((char*)hfsFileName.asChar(), voxelResolutionGlob);
+#else
+ int res = SHAVEexport_archive((char*)fileName.asChar(), voxelResolutionGlob);
+#endif
+ // SHAVEclear_stack(); //nope does not help
+
+ //I hate such approaches, but ...
+ MObjectArray vnodes;
+ FindNodesByTypeId(shaveVrayNode::typeId,vnodes);
+
+ const char *draFilename;
+#if defined(OSMac_) && !defined(OSMac_MachO_)
+ MString hfsFileName = shaveMacCarbon::makeMacFilename(fileName);
+ draFilename = hfsFileName.asChar();
+#else
+ draFilename = fileName.asChar();
+#endif
+ if(vnodes.length() > 0)
+ {
+ for(unsigned int i = 0; i < vnodes.length(); i++)
+ {
+ MFnDependencyNode dFn(vnodes[i]);
+ shaveVrayNode* vnode = (shaveVrayNode*)dFn.userNode();
+ vnode->readDraToParam(draFilename);
+ }
+ }
+
+ exportOK = (res != -1);
+ }
+ LEAVE();
+}
+
+void shaveVrayRenderer::frameEnd(const shaveGlobals::Globals& g)
+{
+ (void) g;
+#if 0 //do nothing - vrayKeyframeCallback is used instead
+ ENTER();
+
+ shaveRenderer::frameEnd(g);
+
+ LEAVE();
+#endif
+}
+void shaveVrayRenderer::renderEnd()
+{
+ //MGlobal::displayInfo("shaveVrayRenderer::renderEnd");
+
+ if(ioError)
+ return;
+
+ ENTER();
+
+ //re-set up vraySettings.preKeyframeMel
+ MStatus stat;
+ MSelectionList vraySettingsList;
+ vraySettingsList.clear();
+ vraySettingsList.add("vraySettings");
+
+ if (vraySettingsList.length() > 0)
+ {
+ MObject vraySettingsNode;
+ vraySettingsList.getDependNode(0, vraySettingsNode);
+
+ MFnDependencyNode depFn(vraySettingsNode);
+ MPlug preKeyframeMelPlug = depFn.findPlug("preKeyframeMel");
+ if(!preKeyframeMelPlug.isNull())
+ {
+ MString kf("");
+ stat = preKeyframeMelPlug.setValue(kf);
+ if(stat != MStatus::kSuccess)
+ MGlobal::displayError("shave: can not reset vraySettings.preKeyframeMel");
+
+ }
+ else
+ MGlobal::displayError("shave: can not find vraySettings.preKeyframeMel");
+
+ }
+ else
+ MGlobal::displayError("shave: can not get vraySettings.");
+
+
+ shaveRenderer::renderEnd();
+
+ MGlobal::executeCommand("shaveVrayShader -delete -all");
+ //MGlobal::executeCommand("shaveVrayShader -removeCallback");
+
+ //MString fileDir;
+ //MGlobal::executeCommand("eval(\"internalVar -userTmpDir\")",fileDir);
+ MString tempFile;
+ MGlobal::executeCommand("eval(\"getAttr shaveGlobals.vrayDraFile\");",tempFile);
+ if(fileName.length() > 0 && tempFile == "")
+ {
+ if(remove(fileName.asChar()) == -1)
+ MGlobal::displayInfo(MString("shave: can not delete ")+fileName);
+ }
+
+ MGlobal::setActiveSelectionList( list, MGlobal::kReplaceList);
+
+ LEAVE();
+}
+
+
+void shaveVrayRenderer::timeChange(const MTime& newTime)
+{
+ if(ioError)
+ return;
+
+#if 0 //do nothing - vrayKeyframeCallback is used instead
+ ENTER();
+
+ switch (mTimeState)
+ {
+ case kAwaitingShutterOpen:
+ doShutter(newTime, shaveConstant::kShutterOpen);
+
+ if (shaveRenderCancelled)
+ mTimeState = kAwaitingNothing;
+ else
+ mTimeState = kAwaitingShutterClose;
+ break;
+
+
+ case kAwaitingShutterClose:
+ doShutter(newTime, shaveConstant::kShutterClose);
+
+ mTimeState = kAwaitingNothing;
+ break;
+
+ case kAwaitingShutterBoth:
+ doShutter(newTime, shaveConstant::kShutterBoth);
+
+ mTimeState = kAwaitingNothing;
+ break;
+
+ default:
+ break;
+ }
+
+ LEAVE();
+#endif
+}
+
+bool shaveVrayRenderer::isGeomNode(const shaveHairShape* nodePtr) const
+{
+ return false;
+
+ //if (nodePtr->isInstanced()) return false;
+ //return (getRenderMode() == shaveConstant::kGeometryRender);
+}
+
+#endif //USE_VRAY