diff options
Diffstat (limited to 'mayaPlug/pluginImpl.cpp')
| -rw-r--r-- | mayaPlug/pluginImpl.cpp | 509 |
1 files changed, 509 insertions, 0 deletions
diff --git a/mayaPlug/pluginImpl.cpp b/mayaPlug/pluginImpl.cpp new file mode 100644 index 0000000..b86107e --- /dev/null +++ b/mayaPlug/pluginImpl.cpp @@ -0,0 +1,509 @@ +// Shave and a Haircut +// (c) 2019 Epic Games +// US Patent 6720962 + +#include <maya/MCommonSystemUtils.h> +#include <maya/MFileIO.h> +#include <maya/MFnPlugin.h> +#include <maya/MGlobal.h> +#include <maya/MShaderManager.h> +#include <maya/MString.h> +#include <maya/MViewport2Renderer.h> + +#include "isSharedCmd.h" +#include "libShave.h" +#include "pluginImpl.h" +#include "shaveBackgroundShader.h" +#include "shaveBlindData.h" +#include "shaveBrushCtxCmd.h" +#include "shaveBrushManip.h" +#include "shaveCutCtxCmd.h" +#include "shaveDebug.h" +#include "shaveCallbacks.h" +#include "shaveGeometryOverride.h" +#include "shaveGlobals.h" +#include "shaveHairShape.h" +#include "shaveHairUI.h" +#include "shaveIconCmd.h" +#include "shaveInfo.h" +#include "shaveNode.h" +#include "shaveNodeCmd.h" +#include "shavePadCmd.h" +#include "shaveRenderCmd.h" +#include "shaveSDK.h" +#include "shaveShadowNode.h" +#include "shaveStyleCmd.h" +#include "shaveTextureStore.h" +#include "shaveUtilCmd.h" +#include "shaveWriteHairCmd.h" +#include "shaveVertexShader.h" +#include "shaveVolumeShader.h" +/// vlad|22Apr2010 -- include vray stuff +#include "shaveVrayNode.h" +#include "shaveVrayCmd.h" +/// vlad|15Jun2011 -- procedurals +#include "shaveProceduralsCmd.h" +/// vlad|32apr2013 -- exp to image +#include "shavePack2TexCmd.h" +#include "shaveExportGame.h" + +#if !defined(OSMac_CFM_) && (!defined(_DEBUG) || defined(LINUX)) +#include "shaveWriteRib.h" +#endif + +#include <maya/MDrawRegistry.h> + +// We use these flags to keep track of what has been registered. If we +// get a failure partway through plugin initialization these will allow +// the plugin to be unloaded without incurring even more errors. +// +static bool blindShaveData_isRegistered = false; + +static bool isSharedCmd_isRegistered = false; +static bool shaveBrushCtxCmd_isRegistered = false; +static bool shaveCutCtxCmd_isRegistered = false; +static bool shaveIconCmd_isRegistered = false; +static bool shaveInfo_isRegistered = false; +static bool shaveNodeCmd_isRegistered = false; +static bool shavePadCmd_isRegistered = false; +static bool ShavePreprocTex_isRegistered = false; +static bool shaveRenderCmd_isRegistered = false; +static bool shaveStyleCmd_isRegistered = false; +static bool shaveUtilCmd_isRegistered = false; +static bool shaveWriteHairCmd_isRegistered = false; +#if !defined(OSMac_CFM_) && (!defined(_DEBUG) || defined(LINUX)) +static bool shaveWriteRib_isRegistered = false; +#endif +static bool shaveRepair_isRegistered = false; +static bool shavePurge_isRegistered = false; + +static bool shaveBackgroundShader_isRegistered = false; +static bool shaveBrushManip_isRegistered = false; +static bool shaveGlobals_isRegistered = false; +static bool shaveHairShape_isRegistered = false; +static bool shaveNode_isRegistered = false; +static bool shaveShadowNode_isRegistered = false; +static bool shaveVertexShader_isRegistered = false; +static bool shaveVolumeShader_isRegistered = false; + + +static void popupError(MString title, MString msg) +{ + MGlobal::displayError(msg); + +#if 0 + // If you once had Shave hair in a scene but no longer do it's still + // possible to end up with a 'requires' command in the scene file + // which loads Shave. If you later try to edit that scene on a machine + // which doesn't have Shave properly installed, you'll get these error + // msgs. + // + // Users can live with the error msgs as they are used to them from + // other plugins that fail their 'requires'. However they dislike + // having to dismiss dialog boxes to continue working, so we've now + // ifdefed out the popup dialogs + + if (MGlobal::mayaState() == MGlobal::kInteractive) + { + MString cmd; + + cmd = MString("confirmDialog -title \"") + title + + "\" -button \"OK\" -message \"" + msg + "\""; + + MGlobal::executeCommand(cmd); + } +#endif +} + + +// +// Plugin Registration +// +MStatus shaveInitializePlugin(MObject obj) +{ + MStatus st; + MString msg; + MFnPlugin plugin(obj, "2019 Epic Games Maya Shave.", "1.1", "Any"); + + SHAVEinit(); + + // Before we go any further, let's make sure that the version of the + // scripts matches the version of the plugin. + // + MString pluginVersion(SHAVEquery_version()); + int haveVersionCmd; + + MGlobal::executeCommand("exists shaveVersion", haveVersionCmd); + + // Let's say that the user starts Maya and tries to load shave but + // finds a mismatch. They leave Maya running while they copy the + // correct scripts into their script directory. They then try loading + // the plugin again. However, Maya will still have the old version of + // the 'shaveVersion' command stored in memory. So we have to source + // it to be sure that we get the new one. + // + if (haveVersionCmd && !MGlobal::executeCommand("source shaveVersion")) + haveVersionCmd = false; + + if (!haveVersionCmd) + { + msg = "Cannot find the 'shaveVersion.mel' script. Shave appears\\n" + "to not be properly installed on this machine. Please try\\n" + "reinstalling Shave. If the problem persists then send mail\\n" + "to [email protected]"; + + popupError("Shave Installation Error", msg); + + return MS::kFailure; + } + + MString scriptVersion; + + MGlobal::executeCommand("shaveVersion", scriptVersion); + + if (scriptVersion != pluginVersion) + { + msg = MString("There is a mismatch between the Shave plugin, which is") + + " for version " + pluginVersion + " of Shave, and the Shave" + + " scripts, which are for version " + scriptVersion + " of Shave."; + + popupError("Shave Version Mismatch", msg); + + return MS::kFailure; + } + + // + // Register Data Types. + // + // Must be done before registering any nodes which use them. + // + REGISTER_DATA(blindShaveData) + + // + // Register Nodes. + // + st = plugin.registerShape( shaveHairShape::nodeTypeName, + shaveHairShape::id, + &shaveHairShape::creator, + &shaveHairShape::initialize, + &shaveHairUI::creator, + &shaveHairShape::drawDbClassification ); + + if (!st) + st.perror("register shaveHairShape."); + else + shaveHairShape_isRegistered = true; + + st = plugin.registerNode( shaveBrushManip::nodeTypeName, + shaveBrushManip::id, + &shaveBrushManip::creator, + &shaveBrushManip::initialize, + MPxNode::kManipContainer, + &shaveBrushManip::drawDbClassification ); + + if (!st) + st.perror("register shave Brush."); + else + shaveBrushManip_isRegistered = true; + + REGISTER_NODE(shaveGlobals, kDependNode, 0) + REGISTER_NODE(shaveShadowNode, kDependNode, 0) + + // + // We need this to be able to load and convert pre-4.0 scenes. + // + REGISTER_NODE(shaveNode, kDependNode,0) + + // + // The following are all render nodes, but only shaveBackgroundShader + // is accessible to users. By not giving the others classification + // strings they won't show up in the Hypershade window and users + // won't be tempted to use them. + // + MString classification("shader/surface"); + + REGISTER_NODE(shaveBackgroundShader, kDependNode, &classification) + REGISTER_NODE(shaveVertexShader, kDependNode, 0) + REGISTER_NODE(shaveVolumeShader, kDependNode, 0) + + // + // Register Commands. + // + REGISTER_CMD(shaveRepair) + REGISTER_CMD(shavePurge) + REGISTER_CMD(isSharedCmd) + REGISTER_CMD(shaveIconCmd) + REGISTER_CMD(shaveInfo); + REGISTER_CMD(shaveNodeCmd) + REGISTER_CMD(shavePadCmd) + REGISTER_CMD(ShavePreprocTex) + REGISTER_CMD(shaveRenderCmd) + REGISTER_CMD(shaveStyleCmd) + REGISTER_CMD(shaveUtilCmd) + REGISTER_CMD(shaveWriteHairCmd) +#if !defined(OSMac_CFM_) && (!defined(_DEBUG) || defined(LINUX)) + REGISTER_CMD(shaveWriteRib) +#endif + + + REGISTER_CTX_CMD(shaveBrushCtxCmd); + REGISTER_CTX_CMD(shaveCutCtxCmd); + +#ifdef USE_VRAY + // vlad|22Apr2010 - register stuff needed by V-Ray + //register the node + const MString vclassification(shaveVrayNode::classification); + st = plugin.registerNode( shaveVrayNode::typeName, + shaveVrayNode::typeId, + shaveVrayNode::creator, + shaveVrayNode::initialize, + MPxNode::kDependNode, + &vclassification); + if (!st) + st.perror("register shaveVrayNode."); + + //register command + st = plugin.registerCommand(shaveVrayCmd::cmd, + shaveVrayCmd::creator, + shaveVrayCmd::newSyntax); + if (!st) + st.perror("register shaveVrayCmd."); + +#endif + +#ifdef USE_PROCEDURALS + st = plugin.registerCommand(shaveProceduralsCmd::cmd, + shaveProceduralsCmd::creator, + shaveProceduralsCmd::newSyntax); + if (!st) + st.perror("register shaveProceduralsCmd."); +#endif + + st = MHWRender::MDrawRegistry::registerGeometryOverrideCreator( + shaveHairShape::drawDbClassification, + shaveHairShape::drawRegistrantId, + shaveGeometryOverride::Creator); + if (!st) + st.perror("register shaveGeometryOverride."); + +#if MAYA_API_VERSION >= 201600 + st = shaveGeometryOverride::registerComponentConverters(); + if (!st) + { + st.perror("register shaveGeometryOverride component converters"); + } +#endif + + st = MHWRender::MDrawRegistry::registerGeometryOverrideCreator( + shaveBrushManip::drawDbClassification, + shaveBrushManip::drawRegistrantId, + shaveBrushOverride::Creator); + if (!st) + st.perror("register shaveBrushOverride."); + + //register command + st = plugin.registerCommand(shavePack2TexCmd::cmd, + shavePack2TexCmd::creator, + shavePack2TexCmd::newSyntax); + if (!st) + st.perror("register shavePack2TexCmd."); + + st = plugin.registerCommand(shaveExportGame::cmd, + shaveExportGame::creator, + shaveExportGame::newSyntax); + if (!st) + st.perror("register shaveExportGame."); + + if (MGlobal::mayaState() == MGlobal::kInteractive) + { + // Register selection type for the entire hair object. + // + int meshPriority = MSelectionMask::getSelectionTypePriority("polymesh"); + + if (!MSelectionMask::registerSelectionType(shaveHairShape::kShapeSelectionMaskName, meshPriority)) + { + std::cerr << "Error registering '" + << shaveHairShape::kShapeSelectionMaskName + << "' selection type." << std::endl; + } + + // Add it to Maya's 'Surface' component menu. + // + st = MGlobal::executeCommand( + MString("addSelectTypeItem(\"Surface\", \"") + + shaveHairShape::kShapeSelectionMaskName + + "\", \"Shave Hair\")" + ); + if (!st) + { + st.perror("addSelectTypeItem"); + } + } + + // Normally, we initialize SHAVE just before starting a new scene. + // However, the plugin will typically be loaded into a scene after it + // has already been started, so we have to force the initialization + // here. + // + shaveCallbacks::prepareForNewScene(true); + + // Allow our CFGX shaders (and anyone else's, really) to be relocated + // to the directory set in the SHAVE_SHADER_PATH envariable. + // + MString shaderPath = MCommonSystemUtils::getEnv("SHAVE_SHADER_PATH"); + + if (shaderPath.length() > 0) + { + MHWRender::MRenderer::theRenderer()->getShaderManager()->addShaderPath(shaderPath); + } + + // We used to call the 'shaveUI' command ('shaveInit', actually) + // directly, but that caused problems when the plugin was loaded + // via a referenced file because the so-called "permanent" nodes, + // such as defaultRenderGlobals, might not yet exist which then led to + // many problems. By using registerUI() we're guaranteed that Maya + // will have finished its own initialization before we do ours. + // + // However, even while disabled, the nodes can still call certain + // basic MEL utility procedures, such as shaveExpandTempFilePath(), + // so we must still force the sourcing of 'shaveUI.mel' right away, + // rather than waiting until Maya calls shaveUI() for us. + MGlobal::executeCommand("source shaveUI.mel"); //goes up 06may2014 + plugin.registerUI("shaveUI", "", "shaveUI", ""); + + return st; +} + + +// +// Plugin Registration +// +MStatus shaveUninitializePlugin(MObject obj) +{ + MStatus st; + MFnPlugin plugin(obj); + + shaveCallbacks::mayaExiting(); + + // + // Remove all callbacks. + // + shaveCallbacks::removeCallbacks(); + + // We don't want to delete our hotkeySet in case the user has made + // changes to it. But we should make sure that it's not the current + // set. + // + MString keySet; + MGlobal::executeCommand("hotkeySet -q -current", keySet); + + if (keySet == "Shave_Hotkeys") + { + MGlobal::executeCommand("hotkeySet -e -current Maya_Default"); + } + +#if MAYA_API_VERSION >= 201600 + st = shaveGeometryOverride::deregisterComponentConverters(); + if (!st) + { + st.perror("deregistering shaveGeometryOverride component converters"); + } +#endif + + st = MHWRender::MDrawRegistry::deregisterGeometryOverrideCreator( + shaveHairShape::drawDbClassification, + shaveHairShape::drawRegistrantId); + if (!st) + st.perror("deregister shaveGeometryOverride."); + + st = MHWRender::MDrawRegistry::deregisterGeometryOverrideCreator( + shaveBrushManip::drawDbClassification, + shaveBrushManip::drawRegistrantId); + if (!st) + st.perror("deregister shaveBrushOverride."); + + // Deregister the various elements in the reverse order to which they + // were registered. (Reversing the order may not be essential but is + // generally the best approach to avoid problems.) + // + + if (MGlobal::mayaState() == MGlobal::kInteractive) + { + // Custom selection types. + // + st = MGlobal::executeCommand( + MString("deleteSelectTypeItem(\"Surface\", \"") + + shaveHairShape::kShapeSelectionMaskName + "\")" + ); + if (!st) + { + st.perror("deleteSelectTypeItem"); + } + + if (!MSelectionMask::deregisterSelectionType(shaveHairShape::kShapeSelectionMaskName)) + { + std::cerr << "Error deregistering '" + << shaveHairShape::kShapeSelectionMaskName + << "' selection type." << std::endl; + } + } + + DEREGISTER_CTX_CMD(shaveCutCtxCmd); + DEREGISTER_CTX_CMD(shaveBrushCtxCmd); + + DEREGISTER_CMD(shaveRepair) + DEREGISTER_CMD(shavePurge) +#if !defined(OSMac_CFM_) && (!defined(_DEBUG) || defined(LINUX)) + DEREGISTER_CMD(shaveWriteRib) +#endif + DEREGISTER_CMD(shaveWriteHairCmd) + DEREGISTER_CMD(shaveUtilCmd) + DEREGISTER_CMD(shaveStyleCmd) + DEREGISTER_CMD(shaveRenderCmd) + DEREGISTER_CMD(ShavePreprocTex) + DEREGISTER_CMD(shavePadCmd) + DEREGISTER_CMD(shaveNodeCmd) + DEREGISTER_CMD(shaveInfo) + DEREGISTER_CMD(shaveIconCmd) + DEREGISTER_CMD(isSharedCmd) + + DEREGISTER_MANIP(shaveBrushManip) + + DEREGISTER_NODE(shaveVolumeShader) + DEREGISTER_NODE(shaveVertexShader) + DEREGISTER_NODE(shaveBackgroundShader) + DEREGISTER_NODE(shaveNode) + DEREGISTER_NODE(shaveShadowNode) + DEREGISTER_NODE(shaveGlobals) + DEREGISTER_NODE(shaveHairShape) + + DEREGISTER_DATA(blindShaveData); + +#ifdef USE_VRAY + // vlad|22Apr2010 - deregister stuff needed by V-Ray + st = plugin.deregisterNode( shaveVrayNode::typeId ); + if (!st) + st.perror("deregister shaveVrayNode."); + + st = plugin.deregisterCommand( shaveVrayCmd::cmd ); + if (!st) + st.perror("deregister shaveVrayCmd."); +#endif + +#ifdef USE_PROCEDURALS + st = plugin.deregisterCommand( shaveProceduralsCmd::cmd ); + if (!st) + st.perror("deregister shaveProceduralsCmd."); +#endif + + st = plugin.deregisterCommand( shavePack2TexCmd::cmd ); + if (!st) + st.perror("deregister shavePack2TexCmd."); + + st = plugin.deregisterCommand( shaveExportGame::cmd ); + if (!st) + st.perror("deregister shaveExportGame."); + + return st; +} + |