[
  {
    "path": ".gitignore",
    "content": "## Ignore Visual Studio temporary files, build results, and\n## files generated by popular Visual Studio add-ons.\n\n# User-specific files\n*.suo\n*.user\n*.sln.docstates\n\n# Build results\n\n[Dd]ebug/\n[Rr]elease/\nx64/\nbuild/\n[Bb]in/\n[Oo]bj/\n\n# Enable \"build/\" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets\n!packages/*/build/\n\n# MSTest test Results\n[Tt]est[Rr]esult*/\n[Bb]uild[Ll]og.*\n\n*_i.c\n*_p.c\n*.ilk\n*.meta\n*.obj\n*.pch\n*.pdb\n*.pgc\n*.pgd\n*.rsp\n*.sbr\n*.tlb\n*.tli\n*.tlh\n*.tmp\n*.tmp_proj\n*.log\n*.vspscc\n*.vssscc\n.builds\n*.pidb\n*.log\n*.scc\n\n# Visual C++ cache files\nipch/\n*.aps\n*.ncb\n*.opensdf\n*.sdf\n*.cachefile\n\n# Visual Studio profiler\n*.psess\n*.vsp\n*.vspx\n\n# Guidance Automation Toolkit\n*.gpState\n\n# ReSharper is a .NET coding add-in\n_ReSharper*/\n*.[Rr]e[Ss]harper\n\n# TeamCity is a build add-in\n_TeamCity*\n\n# DotCover is a Code Coverage Tool\n*.dotCover\n\n# NCrunch\n*.ncrunch*\n.*crunch*.local.xml\n\n# Installshield output folder\n[Ee]xpress/\n\n# DocProject is a documentation generator add-in\nDocProject/buildhelp/\nDocProject/Help/*.HxT\nDocProject/Help/*.HxC\nDocProject/Help/*.hhc\nDocProject/Help/*.hhk\nDocProject/Help/*.hhp\nDocProject/Help/Html2\nDocProject/Help/html\n\n# Click-Once directory\npublish/\n\n# Publish Web Output\n*.Publish.xml\n*.pubxml\n\n# NuGet Packages Directory\n## TODO: If you have NuGet Package Restore enabled, uncomment the next line\n#packages/\n\n# Windows Azure Build Output\ncsx\n*.build.csdef\n\n# Windows Store app package directory\nAppPackages/\n\n# Others\nsql/\n*.Cache\nClientBin/\n[Ss]tyle[Cc]op.*\n~$*\n*~\n*.dbmdl\n*.[Pp]ublish.xml\n*.pfx\n*.publishsettings\n\n# RIA/Silverlight projects\nGenerated_Code/\n\n# Backup & report files from converting an old project file to a newer\n# Visual Studio version. Backup files are not needed, because we have git ;-)\n_UpgradeReport_Files/\nBackup*/\nUpgradeLog*.XML\nUpgradeLog*.htm\n\n# SQL Server files\nApp_Data/*.mdf\nApp_Data/*.ldf\n\n# =========================\n# Windows detritus\n# =========================\n\n# Windows image file caches\nThumbs.db\nehthumbs.db\n\n# Folder config file\nDesktop.ini\n\n# Recycle Bin used on file shares\n$RECYCLE.BIN/\n\n# Mac crap\n.DS_Store\n\n# Compiled Object files\n*.slo\n*.lo\n*.o\n\n# Compiled Dynamic libraries\n*.so\n*.dylib\n\n# Compiled Static libraries\n*.lai\n*.la\n*.a\n"
  },
  {
    "path": "01_API_Overview/helloWorld/Exercise - py/helloWorldCmd.py",
    "content": "# Copyright (C) \n# \n# Author: Autodesk Developer Network\n\n#For this exercise, search for the TODO keywords and follow the instructions in\n#comments. If you are unsure of what you need to do, feel free to ask the instructor\n#or look into the solution folder.\n#Each #... line is a line of code you need to write or complete.\n\n# Python script to execute to test the sample in the Maya Script Editor\n# import maya\n# maya.cmds.loadPlugin(\"helloWorldCmd.py\")\n# maya.cmds.spHelloWorld()\n\n#- Import all the necessary modules here\n#TODO: ...\n\nkPluginCmdName = \"spHelloWorld\"\n\n# class implementation for custom command\nclass scriptedCommand(OpenMayaMPx.MPxCommand):\n\t#- TODO: Add Implementation of __init__(self) and doIt(self,argList)\n\t#...\n\n# Creator\n#- TODO: Implement the creator function and apply asMPxPtr() to it\n#...\n\t\n# Initialize the script plug-in\ndef initializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\t#- TODO: Register this custom command                \n\t\t#...\n\texcept:\n\t\tsys.stderr.write( \"Failed to register command: %s\\n\" % kPluginCmdName )\n\t\traise\n\n# Uninitialize the script plug-in\ndef uninitializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\t#- TODO: Deregister this custom command                 \n\t\t#...\n\texcept:\n\t\tsys.stderr.write( \"Failed to unregister command: %s\\n\" % kPluginCmdName )\n\t\traise"
  },
  {
    "path": "01_API_Overview/helloWorld/Solution - py/helloWorldCmd.py",
    "content": "# Copyright (C) \n# \n# File: helloWorld.py\n#\n# Author: Autodesk Developer Network\n\n# Python script to execute to test the sample in the Maya Script Editor\n# import maya\n# maya.cmds.loadPlugin(\"helloWorldCmd.py\")\n# maya.cmds.spHelloWorld()\n\n#- Import all the necessary modules here\nimport sys\nimport maya.OpenMaya as OpenMaya\nimport maya.OpenMayaMPx as OpenMayaMPx\n\nkPluginCmdName = \"spHelloWorld\"\n\n# class implementation for custom command\nclass scriptedCommand(OpenMayaMPx.MPxCommand):\n\tdef __init__(self):\n\t\tOpenMayaMPx.MPxCommand.__init__(self)\n\tdef doIt(self,argList):\n\t\tprint \"Hello World!\"\n\n# Creator\ndef cmdCreator():\n\treturn OpenMayaMPx.asMPxPtr( scriptedCommand() )\n\t\n# Initialize the script plug-in\ndef initializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\tmplugin.registerCommand( kPluginCmdName, cmdCreator )\n\texcept:\n\t\tsys.stderr.write( \"Failed to register command: %s\\n\" % kPluginCmdName )\n\t\traise\n\n# Uninitialize the script plug-in\ndef uninitializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\tmplugin.deregisterCommand( kPluginCmdName )\n\texcept:\n\t\tsys.stderr.write( \"Failed to unregister command: %s\\n\" % kPluginCmdName )\n\t\traise\n"
  },
  {
    "path": "02_Commands/dagInfo/Exercise - C++/dagInfo.cpp",
    "content": "// \n// File: \n//\n// Dependency Graph Node: \n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#include \"dagInfo.h\"\n\n#include <maya/MArgList.h>\n#include <maya/MSelectionList.h>\n#include <maya/MItSelectionList.h>\n#include <maya/MGlobal.h>\n#include <maya/MDagPath.h>\n#include <maya/MDagPathArray.h>\n#include <maya/MFnDagNode.h>\n#include <maya/MMatrix.h>\n#include <maya/MFnBlendShapeDeformer.h>\n#include <maya/MFnTransform.h>\n\n//- This method performs the action of the command. It iterates over all\n//- selected items and prints out connected plug and dependency node type\n//- information.\nMStatus dagInfo::doIt(const MArgList& )\n{\n\tMStatus stat;\n\n\t//- Select all objects currently selected into the Maya editor.\n\tMSelectionList slist;\n\tMGlobal::getActiveSelectionList( slist );\n\t//- Create an iterator on the selection list (using the iterator pattern).\n\tMItSelectionList iter( slist, MFn::kDagNode,&stat );\n\n\t//- Iterate over all selected dependency nodes\n\tfor ( ; !iter.isDone(); iter.next() ) \n\t{\n\t\t\n\t\t//- get the dependency node first and then apply MFnDagNode function set onto it.\n\t\tMObject depNode;\n\t\titer.getDependNode(depNode);\n\n\t\tMFnDagNode fnDag(depNode);\n\t\tcout<<\"********************************************************\"<<endl;\n\t\tcout<<\"The selected node name is \"<<fnDag.name(&stat)<<\", node type : \"<<depNode.apiTypeStr()<<endl;\n\n\t\t//- TODO: Retrieve number of instances on this dag node\n\t\tunsigned int num = //...\n\t\tif( num != 1 )\tcout<<\"Number of instances on this node is : \"<<num<<endl;\n\t\t\n\t\tMDagPathArray dagPathArray;\n\t\t//- TODO: Retrieve all the instanced paths of this dag node, assign to \"dagPathArray\"\n\t\t//- and print out them\n\t\t//...\n\n\t\tfor(unsigned int j = 0; j < dagPathArray.length(); j++)\n\t\t{\n\t\t\tMDagPath instanceDagPath = dagPathArray[j];\n\t\t\t//- TODO: Get this instance full dag path and print it\n\t\t\tcout<<\"Dag Path \"<<j<<\" for this node:\"<< //...\n\t\t\t\t<<endl;\n\t\t\n\t\t\t//- TODO: Get the exclusive matrix of this node and print it.\n\t\t\tMMatrix exMatrix = //...\n\t\t\tcout<<\"The exclusive transformation matrix of this node is \"<<exMatrix<<endl;\n\n\t\t\t//- TODO: Get the inclusive matrix of this node and print it.\n\t\t\t//- If it is a shape node, the inclusive and exclusive matrix should be the same\n\t\t\t//- If it is a transform node and its transformation matrix is not identity, they \n\t\t\t//- should be different!\n\t\t\tMMatrix inMatrix = //...\n\t\t\tcout<<\"The inclusive transformation matrix of this node is \"<<inMatrix<<endl;\n\n\t\t\t//- TODO: Decide if this dag node is a transform node\n\t\t\t//\n\t\t\tif ( //... )\n\t\t\t{\n\t\t\t\t//- If this dag node is a transform node, also get its local transformation matrix\n\t\t\t\tMFnTransform fnTrans(instanceDagPath);\n\t\t\t\tMTransformationMatrix localMatrix = fnTrans.transformation();\n\t\t\t\tcout<<\"The local transformation matrix represented by this transform node is \"<<localMatrix.asMatrix()<<endl;\n\t\t\t}\n\t\t}\n\t}\n\n\t//- Return success to Maya\n\treturn MS::kSuccess;\n}"
  },
  {
    "path": "02_Commands/dagInfo/Exercise - C++/dagInfo.h",
    "content": "//\n// Copyright (C) \n// \n// File: dagInfo.h\n//\n// MEL Command: dagInfo\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#pragma once\n\n#include <maya/MPxCommand.h>\n\n// Command class declaration\nclass dagInfo : public MPxCommand\n{\npublic:\n\tdagInfo() {}\n\tvirtual ~dagInfo() {}\n\n\tstatic void *creator() {\n\t\treturn new dagInfo();\n\t}\n\t\n\t//- This method should perform a command by setting up internal class data\n\t//- and then calling the redoIt method if undo is supported by the command.\n\t//- The actual action performed by the command should be done in the redoIt \n\t//- method. This is a pure virtual method, and must be overridden in derived \n\t//- classes.\n\tvirtual MStatus doIt(const MArgList &);\n\n};\n"
  },
  {
    "path": "02_Commands/dagInfo/Exercise - C++/dagInfo.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 2012\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"dagInfo\", \"dagInfo.vcxproj\", \"{62B3E8DE-B8B9-4DEF-99F4-78E2EA80E56B}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|x64 = Debug|x64\n\t\tRelease|x64 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{62B3E8DE-B8B9-4DEF-99F4-78E2EA80E56B}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{62B3E8DE-B8B9-4DEF-99F4-78E2EA80E56B}.Debug|x64.Build.0 = Debug|x64\n\t\t{62B3E8DE-B8B9-4DEF-99F4-78E2EA80E56B}.Release|x64.ActiveCfg = Release|x64\n\t\t{62B3E8DE-B8B9-4DEF-99F4-78E2EA80E56B}.Release|x64.Build.0 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "02_Commands/dagInfo/Exercise - C++/dagInfo.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{62B3E8DE-B8B9-4DEF-99F4-78E2EA80E56B}</ProjectGuid>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup>\n    <_ProjectFileVersion>11.0.61030.0</_ProjectFileVersion>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <OutDir>Debug\\</OutDir>\n    <IntDir>Debug\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <OutDir>C:\\MayaAPITraining\\plug-ins\\</OutDir>\n    <TargetExt>.mll</TargetExt>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <OutDir>Release\\</OutDir>\n    <IntDir>Release\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2009\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/dagInfo.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;OpenMayaAnim.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>C:\\MayaAPITraining\\plug-ins\\dagInfo.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2009\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/dagInfo.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/dagInfo.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2015\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/dagInfo.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;OpenMayaAnim.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>C:\\MayaAPITraining\\plug-ins\\dagInfo.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2015\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/dagInfo.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/dagInfo.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/dagInfo.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\dagInfo.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/dagInfo.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/dagInfo.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/dagInfo.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\dagInfo.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/dagInfo.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/dagInfo.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"dagInfo.cpp\" />\n    <ClCompile Include=\"pluginMain.cpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"dagInfo.h\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "02_Commands/dagInfo/Exercise - C++/pluginMain.cpp",
    "content": "//\n// Copyright (C)  \n// \n// File: pluginMain.cpp\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#include <maya/MFnPlugin.h>\n#include <maya/MGlobal.h>\n#include \"dagInfo.h\"\n\nMStatus initializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is loaded into Maya.  It \n//\t\tregisters all of the services that this plug-in provides with \n//\t\tMaya.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{ \n\tMStatus   status;\n\tMFnPlugin plugin( obj, \"\", \"2009\", \"Any\");\n\n\t// Add plug-in feature registration here\n\t//\n\n\tstatus = plugin.registerCommand(\"dagInfo\",dagInfo::creator);\n\n\treturn status;\n}\n\nMStatus uninitializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is unloaded from Maya. It \n//\t\tderegisters all of the services that it was providing.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{\n\tMStatus   status;\n\tMFnPlugin plugin( obj );\n\n\t// Add plug-in feature deregistration here\n\t//\n\tstatus = plugin.deregisterCommand(\"dagInfo\");\n\n\treturn status;\n}\n"
  },
  {
    "path": "02_Commands/dagInfo/Exercise - py/dagInfo.py",
    "content": "# Copyright (C) \n# \n# Author: Autodesk Developer Network\n\n#For this exercise, search for the TODO keywords and follow the instructions in\n#comments. If you are unsure of what you need to do, feel free to ask the instructor\n#or look into the solution folder.\n#Each #... line is a line of code you need to write or complete.\n\nimport sys\nimport maya.OpenMaya as OpenMaya\nimport maya.OpenMayaMPx as OpenMayaMPx\n\n# Command name\nkPluginCmdName = \"dagInfo\"\n\n# dagInfo command\nclass dagInfo(OpenMayaMPx.MPxCommand):\n\t\n\tdef __init__(self):\n\t\tOpenMayaMPx.MPxCommand.__init__(self)\n\n\t#- This method performs the action of the command. It iterates over all\n\t#- selected items and prints out connected plug and dependency node type\n\t#- information.\n\tdef doIt(self, args):\n\t\t#- Select all objects currently selected into the Maya editor.\n\t\tslist = OpenMaya.MSelectionList()\n\t\tOpenMaya.MGlobal.getActiveSelectionList( slist )\n\t\t#- Create an iterator on the selection list (using the iterator pattern).\n\t\titer = OpenMaya.MItSelectionList( slist, OpenMaya.MFn.kDagNode )\n\n\t\t#- Iterate over all selected dependency nodes\n\t\twhile ( iter.isDone() == 0 ): \n\t\t\t#- Not getting the dag path, it will only return one path. I.e.:\n\t\t\t#dagPath = OpenMaya.MDagPath \n\t\t\t#iter.getDagPath(dagPath)\n\n\t\t\t#- Instead, get the dependency node first and then apply MFnDagNode function set onto it.\n\t\t\tdepNode = OpenMaya.MObject()\n\t\t\titer.getDependNode(depNode)\n\n\t\t\tfnDag = OpenMaya.MFnDagNode(depNode)\n\t\t\tprint \"********************************************************\"\n\t\t\tsys.stdout.write( '\\n' )\n\t\t\tprint \"The selected node name is %s\" % fnDag.name()\n\t\t\tprint \", node type : %s\" % depNode.apiTypeStr()\n\t\t\tsys.stdout.write( '\\n' )\n\n\t\t\t#- TODO: Retrieve number of instances on this dag node\n\t\t\tnum = #...\n\t\t\tif( num != 1 ):\n\t\t\t\tprint \"Number of instances on this node is : %d\" % num\n\t\t\t\tsys.stdout.write( '\\n' )\n\t\t\t\n\t\t\t# Save out the MMatrix __str__ function so we can replace it once were done\n\t\t\toldMMatrix_str = OpenMaya.MMatrix .__str__\t\t\n\t\t\t# Call my new printing function to print the matrix so that is it readable\n\t\t\tOpenMaya.MMatrix.__str__ = myMatrix_str\t\t\n\t\t\t\n\t\t\t#- TODO: Retrieve all the instanced paths of this dag node and print out them\n\t\t\tdagPathArray = OpenMaya.MDagPathArray()\n\t\t\t#...\n\t\t\tfor j in range (0, dagPathArray.length()):\n\t\t\t\tinstanceDagPath = dagPathArray[j]\n\t\t\t\t#- TODO: Get this instance full dag path and print it\n\t\t\t\t#...\n\t\t\t\t\n\t\t\t\tsys.stdout.write( '\\n' )\n\t\t\t\n\t\t\t\t#- TODO: Get the exclusive matrix of this node\n\t\t\t\texMatrix = #...\n\t\t\t\t\n\t\t\t\tprint \"The exclusive transformation matrix of this node is \"\n\t\t\t\tprint exMatrix\n\t\t\t\tsys.stdout.write( '\\n' )\n\n\t\t\t\t#- TODO: Get the inclusive matrix of this node\n\t\t\t\t#- If it is a shape node, the inclusive and exclusive matrix should be the same\n\t\t\t\t#- If it is a transform node and its transformation matrix is not identity, they \n\t\t\t\t#- should be different!\n\t\t\t\tinMatrix = #...\n\t\t\t\tprint \"The inclusive transformation matrix of this node is \"\n\t\t\t\tprint inMatrix\n\t\t\t\tsys.stdout.write( '\\n' )\n\n\t\t\t\t#- TODO: If this dag node is a transform node, also get its local transformation matrix\n\t\t\t\tif ( #... ):\n\t\t\t\t\tfnTrans = OpenMaya.MFnTransform(instanceDagPath)\n\t\t\t\t\tlocalMatrix = fnTrans.transformation()\n\t\t\t\t\tprint \"The local transformation matrix represented by this transform node is \"\n\t\t\t\t\tprint localMatrix.asMatrix()\n\t\t\t\t\tsys.stdout.write( '\\n' )\n\n\t\t\titer.next()\n\t\t\t# Replace MMatrix __str__ function to the default\n\t\t\tOpenMaya.MMatrix.__str__ = oldMMatrix_str\n\n\n# New __str__ function for Making the matrix readable....\ndef myMatrix_str(self):\n\treturn \"[[%g,%g,%g,%g][%g,%g,%g,%g][%g,%g,%g,%g][%g,%g,%g,%g]]\" % (self(0,0), self(0,1), self(0,2), self(0,3), self(1,0), self(1,1), self(1,2), self(1,3), self(2,0), self(2,1), self(2,2), self(2,3), self(3,0), self(3,1), self(3,2), self(3,3))\n\n# Creator\ndef cmdCreator():\n\treturn OpenMayaMPx.asMPxPtr( dagInfo() )\n\n# Initialize the script plug-in\ndef initializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\tmplugin.registerCommand( kPluginCmdName, cmdCreator )\n\texcept:\n\t\tsys.stderr.write( \"Failed to register command: %s\\n\" % kPluginCmdName )\n\n# Uninitialize the script plug-in\ndef uninitializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\tmplugin.deregisterCommand( kPluginCmdName )\n\texcept:\n\t\tsys.stderr.write( \"Failed to unregister command: %s\\n\" % kPluginCmdName )\n\n"
  },
  {
    "path": "02_Commands/dagInfo/Solution - C++/dagInfo.cpp",
    "content": "// \n// File: \n//\n// Dependency Graph Node: \n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#include \"dagInfo.h\"\n\n#include <maya/MArgList.h>\n#include <maya/MSelectionList.h>\n#include <maya/MItSelectionList.h>\n#include <maya/MGlobal.h>\n#include <maya/MDagPath.h>\n#include <maya/MDagPathArray.h>\n#include <maya/MFnDagNode.h>\n#include <maya/MMatrix.h>\n#include <maya/MFnBlendShapeDeformer.h>\n#include <maya/MFnTransform.h>\n\n//- This method performs the action of the command. It iterates over all\n//- selected items and prints out connected plug and dependency node type\n//- information.\nMStatus dagInfo::doIt(const MArgList& )\n{\n\tMStatus stat;\n\n\t//- Select all objects currently selected into the Maya editor.\n\tMSelectionList slist;\n\tMGlobal::getActiveSelectionList( slist );\n\t//- Create an iterator on the selection list (using the iterator pattern).\n\tMItSelectionList iter( slist, MFn::kDagNode,&stat );\n\n\t//- Iterate over all selected dependency nodes\n\tfor ( ; !iter.isDone(); iter.next() ) \n\t{\n\t\t//- get the dependency node first and then apply MFnDagNode function set onto it.\n\t\tMObject depNode;\n\t\titer.getDependNode(depNode);\n\n\t\tMFnDagNode fnDag(depNode);\n\t\tcout<<\"********************************************************\"<<endl;\n\t\tcout<<\"The selected node name is \"<<fnDag.name(&stat)<<\", node type : \"<<depNode.apiTypeStr()<<endl;\n\n\t\t//- Retrieve number of instances on this dag node\n\t\tunsigned int num = fnDag.instanceCount(true,&stat);\n\t\tif( num != 1 )\tcout<<\"Number of instances on this node is : \"<<num<<endl;\n\t\t\n\t\t//- Retrieve all the instanced paths of this dag node and print out them\n\t\tMDagPathArray dagPathArray;\n\t\tfnDag.getAllPaths(dagPathArray);\n\t\tfor(unsigned int j = 0; j < dagPathArray.length(); j++)\n\t\t{\n\t\t\tMDagPath instanceDagPath = dagPathArray[j];\n\t\t\tcout<<\"Dag Path \"<<j<<\" for this node:\"<<instanceDagPath.fullPathName(&stat)<<endl;\n\t\t\n\t\t\t//- Get the exclusive matrix of this node\n\t\t\tMMatrix exMatrix = instanceDagPath.exclusiveMatrix(&stat);\n\t\t\tcout<<\"The exclusive transformation matrix of this node is \"<<exMatrix<<endl;\n\n\t\t\t//- Get the inclusive matrix of this node\n\t\t\t//- If it is a shape node, the inclusive and exclusive matrix should be the same\n\t\t\t//- If it is a transform node and its transformation matrix is not identity, they \n\t\t\t//- should be different!\n\t\t\tMMatrix inMatrix = instanceDagPath.inclusiveMatrix(&stat);\n\t\t\tcout<<\"The inclusive transformation matrix of this node is \"<<inMatrix<<endl;\n\n\t\t\t//- If this dag node is a transform node, also get its local transformation matrix\n\t\t\tif (depNode.hasFn(MFn::kTransform))\n\t\t\t{\n\t\t\t\tMFnTransform fnTrans(instanceDagPath);\n\t\t\t\tMTransformationMatrix localMatrix = fnTrans.transformation();\n\t\t\t\tcout<<\"The local transformation matrix represented by this transform node is \"<<localMatrix.asMatrix()<<endl;\n\t\t\t}\n\t\t}\n\t}\n\n\t//- Return success to Maya\n\treturn MS::kSuccess;\n}"
  },
  {
    "path": "02_Commands/dagInfo/Solution - C++/dagInfo.h",
    "content": "//\n// Copyright (C) \n// \n// File: dagInfo.h\n//\n// MEL Command: dagInfo\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#pragma once\n\n#include <maya/MPxCommand.h>\n\n// Command class declaration\nclass dagInfo : public MPxCommand\n{\npublic:\n\tdagInfo() {}\n\tvirtual ~dagInfo() {}\n\n\tstatic void *creator() {\n\t\treturn new dagInfo();\n\t}\n\t\n\t//- This method should perform a command by setting up internal class data\n\t//- and then calling the redoIt method if undo is supported by the command.\n\t//- The actual action performed by the command should be done in the redoIt \n\t//- method. This is a pure virtual method, and must be overridden in derived \n\t//- classes.\n\tvirtual MStatus doIt(const MArgList &);\n\n};\n"
  },
  {
    "path": "02_Commands/dagInfo/Solution - C++/dagInfo.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 2012\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"dagInfo\", \"dagInfo.vcxproj\", \"{62B3E8DE-B8B9-4DEF-99F4-78E2EA80E56B}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|x64 = Debug|x64\n\t\tRelease|x64 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{62B3E8DE-B8B9-4DEF-99F4-78E2EA80E56B}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{62B3E8DE-B8B9-4DEF-99F4-78E2EA80E56B}.Debug|x64.Build.0 = Debug|x64\n\t\t{62B3E8DE-B8B9-4DEF-99F4-78E2EA80E56B}.Release|x64.ActiveCfg = Release|x64\n\t\t{62B3E8DE-B8B9-4DEF-99F4-78E2EA80E56B}.Release|x64.Build.0 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "02_Commands/dagInfo/Solution - C++/dagInfo.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{62B3E8DE-B8B9-4DEF-99F4-78E2EA80E56B}</ProjectGuid>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup>\n    <_ProjectFileVersion>11.0.61030.0</_ProjectFileVersion>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <OutDir>Debug\\</OutDir>\n    <IntDir>Debug\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <TargetExt>.mll</TargetExt>\n    <OutDir>C:\\MayaAPITraining\\plug-ins\\</OutDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <OutDir>Release\\</OutDir>\n    <IntDir>Release\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2009\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/dagInfo.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;OpenMayaAnim.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>C:\\MayaAPITraining\\plug-ins\\dagInfo.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2009\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/dagInfo.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/dagInfo.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2015\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/dagInfo.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;OpenMayaAnim.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>C:\\MayaAPITraining\\plug-ins\\dagInfo.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2015\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/dagInfo.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/dagInfo.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/dagInfo.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\dagInfo.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/dagInfo.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/dagInfo.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/dagInfo.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\dagInfo.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/dagInfo.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/dagInfo.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"dagInfo.cpp\" />\n    <ClCompile Include=\"pluginMain.cpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"dagInfo.h\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "02_Commands/dagInfo/Solution - C++/pluginMain.cpp",
    "content": "//\n// Copyright (C)  \n// \n// File: pluginMain.cpp\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#include <maya/MFnPlugin.h>\n#include <maya/MGlobal.h>\n#include \"dagInfo.h\"\n\nMStatus initializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is loaded into Maya.  It \n//\t\tregisters all of the services that this plug-in provides with \n//\t\tMaya.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{ \n\tMStatus   status;\n\tMFnPlugin plugin( obj, \"\", \"2012\", \"Any\");\n\n\t// Add plug-in feature registration here\n\t//\n\n\tstatus = plugin.registerCommand(\"dagInfo\",dagInfo::creator);\n\n\treturn status;\n}\n\nMStatus uninitializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is unloaded from Maya. It \n//\t\tderegisters all of the services that it was providing.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{\n\tMStatus   status;\n\tMFnPlugin plugin( obj );\n\n\t// Add plug-in feature deregistration here\n\t//\n\tstatus = plugin.deregisterCommand(\"dagInfo\");\n\n\treturn status;\n}\n"
  },
  {
    "path": "02_Commands/dagInfo/Solution - py/dagInfo.py",
    "content": "# Copyright (C) \n# \n# File: dagInfo.py\n#\n# Author: Autodesk Developer Network\n\nimport sys\nimport maya.OpenMaya as OpenMaya\nimport maya.OpenMayaMPx as OpenMayaMPx\n\n# Command name\nkPluginCmdName = \"dagInfo\"\n\n# dagInfo command\nclass dagInfo(OpenMayaMPx.MPxCommand):\n\t\n\tdef __init__(self):\n\t\tOpenMayaMPx.MPxCommand.__init__(self)\n\n\t#- This method performs the action of the command. It iterates over all\n\t#- selected items and prints out connected plug and dependency node type\n\t#- information.\n\tdef doIt(self, args):\n\t\t#- Select all objects currently selected into the Maya editor.\n\t\tslist = OpenMaya.MSelectionList()\n\t\tOpenMaya.MGlobal.getActiveSelectionList( slist )\n\t\t#- Create an iterator on the selection list (using the iterator pattern).\n\t\titer = OpenMaya.MItSelectionList( slist, OpenMaya.MFn.kDagNode )\n\n\t\t#- Iterate over all selected dependency nodes\n\t\twhile ( iter.isDone() == 0 ): \n\t\t\t#- Not getting the dag path, it will only return one path. I.e.:\n\t\t\t#dagPath = OpenMaya.MDagPath \n\t\t\t#iter.getDagPath(dagPath)\n\n\t\t\t#- Instead, get the dependency node first and then apply MFnDagNode function set onto it.\n\t\t\tdepNode = OpenMaya.MObject()\n\t\t\titer.getDependNode(depNode)\n\n\t\t\tfnDag = OpenMaya.MFnDagNode(depNode)\n\t\t\tprint \"********************************************************\"\n\t\t\tsys.stdout.write( '\\n' )\n\t\t\tprint \"The selected node name is %s, node type : %s\" % (fnDag.name(), depNode.apiTypeStr())\n\t\t\tsys.stdout.write( '\\n' )\n\n\t\t\t#- Retrieve number of instances on this dag node\n\t\t\tnum = fnDag.instanceCount(1)\n\t\t\tif( num != 1 ):\n\t\t\t\tprint \"Number of instances on this node is : %d\" % num\n\t\t\t\tsys.stdout.write( '\\n' )\n\t\t\t\n\t\t\t#Save out the MMatrix __str__ function so we can replace it once were done\n\t\t\toldMMatrix_str = OpenMaya.MMatrix .__str__\t\t\n\t\t\t# Call my new printing function to print the matrix so that is it readable\n\t\t\tOpenMaya.MMatrix.__str__ = myMatrix_str\t\t\n\t\t\t\n\t\t\t#- Retrieve all the instanced paths of this dag node and print out them\n\t\t\tdagPathArray = OpenMaya.MDagPathArray()\n\t\t\tfnDag.getAllPaths(dagPathArray)\n\t\t\tfor j in range (0, dagPathArray.length()):\n\t\t\t\tinstanceDagPath = dagPathArray[j]\n\t\t\t\tprint \"Dag Path %d for this node: %s\" % (j, instanceDagPath.fullPathName())\n\t\t\t\t\n\t\t\t\tsys.stdout.write( '\\n' )\n\t\t\t\n\t\t\t\t#- Get the exclusive matrix of this node\n\t\t\t\texMatrix = instanceDagPath.exclusiveMatrix()\n\n\t\t\t\tprint \"The exclusive transformation matrix of this node is:\"\n\t\t\t\tprint exMatrix\n\t\t\t\tsys.stdout.write( '\\n' )\n\n\t\t\t\t#- Get the inclusive matrix of this node\n\t\t\t\t#- If it is a shape node, the inclusive and exclusive matrix should be the same\n\t\t\t\t#- If it is a transform node and its transformation matrix is not identity, they \n\t\t\t\t#- should be different!\n\t\t\t\tinMatrix = instanceDagPath.inclusiveMatrix()\n\t\t\t\tprint \"The inclusive transformation matrix of this node is:\"\n\t\t\t\tprint inMatrix\n\t\t\t\tsys.stdout.write( '\\n' )\n\n\t\t\t\t#- If this dag node is a transform node, also get its local transformation matrix\n\t\t\t\tif (depNode.hasFn(OpenMaya.MFn.kTransform)):\n\t\t\t\t\tfnTrans = OpenMaya.MFnTransform(instanceDagPath)\n\t\t\t\t\tlocalMatrix = fnTrans.transformation()\n\t\t\t\t\tprint \"The local transformation matrix represented by this transform node is:\"\n\t\t\t\t\tprint localMatrix.asMatrix()\n\t\t\t\t\tsys.stdout.write( '\\n' )\n\t\t\t\t\n\t\t\titer.next()\n\t\t\t# Replace MMatrix __str__ function to the default\n\t\t\tOpenMaya.MMatrix.__str__ = oldMMatrix_str\n\n\n# New __str__ function for Making the matrix readable....\ndef myMatrix_str(self):\n\treturn \"[[%g,%g,%g,%g][%g,%g,%g,%g][%g,%g,%g,%g][%g,%g,%g,%g]]\" % (self(0,0), self(0,1), self(0,2), self(0,3), \n\tself(1,0), self(1,1), self(1,2), self(1,3), self(2,0), self(2,1), self(2,2), self(2,3), self(3,0), self(3,1), self(3,2), self(3,3))\n\n# Creator\ndef cmdCreator():\n\treturn OpenMayaMPx.asMPxPtr( dagInfo() )\n\n# Initialize the script plug-in\ndef initializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\tmplugin.registerCommand( kPluginCmdName, cmdCreator )\n\texcept:\n\t\tsys.stderr.write( \"Failed to register command: %s\\n\" % kPluginCmdName )\n\n# Uninitialize the script plug-in\ndef uninitializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\tmplugin.deregisterCommand( kPluginCmdName )\n\texcept:\n\t\tsys.stderr.write( \"Failed to unregister command: %s\\n\" % kPluginCmdName )\n\n"
  },
  {
    "path": "02_Commands/dagInfo/multiInstance.ma",
    "content": "//Maya ASCII 2012 scene\n//Name: multiInstance.ma\n//Last modified: Sun, Sep 25, 2011 11:03:05 PM\n//Codeset: 1252\nrequires maya \"2012\";\ncurrentUnit -l centimeter -a degree -t film;\nfileInfo \"application\" \"maya\";\nfileInfo \"product\" \"Maya 2012\";\nfileInfo \"version\" \"2012 Hotfix 1\";\nfileInfo \"cutIdentifier\" \"001200000000-798788\";\nfileInfo \"osv\" \"Microsoft Windows XP Professional Service Pack 3 (Build 2600)\\n\";\ncreateNode transform -s -n \"persp\";\n\tsetAttr \".v\" no;\n\tsetAttr \".t\" -type \"double3\" 36.204867073134864 24.239823589777796 10.518486229164782 ;\n\tsetAttr \".r\" -type \"double3\" -32.738352729661635 73.799999999992863 1.1400200983521435e-014 ;\ncreateNode camera -s -n \"perspShape\" -p \"persp\";\n\tsetAttr -k off \".v\" no;\n\tsetAttr \".fl\" 34.999999999999993;\n\tsetAttr \".coi\" 44.82186966202994;\n\tsetAttr \".imn\" -type \"string\" \"persp\";\n\tsetAttr \".den\" -type \"string\" \"persp_depth\";\n\tsetAttr \".man\" -type \"string\" \"persp_mask\";\n\tsetAttr \".hc\" -type \"string\" \"viewSet -p %camera\";\ncreateNode transform -s -n \"top\";\n\tsetAttr \".v\" no;\n\tsetAttr \".t\" -type \"double3\" 0 100.1 0 ;\n\tsetAttr \".r\" -type \"double3\" -89.999999999999986 0 0 ;\ncreateNode camera -s -n \"topShape\" -p \"top\";\n\tsetAttr -k off \".v\" no;\n\tsetAttr \".rnd\" no;\n\tsetAttr \".coi\" 100.1;\n\tsetAttr \".ow\" 30;\n\tsetAttr \".imn\" -type \"string\" \"top\";\n\tsetAttr \".den\" -type \"string\" \"top_depth\";\n\tsetAttr \".man\" -type \"string\" \"top_mask\";\n\tsetAttr \".hc\" -type \"string\" \"viewSet -t %camera\";\n\tsetAttr \".o\" yes;\ncreateNode transform -s -n \"front\";\n\tsetAttr \".v\" no;\n\tsetAttr \".t\" -type \"double3\" 0 0 100.1 ;\ncreateNode camera -s -n \"frontShape\" -p \"front\";\n\tsetAttr -k off \".v\" no;\n\tsetAttr \".rnd\" no;\n\tsetAttr \".coi\" 100.1;\n\tsetAttr \".ow\" 30;\n\tsetAttr \".imn\" -type \"string\" \"front\";\n\tsetAttr \".den\" -type \"string\" \"front_depth\";\n\tsetAttr \".man\" -type \"string\" \"front_mask\";\n\tsetAttr \".hc\" -type \"string\" \"viewSet -f %camera\";\n\tsetAttr \".o\" yes;\ncreateNode transform -s -n \"side\";\n\tsetAttr \".v\" no;\n\tsetAttr \".t\" -type \"double3\" 100.1 0 0 ;\n\tsetAttr \".r\" -type \"double3\" 0 89.999999999999986 0 ;\ncreateNode camera -s -n \"sideShape\" -p \"side\";\n\tsetAttr -k off \".v\" no;\n\tsetAttr \".rnd\" no;\n\tsetAttr \".coi\" 100.1;\n\tsetAttr \".ow\" 30;\n\tsetAttr \".imn\" -type \"string\" \"side\";\n\tsetAttr \".den\" -type \"string\" \"side_depth\";\n\tsetAttr \".man\" -type \"string\" \"side_mask\";\n\tsetAttr \".hc\" -type \"string\" \"viewSet -s %camera\";\n\tsetAttr \".o\" yes;\ncreateNode transform -n \"pCylinder1\";\n\tsetAttr \".t\" -type \"double3\" 0 0 -6 ;\ncreateNode mesh -n \"pCylinderShape1\" -p \"pCylinder1\";\n\tsetAttr -k off \".v\";\n\tsetAttr -s 4 \".iog\";\n\tsetAttr \".vir\" yes;\n\tsetAttr \".vif\" yes;\n\tsetAttr \".uvst[0].uvsn\" -type \"string\" \"map1\";\n\tsetAttr \".cuvs\" -type \"string\" \"map1\";\n\tsetAttr \".dcc\" -type \"string\" \"Ambient+Diffuse\";\n\tsetAttr \".covm[0]\"  0 1 1;\n\tsetAttr \".cdvm[0]\"  0 1 1;\n\tsetAttr \".bnr\" 0;\ncreateNode transform -n \"pCylinder2\";\n\tsetAttr \".t\" -type \"double3\" 0 0 -2 ;\ncreateNode transform -n \"pCylinder3\";\n\tsetAttr \".t\" -type \"double3\" 0 0 2 ;\ncreateNode transform -n \"pCylinder4\";\n\tsetAttr \".t\" -type \"double3\" 0 0 6 ;\nparent -s -nc -r -add \"|pCylinder1|pCylinderShape1\" \"pCylinder2\" ;\nparent -s -nc -r -add \"|pCylinder1|pCylinderShape1\" \"pCylinder3\" ;\nparent -s -nc -r -add \"|pCylinder1|pCylinderShape1\" \"pCylinder4\" ;\ncreateNode lightLinker -s -n \"lightLinker1\";\n\tsetAttr -s 2 \".lnk\";\n\tsetAttr -s 2 \".slnk\";\ncreateNode displayLayerManager -n \"layerManager\";\ncreateNode displayLayer -n \"defaultLayer\";\ncreateNode renderLayerManager -n \"renderLayerManager\";\ncreateNode renderLayer -n \"defaultRenderLayer\";\n\tsetAttr \".g\" yes;\ncreateNode polyCylinder -n \"polyCylinder1\";\n\tsetAttr \".sc\" 1;\n\tsetAttr \".cuv\" 3;\ncreateNode script -n \"uiConfigurationScriptNode\";\n\tsetAttr \".b\" -type \"string\" (\n\t\t\"// Maya Mel UI Configuration File.\\n//\\n//  This script is machine generated.  Edit at your own risk.\\n//\\n//\\n\\nglobal string $gMainPane;\\nif (`paneLayout -exists $gMainPane`) {\\n\\n\\tglobal int $gUseScenePanelConfig;\\n\\tint    $useSceneConfig = $gUseScenePanelConfig;\\n\\tint    $menusOkayInPanels = `optionVar -q allowMenusInPanels`;\\tint    $nVisPanes = `paneLayout -q -nvp $gMainPane`;\\n\\tint    $nPanes = 0;\\n\\tstring $editorName;\\n\\tstring $panelName;\\n\\tstring $itemFilterName;\\n\\tstring $panelConfig;\\n\\n\\t//\\n\\t//  get current state of the UI\\n\\t//\\n\\tsceneUIReplacement -update $gMainPane;\\n\\n\\t$panelName = `sceneUIReplacement -getNextPanel \\\"modelPanel\\\" (localizedPanelLabel(\\\"Top View\\\")) `;\\n\\tif (\\\"\\\" == $panelName) {\\n\\t\\tif ($useSceneConfig) {\\n\\t\\t\\t$panelName = `modelPanel -unParent -l (localizedPanelLabel(\\\"Top View\\\")) -mbv $menusOkayInPanels `;\\n\\t\\t\\t$editorName = $panelName;\\n            modelEditor -e \\n                -camera \\\"top\\\" \\n                -useInteractiveMode 0\\n                -displayLights \\\"default\\\" \\n                -displayAppearance \\\"wireframe\\\" \\n\"\n\t\t+ \"                -activeOnly 0\\n                -ignorePanZoom 0\\n                -wireframeOnShaded 0\\n                -headsUpDisplay 1\\n                -selectionHiliteDisplay 1\\n                -useDefaultMaterial 0\\n                -bufferMode \\\"double\\\" \\n                -twoSidedLighting 1\\n                -backfaceCulling 0\\n                -xray 0\\n                -jointXray 0\\n                -activeComponentsXray 0\\n                -displayTextures 0\\n                -smoothWireframe 0\\n                -lineWidth 1\\n                -textureAnisotropic 0\\n                -textureHilight 1\\n                -textureSampling 2\\n                -textureDisplay \\\"modulate\\\" \\n                -textureMaxSize 8192\\n                -fogging 0\\n                -fogSource \\\"fragment\\\" \\n                -fogMode \\\"linear\\\" \\n                -fogStart 0\\n                -fogEnd 100\\n                -fogDensity 0.1\\n                -fogColor 0.5 0.5 0.5 1 \\n                -maxConstantTransparency 1\\n                -rendererName \\\"base_OpenGL_Renderer\\\" \\n\"\n\t\t+ \"                -colorResolution 256 256 \\n                -bumpResolution 512 512 \\n                -textureCompression 0\\n                -transparencyAlgorithm \\\"frontAndBackCull\\\" \\n                -transpInShadows 0\\n                -cullingOverride \\\"none\\\" \\n                -lowQualityLighting 0\\n                -maximumNumHardwareLights 1\\n                -occlusionCulling 0\\n                -shadingModel 0\\n                -useBaseRenderer 0\\n                -useReducedRenderer 0\\n                -smallObjectCulling 0\\n                -smallObjectThreshold -1 \\n                -interactiveDisableShadows 0\\n                -interactiveBackFaceCull 0\\n                -sortTransparent 1\\n                -nurbsCurves 1\\n                -nurbsSurfaces 1\\n                -polymeshes 1\\n                -subdivSurfaces 1\\n                -planes 1\\n                -lights 1\\n                -cameras 1\\n                -controlVertices 1\\n                -hulls 1\\n                -grid 1\\n                -joints 1\\n                -ikHandles 1\\n\"\n\t\t+ \"                -deformers 1\\n                -dynamics 1\\n                -fluids 1\\n                -hairSystems 1\\n                -follicles 1\\n                -nCloths 1\\n                -nParticles 1\\n                -nRigids 1\\n                -dynamicConstraints 1\\n                -locators 1\\n                -manipulators 1\\n                -dimensions 1\\n                -handles 1\\n                -pivots 1\\n                -textures 1\\n                -strokes 1\\n                -motionTrails 1\\n                -shadows 0\\n                $editorName;\\nmodelEditor -e -viewSelected 0 $editorName;\\n\\t\\t}\\n\\t} else {\\n\\t\\t$label = `panel -q -label $panelName`;\\n\\t\\tmodelPanel -edit -l (localizedPanelLabel(\\\"Top View\\\")) -mbv $menusOkayInPanels  $panelName;\\n\\t\\t$editorName = $panelName;\\n        modelEditor -e \\n            -camera \\\"top\\\" \\n            -useInteractiveMode 0\\n            -displayLights \\\"default\\\" \\n            -displayAppearance \\\"wireframe\\\" \\n            -activeOnly 0\\n            -ignorePanZoom 0\\n            -wireframeOnShaded 0\\n\"\n\t\t+ \"            -headsUpDisplay 1\\n            -selectionHiliteDisplay 1\\n            -useDefaultMaterial 0\\n            -bufferMode \\\"double\\\" \\n            -twoSidedLighting 1\\n            -backfaceCulling 0\\n            -xray 0\\n            -jointXray 0\\n            -activeComponentsXray 0\\n            -displayTextures 0\\n            -smoothWireframe 0\\n            -lineWidth 1\\n            -textureAnisotropic 0\\n            -textureHilight 1\\n            -textureSampling 2\\n            -textureDisplay \\\"modulate\\\" \\n            -textureMaxSize 8192\\n            -fogging 0\\n            -fogSource \\\"fragment\\\" \\n            -fogMode \\\"linear\\\" \\n            -fogStart 0\\n            -fogEnd 100\\n            -fogDensity 0.1\\n            -fogColor 0.5 0.5 0.5 1 \\n            -maxConstantTransparency 1\\n            -rendererName \\\"base_OpenGL_Renderer\\\" \\n            -colorResolution 256 256 \\n            -bumpResolution 512 512 \\n            -textureCompression 0\\n            -transparencyAlgorithm \\\"frontAndBackCull\\\" \\n            -transpInShadows 0\\n            -cullingOverride \\\"none\\\" \\n\"\n\t\t+ \"            -lowQualityLighting 0\\n            -maximumNumHardwareLights 1\\n            -occlusionCulling 0\\n            -shadingModel 0\\n            -useBaseRenderer 0\\n            -useReducedRenderer 0\\n            -smallObjectCulling 0\\n            -smallObjectThreshold -1 \\n            -interactiveDisableShadows 0\\n            -interactiveBackFaceCull 0\\n            -sortTransparent 1\\n            -nurbsCurves 1\\n            -nurbsSurfaces 1\\n            -polymeshes 1\\n            -subdivSurfaces 1\\n            -planes 1\\n            -lights 1\\n            -cameras 1\\n            -controlVertices 1\\n            -hulls 1\\n            -grid 1\\n            -joints 1\\n            -ikHandles 1\\n            -deformers 1\\n            -dynamics 1\\n            -fluids 1\\n            -hairSystems 1\\n            -follicles 1\\n            -nCloths 1\\n            -nParticles 1\\n            -nRigids 1\\n            -dynamicConstraints 1\\n            -locators 1\\n            -manipulators 1\\n            -dimensions 1\\n            -handles 1\\n            -pivots 1\\n\"\n\t\t+ \"            -textures 1\\n            -strokes 1\\n            -motionTrails 1\\n            -shadows 0\\n            $editorName;\\nmodelEditor -e -viewSelected 0 $editorName;\\n\\t\\tif (!$useSceneConfig) {\\n\\t\\t\\tpanel -e -l $label $panelName;\\n\\t\\t}\\n\\t}\\n\\n\\n\\t$panelName = `sceneUIReplacement -getNextPanel \\\"modelPanel\\\" (localizedPanelLabel(\\\"Side View\\\")) `;\\n\\tif (\\\"\\\" == $panelName) {\\n\\t\\tif ($useSceneConfig) {\\n\\t\\t\\t$panelName = `modelPanel -unParent -l (localizedPanelLabel(\\\"Side View\\\")) -mbv $menusOkayInPanels `;\\n\\t\\t\\t$editorName = $panelName;\\n            modelEditor -e \\n                -camera \\\"side\\\" \\n                -useInteractiveMode 0\\n                -displayLights \\\"default\\\" \\n                -displayAppearance \\\"wireframe\\\" \\n                -activeOnly 0\\n                -ignorePanZoom 0\\n                -wireframeOnShaded 0\\n                -headsUpDisplay 1\\n                -selectionHiliteDisplay 1\\n                -useDefaultMaterial 0\\n                -bufferMode \\\"double\\\" \\n                -twoSidedLighting 1\\n                -backfaceCulling 0\\n\"\n\t\t+ \"                -xray 0\\n                -jointXray 0\\n                -activeComponentsXray 0\\n                -displayTextures 0\\n                -smoothWireframe 0\\n                -lineWidth 1\\n                -textureAnisotropic 0\\n                -textureHilight 1\\n                -textureSampling 2\\n                -textureDisplay \\\"modulate\\\" \\n                -textureMaxSize 8192\\n                -fogging 0\\n                -fogSource \\\"fragment\\\" \\n                -fogMode \\\"linear\\\" \\n                -fogStart 0\\n                -fogEnd 100\\n                -fogDensity 0.1\\n                -fogColor 0.5 0.5 0.5 1 \\n                -maxConstantTransparency 1\\n                -rendererName \\\"base_OpenGL_Renderer\\\" \\n                -colorResolution 256 256 \\n                -bumpResolution 512 512 \\n                -textureCompression 0\\n                -transparencyAlgorithm \\\"frontAndBackCull\\\" \\n                -transpInShadows 0\\n                -cullingOverride \\\"none\\\" \\n                -lowQualityLighting 0\\n                -maximumNumHardwareLights 1\\n\"\n\t\t+ \"                -occlusionCulling 0\\n                -shadingModel 0\\n                -useBaseRenderer 0\\n                -useReducedRenderer 0\\n                -smallObjectCulling 0\\n                -smallObjectThreshold -1 \\n                -interactiveDisableShadows 0\\n                -interactiveBackFaceCull 0\\n                -sortTransparent 1\\n                -nurbsCurves 1\\n                -nurbsSurfaces 1\\n                -polymeshes 1\\n                -subdivSurfaces 1\\n                -planes 1\\n                -lights 1\\n                -cameras 1\\n                -controlVertices 1\\n                -hulls 1\\n                -grid 1\\n                -joints 1\\n                -ikHandles 1\\n                -deformers 1\\n                -dynamics 1\\n                -fluids 1\\n                -hairSystems 1\\n                -follicles 1\\n                -nCloths 1\\n                -nParticles 1\\n                -nRigids 1\\n                -dynamicConstraints 1\\n                -locators 1\\n                -manipulators 1\\n                -dimensions 1\\n\"\n\t\t+ \"                -handles 1\\n                -pivots 1\\n                -textures 1\\n                -strokes 1\\n                -motionTrails 1\\n                -shadows 0\\n                $editorName;\\nmodelEditor -e -viewSelected 0 $editorName;\\n\\t\\t}\\n\\t} else {\\n\\t\\t$label = `panel -q -label $panelName`;\\n\\t\\tmodelPanel -edit -l (localizedPanelLabel(\\\"Side View\\\")) -mbv $menusOkayInPanels  $panelName;\\n\\t\\t$editorName = $panelName;\\n        modelEditor -e \\n            -camera \\\"side\\\" \\n            -useInteractiveMode 0\\n            -displayLights \\\"default\\\" \\n            -displayAppearance \\\"wireframe\\\" \\n            -activeOnly 0\\n            -ignorePanZoom 0\\n            -wireframeOnShaded 0\\n            -headsUpDisplay 1\\n            -selectionHiliteDisplay 1\\n            -useDefaultMaterial 0\\n            -bufferMode \\\"double\\\" \\n            -twoSidedLighting 1\\n            -backfaceCulling 0\\n            -xray 0\\n            -jointXray 0\\n            -activeComponentsXray 0\\n            -displayTextures 0\\n            -smoothWireframe 0\\n            -lineWidth 1\\n\"\n\t\t+ \"            -textureAnisotropic 0\\n            -textureHilight 1\\n            -textureSampling 2\\n            -textureDisplay \\\"modulate\\\" \\n            -textureMaxSize 8192\\n            -fogging 0\\n            -fogSource \\\"fragment\\\" \\n            -fogMode \\\"linear\\\" \\n            -fogStart 0\\n            -fogEnd 100\\n            -fogDensity 0.1\\n            -fogColor 0.5 0.5 0.5 1 \\n            -maxConstantTransparency 1\\n            -rendererName \\\"base_OpenGL_Renderer\\\" \\n            -colorResolution 256 256 \\n            -bumpResolution 512 512 \\n            -textureCompression 0\\n            -transparencyAlgorithm \\\"frontAndBackCull\\\" \\n            -transpInShadows 0\\n            -cullingOverride \\\"none\\\" \\n            -lowQualityLighting 0\\n            -maximumNumHardwareLights 1\\n            -occlusionCulling 0\\n            -shadingModel 0\\n            -useBaseRenderer 0\\n            -useReducedRenderer 0\\n            -smallObjectCulling 0\\n            -smallObjectThreshold -1 \\n            -interactiveDisableShadows 0\\n            -interactiveBackFaceCull 0\\n\"\n\t\t+ \"            -sortTransparent 1\\n            -nurbsCurves 1\\n            -nurbsSurfaces 1\\n            -polymeshes 1\\n            -subdivSurfaces 1\\n            -planes 1\\n            -lights 1\\n            -cameras 1\\n            -controlVertices 1\\n            -hulls 1\\n            -grid 1\\n            -joints 1\\n            -ikHandles 1\\n            -deformers 1\\n            -dynamics 1\\n            -fluids 1\\n            -hairSystems 1\\n            -follicles 1\\n            -nCloths 1\\n            -nParticles 1\\n            -nRigids 1\\n            -dynamicConstraints 1\\n            -locators 1\\n            -manipulators 1\\n            -dimensions 1\\n            -handles 1\\n            -pivots 1\\n            -textures 1\\n            -strokes 1\\n            -motionTrails 1\\n            -shadows 0\\n            $editorName;\\nmodelEditor -e -viewSelected 0 $editorName;\\n\\t\\tif (!$useSceneConfig) {\\n\\t\\t\\tpanel -e -l $label $panelName;\\n\\t\\t}\\n\\t}\\n\\n\\n\\t$panelName = `sceneUIReplacement -getNextPanel \\\"modelPanel\\\" (localizedPanelLabel(\\\"Front View\\\")) `;\\n\\tif (\\\"\\\" == $panelName) {\\n\"\n\t\t+ \"\\t\\tif ($useSceneConfig) {\\n\\t\\t\\t$panelName = `modelPanel -unParent -l (localizedPanelLabel(\\\"Front View\\\")) -mbv $menusOkayInPanels `;\\n\\t\\t\\t$editorName = $panelName;\\n            modelEditor -e \\n                -camera \\\"front\\\" \\n                -useInteractiveMode 0\\n                -displayLights \\\"default\\\" \\n                -displayAppearance \\\"wireframe\\\" \\n                -activeOnly 0\\n                -ignorePanZoom 0\\n                -wireframeOnShaded 0\\n                -headsUpDisplay 1\\n                -selectionHiliteDisplay 1\\n                -useDefaultMaterial 0\\n                -bufferMode \\\"double\\\" \\n                -twoSidedLighting 1\\n                -backfaceCulling 0\\n                -xray 0\\n                -jointXray 0\\n                -activeComponentsXray 0\\n                -displayTextures 0\\n                -smoothWireframe 0\\n                -lineWidth 1\\n                -textureAnisotropic 0\\n                -textureHilight 1\\n                -textureSampling 2\\n                -textureDisplay \\\"modulate\\\" \\n                -textureMaxSize 8192\\n\"\n\t\t+ \"                -fogging 0\\n                -fogSource \\\"fragment\\\" \\n                -fogMode \\\"linear\\\" \\n                -fogStart 0\\n                -fogEnd 100\\n                -fogDensity 0.1\\n                -fogColor 0.5 0.5 0.5 1 \\n                -maxConstantTransparency 1\\n                -rendererName \\\"base_OpenGL_Renderer\\\" \\n                -colorResolution 256 256 \\n                -bumpResolution 512 512 \\n                -textureCompression 0\\n                -transparencyAlgorithm \\\"frontAndBackCull\\\" \\n                -transpInShadows 0\\n                -cullingOverride \\\"none\\\" \\n                -lowQualityLighting 0\\n                -maximumNumHardwareLights 1\\n                -occlusionCulling 0\\n                -shadingModel 0\\n                -useBaseRenderer 0\\n                -useReducedRenderer 0\\n                -smallObjectCulling 0\\n                -smallObjectThreshold -1 \\n                -interactiveDisableShadows 0\\n                -interactiveBackFaceCull 0\\n                -sortTransparent 1\\n                -nurbsCurves 1\\n\"\n\t\t+ \"                -nurbsSurfaces 1\\n                -polymeshes 1\\n                -subdivSurfaces 1\\n                -planes 1\\n                -lights 1\\n                -cameras 1\\n                -controlVertices 1\\n                -hulls 1\\n                -grid 1\\n                -joints 1\\n                -ikHandles 1\\n                -deformers 1\\n                -dynamics 1\\n                -fluids 1\\n                -hairSystems 1\\n                -follicles 1\\n                -nCloths 1\\n                -nParticles 1\\n                -nRigids 1\\n                -dynamicConstraints 1\\n                -locators 1\\n                -manipulators 1\\n                -dimensions 1\\n                -handles 1\\n                -pivots 1\\n                -textures 1\\n                -strokes 1\\n                -motionTrails 1\\n                -shadows 0\\n                $editorName;\\nmodelEditor -e -viewSelected 0 $editorName;\\n\\t\\t}\\n\\t} else {\\n\\t\\t$label = `panel -q -label $panelName`;\\n\\t\\tmodelPanel -edit -l (localizedPanelLabel(\\\"Front View\\\")) -mbv $menusOkayInPanels  $panelName;\\n\"\n\t\t+ \"\\t\\t$editorName = $panelName;\\n        modelEditor -e \\n            -camera \\\"front\\\" \\n            -useInteractiveMode 0\\n            -displayLights \\\"default\\\" \\n            -displayAppearance \\\"wireframe\\\" \\n            -activeOnly 0\\n            -ignorePanZoom 0\\n            -wireframeOnShaded 0\\n            -headsUpDisplay 1\\n            -selectionHiliteDisplay 1\\n            -useDefaultMaterial 0\\n            -bufferMode \\\"double\\\" \\n            -twoSidedLighting 1\\n            -backfaceCulling 0\\n            -xray 0\\n            -jointXray 0\\n            -activeComponentsXray 0\\n            -displayTextures 0\\n            -smoothWireframe 0\\n            -lineWidth 1\\n            -textureAnisotropic 0\\n            -textureHilight 1\\n            -textureSampling 2\\n            -textureDisplay \\\"modulate\\\" \\n            -textureMaxSize 8192\\n            -fogging 0\\n            -fogSource \\\"fragment\\\" \\n            -fogMode \\\"linear\\\" \\n            -fogStart 0\\n            -fogEnd 100\\n            -fogDensity 0.1\\n            -fogColor 0.5 0.5 0.5 1 \\n            -maxConstantTransparency 1\\n\"\n\t\t+ \"            -rendererName \\\"base_OpenGL_Renderer\\\" \\n            -colorResolution 256 256 \\n            -bumpResolution 512 512 \\n            -textureCompression 0\\n            -transparencyAlgorithm \\\"frontAndBackCull\\\" \\n            -transpInShadows 0\\n            -cullingOverride \\\"none\\\" \\n            -lowQualityLighting 0\\n            -maximumNumHardwareLights 1\\n            -occlusionCulling 0\\n            -shadingModel 0\\n            -useBaseRenderer 0\\n            -useReducedRenderer 0\\n            -smallObjectCulling 0\\n            -smallObjectThreshold -1 \\n            -interactiveDisableShadows 0\\n            -interactiveBackFaceCull 0\\n            -sortTransparent 1\\n            -nurbsCurves 1\\n            -nurbsSurfaces 1\\n            -polymeshes 1\\n            -subdivSurfaces 1\\n            -planes 1\\n            -lights 1\\n            -cameras 1\\n            -controlVertices 1\\n            -hulls 1\\n            -grid 1\\n            -joints 1\\n            -ikHandles 1\\n            -deformers 1\\n            -dynamics 1\\n            -fluids 1\\n\"\n\t\t+ \"            -hairSystems 1\\n            -follicles 1\\n            -nCloths 1\\n            -nParticles 1\\n            -nRigids 1\\n            -dynamicConstraints 1\\n            -locators 1\\n            -manipulators 1\\n            -dimensions 1\\n            -handles 1\\n            -pivots 1\\n            -textures 1\\n            -strokes 1\\n            -motionTrails 1\\n            -shadows 0\\n            $editorName;\\nmodelEditor -e -viewSelected 0 $editorName;\\n\\t\\tif (!$useSceneConfig) {\\n\\t\\t\\tpanel -e -l $label $panelName;\\n\\t\\t}\\n\\t}\\n\\n\\n\\t$panelName = `sceneUIReplacement -getNextPanel \\\"modelPanel\\\" (localizedPanelLabel(\\\"Persp View\\\")) `;\\n\\tif (\\\"\\\" == $panelName) {\\n\\t\\tif ($useSceneConfig) {\\n\\t\\t\\t$panelName = `modelPanel -unParent -l (localizedPanelLabel(\\\"Persp View\\\")) -mbv $menusOkayInPanels `;\\n\\t\\t\\t$editorName = $panelName;\\n            modelEditor -e \\n                -camera \\\"persp\\\" \\n                -useInteractiveMode 0\\n                -displayLights \\\"default\\\" \\n                -displayAppearance \\\"wireframe\\\" \\n                -activeOnly 0\\n                -ignorePanZoom 0\\n\"\n\t\t+ \"                -wireframeOnShaded 0\\n                -headsUpDisplay 1\\n                -selectionHiliteDisplay 1\\n                -useDefaultMaterial 0\\n                -bufferMode \\\"double\\\" \\n                -twoSidedLighting 1\\n                -backfaceCulling 0\\n                -xray 0\\n                -jointXray 0\\n                -activeComponentsXray 0\\n                -displayTextures 0\\n                -smoothWireframe 0\\n                -lineWidth 1\\n                -textureAnisotropic 0\\n                -textureHilight 1\\n                -textureSampling 2\\n                -textureDisplay \\\"modulate\\\" \\n                -textureMaxSize 8192\\n                -fogging 0\\n                -fogSource \\\"fragment\\\" \\n                -fogMode \\\"linear\\\" \\n                -fogStart 0\\n                -fogEnd 100\\n                -fogDensity 0.1\\n                -fogColor 0.5 0.5 0.5 1 \\n                -maxConstantTransparency 1\\n                -rendererName \\\"base_OpenGL_Renderer\\\" \\n                -colorResolution 256 256 \\n                -bumpResolution 512 512 \\n\"\n\t\t+ \"                -textureCompression 0\\n                -transparencyAlgorithm \\\"frontAndBackCull\\\" \\n                -transpInShadows 0\\n                -cullingOverride \\\"none\\\" \\n                -lowQualityLighting 0\\n                -maximumNumHardwareLights 1\\n                -occlusionCulling 0\\n                -shadingModel 0\\n                -useBaseRenderer 0\\n                -useReducedRenderer 0\\n                -smallObjectCulling 0\\n                -smallObjectThreshold -1 \\n                -interactiveDisableShadows 0\\n                -interactiveBackFaceCull 0\\n                -sortTransparent 1\\n                -nurbsCurves 1\\n                -nurbsSurfaces 1\\n                -polymeshes 1\\n                -subdivSurfaces 1\\n                -planes 1\\n                -lights 1\\n                -cameras 1\\n                -controlVertices 1\\n                -hulls 1\\n                -grid 1\\n                -joints 1\\n                -ikHandles 1\\n                -deformers 1\\n                -dynamics 1\\n                -fluids 1\\n\"\n\t\t+ \"                -hairSystems 1\\n                -follicles 1\\n                -nCloths 1\\n                -nParticles 1\\n                -nRigids 1\\n                -dynamicConstraints 1\\n                -locators 1\\n                -manipulators 1\\n                -dimensions 1\\n                -handles 1\\n                -pivots 1\\n                -textures 1\\n                -strokes 1\\n                -motionTrails 1\\n                -shadows 0\\n                $editorName;\\nmodelEditor -e -viewSelected 0 $editorName;\\n\\t\\t}\\n\\t} else {\\n\\t\\t$label = `panel -q -label $panelName`;\\n\\t\\tmodelPanel -edit -l (localizedPanelLabel(\\\"Persp View\\\")) -mbv $menusOkayInPanels  $panelName;\\n\\t\\t$editorName = $panelName;\\n        modelEditor -e \\n            -camera \\\"persp\\\" \\n            -useInteractiveMode 0\\n            -displayLights \\\"default\\\" \\n            -displayAppearance \\\"wireframe\\\" \\n            -activeOnly 0\\n            -ignorePanZoom 0\\n            -wireframeOnShaded 0\\n            -headsUpDisplay 1\\n            -selectionHiliteDisplay 1\\n            -useDefaultMaterial 0\\n\"\n\t\t+ \"            -bufferMode \\\"double\\\" \\n            -twoSidedLighting 1\\n            -backfaceCulling 0\\n            -xray 0\\n            -jointXray 0\\n            -activeComponentsXray 0\\n            -displayTextures 0\\n            -smoothWireframe 0\\n            -lineWidth 1\\n            -textureAnisotropic 0\\n            -textureHilight 1\\n            -textureSampling 2\\n            -textureDisplay \\\"modulate\\\" \\n            -textureMaxSize 8192\\n            -fogging 0\\n            -fogSource \\\"fragment\\\" \\n            -fogMode \\\"linear\\\" \\n            -fogStart 0\\n            -fogEnd 100\\n            -fogDensity 0.1\\n            -fogColor 0.5 0.5 0.5 1 \\n            -maxConstantTransparency 1\\n            -rendererName \\\"base_OpenGL_Renderer\\\" \\n            -colorResolution 256 256 \\n            -bumpResolution 512 512 \\n            -textureCompression 0\\n            -transparencyAlgorithm \\\"frontAndBackCull\\\" \\n            -transpInShadows 0\\n            -cullingOverride \\\"none\\\" \\n            -lowQualityLighting 0\\n            -maximumNumHardwareLights 1\\n\"\n\t\t+ \"            -occlusionCulling 0\\n            -shadingModel 0\\n            -useBaseRenderer 0\\n            -useReducedRenderer 0\\n            -smallObjectCulling 0\\n            -smallObjectThreshold -1 \\n            -interactiveDisableShadows 0\\n            -interactiveBackFaceCull 0\\n            -sortTransparent 1\\n            -nurbsCurves 1\\n            -nurbsSurfaces 1\\n            -polymeshes 1\\n            -subdivSurfaces 1\\n            -planes 1\\n            -lights 1\\n            -cameras 1\\n            -controlVertices 1\\n            -hulls 1\\n            -grid 1\\n            -joints 1\\n            -ikHandles 1\\n            -deformers 1\\n            -dynamics 1\\n            -fluids 1\\n            -hairSystems 1\\n            -follicles 1\\n            -nCloths 1\\n            -nParticles 1\\n            -nRigids 1\\n            -dynamicConstraints 1\\n            -locators 1\\n            -manipulators 1\\n            -dimensions 1\\n            -handles 1\\n            -pivots 1\\n            -textures 1\\n            -strokes 1\\n            -motionTrails 1\\n\"\n\t\t+ \"            -shadows 0\\n            $editorName;\\nmodelEditor -e -viewSelected 0 $editorName;\\n\\t\\tif (!$useSceneConfig) {\\n\\t\\t\\tpanel -e -l $label $panelName;\\n\\t\\t}\\n\\t}\\n\\n\\n\\t$panelName = `sceneUIReplacement -getNextPanel \\\"outlinerPanel\\\" (localizedPanelLabel(\\\"Outliner\\\")) `;\\n\\tif (\\\"\\\" == $panelName) {\\n\\t\\tif ($useSceneConfig) {\\n\\t\\t\\t$panelName = `outlinerPanel -unParent -l (localizedPanelLabel(\\\"Outliner\\\")) -mbv $menusOkayInPanels `;\\n\\t\\t\\t$editorName = $panelName;\\n            outlinerEditor -e \\n                -showShapes 1\\n                -showAttributes 0\\n                -showConnected 0\\n                -showAnimCurvesOnly 0\\n                -showMuteInfo 0\\n                -organizeByLayer 1\\n                -showAnimLayerWeight 1\\n                -autoExpandLayers 1\\n                -autoExpand 0\\n                -showDagOnly 0\\n                -showAssets 1\\n                -showContainedOnly 1\\n                -showPublishedAsConnected 0\\n                -showContainerContents 1\\n                -ignoreDagHierarchy 0\\n                -expandConnections 0\\n\"\n\t\t+ \"                -showUpstreamCurves 1\\n                -showUnitlessCurves 1\\n                -showCompounds 1\\n                -showLeafs 1\\n                -showNumericAttrsOnly 0\\n                -highlightActive 1\\n                -autoSelectNewObjects 0\\n                -doNotSelectNewObjects 0\\n                -dropIsParent 1\\n                -transmitFilters 0\\n                -setFilter \\\"defaultSetFilter\\\" \\n                -showSetMembers 1\\n                -allowMultiSelection 1\\n                -alwaysToggleSelect 0\\n                -directSelect 0\\n                -displayMode \\\"DAG\\\" \\n                -expandObjects 0\\n                -setsIgnoreFilters 1\\n                -containersIgnoreFilters 0\\n                -editAttrName 0\\n                -showAttrValues 0\\n                -highlightSecondary 0\\n                -showUVAttrsOnly 0\\n                -showTextureNodesOnly 0\\n                -attrAlphaOrder \\\"default\\\" \\n                -animLayerFilterOptions \\\"allAffecting\\\" \\n                -sortOrder \\\"none\\\" \\n                -longNames 0\\n\"\n\t\t+ \"                -niceNames 1\\n                -showNamespace 1\\n                -showPinIcons 0\\n                -mapMotionTrails 0\\n                $editorName;\\n\\t\\t}\\n\\t} else {\\n\\t\\t$label = `panel -q -label $panelName`;\\n\\t\\toutlinerPanel -edit -l (localizedPanelLabel(\\\"Outliner\\\")) -mbv $menusOkayInPanels  $panelName;\\n\\t\\t$editorName = $panelName;\\n        outlinerEditor -e \\n            -showShapes 1\\n            -showAttributes 0\\n            -showConnected 0\\n            -showAnimCurvesOnly 0\\n            -showMuteInfo 0\\n            -organizeByLayer 1\\n            -showAnimLayerWeight 1\\n            -autoExpandLayers 1\\n            -autoExpand 0\\n            -showDagOnly 0\\n            -showAssets 1\\n            -showContainedOnly 1\\n            -showPublishedAsConnected 0\\n            -showContainerContents 1\\n            -ignoreDagHierarchy 0\\n            -expandConnections 0\\n            -showUpstreamCurves 1\\n            -showUnitlessCurves 1\\n            -showCompounds 1\\n            -showLeafs 1\\n            -showNumericAttrsOnly 0\\n            -highlightActive 1\\n\"\n\t\t+ \"            -autoSelectNewObjects 0\\n            -doNotSelectNewObjects 0\\n            -dropIsParent 1\\n            -transmitFilters 0\\n            -setFilter \\\"defaultSetFilter\\\" \\n            -showSetMembers 1\\n            -allowMultiSelection 1\\n            -alwaysToggleSelect 0\\n            -directSelect 0\\n            -displayMode \\\"DAG\\\" \\n            -expandObjects 0\\n            -setsIgnoreFilters 1\\n            -containersIgnoreFilters 0\\n            -editAttrName 0\\n            -showAttrValues 0\\n            -highlightSecondary 0\\n            -showUVAttrsOnly 0\\n            -showTextureNodesOnly 0\\n            -attrAlphaOrder \\\"default\\\" \\n            -animLayerFilterOptions \\\"allAffecting\\\" \\n            -sortOrder \\\"none\\\" \\n            -longNames 0\\n            -niceNames 1\\n            -showNamespace 1\\n            -showPinIcons 0\\n            -mapMotionTrails 0\\n            $editorName;\\n\\t\\tif (!$useSceneConfig) {\\n\\t\\t\\tpanel -e -l $label $panelName;\\n\\t\\t}\\n\\t}\\n\\n\\n\\t$panelName = `sceneUIReplacement -getNextScriptedPanel \\\"graphEditor\\\" (localizedPanelLabel(\\\"Graph Editor\\\")) `;\\n\"\n\t\t+ \"\\tif (\\\"\\\" == $panelName) {\\n\\t\\tif ($useSceneConfig) {\\n\\t\\t\\t$panelName = `scriptedPanel -unParent  -type \\\"graphEditor\\\" -l (localizedPanelLabel(\\\"Graph Editor\\\")) -mbv $menusOkayInPanels `;\\n\\n\\t\\t\\t$editorName = ($panelName+\\\"OutlineEd\\\");\\n            outlinerEditor -e \\n                -showShapes 1\\n                -showAttributes 1\\n                -showConnected 1\\n                -showAnimCurvesOnly 1\\n                -showMuteInfo 0\\n                -organizeByLayer 1\\n                -showAnimLayerWeight 1\\n                -autoExpandLayers 1\\n                -autoExpand 1\\n                -showDagOnly 0\\n                -showAssets 1\\n                -showContainedOnly 0\\n                -showPublishedAsConnected 0\\n                -showContainerContents 0\\n                -ignoreDagHierarchy 0\\n                -expandConnections 1\\n                -showUpstreamCurves 1\\n                -showUnitlessCurves 1\\n                -showCompounds 0\\n                -showLeafs 1\\n                -showNumericAttrsOnly 1\\n                -highlightActive 0\\n\"\n\t\t+ \"                -autoSelectNewObjects 1\\n                -doNotSelectNewObjects 0\\n                -dropIsParent 1\\n                -transmitFilters 1\\n                -setFilter \\\"0\\\" \\n                -showSetMembers 0\\n                -allowMultiSelection 1\\n                -alwaysToggleSelect 0\\n                -directSelect 0\\n                -displayMode \\\"DAG\\\" \\n                -expandObjects 0\\n                -setsIgnoreFilters 1\\n                -containersIgnoreFilters 0\\n                -editAttrName 0\\n                -showAttrValues 0\\n                -highlightSecondary 0\\n                -showUVAttrsOnly 0\\n                -showTextureNodesOnly 0\\n                -attrAlphaOrder \\\"default\\\" \\n                -animLayerFilterOptions \\\"allAffecting\\\" \\n                -sortOrder \\\"none\\\" \\n                -longNames 0\\n                -niceNames 1\\n                -showNamespace 1\\n                -showPinIcons 1\\n                -mapMotionTrails 1\\n                $editorName;\\n\\n\\t\\t\\t$editorName = ($panelName+\\\"GraphEd\\\");\\n            animCurveEditor -e \\n\"\n\t\t+ \"                -displayKeys 1\\n                -displayTangents 0\\n                -displayActiveKeys 0\\n                -displayActiveKeyTangents 1\\n                -displayInfinities 0\\n                -autoFit 0\\n                -snapTime \\\"integer\\\" \\n                -snapValue \\\"none\\\" \\n                -showResults \\\"off\\\" \\n                -showBufferCurves \\\"off\\\" \\n                -smoothness \\\"fine\\\" \\n                -resultSamples 1\\n                -resultScreenSamples 0\\n                -resultUpdate \\\"delayed\\\" \\n                -showUpstreamCurves 1\\n                -stackedCurves 0\\n                -stackedCurvesMin -1\\n                -stackedCurvesMax 1\\n                -stackedCurvesSpace 0.2\\n                -displayNormalized 0\\n                -preSelectionHighlight 0\\n                -constrainDrag 0\\n                -classicMode 1\\n                $editorName;\\n\\t\\t}\\n\\t} else {\\n\\t\\t$label = `panel -q -label $panelName`;\\n\\t\\tscriptedPanel -edit -l (localizedPanelLabel(\\\"Graph Editor\\\")) -mbv $menusOkayInPanels  $panelName;\\n\\n\\t\\t\\t$editorName = ($panelName+\\\"OutlineEd\\\");\\n\"\n\t\t+ \"            outlinerEditor -e \\n                -showShapes 1\\n                -showAttributes 1\\n                -showConnected 1\\n                -showAnimCurvesOnly 1\\n                -showMuteInfo 0\\n                -organizeByLayer 1\\n                -showAnimLayerWeight 1\\n                -autoExpandLayers 1\\n                -autoExpand 1\\n                -showDagOnly 0\\n                -showAssets 1\\n                -showContainedOnly 0\\n                -showPublishedAsConnected 0\\n                -showContainerContents 0\\n                -ignoreDagHierarchy 0\\n                -expandConnections 1\\n                -showUpstreamCurves 1\\n                -showUnitlessCurves 1\\n                -showCompounds 0\\n                -showLeafs 1\\n                -showNumericAttrsOnly 1\\n                -highlightActive 0\\n                -autoSelectNewObjects 1\\n                -doNotSelectNewObjects 0\\n                -dropIsParent 1\\n                -transmitFilters 1\\n                -setFilter \\\"0\\\" \\n                -showSetMembers 0\\n                -allowMultiSelection 1\\n\"\n\t\t+ \"                -alwaysToggleSelect 0\\n                -directSelect 0\\n                -displayMode \\\"DAG\\\" \\n                -expandObjects 0\\n                -setsIgnoreFilters 1\\n                -containersIgnoreFilters 0\\n                -editAttrName 0\\n                -showAttrValues 0\\n                -highlightSecondary 0\\n                -showUVAttrsOnly 0\\n                -showTextureNodesOnly 0\\n                -attrAlphaOrder \\\"default\\\" \\n                -animLayerFilterOptions \\\"allAffecting\\\" \\n                -sortOrder \\\"none\\\" \\n                -longNames 0\\n                -niceNames 1\\n                -showNamespace 1\\n                -showPinIcons 1\\n                -mapMotionTrails 1\\n                $editorName;\\n\\n\\t\\t\\t$editorName = ($panelName+\\\"GraphEd\\\");\\n            animCurveEditor -e \\n                -displayKeys 1\\n                -displayTangents 0\\n                -displayActiveKeys 0\\n                -displayActiveKeyTangents 1\\n                -displayInfinities 0\\n                -autoFit 0\\n                -snapTime \\\"integer\\\" \\n\"\n\t\t+ \"                -snapValue \\\"none\\\" \\n                -showResults \\\"off\\\" \\n                -showBufferCurves \\\"off\\\" \\n                -smoothness \\\"fine\\\" \\n                -resultSamples 1\\n                -resultScreenSamples 0\\n                -resultUpdate \\\"delayed\\\" \\n                -showUpstreamCurves 1\\n                -stackedCurves 0\\n                -stackedCurvesMin -1\\n                -stackedCurvesMax 1\\n                -stackedCurvesSpace 0.2\\n                -displayNormalized 0\\n                -preSelectionHighlight 0\\n                -constrainDrag 0\\n                -classicMode 1\\n                $editorName;\\n\\t\\tif (!$useSceneConfig) {\\n\\t\\t\\tpanel -e -l $label $panelName;\\n\\t\\t}\\n\\t}\\n\\n\\n\\t$panelName = `sceneUIReplacement -getNextScriptedPanel \\\"dopeSheetPanel\\\" (localizedPanelLabel(\\\"Dope Sheet\\\")) `;\\n\\tif (\\\"\\\" == $panelName) {\\n\\t\\tif ($useSceneConfig) {\\n\\t\\t\\t$panelName = `scriptedPanel -unParent  -type \\\"dopeSheetPanel\\\" -l (localizedPanelLabel(\\\"Dope Sheet\\\")) -mbv $menusOkayInPanels `;\\n\\n\\t\\t\\t$editorName = ($panelName+\\\"OutlineEd\\\");\\n            outlinerEditor -e \\n\"\n\t\t+ \"                -showShapes 1\\n                -showAttributes 1\\n                -showConnected 1\\n                -showAnimCurvesOnly 1\\n                -showMuteInfo 0\\n                -organizeByLayer 1\\n                -showAnimLayerWeight 1\\n                -autoExpandLayers 1\\n                -autoExpand 0\\n                -showDagOnly 0\\n                -showAssets 1\\n                -showContainedOnly 0\\n                -showPublishedAsConnected 0\\n                -showContainerContents 0\\n                -ignoreDagHierarchy 0\\n                -expandConnections 1\\n                -showUpstreamCurves 1\\n                -showUnitlessCurves 0\\n                -showCompounds 1\\n                -showLeafs 1\\n                -showNumericAttrsOnly 1\\n                -highlightActive 0\\n                -autoSelectNewObjects 0\\n                -doNotSelectNewObjects 1\\n                -dropIsParent 1\\n                -transmitFilters 0\\n                -setFilter \\\"0\\\" \\n                -showSetMembers 0\\n                -allowMultiSelection 1\\n\"\n\t\t+ \"                -alwaysToggleSelect 0\\n                -directSelect 0\\n                -displayMode \\\"DAG\\\" \\n                -expandObjects 0\\n                -setsIgnoreFilters 1\\n                -containersIgnoreFilters 0\\n                -editAttrName 0\\n                -showAttrValues 0\\n                -highlightSecondary 0\\n                -showUVAttrsOnly 0\\n                -showTextureNodesOnly 0\\n                -attrAlphaOrder \\\"default\\\" \\n                -animLayerFilterOptions \\\"allAffecting\\\" \\n                -sortOrder \\\"none\\\" \\n                -longNames 0\\n                -niceNames 1\\n                -showNamespace 1\\n                -showPinIcons 0\\n                -mapMotionTrails 1\\n                $editorName;\\n\\n\\t\\t\\t$editorName = ($panelName+\\\"DopeSheetEd\\\");\\n            dopeSheetEditor -e \\n                -displayKeys 1\\n                -displayTangents 0\\n                -displayActiveKeys 0\\n                -displayActiveKeyTangents 0\\n                -displayInfinities 0\\n                -autoFit 0\\n                -snapTime \\\"integer\\\" \\n\"\n\t\t+ \"                -snapValue \\\"none\\\" \\n                -outliner \\\"dopeSheetPanel1OutlineEd\\\" \\n                -showSummary 1\\n                -showScene 0\\n                -hierarchyBelow 0\\n                -showTicks 1\\n                -selectionWindow 0 0 0 0 \\n                $editorName;\\n\\t\\t}\\n\\t} else {\\n\\t\\t$label = `panel -q -label $panelName`;\\n\\t\\tscriptedPanel -edit -l (localizedPanelLabel(\\\"Dope Sheet\\\")) -mbv $menusOkayInPanels  $panelName;\\n\\n\\t\\t\\t$editorName = ($panelName+\\\"OutlineEd\\\");\\n            outlinerEditor -e \\n                -showShapes 1\\n                -showAttributes 1\\n                -showConnected 1\\n                -showAnimCurvesOnly 1\\n                -showMuteInfo 0\\n                -organizeByLayer 1\\n                -showAnimLayerWeight 1\\n                -autoExpandLayers 1\\n                -autoExpand 0\\n                -showDagOnly 0\\n                -showAssets 1\\n                -showContainedOnly 0\\n                -showPublishedAsConnected 0\\n                -showContainerContents 0\\n                -ignoreDagHierarchy 0\\n\"\n\t\t+ \"                -expandConnections 1\\n                -showUpstreamCurves 1\\n                -showUnitlessCurves 0\\n                -showCompounds 1\\n                -showLeafs 1\\n                -showNumericAttrsOnly 1\\n                -highlightActive 0\\n                -autoSelectNewObjects 0\\n                -doNotSelectNewObjects 1\\n                -dropIsParent 1\\n                -transmitFilters 0\\n                -setFilter \\\"0\\\" \\n                -showSetMembers 0\\n                -allowMultiSelection 1\\n                -alwaysToggleSelect 0\\n                -directSelect 0\\n                -displayMode \\\"DAG\\\" \\n                -expandObjects 0\\n                -setsIgnoreFilters 1\\n                -containersIgnoreFilters 0\\n                -editAttrName 0\\n                -showAttrValues 0\\n                -highlightSecondary 0\\n                -showUVAttrsOnly 0\\n                -showTextureNodesOnly 0\\n                -attrAlphaOrder \\\"default\\\" \\n                -animLayerFilterOptions \\\"allAffecting\\\" \\n                -sortOrder \\\"none\\\" \\n\"\n\t\t+ \"                -longNames 0\\n                -niceNames 1\\n                -showNamespace 1\\n                -showPinIcons 0\\n                -mapMotionTrails 1\\n                $editorName;\\n\\n\\t\\t\\t$editorName = ($panelName+\\\"DopeSheetEd\\\");\\n            dopeSheetEditor -e \\n                -displayKeys 1\\n                -displayTangents 0\\n                -displayActiveKeys 0\\n                -displayActiveKeyTangents 0\\n                -displayInfinities 0\\n                -autoFit 0\\n                -snapTime \\\"integer\\\" \\n                -snapValue \\\"none\\\" \\n                -outliner \\\"dopeSheetPanel1OutlineEd\\\" \\n                -showSummary 1\\n                -showScene 0\\n                -hierarchyBelow 0\\n                -showTicks 1\\n                -selectionWindow 0 0 0 0 \\n                $editorName;\\n\\t\\tif (!$useSceneConfig) {\\n\\t\\t\\tpanel -e -l $label $panelName;\\n\\t\\t}\\n\\t}\\n\\n\\n\\t$panelName = `sceneUIReplacement -getNextScriptedPanel \\\"clipEditorPanel\\\" (localizedPanelLabel(\\\"Trax Editor\\\")) `;\\n\\tif (\\\"\\\" == $panelName) {\\n\\t\\tif ($useSceneConfig) {\\n\"\n\t\t+ \"\\t\\t\\t$panelName = `scriptedPanel -unParent  -type \\\"clipEditorPanel\\\" -l (localizedPanelLabel(\\\"Trax Editor\\\")) -mbv $menusOkayInPanels `;\\n\\n\\t\\t\\t$editorName = clipEditorNameFromPanel($panelName);\\n            clipEditor -e \\n                -displayKeys 0\\n                -displayTangents 0\\n                -displayActiveKeys 0\\n                -displayActiveKeyTangents 0\\n                -displayInfinities 0\\n                -autoFit 0\\n                -snapTime \\\"none\\\" \\n                -snapValue \\\"none\\\" \\n                -manageSequencer 0 \\n                $editorName;\\n\\t\\t}\\n\\t} else {\\n\\t\\t$label = `panel -q -label $panelName`;\\n\\t\\tscriptedPanel -edit -l (localizedPanelLabel(\\\"Trax Editor\\\")) -mbv $menusOkayInPanels  $panelName;\\n\\n\\t\\t\\t$editorName = clipEditorNameFromPanel($panelName);\\n            clipEditor -e \\n                -displayKeys 0\\n                -displayTangents 0\\n                -displayActiveKeys 0\\n                -displayActiveKeyTangents 0\\n                -displayInfinities 0\\n                -autoFit 0\\n                -snapTime \\\"none\\\" \\n\"\n\t\t+ \"                -snapValue \\\"none\\\" \\n                -manageSequencer 0 \\n                $editorName;\\n\\t\\tif (!$useSceneConfig) {\\n\\t\\t\\tpanel -e -l $label $panelName;\\n\\t\\t}\\n\\t}\\n\\n\\n\\t$panelName = `sceneUIReplacement -getNextScriptedPanel \\\"hyperGraphPanel\\\" (localizedPanelLabel(\\\"Hypergraph Hierarchy\\\")) `;\\n\\tif (\\\"\\\" == $panelName) {\\n\\t\\tif ($useSceneConfig) {\\n\\t\\t\\t$panelName = `scriptedPanel -unParent  -type \\\"hyperGraphPanel\\\" -l (localizedPanelLabel(\\\"Hypergraph Hierarchy\\\")) -mbv $menusOkayInPanels `;\\n\\n\\t\\t\\t$editorName = ($panelName+\\\"HyperGraphEd\\\");\\n            hyperGraph -e \\n                -graphLayoutStyle \\\"hierarchicalLayout\\\" \\n                -orientation \\\"horiz\\\" \\n                -mergeConnections 0\\n                -zoom 1\\n                -animateTransition 0\\n                -showRelationships 1\\n                -showShapes 0\\n                -showDeformers 0\\n                -showExpressions 0\\n                -showConstraints 0\\n                -showUnderworld 0\\n                -showInvisible 0\\n                -transitionFrames 1\\n                -opaqueContainers 0\\n\"\n\t\t+ \"                -freeform 0\\n                -imagePosition 0 0 \\n                -imageScale 1\\n                -imageEnabled 0\\n                -graphType \\\"DAG\\\" \\n                -heatMapDisplay 0\\n                -updateSelection 1\\n                -updateNodeAdded 1\\n                -useDrawOverrideColor 0\\n                -limitGraphTraversal -1\\n                -range 0 0 \\n                -iconSize \\\"smallIcons\\\" \\n                -showCachedConnections 0\\n                $editorName;\\n\\t\\t}\\n\\t} else {\\n\\t\\t$label = `panel -q -label $panelName`;\\n\\t\\tscriptedPanel -edit -l (localizedPanelLabel(\\\"Hypergraph Hierarchy\\\")) -mbv $menusOkayInPanels  $panelName;\\n\\n\\t\\t\\t$editorName = ($panelName+\\\"HyperGraphEd\\\");\\n            hyperGraph -e \\n                -graphLayoutStyle \\\"hierarchicalLayout\\\" \\n                -orientation \\\"horiz\\\" \\n                -mergeConnections 0\\n                -zoom 1\\n                -animateTransition 0\\n                -showRelationships 1\\n                -showShapes 0\\n                -showDeformers 0\\n                -showExpressions 0\\n\"\n\t\t+ \"                -showConstraints 0\\n                -showUnderworld 0\\n                -showInvisible 0\\n                -transitionFrames 1\\n                -opaqueContainers 0\\n                -freeform 0\\n                -imagePosition 0 0 \\n                -imageScale 1\\n                -imageEnabled 0\\n                -graphType \\\"DAG\\\" \\n                -heatMapDisplay 0\\n                -updateSelection 1\\n                -updateNodeAdded 1\\n                -useDrawOverrideColor 0\\n                -limitGraphTraversal -1\\n                -range 0 0 \\n                -iconSize \\\"smallIcons\\\" \\n                -showCachedConnections 0\\n                $editorName;\\n\\t\\tif (!$useSceneConfig) {\\n\\t\\t\\tpanel -e -l $label $panelName;\\n\\t\\t}\\n\\t}\\n\\n\\n\\t$panelName = `sceneUIReplacement -getNextScriptedPanel \\\"hyperShadePanel\\\" (localizedPanelLabel(\\\"Hypershade\\\")) `;\\n\\tif (\\\"\\\" == $panelName) {\\n\\t\\tif ($useSceneConfig) {\\n\\t\\t\\t$panelName = `scriptedPanel -unParent  -type \\\"hyperShadePanel\\\" -l (localizedPanelLabel(\\\"Hypershade\\\")) -mbv $menusOkayInPanels `;\\n\\t\\t}\\n\\t} else {\\n\"\n\t\t+ \"\\t\\t$label = `panel -q -label $panelName`;\\n\\t\\tscriptedPanel -edit -l (localizedPanelLabel(\\\"Hypershade\\\")) -mbv $menusOkayInPanels  $panelName;\\n\\t\\tif (!$useSceneConfig) {\\n\\t\\t\\tpanel -e -l $label $panelName;\\n\\t\\t}\\n\\t}\\n\\n\\n\\t$panelName = `sceneUIReplacement -getNextScriptedPanel \\\"visorPanel\\\" (localizedPanelLabel(\\\"Visor\\\")) `;\\n\\tif (\\\"\\\" == $panelName) {\\n\\t\\tif ($useSceneConfig) {\\n\\t\\t\\t$panelName = `scriptedPanel -unParent  -type \\\"visorPanel\\\" -l (localizedPanelLabel(\\\"Visor\\\")) -mbv $menusOkayInPanels `;\\n\\t\\t}\\n\\t} else {\\n\\t\\t$label = `panel -q -label $panelName`;\\n\\t\\tscriptedPanel -edit -l (localizedPanelLabel(\\\"Visor\\\")) -mbv $menusOkayInPanels  $panelName;\\n\\t\\tif (!$useSceneConfig) {\\n\\t\\t\\tpanel -e -l $label $panelName;\\n\\t\\t}\\n\\t}\\n\\n\\n\\t$panelName = `sceneUIReplacement -getNextScriptedPanel \\\"polyTexturePlacementPanel\\\" (localizedPanelLabel(\\\"UV Texture Editor\\\")) `;\\n\\tif (\\\"\\\" == $panelName) {\\n\\t\\tif ($useSceneConfig) {\\n\\t\\t\\t$panelName = `scriptedPanel -unParent  -type \\\"polyTexturePlacementPanel\\\" -l (localizedPanelLabel(\\\"UV Texture Editor\\\")) -mbv $menusOkayInPanels `;\\n\"\n\t\t+ \"\\t\\t}\\n\\t} else {\\n\\t\\t$label = `panel -q -label $panelName`;\\n\\t\\tscriptedPanel -edit -l (localizedPanelLabel(\\\"UV Texture Editor\\\")) -mbv $menusOkayInPanels  $panelName;\\n\\t\\tif (!$useSceneConfig) {\\n\\t\\t\\tpanel -e -l $label $panelName;\\n\\t\\t}\\n\\t}\\n\\n\\n\\t$panelName = `sceneUIReplacement -getNextScriptedPanel \\\"renderWindowPanel\\\" (localizedPanelLabel(\\\"Render View\\\")) `;\\n\\tif (\\\"\\\" == $panelName) {\\n\\t\\tif ($useSceneConfig) {\\n\\t\\t\\t$panelName = `scriptedPanel -unParent  -type \\\"renderWindowPanel\\\" -l (localizedPanelLabel(\\\"Render View\\\")) -mbv $menusOkayInPanels `;\\n\\t\\t}\\n\\t} else {\\n\\t\\t$label = `panel -q -label $panelName`;\\n\\t\\tscriptedPanel -edit -l (localizedPanelLabel(\\\"Render View\\\")) -mbv $menusOkayInPanels  $panelName;\\n\\t\\tif (!$useSceneConfig) {\\n\\t\\t\\tpanel -e -l $label $panelName;\\n\\t\\t}\\n\\t}\\n\\n\\n\\t$panelName = `sceneUIReplacement -getNextPanel \\\"blendShapePanel\\\" (localizedPanelLabel(\\\"Blend Shape\\\")) `;\\n\\tif (\\\"\\\" == $panelName) {\\n\\t\\tif ($useSceneConfig) {\\n\\t\\t\\tblendShapePanel -unParent -l (localizedPanelLabel(\\\"Blend Shape\\\")) -mbv $menusOkayInPanels ;\\n\\t\\t}\\n\\t} else {\\n\\t\\t$label = `panel -q -label $panelName`;\\n\"\n\t\t+ \"\\t\\tblendShapePanel -edit -l (localizedPanelLabel(\\\"Blend Shape\\\")) -mbv $menusOkayInPanels  $panelName;\\n\\t\\tif (!$useSceneConfig) {\\n\\t\\t\\tpanel -e -l $label $panelName;\\n\\t\\t}\\n\\t}\\n\\n\\n\\t$panelName = `sceneUIReplacement -getNextScriptedPanel \\\"dynRelEdPanel\\\" (localizedPanelLabel(\\\"Dynamic Relationships\\\")) `;\\n\\tif (\\\"\\\" == $panelName) {\\n\\t\\tif ($useSceneConfig) {\\n\\t\\t\\t$panelName = `scriptedPanel -unParent  -type \\\"dynRelEdPanel\\\" -l (localizedPanelLabel(\\\"Dynamic Relationships\\\")) -mbv $menusOkayInPanels `;\\n\\t\\t}\\n\\t} else {\\n\\t\\t$label = `panel -q -label $panelName`;\\n\\t\\tscriptedPanel -edit -l (localizedPanelLabel(\\\"Dynamic Relationships\\\")) -mbv $menusOkayInPanels  $panelName;\\n\\t\\tif (!$useSceneConfig) {\\n\\t\\t\\tpanel -e -l $label $panelName;\\n\\t\\t}\\n\\t}\\n\\n\\n\\t$panelName = `sceneUIReplacement -getNextScriptedPanel \\\"relationshipPanel\\\" (localizedPanelLabel(\\\"Relationship Editor\\\")) `;\\n\\tif (\\\"\\\" == $panelName) {\\n\\t\\tif ($useSceneConfig) {\\n\\t\\t\\t$panelName = `scriptedPanel -unParent  -type \\\"relationshipPanel\\\" -l (localizedPanelLabel(\\\"Relationship Editor\\\")) -mbv $menusOkayInPanels `;\\n\"\n\t\t+ \"\\t\\t}\\n\\t} else {\\n\\t\\t$label = `panel -q -label $panelName`;\\n\\t\\tscriptedPanel -edit -l (localizedPanelLabel(\\\"Relationship Editor\\\")) -mbv $menusOkayInPanels  $panelName;\\n\\t\\tif (!$useSceneConfig) {\\n\\t\\t\\tpanel -e -l $label $panelName;\\n\\t\\t}\\n\\t}\\n\\n\\n\\t$panelName = `sceneUIReplacement -getNextScriptedPanel \\\"referenceEditorPanel\\\" (localizedPanelLabel(\\\"Reference Editor\\\")) `;\\n\\tif (\\\"\\\" == $panelName) {\\n\\t\\tif ($useSceneConfig) {\\n\\t\\t\\t$panelName = `scriptedPanel -unParent  -type \\\"referenceEditorPanel\\\" -l (localizedPanelLabel(\\\"Reference Editor\\\")) -mbv $menusOkayInPanels `;\\n\\t\\t}\\n\\t} else {\\n\\t\\t$label = `panel -q -label $panelName`;\\n\\t\\tscriptedPanel -edit -l (localizedPanelLabel(\\\"Reference Editor\\\")) -mbv $menusOkayInPanels  $panelName;\\n\\t\\tif (!$useSceneConfig) {\\n\\t\\t\\tpanel -e -l $label $panelName;\\n\\t\\t}\\n\\t}\\n\\n\\n\\t$panelName = `sceneUIReplacement -getNextScriptedPanel \\\"componentEditorPanel\\\" (localizedPanelLabel(\\\"Component Editor\\\")) `;\\n\\tif (\\\"\\\" == $panelName) {\\n\\t\\tif ($useSceneConfig) {\\n\\t\\t\\t$panelName = `scriptedPanel -unParent  -type \\\"componentEditorPanel\\\" -l (localizedPanelLabel(\\\"Component Editor\\\")) -mbv $menusOkayInPanels `;\\n\"\n\t\t+ \"\\t\\t}\\n\\t} else {\\n\\t\\t$label = `panel -q -label $panelName`;\\n\\t\\tscriptedPanel -edit -l (localizedPanelLabel(\\\"Component Editor\\\")) -mbv $menusOkayInPanels  $panelName;\\n\\t\\tif (!$useSceneConfig) {\\n\\t\\t\\tpanel -e -l $label $panelName;\\n\\t\\t}\\n\\t}\\n\\n\\n\\t$panelName = `sceneUIReplacement -getNextScriptedPanel \\\"dynPaintScriptedPanelType\\\" (localizedPanelLabel(\\\"Paint Effects\\\")) `;\\n\\tif (\\\"\\\" == $panelName) {\\n\\t\\tif ($useSceneConfig) {\\n\\t\\t\\t$panelName = `scriptedPanel -unParent  -type \\\"dynPaintScriptedPanelType\\\" -l (localizedPanelLabel(\\\"Paint Effects\\\")) -mbv $menusOkayInPanels `;\\n\\t\\t}\\n\\t} else {\\n\\t\\t$label = `panel -q -label $panelName`;\\n\\t\\tscriptedPanel -edit -l (localizedPanelLabel(\\\"Paint Effects\\\")) -mbv $menusOkayInPanels  $panelName;\\n\\t\\tif (!$useSceneConfig) {\\n\\t\\t\\tpanel -e -l $label $panelName;\\n\\t\\t}\\n\\t}\\n\\n\\n\\t$panelName = `sceneUIReplacement -getNextScriptedPanel \\\"scriptEditorPanel\\\" (localizedPanelLabel(\\\"Script Editor\\\")) `;\\n\\tif (\\\"\\\" == $panelName) {\\n\\t\\tif ($useSceneConfig) {\\n\\t\\t\\t$panelName = `scriptedPanel -unParent  -type \\\"scriptEditorPanel\\\" -l (localizedPanelLabel(\\\"Script Editor\\\")) -mbv $menusOkayInPanels `;\\n\"\n\t\t+ \"\\t\\t}\\n\\t} else {\\n\\t\\t$label = `panel -q -label $panelName`;\\n\\t\\tscriptedPanel -edit -l (localizedPanelLabel(\\\"Script Editor\\\")) -mbv $menusOkayInPanels  $panelName;\\n\\t\\tif (!$useSceneConfig) {\\n\\t\\t\\tpanel -e -l $label $panelName;\\n\\t\\t}\\n\\t}\\n\\n\\n\\t$panelName = `sceneUIReplacement -getNextScriptedPanel \\\"multiListerPanel\\\" (localizedPanelLabel(\\\"Multilister\\\")) `;\\n\\tif (\\\"\\\" == $panelName) {\\n\\t\\tif ($useSceneConfig) {\\n\\t\\t\\t$panelName = `scriptedPanel -unParent  -type \\\"multiListerPanel\\\" -l (localizedPanelLabel(\\\"Multilister\\\")) -mbv $menusOkayInPanels `;\\n\\t\\t}\\n\\t} else {\\n\\t\\t$label = `panel -q -label $panelName`;\\n\\t\\tscriptedPanel -edit -l (localizedPanelLabel(\\\"Multilister\\\")) -mbv $menusOkayInPanels  $panelName;\\n\\t\\tif (!$useSceneConfig) {\\n\\t\\t\\tpanel -e -l $label $panelName;\\n\\t\\t}\\n\\t}\\n\\n\\n\\t$panelName = `sceneUIReplacement -getNextPanel \\\"devicePanel\\\" (localizedPanelLabel(\\\"Devices\\\")) `;\\n\\tif (\\\"\\\" == $panelName) {\\n\\t\\tif ($useSceneConfig) {\\n\\t\\t\\tdevicePanel -unParent -l (localizedPanelLabel(\\\"Devices\\\")) -mbv $menusOkayInPanels ;\\n\\t\\t}\\n\\t} else {\\n\\t\\t$label = `panel -q -label $panelName`;\\n\"\n\t\t+ \"\\t\\tdevicePanel -edit -l (localizedPanelLabel(\\\"Devices\\\")) -mbv $menusOkayInPanels  $panelName;\\n\\t\\tif (!$useSceneConfig) {\\n\\t\\t\\tpanel -e -l $label $panelName;\\n\\t\\t}\\n\\t}\\n\\n\\n\\t$panelName = `sceneUIReplacement -getNextScriptedPanel \\\"webBrowserPanel\\\" (localizedPanelLabel(\\\"Web Browser\\\")) `;\\n\\tif (\\\"\\\" == $panelName) {\\n\\t\\tif ($useSceneConfig) {\\n\\t\\t\\t$panelName = `scriptedPanel -unParent  -type \\\"webBrowserPanel\\\" -l (localizedPanelLabel(\\\"Web Browser\\\")) -mbv $menusOkayInPanels `;\\n\\t\\t}\\n\\t} else {\\n\\t\\t$label = `panel -q -label $panelName`;\\n\\t\\tscriptedPanel -edit -l (localizedPanelLabel(\\\"Web Browser\\\")) -mbv $menusOkayInPanels  $panelName;\\n\\t\\tif (!$useSceneConfig) {\\n\\t\\t\\tpanel -e -l $label $panelName;\\n\\t\\t}\\n\\t}\\n\\n\\n\\t$panelName = `sceneUIReplacement -getNextScriptedPanel \\\"createNodePanel\\\" (localizedPanelLabel(\\\"Create Node\\\")) `;\\n\\tif (\\\"\\\" == $panelName) {\\n\\t\\tif ($useSceneConfig) {\\n\\t\\t\\t$panelName = `scriptedPanel -unParent  -type \\\"createNodePanel\\\" -l (localizedPanelLabel(\\\"Create Node\\\")) -mbv $menusOkayInPanels `;\\n\\t\\t}\\n\\t} else {\\n\\t\\t$label = `panel -q -label $panelName`;\\n\"\n\t\t+ \"\\t\\tscriptedPanel -edit -l (localizedPanelLabel(\\\"Create Node\\\")) -mbv $menusOkayInPanels  $panelName;\\n\\t\\tif (!$useSceneConfig) {\\n\\t\\t\\tpanel -e -l $label $panelName;\\n\\t\\t}\\n\\t}\\n\\n\\n\\t$panelName = `sceneUIReplacement -getNextScriptedPanel \\\"sequenceEditorPanel\\\" (localizedPanelLabel(\\\"Camera Sequencer\\\")) `;\\n\\tif (\\\"\\\" == $panelName) {\\n\\t\\tif ($useSceneConfig) {\\n\\t\\t\\t$panelName = `scriptedPanel -unParent  -type \\\"sequenceEditorPanel\\\" -l (localizedPanelLabel(\\\"Camera Sequencer\\\")) -mbv $menusOkayInPanels `;\\n\\n\\t\\t\\t$editorName = sequenceEditorNameFromPanel($panelName);\\n            clipEditor -e \\n                -displayKeys 0\\n                -displayTangents 0\\n                -displayActiveKeys 0\\n                -displayActiveKeyTangents 0\\n                -displayInfinities 0\\n                -autoFit 0\\n                -snapTime \\\"none\\\" \\n                -snapValue \\\"none\\\" \\n                -manageSequencer 1 \\n                $editorName;\\n\\t\\t}\\n\\t} else {\\n\\t\\t$label = `panel -q -label $panelName`;\\n\\t\\tscriptedPanel -edit -l (localizedPanelLabel(\\\"Camera Sequencer\\\")) -mbv $menusOkayInPanels  $panelName;\\n\"\n\t\t+ \"\\t\\t\\t$editorName = sequenceEditorNameFromPanel($panelName);\\n            clipEditor -e \\n                -displayKeys 0\\n                -displayTangents 0\\n                -displayActiveKeys 0\\n                -displayActiveKeyTangents 0\\n                -displayInfinities 0\\n                -autoFit 0\\n                -snapTime \\\"none\\\" \\n                -snapValue \\\"none\\\" \\n                -manageSequencer 1 \\n                $editorName;\\n\\t\\tif (!$useSceneConfig) {\\n\\t\\t\\tpanel -e -l $label $panelName;\\n\\t\\t}\\n\\t}\\n\\n\\n\\tif ($useSceneConfig) {\\n        string $configName = `getPanel -cwl (localizedPanelLabel(\\\"Current Layout\\\"))`;\\n        if (\\\"\\\" != $configName) {\\n\\t\\t\\tpanelConfiguration -edit -label (localizedPanelLabel(\\\"Current Layout\\\")) \\n\\t\\t\\t\\t-defaultImage \\\"\\\"\\n\\t\\t\\t\\t-image \\\"\\\"\\n\\t\\t\\t\\t-sc false\\n\\t\\t\\t\\t-configString \\\"global string $gMainPane; paneLayout -e -cn \\\\\\\"single\\\\\\\" -ps 1 100 100 $gMainPane;\\\"\\n\\t\\t\\t\\t-removeAllPanels\\n\\t\\t\\t\\t-ap true\\n\\t\\t\\t\\t\\t(localizedPanelLabel(\\\"Persp View\\\")) \\n\\t\\t\\t\\t\\t\\\"modelPanel\\\"\\n\"\n\t\t+ \"\\t\\t\\t\\t\\t\\\"$panelName = `modelPanel -unParent -l (localizedPanelLabel(\\\\\\\"Persp View\\\\\\\")) -mbv $menusOkayInPanels `;\\\\n$editorName = $panelName;\\\\nmodelEditor -e \\\\n    -cam `findStartUpCamera persp` \\\\n    -useInteractiveMode 0\\\\n    -displayLights \\\\\\\"default\\\\\\\" \\\\n    -displayAppearance \\\\\\\"wireframe\\\\\\\" \\\\n    -activeOnly 0\\\\n    -ignorePanZoom 0\\\\n    -wireframeOnShaded 0\\\\n    -headsUpDisplay 1\\\\n    -selectionHiliteDisplay 1\\\\n    -useDefaultMaterial 0\\\\n    -bufferMode \\\\\\\"double\\\\\\\" \\\\n    -twoSidedLighting 1\\\\n    -backfaceCulling 0\\\\n    -xray 0\\\\n    -jointXray 0\\\\n    -activeComponentsXray 0\\\\n    -displayTextures 0\\\\n    -smoothWireframe 0\\\\n    -lineWidth 1\\\\n    -textureAnisotropic 0\\\\n    -textureHilight 1\\\\n    -textureSampling 2\\\\n    -textureDisplay \\\\\\\"modulate\\\\\\\" \\\\n    -textureMaxSize 8192\\\\n    -fogging 0\\\\n    -fogSource \\\\\\\"fragment\\\\\\\" \\\\n    -fogMode \\\\\\\"linear\\\\\\\" \\\\n    -fogStart 0\\\\n    -fogEnd 100\\\\n    -fogDensity 0.1\\\\n    -fogColor 0.5 0.5 0.5 1 \\\\n    -maxConstantTransparency 1\\\\n    -rendererName \\\\\\\"base_OpenGL_Renderer\\\\\\\" \\\\n    -colorResolution 256 256 \\\\n    -bumpResolution 512 512 \\\\n    -textureCompression 0\\\\n    -transparencyAlgorithm \\\\\\\"frontAndBackCull\\\\\\\" \\\\n    -transpInShadows 0\\\\n    -cullingOverride \\\\\\\"none\\\\\\\" \\\\n    -lowQualityLighting 0\\\\n    -maximumNumHardwareLights 1\\\\n    -occlusionCulling 0\\\\n    -shadingModel 0\\\\n    -useBaseRenderer 0\\\\n    -useReducedRenderer 0\\\\n    -smallObjectCulling 0\\\\n    -smallObjectThreshold -1 \\\\n    -interactiveDisableShadows 0\\\\n    -interactiveBackFaceCull 0\\\\n    -sortTransparent 1\\\\n    -nurbsCurves 1\\\\n    -nurbsSurfaces 1\\\\n    -polymeshes 1\\\\n    -subdivSurfaces 1\\\\n    -planes 1\\\\n    -lights 1\\\\n    -cameras 1\\\\n    -controlVertices 1\\\\n    -hulls 1\\\\n    -grid 1\\\\n    -joints 1\\\\n    -ikHandles 1\\\\n    -deformers 1\\\\n    -dynamics 1\\\\n    -fluids 1\\\\n    -hairSystems 1\\\\n    -follicles 1\\\\n    -nCloths 1\\\\n    -nParticles 1\\\\n    -nRigids 1\\\\n    -dynamicConstraints 1\\\\n    -locators 1\\\\n    -manipulators 1\\\\n    -dimensions 1\\\\n    -handles 1\\\\n    -pivots 1\\\\n    -textures 1\\\\n    -strokes 1\\\\n    -motionTrails 1\\\\n    -shadows 0\\\\n    $editorName;\\\\nmodelEditor -e -viewSelected 0 $editorName\\\"\\n\"\n\t\t+ \"\\t\\t\\t\\t\\t\\\"modelPanel -edit -l (localizedPanelLabel(\\\\\\\"Persp View\\\\\\\")) -mbv $menusOkayInPanels  $panelName;\\\\n$editorName = $panelName;\\\\nmodelEditor -e \\\\n    -cam `findStartUpCamera persp` \\\\n    -useInteractiveMode 0\\\\n    -displayLights \\\\\\\"default\\\\\\\" \\\\n    -displayAppearance \\\\\\\"wireframe\\\\\\\" \\\\n    -activeOnly 0\\\\n    -ignorePanZoom 0\\\\n    -wireframeOnShaded 0\\\\n    -headsUpDisplay 1\\\\n    -selectionHiliteDisplay 1\\\\n    -useDefaultMaterial 0\\\\n    -bufferMode \\\\\\\"double\\\\\\\" \\\\n    -twoSidedLighting 1\\\\n    -backfaceCulling 0\\\\n    -xray 0\\\\n    -jointXray 0\\\\n    -activeComponentsXray 0\\\\n    -displayTextures 0\\\\n    -smoothWireframe 0\\\\n    -lineWidth 1\\\\n    -textureAnisotropic 0\\\\n    -textureHilight 1\\\\n    -textureSampling 2\\\\n    -textureDisplay \\\\\\\"modulate\\\\\\\" \\\\n    -textureMaxSize 8192\\\\n    -fogging 0\\\\n    -fogSource \\\\\\\"fragment\\\\\\\" \\\\n    -fogMode \\\\\\\"linear\\\\\\\" \\\\n    -fogStart 0\\\\n    -fogEnd 100\\\\n    -fogDensity 0.1\\\\n    -fogColor 0.5 0.5 0.5 1 \\\\n    -maxConstantTransparency 1\\\\n    -rendererName \\\\\\\"base_OpenGL_Renderer\\\\\\\" \\\\n    -colorResolution 256 256 \\\\n    -bumpResolution 512 512 \\\\n    -textureCompression 0\\\\n    -transparencyAlgorithm \\\\\\\"frontAndBackCull\\\\\\\" \\\\n    -transpInShadows 0\\\\n    -cullingOverride \\\\\\\"none\\\\\\\" \\\\n    -lowQualityLighting 0\\\\n    -maximumNumHardwareLights 1\\\\n    -occlusionCulling 0\\\\n    -shadingModel 0\\\\n    -useBaseRenderer 0\\\\n    -useReducedRenderer 0\\\\n    -smallObjectCulling 0\\\\n    -smallObjectThreshold -1 \\\\n    -interactiveDisableShadows 0\\\\n    -interactiveBackFaceCull 0\\\\n    -sortTransparent 1\\\\n    -nurbsCurves 1\\\\n    -nurbsSurfaces 1\\\\n    -polymeshes 1\\\\n    -subdivSurfaces 1\\\\n    -planes 1\\\\n    -lights 1\\\\n    -cameras 1\\\\n    -controlVertices 1\\\\n    -hulls 1\\\\n    -grid 1\\\\n    -joints 1\\\\n    -ikHandles 1\\\\n    -deformers 1\\\\n    -dynamics 1\\\\n    -fluids 1\\\\n    -hairSystems 1\\\\n    -follicles 1\\\\n    -nCloths 1\\\\n    -nParticles 1\\\\n    -nRigids 1\\\\n    -dynamicConstraints 1\\\\n    -locators 1\\\\n    -manipulators 1\\\\n    -dimensions 1\\\\n    -handles 1\\\\n    -pivots 1\\\\n    -textures 1\\\\n    -strokes 1\\\\n    -motionTrails 1\\\\n    -shadows 0\\\\n    $editorName;\\\\nmodelEditor -e -viewSelected 0 $editorName\\\"\\n\"\n\t\t+ \"\\t\\t\\t\\t$configName;\\n\\n            setNamedPanelLayout (localizedPanelLabel(\\\"Current Layout\\\"));\\n        }\\n\\n        panelHistory -e -clear mainPanelHistory;\\n        setFocus `paneLayout -q -p1 $gMainPane`;\\n        sceneUIReplacement -deleteRemaining;\\n        sceneUIReplacement -clear;\\n\\t}\\n\\n\\ngrid -spacing 5 -size 12 -divisions 5 -displayAxes yes -displayGridLines yes -displayDivisionLines yes -displayPerspectiveLabels no -displayOrthographicLabels no -displayAxesBold yes -perspectiveLabelPosition axis -orthographicLabelPosition edge;\\nviewManip -drawCompass 0 -compassAngle 0 -frontParameters \\\"\\\" -homeParameters \\\"\\\" -selectionLockParameters \\\"\\\";\\n}\\n\");\n\tsetAttr \".st\" 3;\ncreateNode script -n \"sceneConfigurationScriptNode\";\n\tsetAttr \".b\" -type \"string\" \"playbackOptions -min 1 -max 24 -ast 1 -aet 48 \";\n\tsetAttr \".st\" 6;\nselect -ne :time1;\n\tsetAttr \".o\" 1;\n\tsetAttr \".unw\" 1;\nselect -ne :renderPartition;\n\tsetAttr -s 2 \".st\";\nselect -ne :initialShadingGroup;\n\tsetAttr -s 4 \".dsm\";\n\tsetAttr \".ro\" yes;\nselect -ne :initialParticleSE;\n\tsetAttr \".ro\" yes;\nselect -ne :defaultShaderList1;\n\tsetAttr -s 2 \".s\";\nselect -ne :postProcessList1;\n\tsetAttr -s 2 \".p\";\nselect -ne :defaultRenderingList1;\nselect -ne :renderGlobalsList1;\nselect -ne :hardwareRenderGlobals;\n\tsetAttr \".ctrs\" 256;\n\tsetAttr \".btrs\" 512;\nselect -ne :defaultHardwareRenderGlobals;\n\tsetAttr \".fn\" -type \"string\" \"im\";\n\tsetAttr \".res\" -type \"string\" \"ntsc_4d 646 485 1.333\";\nconnectAttr \"polyCylinder1.out\" \"|pCylinder1|pCylinderShape1.i\";\nrelationship \"link\" \":lightLinker1\" \":initialShadingGroup.message\" \":defaultLightSet.message\";\nrelationship \"link\" \":lightLinker1\" \":initialParticleSE.message\" \":defaultLightSet.message\";\nrelationship \"shadowLink\" \":lightLinker1\" \":initialShadingGroup.message\" \":defaultLightSet.message\";\nrelationship \"shadowLink\" \":lightLinker1\" \":initialParticleSE.message\" \":defaultLightSet.message\";\nconnectAttr \"layerManager.dli[0]\" \"defaultLayer.id\";\nconnectAttr \"renderLayerManager.rlmi[0]\" \"defaultRenderLayer.rlid\";\nconnectAttr \"|pCylinder1|pCylinderShape1.iog\" \":initialShadingGroup.dsm\" -na;\nconnectAttr \"|pCylinder2|pCylinderShape1.iog\" \":initialShadingGroup.dsm\" -na;\nconnectAttr \"|pCylinder3|pCylinderShape1.iog\" \":initialShadingGroup.dsm\" -na;\nconnectAttr \"|pCylinder4|pCylinderShape1.iog\" \":initialShadingGroup.dsm\" -na;\nconnectAttr \"defaultRenderLayer.msg\" \":defaultRenderingList1.r\" -na;\n// End of multiInstance.ma\n"
  },
  {
    "path": "02_Commands/instanceRotate/Exercise - C++/instanceRotate.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 2012\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"instanceRotate\", \"instanceRotate.vcxproj\", \"{B29093BC-064C-4465-A61B-2DE73002010E}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|x64 = Debug|x64\n\t\tRelease|x64 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{B29093BC-064C-4465-A61B-2DE73002010E}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{B29093BC-064C-4465-A61B-2DE73002010E}.Debug|x64.Build.0 = Debug|x64\n\t\t{B29093BC-064C-4465-A61B-2DE73002010E}.Release|x64.ActiveCfg = Release|x64\n\t\t{B29093BC-064C-4465-A61B-2DE73002010E}.Release|x64.Build.0 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "02_Commands/instanceRotate/Exercise - C++/instanceRotate.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{B29093BC-064C-4465-A61B-2DE73002010E}</ProjectGuid>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup>\n    <_ProjectFileVersion>11.0.61030.0</_ProjectFileVersion>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <OutDir>Debug\\</OutDir>\n    <IntDir>Debug\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <OutDir>C:\\MayaAPITraining\\plug-ins\\</OutDir>\n    <TargetExt>.mll</TargetExt>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <OutDir>Release\\</OutDir>\n    <IntDir>Release\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2009\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>C:\\MayaAPITraining\\plug-ins\\instanceRotate.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2009\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2015\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>C:\\MayaAPITraining\\plug-ins\\instanceRotate.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2015\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"instanceRotateCmd.cpp\" />\n    <ClCompile Include=\"pluginMain.cpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"instanceRotateCmd.h\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "02_Commands/instanceRotate/Exercise - C++/instanceRotateCmd.cpp",
    "content": "//\n// Copyright (C) \n// \n// File: instanceRotateCmd.cpp\n//\n// MEL Command: instanceRotate\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#include <stdlib.h>\n#include <time.h>\n#include \"instanceRotateCmd.h\"\n\n#include <maya/MGlobal.h>\n#include <maya/MArgDatabase.h>\n#include <maya/MSyntax.h>\n#include <maya/MFnDagNode.h>\n#include <maya/MSelectionList.h>\n#include <maya/MPlug.h>\n\n//- Create a new MSyntax object to teach Maya about possible arguments\n//- in our command. This newSyntax() method is used during the command\n//- registration into our plug-in\n/*static*/ MSyntax instanceRotate::cmdSyntax()\n{\n\tMSyntax syntax;\n\tsyntax.addFlag(ROTATEFLAG,ROTATELONGFLAG,MSyntax::kUnsigned);\n\tsyntax.enableEdit(false);\n\tsyntax.enableQuery(false);\n\treturn syntax;\n}\n\n//- This method should perform a command by setting up internal class data\n//- and then calling the redoIt method if undo is supported by the command.\n//- The actual action performed by the command should be done in the redoIt \n//- method. This is a pure virtual method, and must be overridden in derived \n//- classes.\nMStatus instanceRotate::doIt( const MArgList& argList)\n{\n\tMStatus stat = MS::kSuccess;\n\n\t//- Since all the command actions will be done in the redoIt() method, this\n\t//- method will only parse the arguments. redoIt() will not use arguments\n\t//- at all.\n\tMArgDatabase argDB(syntax(),argList,&stat);\n\tif ( MS::kSuccess != stat )\n\t{\n\t\tcerr << \"Invalid flag used\";              \n\t\treturn stat.statusCode();        \n\t}\n\n\tunsigned int numFlags = argDB.numberOfFlagsUsed();\n\tif(numFlags != 1) \n\t{\n\t\tMGlobal::displayError(\"Simple Plugs requires one flag argument and a DAG object must be selected\");\n\t\treturn MS::kFailure;\n\t}\n\telse\n\t{\n\t\tif(argDB.isFlagSet(ROTATEFLAG, &stat))\n\t\t{\t\n\t\t\tuint flag =0;\n\t\t\t//- The user enters 1, 2, or 3 to indicate x, y, or z rotation axis\n\t\t\t//- TODO: get flag argument from \"ROTATEFLAG\"\n\t\t\t//...\n\n\t\t\tif(flag == AXIS_X)\n\t\t\t\taxis = AXIS_X;\n\t\t\telse if(flag == AXIS_Y)\n\t\t\t\taxis = AXIS_Y;\n\t\t\telse if(flag == AXIS_Z)\n\t\t\t\taxis = AXIS_Z;\n\t\t\telse\n\t\t\t{\n\t\t\t\tMGlobal::displayError(\"Invalid axis rotation argument\");\n\t\t\t\treturn MS::kFailure;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn redoIt();\n}\n\n//- This method should do the actual work of the command based on the internal \n//- class data only. Internal class data should be set in the doIt method.\nMStatus instanceRotate::redoIt()\n{\n\tsetResult( \"instanceRotate command executed!\\n\" );\n\n\t//- This is really where is the intelligence of the command. Here we will\n\t//- preform all the actions we wanted to implement for this command.\n\n\t//- Get the active selection in the Maya viewport.\n\tMSelectionList selList;\n\tMGlobal::getActiveSelectionList(selList);\n\n\tif(selList.isEmpty())\n\t{\n\t\tMGlobal::displayError(\"A single DAG object must be selected\");\n\t\treturn MS::kFailure;\n\t}\n\n\tMDagPath dagPath;\n\tselList.getDagPath(0,dagPath);\n\n\t//- Chances are the user selected the object from the panel view or\n\t//- outliner window so the object in the list will actually be a \n\t//- transform node... if so we call extendToShape to grab the actual\n\t//- shape node from the dagPath\n\n\t//- TODO: Test if this node is a transform node, and if so extend the\n\t//- TODO: dagPath to the real shape node.\n\t//...\n\t//...\n\n\tif(dagPath.isInstanced())\n\t{\n\t\tshapeObj = dagPath;\n\t\trotate(dagPath);\n\t}\n\telse\n\t{\n\t\tMGlobal::displayError(\"The selected item is not an instanced DAG object\");\n\t\treturn MS::kFailure;\n\t}\n\n\treturn MS::kSuccess;\n}\n\n//- This method should undo the work done by the redoIt method based on the \n//- internal class data only.\nMStatus instanceRotate::undoIt()\n{\n\tMGlobal::displayInfo( \"instanceRotate command undone!\\n\" );\n\t\n\tMFnDagNode fnDag(shapeObj);\n\n\tfor(uint i = 0; i<numInstances; i++)\n\t{\n\n\t\tMObject currentParent = fnDag.parent(i);\n\t\tMFnDependencyNode fnParent(currentParent);\n\t\tMPlug rotPlug = fnParent.findPlug(\"rotate\");\n\t\tswitch (axis)\n\t\t{\n\t\tcase AXIS_X:\n\t\t\t{\n\t\t\t\tMPlug rotxPlug = rotPlug.child(0);\n\t\t\t\trotxPlug.setValue(rotations[i]);\n\t\t\t\tbreak;\n\t\t\t}\n\t\tcase AXIS_Y:\n\t\t\t{\n\t\t\t\tMPlug rotyPlug = rotPlug.child(1);\n\t\t\t\trotyPlug.setValue(rotations[i]);\n\t\t\t\tbreak;\n\t\t\t}\n\t\tcase AXIS_Z:\n\t\t\t{\n\t\t\t\tMPlug rotzPlug = rotPlug.child(2);\n\t\t\t\trotzPlug.setValue(rotations[i]);\n\t\t\t\tbreak;\n\t\t\t}\n\t\tdefault:\n\t\t\t{\n\t\t\t\tMPlug rotyPlug = rotPlug.child(1);\n\t\t\t\trotyPlug.setValue(rotations[i]);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t//- Empty the array in case the user chooses redoIt\n\trotations.clear();\n\n\treturn MS::kSuccess;\n}\n\n//- Method used by redoIt to assign a 45 degree rotation along a random axis.\nvoid instanceRotate::rotate( MDagPath dp )\n{\n\t//- Seeds the random number generation function rand so it does not produce the \n\t//- same sequence of numbers every time.\n\tsrand(time(NULL));\n\n\t//- The passed-in dag object is a shape object, \n\t//- need to find all the parent transform objects.\n\tMFnDagNode fnDag(dp);\n\t//- The number of parents represents the current number of instances.\n\tnumInstances = fnDag.parentCount();\n\n\tfor(uint i = 0;i<numInstances;i++)\n\t{\n\t\tMObject currentParent = fnDag.parent(i);\n\t\tMFnDependencyNode fnParent(currentParent);\t\n\n\t\t//- Find the rotate plug, figure out which axis the user opted for \n\t\t//- and set the plug to a random direction.\n\n\t\t//- TODO: find the plug named 'rotate'\n\t\tMPlug rotPlug = //...\n\n\t\t//- Acquire a random number deciding which direction the 45 degree should be\n\t\tint randVal;\n\t\tif(rand()%2 == 0)\n\t\t\trandVal = 1;\n\t\telse randVal = -1;\n\t\tcout<<\"The randVal is \"<<randVal<<endl;\n\n\t\tswitch(axis)\n\t\t{\n\n\t\tcase AXIS_X:\n\t\t\t{\n\t\t\t\t//- TODO: Get the first child plug 'rotateX' \n\t\t\t\tMPlug rotxPlug = //...\n\n\t\t\t\t//- retrieve original rotation and store it in member variable \"rotations\"\n\t\t\t\tdouble origRot = 0;\n\t\t\t\t//- TODO: Get the plug value\n\t\t\t\t//...\n\t\t\t\trotations.append(origRot);\n\n\t\t\t\t//- set new rotation\n\t\t\t\tdouble rot = origRot + randVal * ROTATIONVALUE;\n\t\t\t\t//- TODO: Set the new plug value\n\t\t\t\t//...\n\t\t\t\tbreak;\n\t\t\t}\n\t\tcase AXIS_Y:\n\t\tdefault: //- by default, rotate around y axis\n\t\t\t{\n\t\t\t\t//- TODO: Get the second child plug 'rotateY' \n\t\t\t\tMPlug rotyPlug = //...\n\n\t\t\t\tdouble origRot = 0;\n\t\t\t\t//- TODO: Get the plug value\n\t\t\t\t//...\n\t\t\t\trotations.append(origRot);\n\n\t\t\t\tdouble rot = origRot + randVal * ROTATIONVALUE;\n\t\t\t\t//- TODO: Set the new plug value\n\t\t\t\t//...\n\t\t\t\tbreak;\n\t\t\t}\n\t\tcase AXIS_Z:\n\t\t\t{\n\t\t\t\t//- TODO: Get the third child plug 'rotateZ'\n\t\t\t\tMPlug rotzPlug = //...\n\n\t\t\t\tdouble origRot = 0;\n\t\t\t\t//- TODO: Get the plug value\n\t\t\t\t//...\n\t\t\t\trotations.append(origRot);\n\n\t\t\t\tdouble rot = origRot + randVal * ROTATIONVALUE;\n\t\t\t\t//- TODO: Set the new plug value\n\t\t\t\t//...\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n}\n"
  },
  {
    "path": "02_Commands/instanceRotate/Exercise - C++/instanceRotateCmd.h",
    "content": "//\n// Copyright (C) \n// \n// File: instanceRotateCmd.h\n//\n// MEL Command: instanceRotate\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#pragma once\n\n#include <maya/MPxCommand.h>\n#include <maya/MDagPath.h>\n#include <maya/MDoubleArray.h>\n\n//- Forward declaration\nclass MArgList;\n\n//- A convenience enum to keep track of which axis the user wanted to rotate around\ntypedef enum AXIS {AXIS_X = 1, AXIS_Y = 2, AXIS_Z = 3};\n\n//- This are the long and short command names.\n#define ROTATEFLAG \"-r\"\n#define ROTATELONGFLAG \"-rotate\"\n\n#define ROTATIONVALUE 0.785398163\n\n// Command class declaration\nclass instanceRotate : public MPxCommand\n{\n\npublic:\n\tinstanceRotate() {}\n\tvirtual ~instanceRotate() {}\n\n\t//- This method should perform a command by setting up internal class data\n\t//- and then calling the redoIt method if undo is supported by the command.\n\t//- The actual action performed by the command should be done in the redoIt \n\t//- method. This is a pure virtual method, and must be overridden in derived \n\t//- classes.\n\tvirtual MStatus doIt( const MArgList& );\n\t//- This method should do the actual work of the command based on the internal \n\t//- class data only. Internal class data should be set in the doIt method.\n\tvirtual MStatus redoIt();\n\t//- This method should undo the work done by the redoIt method based on the \n\t//- internal class data only.\n\tvirtual MStatus undoIt();\n\t//- This method is used to specify whether or not the command is undoable. In \n\t//- the base class, it always returns false. If you are writing a command that \n\t//- might be eligible for undo, you should override this method.\n\t//- After Maya executes the command's doIt method, it will call isUndoable. If \n\t//- isUndoable returns true, Maya will retain the instance of the class and pass \n\t//- it to Maya's undo manager so that the undoIt and redoIt methods can be called\n\t//- when appropriate. If isUndoable returns false, the command instance will be \n\t//- immediately destroyed.\n\tvirtual bool isUndoable() const {\n\t\treturn true;\n\t}\n\n\tstatic void* creator() {\n\t\tnew instanceRotate();\n\t}\n\n\tvirtual\tbool hasSyntax() {\n\t\treturn true;\n\t}\n\tstatic MSyntax cmdSyntax();\n\n\t//- Rotates each instance with 45 degrees along user-specified axis\n\tvoid rotate( MDagPath dp );\n\n\t//- Store the user selection of the rotation axis (one axis for all of the instances)\n\tAXIS axis;\n\n\t//- Store the base shape for the instances here for undo\n\tMDagPath shapeObj;\n\n\t//- Store the number of instances for one shape\n\tuint numInstances;\n\n\t//- Store the original rotation values for undo here\n\tMDoubleArray rotations;\n};\n"
  },
  {
    "path": "02_Commands/instanceRotate/Exercise - C++/pluginMain.cpp",
    "content": "//\n// Copyright (C) \n// \n// File: pluginMain.cpp\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#include \"instanceRotateCmd.h\"\n#include <maya/MFnPlugin.h>\n\nMStatus initializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is loaded into Maya.  It \n//\t\tregisters all of the services that this plug-in provides with \n//\t\tMaya.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{ \n\tMStatus   status;\n\tMFnPlugin plugin( obj, \"\", \"2008\", \"Any\");\n\n\t// Add plug-in feature registration here\n\t//\n\tstatus = plugin.registerCommand( \"instanceRotate\", instanceRotate::creator,instanceRotate::cmdSyntax );\n\n\tif (!status) {\n\t\tstatus.perror(\"registerCommand\");\n\t\treturn status;\n\t}\n\n\treturn status;\n}\n\nMStatus uninitializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is unloaded from Maya. It \n//\t\tderegisters all of the services that it was providing.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{\n\tMStatus   status;\n\tMFnPlugin plugin( obj );\n\n\t// Add plug-in feature deregistration here\n\t//\n\tstatus = plugin.deregisterCommand( \"instanceRotate\" );\n\n\tif (!status) {\n\t\tstatus.perror(\"deregisterCommand\");\n\t\treturn status;\n\t}\n\n\treturn status;\n}\n"
  },
  {
    "path": "02_Commands/instanceRotate/Exercise - py/instanceRotateCmd.py",
    "content": "# Copyright (C) \n# \n# Author: Autodesk Developer Network\n\n#For this exercise, search for the TODO keywords and follow the instructions in\n#comments. If you are unsure of what you need to do, feel free to ask the instructor\n#or look into the solution folder.\n#Each #... line is a line of code you need to write or complete.\n\nimport sys\nimport maya.OpenMaya as OpenMaya\nimport maya.OpenMayaMPx as OpenMayaMPx\n\n# Command name\nkPluginCmdName = \"instanceRotate\"\n\n# Command switch short and long names\nROTATEFLAG = \"-r\"\nROTATELONGFLAG = \"-rotate\"\n\nROTATIONVALUE = 0.785398163\nAXIS_X = 1\nAXIS_Y = 2\nAXIS_Z = 3\n\n# instanceRotate command\nclass instanceRotate(OpenMayaMPx.MPxCommand):\n\t#- Store the base shape for the instances here for undo\n\tshapeObj = OpenMaya.MDagPath()\n\t#- Store the original rotation values for undo here\n\trotations = OpenMaya.MDoubleArray()\n\n\tdef __init__(self):\n\t\tOpenMayaMPx.MPxCommand.__init__(self)\n\t\t#- Store the user selection of the rotation axis (one axis for all of the instances)\n\t\tself.axis = AXIS_X\n\t\t#- Store the number of instances for one shape\n\t\tself.numInstances = 0\n\n\t#- This method is used to specify whether or not the command is undoable. In \n\t#- the base class, it always returns false. If you are writing a command that \n\t#- might be eligible for undo, you should override this method.\n\t#- After Maya executes the command's doIt method, it will call isUndoable. If \n\t#- isUndoable returns true, Maya will retain the instance of the class and pass \n\t#- it to Maya's undo manager so that the undoIt and redoIt methods can be called\n\t#- when appropriate. If isUndoable returns false, the command instance will be \n\t#- immediately destroyed.\n\t#def isUndoable(self):\n\t#\treturn True\n\n\t#def hasSyntax(self):\n\t#\treturn True\n\n\t#- This method should perform a command by setting up internal class data\n\t#- and then calling the redoIt method if undo is supported by the command.\n\t#- The actual action performed by the command should be done in the redoIt \n\t#- method. This is a pure virtual method, and must be overridden in derived \n\t#- classes.\n\tdef doIt(self, args):\n\t\t#- Since all the command actions will be done in the redoIt() method, this\n\t\t#- method will only parse the arguments. redoIt() will not use arguments\n\t\t#- at all.\n\t\targParser = OpenMaya.MArgParser (self.syntax(),args)\n\n\t\tnumFlags = argParser.numberOfFlagsUsed()\n\t\tif(numFlags != 1):\n\t\t\tOpenMaya.MGlobal.displayError(\"Simple Plugs requires one flag argument and a DAG object must be selected\")\n\t\t\treturn None\n\t\telse:\n\t\t\tif(argParser.isFlagSet(ROTATEFLAG) | argParser.isFlagSet(ROTATELONGFLAG)):\n\t\t\t\t#- The user enters 1, 2, or 3 to indicate x, y, or z rotation axis\n\t\t\t\tflag =argParser.flagArgumentInt(ROTATEFLAG,0)\n\n\t\t\t\tif(flag == AXIS_X):\n\t\t\t\t\tself.axis = AXIS_X\n\t\t\t\telif(flag == AXIS_Y):\n\t\t\t\t\tself.axis = AXIS_Y\n\t\t\t\telif(flag == AXIS_Z):\n\t\t\t\t\tself.axis = AXIS_Z\n\t\t\t\telse:\n\t\t\t\t\tOpenMaya.MGlobal.displayError(\"Invalid axis rotation argument\")\n\t\t\t\t\treturn None\n\n\t\treturn self.redoIt(args)\n\n\t#- This method should do the actual work of the command based on the internal \n\t#- class data only. Internal class data should be set in the doIt method.\n\tdef redoIt(self, args):\n\t\tOpenMayaMPx.MPxCommand.setResult( \"instanceRotate command executed!\\n\" )\n\n\t\t#- This is really where is the intelligence of the command. Here we will\n\t\t#- preform all the actions we wanted to implement for this command.\n\n\t\t#- Get the active selection in the Maya viewport.\n\t\tselList = OpenMaya.MSelectionList()\n\t\tOpenMaya.MGlobal.getActiveSelectionList(selList)\n\n\t\tif(selList.isEmpty()):\n\t\t\tOpenMaya.MGlobal.displayError(\"A single DAG object must be selected\")\n\t\t\treturn None\n\n\t\tdagPath = OpenMaya.MDagPath()\n\t\tselList.getDagPath(0,dagPath)\n\n\t\t#- Chances are the user selected the object from the panel view or\n\t\t#- outliner window so the object in the list will actually be a \n\t\t#- transform node... if so we call extendToShape to grab the actual\n\t\t#- shape node from the dagPath\n\t\t\n\t\t#- TODO: Test if this node is a transform node, and if so extend the\n\t\t#- TODO: dagPath to the real shape node.\n\t\t#...\n\t\t#...\n\n\t\tif(dagPath.isInstanced()):\n\t\t\tself.shapeObj = dagPath\n\t\t\tself.rotate(dagPath)\n\t\telse:\n\t\t\tOpenMaya.MGlobal.displayError(\"The selected item is not an instanced DAG object\")\n\t\t\treturn None\n\n\t#- This method should undo the work done by the redoIt method based on the \n\t#- internal class data only.\n\tdef undoIt(self, args):\n\t\tOpenMaya.MGlobal.displayInfo( \"instanceRotate command undone!\\n\" )\n\t\t\n\t\tfnDag = MFnDagNode(self.shapeObj)\n\n\t\tfor i in range ( 0, self.numInstances ):\n\t\t\tcurrentParent = fnDag.parent(i)\n\t\t\tfnParent = OpenMaya.MFnDependencyNode(currentParent)\n\t\t\trotPlug = fnParent.findPlug(\"rotate\")\n\t\t\tif (self.axis == AXIS_X):\n\t\t\t\trotxPlug = rotPlug.child(0)\n\t\t\t\trotxPlug.setDouble(self.rotations[i])\n\t\t\telif (self.axis == AXIS_Z):\n\t\t\t\trotzPlug = rotPlug.child(2)\n\t\t\t\trotzPlug.setDouble(self.rotations[i])\n\t\t\telse: # AXIS_Y:\n\t\t\t\trotyPlug = rotPlug.child(1)\n\t\t\t\trotyPlug.setDouble(self.rotations[i])\n\n\t\t#- Empty the array in case the user chooses redoIt\n\t\tself.rotations.clear()\n\n\t#- Method used by redoIt to assign a 45 degree rotation along a random axis.\n\tdef rotate( self, dp ):\n\t\t#- The passed-in dag object is a shape object, \n\t\t#- need to find all the parent transform objects.\n\t\tfnDag = OpenMaya.MFnDagNode(dp)\n\t\t#- The number of parents represents the current number of instances.\n\t\tself.numInstances = fnDag.parentCount()\n\n\t\tfor i in range ( 0, self.numInstances ):\n\t\t\tcurrentParent = fnDag.parent(i)\n\t\t\tfnParent = OpenMaya.MFnDependencyNode(currentParent)\t\n\n\t\t\t#- Find the rotate plug, figure out which axis the user opted for \n\t\t\t#- and set the plug to a random direction.\n\t\t\t\n\t\t\t#- TODO: find the plug named 'rotate'\n\t\t\trotPlug = #...\n\n\t\t\t#- Acquire a random number deciding which direction the 45 degree should be\n\t\t\trandVal = random.randint(0, 1000)\n\t\t\tif(randVal % 2 == 0):\n\t\t\t\trandVal = 1\n\t\t\telse:\n\t\t\t\trandVal = -1\n\t\t\tprint \"The randVal is %d \" % randVal\n\t\t\tsys.stdout.write( '\\n' )\n\n\t\t\tif (self.axis == AXIS_X):\n\t\t\t\t#- TODO: Get the X plug of the 'rotate' plug\n\t\t\t\trotxPlug = #...\n\n\t\t\t\t#- retrieve original rotation and store it in member variable \"rotations\"\n\t\t\t\torigRot = 0\n\t\t\t\t#- TODO: Get the plug value\n\t\t\t\t#...\n\t\t\t\tself.rotations.append(origRot)\n\n\t\t\t\t#- set new rotation\n\t\t\t\trot = origRot + randVal * ROTATIONVALUE\n\t\t\t\t#- TODO: Set the new plug value\n\t\t\t\t#...\n\t\t\telif (self.axis == AXIS_Z):\n\t\t\t\t#- TODO: Get the Z plug of the 'rotate' plug\n\t\t\t\trotzPlug = #...\n\n\t\t\t\torigRot = 0\n\t\t\t\t#- TODO: Get the plug value\n\t\t\t\t#...\n\t\t\t\tself.rotations.append(origRot)\n\n\t\t\t\trot = origRot + randVal * ROTATIONVALUE\n\t\t\t\t#- TODO: Set the new plug value\n\t\t\t\t#...\n\t\t\telse: # AXIS_Y: - by default, rotate around y axis\n\t\t\t\t- TODO: Get the Y plug of the 'rotate' plug\n\t\t\t\trotyPlug = #...\n\n\t\t\t\torigRot = 0\n\t\t\t\t#- TODO: Get the plug value\n\t\t\t\t#...\n\t\t\t\tself.rotations.append(origRot)\n\n\t\t\t\trot = origRot + randVal * ROTATIONVALUE\n\t\t\t\t#- TODO: Set the new plug value\n\t\t\t\t#...\n\n# Creator\ndef cmdCreator():\n\treturn OpenMayaMPx.asMPxPtr( instanceRotate() )\n\n#- Create a new MSyntax object to teach Maya about possible arguments\n#- in our command. This newSyntax() method is used during the command\n#- registration into our plug-in\n# Syntax creator\ndef syntaxCreator():\n\tsyntax = OpenMaya.MSyntax()\n\tsyntax.addFlag(ROTATEFLAG, ROTATELONGFLAG, OpenMaya.MSyntax.kUnsigned)\n\tsyntax.enableEdit(0)\n\tsyntax.enableQuery(0)\n\treturn syntax\n\n# Initialize the script plug-in\ndef initializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\tmplugin.registerCommand( kPluginCmdName, cmdCreator, syntaxCreator )\n\texcept:\n\t\tsys.stderr.write( \"Failed to register command: %s\\n\" % kPluginCmdName )\n\n# Uninitialize the script plug-in\ndef uninitializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\tmplugin.deregisterCommand( kPluginCmdName )\n\texcept:\n\t\tsys.stderr.write( \"Failed to unregister command: %s\\n\" % kPluginCmdName )\n\n"
  },
  {
    "path": "02_Commands/instanceRotate/Solution - C++/instanceRotate.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 2012\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"instanceRotate\", \"instanceRotate.vcxproj\", \"{B29093BC-064C-4465-A61B-2DE73002010E}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|x64 = Debug|x64\n\t\tRelease|x64 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{B29093BC-064C-4465-A61B-2DE73002010E}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{B29093BC-064C-4465-A61B-2DE73002010E}.Debug|x64.Build.0 = Debug|x64\n\t\t{B29093BC-064C-4465-A61B-2DE73002010E}.Release|x64.ActiveCfg = Release|x64\n\t\t{B29093BC-064C-4465-A61B-2DE73002010E}.Release|x64.Build.0 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "02_Commands/instanceRotate/Solution - C++/instanceRotate.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{B29093BC-064C-4465-A61B-2DE73002010E}</ProjectGuid>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup>\n    <_ProjectFileVersion>11.0.61030.0</_ProjectFileVersion>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <OutDir>Debug\\</OutDir>\n    <IntDir>Debug\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <OutDir>C:\\MayaAPITraining\\plug-ins\\</OutDir>\n    <TargetExt>.mll</TargetExt>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <OutDir>Release\\</OutDir>\n    <IntDir>Release\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2009\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>C:\\MayaAPITraining\\plug-ins\\instanceRotate.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2009\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2015\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>C:\\MayaAPITraining\\plug-ins\\instanceRotate.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2015\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"instanceRotateCmd.cpp\" />\n    <ClCompile Include=\"pluginMain.cpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"instanceRotateCmd.h\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "02_Commands/instanceRotate/Solution - C++/instanceRotateCmd.cpp",
    "content": "//\n// Copyright (C) \n// \n// File: instanceRotateCmd.cpp\n//\n// MEL Command: instanceRotate\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#include <stdlib.h>\n#include <time.h>\n#include \"instanceRotateCmd.h\"\n\n#include <maya/MGlobal.h>\n#include <maya/MArgDatabase.h>\n#include <maya/MSyntax.h>\n#include <maya/MFnDagNode.h>\n#include <maya/MSelectionList.h>\n#include <maya/MPlug.h>\n\n//- Create a new MSyntax object to teach Maya about possible arguments\n//- in our command. This newSyntax() method is used during the command\n//- registration into our plug-in\n/*static*/ MSyntax instanceRotate::cmdSyntax()\n{\n\tMSyntax syntax;\n\tsyntax.addFlag(ROTATEFLAG,ROTATELONGFLAG,MSyntax::kUnsigned);\n\tsyntax.enableEdit(false);\n\tsyntax.enableQuery(false);\n\treturn syntax;\n}\n\n//- This method should perform a command by setting up internal class data\n//- and then calling the redoIt method if undo is supported by the command.\n//- The actual action performed by the command should be done in the redoIt \n//- method. This is a pure virtual method, and must be overridden in derived \n//- classes.\nMStatus instanceRotate::doIt( const MArgList& argList)\n{\n\tMStatus stat = MS::kSuccess;\n\n\t//- Since all the command actions will be done in the redoIt() method, this\n\t//- method will only parse the arguments. redoIt() will not use arguments\n\t//- at all.\n\tMArgDatabase argDB(syntax(),argList,&stat);\n\tif ( MS::kSuccess != stat )\n\t{\n\t\tcerr << \"Invalid flag used\";              \n\t\treturn stat.statusCode();        \n\t}\n\n\tunsigned int numFlags = argDB.numberOfFlagsUsed();\n\tif(numFlags != 1) \n\t{\n\t\tMGlobal::displayError(\"Simple Plugs requires one flag argument and a DAG object must be selected\");\n\t\treturn MS::kFailure;\n\t}\n\telse\n\t{\n\t\tif(argDB.isFlagSet(ROTATEFLAG, &stat))\n\t\t{\t\n\t\t\tuint flag =0;\n\t\t\t//- The user enters 1, 2, or 3 to indicate x, y, or z rotation axis\n\t\t\targDB.getFlagArgument(ROTATEFLAG,0,flag);\n\n\t\t\tif(flag == AXIS_X)\n\t\t\t\taxis = AXIS_X;\n\t\t\telse if(flag == AXIS_Y)\n\t\t\t\taxis = AXIS_Y;\n\t\t\telse if(flag == AXIS_Z)\n\t\t\t\taxis = AXIS_Z;\n\t\t\telse\n\t\t\t{\n\t\t\t\tMGlobal::displayError(\"Invalid axis rotation argument\");\n\t\t\t\treturn MS::kFailure;\n\t\t\t}\n\t\t}\n\t}\n\n\treturn redoIt();\n}\n\n//- This method should do the actual work of the command based on the internal \n//- class data only. Internal class data should be set in the doIt method.\nMStatus instanceRotate::redoIt()\n{\n\tsetResult( \"instanceRotate command executed!\\n\" );\n\n\t//- This is really where is the intelligence of the command. Here we will\n\t//- preform all the actions we wanted to implement for this command.\n\n\t//- Get the active selection in the Maya viewport.\n\tMSelectionList selList;\n\tMGlobal::getActiveSelectionList(selList);\n\n\tif(selList.isEmpty())\n\t{\n\t\tMGlobal::displayError(\"A single DAG object must be selected\");\n\t\treturn MS::kFailure;\n\t}\n\n\tMDagPath dagPath;\n\tselList.getDagPath(0,dagPath);\n\n\t//- Chances are the user selected the object from the panel view or\n\t//- outliner window so the object in the list will actually be a \n\t//- transform node... if so we call extendToShape to grab the actual\n\t//- shape node from the dagPath\n\tif(dagPath.hasFn(MFn::kTransform))\n\t\tdagPath.extendToShape();\n\n\tif(dagPath.isInstanced())\n\t{\n\t\tshapeObj = dagPath;\n\t\trotate(dagPath);\n\t}\n\telse\n\t{\n\t\tMGlobal::displayError(\"The selected item is not an instanced DAG object\");\n\t\treturn MS::kFailure;\n\t}\n\n\treturn MS::kSuccess;\n}\n\n//- This method should undo the work done by the redoIt method based on the \n//- internal class data only.\nMStatus instanceRotate::undoIt()\n{\n\tMGlobal::displayInfo( \"instanceRotate command undone!\\n\" );\n\t\n\tMFnDagNode fnDag(shapeObj);\n\n\tfor(uint i = 0; i<numInstances; i++)\n\t{\n\n\t\tMObject currentParent = fnDag.parent(i);\n\t\tMFnDependencyNode fnParent(currentParent);\n\t\tMPlug rotPlug = fnParent.findPlug(\"rotate\");\n\t\tswitch (axis)\n\t\t{\n\t\tcase AXIS_X:\n\t\t\t{\n\t\t\t\tMPlug rotxPlug = rotPlug.child(0);\n\t\t\t\trotxPlug.setValue(rotations[i]);\n\t\t\t\tbreak;\n\t\t\t}\n\t\tcase AXIS_Y:\n\t\t\t{\n\t\t\t\tMPlug rotyPlug = rotPlug.child(1);\n\t\t\t\trotyPlug.setValue(rotations[i]);\n\t\t\t\tbreak;\n\t\t\t}\n\t\tcase AXIS_Z:\n\t\t\t{\n\t\t\t\tMPlug rotzPlug = rotPlug.child(2);\n\t\t\t\trotzPlug.setValue(rotations[i]);\n\t\t\t\tbreak;\n\t\t\t}\n\t\tdefault:\n\t\t\t{\n\t\t\t\tMPlug rotyPlug = rotPlug.child(1);\n\t\t\t\trotyPlug.setValue(rotations[i]);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n\t//- Empty the array in case the user chooses redoIt\n\trotations.clear();\n\n\treturn MS::kSuccess;\n}\n\n//- Method used by redoIt to assign a 45 degree rotation along a random axis.\nvoid instanceRotate::rotate( MDagPath dp )\n{\n\t//- Seeds the random number generation function rand so it does not produce the \n\t//- same sequence of numbers every time.\n\tsrand(time(NULL));\n\n\t//- The passed-in dag object is a shape object, \n\t//- need to find all the parent transform objects.\n\tMFnDagNode fnDag(dp);\n\t//- The number of parents represents the current number of instances.\n\tnumInstances = fnDag.parentCount();\n\n\tfor(uint i = 0;i<numInstances;i++)\n\t{\n\t\tMObject currentParent = fnDag.parent(i);\n\t\tMFnDependencyNode fnParent(currentParent);\t\n\n\t\t//- Find the rotate plug, figure out which axis the user opted for \n\t\t//- and set the plug to a random direction.\n\t\tMPlug rotPlug = fnParent.findPlug(\"rotate\");\n\n\t\t//- Acquire a random number deciding which direction the 45 degree should be\n\t\tint randVal;\n\t\tif(rand()%2 == 0)\n\t\t\trandVal = 1;\n\t\telse randVal = -1;\n\t\tcout<<\"The randVal is \"<<randVal<<endl;\n\n\t\tswitch(axis)\n\t\t{\n\n\t\tcase AXIS_X:\n\t\t\t{\n\t\t\t\tMPlug rotxPlug = rotPlug.child(0);\n\n\t\t\t\t//- retrieve original rotation and store it in member variable \"rotations\"\n\t\t\t\tdouble origRot = 0;\n\t\t\t\trotxPlug.getValue(origRot);\n\t\t\t\trotations.append(origRot);\n\n\t\t\t\t//- set new rotation\n\t\t\t\tdouble rot = origRot + randVal * ROTATIONVALUE;\n\t\t\t\trotxPlug.setValue(rot);\n\t\t\t\tbreak;\n\t\t\t}\n\t\tcase AXIS_Y:\n\t\tdefault: //- by default, rotate around y axis\n\t\t\t{\n\t\t\t\tMPlug rotyPlug = rotPlug.child(1);\n\n\t\t\t\tdouble origRot = 0;\n\t\t\t\trotyPlug.getValue(origRot);\n\t\t\t\trotations.append(origRot);\n\n\t\t\t\tdouble rot = origRot + randVal * ROTATIONVALUE;\n\t\t\t\trotyPlug.setValue(rot);\n\t\t\t\tbreak;\n\t\t\t}\n\t\tcase AXIS_Z:\n\t\t\t{\n\t\t\t\tMPlug rotzPlug = rotPlug.child(2);\n\n\t\t\t\tdouble origRot = 0;\n\t\t\t\trotzPlug.getValue(origRot);\n\t\t\t\trotations.append(origRot);\n\n\t\t\t\tdouble rot = origRot + randVal * ROTATIONVALUE;\n\t\t\t\trotzPlug.setValue(rot);\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n\n}\n"
  },
  {
    "path": "02_Commands/instanceRotate/Solution - C++/instanceRotateCmd.h",
    "content": "//\n// Copyright (C) \n// \n// File: instanceRotateCmd.h\n//\n// MEL Command: instanceRotate\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#pragma once\n\n#include <maya/MPxCommand.h>\n#include <maya/MDagPath.h>\n#include <maya/MDoubleArray.h>\n\n//- Forward declaration\nclass MArgList;\n\n//- A convenience enum to keep track of which axis the user wanted to rotate around\ntypedef enum AXIS {AXIS_X = 1, AXIS_Y = 2, AXIS_Z = 3};\n\n//- This are the long and short command names.\n#define ROTATEFLAG \"-r\"\n#define ROTATELONGFLAG \"-rotate\"\n\n#define ROTATIONVALUE 0.785398163\n\n// Command class declaration\nclass instanceRotate : public MPxCommand\n{\n\npublic:\n\tinstanceRotate() {}\n\tvirtual ~instanceRotate() {}\n\n\t//- This method should perform a command by setting up internal class data\n\t//- and then calling the redoIt method if undo is supported by the command.\n\t//- The actual action performed by the command should be done in the redoIt \n\t//- method. This is a pure virtual method, and must be overridden in derived \n\t//- classes.\n\tvirtual MStatus doIt( const MArgList& );\n\t//- This method should do the actual work of the command based on the internal \n\t//- class data only. Internal class data should be set in the doIt method.\n\tvirtual MStatus redoIt();\n\t//- This method should undo the work done by the redoIt method based on the \n\t//- internal class data only.\n\tvirtual MStatus undoIt();\n\t//- This method is used to specify whether or not the command is undoable. In \n\t//- the base class, it always returns false. If you are writing a command that \n\t//- might be eligible for undo, you should override this method.\n\t//- After Maya executes the command's doIt method, it will call isUndoable. If \n\t//- isUndoable returns true, Maya will retain the instance of the class and pass \n\t//- it to Maya's undo manager so that the undoIt and redoIt methods can be called\n\t//- when appropriate. If isUndoable returns false, the command instance will be \n\t//- immediately destroyed.\n\tvirtual bool isUndoable() const {\n\t\treturn true;\n\t}\n\n\tstatic void* creator() {\n\t\treturn new instanceRotate();\n\t}\n\n\tvirtual\tbool hasSyntax() {\n\t\treturn true;\n\t}\n\tstatic MSyntax cmdSyntax();\n\n\t//- Rotates each instance with 45 degrees along user-specified axis\n\tvoid rotate( MDagPath dp );\n\n\t//- Store the user selection of the rotation axis (one axis for all of the instances)\n\tAXIS axis;\n\n\t//- Store the base shape for the instances here for undo\n\tMDagPath shapeObj;\n\n\t//- Store the number of instances for one shape\n\tuint numInstances;\n\n\t//- Store the original rotation values for undo here\n\tMDoubleArray rotations;\n};\n"
  },
  {
    "path": "02_Commands/instanceRotate/Solution - C++/pluginMain.cpp",
    "content": "//\n// Copyright (C) \n// \n// File: pluginMain.cpp\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#include \"instanceRotateCmd.h\"\n#include <maya/MFnPlugin.h>\n\nMStatus initializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is loaded into Maya.  It \n//\t\tregisters all of the services that this plug-in provides with \n//\t\tMaya.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{ \n\tMStatus   status;\n\tMFnPlugin plugin( obj, \"\", \"2008\", \"Any\");\n\n\t// Add plug-in feature registration here\n\t//\n\tstatus = plugin.registerCommand( \"instanceRotate\", instanceRotate::creator,instanceRotate::cmdSyntax );\n\n\tif (!status) {\n\t\tstatus.perror(\"registerCommand\");\n\t\treturn status;\n\t}\n\n\treturn status;\n}\n\nMStatus uninitializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is unloaded from Maya. It \n//\t\tderegisters all of the services that it was providing.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{\n\tMStatus   status;\n\tMFnPlugin plugin( obj );\n\n\t// Add plug-in feature deregistration here\n\t//\n\tstatus = plugin.deregisterCommand( \"instanceRotate\" );\n\n\tif (!status) {\n\t\tstatus.perror(\"deregisterCommand\");\n\t\treturn status;\n\t}\n\n\treturn status;\n}\n"
  },
  {
    "path": "02_Commands/instanceRotate/Solution - py/instanceRotateCmd.py",
    "content": "#\n# Copyright (C) \n# \n# File: instanceRotateCmd.py\n#\n# MEL Command: instanceRotate\n#\n# Author: Maya Plug-in Wizard 2.0\n#\nimport sys, random\nimport maya.OpenMaya as OpenMaya\nimport maya.OpenMayaMPx as OpenMayaMPx\n\n# Command name\nkPluginCmdName = \"instanceRotate\"\n\n# Command switch short and long names\nROTATEFLAG = \"-r\"\nROTATELONGFLAG = \"-rotate\"\n\nROTATIONVALUE = 0.785398163\nAXIS_X = 1\nAXIS_Y = 2\nAXIS_Z = 3\n\n# instanceRotate command\nclass instanceRotate(OpenMayaMPx.MPxCommand):\n\t#- Store the base shape for the instances here for undo\n\tshapeObj = OpenMaya.MDagPath()\n\t#- Store the original rotation values for undo here\n\trotations = OpenMaya.MDoubleArray()\n\n\tdef __init__(self):\n\t\tOpenMayaMPx.MPxCommand.__init__(self)\n\t\t#- Store the user selection of the rotation axis (one axis for all of the instances)\n\t\tself.axis = AXIS_X\n\t\t#- Store the number of instances for one shape\n\t\tself.numInstances = 0\n\n\t#- This method is used to specify whether or not the command is undoable. In \n\t#- the base class, it always returns false. If you are writing a command that \n\t#- might be eligible for undo, you should override this method.\n\t#- After Maya executes the command's doIt method, it will call isUndoable. If \n\t#- isUndoable returns true, Maya will retain the instance of the class and pass \n\t#- it to Maya's undo manager so that the undoIt and redoIt methods can be called\n\t#- when appropriate. If isUndoable returns false, the command instance will be \n\t#- immediately destroyed.\n\t#def isUndoable(self):\n\t#\treturn True\n\n\t#def hasSyntax(self):\n\t#\treturn True\n\n\t#- This method should perform a command by setting up internal class data\n\t#- and then calling the redoIt method if undo is supported by the command.\n\t#- The actual action performed by the command should be done in the redoIt \n\t#- method. This is a pure virtual method, and must be overridden in derived \n\t#- classes.\n\tdef doIt(self, args):\n\t\t#- Since all the command actions will be done in the redoIt() method, this\n\t\t#- method will only parse the arguments. redoIt() will not use arguments\n\t\t#- at all.\n\t\targParser = OpenMaya.MArgParser (self.syntax(),args)\n\n\t\tnumFlags = argParser.numberOfFlagsUsed()\n\t\tif(numFlags != 1):\n\t\t\tOpenMaya.MGlobal.displayError(\"Simple Plugs requires one flag argument and a DAG object must be selected\")\n\t\t\treturn None\n\t\telse:\n\t\t\tif(argParser.isFlagSet(ROTATEFLAG) | argParser.isFlagSet(ROTATELONGFLAG)):\n\t\t\t\t#- The user enters 1, 2, or 3 to indicate x, y, or z rotation axis\n\t\t\t\tflag =argParser.flagArgumentInt(ROTATEFLAG,0)\n\n\t\t\t\tif(flag == AXIS_X):\n\t\t\t\t\tself.axis = AXIS_X\n\t\t\t\telif(flag == AXIS_Y):\n\t\t\t\t\tself.axis = AXIS_Y\n\t\t\t\telif(flag == AXIS_Z):\n\t\t\t\t\tself.axis = AXIS_Z\n\t\t\t\telse:\n\t\t\t\t\tOpenMaya.MGlobal.displayError(\"Invalid axis rotation argument\")\n\t\t\t\t\treturn None\n\n\t\treturn self.redoIt(args)\n\n\t#- This method should do the actual work of the command based on the internal \n\t#- class data only. Internal class data should be set in the doIt method.\n\tdef redoIt(self, args):\n\t\tOpenMayaMPx.MPxCommand.setResult( \"instanceRotate command executed!\\n\" )\n\n\t\t#- This is really where is the intelligence of the command. Here we will\n\t\t#- preform all the actions we wanted to implement for this command.\n\n\t\t#- Get the active selection in the Maya viewport.\n\t\tselList = OpenMaya.MSelectionList()\n\t\tOpenMaya.MGlobal.getActiveSelectionList(selList)\n\n\t\tif(selList.isEmpty()):\n\t\t\tOpenMaya.MGlobal.displayError(\"A single DAG object must be selected\")\n\t\t\treturn None\n\n\t\tdagPath = OpenMaya.MDagPath()\n\t\tselList.getDagPath(0,dagPath)\n\n\t\t#- Chances are the user selected the object from the panel view or\n\t\t#- outliner window so the object in the list will actually be a \n\t\t#- transform node... if so we call extendToShape to grab the actual\n\t\t#- shape node from the dagPath\n\t\tif(dagPath.hasFn(OpenMaya.MSpace.kTransform)):\n\t\t\tdagPath.extendToShape()\n\n\t\tif(dagPath.isInstanced()):\n\t\t\tself.shapeObj = dagPath\n\t\t\tself.rotate(dagPath)\n\t\telse:\n\t\t\tOpenMaya.MGlobal.displayError(\"The selected item is not an instanced DAG object\")\n\t\t\treturn None\n\n\t\t\n\n\t#- This method should undo the work done by the redoIt method based on the \n\t#- internal class data only.\n\tdef undoIt(self, args):\n\t\tOpenMaya.MGlobal.displayInfo( \"instanceRotate command undone!\\n\" )\n\t\t\n\t\tfnDag = MFnDagNode(self.shapeObj)\n\n\t\tfor i in range ( 0, self.numInstances ):\n\t\t\tcurrentParent = fnDag.parent(i)\n\t\t\tfnParent = OpenMaya.MFnDependencyNode(currentParent)\n\t\t\trotPlug = fnParent.findPlug(\"rotate\")\n\t\t\tif (self.axis == AXIS_X):\n\t\t\t\trotxPlug = rotPlug.child(0)\n\t\t\t\trotxPlug.setDouble(self.rotations[i])\n\t\t\telif (self.axis == AXIS_Z):\n\t\t\t\trotzPlug = rotPlug.child(2)\n\t\t\t\trotzPlug.setDouble(self.rotations[i])\n\t\t\telse: # AXIS_Y:\n\t\t\t\trotyPlug = rotPlug.child(1)\n\t\t\t\trotyPlug.setDouble(self.rotations[i])\n\n\t\t#- Empty the array in case the user chooses redoIt\n\t\tself.rotations.clear()\n\n\t\t\n\n\t#- Method used by redoIt to assign a 45 degree rotation along a random axis.\n\tdef rotate( self, dp ):\n\t\t#- The passed-in dag object is a shape object, \n\t\t#- need to find all the parent transform objects.\n\t\tfnDag = OpenMaya.MFnDagNode(dp)\n\t\t#- The number of parents represents the current number of instances.\n\t\tself.numInstances = fnDag.parentCount()\n\n\t\tfor i in range ( 0, self.numInstances ):\n\t\t\tcurrentParent = fnDag.parent(i)\n\t\t\tfnParent = OpenMaya.MFnDependencyNode(currentParent)\t\n\n\t\t\t#- Find the rotate plug, figure out which axis the user opted for \n\t\t\t#- and set the plug to a random direction.\n\t\t\trotPlug = fnParent.findPlug(\"rotate\")\n\n\t\t\t#- Acquire a random number deciding which direction the 45 degree should be\n\t\t\trandVal = random.randint(0, 1000)\n\t\t\tif(randVal % 2 == 0):\n\t\t\t\trandVal = 1\n\t\t\telse:\n\t\t\t\trandVal = -1\n\t\t\tprint \"The randVal is %d \" % randVal\n\t\t\tsys.stdout.write( '\\n' )\n\n\t\t\tif (self.axis == AXIS_X):\n\t\t\t\trotxPlug = rotPlug.child(0)\n\n\t\t\t\t#- retrieve original rotation and store it in member variable \"rotations\"\n\t\t\t\torigRot = rotxPlug.asDouble()\n\t\t\t\tself.rotations.append(origRot)\n\n\t\t\t\t#- set new rotation\n\t\t\t\trot = origRot + randVal * ROTATIONVALUE\n\t\t\t\trotxPlug.setDouble(rot)\n\t\t\telif (self.axis == AXIS_Z):\n\t\t\t\trotzPlug = rotPlug.child(2)\n\n\t\t\t\torigRot = rotzPlug.asDouble()\n\t\t\t\tself.rotations.append(origRot)\n\n\t\t\t\trot = origRot + randVal * ROTATIONVALUE\n\t\t\t\trotzPlug.setDouble(rot)\n\t\t\telse: # AXIS_Y: - by default, rotate around y axis\n\t\t\t\trotyPlug = rotPlug.child(1)\n\n\t\t\t\torigRot = rotyPlug.asDouble()\n\t\t\t\tself.rotations.append(origRot)\n\n\t\t\t\trot = origRot + randVal * ROTATIONVALUE\n\t\t\t\trotyPlug.setDouble(rot)\n\n# Creator\ndef cmdCreator():\n\treturn OpenMayaMPx.asMPxPtr( instanceRotate() )\n\n#- Create a new MSyntax object to teach Maya about possible arguments\n#- in our command. This newSyntax() method is used during the command\n#- registration into our plug-in\n# Syntax creator\ndef syntaxCreator():\n\tsyntax = OpenMaya.MSyntax()\n\tsyntax.addFlag(ROTATEFLAG, ROTATELONGFLAG, OpenMaya.MSyntax.kUnsigned)\n\tsyntax.enableEdit(0)\n\tsyntax.enableQuery(0)\n\treturn syntax\n\n# Initialize the script plug-in\ndef initializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\tmplugin.registerCommand( kPluginCmdName, cmdCreator, syntaxCreator )\n\texcept:\n\t\tsys.stderr.write( \"Failed to register command: %s\\n\" % kPluginCmdName )\n\n# Uninitialize the script plug-in\ndef uninitializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\tmplugin.deregisterCommand( kPluginCmdName )\n\texcept:\n\t\tsys.stderr.write( \"Failed to unregister command: %s\\n\" % kPluginCmdName )\n\n"
  },
  {
    "path": "02_Commands/nodeInfo/Exercise - C++/nodeInfoCmd.cpp",
    "content": "// \n// File: \n//\n// Dependency Graph Node: \n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#include <maya/MIOStream.h>\n#include <maya/MString.h>\n#include <maya/MStringResource.h>\n#include <maya/MStringResourceId.h>\n#include <maya/MArgList.h>\n\n#include <maya/MPxCommand.h>\n#include <maya/MSyntax.h>\n#include <maya/MArgDatabase.h>\n\n#include <maya/MGlobal.h>\n#include <maya/MDagPath.h>\n#include <maya/MItSelectionList.h>\n#include <maya/MSelectionList.h>\n\n#include <maya/MFnDependencyNode.h>\n#include <maya/MPlugArray.h>\n#include <maya/MPlug.h>\n\n#include \"nodeInfoCmd.h\"\n\n// Command class implementation\nnodeInfo::nodeInfo() : quiet (false)\n{}\n\nnodeInfo::~nodeInfo()\n{}\n\n//- Create a new MSyntax object to teach Maya about possible arguments\n//- in our command. This newSyntax() method is used during the command\n//- registration into our plug-in\n/*stattic*/ MSyntax nodeInfo::newSyntax()\n{\n\t MSyntax syntax;\n\t \n\t //- TODO: add flags onto the new created MSyntax object\n\t //....\n\n\t return syntax;\n}\n\n//- This is a method which will be used by our command doIt() method to\n//- check arguments passed into our command call.\nMStatus nodeInfo::parseArgs( const MArgList& args )\n{\n\tMStatus\t\t\tstat;\n\tMArgDatabase\targData(syntax(), args);\n\n\t//- TODO: use MArgDataBase::isFlagSet to parse if the flag has been set by user\n\t//- and assign the corresponding boolean value to variable \"quiet\" based on the flag\n\t//...\n\n\treturn stat;\n}\n\n//- This method performs the action of the command. It iterates over all\n//- selected items and prints out connected plug and dependency node type\n//- information.\n//- TODO: Define the method called by Maya to execute your command (the \n//- function argument will be named args for this exercise).\n//...\n{\n\tMStatus stat;\t\t\t// Status code\n\tMObject dependNode;\t\t// Selected dependency node\n\n\tstat = parseArgs ( args );\n\tif ( !stat )\n\t\treturn stat;\n\n\tMSelectionList slist;\n\t//- TODO: Retrieve all objects currently selected into the Maya editor and put it onto \"slist\"\n\t//...\n\n\n\t//- Create an iterator on the selection list (using the iterator pattern).\n\tMItSelectionList iter( slist, MFn::kInvalid,&stat );\n\n\t//- Iterate over all selected dependency nodes\n\tfor ( ; !iter.isDone(); iter.next() ) \n\t{\n\t\t//- TODO: From the iterator,get corresponding dependency node \n\t\t//- by using MItSelectionList::getDependNode()\n\t\t//...\n\n\t\t//- TODO: Create a function set for the dependency node (name it fnDependNode)\n\t\t//...\n\n\t\t//- Check the type of the dependency node\n\t\tMString nodeName = fnDependNode.name();\n\t\tcout << \"////////////////////////////////////////////\" << endl;\n\t\tcout << nodeName << \" is of type \" << dependNode.apiTypeStr() << endl;\n\n\t\tMPlugArray connectedPlugs;\n\t\t//- TODO: Get all connected plugs to this node by using MFnDependencyNode::getConnections()\n\t\t//- add assign them to \"connectedPlugs\"\n\t\t//...\n\n\t\tint numberOfPlugs = connectedPlugs.length();\n\t\tif ( !quiet )\n\t\t{\n\t\t\tcout << \"Number of connections found: \" << numberOfPlugs << endl;\n\t\t}\n\n\t\t//- Print out the dependency node name and attributes\n\t\t//- for each plug\n\t\tfor ( int i=0; i<numberOfPlugs; i++ ) \n\t\t{\n\t\t\tMPlug plug = connectedPlugs[i];\n\t\t\tMString pinfo = plug.info();\n\t\t\tif ( !quiet )\n\t\t\t{\n\t\t\t\tcout << \" Connected Plug Info: \" << pinfo << endl;\n\t\t\t}\n\n\t\t\t//- Now get the plugs that this plug is the\n\t\t\t//- destination of and print the node type.\n\t\t\tMPlugArray array;\n\t\t\t//- TODO: Get the list of plugs this current plug is connected to.\n\t\t\t//...\n\n\t\t\tfor ( unsigned int j=0; j<array.length(); j++ )\n\t\t\t{\n\t\t\t\tMObject mnode = array[j].node();\n\t\t\t\tif( !quiet )\n\t\t\t\t{\n\t\t\t\t\tMFnDependencyNode fnConnectedNode(mnode);\n\t\t\t\t\tcout << \" This plug is a destination of node:\" << fnConnectedNode.name() << endl;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\n\t//- Return success to Maya\n\treturn MS::kSuccess;\n}\n\n\n"
  },
  {
    "path": "02_Commands/nodeInfo/Exercise - C++/nodeInfoCmd.h",
    "content": "//\n// Copyright (C) \n// \n// File: \n//\n// Dependency Graph Node: \n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#pragma once\n\n#include <maya/MPxCommand.h>\n\n//- This are the long and shor command names.\n#define kQuietFlag\t\t\"-q\"\n#define kQuietFlagLong\t\"-quiet\"\n\n// Command class declaration\nclass nodeInfo : public MPxCommand\n{\npublic:\n\tnodeInfo();\n\tvirtual ~nodeInfo(); \n\n\t//- TODO: Declare the method called by Maya to execute your command.\n\t//...\n\n\t//- Create a new MSyntax object to teach Maya about possible arguments\n\t//- in our command. This newSyntax() method is used during the command\n\t//- registration into our plug-in\n\tstatic MSyntax newSyntax();\n\n\tstatic void* creator() {\n\t\treturn new nodeInfo ();\n\t}\n\nprivate:\n\tMStatus\t\t\tparseArgs( const MArgList& args );\n\tbool\t\t\tquiet;\n};\n"
  },
  {
    "path": "02_Commands/nodeInfo/Exercise - C++/nodeInfoCmd.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 2012\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"nodeInfoCmd\", \"nodeInfoCmd.vcxproj\", \"{B86ED337-5087-4A1B-B9F4-3B634AE09BC4}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|x64 = Debug|x64\n\t\tRelease|x64 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{B86ED337-5087-4A1B-B9F4-3B634AE09BC4}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{B86ED337-5087-4A1B-B9F4-3B634AE09BC4}.Debug|x64.Build.0 = Debug|x64\n\t\t{B86ED337-5087-4A1B-B9F4-3B634AE09BC4}.Release|x64.ActiveCfg = Release|x64\n\t\t{B86ED337-5087-4A1B-B9F4-3B634AE09BC4}.Release|x64.Build.0 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "02_Commands/nodeInfo/Exercise - C++/nodeInfoCmd.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{B86ED337-5087-4A1B-B9F4-3B634AE09BC4}</ProjectGuid>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup>\n    <_ProjectFileVersion>11.0.61030.0</_ProjectFileVersion>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <OutDir>Debug\\</OutDir>\n    <IntDir>Debug\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <OutDir>C:\\MayaAPITraining\\plug-ins\\</OutDir>\n    <TargetExt>.mll</TargetExt>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <OutDir>Release\\</OutDir>\n    <IntDir>Release\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2009\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>C:\\MayaAPITraining\\plug-ins\\nodeInfoCmd.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2009\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2015\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>C:\\MayaAPITraining\\plug-ins\\nodeInfoCmd.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2015\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"nodeInfoCmd.cpp\" />\n    <ClCompile Include=\"pluginMain.cpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"nodeInfoCmd.h\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "02_Commands/nodeInfo/Exercise - C++/pluginMain.cpp",
    "content": "// \n// File: \n//\n// Dependency Graph Node: \n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#include \"nodeInfoCmd.h\"\n#include <maya/MFnPlugin.h>\n\nMStatus initializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is loaded into Maya.  It \n//\t\tregisters all of the services that this plug-in provides with \n//\t\tMaya.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{\n\tMStatus   status;\n\tMFnPlugin plugin( obj, PLUGIN_COMPANY, \"2009\", \"Any\");\n\n\t// Add plug-in feature registration here\n\t\n\t//- TODO: Register your command into Maya, and make sure you define a syntax\n\t//...\n\n\tif (!status) {\n\t\tstatus.perror(\"registerCommand\");\n\t\treturn status;\n\t}\n\n\treturn status;\n}\n\nMStatus uninitializePlugin( MObject obj)\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is unloaded from Maya. It \n//\t\tderegisters all of the services that it was providing.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{\n\tMStatus\t  status;\n\tMFnPlugin plugin( obj );\n\n\t// Add plug-in feature deregistration here\n\t\n\t//- TODO: unregister your command from Maya before you unload.\n\t//...\n\n\tif (!status) {\n\t\tstatus.perror(\"deregisterCommand\");\n\t\treturn status;\n\t}\n\n\treturn status;\n}\n"
  },
  {
    "path": "02_Commands/nodeInfo/Exercise - py/nodeInfoCmd.py",
    "content": "# Copyright (C) \n# \n# Author: Autodesk Developer Network\n\n#For this exercise, search for the TODO keywords and follow the instructions in\n#comments. If you are unsure of what you need to do, feel free to ask the instructor\n#or look into the solution folder.\n#Each #... line is a line of code you need to write or complete.\n\nimport sys\nimport maya.OpenMaya as OpenMaya\nimport maya.OpenMayaMPx as OpenMayaMPx\n\n# Command name\nkPluginCmdName = \"nodeInfoCmd\"\n\n# Command switch short and long names\nkQuietFlag = \"-q\"\nkQuietFlagLong = \"-quiet\"\n\n# nodeInfoCmd command\nclass nodeInfoCmd(OpenMayaMPx.MPxCommand):\n\t\n\tdef __init__(self):\n\t\tOpenMayaMPx.MPxCommand.__init__(self)\n\t\tself.quiet = 0\n\t\n\t#- This is a method which will be used by our command doIt() method to\n\t#- check arguments passed into our command call.\n\tdef parseArgs ( self, args ):\n\t\targData = OpenMaya.MArgDatabase( self.syntax(), args)\n\t\tif (argData.isFlagSet(kQuietFlag)):\n\t\t\tself.quiet = 1\n\t\n\t#- This method performs the action of the command. It iterates over all\n\t#- selected items and prints out connected plug and dependency node type\n\t#- information.\n\t#- TODO: Define the method called by Maya to execute your command (the \n\t#- function argument will be named args for this exercise).\n\tdef #...\n\t\tself.parseArgs ( args )\n\n\t\t#- TODO: Select all objects currently selected into the Maya editor.\n\t\tslist = OpenMaya.MSelectionList()\n\t\t#...\n\t\t\n\t\t#- Create an iterator on the selection list (using the iterator pattern).\n\t\titer = OpenMaya.MItSelectionList(slist)\n\t\n\t\t#- Iterate over all selected dependency nodes\n\t\tdependNode = OpenMaya.MObject()\n\t\tfnDependNode = OpenMaya.MFnDependencyNode()\n\t\twhile (iter.isDone() == 0):\n\t\t\t#- TODO: Get the selected dependency node\n\t\t\t#...\n\n\t\t\t#- TODO: Create a function set for the dependency node\n\t\t\t#...\n\t\t\tif  not self.quiet:\n\t\t\t\t#- Check the type of the dependency node\n\t\t\t\tnodeName = fnDependNode.name()\n\t\t\t\tprint \"######################\"\n\t\t\t\tsys.stdout.write( '\\n' )\n\t\t\t\tprint nodeName \n\t\t\t\tprint \" is of type %s\" % dependNode.apiTypeStr()\n\t\t\t\tsys.stdout.write( '\\n' )\n\n\t\t\t#- TODO: Get all connected plugs to this node\n\t\t\ttry:\n\t\t\t\tconnectedPlugs = OpenMaya.MPlugArray()\n\t\t\t\ttry:\n\t\t\t\t\t#...\n\t\t\t\texcept:\t\t\t\t\t\n\t\t\t\t\tpass\n\n\t\t\t\tnumberOfPlugs = connectedPlugs.length()\n\t\t\t\tif  not self.quiet:\n\t\t\t\t\tprint \"Number of connections found: %d \" % numberOfPlugs\n\t\t\t\t\tsys.stdout.write( '\\n' )\n\n\t\t\t\t#- Print out the dependency node name and attributes\n\t\t\t\t#- for each plug\n\t\t\t\tfor i in range( 0, numberOfPlugs ): \n\t\t\t\t\tplug = connectedPlugs[i]\n\t\t\t\t\tpinfo = plug.info()\n\t\t\t\t\tif  not self.quiet:\n\t\t\t\t\t\tprint \" Connected Plug Info: %s\" % pinfo\n\t\t\t\t\t\tsys.stdout.write( '\\n' )\n\n\t\t\t\t\t#- Now get the plugs that this plug is the\n\t\t\t\t\t#- destination of and print the node type.\n\t\t\t\t\tarray = OpenMaya.MPlugArray()\n\t\t\t\t\t#- TODO: Get the list of plugs, this plug is connected to.\n\t\t\t\t\t#...\n\t\t\t\t\tfor j in range( 0, array.length() ): \n\t\t\t\t\t\tmnode = array[j].node()\n\t\t\t\t\t\tif  not self.quiet:\n\t\t\t\t\t\t\tfnConnectedNode = OpenMaya.MFnDependencyNode(mnode)\n\t\t\t\t\t\t\tprint \" This plug is a destination of node: %s\" % fnConnectedNode.name()\n\t\t\t\t\t\t\tsys.stdout.write( '\\n' )\n\t\t\texcept:\n\t\t\t\tsys.stderr.write( \"Failed to get connections: %s\" % kPluginCmdName)\n\t\t\t\t#raise\n\n\t\t\titer.next()\n\n\t\n# Creator\ndef cmdCreator():\n\treturn OpenMayaMPx.asMPxPtr( nodeInfoCmd() )\n\n#- Create a new MSyntax object to teach Maya about possible arguments\n#- in our command. This newSyntax() method is used during the command\n#- registration into our plug-in\n# Syntax creator\ndef syntaxCreator():\n\tsyntax = OpenMaya.MSyntax()\n\tsyntax.addFlag(kQuietFlag, kQuietFlagLong)\n\treturn syntax\n\n# Initialize the script plug-in\ndef initializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\t#- TODO: Register your command into Maya, and make sure you define a syntax\n\t\t#...\n\texcept:\n\t\tsys.stderr.write( \"Failed to register command: %s\\n\" % kPluginCmdName )\n\n# Uninitialize the script plug-in\ndef uninitializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\t#- TODO: unregister your command from Maya before you unload.\n\t\t#...\n\texcept:\n\t\tsys.stderr.write( \"Failed to unregister command: %s\\n\" % kPluginCmdName )\n\n"
  },
  {
    "path": "02_Commands/nodeInfo/Solution - C++/nodeInfoCmd.cpp",
    "content": "// \n// File: \n//\n// Dependency Graph Node: \n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#include <maya/MIOStream.h>\n#include <maya/MString.h>\n#include <maya/MStringResource.h>\n#include <maya/MStringResourceId.h>\n#include <maya/MArgList.h>\n\n#include <maya/MPxCommand.h>\n#include <maya/MSyntax.h>\n#include <maya/MArgDatabase.h>\n\n#include <maya/MGlobal.h>\n#include <maya/MDagPath.h>\n#include <maya/MItSelectionList.h>\n#include <maya/MSelectionList.h>\n\n#include <maya/MFnDependencyNode.h>\n#include <maya/MPlugArray.h>\n#include <maya/MPlug.h>\n\n#include \"nodeInfoCmd.h\"\n\n// Command class implementation\nnodeInfo::nodeInfo() : quiet (false)\n{}\n\nnodeInfo::~nodeInfo()\n{}\n\n//- Create a new MSyntax object to teach Maya about possible arguments\n//- in our command. This newSyntax() method is used during the command\n//- registration into our plug-in\n/*static*/ MSyntax nodeInfo::newSyntax()\n{\n\t MSyntax syntax;\n\t syntax.addFlag(kQuietFlag, kQuietFlagLong);\n\t return syntax;\n}\n\n//- This is a method which will be used by our command doIt() method to\n//- check arguments passed into our command call.\nMStatus nodeInfo::parseArgs( const MArgList& args )\n{\n\tMStatus\t\t\tstat;\n\tMArgDatabase\targData(syntax(), args);\n\n\tif (argData.isFlagSet(kQuietFlag))\n\t\tquiet = true;\n\n\treturn stat;\n}\n\n//- This method performs the action of the command. It iterates over all\n//- selected items and prints out connected plug and dependency node type\n//- information.\nMStatus nodeInfo::doIt( const MArgList& args )\n{\n\tMStatus stat;\t\t\t// Status code\n\tMObject dependNode;\t\t// Selected dependency node\n\n\tstat = parseArgs ( args );\n\tif ( !stat )\n\t\treturn stat;\n\n\t//- Retrieve all objects currently selected into the Maya editor.\n\tMSelectionList slist;\n\tMGlobal::getActiveSelectionList( slist );\n\t//- Create an iterator on the selection list (using the iterator pattern).\n\tMItSelectionList iter( slist, MFn::kInvalid,&stat );\n\n\t//- Iterate over all selected dependency nodes\n\tfor ( ; !iter.isDone(); iter.next() ) \n\t{\n\t\t//- Get the selected dependency node\n\t\titer.getDependNode( dependNode );\n\n\t\t//- Create a function set for the dependency node\n\t\tMFnDependencyNode fnDependNode( dependNode );\n\n\t\t//- Check the type of the dependency node\n\t\tMString nodeName = fnDependNode.name();\n\t\tcout << \"////////////////////////////////////////////\" << endl;\n\t\tcout << nodeName << \" is of type \" << dependNode.apiTypeStr() << endl;\n\n\t\t//- Get all connected plugs to this node\n\t\tMPlugArray connectedPlugs;\n\t\tfnDependNode.getConnections( connectedPlugs );\n\n\t\tint numberOfPlugs = connectedPlugs.length();\n\t\tif ( !quiet )\n\t\t{\n\t\t\tcout << \"Number of connections found: \" << numberOfPlugs << endl;\n\t\t}\n\n\t\t//- Print out the dependency node name and attributes\n\t\t//- for each plug\n\t\tfor ( int i=0; i<numberOfPlugs; i++ ) \n\t\t{\n\t\t\tMPlug plug = connectedPlugs[i];\n\t\t\tMString pinfo = plug.info();\n\t\t\tif ( !quiet )\n\t\t\t{\n\t\t\t\tcout << \" Connected Plug Info: \" << pinfo << endl;\n\t\t\t}\n\n\t\t\t//- Now get the plugs that this plug is the\n\t\t\t//- destination of and print the node type.\n\t\t\tMPlugArray sourceArray;\n\t\t\tplug.connectedTo( sourceArray, true, false );\n\t\t\tfor ( unsigned int j=0; j<sourceArray.length(); j++ )\n\t\t\t{\n\t\t\t\tMObject mnode = sourceArray[j].node();\n\t\t\t\tif( !quiet )\n\t\t\t\t{\n\t\t\t\t\tMFnDependencyNode fnConnectedNode(mnode);\n\t\t\t\t\tcout << \" This plug is a destination of node:\" << fnConnectedNode.name() << endl;\n\t\t\t\t}\n\t\t\t}\n\n\t\t}\n\t}\n\n\t//- Return success to Maya\n\treturn MS::kSuccess;\n}\n\n\n"
  },
  {
    "path": "02_Commands/nodeInfo/Solution - C++/nodeInfoCmd.h",
    "content": "//\n// Copyright (C) \n// \n// File: \n//\n// Dependency Graph Node: \n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#pragma once\n\n#include <maya/MPxCommand.h>\n\n//- This are the long and short command names.\n#define kQuietFlag\t\t\"-q\"\n#define kQuietFlagLong\t\"-quiet\"\n\n// Command class declaration\nclass nodeInfo : public MPxCommand\n{\npublic:\n\tnodeInfo();\n\tvirtual ~nodeInfo(); \n\n\t//- This method should perform a command by setting up internal class data\n\t//- and then calling the redoIt method if undo is supported by the command.\n\t//- The actual action performed by the command should be done in the redoIt \n\t//- method. This is a pure virtual method, and must be overridden in derived \n\t//- classes.\n\tvirtual MStatus doIt( const MArgList& args );\n\n\t//- Create a new MSyntax object to teach Maya about possible arguments\n\t//- in our command. This newSyntax() method is used during the command\n\t//- registration into our plug-in\n\tstatic MSyntax\tnewSyntax();\n\n\tstatic void* creator() {\n\t\treturn new nodeInfo ();\n\t}\n\nprivate:\n\tMStatus\t\t\tparseArgs( const MArgList& args );\n\tbool\t\t\tquiet;\n};\n"
  },
  {
    "path": "02_Commands/nodeInfo/Solution - C++/nodeInfoCmd.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 2012\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"nodeInfoCmd\", \"nodeInfoCmd.vcxproj\", \"{B86ED337-5087-4A1B-B9F4-3B634AE09BC4}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|x64 = Debug|x64\n\t\tRelease|x64 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{B86ED337-5087-4A1B-B9F4-3B634AE09BC4}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{B86ED337-5087-4A1B-B9F4-3B634AE09BC4}.Debug|x64.Build.0 = Debug|x64\n\t\t{B86ED337-5087-4A1B-B9F4-3B634AE09BC4}.Release|x64.ActiveCfg = Release|x64\n\t\t{B86ED337-5087-4A1B-B9F4-3B634AE09BC4}.Release|x64.Build.0 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "02_Commands/nodeInfo/Solution - C++/nodeInfoCmd.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{B86ED337-5087-4A1B-B9F4-3B634AE09BC4}</ProjectGuid>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup>\n    <_ProjectFileVersion>11.0.61030.0</_ProjectFileVersion>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <OutDir>Debug\\</OutDir>\n    <IntDir>Debug\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <OutDir>C:\\MayaAPITraining\\plug-ins\\</OutDir>\n    <TargetExt>.mll</TargetExt>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <OutDir>Release\\</OutDir>\n    <IntDir>Release\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2009\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>C:\\MayaAPITraining\\plug-ins\\nodeInfoCmd.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2009\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2015\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>C:\\MayaAPITraining\\plug-ins\\nodeInfoCmd.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2015\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"nodeInfoCmd.cpp\" />\n    <ClCompile Include=\"pluginMain.cpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"nodeInfoCmd.h\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "02_Commands/nodeInfo/Solution - C++/pluginMain.cpp",
    "content": "// \n// File: \n//\n// Dependency Graph Node: \n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#include \"nodeInfoCmd.h\"\n#include <maya/MFnPlugin.h>\n\nMStatus initializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is loaded into Maya.  It \n//\t\tregisters all of the services that this plug-in provides with \n//\t\tMaya.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{\n\tMStatus   status;\n\tMFnPlugin plugin( obj, PLUGIN_COMPANY, \"2009\", \"Any\");\n\n\t// Add plug-in feature registration here\n\t//\n\tstatus = plugin.registerCommand( \"nodeInfo\", nodeInfo::creator, nodeInfo::newSyntax);\n\n\tif (!status) {\n\t\tstatus.perror(\"registerCommand\");\n\t\treturn status;\n\t}\n\n\treturn status;\n}\n\nMStatus uninitializePlugin( MObject obj)\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is unloaded from Maya. It \n//\t\tderegisters all of the services that it was providing.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{\n\tMStatus\t  status;\n\tMFnPlugin plugin( obj );\n\n\t// Add plug-in feature deregistration here\n\t//\n\tplugin.deregisterCommand ( \"nodeInfo\" ) ;\n\tif (!status) {\n\t\tstatus.perror(\"deregisterCommand\");\n\t\treturn status;\n\t}\n\n\treturn status;\n}\n"
  },
  {
    "path": "02_Commands/nodeInfo/Solution - py/nodeInfoCmd.py",
    "content": "# \n# File: \n#\n# Dependency Graph Node: \n#\n# Author: Maya Plug-in Wizard 2.0\n#\nimport sys\nimport maya.OpenMaya as OpenMaya\nimport maya.OpenMayaMPx as OpenMayaMPx\n\n# Command name\nkPluginCmdName = \"nodeInfoCmd\"\n\n# Command switch short and long names\nkQuietFlag = \"-q\"\nkQuietFlagLong = \"-quiet\"\n\n# nodeInfoCmd command\nclass nodeInfoCmd(OpenMayaMPx.MPxCommand):\n\t\n\tdef __init__(self):\n\t\tOpenMayaMPx.MPxCommand.__init__(self)\n\t\tself.quiet = 0\n\t\n\t#- This is a method which will be used by our command doIt() method to\n\t#- check arguments passed into our command call.\n\tdef parseArgs ( self, args ):\n\t\targData = OpenMaya.MArgDatabase( self.syntax(), args)\n\t\tif argData.isFlagSet(kQuietFlag):\n\t\t\tself.quiet = 1\n\n\t#- This method performs the action of the command. It iterates over all\n\t#- selected items and prints out connected plug and dependency node type\n\t#- information.\n\tdef doIt(self, args):\n\t\tself.parseArgs ( args )\n\n\t\t#- Select all objects currently selected into the Maya editor.\n\t\tslist = OpenMaya.MSelectionList()\n\t\tOpenMaya.MGlobal.getActiveSelectionList( slist )\n\t\t\n\t\t\n\t\t#- Create an iterator on the selection list (using the iterator pattern).\n\t\titer = OpenMaya.MItSelectionList(slist)\n\t\n\t\t#- Iterate over all selected dependency nodes\n\t\tdependNode = OpenMaya.MObject()\n\t\tfnDependNode = OpenMaya.MFnDependencyNode()\n\t\twhile (iter.isDone() == 0):\n\t\t\t#- Get the selected dependency node\n\t\t\titer.getDependNode( dependNode )\n\n\t\t\t#- Create a function set for the dependency node\n\t\t\tfnDependNode.setObject( dependNode )\n\n\t\t\tif  not self.quiet:\n\t\t\t\t#- Check the type of the dependency node\n\t\t\t\tnodeName = fnDependNode.name()\n\t\t\t\tprint \"######################\"\n\t\t\t\tsys.stdout.write( '\\n' )\n\t\t\t\tprint nodeName \n\t\t\t\tprint \" is of type %s\" % dependNode.apiTypeStr()\n\t\t\t\tsys.stdout.write( '\\n' )\n\n\t\t\t#- Get all connected plugs to this node\n\t\t\ttry:\n\t\t\t\tconnectedPlugs = OpenMaya.MPlugArray()\n\t\t\t\ttry:\n\t\t\t\t\tfnDependNode.getConnections(connectedPlugs)\n\t\t\t\texcept:\t\t\t\t\t\n\t\t\t\t\tpass\n\t\t\t\t\t\n\t\t\t\tnumberOfPlugs = connectedPlugs.length()\n\t\t\t\t\n\t\t\t\tif  not self.quiet:\n\t\t\t\t\tprint \"Number of connections found: %d \" % numberOfPlugs\n\t\t\t\t\tsys.stdout.write( '\\n' )\n\t\t\t\t\n\t\t\t\t#- Print out the dependency node name and attributes\n\t\t\t\t#- for each plug\n\t\t\t\tfor i in range( 0, numberOfPlugs ): \n\t\t\t\t\tplug = connectedPlugs[i]\n\t\t\t\t\tpinfo = plug.info()\n\t\t\t\t\tif  not self.quiet:\n\t\t\t\t\t\tprint \" Connected Plug Info: %s\" % pinfo\n\t\t\t\t\t\tsys.stdout.write( '\\n' )\n\n\t\t\t\t\t#- Now get the plugs that this plug is the\n\t\t\t\t\t#- destination of and print the node type.\n\t\t\t\t\tarray = OpenMaya.MPlugArray()\n\t\t\t\t\t\n\t\t\t\t\tplug.connectedTo( array, 1, 0 )\n\t\t\t\t\t\n\t\t\t\t\tfor j in range( 0, array.length() ): \n\t\t\t\t\t\tmnode = array[j].node()\n\t\t\t\t\t\tif  not self.quiet:\n\t\t\t\t\t\t\tfnConnectedNode = OpenMaya.MFnDependencyNode(mnode)\n\t\t\t\t\t\t\tprint \" This plug is a destination of node: %s\" % fnConnectedNode.name()\n\t\t\t\t\t\t\tsys.stdout.write( '\\n' )\n\n\t\t\texcept:\n\t\t\t\tsys.stderr.write( \"Failed to get connections: %s\" % kPluginCmdName)\n\t\t\t\t#raise\n\n\t\t\titer.next()\n\n# Creator\ndef cmdCreator():\n\treturn OpenMayaMPx.asMPxPtr( nodeInfoCmd() )\n\n#- Create a new MSyntax object to teach Maya about possible arguments\n#- in our command. This newSyntax() method is used during the command\n#- registration into our plug-in\n# Syntax creator\ndef syntaxCreator():\n\tsyntax = OpenMaya.MSyntax()\n\tsyntax.addFlag(kQuietFlag, kQuietFlagLong)\n\treturn syntax\n\n# Initialize the script plug-in\ndef initializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\tmplugin.registerCommand( kPluginCmdName, cmdCreator, syntaxCreator )\n\texcept:\n\t\tsys.stderr.write( \"Failed to register command: %s\\n\" % kPluginCmdName )\n\n# Uninitialize the script plug-in\ndef uninitializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\tmplugin.deregisterCommand( kPluginCmdName )\n\texcept:\n\t\tsys.stderr.write( \"Failed to unregister command: %s\\n\" % kPluginCmdName )\n\n"
  },
  {
    "path": "03_Nodes/simpleNode/Exercise - C++/pluginMain.cpp",
    "content": "//\n// Copyright (C)  \n// \n// File: pluginMain.cpp\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n\n#include <maya/MFnPlugin.h>\n#include \"simpleNode.h\"\n\nMStatus initializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is loaded into Maya.  It \n//\t\tregisters all of the services that this plug-in provides with \n//\t\tMaya.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{ \n\tMStatus   status;\n\tMFnPlugin plugin( obj, \"\", \"2009\", \"Any\");\n\n\t// Add plug-in feature registration here\n\t//\n\n\t//- TODO: Register your node here, so Maya can use it and recognize it\n\t//- TODO: while reading/saving a file which has instance of this node type.\n\t//...\n\n\tif (!status) {\n\t\tstatus.perror(\"registerNode\");\n\t\treturn status;\n\t}\n\treturn status;\n}\n\nMStatus uninitializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is unloaded from Maya. It \n//\t\tderegisters all of the services that it was providing.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{\n\tMStatus   status;\n\tMFnPlugin plugin( obj );\n\n\t// Add plug-in feature deregistration here\n\t//\n\n\t//- TODO: Unregister your node here, so Maya stops using it.\n\t//...\n\n\tif (!status) {\n\t\tstatus.perror(\"deregisterNode\");\n\t\treturn status;\n\t}\n\n\treturn status;\n}\n"
  },
  {
    "path": "03_Nodes/simpleNode/Exercise - C++/simpleNode.cpp",
    "content": "//\n// Copyright (C) \n// \n// File: simpleNode.cpp\n//\n// Dependency Graph Node: simpleNode\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n\n#include \"simpleNode.h\"\n#include <maya/MGlobal.h>\n\n//- Assigning a unique node ID to your new node class.\n//- Ask ADN or Autodesk product support to reserve IDs for your company. You can\n//- reserve ID by block of 64, 128, 256, or 512 consecutive ID.\n//-\n//- In the solution project, 0x00001 is a temporary ID reserved for development. Never use that ID in a\n//- production environment.\n\n//- TODO: Define here your unique node ID\n//...\n\n//- Instantiate the static attributes of your node class.\n/*static*/ MObject simpleNode::input;        \n/*static*/ MObject simpleNode::output;        \n\t\t \n\n//- The initialize method is called to create and initialize all of the \n//- attributes and attribute dependencies for this node type. This is \n//- only called once when the node type is registered with Maya.\n//- Return Values: MS::kSuccess / MS::kFailure\n//-\nMStatus simpleNode::initialize()\n{\n\t//- Initialize a float input attribute using the MFnNumericAttribute\n\t//- class. Make that attribute definition saved into Maya file (setStorable),\n\t//- and selectable in the channel box (setKeyable).\n\n\t//- Create a generic attribute using MFnNumericAttribute\n\tMFnNumericAttribute nAttr;\n\tsimpleNode::input = nAttr.create( \"input\", \"in\", MFnNumericData::kFloat, 0.0 );\n\t//- Attribute will be written to files when this type of node is stored\n \tnAttr.setStorable(true);\n\t//- Attribute is keyable and will show up in the channel box\n \tnAttr.setKeyable(true);\n\n\t//- TODO: Initialize a float output attribute using the MFnNumericAttribute\n\t//- class. Make that attribute definition not saved into Maya file.\n\t//...\n\t//- TODO: Attribute will not be written to files when this type of node is stored\n\t//...\n\t\n\n\t//- Now add the attribute to your node definition using the addAttribute()\n\t//- method.\n\n\t//- Add the attributes we have created to the node\n\taddAttribute( simpleNode::input );\t\n\t//- TODO: Add the output attribute to the node type definition\n\t//...\n\t\n\t//- Finally tell Maya how the information should flow through your node.\n\t//- This will also tell Maya how the dirty flag is propagated in your node\n\t//- and ultimately in the Maya DG. To do this, use the attributeAffects()\n\t//- method to link your node' attributes together.\n\n\t//- TODO: Set up a dependency between the input and the output. This will cause\n\t//- the output to be marked dirty when the input changes. The output will\n\t//- then be recomputed the next time the value of the output is requested.\n\t//...\n\n\t//- Return success to Maya\n\treturn MS::kSuccess;\n}\n\n//- This method computes the value of the given output plug based\n//- on the values of the input attributes.\n//- Arguments:\n//- \tplug - the plug to compute\n//- \tdata - object that provides access to the attributes for this node\nMStatus simpleNode::compute( const MPlug& plug, MDataBlock& data )\n{\n\t//- Check which output attribute we have been asked to compute. If this \n\t//- node doesn't know how to compute it, you must return MS::kUnknownParameter.\n\n\tif( plug == simpleNode::output )\n\t{\n\t\t//- Get a handle to the input attribute that we will need for the\n\t\t//- computation. If the value is being supplied via a connection \n\t\t//- in the dependency graph, then this call will cause all upstream  \n\t\t//- connections to be evaluated so that the correct value is supplied.\n\t\tMDataHandle inputData = data.inputValue( simpleNode::input );\n\n\t\t//- Read the input value from the handle.\n\t\tfloat result = inputData.asFloat();\n\n\t\t//- Get a handle to the output attribute. Use \"outputValue\", which \n\t\t//- is similar to the \"inputValue\" call above except that no \n\t\t//- dependency graph computation will be done as a result of this call.\n\t\t//- TODO: Get a handle on the output attribute\n\t\t//...\n\n\t\t//- TODO: Set the new output value to the handle (multiply the value by 2 for\n\t\t//- example to see a change [result * 2])\n\t\t//...\n\n\t\t//- Mark the destination plug as being clean. This will prevent the\n\t\t//- dependency graph from repeating this calculation until an input \n\t\t//- attribute of this node which affects this output attribute changes.\n\n\t\t//- TODO: Tell Maya the plug is now clean\n\t\t//...\n\n\t\t//- Return success to Maya\n\t\treturn MS::kSuccess;\n\t}\n\n\t//- Tell Maya that we do not know how to handle this plug, but let give a chance\n\t//- to our parent class to evaluate it.\n\treturn MS::kUnknownParameter;\n}\n"
  },
  {
    "path": "03_Nodes/simpleNode/Exercise - C++/simpleNode.h",
    "content": "//\n// Copyright (C) \n// \n// File: simpleNode.h\n//\n// Dependency Graph Node: simpleNode\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#pragma once\n\n//- Include Maya necessary headers for our class\n#include <maya/MPxNode.h>\n#include <maya/MFnNumericAttribute.h>\n#include <maya/MFnStringData.h>\n#include <maya/MTypeId.h> \n#include <maya/MPlug.h>\n#include <maya/MDataBlock.h>\n#include <maya/MDataHandle.h>\n\n//- Derive a new class from the default Maya node proxy class.\nclass simpleNode : public MPxNode\n{\npublic:\n\tsimpleNode() {\n\t\t//- Never do anything here which would affect Maya.\n\t\t//- Instead implement the virtual postConstructor() method.\n\t}\n\tvirtual ~simpleNode() {}\n\n\t//- Declare the virtual compute() method.\n\tvirtual MStatus\t\tcompute( const MPlug& plug, MDataBlock& data );\n\n\t//- Declare/implement the static creator method.\n\t//- This method exists to give Maya a way to create new objects\n\t//- of this type. \n\tstatic  void*\t\tcreator() {\n\t\treturn new simpleNode();\n\t}\n\n\t//- Declare the static initialize() method.\n\tstatic  MStatus\t\tinitialize();\n\npublic:\n\t// There needs to be a MObject handle declared for each attribute that\n\t// the node will have.  These handles are needed for getting and setting\n\t// the values later.\n\t//\n\tstatic  MObject\t\tinput;\t\t// input attribute\n\t//- TODO: Declare here the output attribute\n\t//- TODO: ...\n\t\n\n\t//- This is a unique node ID for your new node class. It is declared\n\t//- static because it is common to all instance of that class.\n\t//-\n\t//- The typeid is a unique 32bit identifier that describes this node.\n\t//- It is used to save and retrieve nodes of this type from the binary\n\t//- file format. If it is not unique, it will cause file IO problems.\n\n\t//- TODO: Declare here your unique node ID\n\t//...\n};\n"
  },
  {
    "path": "03_Nodes/simpleNode/Exercise - C++/simpleNode.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 2012\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"simpleNode\", \"simpleNode.vcxproj\", \"{439648C5-792B-4918-AC04-5B034F382742}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|x64 = Debug|x64\n\t\tRelease|x64 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{439648C5-792B-4918-AC04-5B034F382742}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{439648C5-792B-4918-AC04-5B034F382742}.Debug|x64.Build.0 = Debug|x64\n\t\t{439648C5-792B-4918-AC04-5B034F382742}.Release|x64.ActiveCfg = Release|x64\n\t\t{439648C5-792B-4918-AC04-5B034F382742}.Release|x64.Build.0 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "03_Nodes/simpleNode/Exercise - C++/simpleNode.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{439648C5-792B-4918-AC04-5B034F382742}</ProjectGuid>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup>\n    <_ProjectFileVersion>11.0.61030.0</_ProjectFileVersion>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <OutDir>Debug\\</OutDir>\n    <IntDir>Debug\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <OutDir>C:\\MayaAPITraining\\plug-ins\\</OutDir>\n    <TargetExt>.mll</TargetExt>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <OutDir>Release\\</OutDir>\n    <IntDir>Release\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2009\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/simpleNode.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>..\\..\\..\\plug-ins\\simpleNode.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2009\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/simpleNode.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/simpleNode.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2015\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/simpleNode.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>C:\\MayaAPITraining\\plug-ins\\simpleNode.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2015\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/simpleNode.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/simpleNode.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/simpleNode.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\simpleNode.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/simpleNode.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/simpleNode.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/simpleNode.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\simpleNode.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/simpleNode.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/simpleNode.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"pluginMain.cpp\" />\n    <ClCompile Include=\"simpleNode.cpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"simpleNode.h\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "03_Nodes/simpleNode/Exercise - py/simpleNode.py",
    "content": "# Copyright (C) \n# \n# Author: Autodesk Developer Network\n\n#For this exercise, search for the TODO keywords and follow the instructions in\n#comments. If you are unsure of what you need to do, feel free to ask the instructor\n#or look into the solution folder.\n#Each #... line is a line of code you need to write or complete.\n\nimport maya.OpenMaya as OpenMaya\nimport maya.OpenMayaMPx as OpenMayaMPx\nimport sys\n\n#- Assing a unique node ID to your new node class.\n#- Ask ADN or Autodesk product support to reserve IDs for your company. You can\n#- reserve ID by block of 64, 128, 256, or 512 consecutive ID.\n#-\n#- In the solution project, 0x00001 is a temporary ID reserved for development. Never use that ID in a\n#- production environment.\n\nkPluginNodeTypeName = \"simpleNode\"\n#- TODO: Define here your unique node ID\nsimpleNodeId = #...\n\n# Node definition\nclass simpleNode(OpenMayaMPx.MPxNode):\n\t# Node attributes\n\tinput = OpenMaya.MObject()\n\t#- TODO: Declare here the output attribute\n\t#- TODO: ...\n\t\n\tdef __init__(self):\n\t\tOpenMayaMPx.MPxNode.__init__(self)\n\t\t\n\t#- This method computes the value of the given output plug based\n\t#- on the values of the input attributes.\n\t#- Arguments:\n\t#- \tplug - the plug to compute\n\t#- \tdata - object that provides access to the attributes for this node\n\tdef compute(self,plug,dataBlock):\n\t\tif ( plug == simpleNode.output ):\n\t\t\t#- Get a handle to the input attribute that we will need for the\n\t\t\t#- computation. If the value is being supplied via a connection \n\t\t\t#- in the dependency graph, then this call will cause all upstream  \n\t\t\t#- connections to be evaluated so that the correct value is supplied.\n\t\t\tinputData = dataBlock.inputValue( simpleNode.input )\n\t\t\t\n\t\t\t#- Read the input value from the handle.\n\t\t\tresult = inputData.asFloat()\n\n\t\t\t#- Get a handle to the output attribute. This is similar to the\n\t\t\t#- \"inputValue\" call above except that no dependency graph \n\t\t\t#- computation will be done as a result of this call.\n\n\t\t\t#- Get a handle on the aOutput attribute\n\t\t\toutputHandle = dataBlock.outputValue( simpleNode.output )\n\n\t\t\t#- TODO: Set the new output value to the handle (multiply the value by 2 for\n\t\t\t#- example to see a change [result * 2])\n\t\t\t#...\n\n\t\t\t#- Mark the destination plug as being clean. This will prevent the\n\t\t\t#- dependency graph from repeating this calculation until an input \n\t\t\t#- attribute of this node which affects this output attribute changes.\n\n\t\t\t#- TODO: Tell Maya the plug is now clean\n\t\t\t#...\n\n\t\t#- Tell Maya that we do not know how to handle this plug, but let give a chance\n\t\t#- to our parent class to evaluate it.\n\t\treturn OpenMaya.kUnknownParameter\n\n# Creator\ndef nodeCreator():\n\treturn OpenMayaMPx.asMPxPtr( simpleNode() )\n\n#- The initialize method is called to create and initialize all of the \n#- attributes and attribute dependencies for this node type. This is \n#- only called once when the node type is registered with Maya.\n#-\ndef nodeInitializer():\n\t#- Initialize a float input attribute using the MFnNumericAttribute\n\t#- class. Make that attribute definition saved into Maya file (setStorable),\n\t#- and selectable in the channel box (setKeyable).\n\n\t#- Create a generic attribute using MFnNumericAttribute\n\tnAttr = OpenMaya.MFnNumericAttribute()\n\tsimpleNode.input = nAttr.create( \"input\", \"in\", OpenMaya.MFnNumericData.kFloat, 0.0 )\n\t#- Attribute will be written to files when this type of node is stored\n \tnAttr.setStorable(1)\n\t#- Attribute is keyable and will show up in the channel box\n \tnAttr.setKeyable(1)\n\n\t#- TODO: Initialize a float output attribute using the MFnNumericAttribute\n\t#- class. Make that attribute definition not saved into Maya file.\n\t#...\n\t#- TODO: Attribute will not be written to files when this type of node is stored\n\t#...\n\t\n\n\t#- Now add the attribute to your node definition using the addAttribute()\n\t#- method.\n\n\t#- Add the attributes we have created to the node\n\tsimpleNode.addAttribute( simpleNode.input )\n\t#- TODO: Add the output attribute to the node type definition\n\t#...\n\t\n\t\n\t#- Finally tell Maya how the information should flow through your node.\n\t#- This will also tell Maya how the dirty flag is propagated in your node\n\t#- and ultimatelly in the Maya DG. To do this, use the attributeAffects()\n\t#- method to link your node' attributes together.\n\n\t#- TODO: Set up a dependency between the input and the output. This will cause\n\t#- the output to be marked dirty when the input changes. The output will\n\t#- then be recomputed the next time the value of the output is requested.\n\t#...\n\n# Initialize the script plug-in\ndef initializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\t#- TODO: Register your node here, so Maya can use it and recognize it\n\t\t#- TODO: while reading/saving a file which has instance of this node type.\n\t\t#...\n\texcept:\n\t\tsys.stderr.write( \"Failed to register node: %s\" % kPluginNodeTypeName )\n\t\traise\n\n# Uninitialize the script plug-in\ndef uninitializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\t#- TODO: Unregister your node here, so Maya stops using it.\n\t\t#...\n\texcept:\n\t\tsys.stderr.write( \"Failed to deregister node: %s\" % kPluginNodeTypeName )\n\t\traise"
  },
  {
    "path": "03_Nodes/simpleNode/Solution - C++/pluginMain.cpp",
    "content": "//\n// Copyright (C)  \n// \n// File: pluginMain.cpp\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n\n#include <maya/MFnPlugin.h>\n#include \"simpleNode.h\"\n\nMStatus initializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is loaded into Maya.  It \n//\t\tregisters all of the services that this plug-in provides with \n//\t\tMaya.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{ \n\tMStatus   status;\n\tMFnPlugin plugin( obj, \"\", \"2009\", \"Any\");\n\n\t// Add plug-in feature registration here\n\t//\n\n\t//- Register your node here, so Maya can use it and recognize it\n\t//- while reading/saving a file which has instance of this node type.\n\tstatus = plugin.registerNode( \"simpleNode\", simpleNode::id, simpleNode::creator, simpleNode::initialize );\n\n\tif (!status) {\n\t\tstatus.perror(\"registerNode\");\n\t\treturn status;\n\t}\n\treturn status;\n}\n\nMStatus uninitializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is unloaded from Maya. It \n//\t\tderegisters all of the services that it was providing.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{\n\tMStatus   status;\n\tMFnPlugin plugin( obj );\n\n\t// Add plug-in feature deregistration here\n\t//\n\n\t//- Unregister your node here, so Maya stops using it.\n\tstatus = plugin.deregisterNode( simpleNode::id );\n\n\tif (!status) {\n\t\tstatus.perror(\"deregisterNode\");\n\t\treturn status;\n\t}\n\n\treturn status;\n}\n"
  },
  {
    "path": "03_Nodes/simpleNode/Solution - C++/simpleNode.cpp",
    "content": "//\n// Copyright (C) \n// \n// File: simpleNode.cpp\n//\n// Dependency Graph Node: simpleNode\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n\n#include \"simpleNode.h\"\n#include <maya/MGlobal.h>\n\n//- Assigning a unique node ID to your new node class.\n//- Ask ADN or Autodesk product support to reserve IDs for your company. You can\n//- reserve ID by block of 64, 128, 256, or 512 consecutive ID.\n//-\n//- 0x00001 is a temporary ID for reserved for development. Never use that ID in a\n//- production environment.\n/*static*/ MTypeId simpleNode::id( 0x00001 );\n\n//- Instantiate the static attributes of your node class.\n/*static*/ MObject simpleNode::input;        \n/*static*/ MObject simpleNode::output;   \n\t \n\n//- The initialize method is called to create and initialize all of the \n//- attributes and attribute dependencies for this node type. This is \n//- only called once when the node type is registered with Maya.\n//- Return Values: MS::kSuccess / MS::kFailure\n//-\nMStatus simpleNode::initialize()\n{\n\t//- Initialize a float input attribute using the MFnNumericAttribute\n\t//- class. Make that attribute definition saved into Maya file (setStorable),\n\t//- and selectable in the channel box (setKeyable).\n\n\t//- Create a generic attribute using MFnNumericAttribute\n\tMFnNumericAttribute nAttr;\n\tsimpleNode::input = nAttr.create( \"input\", \"in\", MFnNumericData::kFloat, 0.0 );\n\t//- Attribute will be written to files when this type of node is stored\n \tnAttr.setStorable(true);\n\t//- Attribute is keyable and will show up in the channel box\n \tnAttr.setKeyable(true);\n\n\t//- Initialize a float output attribute using the MFnNumericAttribute\n\t//- class. Make that attribute definition not saved into Maya file.\n\tsimpleNode::output = nAttr.create( \"output\", \"out\", MFnNumericData::kFloat, 0.0 );\n\t//- Attribute will not be written to files when this type of node is stored\n\tnAttr.setStorable(false);\n\t\n\t//- Now add the attribute to your node definition using the addAttribute()\n\t//- method.\n\n\t//- Add the attributes we have created to the node\n\taddAttribute( simpleNode::input );\t\n\t//- Add the aOutput attribute to the node type definition\n\taddAttribute( simpleNode::output );\n\t\n\t//- Finally tell Maya how the information should flow through your node.\n\t//- This will also tell Maya how the dirty flag is propagated in your node\n\t//- and ultimately in the Maya DG. To do this, use the attributeAffects()\n\t//- method to link your node' attributes together.\n\n\t//- Set up a dependency between the input and the output. This will cause\n\t//- the output to be marked dirty when the input changes. The output will\n\t//- then be recomputed the next time the value of the output is requested.\n\tattributeAffects( simpleNode::input, simpleNode::output );\n\n\t//- Return success to Maya\n\treturn MS::kSuccess;\n}\n\n//- This method computes the value of the given output plug based\n//- on the values of the input attributes.\n//- Arguments:\n//- \tplug - the plug to compute\n//- \tdata - object that provides access to the attributes for this node\nMStatus simpleNode::compute( const MPlug& plug, MDataBlock& data )\n{\n\t//- Check which output attribute we have been asked to compute. If this \n\t//- node doesn't know how to compute it, you must return MS::kUnknownParameter.\n\n\tif( plug == simpleNode::output )\n\t{\n\t\t//- Get a handle to the input attribute that we will need for the\n\t\t//- computation. If the value is being supplied via a connection \n\t\t//- in the dependency graph, then this call will cause all upstream  \n\t\t//- connections to be evaluated so that the correct value is supplied.\n\t\tMDataHandle inputData = data.inputValue( simpleNode::input );\n\n\t\t//- Read the input value from the handle.\n\t\tfloat result = inputData.asFloat();\n\n\t\t//- Get a handle to the output attribute. This is similar to the\n\t\t//- \"inputValue\" call above except that no dependency graph \n\t\t//- computation will be done as a result of this call.\n\n\t\t//- Get a handle on the output attribute\n\t\tMDataHandle outputHandle = data.outputValue( simpleNode::output );\n\n\t\t//- Set the new output value to the handle.\n\t\toutputHandle.set( result * 2 );\n\n\t\t//- Mark the destination plug as being clean. This will prevent the\n\t\t//- dependency graph from repeating this calculation until an input \n\t\t//- attribute of this node which affects this output attribute changes.\n\n\t\t//- Tell Maya the plug is now clean\n\t\tdata.setClean(plug);\n\n\t\t//- Return success to Maya\n\t\treturn MS::kSuccess;\n\t}\n\n\t//- Tell Maya that we do not know how to handle this plug, but let give a chance\n\t//- to our parent class to evaluate it.\n\treturn MS::kUnknownParameter;\n}\n"
  },
  {
    "path": "03_Nodes/simpleNode/Solution - C++/simpleNode.h",
    "content": "//\n// Copyright (C) \n// \n// File: simpleNode.h\n//\n// Dependency Graph Node: simpleNode\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#pragma once\n\n//- Include Maya necessary headers for our class\n#include <maya/MPxNode.h>\n#include <maya/MFnNumericAttribute.h>\n#include <maya/MFnStringData.h>\n#include <maya/MTypeId.h> \n#include <maya/MPlug.h>\n#include <maya/MDataBlock.h>\n#include <maya/MDataHandle.h>\n\n//- Derive a new class from the default Maya node proxy class.\nclass simpleNode : public MPxNode\n{\npublic:\n\tsimpleNode() {\n\t\t//- Never do anything here which would affect Maya.\n\t\t//- Instead implement the virtual postConstructor() method.\n\t}\n\tvirtual ~simpleNode() {}\n\n\t//- Declare the virtual compute() method.\n\tvirtual MStatus\t\tcompute( const MPlug& plug, MDataBlock& data );\n\n\t//- Declare/implement the static creator method.\n\t//- This method exists to give Maya a way to create new objects\n\t//- of this type. \n\tstatic  void*\t\tcreator() {\n\t\treturn new simpleNode();\n\t}\n\n\t//- Declare the static initialize() method.\n\tstatic  MStatus\t\tinitialize();\n\npublic:\n\t// There needs to be a MObject handle declared for each attribute that\n\t// the node will have.  These handles are needed for getting and setting\n\t// the values later.\n\t//\n\tstatic  MObject\t\tinput;\t\t// input attribute\n\tstatic  MObject\t\toutput;\t\t// output attribute\n\n\n\t//- This is a unique node ID for your new node class. It is declared\n\t//- static because it is common to all instance of that class.\n\t//-\n\t//- The typeid is a unique 32bit identifier that describes this node.\n\t//- It is used to save and retrieve nodes of this type from the binary\n\t//- file format. If it is not unique, it will cause file IO problems.\n\tstatic\tMTypeId\t\tid;\n};\n"
  },
  {
    "path": "03_Nodes/simpleNode/Solution - C++/simpleNode.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 2012\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"simpleNode\", \"simpleNode.vcxproj\", \"{439648C5-792B-4918-AC04-5B034F382742}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|x64 = Debug|x64\n\t\tRelease|x64 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{439648C5-792B-4918-AC04-5B034F382742}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{439648C5-792B-4918-AC04-5B034F382742}.Debug|x64.Build.0 = Debug|x64\n\t\t{439648C5-792B-4918-AC04-5B034F382742}.Release|x64.ActiveCfg = Release|x64\n\t\t{439648C5-792B-4918-AC04-5B034F382742}.Release|x64.Build.0 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "03_Nodes/simpleNode/Solution - C++/simpleNode.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{439648C5-792B-4918-AC04-5B034F382742}</ProjectGuid>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup>\n    <_ProjectFileVersion>11.0.61030.0</_ProjectFileVersion>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <OutDir>Debug\\</OutDir>\n    <IntDir>Debug\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <OutDir>C:\\MayaAPITraining\\plug-ins\\</OutDir>\n    <TargetExt>.mll</TargetExt>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <OutDir>Release\\</OutDir>\n    <IntDir>Release\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2009\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/simpleNode.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>..\\..\\..\\plug-ins\\simpleNode.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2009\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/simpleNode.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/simpleNode.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2015\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/simpleNode.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>C:\\MayaAPITraining\\plug-ins\\simpleNode.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2015\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/simpleNode.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/simpleNode.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/simpleNode.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\simpleNode.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/simpleNode.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/simpleNode.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/simpleNode.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\simpleNode.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/simpleNode.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/simpleNode.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"pluginMain.cpp\" />\n    <ClCompile Include=\"simpleNode.cpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"simpleNode.h\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "03_Nodes/simpleNode/Solution - py/simpleNode.py",
    "content": "#\n# Copyright (C) \n# \n# File: simpleNode.cpp\n#\n# Dependency Graph Node: simpleNode\n#\n# Author: Maya Plug-in Wizard 2.0\n#\n\nimport maya.OpenMaya as OpenMaya\nimport maya.OpenMayaMPx as OpenMayaMPx\nimport sys\n\n#- Assing a unique node ID to your new node class.\n#- Ask ADN or Autodesk product support to reserve IDs for your company. You can\n#- reserve ID by block of 64, 128, 256, or 512 consecutive ID.\n#-\n#- 0x00001 is a temporary ID for reserved for development. Never use that ID in a\n#- production environment.\nkPluginNodeTypeName = \"simpleNode\"\nsimpleNodeId = OpenMaya.MTypeId(0x00001)\n\n# Node definition\nclass simpleNode(OpenMayaMPx.MPxNode):\n\t# Node attributes\n\tinput = OpenMaya.MObject()\n\toutput = OpenMaya.MObject()\n\t\n\tdef __init__(self):\n\t\tOpenMayaMPx.MPxNode.__init__(self)\n\t\t\n\t#- This method computes the value of the given output plug based\n\t#- on the values of the input attributes.\n\t#- Arguments:\n\t#- \tplug - the plug to compute\n\t#- \tdata - object that provides access to the attributes for this node\n\tdef compute(self,plug,dataBlock):\n\t\tif ( plug == simpleNode.output ):\n\t\t\t#- Get a handle to the input attribute that we will need for the\n\t\t\t#- computation. If the value is being supplied via a connection \n\t\t\t#- in the dependency graph, then this call will cause all upstream  \n\t\t\t#- connections to be evaluated so that the correct value is supplied.\n\t\t\tinputData = dataBlock.inputValue( simpleNode.input )\n\t\t\t\n\t\t\t#- Read the input value from the handle.\n\t\t\tresult = inputData.asFloat()\n\n\t\t\t#- Get a handle to the output attribute. This is similar to the\n\t\t\t#- \"inputValue\" call above except that no dependency graph \n\t\t\t#- computation will be done as a result of this call.\n\n\t\t\t#- Get a handle on the aOutput attribute\n\t\t\toutputHandle = dataBlock.outputValue( simpleNode.output )\n\n\t\t\t#- Set the new output value to the handle.\n\t\t\toutputHandle.setFloat( result * 2 )\n\n\t\t\t#- Mark the destination plug as being clean. This will prevent the\n\t\t\t#- dependency graph from repeating this calculation until an input \n\t\t\t#- attribute of this node which affects this output attribute changes.\n\n\t\t\t#- Tell Maya the plug is now clean\n\t\t\tdataBlock.setClean( plug )\n\n\t\t\t#- Return success to Maya\n\n\t\t#- Tell Maya that we do not know how to handle this plug, but let give a chance\n\t\t#- to our parent class to evaluate it.\n\t\treturn OpenMaya.kUnknownParameter\n\n# Creator\ndef nodeCreator():\n\treturn OpenMayaMPx.asMPxPtr( simpleNode() )\n\n#- The initialize method is called to create and initialize all of the \n#- attributes and attribute dependencies for this node type. This is \n#- only called once when the node type is registered with Maya.\n#-\ndef nodeInitializer():\n\t#- Initialize a float input attribute using the MFnNumericAttribute\n\t#- class. Make that attribute definition saved into Maya file (setStorable),\n\t#- and selectable in the channel box (setKeyable).\n\n\t#- Create a generic attribute using MFnNumericAttribute\n\tnAttr = OpenMaya.MFnNumericAttribute()\n\tsimpleNode.input = nAttr.create( \"input\", \"in\", OpenMaya.MFnNumericData.kFloat, 0.0 )\n\t#- Attribute will be written to files when this type of node is stored\n \tnAttr.setStorable(1)\n\t#- Attribute is keyable and will show up in the channel box\n \tnAttr.setKeyable(1)\n\n\t#- Initialize a float output attribute using the MFnNumericAttribute\n\t#- class. Make that attribute definition not saved into Maya file.\n\tsimpleNode.output = nAttr.create( \"output\", \"out\", OpenMaya.MFnNumericData.kFloat, 0.0 )\n\t#- Attribute will not be written to files when this type of node is stored\n\tnAttr.setStorable(0)\n\t\n\t\n\t#- Now add the attribute to your node definition using the addAttribute()\n\t#- method.\n\n\t#- Add the attributes we have created to the node\n\tsimpleNode.addAttribute( simpleNode.input )\t\n\t#- Add the aOutput attribute to the node type definition\n\tsimpleNode.addAttribute( simpleNode.output )\n\t\n\t#- Finally tell Maya how the information should flow through your node.\n\t#- This will also tell Maya how the dirty flag is propagated in your node\n\t#- and ultimatelly in the Maya DG. To do this, use the attributeAffects()\n\t#- method to link your node' attributes together.\n\n\t#- Set up a dependency between the input and the output. This will cause\n\t#- the output to be marked dirty when the input changes. The output will\n\t#- then be recomputed the next time the value of the output is requested.\n\tsimpleNode.attributeAffects( simpleNode.input, simpleNode.output )\n\n# Initialize the script plug-in\ndef initializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\tmplugin.registerNode( kPluginNodeTypeName, simpleNodeId, nodeCreator, nodeInitializer )\n\texcept:\n\t\tsys.stderr.write( \"Failed to register node: %s\" % kPluginNodeTypeName )\n\t\traise\n\n# Uninitialize the script plug-in\ndef uninitializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\tmplugin.deregisterNode( simpleNodeId )\n\texcept:\n\t\tsys.stderr.write( \"Failed to deregister node: %s\" % kPluginNodeTypeName )\n\t\traise"
  },
  {
    "path": "03_Nodes/sineNode/Exercise - C++/pluginMain.cpp",
    "content": "//\n// Copyright (C)  \n// \n// File: pluginMain.cpp\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n\n#include <maya/MFnPlugin.h>\n#include \"simpleNode.h\"\n\nMStatus initializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is loaded into Maya.  It \n//\t\tregisters all of the services that this plug-in provides with \n//\t\tMaya.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{ \n\tMStatus   status;\n\tMFnPlugin plugin( obj, \"\", \"2009\", \"Any\");\n\n\t// Add plug-in feature registration here\n\t//\n\n\t//- TODO: Register your node here, so Maya can use it and recognize it\n\t//- TODO: while reading/saving a file which has instance of this node type.\n\t//...\n\n\tif (!status) {\n\t\tstatus.perror(\"registerNode\");\n\t\treturn status;\n\t}\n\treturn status;\n}\n\nMStatus uninitializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is unloaded from Maya. It \n//\t\tderegisters all of the services that it was providing.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{\n\tMStatus   status;\n\tMFnPlugin plugin( obj );\n\n\t// Add plug-in feature deregistration here\n\t//\n\n\t//- TODO: Unregister your node here, so Maya stops using it.\n\t//...\n\n\tif (!status) {\n\t\tstatus.perror(\"deregisterNode\");\n\t\treturn status;\n\t}\n\n\treturn status;\n}\n"
  },
  {
    "path": "03_Nodes/sineNode/Exercise - C++/simpleNode.cpp",
    "content": "//\n// Copyright (C) \n// \n// File: simpleNode.cpp\n//\n// Dependency Graph Node: simpleNode\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n\n#include \"simpleNode.h\"\n#include <maya/MGlobal.h>\n\n//- Assigning a unique node ID to your new node class.\n//- Ask ADN or Autodesk product support to reserve IDs for your company. You can\n//- reserve ID by block of 64, 128, 256, or 512 consecutive ID.\n//-\n//- In the solution project, 0x00001 is a temporary ID for reserved for development. Never use that ID in a\n//- production environment.\n\n//- TODO: Define here your unique node ID\n//...\n\n//- Instantiate the static attributes of your node class.\n/*static*/ MObject simpleNode::input;        \n/*static*/ MObject simpleNode::output;        \n/*static*/ MObject simpleNode::descString;\t\t \n\n//- The initialize method is called to create and initialize all of the \n//- attributes and attribute dependencies for this node type. This is \n//- only called once when the node type is registered with Maya.\n//- Return Values: MS::kSuccess / MS::kFailure\n//-\nMStatus simpleNode::initialize()\n{\n\t//- Initialize a float input attribute using the MFnNumericAttribute\n\t//- class. Make that attribute definition saved into Maya file (setStorable),\n\t//- and selectable in the channel box (setKeyable).\n\n\t//- Create a generic attribute using MFnNumericAttribute\n\tMFnNumericAttribute nAttr;\n\tinput = nAttr.create( \"input\", \"in\", MFnNumericData::kFloat, 0.0 );\n\t//- Attribute will be written to files when this type of node is stored\n \tnAttr.setStorable(true);\n\t//- Attribute is keyable and will show up in the channel box\n \tnAttr.setKeyable(true);\n\n\t//- TODO: Initialize a float output attribute using the MFnNumericAttribute\n\t//- class. Make that attribute definition not saved into Maya file.\n\t//...\n\t//- TODO: Attribute will not be written to files when this type of node is stored\n\t//...\n\t\n\t//- Initialize a string output attribute using the MFnTypedAttribute\n\t//- class. Make that attribute definition saved into Maya file.\n\t//- In order to specify the attribute default value, you will need to \n\t//- use the MFnStringData class, before creating the attribute itself.\n\n\n\t//- Use MFnStringData to implement default value first\n\tMFnStringData fnStringData;\n\tMString defaultString(\"description string for current node\");\n\tMObject defaultStringObj = fnStringData.create(defaultString);\n\n\t//- TODO: create a string attribute using the MFnTypedAttribute\n\t//- and use the above MObject as a default value for your string attribute\n\t//...\n\n\t//- Attribute will be written to files when this type of node is stored\n\ttypedAttr.setStorable(true);\n\n\t//- Now add the attribute to your node definition using the addAttribute()\n\t//- method.\n\n\t//- Add the attributes we have created to the node\n\taddAttribute( input );\t\n\t//- TODO: Add the output attribute to the node type definition\n\t//...\n\taddAttribute(descString);\n\t\n\t//- Finally tell Maya how the information should flow through your node.\n\t//- This will also tell Maya how the dirty flag is propagated in your node\n\t//- and ultimately in the Maya DG. To do this, use the attributeAffects()\n\t//- method to link your node' attributes together.\n\n\t//- TODO: Set up a dependency between the input and the output. This will cause\n\t//- the output to be marked dirty when the input changes. The output will\n\t//- then be recomputed the next time the value of the output is requested.\n\t//...\n\n\t//- Return success to Maya\n\treturn MS::kSuccess;\n}\n\n//- This method computes the value of the given output plug based\n//- on the values of the input attributes.\n//- Arguments:\n//- \tplug - the plug to compute\n//- \tdata - object that provides access to the attributes for this node\nMStatus simpleNode::compute( const MPlug& plug, MDataBlock& data )\n{\n\tMStatus returnStatus;\n \n\t//- Check which output attribute we have been asked to compute. If this \n\t//- node doesn't know how to compute it, you must return MS::kUnknownParameter.\n\n\tif( plug == output )\n\t{\n\t\t//- Get a handle to the input attribute that we will need for the\n\t\t//- computation. If the value is being supplied via a connection \n\t\t//- in the dependency graph, then this call will cause all upstream  \n\t\t//- connections to be evaluated so that the correct value is supplied.\n\t\tMDataHandle inputData = data.inputValue( input, &returnStatus );\n\n\t\t//- Read the input value from the handle.\n\t\tfloat result = inputData.asFloat();\n\n\t\t//- Get a handle to the output attribute. Use \"outputValue\", which \n\t\t//- is similar to the \"inputValue\" call above except that no \n\t\t//- dependency graph computation will be done as a result of this call.\n\t\t//- ToDO: Get a handle on the aOutput attribute\n\t\t//...\n\n\t\t//- TODO: Set the new output value to the handle.\n\t\t//...\n\n\t\t//- Mark the destination plug as being clean. This will prevent the\n\t\t//- dependency graph from repeating this calculation until an input \n\t\t//- attribute of this node which affects this output attribute changes.\n\n\t\t//- TODO: Tell Maya the plug is now clean\n\t\t//...\n\n\t\t//- Return success to Maya\n\t\treturn MS::kSuccess;\n\t}\n\n\t//- Tell Maya that we do not know how to handle this plug, but let give a chance\n\t//- to our parent class to evaluate it.\n\treturn MS::kUnknownParameter;\n}\n"
  },
  {
    "path": "03_Nodes/sineNode/Exercise - C++/simpleNode.h",
    "content": "//\n// Copyright (C) \n// \n// File: simpleNode.h\n//\n// Dependency Graph Node: simpleNode\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#pragma once\n\n//- Include Maya necessary headers for our class\n#include <maya/MPxNode.h>\n#include <maya/MFnNumericAttribute.h>\n#include <maya/MFnTypedAttribute.h>\n#include <maya/MFnStringData.h>\n#include <maya/MTypeId.h> \n#include <maya/MPlug.h>\n#include <maya/MDataBlock.h>\n#include <maya/MDataHandle.h>\n\n//- Derive a new class from the default Maya node proxy class.\nclass simpleNode : public MPxNode\n{\npublic:\n\tsimpleNode() {\n\t\t//- Never do anything here which would affect Maya.\n\t\t//- Instead implement the virtual postConstructor() method.\n\t}\n\tvirtual ~simpleNode() {}\n\n\t//- Declare the virtual compute() method.\n\tvirtual MStatus\t\tcompute( const MPlug& plug, MDataBlock& data );\n\n\t//- Declare/implement the static creator method.\n\t//- This method exists to give Maya a way to create new objects\n\t//- of this type. \n\tstatic  void*\t\tcreator() {\n\t\treturn new simpleNode();\n\t}\n\n\t//- Declare the static initialize() method.\n\tstatic  MStatus\t\tinitialize();\n\npublic:\n\t// There needs to be a MObject handle declared for each attribute that\n\t// the node will have.  These handles are needed for getting and setting\n\t// the values later.\n\t//\n\tstatic  MObject\t\tinput;\t\t// input attribute\n\t//- TODO: Declare here the output attribute\n\t//- TODO: ...\n\tstatic\tMObject\t\tdescString; // Description string attribute describing the function of this node\n\n\t//- This is a unique node ID for your new node class. It is declared\n\t//- static because it is common to all instance of that class.\n\t//-\n\t//- The typeid is a unique 32bit identifier that describes this node.\n\t//- It is used to save and retrieve nodes of this type from the binary\n\t//- file format. If it is not unique, it will cause file IO problems.\n\n\t//- TODO: Declare here your unique node ID\n\t//...\n};\n"
  },
  {
    "path": "03_Nodes/sineNode/Exercise - C++/simpleNode.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 2012\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"simpleNode\", \"simpleNode.vcxproj\", \"{439648C5-792B-4918-AC04-5B034F382742}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|x64 = Debug|x64\n\t\tRelease|x64 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{439648C5-792B-4918-AC04-5B034F382742}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{439648C5-792B-4918-AC04-5B034F382742}.Debug|x64.Build.0 = Debug|x64\n\t\t{439648C5-792B-4918-AC04-5B034F382742}.Release|x64.ActiveCfg = Release|x64\n\t\t{439648C5-792B-4918-AC04-5B034F382742}.Release|x64.Build.0 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "03_Nodes/sineNode/Exercise - C++/simpleNode.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{439648C5-792B-4918-AC04-5B034F382742}</ProjectGuid>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup>\n    <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">Debug\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">Debug\\</IntDir>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Release\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Release\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <OutDir>C:\\MayaAPITraining\\plug-ins\\</OutDir>\n    <TargetExt>.mll</TargetExt>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2009\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/simpleNode.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Debug\\simpleNode.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2009\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/simpleNode.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/simpleNode.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2015\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/simpleNode.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>C:\\MayaAPITraining\\plug-ins\\simpleNode.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2015\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/simpleNode.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/simpleNode.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/simpleNode.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\simpleNode.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/simpleNode.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/simpleNode.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/simpleNode.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\simpleNode.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/simpleNode.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/simpleNode.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"pluginMain.cpp\" />\n    <ClCompile Include=\"simpleNode.cpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"simpleNode.h\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "03_Nodes/sineNode/Exercise - py/sineNode.py",
    "content": "# Copyright (C) \n# \n# Author: Autodesk Developer Network\n\n#For this exercise, search for the TODO keywords and follow the instructions in\n#comments. If you are unsure of what you need to do, feel free to ask the instructor\n#or look into the solution folder.\n#Each #... line is a line of code you need to write or complete.\n\n#- TODO: Import all the necessary modules here\n#...\n\nkPluginNodeTypeName = \"spSineNode\"\n\n#- TODO: Allocate a type id for your custom node\n#...\n\n# Node definition\nclass sineNode(OpenMayaMPx.MPxNode):\n\n#- TODO: Define your class variables\n#...\n\tdef __init__(self):\n                OpenMayaMPx.MPxNode.__init__(self)\n\n#- TODO: Add Implementation of compute\n#...\n\t\tif ( plug == sineNode.output ):\n#- TODO: Get handle of input attribute and data from the handle\n#...\n\t\t\tresult = math.sin( inputFloat ) * 10.0\n\t\t\toutputHandle = dataBlock.outputValue( sineNode.output )\n\t\t\toutputHandle.setFloat( result )\n\t\t\tdataBlock.setClean( plug )\n\n\t\treturn OpenMaya.kUnknownParameter\n\n# creator\ndef nodeCreator():\n#- TODO: Implement the creator and apply asMPxPtr() to it\n#...\n\n# initializer\ndef nodeInitializer():\n\t# input\n#- TODO: Create an input attribute with name \"input\"\t\n#...\n\tnAttr.setStorable(1)\n\t# output\n\tnAttr = OpenMaya.MFnNumericAttribute()\n\tsineNode.output = nAttr.create( \"output\", \"out\", OpenMaya.MFnNumericData.kFloat, 0.0 )\n\tnAttr.setStorable(1)\n\tnAttr.setWritable(1)\n#- TODO: Add attributes and set up relationship\n#...\n\t\n# Initialize the script plug-in\ndef initializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n#- TODO: Register this custom node                \n#...\n\texcept:\n\t\tsys.stderr.write( \"Failed to register node: %s\" % kPluginNodeTypeName )\n\t\traise\n\n# Uninitialize the script plug-in\ndef uninitializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n#- TODO: Deregister this custom node                 \n#...\n\texcept:\n\t\tsys.stderr.write( \"Failed to deregister node: %s\" % kPluginNodeTypeName )\n\t\traise\n\t\n"
  },
  {
    "path": "03_Nodes/sineNode/Solution - C++/pluginMain.cpp",
    "content": "//\n// Copyright (C)  \n// \n// File: pluginMain.cpp\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n\n#include <maya/MFnPlugin.h>\n#include \"simpleNode.h\"\n\nMStatus initializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is loaded into Maya.  It \n//\t\tregisters all of the services that this plug-in provides with \n//\t\tMaya.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{ \n\tMStatus   status;\n\tMFnPlugin plugin( obj, \"\", \"2009\", \"Any\");\n\n\t// Add plug-in feature registration here\n\t//\n\n\t//- Register your node here, so Maya can use it and recognize it\n\t//- while reading/saving a file which has instance of this node type.\n\tstatus = plugin.registerNode( \"simpleNode\", simpleNode::id, simpleNode::creator, simpleNode::initialize );\n\n\tif (!status) {\n\t\tstatus.perror(\"registerNode\");\n\t\treturn status;\n\t}\n\treturn status;\n}\n\nMStatus uninitializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is unloaded from Maya. It \n//\t\tderegisters all of the services that it was providing.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{\n\tMStatus   status;\n\tMFnPlugin plugin( obj );\n\n\t// Add plug-in feature deregistration here\n\t//\n\n\t//- Unregister your node here, so Maya stops using it.\n\tstatus = plugin.deregisterNode( simpleNode::id );\n\n\tif (!status) {\n\t\tstatus.perror(\"deregisterNode\");\n\t\treturn status;\n\t}\n\n\treturn status;\n}\n"
  },
  {
    "path": "03_Nodes/sineNode/Solution - C++/simpleNode.cpp",
    "content": "//\n// Copyright (C) \n// \n// File: simpleNode.cpp\n//\n// Dependency Graph Node: simpleNode\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n\n#include \"simpleNode.h\"\n#include <maya/MGlobal.h>\n\n//- Assigning a unique node ID to your new node class.\n//- Ask ADN or Autodesk product support to reserve IDs for your company. You can\n//- reserve ID by block of 64, 128, 256, or 512 consecutive ID.\n//-\n//- 0x00001 is a temporary ID for reserved for development. Never use that ID in a\n//- production environment.\n/*static*/ MTypeId simpleNode::id( 0x00001 );\n\n//- Instantiate the static attributes of your node class.\n/*static*/ MObject simpleNode::input;        \n/*static*/ MObject simpleNode::output;   \n/*static*/ MObject simpleNode::descString;\t\t \n\n//- The initialize method is called to create and initialize all of the \n//- attributes and attribute dependencies for this node type. This is \n//- only called once when the node type is registered with Maya.\n//- Return Values: MS::kSuccess / MS::kFailure\n//-\nMStatus simpleNode::initialize()\n{\n\t//- Initialize a float input attribute using the MFnNumericAttribute\n\t//- class. Make that attribute definition saved into Maya file (setStorable),\n\t//- and selectable in the channel box (setKeyable).\n\n\t//- Create a generic attribute using MFnNumericAttribute\n\tMFnNumericAttribute nAttr;\n\tinput = nAttr.create( \"input\", \"in\", MFnNumericData::kFloat, 0.0 );\n\t//- Attribute will be written to files when this type of node is stored\n \tnAttr.setStorable(true);\n\t//- Attribute is keyable and will show up in the channel box\n \tnAttr.setKeyable(true);\n\n\t//- Initialize a float output attribute using the MFnNumericAttribute\n\t//- class. Make that attribute definition not saved into Maya file.\n\toutput = nAttr.create( \"output\", \"out\", MFnNumericData::kFloat, 0.0 );\n\t//- Attribute will not be written to files when this type of node is stored\n\tnAttr.setStorable(false);\n\t\n\t//- Initialize a string output attribute using the MFnTypedAttribute\n\t//- class. Make that attribute definition saved into Maya file.\n\t//- In order to specify the attribute default value, you will need to \n\t//- use the MFnStringData class, before creating the attribute itself.\n\n\t//- Create a string attribute using MFnTypedAttribute\n\tMFnTypedAttribute typedAttr;\n\t//- Use MFnStringData to implement default value of this attribute\n\tMFnStringData fnStringData;\n\tMString defaultString(\"description string for current node\");\n\tMObject defaultStringObj = fnStringData.create(defaultString);\n\tdescString = typedAttr.create(\"descString\", \"dStr\", MFnData::kString,defaultStringObj);\n\t//- Attribute will be written to files when this type of node is stored\n\ttypedAttr.setStorable(true);\n\n\t//- Now add the attribute to your node definition using the addAttribute()\n\t//- method.\n\n\t//- Add the attributes we have created to the node\n\taddAttribute( input );\t\n\t//- Add the aOutput attribute to the node type definition\n\taddAttribute( output );\n\taddAttribute(descString);\n\t\n\t//- Finally tell Maya how the information should flow through your node.\n\t//- This will also tell Maya how the dirty flag is propagated in your node\n\t//- and ultimately in the Maya DG. To do this, use the attributeAffects()\n\t//- method to link your node' attributes together.\n\n\t//- Set up a dependency between the input and the output. This will cause\n\t//- the output to be marked dirty when the input changes. The output will\n\t//- then be recomputed the next time the value of the output is requested.\n\tattributeAffects( input, output );\n\n\t//- Return success to Maya\n\treturn MS::kSuccess;\n}\n\n//- This method computes the value of the given output plug based\n//- on the values of the input attributes.\n//- Arguments:\n//- \tplug - the plug to compute\n//- \tdata - object that provides access to the attributes for this node\nMStatus simpleNode::compute( const MPlug& plug, MDataBlock& data )\n{\n\tMStatus returnStatus;\n \n\t//- Check which output attribute we have been asked to compute. If this \n\t//- node doesn't know how to compute it, you must return MS::kUnknownParameter.\n\n\tif( plug == output )\n\t{\n\t\t//- Get a handle to the input attribute that we will need for the\n\t\t//- computation. If the value is being supplied via a connection \n\t\t//- in the dependency graph, then this call will cause all upstream  \n\t\t//- connections to be evaluated so that the correct value is supplied.\n\t\tMDataHandle inputData = data.inputValue( input, &returnStatus );\n\n\t\t//- Read the input value from the handle.\n\t\tfloat result = inputData.asFloat();\n\n\t\t//- Get a handle to the output attribute. This is similar to the\n\t\t//- \"inputValue\" call above except that no dependency graph \n\t\t//- computation will be done as a result of this call.\n\n\t\t//- Get a handle on the aOutput attribute\n\t\tMDataHandle outputHandle = data.outputValue( simpleNode::output );\n\n\t\t//- Set the new output value to the handle.\n\t\toutputHandle.set( result * 2 );\n\n\t\t//- Mark the destination plug as being clean. This will prevent the\n\t\t//- dependency graph from repeating this calculation until an input \n\t\t//- attribute of this node which affects this output attribute changes.\n\n\t\t//- Tell Maya the plug is now clean\n\t\tdata.setClean(plug);\n\n\t\t//- Return success to Maya\n\t\treturn MS::kSuccess;\n\t}\n\n\t//- Tell Maya that we do not know how to handle this plug, but let give a chance\n\t//- to our parent class to evaluate it.\n\treturn MS::kUnknownParameter;\n}\n"
  },
  {
    "path": "03_Nodes/sineNode/Solution - C++/simpleNode.h",
    "content": "//\n// Copyright (C) \n// \n// File: simpleNode.h\n//\n// Dependency Graph Node: simpleNode\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#pragma once\n\n//- Include Maya necessary headers for our class\n#include <maya/MPxNode.h>\n#include <maya/MFnNumericAttribute.h>\n#include <maya/MFnTypedAttribute.h>\n#include <maya/MFnStringData.h>\n#include <maya/MTypeId.h> \n#include <maya/MPlug.h>\n#include <maya/MDataBlock.h>\n#include <maya/MDataHandle.h>\n\n//- Derive a new class from the default Maya node proxy class.\nclass simpleNode : public MPxNode\n{\npublic:\n\tsimpleNode() {\n\t\t//- Never do anything here which would affect Maya.\n\t\t//- Instead implement the virtual postConstructor() method.\n\t}\n\tvirtual ~simpleNode() {}\n\n\t//- Declare the virtual compute() method.\n\tvirtual MStatus\t\tcompute( const MPlug& plug, MDataBlock& data );\n\n\t//- Declare/implement the static creator method.\n\t//- This method exists to give Maya a way to create new objects\n\t//- of this type. \n\tstatic  void*\t\tcreator() {\n\t\treturn new simpleNode();\n\t}\n\n\t//- Declare the static initialize() method.\n\tstatic  MStatus\t\tinitialize();\n\npublic:\n\t// There needs to be a MObject handle declared for each attribute that\n\t// the node will have.  These handles are needed for getting and setting\n\t// the values later.\n\t//\n\tstatic  MObject\t\tinput;\t\t// input attribute\n\tstatic  MObject\t\toutput;\t\t// output attribute\n\tstatic\tMObject\t\tdescString; // Description string attribute describing the function of this node\n\n\n\t//- This is a unique node ID for your new node class. It is declared\n\t//- static because it is common to all instance of that class.\n\t//-\n\t//- The typeid is a unique 32bit identifier that describes this node.\n\t//- It is used to save and retrieve nodes of this type from the binary\n\t//- file format. If it is not unique, it will cause file IO problems.\n\tstatic\tMTypeId\t\tid;\n};\n"
  },
  {
    "path": "03_Nodes/sineNode/Solution - C++/simpleNode.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 2012\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"simpleNode\", \"simpleNode.vcxproj\", \"{439648C5-792B-4918-AC04-5B034F382742}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|x64 = Debug|x64\n\t\tRelease|x64 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{439648C5-792B-4918-AC04-5B034F382742}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{439648C5-792B-4918-AC04-5B034F382742}.Debug|x64.Build.0 = Debug|x64\n\t\t{439648C5-792B-4918-AC04-5B034F382742}.Release|x64.ActiveCfg = Release|x64\n\t\t{439648C5-792B-4918-AC04-5B034F382742}.Release|x64.Build.0 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "03_Nodes/sineNode/Solution - C++/simpleNode.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{439648C5-792B-4918-AC04-5B034F382742}</ProjectGuid>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup>\n    <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">Debug\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">Debug\\</IntDir>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Release\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Release\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <OutDir>C:\\MayaAPITraining\\plug-ins\\</OutDir>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2009\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/simpleNode.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Debug\\simpleNode.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2009\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/simpleNode.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/simpleNode.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2015\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/simpleNode.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>C:\\MayaAPITraining\\plug-ins\\simpleNode.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2015\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/simpleNode.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/simpleNode.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/simpleNode.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\simpleNode.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/simpleNode.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/simpleNode.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/simpleNode.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\simpleNode.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/simpleNode.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/simpleNode.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"pluginMain.cpp\" />\n    <ClCompile Include=\"simpleNode.cpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"simpleNode.h\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "03_Nodes/sineNode/Solution - py/sineNode.py",
    "content": "#\n# Copyright (C) \n# \n# File: sineNode.py\n#\n# Dependency Graph Node: sineNode\n#\n# Author: \n#\n\nimport math, sys\n\nimport maya.OpenMaya as OpenMaya\nimport maya.OpenMayaMPx as OpenMayaMPx\n\nkPluginNodeTypeName = \"spSineNode\"\n\nsineNodeId = OpenMaya.MTypeId(0x87000)\n\n# Node definition\nclass sineNode(OpenMayaMPx.MPxNode):\n\t# class variables\n\tinput = OpenMaya.MObject()\n\toutput = OpenMaya.MObject()\n\tdef __init__(self):\n\t\tOpenMayaMPx.MPxNode.__init__(self)\n\tdef compute(self,plug,dataBlock):\n\t\tif ( plug == sineNode.output ):\n\t\t\tdataHandle = dataBlock.inputValue( sineNode.input )\n\t\t\t\n\t\t\tinputFloat = dataHandle.asFloat()\n\t\t\tresult = math.sin( inputFloat ) * 10.0\n\t\t\toutputHandle = dataBlock.outputValue( sineNode.output )\n\t\t\toutputHandle.setFloat( result )\n\t\t\tdataBlock.setClean( plug )\n\n\t\treturn OpenMaya.kUnknownParameter\n\n# creator\ndef nodeCreator():\n\treturn OpenMayaMPx.asMPxPtr( sineNode() )\n\n# Initializer\ndef nodeInitializer():\n\t# input\n\tnAttr = OpenMaya.MFnNumericAttribute()\n\tsineNode.input = nAttr.create( \"input\", \"in\", OpenMaya.MFnNumericData.kFloat, 0.0 )\n\tnAttr.setStorable(1)\n\t# output\n\tnAttr = OpenMaya.MFnNumericAttribute()\n\tsineNode.output = nAttr.create( \"output\", \"out\", OpenMaya.MFnNumericData.kFloat, 0.0 )\n\tnAttr.setStorable(1)\n\tnAttr.setWritable(1)\n\t# add attributes\n\tsineNode.addAttribute( sineNode.input )\n\tsineNode.addAttribute( sineNode.output )\n\tsineNode.attributeAffects( sineNode.input, sineNode.output )\n\t\n# Initialize the script plug-in\ndef initializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\tmplugin.registerNode( kPluginNodeTypeName, sineNodeId, nodeCreator, nodeInitializer )\n\texcept:\n\t\tsys.stderr.write( \"Failed to register node: %s\" % kPluginNodeTypeName )\n\t\traise\n\n# Uninitialize the script plug-in\ndef uninitializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\tmplugin.deregisterNode( sineNodeId )\n\texcept:\n\t\tsys.stderr.write( \"Failed to deregister node: %s\" % kPluginNodeTypeName )\n\t\traise\n\t\n"
  },
  {
    "path": "03_Nodes/transCircleNode/Exercise - C++/AEtransCircleTemplate.mel",
    "content": "//-\n// ==========================================================================\n// Copyright (C) 1995 - 2006 Autodesk, Inc. and/or its licensors.  All \n// rights reserved.\n//\n// The coded instructions, statements, computer programs, and/or related \n// material (collectively the \"Data\") in these files contain unpublished \n// information proprietary to Autodesk, Inc. (\"Autodesk\") and/or its \n// licensors, which is protected by U.S. and Canadian federal copyright \n// law and by international treaties.\n//\n// The Data is provided for use exclusively by You. You have the right \n// to use, modify, and incorporate this Data into other products for \n// purposes authorized by the Autodesk software license agreement, \n// without fee.\n//\n// The copyright notices in the Software and this entire statement, \n// including the above license grant, this restriction and the \n// following disclaimer, must be included in all copies of the \n// Software, in whole or in part, and all derivative works of \n// the Software, unless such copies or derivative works are solely \n// in the form of machine-executable object code generated by a \n// source language processor.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND. \n// AUTODESK DOES NOT MAKE AND HEREBY DISCLAIMS ANY EXPRESS OR IMPLIED \n// WARRANTIES INCLUDING, BUT NOT LIMITED TO, THE WARRANTIES OF \n// NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR \n// PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE, OR \n// TRADE PRACTICE. IN NO EVENT WILL AUTODESK AND/OR ITS LICENSORS \n// BE LIABLE FOR ANY LOST REVENUES, DATA, OR PROFITS, OR SPECIAL, \n// DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES, EVEN IF AUTODESK \n// AND/OR ITS LICENSORS HAS BEEN ADVISED OF THE POSSIBILITY \n// OR PROBABILITY OF SUCH DAMAGES.\n//\n// ==========================================================================\n//+\n\n//\n//  Creation Date:\tMarch 04, 2009\n// \n//\n//  Procedure Name:\n//\tAEtransCircleTemplate\n//\n//  Description:\n//\tCreates the attribute editor controls for the transCircle node\n//\n//  Input Value:\n//\tnodeName\n//\n//  Output Value:\n//\tNone\n//\n\n///////////////////////////////////////////////////////////////\n//\tExample : \n///////////////////////////////////////////////////////////////\n/*\nfile -f -new;\n\ncreateNode transCircle;\n\nopenAEWindow;\n*/\n\n\n\nglobal proc AEtransCircleTemplate( string $nodeName )\n{\n\t\n}\n\n\n"
  },
  {
    "path": "03_Nodes/transCircleNode/Exercise - C++/pluginMain.cpp",
    "content": "//\n// Copyright (C)  \n// \n// File: pluginMain.cpp\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n\n#include <maya/MFnPlugin.h>\n#include \"transCircleNode.h\"\n\nMStatus initializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is loaded into Maya.  It \n//\t\tregisters all of the services that this plug-in provides with \n//\t\tMaya.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{ \n\tMStatus   status;\n\tMFnPlugin plugin( obj, \"\", \"2009\", \"Any\");\n\n\t//- TODO: Add plug-in feature registration here\n\t//...\n\t\n\treturn status;\n}\n\nMStatus uninitializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is unloaded from Maya. It \n//\t\tderegisters all of the services that it was providing.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{\n\tMStatus   status;\n\tMFnPlugin plugin( obj );\n\n\t//- TODO: Add plug-in feature deregistration here\n\t//...\n\n\treturn status;\n}\n"
  },
  {
    "path": "03_Nodes/transCircleNode/Exercise - C++/transCircleNode.cpp",
    "content": "//\n// Copyright (C) \n// \n// File: \n//\n// Dependency Graph Node: \n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#include \"transCircleNode.h\"\n\n//- Assign a unique node ID to your new node class.\n//- Ask ADN or Autodesk product support to reserve IDs for your company. You can\n//- reserve ID by block of 64, 128, 256, or 512 consecutive ID.\n//-\n//- 0x80013 is a temporary ID reserved for development. Never use that ID in a\n//- production environment.\n/*static*/MTypeId\ttransCircle::id( 0x80013 );\n\n//- Instantiate the static attributes of your node class.\n/*static*/MObject\ttransCircle::input;        \n/*static*/MObject\ttransCircle::frames;\n/*static*/MObject\ttransCircle::scale;\n\n/*static*/MObject\ttransCircle::inputTranslateX;\n/*static*/MObject\ttransCircle::inputTranslateY;\n/*static*/MObject\ttransCircle::inputTranslateZ;\n/*static*/MObject\ttransCircle::inputTranslate;\n\n//- TODO: Instantiate the outputTranslate compound attribute and its X, Y, Z\n//- TODO: components\n//...\n//...\n//...\n//...\n\n//- The initialize method is called to create and initialize all of the \n//- attributes and attribute dependencies for this node type. This is \n//- only called once when the node type is registered with Maya.\n//- Return Values: MS::kSuccess / MS::kFailure\n//-\nMStatus transCircle::initialize()\n{\n\t//- Create a numeric attribute using MFnNumericAttribute\n\tMFnNumericAttribute nAttr;\n\tinput = nAttr.create( \"input\", \"in\", MFnNumericData::kDouble, 0.0 );\n\t//- Attribute will be written to files when this type of node is stored\n\tnAttr.setStorable(true);\n\n\t//- Create individual input translate attributes\n\tinputTranslateX = nAttr.create( \"inputTranslateX\", \"itX\", MFnNumericData::kDouble, 0.0 );\n\tnAttr.setStorable(true);\n\n\tinputTranslateY = nAttr.create( \"inputTranslateY\", \"itY\", MFnNumericData::kDouble, 0.0 );\n\tnAttr.setStorable(true);\n\n\tinputTranslateZ = nAttr.create( \"inputTranslateZ\", \"itZ\", MFnNumericData::kDouble, 0.0 );\n\tnAttr.setStorable(true);\n\n\t//- Create compound input translate attributes by adding individual input translate attributes\n\tMFnCompoundAttribute comAttr;\n\tinputTranslate = comAttr.create(\"inputTranslate\",\"it\");\n\tcomAttr.addChild(inputTranslateX);\n\tcomAttr.addChild(inputTranslateY);\n\tcomAttr.addChild(inputTranslateZ);\n\tcomAttr.setStorable(true);\n\n\t//- TODO: Create the outputTranslate compound attribute and its X, Y, Z\n\t//- TODO: components. Make the attribute saved into the Maya file, and not \n\t//- TODO: writable. Tips: properties needs to be set for each components, \n\t//- TODO: including the parent.\n\n\t//- Create individual output translate attributes\n\t//...\n\t//...\n\t//...\n\n\t//...\n\t//...\n\t//...\n\n\t//...\n\t//...\n\t//...\n\n\t//- Create compound output translate attributes by adding individual output translate attributes\n\t//...\n\t//...\n\t//...\n\t//...\n\t//...\n\t//...\n\n\t//- Create other attributes for our node\n\tscale = nAttr.create( \"scale\", \"sc\",MFnNumericData::kDouble, 10.0 );\n\tnAttr.setStorable(true);\n\n\tframes = nAttr.create( \"frames\", \"fr\", MFnNumericData::kDouble, 48.0 );\n\tnAttr.setStorable(true);\n\n\t//- Now add the attribute to your node definition using the addAttribute()\n\t//- method.\n\n\t//- Add the attributes we have created to the node. For compound attributes,\n\t//- you only need to add the parent attribute.\n\taddAttribute( input );\n\taddAttribute( inputTranslate );\n\t\n\t//- TODO: Add the compound attribute to the list of the node' attribute.\n\t//- TODO: Since the child-parent relationship has been setup, we only need\n\t//- TODO: to add the parent attribute.\n\t//...\n\t\n\taddAttribute( scale );\n\taddAttribute( frames );\n\n\t//- Finally tell Maya how the information should flow through your node.\n\t//- This will also tell Maya how the dirty flag is propagated in your node\n\t//- and ultimately in the Maya DG. To do this, use the attributeAffects()\n\t//- method to link your node' attributes together.\n\n\t//- Set up a dependency between the input and the output. This will cause\n\t//- the output to be marked dirty when the input changes. The output will\n\t//- then be recomputed the next time the value of the output is requested.\n\n\t//- All input compound attributes' children will affect the individual children\n\t//- of the output compound attributes. Also, any change to the \n\t//- parent attribute is affecting the children of the output attribute and the \n\t//- output parent attribute as well.\n\tattributeAffects( inputTranslateX, outputTranslateX );\n\tattributeAffects( inputTranslateY, outputTranslateY );\n\tattributeAffects( inputTranslateZ, outputTranslateZ );\n\tattributeAffects( inputTranslate, outputTranslateX );\n\tattributeAffects( inputTranslate, outputTranslateY );\n\tattributeAffects( inputTranslate, outputTranslateZ );\n\tattributeAffects( inputTranslate, outputTranslate );\n\n\t//- Other relationships,\n\tattributeAffects( input, outputTranslateX );\n\tattributeAffects( input, outputTranslateY );\n\tattributeAffects( scale, outputTranslateX );\n\tattributeAffects( scale, outputTranslateY );\n\tattributeAffects( frames, outputTranslateX );\n\tattributeAffects( frames, outputTranslateY );\n\n\t//- Return success to Maya\n\treturn MS::kSuccess;\n}\n\n//- This method computes the value of the given output plug based\n//- on the values of the input attributes.\n//- Arguments:\n//- \tplug - the plug to compute\n//- \tdata - object that provides access to the attributes for this node\nMStatus transCircle::compute( const MPlug& plug, MDataBlock& data )\n{\n    MStatus stat;\n \n\t//- Check which output attribute we have been asked to compute. If this \n\t//- node doesn't know how to compute it, you must return MS::kUnknownParameter.\n\n\tbool k = ( plug == outputTranslateX ) |\n\t         ( plug == outputTranslateY ) |\n\t\t\t ( plug == outputTranslateZ ) |\n\t\t\t ( plug == outputTranslate );\n\tif (!k) return MS::kUnknownParameter;\n\n\t//- Get a handle on the input attributes that we will need for the\n\t//- computation. If the value is being supplied via a connection \n\t//- in the dependency graph, then this call will cause all upstream  \n\t//- connections to be evaluated so that the correct value is supplied.\n\n\tMDataHandle inputData = data.inputValue( input, &stat );\n\tMDataHandle scaleData = data.inputValue( scale, &stat );\n\tMDataHandle framesData = data.inputValue( frames, &stat );\n\n\t//- Retrieve value of current frame attribute,scale factor \n\t//- and number of frames for one circle \n\tdouble currentFrame = inputData.asDouble();\n\tdouble scaleFactor  = scaleData.asDouble();\n\tdouble framesPerCircle = framesData.asDouble();\n\n\t//- Retrieve values on individual input translate attribute\n\n\t//- TODO: Retrieve the double value of the X, Y, Z components of the inputTranslate attribute\n\tMDataHandle inputTranslateXHandle = //...\n\tdouble inputTranslateXData = //...\n\n\tMDataHandle inputTranslateYHandle = //...\n\tdouble inputTranslateYData = //...\n\n\tMDataHandle inputTranslateZHandle = //...\n\tdouble inputTranslateZData = //...\n\n\t//- Calculate corresponding angle based on current frame \n\tdouble angle = 6.2831853 * ( currentFrame/framesPerCircle );\n\t\n\t//- The value of output translate is input translate value plus the value of circular movement  \n\tdouble outputTranslateXData = inputTranslateXData + (sin( angle ) * scaleFactor);\n\tdouble outputTranslateYData = inputTranslateYData + 1.0;\n\tdouble outputTranslateZData = inputTranslateZData + (cos( angle ) * scaleFactor);\n\n\t//- Get a handle on the output attributes and set the new value.\n\n\t//- TODO: Set the double value of the X, Y, Z components of the outputTranslate attribute\n\n\tMDataHandle outputTranslateXHandle = //...\n\t//...\n\n\tMDataHandle outputTranslateYHandle = //...\n\t//...\n\n\tMDataHandle outputTranslateZHandle = //...\n\t//...\n\n\t//- Tell Maya the plug is now clean\n\tdata.setClean(plug);\n\n\t//- Return success to Maya\n    return MS::kSuccess;\n}\n\n"
  },
  {
    "path": "03_Nodes/transCircleNode/Exercise - C++/transCircleNode.h",
    "content": "//\n// Copyright (C) \n// \n// File: \n//\n// Dependency Graph Node: \n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#pragma once\n\n//- Include Maya necessary headers for our class\n#include <maya/MPxNode.h>\n#include <maya/MString.h> \n#include <maya/MTypeId.h> \n#include <maya/MPlug.h>\n\n#include <maya/MFnNumericAttribute.h>\n#include <maya/MFnCompoundAttribute.h>\n#include <maya/MFnTypedAttribute.h>\n\n#include <maya/MDataBlock.h>\n#include <maya/MDataHandle.h>\n\n#include <string.h>\n#include <maya/MIOStream.h>\n#include <math.h>\n\n//- Derive a new class from the default Maya node proxy class.\nclass transCircle : public MPxNode\n{\npublic:\n\ttransCircle() {}\n\tvirtual\t~transCircle() {}\n\n\tvirtual MStatus\t\tcompute( const MPlug& plug, MDataBlock& data );\n\n\tstatic  MStatus\t\tinitialize();\n\tstatic  void*\t\tcreator() {\n\t\treturn new transCircle();\n\t}\n\npublic:\n\t// There needs to be a MObject handle declared for each attribute that\n\t// the node will have.  These handles are needed for getting and setting\n\t// the values later.\n\t//\n\tstatic  MObject\t\tinput;            // The input value.\n\n\t//- Compound attributes in Maya are build from several individual attributes. In\n\t//- our example the input compound attribute is made of inputTranslateX,\n\t//- inputTranslateY and inputTranslateZ. \n\tstatic  MObject\t\tinputTranslateX;  // The translate X value.  (input)\n\tstatic  MObject\t\tinputTranslateY;  // The translate Y value.  (input)\n\tstatic  MObject\t\tinputTranslateZ;  // The translate Z value.  (input)\n\tstatic  MObject\t\tinputTranslate;\n\n\t//- TODO: Declare a outputTranslate compound attribute and its X, Y, Z\n\t//- TODO: components, in order to make the rest of the code work, \n\t//- TODO: name your output parent object \"outputTranslate\",and its children\n\t//- TODO: \"outputTranslateX\", \"outputTranslateY\" and \"outputTranslateZ\"\n\t//...\n\t//...\n\t//...\n\t//...\n\n\tstatic  MObject\t\tframes;           // Number of frames for one circle.\n\tstatic  MObject\t\tscale;            // Radius of circle.\n\n\t//- This is a unique node ID for your new node class. It is declared\n\t//- static because it is common to all instance of that class.\n\t//-\n\t//- The typeid is a unique 32bit identifier that describes this node.\n\t//- It is used to save and retrieve nodes of this type from the binary\n\t//- file format. If it is not unique, it will cause file IO problems.\n\tstatic  MTypeId\t\tid;\n};\n"
  },
  {
    "path": "03_Nodes/transCircleNode/Exercise - C++/transCircleNode.mel",
    "content": "//-\n// ==========================================================================\n// Copyright (C) 1995 - 2006 Autodesk, Inc. and/or its licensors.  All \n// rights reserved.\n//\n// The coded instructions, statements, computer programs, and/or related \n// material (collectively the \"Data\") in these files contain unpublished \n// information proprietary to Autodesk, Inc. (\"Autodesk\") and/or its \n// licensors, which is protected by U.S. and Canadian federal copyright \n// law and by international treaties.\n//\n// The Data is provided for use exclusively by You. You have the right \n// to use, modify, and incorporate this Data into other products for \n// purposes authorized by the Autodesk software license agreement, \n// without fee.\n//\n// The copyright notices in the Software and this entire statement, \n// including the above license grant, this restriction and the \n// following disclaimer, must be included in all copies of the \n// Software, in whole or in part, and all derivative works of \n// the Software, unless such copies or derivative works are solely \n// in the form of machine-executable object code generated by a \n// source language processor.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND. \n// AUTODESK DOES NOT MAKE AND HEREBY DISCLAIMS ANY EXPRESS OR IMPLIED \n// WARRANTIES INCLUDING, BUT NOT LIMITED TO, THE WARRANTIES OF \n// NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR \n// PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE, OR \n// TRADE PRACTICE. IN NO EVENT WILL AUTODESK AND/OR ITS LICENSORS \n// BE LIABLE FOR ANY LOST REVENUES, DATA, OR PROFITS, OR SPECIAL, \n// DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES, EVEN IF AUTODESK \n// AND/OR ITS LICENSORS HAS BEEN ADVISED OF THE POSSIBILITY \n// OR PROBABILITY OF SUCH DAMAGES.\n//\n// ==========================================================================\n//+\n\ncreateNode transCircle -n circleNode1;\nsphere -n sphere1 -r 1;\nsphere -n sphere2 -r 2;\nconnectAttr sphere2.translate circleNode1.inputTranslate;\nconnectAttr circleNode1.outputTranslate sphere1.translate;\nconnectAttr time1.outTime circleNode1.input;\n"
  },
  {
    "path": "03_Nodes/transCircleNode/Exercise - C++/transCircleNode.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 2012\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"transCircleNode\", \"transCircleNode.vcxproj\", \"{B6A0AEBE-B5EE-4EB6-BE01-F1738C49F587}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|x64 = Debug|x64\n\t\tRelease|x64 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{B6A0AEBE-B5EE-4EB6-BE01-F1738C49F587}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{B6A0AEBE-B5EE-4EB6-BE01-F1738C49F587}.Debug|x64.Build.0 = Debug|x64\n\t\t{B6A0AEBE-B5EE-4EB6-BE01-F1738C49F587}.Release|x64.ActiveCfg = Release|x64\n\t\t{B6A0AEBE-B5EE-4EB6-BE01-F1738C49F587}.Release|x64.Build.0 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "03_Nodes/transCircleNode/Exercise - C++/transCircleNode.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{B6A0AEBE-B5EE-4EB6-BE01-F1738C49F587}</ProjectGuid>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup>\n    <_ProjectFileVersion>11.0.61030.0</_ProjectFileVersion>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <OutDir>Debug\\</OutDir>\n    <IntDir>Debug\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <OutDir>C:\\MayaAPITraining\\plug-ins\\</OutDir>\n    <TargetExt>.mll</TargetExt>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <OutDir>Release\\</OutDir>\n    <IntDir>Release\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2009\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/transCircleNode.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>..\\..\\..\\plug-ins\\transCircleNode.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2009\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/transCircleNode.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/transCircleNode.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2015\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/transCircleNode.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>C:\\MayaAPITraining\\plug-ins\\transCircleNode.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2015\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/transCircleNode.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/transCircleNode.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/transCircleNode.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\transCircleNode.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/transCircleNode.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/transCircleNode.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/transCircleNode.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\transCircleNode.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/transCircleNode.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/transCircleNode.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"pluginMain.cpp\" />\n    <ClCompile Include=\"transCircleNode.cpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"transCircleNode.h\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"AEtransCircleTemplate.mel\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "03_Nodes/transCircleNode/Exercise - py/AEtransCircleTemplate.mel",
    "content": "//-\n// ==========================================================================\n// Copyright (C) 1995 - 2006 Autodesk, Inc. and/or its licensors.  All \n// rights reserved.\n//\n// The coded instructions, statements, computer programs, and/or related \n// material (collectively the \"Data\") in these files contain unpublished \n// information proprietary to Autodesk, Inc. (\"Autodesk\") and/or its \n// licensors, which is protected by U.S. and Canadian federal copyright \n// law and by international treaties.\n//\n// The Data is provided for use exclusively by You. You have the right \n// to use, modify, and incorporate this Data into other products for \n// purposes authorized by the Autodesk software license agreement, \n// without fee.\n//\n// The copyright notices in the Software and this entire statement, \n// including the above license grant, this restriction and the \n// following disclaimer, must be included in all copies of the \n// Software, in whole or in part, and all derivative works of \n// the Software, unless such copies or derivative works are solely \n// in the form of machine-executable object code generated by a \n// source language processor.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND. \n// AUTODESK DOES NOT MAKE AND HEREBY DISCLAIMS ANY EXPRESS OR IMPLIED \n// WARRANTIES INCLUDING, BUT NOT LIMITED TO, THE WARRANTIES OF \n// NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR \n// PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE, OR \n// TRADE PRACTICE. IN NO EVENT WILL AUTODESK AND/OR ITS LICENSORS \n// BE LIABLE FOR ANY LOST REVENUES, DATA, OR PROFITS, OR SPECIAL, \n// DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES, EVEN IF AUTODESK \n// AND/OR ITS LICENSORS HAS BEEN ADVISED OF THE POSSIBILITY \n// OR PROBABILITY OF SUCH DAMAGES.\n//\n// ==========================================================================\n//+\n\n//\n//  Creation Date:\tMarch 04, 2009\n// \n//\n//  Procedure Name:\n//\tAEtransCircleTemplate\n//\n//  Description:\n//\tCreates the attribute editor controls for the transCircle node\n//\n//  Input Value:\n//\tnodeName\n//\n//  Output Value:\n//\tNone\n//\n\n///////////////////////////////////////////////////////////////\n//\tExample : \n///////////////////////////////////////////////////////////////\n/*\nfile -f -new;\n\ncreateNode transCircle;\n\nopenAEWindow;\n*/\n\n\n\nglobal proc AEtransCircleTemplate( string $nodeName )\n{\n\t// Put our attributes into a scrolled layout field\n\n\teditorTemplate -beginScrollLayout;\n\n\t// They all go into the collapsable \"Parameters\" section\n\teditorTemplate -beginLayout \"Parameters\" -collapse false;\n\n\t   // Add a \"special\" control for the scale attribute that allow\n\t   // \"quick set\" options for scales of 5, 10, and 15.\n\t   editorTemplate -callCustom \"transCircleScaleNew\"\n\t   \t\t\t\t  \"transCircleScaleReplace\"\n\t\t\t\t\t  \"scale\";\n\n\t\t// Add the default controls for the scale and frames attributes\n\t\teditorTemplate -addControl \"scale\";\n\t\teditorTemplate -addControl \"frames\";\n\teditorTemplate -endLayout;\n\n\t// Create an \"Extras\" section and also add controls for any\n\t// attributes we have not explicitly mentioned.\n\teditorTemplate -addExtraControls;\n\n\teditorTemplate -endScrollLayout;\n\n\t// Tell the attribute editor not to display the attributes we\n\t// don't care about.\n\teditorTemplate -suppress \"inputTranslate\";\n\teditorTemplate -suppress \"input\";\n\teditorTemplate -suppress \"caching\";\n\teditorTemplate -suppress \"nodeState\";\n}\n\n\n///////////////////////////////////////////////////////////////\n//\n// Description : \n//\tThis procedure is called when the AE is editing a transCircle \n//\tnode for the first time.  Use this for creating the custom \n//\tlayout and controls\n//\nglobal proc transCircleScaleNew( string $attrName )\n{\n\t// Create the \"quick set\" control for the scale attribute\n\tradioButtonGrp\n\t\t-label \"Quick Scale\"\n\t\t-numberOfRadioButtons 3\n\t\t-label1 \"Five\"\n\t\t-data1 5\n\t\t-label2 \"Ten\"\n\t\t-data2 10\n\t\t-label3 \"Fifteen\"\n\t\t-data3 15\n\t\tscaleGrp;\n\tconnectControl scaleGrp $attrName;\n}\n\n\n///////////////////////////////////////////////////////////////\n//\n// Description : \n//\tThis procedure is called whenever the AE is editing another \n//\ttransCircle type.  This procedure is necessary to reconnect\n//\tany controls with their associated attributes\n//\nglobal proc transCircleScaleReplace( string $attrName )\n{\n   // Install the connection between the radioButtonGrp and the\n   // actual scale attribute\n   connectControl scaleGrp $attrName;\n}\n"
  },
  {
    "path": "03_Nodes/transCircleNode/Exercise - py/transCircleNode.mel",
    "content": "//-\n// ==========================================================================\n// Copyright (C) 1995 - 2006 Autodesk, Inc. and/or its licensors.  All \n// rights reserved.\n//\n// The coded instructions, statements, computer programs, and/or related \n// material (collectively the \"Data\") in these files contain unpublished \n// information proprietary to Autodesk, Inc. (\"Autodesk\") and/or its \n// licensors, which is protected by U.S. and Canadian federal copyright \n// law and by international treaties.\n//\n// The Data is provided for use exclusively by You. You have the right \n// to use, modify, and incorporate this Data into other products for \n// purposes authorized by the Autodesk software license agreement, \n// without fee.\n//\n// The copyright notices in the Software and this entire statement, \n// including the above license grant, this restriction and the \n// following disclaimer, must be included in all copies of the \n// Software, in whole or in part, and all derivative works of \n// the Software, unless such copies or derivative works are solely \n// in the form of machine-executable object code generated by a \n// source language processor.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND. \n// AUTODESK DOES NOT MAKE AND HEREBY DISCLAIMS ANY EXPRESS OR IMPLIED \n// WARRANTIES INCLUDING, BUT NOT LIMITED TO, THE WARRANTIES OF \n// NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR \n// PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE, OR \n// TRADE PRACTICE. IN NO EVENT WILL AUTODESK AND/OR ITS LICENSORS \n// BE LIABLE FOR ANY LOST REVENUES, DATA, OR PROFITS, OR SPECIAL, \n// DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES, EVEN IF AUTODESK \n// AND/OR ITS LICENSORS HAS BEEN ADVISED OF THE POSSIBILITY \n// OR PROBABILITY OF SUCH DAMAGES.\n//\n// ==========================================================================\n//+\n\ncreateNode transCircle -n circleNode1;\nsphere -n sphere1 -r 1;\nsphere -n sphere2 -r 2;\nconnectAttr sphere2.translate circleNode1.inputTranslate;\nconnectAttr circleNode1.outputTranslate sphere1.translate;\nconnectAttr time1.outTime circleNode1.input;\n"
  },
  {
    "path": "03_Nodes/transCircleNode/Exercise - py/transCircleNode.py",
    "content": "# Copyright (C) \n# \n# Author: Autodesk Developer Network\n\n#For this exercise, search for the TODO keywords and follow the instructions in\n#comments. If you are unsure of what you need to do, feel free to ask the instructor\n#or look into the solution folder.\n#Each #... line is a line of code you need to write or complete.\n\nimport maya.OpenMaya as OpenMaya\nimport maya.OpenMayaMPx as OpenMayaMPx\n\n#- Assing a unique node ID to your new node class.\n#- Ask ADN or Autodesk product support to reserve IDs for your company. You can\n#- reserve ID by block of 64, 128, 256, or 512 consecutive ID.\n#-\n#- 0x80013 is a temporary ID reserved for development. Never use that ID in a\n#- production environement.\nkPluginNodeTypeName = \"transCircle\"\ntransCircleNodeId = OpenMaya.MTypeId(0x80013)\n\n# Node definition\nclass transCircleNode(OpenMayaMPx.MPxNode):\n\t# Node attributes\n\t#- Compound attributes in Maya are build from several individual attributes. In\n\t#- our example the translation vector is made of the x,y,z attributes, and the\n\t#- compound attribute itself.\n\tinputTranslateX = OpenMaya.MObject() # The translate X value.  (input)\n\tinputTranslateY = OpenMaya.MObject() # The translate Y value.  (input)\n\tinputTranslateZ = OpenMaya.MObject() # The translate Z value.  (input)\n\tinputTranslate = OpenMaya.MObject()\n\n\t#- TODO: Declare a outputTranslate coumpound attribute and its X, Y, Z\n\t#- TODO: components\n\t#...\n\t#...\n\t#...\n\t#...\n\n\tframes = OpenMaya.MObject() # Number of frames for one circle.\n\tscale = OpenMaya.MObject() # Radius of circle.\n\t\n\tdef __init__(self):\n\t\tOpenMayaMPx.MPxNode.__init__(self)\n\t\t\n\t#- This method computes the value of the given output plug based\n\t#- on the values of the input attributes.\n\t#- Arguments:\n\t#- \tplug - the plug to compute\n\t#- \tdata - object that provides access to the attributes for this node\n\tdef compute(self,plug,dataBlock):\n\t\t#- Check which output attribute we have been asked to compute. If this \n\t\t#- node doesn't know how to compute it, you must return MS::kUnknownParameter.\n\n\t\tif ( plug == transCircleNode.outputTranslateX or plug == transCircleNode.outputTranslateY or plug == transCircleNode.outputTranslateZ or plug == transCircleNode.outputTranslate ):\n\t\t\t\n\n\t\t\t#- Get a handle on the input attributes that we will need for the\n\t\t\t#- computation. If the value is being supplied via a connection \n\t\t\t#- in the dependency graph, then this call will cause all upstream  \n\t\t\t#- connections to be evaluated so that the correct value is supplied.\n\n\t\t\tinputData = data.inputValue( transCircleNode.input )\n\t\t\tscaleData = data.inputValue( transCircleNode.scale )\n\t\t\tframesData = data.inputValue( transCircleNode.frames )\n\n\t\t\t#- Retrieve value of current frame attribute,scale factor \n\t\t\t#- and number of frames for one circle \n\t\t\tcurrentFrame = inputData.asDouble()\n\t\t\tscaleFactor  = scaleData.asDouble()\n\t\t\tframesPerCircle = framesData.asDouble()\n\n\t\t\t#- Retrieve values on individual input translate attribute\n\n\t\t\t#- TODO: Retrieve the double value of the X, Y, Z components of the inputTranslate attribute\n\n\t\t\tinputTranslateXHandle = #...\n\t\t\tinputTranslateXData = #...\n\n\t\t\tinputTranslateYHandle = #...\n\t\t\tinputTranslateYData = #...\n\n\t\t\tinputTranslateZHandle = #...\n\t\t\tinputTranslateZData = #...\n\n\t\t\t#- Calculate corresponding angle based on current frame \n\t\t\tangle = 6.2831853 * ( currentFrame/framesPerCircle )\n\n\t\t\t#- The value of output translate is input translate value plus the value of circular movement  \n\t\t\toutputTranslateXData = inputTranslateXData + (sin( angle ) * scaleFactor)\n\t\t\toutputTranslateYData = inputTranslateYData + 1.0\n\t\t\toutputTranslateZData = inputTranslateZData + (cos( angle ) * scaleFactor)\n\n\t\t\t#- Get a handle on the output attributes and set the new value.\n\n\t\t\t#- TODO: Set the double value of the X, Y, Z components of the outputTranslate attribute\n\n\t\t\toutputTranslateXHandle = #...\n\t\t\t#...\n\n\t\t\toutputTranslateYHandle = #...\n\t\t\t#...\n\n\t\t\toutputTranslateZHandle = #... \n\t\t\t#...\n\n\t\t\t#- Tell Maya the plug is now clean\n\t\t\tdataBlock.setClean( plug )\n\n\t\telse:\n\t\t\treturn OpenMaya.kUnknownParameter\n\n# Creator\ndef nodeCreator():\n\treturn OpenMayaMPx.asMPxPtr( transCircleNode() )\n\n#- The initialize method is called to create and initialize all of the \n#- attributes and attribute dependencies for this node type. This is \n#- only called once when the node type is registered with Maya.\n#-\ndef nodeInitializer():\n\t#- Create a generic attribute using MFnNumericAttribute\n\tnAttr = OpenMaya.MFnNumericAttribute()\n\ttransCircleNode.input = nAttr.create( \"input\", \"in\", OpenMaya.MFnNumericData.kDouble, 0.0 )\n\t#- Attribute will be written to files when this type of node is stored\n\tnAttr.setStorable(1)\n\n\t#- Create individual input translate attributes\n\ttransCircleNode.inputTranslateX = nAttr.create( \"inputTranslateX\", \"itX\", OpenMaya.MFnNumericData.kDouble, 0.0 )\n\tnAttr.setStorable(1)\n\n\ttransCircleNode.inputTranslateY = nAttr.create( \"inputTranslateY\", \"itY\", OpenMaya.MFnNumericData.kDouble, 0.0 )\n\tnAttr.setStorable(1)\n\n\ttransCircleNode.inputTranslateZ = nAttr.create( \"inputTranslateZ\", \"itZ\", OpenMaya.MFnNumericData.kDouble, 0.0 )\n\tnAttr.setStorable(1)\n\n\t#- Create compound input translate attributes and add individual input translate attributes\n\tcomAttr = OpenMaya.MFnCompoundAttribute()\n\ttransCircleNode.inputTranslate = comAttr.create(\"inputTranslate\",\"it\")\n\tcomAttr.addChild(transCircleNode.inputTranslateX)\n\tcomAttr.addChild(transCircleNode.inputTranslateY)\n\tcomAttr.addChild(transCircleNode.inputTranslateZ)\n\tcomAttr.setStorable(1)\n\n\t#- TODO: Create the outputTranslate coumpound attribute and its X, Y, Z\n\t#- TODO: components. Make the attribute saved into the Maya file, and not \n\t#- TODO: writable. Tips: properties needs to be set for each components, \n\t#- TODO: including the parent.\n\n\t#- Create individual output translate attributes\n\t#...\n\t#...\n\t#...\n\n\t#...\n\t#...\n\t#...\n\n\t#...\n\t#...\n\t#...\n\n\t#- Create compound output translate attributes and add individual output translate attributes\n\t#...\n\t#...\n\t#...\n\t#...\n\t#...\n\t#...\n\n\t#- Create other attributes for our node\n\ttransCircleNode.scale = nAttr.create( \"scale\", \"sc\", OpenMaya.MFnNumericData.kDouble, 10.0 )\n\tnAttr.setStorable(1)\n\n\ttransCircleNode.frames = nAttr.create( \"frames\", \"fr\", OpenMaya.MFnNumericData.kDouble, 48.0 )\n\tnAttr.setStorable(1)\n\n\t#- Now add the attribute to your node definition using the addAttribute()\n\t#- method.\n\n\t#- Add the attributes we have created to the node. For compound attributes,\n\t#- you only need to add the parent attribute.\n\ttransCircleNode.addAttribute( transCircleNode.input )\n\ttransCircleNode.addAttribute( transCircleNode.inputTranslate )\n\t#- TODO: Add the coumpound attribute to the list of the node' attribute.\n\t#- TODO: Since the child-parent relationship has been setup, we only need\n\t#- TODO: to add the parent attribute.\n\t#...\n\ttransCircleNode.addAttribute( transCircleNode.scale )\n\ttransCircleNode.addAttribute( transCircleNode.frames )\n\n\t#- Finally tell Maya how the information should flow through your node.\n\t#- This will also tell Maya how the dirty flag is propagated in your node\n\t#- and ultimatelly in the Maya DG. To do this, use the attributeAffects()\n\t#- method to link your node' attributes together.\n\n\t#- Set up a dependency between the input and the output. This will cause\n\t#- the output to be marked dirty when the input changes. The output will\n\t#- then be recomputed the next time the value of the output is requested.\n\n\t#- All input compound attributes' component will affects the output components\n\t#- of the output compound attributes' components. Including the parent attribute.\n\ttransCircleNode.attributeAffects( transCircleNode.inputTranslateX, transCircleNode.outputTranslateX )\n\ttransCircleNode.attributeAffects( transCircleNode.inputTranslateY, transCircleNode.outputTranslateY )\n\ttransCircleNode.attributeAffects( transCircleNode.inputTranslateZ, transCircleNode.outputTranslateZ )\n\ttransCircleNode.attributeAffects( transCircleNode.inputTranslate, transCircleNode.outputTranslateX )\n\ttransCircleNode.attributeAffects( transCircleNode.inputTranslate, transCircleNode.outputTranslateY )\n\ttransCircleNode.attributeAffects( transCircleNode.inputTranslate, transCircleNode.outputTranslateZ )\n\ttransCircleNode.attributeAffects( transCircleNode.inputTranslate, transCircleNode.outputTranslate )\n\n\t#- Other relationships,\n\ttransCircleNode.attributeAffects( transCircleNode.input, transCircleNode.outputTranslateX )\n\ttransCircleNode.attributeAffects( transCircleNode.input, transCircleNode.outputTranslateY )\n\ttransCircleNode.attributeAffects( transCircleNode.scale, transCircleNode.outputTranslateX )\n\ttransCircleNode.attributeAffects( transCircleNode.scale, transCircleNode.outputTranslateY )\n\ttransCircleNode.attributeAffects( transCircleNode.frames, transCircleNode.outputTranslateX )\n\ttransCircleNode.attributeAffects( transCircleNode.frames, transCircleNode.outputTranslateY )\n\n# Initialize the script plug-in\ndef initializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\t#- TODO: Register your node here, so Maya can use it and recognize it\n\t\t#- TODO: while reading/saving a file which has instance of this node type.\n\t\t#...\n\texcept:\n\t\tsys.stderr.write( \"Failed to register node: %s\" % kPluginNodeTypeName )\n\t\traise\n\n# Uninitialize the script plug-in\ndef uninitializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\t#- TODO: Unregister your node here, so Maya stops using it.\n\t\t#...\n\texcept:\n\t\tsys.stderr.write( \"Failed to deregister node: %s\" % kPluginNodeTypeName )\n\t\traise"
  },
  {
    "path": "03_Nodes/transCircleNode/Solution - C++/AEtransCircleTemplate.mel",
    "content": "//-\n// ==========================================================================\n// Copyright (C) 1995 - 2006 Autodesk, Inc. and/or its licensors.  All \n// rights reserved.\n//\n// The coded instructions, statements, computer programs, and/or related \n// material (collectively the \"Data\") in these files contain unpublished \n// information proprietary to Autodesk, Inc. (\"Autodesk\") and/or its \n// licensors, which is protected by U.S. and Canadian federal copyright \n// law and by international treaties.\n//\n// The Data is provided for use exclusively by You. You have the right \n// to use, modify, and incorporate this Data into other products for \n// purposes authorized by the Autodesk software license agreement, \n// without fee.\n//\n// The copyright notices in the Software and this entire statement, \n// including the above license grant, this restriction and the \n// following disclaimer, must be included in all copies of the \n// Software, in whole or in part, and all derivative works of \n// the Software, unless such copies or derivative works are solely \n// in the form of machine-executable object code generated by a \n// source language processor.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND. \n// AUTODESK DOES NOT MAKE AND HEREBY DISCLAIMS ANY EXPRESS OR IMPLIED \n// WARRANTIES INCLUDING, BUT NOT LIMITED TO, THE WARRANTIES OF \n// NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR \n// PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE, OR \n// TRADE PRACTICE. IN NO EVENT WILL AUTODESK AND/OR ITS LICENSORS \n// BE LIABLE FOR ANY LOST REVENUES, DATA, OR PROFITS, OR SPECIAL, \n// DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES, EVEN IF AUTODESK \n// AND/OR ITS LICENSORS HAS BEEN ADVISED OF THE POSSIBILITY \n// OR PROBABILITY OF SUCH DAMAGES.\n//\n// ==========================================================================\n//+\n\n//\n//  Creation Date:\tMarch 04, 2009\n// \n//\n//  Procedure Name:\n//\tAEtransCircleTemplate\n//\n//  Description:\n//\tCreates the attribute editor controls for the transCircle node\n//\n//  Input Value:\n//\tnodeName\n//\n//  Output Value:\n//\tNone\n//\n\n///////////////////////////////////////////////////////////////\n//\tExample : \n///////////////////////////////////////////////////////////////\n/*\nfile -f -new;\n\ncreateNode transCircle;\n\nopenAEWindow;\n*/\n\n\n\nglobal proc AEtransCircleTemplate( string $nodeName )\n{\n\t// Put our attributes into a scrolled layout field\n\n\teditorTemplate -beginScrollLayout;\n\n\t// The all go into the collapsable \"Parameters\" section\n\teditorTemplate -beginLayout \"Parameters\" -collapse false;\n\n\t   // Add a \"special\" control for the scale attribute that allow\n\t   // \"quick set\" options for scales of 5, 10, and 15.\n\t   editorTemplate -callCustom \"transCircleScaleNew\"\n\t   \t\t\t\t  \"transCircleScaleReplace\"\n\t\t\t\t\t  \"scale\";\n\n\t\t// Add the default controls for the scale and frames attributes\n\t\teditorTemplate -addControl \"scale\";\n\t\teditorTemplate -addControl \"frames\";\n\teditorTemplate -endLayout;\n\n\t// Create an \"Extras\" section and also add controls for any\n\t// attributes we have not explicitly mentioned.\n\teditorTemplate -addExtraControls;\n\n\teditorTemplate -endScrollLayout;\n\n\t// Tell the attribute editor not to display the attributes we\n\t// don't care about.\n\teditorTemplate -suppress \"inputTranslate\";\n\teditorTemplate -suppress \"input\";\n\teditorTemplate -suppress \"caching\";\n\teditorTemplate -suppress \"nodeState\";\n}\n\n\n///////////////////////////////////////////////////////////////\n//\n// Description : \n//\tThis procedure is called when the AE is editing a transCircle \n//\tnode for the first time.  Use this for creating the custom \n//\tlayout and controls\n//\nglobal proc transCircleScaleNew( string $attrName )\n{\n\t// Maya the \"quick set\" control for the scale attribute\n\tradioButtonGrp\n\t\t-label \"Quick Scale\"\n\t\t-numberOfRadioButtons 3\n\t\t-label1 \"Five\"\n\t\t-data1 5\n\t\t-label2 \"Ten\"\n\t\t-data2 10\n\t\t-label3 \"Fifteen\"\n\t\t-data3 15\n\t\tscaleGrp;\n\tconnectControl scaleGrp $attrName;\n}\n\n\n///////////////////////////////////////////////////////////////\n//\n// Description : \n//\tThis procedure is called whenever the AE is editing another \n//\ttransCircle type.  This procedure is necessary to reconnect\n//\tany controls with their associated attributes\n//\nglobal proc transCircleScaleReplace( string $attrName )\n{\n   // Install the connection between the radioButtonGrp and the\n   // actual scale attribute\n   connectControl scaleGrp $attrName;\n}\n"
  },
  {
    "path": "03_Nodes/transCircleNode/Solution - C++/pluginMain.cpp",
    "content": "//\n// Copyright (C)  \n// \n// File: pluginMain.cpp\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n\n#include <maya/MFnPlugin.h>\n#include \"transCircleNode.h\"\n\nMStatus initializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is loaded into Maya.  It \n//\t\tregisters all of the services that this plug-in provides with \n//\t\tMaya.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{ \n\tMStatus   status;\n\tMFnPlugin plugin( obj, \"\", \"2009\", \"Any\");\n\n\t// Add plug-in feature registration here\n\t//\n\tstatus = plugin.registerNode( \"transCircle\", transCircle::id,\n\t\ttransCircle::creator, transCircle::initialize );\n\tif (!status) {\n\t\tstatus.perror(\"registerNode\");\n\t\treturn status;\n\t}\n\n\treturn status;\n}\n\nMStatus uninitializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is unloaded from Maya. It \n//\t\tderegisters all of the services that it was providing.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{\n\tMStatus   status;\n\tMFnPlugin plugin( obj );\n\n\t// Add plug-in feature deregistration here\n\t//\n\tstatus = plugin.deregisterNode( transCircle::id );\n\tif (!status) {\n\t\tstatus.perror(\"deregisterNode\");\n\t\treturn status;\n\t}\n\n\treturn status;\n}\n"
  },
  {
    "path": "03_Nodes/transCircleNode/Solution - C++/transCircleNode.cpp",
    "content": "//\n// Copyright (C) \n// \n// File: \n//\n// Dependency Graph Node: \n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#include \"transCircleNode.h\"\n\n//- Assing a unique node ID to your new node class.\n//- Ask ADN or Autodesk product support to reserve IDs for your company. You can\n//- reserve ID by block of 64, 128, 256, or 512 consecutive ID.\n//-\n//- 0x80013 is a temporary ID reserved for development. Never use that ID in a\n//- production environment.\n/*static*/MTypeId\ttransCircle::id( 0x80013 );\n\n//- Instantiate the static attributes of your node class.\n/*static*/MObject\ttransCircle::input;        \n/*static*/MObject\ttransCircle::frames;\n/*static*/MObject\ttransCircle::scale;\n\n/*static*/MObject\ttransCircle::inputTranslateX;\n/*static*/MObject\ttransCircle::inputTranslateY;\n/*static*/MObject\ttransCircle::inputTranslateZ;\n/*static*/MObject\ttransCircle::inputTranslate;\n\n/*static*/MObject\ttransCircle::outputTranslateX;\n/*static*/MObject\ttransCircle::outputTranslateY;\n/*static*/MObject\ttransCircle::outputTranslateZ;\n/*static*/MObject\ttransCircle::outputTranslate;\n\n//- The initialize method is called to create and initialize all of the \n//- attributes and attribute dependencies for this node type. This is \n//- only called once when the node type is registered with Maya.\n//- Return Values: MS::kSuccess / MS::kFailure\n//-\nMStatus transCircle::initialize()\n{\n\t//- Create a numeric attribute using MFnNumericAttribute\n\tMFnNumericAttribute nAttr;\n\tinput = nAttr.create( \"input\", \"in\", MFnNumericData::kDouble, 0.0 );\n\t//- Attribute will be written to files when this type of node is stored\n\tnAttr.setStorable(true);\n\n\t//- Create individual input translate attributes\n\tinputTranslateX = nAttr.create( \"inputTranslateX\", \"itX\", MFnNumericData::kDouble, 0.0 );\n\tnAttr.setStorable(true);\n\n\tinputTranslateY = nAttr.create( \"inputTranslateY\", \"itY\", MFnNumericData::kDouble, 0.0 );\n\tnAttr.setStorable(true);\n\n\tinputTranslateZ = nAttr.create( \"inputTranslateZ\", \"itZ\", MFnNumericData::kDouble, 0.0 );\n\tnAttr.setStorable(true);\n\n\t//- Create compound input translate attributes by adding individual input translate attributes\n\tMFnCompoundAttribute comAttr;\n\tinputTranslate = comAttr.create(\"inputTranslate\",\"it\");\n\tcomAttr.addChild(inputTranslateX);\n\tcomAttr.addChild(inputTranslateY);\n\tcomAttr.addChild(inputTranslateZ);\n\tcomAttr.setStorable(true);\n\t\n\t//- Create individual output translate attributes\n\toutputTranslateX = nAttr.create( \"outputTranslateX\", \"otX\", MFnNumericData::kDouble, 0.0 );\n\tnAttr.setWritable(false);\n\tnAttr.setStorable(true);\n\n\toutputTranslateY = nAttr.create( \"outputTranslateY\", \"otY\",MFnNumericData::kDouble, 0.0 );\n\tnAttr.setWritable(false);\n\tnAttr.setStorable(true);\n\n\toutputTranslateZ = nAttr.create( \"outputTranslateZ\", \"otZ\", MFnNumericData::kDouble, 0.0 );\n\tnAttr.setWritable(false);\n\tnAttr.setStorable(true);\n\n\t//- Create compound output translate attributes by adding individual output translate attributes\n\toutputTranslate = comAttr.create( \"outputTranslate\", \"ot\" );\n\tcomAttr.addChild(outputTranslateX);\n\tcomAttr.addChild(outputTranslateY);\n\tcomAttr.addChild(outputTranslateZ);\n\tcomAttr.setWritable(false);\n\tcomAttr.setStorable(true);\n\n\t//- Create other attributes for our node\n\tscale = nAttr.create( \"scale\", \"sc\",MFnNumericData::kDouble, 10.0 );\n\tnAttr.setStorable(true);\n\n\tframes = nAttr.create( \"frames\", \"fr\", MFnNumericData::kDouble, 48.0 );\n\tnAttr.setStorable(true);\n\n\t//- Now add the attribute to your node definition using the addAttribute()\n\t//- method.\n\n\t//- Add the attributes we have created to the node. For compound attributes,\n\t//- you only need to add the parent attribute.\n\taddAttribute( input );\n\taddAttribute( inputTranslate );\n\taddAttribute( outputTranslate );\n\taddAttribute( scale );\n\taddAttribute( frames );\n\n\t//- Finally tell Maya how the information should flow through your node.\n\t//- This will also tell Maya how the dirty flag is propagated in your node\n\t//- and ultimatelly in the Maya DG. To do this, use the attributeAffects()\n\t//- method to link your node' attributes together.\n\n\t//- Set up a dependency between the input and the output. This will cause\n\t//- the output to be marked dirty when the input changes. The output will\n\t//- then be recomputed the next time the value of the output is requested.\n\n\t//- All input compound attributes' children will affect the individual children\n\t//- of the output compound attributes. Also, any change to the \n\t//- parent attribute is affecting the children of the output attribute and the \n\t//- output parent attribute as well.\n\tattributeAffects( inputTranslateX, outputTranslateX );\n\tattributeAffects( inputTranslateY, outputTranslateY );\n\tattributeAffects( inputTranslateZ, outputTranslateZ );\n\tattributeAffects( inputTranslate, outputTranslateX );\n\tattributeAffects( inputTranslate, outputTranslateY );\n\tattributeAffects( inputTranslate, outputTranslateZ );\n\tattributeAffects( inputTranslate, outputTranslate );\n\n\t//- Other relationships,\n\tattributeAffects( input, outputTranslateX );\n\tattributeAffects( input, outputTranslateY );\n\tattributeAffects( scale, outputTranslateX );\n\tattributeAffects( scale, outputTranslateY );\n\tattributeAffects( frames, outputTranslateX );\n\tattributeAffects( frames, outputTranslateY );\n\n\t//- Return success to Maya\n\treturn MS::kSuccess;\n}\n\n//- This method computes the value of the given output plug based\n//- on the values of the input attributes.\n//- Arguments:\n//- \tplug - the plug to compute\n//- \tdata - object that provides access to the attributes for this node\nMStatus transCircle::compute( const MPlug& plug, MDataBlock& data )\n{\n    MStatus stat;\n \n\t//- Check which output attribute we have been asked to compute. If this \n\t//- node doesn't know how to compute it, you must return MS::kUnknownParameter.\n\n\tbool k = ( plug == outputTranslateX ) |\n\t         ( plug == outputTranslateY ) |\n\t\t\t ( plug == outputTranslateZ ) |\n\t\t\t ( plug == outputTranslate );\n\tif (!k) return MS::kUnknownParameter;\n\n\t//- Get a handle on the input attributes that we will need for the\n\t//- computation. If the value is being supplied via a connection \n\t//- in the dependency graph, then this call will cause all upstream  \n\t//- connections to be evaluated so that the correct value is supplied.\n\n\tMDataHandle inputData = data.inputValue( input, &stat );\n\tMDataHandle scaleData = data.inputValue( scale, &stat );\n\tMDataHandle framesData = data.inputValue( frames, &stat );\n\n\t//- Retrieve value of current frame attribute,scale factor \n\t//- and number of frames for one circle \n\tdouble currentFrame = inputData.asDouble();\n\tdouble scaleFactor  = scaleData.asDouble();\n\tdouble framesPerCircle = framesData.asDouble();\n\n\t//- Retrieve values on individual input translate attribute\n\tMDataHandle inputTranslateXHandle = data.inputValue(inputTranslateX);\n\tdouble inputTranslateXData = inputTranslateXHandle.asDouble();\n\n\tMDataHandle inputTranslateYHandle = data.inputValue(inputTranslateY);\n\tdouble inputTranslateYData = inputTranslateYHandle.asDouble();\n\n\tMDataHandle inputTranslateZHandle = data.inputValue(inputTranslateZ);\n\tdouble inputTranslateZData = inputTranslateZHandle.asDouble();\n\n\t//- Calculate corresponding angle based on current frame \n\tdouble angle = 6.2831853 * ( currentFrame/framesPerCircle );\n\t\n\t//- The value of output translate is input translate value plus the value of circular movement  \n\tdouble outputTranslateXData = inputTranslateXData + (sin( angle ) * scaleFactor);\n\tdouble outputTranslateYData = inputTranslateYData + 1.0;\n\tdouble outputTranslateZData = inputTranslateZData + (cos( angle ) * scaleFactor);\n\n\t//- Get a handle on the output attributes and set the new value.\n\tMDataHandle outputTranslateXHandle = data.outputValue( outputTranslateX ); \n\toutputTranslateXHandle.set(outputTranslateXData);\n\n\tMDataHandle outputTranslateYHandle = data.outputValue( outputTranslateY ); \n\toutputTranslateYHandle.set(outputTranslateYData);\n\n\tMDataHandle outputTranslateZHandle = data.outputValue( outputTranslateZ ); \n\toutputTranslateZHandle.set(outputTranslateZData);\n\n\t//- Tell Maya the plug is now clean\n\tdata.setClean(plug);\n\n\t//- Return success to Maya\n    return MS::kSuccess;\n}\n\n"
  },
  {
    "path": "03_Nodes/transCircleNode/Solution - C++/transCircleNode.h",
    "content": "//\n// Copyright (C) \n// \n// File: \n//\n// Dependency Graph Node: \n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#pragma once\n\n//- Include Maya necessary headers for our class\n#include <maya/MPxNode.h>\n#include <maya/MString.h> \n#include <maya/MTypeId.h> \n#include <maya/MPlug.h>\n\n#include <maya/MFnNumericAttribute.h>\n#include <maya/MFnCompoundAttribute.h>\n#include <maya/MFnTypedAttribute.h>\n\n#include <maya/MDataBlock.h>\n#include <maya/MDataHandle.h>\n\n#include <string.h>\n#include <maya/MIOStream.h>\n#include <math.h>\n\n//- Derive a new class from the default Maya node proxy class.\nclass transCircle : public MPxNode\n{\npublic:\n\ttransCircle() {}\n\tvirtual\t~transCircle() {}\n\n\tvirtual MStatus\t\tcompute( const MPlug& plug, MDataBlock& data );\n\n\tstatic  MStatus\t\tinitialize();\n\tstatic  void*\t\tcreator() {\n\t\treturn new transCircle();\n\t}\n\npublic:\n\t// There needs to be a MObject handle declared for each attribute that\n\t// the node will have.  These handles are needed for getting and setting\n\t// the values later.\n\t//\n\tstatic  MObject\t\tinput;            // The input value.\n\n\t//- Compound attributes in Maya are build from several individual attributes. In\n\t//- our example the input compound attribute is made of inputTranslateX,\n\t//- inputTranslateY and inputTranslateZ. \n\tstatic  MObject\t\tinputTranslateX;  // The translate X value.  (input)\n\tstatic  MObject\t\tinputTranslateY;  // The translate Y value.  (input)\n\tstatic  MObject\t\tinputTranslateZ;  // The translate Z value.  (input)\n\tstatic  MObject\t\tinputTranslate;\n\n\tstatic  MObject\t\toutputTranslateX; // The translate X value.  (output)\n\tstatic  MObject\t\toutputTranslateY; // The translate Y value.  (output)\n\tstatic  MObject\t\toutputTranslateZ; // The translate Z value.  (output)\n\tstatic  MObject\t\toutputTranslate;\n\n\tstatic  MObject\t\tframes;           // Number of frames for one circle.\n\tstatic  MObject\t\tscale;            // Radius of circle.\n\n\t//- This is a unique node ID for your new node class. It is declared\n\t//- static because it is common to all instance of that class.\n\t//-\n\t//- The typeid is a unique 32bit identifier that describes this node.\n\t//- It is used to save and retrieve nodes of this type from the binary\n\t//- file format. If it is not unique, it will cause file IO problems.\n\tstatic  MTypeId\t\tid;\n};\n"
  },
  {
    "path": "03_Nodes/transCircleNode/Solution - C++/transCircleNode.mel",
    "content": "//-\n// ==========================================================================\n// Copyright (C) 1995 - 2006 Autodesk, Inc. and/or its licensors.  All \n// rights reserved.\n//\n// The coded instructions, statements, computer programs, and/or related \n// material (collectively the \"Data\") in these files contain unpublished \n// information proprietary to Autodesk, Inc. (\"Autodesk\") and/or its \n// licensors, which is protected by U.S. and Canadian federal copyright \n// law and by international treaties.\n//\n// The Data is provided for use exclusively by You. You have the right \n// to use, modify, and incorporate this Data into other products for \n// purposes authorized by the Autodesk software license agreement, \n// without fee.\n//\n// The copyright notices in the Software and this entire statement, \n// including the above license grant, this restriction and the \n// following disclaimer, must be included in all copies of the \n// Software, in whole or in part, and all derivative works of \n// the Software, unless such copies or derivative works are solely \n// in the form of machine-executable object code generated by a \n// source language processor.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND. \n// AUTODESK DOES NOT MAKE AND HEREBY DISCLAIMS ANY EXPRESS OR IMPLIED \n// WARRANTIES INCLUDING, BUT NOT LIMITED TO, THE WARRANTIES OF \n// NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR \n// PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE, OR \n// TRADE PRACTICE. IN NO EVENT WILL AUTODESK AND/OR ITS LICENSORS \n// BE LIABLE FOR ANY LOST REVENUES, DATA, OR PROFITS, OR SPECIAL, \n// DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES, EVEN IF AUTODESK \n// AND/OR ITS LICENSORS HAS BEEN ADVISED OF THE POSSIBILITY \n// OR PROBABILITY OF SUCH DAMAGES.\n//\n// ==========================================================================\n//+\n\ncreateNode transCircle -n circleNode1;\nsphere -n sphere1 -r 1;\nsphere -n sphere2 -r 2;\nconnectAttr sphere2.translate circleNode1.inputTranslate;\nconnectAttr circleNode1.outputTranslate sphere1.translate;\nconnectAttr time1.outTime circleNode1.input;\n"
  },
  {
    "path": "03_Nodes/transCircleNode/Solution - C++/transCircleNode.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 2012\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"transCircleNode\", \"transCircleNode.vcxproj\", \"{B6A0AEBE-B5EE-4EB6-BE01-F1738C49F587}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|x64 = Debug|x64\n\t\tRelease|x64 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{B6A0AEBE-B5EE-4EB6-BE01-F1738C49F587}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{B6A0AEBE-B5EE-4EB6-BE01-F1738C49F587}.Debug|x64.Build.0 = Debug|x64\n\t\t{B6A0AEBE-B5EE-4EB6-BE01-F1738C49F587}.Release|x64.ActiveCfg = Release|x64\n\t\t{B6A0AEBE-B5EE-4EB6-BE01-F1738C49F587}.Release|x64.Build.0 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "03_Nodes/transCircleNode/Solution - C++/transCircleNode.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{B6A0AEBE-B5EE-4EB6-BE01-F1738C49F587}</ProjectGuid>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup>\n    <_ProjectFileVersion>11.0.61030.0</_ProjectFileVersion>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <OutDir>Debug\\</OutDir>\n    <IntDir>Debug\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <OutDir>C:\\MayaAPITraining\\plug-ins\\</OutDir>\n    <TargetExt>.mll</TargetExt>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <OutDir>Release\\</OutDir>\n    <IntDir>Release\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2009\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/transCircleNode.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>..\\..\\..\\plug-ins\\transCircleNode.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2009\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/transCircleNode.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/transCircleNode.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2015\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/transCircleNode.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>C:\\MayaAPITraining\\plug-ins\\transCircleNode.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2015\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/transCircleNode.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/transCircleNode.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/transCircleNode.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\transCircleNode.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/transCircleNode.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/transCircleNode.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/transCircleNode.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\transCircleNode.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/transCircleNode.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/transCircleNode.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"pluginMain.cpp\" />\n    <ClCompile Include=\"transCircleNode.cpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"transCircleNode.h\" />\n  </ItemGroup>\n  <ItemGroup>\n    <None Include=\"AEtransCircleTemplate.mel\" />\n    <None Include=\"transCircleNode.mel\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "03_Nodes/transCircleNode/Solution - py/AEtransCircleTemplate.mel",
    "content": "//-\n// ==========================================================================\n// Copyright (C) 1995 - 2006 Autodesk, Inc. and/or its licensors.  All \n// rights reserved.\n//\n// The coded instructions, statements, computer programs, and/or related \n// material (collectively the \"Data\") in these files contain unpublished \n// information proprietary to Autodesk, Inc. (\"Autodesk\") and/or its \n// licensors, which is protected by U.S. and Canadian federal copyright \n// law and by international treaties.\n//\n// The Data is provided for use exclusively by You. You have the right \n// to use, modify, and incorporate this Data into other products for \n// purposes authorized by the Autodesk software license agreement, \n// without fee.\n//\n// The copyright notices in the Software and this entire statement, \n// including the above license grant, this restriction and the \n// following disclaimer, must be included in all copies of the \n// Software, in whole or in part, and all derivative works of \n// the Software, unless such copies or derivative works are solely \n// in the form of machine-executable object code generated by a \n// source language processor.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND. \n// AUTODESK DOES NOT MAKE AND HEREBY DISCLAIMS ANY EXPRESS OR IMPLIED \n// WARRANTIES INCLUDING, BUT NOT LIMITED TO, THE WARRANTIES OF \n// NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR \n// PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE, OR \n// TRADE PRACTICE. IN NO EVENT WILL AUTODESK AND/OR ITS LICENSORS \n// BE LIABLE FOR ANY LOST REVENUES, DATA, OR PROFITS, OR SPECIAL, \n// DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES, EVEN IF AUTODESK \n// AND/OR ITS LICENSORS HAS BEEN ADVISED OF THE POSSIBILITY \n// OR PROBABILITY OF SUCH DAMAGES.\n//\n// ==========================================================================\n//+\n\n//\n//  Creation Date:\tMarch 04, 2009\n// \n//\n//  Procedure Name:\n//\tAEtransCircleTemplate\n//\n//  Description:\n//\tCreates the attribute editor controls for the transCircle node\n//\n//  Input Value:\n//\tnodeName\n//\n//  Output Value:\n//\tNone\n//\n\n///////////////////////////////////////////////////////////////\n//\tExample : \n///////////////////////////////////////////////////////////////\n/*\nfile -f -new;\n\ncreateNode transCircle;\n\nopenAEWindow;\n*/\n\n\n\nglobal proc AEtransCircleTemplate( string $nodeName )\n{\n\t// Put our attributes into a scrolled layout field\n\n\teditorTemplate -beginScrollLayout;\n\n\t// They all go into the collapsable \"Parameters\" section\n\teditorTemplate -beginLayout \"Parameters\" -collapse false;\n\n\t   // Add a \"special\" control for the scale attribute that allow\n\t   // \"quick set\" options for scales of 5, 10, and 15.\n\t   editorTemplate -callCustom \"transCircleScaleNew\"\n\t   \t\t\t\t  \"transCircleScaleReplace\"\n\t\t\t\t\t  \"scale\";\n\n\t\t// Add the default controls for the scale and frames attributes\n\t\teditorTemplate -addControl \"scale\";\n\t\teditorTemplate -addControl \"frames\";\n\teditorTemplate -endLayout;\n\n\t// Create an \"Extras\" section and also add controls for any\n\t// attributes we have not explicitly mentioned.\n\teditorTemplate -addExtraControls;\n\n\teditorTemplate -endScrollLayout;\n\n\t// Tell the attribute editor not to display the attributes we\n\t// don't care about.\n\teditorTemplate -suppress \"inputTranslate\";\n\teditorTemplate -suppress \"input\";\n\teditorTemplate -suppress \"caching\";\n\teditorTemplate -suppress \"nodeState\";\n}\n\n\n///////////////////////////////////////////////////////////////\n//\n// Description : \n//\tThis procedure is called when the AE is editing a transCircle \n//\tnode for the first time.  Use this for creating the custom \n//\tlayout and controls\n//\nglobal proc transCircleScaleNew( string $attrName )\n{\n\t// Create the \"quick set\" control for the scale attribute\n\tradioButtonGrp\n\t\t-label \"Quick Scale\"\n\t\t-numberOfRadioButtons 3\n\t\t-label1 \"Five\"\n\t\t-data1 5\n\t\t-label2 \"Ten\"\n\t\t-data2 10\n\t\t-label3 \"Fifteen\"\n\t\t-data3 15\n\t\tscaleGrp;\n\tconnectControl scaleGrp $attrName;\n}\n\n\n///////////////////////////////////////////////////////////////\n//\n// Description : \n//\tThis procedure is called whenever the AE is editing another \n//\ttransCircle type.  This procedure is necessary to reconnect\n//\tany controls with their associated attributes\n//\nglobal proc transCircleScaleReplace( string $attrName )\n{\n   // Install the connection between the radioButtonGrp and the\n   // actual scale attribute\n   connectControl scaleGrp $attrName;\n}\n"
  },
  {
    "path": "03_Nodes/transCircleNode/Solution - py/transCircleNode.mel",
    "content": "//-\n// ==========================================================================\n// Copyright (C) 1995 - 2006 Autodesk, Inc. and/or its licensors.  All \n// rights reserved.\n//\n// The coded instructions, statements, computer programs, and/or related \n// material (collectively the \"Data\") in these files contain unpublished \n// information proprietary to Autodesk, Inc. (\"Autodesk\") and/or its \n// licensors, which is protected by U.S. and Canadian federal copyright \n// law and by international treaties.\n//\n// The Data is provided for use exclusively by You. You have the right \n// to use, modify, and incorporate this Data into other products for \n// purposes authorized by the Autodesk software license agreement, \n// without fee.\n//\n// The copyright notices in the Software and this entire statement, \n// including the above license grant, this restriction and the \n// following disclaimer, must be included in all copies of the \n// Software, in whole or in part, and all derivative works of \n// the Software, unless such copies or derivative works are solely \n// in the form of machine-executable object code generated by a \n// source language processor.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND. \n// AUTODESK DOES NOT MAKE AND HEREBY DISCLAIMS ANY EXPRESS OR IMPLIED \n// WARRANTIES INCLUDING, BUT NOT LIMITED TO, THE WARRANTIES OF \n// NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR \n// PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE, OR \n// TRADE PRACTICE. IN NO EVENT WILL AUTODESK AND/OR ITS LICENSORS \n// BE LIABLE FOR ANY LOST REVENUES, DATA, OR PROFITS, OR SPECIAL, \n// DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES, EVEN IF AUTODESK \n// AND/OR ITS LICENSORS HAS BEEN ADVISED OF THE POSSIBILITY \n// OR PROBABILITY OF SUCH DAMAGES.\n//\n// ==========================================================================\n//+\n\ncreateNode transCircle -n circleNode1;\nsphere -n sphere1 -r 1;\nsphere -n sphere2 -r 2;\nconnectAttr sphere2.translate circleNode1.inputTranslate;\nconnectAttr circleNode1.outputTranslate sphere1.translate;\nconnectAttr time1.outTime circleNode1.input;\n"
  },
  {
    "path": "03_Nodes/transCircleNode/Solution - py/transCircleNode.py",
    "content": "#\n# Copyright (C) \n# \n# File: transCircleNode.py\n#\n# Dependency Graph Node: \n#\n# Author: Maya Plug-in Wizard 2.0\n#\nimport sys, math\nimport maya.OpenMaya as OpenMaya\nimport maya.OpenMayaMPx as OpenMayaMPx\n\n#- Assing a unique node ID to your new node class.\n#- Ask ADN or Autodesk product support to reserve IDs for your company. You can\n#- reserve ID by block of 64, 128, 256, or 512 consecutive ID.\n#-\n#- 0x80013 is a temporary ID reserved for development. Never use that ID in a\n#- production environement.\nkPluginNodeTypeName = \"transCircle\"\ntransCircleNodeId = OpenMaya.MTypeId(0x80013)\n\n# Node definition\nclass transCircleNode(OpenMayaMPx.MPxNode):\n\t# Node attributes\n\t#- Compound attributes in Maya are build from several individual attributes. In\n\t#- our example the translation vector is made of the x,y,z attributes, and the\n\t#- compound attribute itself.\n\tinputTranslateX = OpenMaya.MObject() # The translate X value.  (input)\n\tinputTranslateY = OpenMaya.MObject() # The translate Y value.  (input)\n\tinputTranslateZ = OpenMaya.MObject() # The translate Z value.  (input)\n\tinputTranslate = OpenMaya.MObject()\n\n\toutputTranslateX = OpenMaya.MObject() # The translate X value.  (output)\n\toutputTranslateY = OpenMaya.MObject() # The translate Y value.  (output)\n\toutputTranslateZ = OpenMaya.MObject() # The translate Z value.  (output)\n\toutputTranslate = OpenMaya.MObject()\n\n\tframes = OpenMaya.MObject() # Number of frames for one circle.\n\tscale = OpenMaya.MObject() # Radius of circle.\n\t\n\tdef __init__(self):\n\t\tOpenMayaMPx.MPxNode.__init__(self)\n\t\t\n\t#- This method computes the value of the given output plug based\n\t#- on the values of the input attributes.\n\t#- Arguments:\n\t#- \tplug - the plug to compute\n\t#- \tdataBlock - object that provides access to the attributes for this node\n\tdef compute(self,plug,dataBlock):\n\t\t#- Check which output attribute we have been asked to compute. If this \n\t\t#- node doesn't know how to compute it, you must return MS::kUnknownParameter.\n\n\t\tif ( plug == transCircleNode.outputTranslateX or plug == transCircleNode.outputTranslateY or plug == transCircleNode.outputTranslateZ or plug == transCircleNode.outputTranslate ):\n\t\t\t\n\n\t\t\t#- Get a handle on the input attributes that we will need for the\n\t\t\t#- computation. If the value is being supplied via a connection \n\t\t\t#- in the dependency graph, then this call will cause all upstream  \n\t\t\t#- connections to be evaluated so that the correct value is supplied.\n\n\t\t\tinputData = dataBlock.inputValue( transCircleNode.input )\n\t\t\tscaleData = dataBlock.inputValue( transCircleNode.scale )\n\t\t\tframesData = dataBlock.inputValue( transCircleNode.frames )\n\n\t\t\t#- Retrieve value of current frame attribute,scale factor \n\t\t\t#- and number of frames for one circle \n\t\t\tcurrentFrame = inputData.asDouble()\n\t\t\tscaleFactor  = scaleData.asDouble()\n\t\t\tframesPerCircle = framesData.asDouble()\n\t\t\t\n\t\t\t#- Retrieve values on individual input translate attribute\n\t\t\tinputTranslateXHandle = dataBlock.inputValue(transCircleNode.inputTranslateX)\n\t\t\tinputTranslateXData = inputTranslateXHandle.asDouble()\n\n\t\t\tinputTranslateYHandle = dataBlock.inputValue(transCircleNode.inputTranslateY)\n\t\t\tinputTranslateYData = inputTranslateYHandle.asDouble()\n\n\t\t\tinputTranslateZHandle = dataBlock.inputValue(transCircleNode.inputTranslateZ)\n\t\t\tinputTranslateZData = inputTranslateZHandle.asDouble()\n\n\t\t\t#- Calculate corresponding angle based on current frame \n\t\t\tangle = 6.2831853 * ( currentFrame/framesPerCircle )\n\n\t\t\t#- The value of output translate is input translate value plus the value of circular movement  \n\t\t\toutputTranslateXData = inputTranslateXData + (math.sin( angle ) * scaleFactor)\n\t\t\toutputTranslateYData = inputTranslateYData + 1.0\n\t\t\toutputTranslateZData = inputTranslateZData + (math.cos( angle ) * scaleFactor)\n\n\t\t\t#- Get a handle on the output attributes and set the new value.\n\t\t\toutputTranslateXHandle = dataBlock.outputValue( transCircleNode.outputTranslateX ) \n\t\t\toutputTranslateXHandle.setDouble(outputTranslateXData)\n\n\t\t\toutputTranslateYHandle = dataBlock.outputValue( transCircleNode.outputTranslateY ) \n\t\t\toutputTranslateYHandle.setDouble(outputTranslateYData)\n\n\t\t\toutputTranslateZHandle = dataBlock.outputValue( transCircleNode.outputTranslateZ ) \n\t\t\toutputTranslateZHandle.setDouble(outputTranslateZData)\n\n\t\t\t#- Tell Maya the plug is now clean\n\t\t\tdataBlock.setClean( plug )\n\t\telse:\n\t\t\treturn OpenMaya.kUnknownParameter\n\n# Creator\ndef nodeCreator():\n\treturn OpenMayaMPx.asMPxPtr( transCircleNode() )\n\n#- The initialize method is called to create and initialize all of the \n#- attributes and attribute dependencies for this node type. This is \n#- only called once when the node type is registered with Maya.\n#-\ndef nodeInitializer():\n\t#- Create a generic attribute using MFnNumericAttribute\n\tnAttr = OpenMaya.MFnNumericAttribute()\n\ttransCircleNode.input = nAttr.create( \"input\", \"in\", OpenMaya.MFnNumericData.kDouble, 0.0 )\n\t#- Attribute will be written to files when this type of node is stored\n\tnAttr.setStorable(1)\n\n\t#- Create individual input translate attributes\n\ttransCircleNode.inputTranslateX = nAttr.create( \"inputTranslateX\", \"itX\", OpenMaya.MFnNumericData.kDouble, 0.0 )\n\tnAttr.setStorable(1)\n\n\ttransCircleNode.inputTranslateY = nAttr.create( \"inputTranslateY\", \"itY\", OpenMaya.MFnNumericData.kDouble, 0.0 )\n\tnAttr.setStorable(1)\n\n\ttransCircleNode.inputTranslateZ = nAttr.create( \"inputTranslateZ\", \"itZ\", OpenMaya.MFnNumericData.kDouble, 0.0 )\n\tnAttr.setStorable(1)\n\n\t#- Create compound input translate attributes and add individual input translate attributes\n\tcomAttr = OpenMaya.MFnCompoundAttribute()\n\ttransCircleNode.inputTranslate = comAttr.create(\"inputTranslate\",\"it\")\n\tcomAttr.addChild(transCircleNode.inputTranslateX)\n\tcomAttr.addChild(transCircleNode.inputTranslateY)\n\tcomAttr.addChild(transCircleNode.inputTranslateZ)\n\tcomAttr.setStorable(1)\n\n\t#- Create individual output translate attributes\n\ttransCircleNode.outputTranslateX = nAttr.create( \"outputTranslateX\", \"otX\", OpenMaya.MFnNumericData.kDouble, 0.0 )\n\tnAttr.setWritable(0)\n\tnAttr.setStorable(1)\n\n\ttransCircleNode.outputTranslateY = nAttr.create( \"outputTranslateY\", \"otY\", OpenMaya.MFnNumericData.kDouble, 0.0 )\n\tnAttr.setWritable(0)\n\tnAttr.setStorable(1)\n\n\ttransCircleNode.outputTranslateZ = nAttr.create( \"outputTranslateZ\", \"otZ\", OpenMaya.MFnNumericData.kDouble, 0.0 )\n\tnAttr.setWritable(0)\n\tnAttr.setStorable(1)\n\n\t#- Create compound output translate attributes and add individual output translate attributes\n\ttransCircleNode.outputTranslate = comAttr.create(\"outputTranslate\",\"ot\")\n\tcomAttr.addChild(transCircleNode.outputTranslateX)\n\tcomAttr.addChild(transCircleNode.outputTranslateY)\n\tcomAttr.addChild(transCircleNode.outputTranslateZ)\n\tcomAttr.setWritable(0)\n\tcomAttr.setStorable(1)\n\n\t#- Create other attributes for our node\n\ttransCircleNode.scale = nAttr.create( \"scale\", \"sc\", OpenMaya.MFnNumericData.kDouble, 10.0 )\n\tnAttr.setStorable(1)\n\n\ttransCircleNode.frames = nAttr.create( \"frames\", \"fr\", OpenMaya.MFnNumericData.kDouble, 48.0 )\n\tnAttr.setStorable(1)\n\n\t#- Now add the attribute to your node definition using the addAttribute()\n\t#- method.\n\n\t#- Add the attributes we have created to the node. For compound attributes,\n\t#- you only need to add the parent attribute.\n\ttransCircleNode.addAttribute( transCircleNode.input )\n\ttransCircleNode.addAttribute( transCircleNode.inputTranslate )\n\ttransCircleNode.addAttribute( transCircleNode.outputTranslate )\n\ttransCircleNode.addAttribute( transCircleNode.scale )\n\ttransCircleNode.addAttribute( transCircleNode.frames )\n\n\t#- Finally tell Maya how the information should flow through your node.\n\t#- This will also tell Maya how the dirty flag is propagated in your node\n\t#- and ultimatelly in the Maya DG. To do this, use the attributeAffects()\n\t#- method to link your node' attributes together.\n\n\t#- Set up a dependency between the input and the output. This will cause\n\t#- the output to be marked dirty when the input changes. The output will\n\t#- then be recomputed the next time the value of the output is requested.\n\n\t#- All input compound attributes' component will affects the output components\n\t#- of the output compound attributes' components. Including the parent attribute.\n\ttransCircleNode.attributeAffects( transCircleNode.inputTranslateX, transCircleNode.outputTranslateX )\n\ttransCircleNode.attributeAffects( transCircleNode.inputTranslateY, transCircleNode.outputTranslateY )\n\ttransCircleNode.attributeAffects( transCircleNode.inputTranslateZ, transCircleNode.outputTranslateZ )\n\ttransCircleNode.attributeAffects( transCircleNode.inputTranslate, transCircleNode.outputTranslateX )\n\ttransCircleNode.attributeAffects( transCircleNode.inputTranslate, transCircleNode.outputTranslateY )\n\ttransCircleNode.attributeAffects( transCircleNode.inputTranslate, transCircleNode.outputTranslateZ )\n\ttransCircleNode.attributeAffects( transCircleNode.inputTranslate, transCircleNode.outputTranslate )\n\n\t#- Other relationships,\n\ttransCircleNode.attributeAffects( transCircleNode.input, transCircleNode.outputTranslateX )\n\ttransCircleNode.attributeAffects( transCircleNode.input, transCircleNode.outputTranslateY )\n\ttransCircleNode.attributeAffects( transCircleNode.scale, transCircleNode.outputTranslateX )\n\ttransCircleNode.attributeAffects( transCircleNode.scale, transCircleNode.outputTranslateY )\n\ttransCircleNode.attributeAffects( transCircleNode.frames, transCircleNode.outputTranslateX )\n\ttransCircleNode.attributeAffects( transCircleNode.frames, transCircleNode.outputTranslateY )\n\n# Initialize the script plug-in\ndef initializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\tmplugin.registerNode( kPluginNodeTypeName, transCircleNodeId, nodeCreator, nodeInitializer )\n\texcept:\n\t\tsys.stderr.write( \"Failed to register node: %s\" % kPluginNodeTypeName )\n\t\traise\n\n# Uninitialize the script plug-in\ndef uninitializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\tmplugin.deregisterNode( transCircleNodeId )\n\texcept:\n\t\tsys.stderr.write( \"Failed to deregister node: %s\" % kPluginNodeTypeName )\n\t\traise"
  },
  {
    "path": "04_NodeAttributes/dynNode/Exercise - C++/DynNode.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 2012\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"DynNode\", \"DynNode.vcxproj\", \"{CC44F4F1-DFF1-466C-AEC2-1F36FB80F568}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|x64 = Debug|x64\n\t\tRelease|x64 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{CC44F4F1-DFF1-466C-AEC2-1F36FB80F568}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{CC44F4F1-DFF1-466C-AEC2-1F36FB80F568}.Debug|x64.Build.0 = Debug|x64\n\t\t{CC44F4F1-DFF1-466C-AEC2-1F36FB80F568}.Release|x64.ActiveCfg = Release|x64\n\t\t{CC44F4F1-DFF1-466C-AEC2-1F36FB80F568}.Release|x64.Build.0 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "04_NodeAttributes/dynNode/Exercise - C++/DynNode.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{CC44F4F1-DFF1-466C-AEC2-1F36FB80F568}</ProjectGuid>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup>\n    <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">Debug\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">Debug\\</IntDir>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Release\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Release\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <OutDir>C:\\MayaAPITraining\\plug-ins\\</OutDir>\n    <TargetExt>.mll</TargetExt>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2009\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>C:\\My Documents\\maya\\2009\\plug-ins\\dynNode.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2009\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2015\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>C:\\MayaAPITraining\\plug-ins\\dynNode.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2015\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"dynNode.cpp\" />\n    <ClCompile Include=\"pluginMain.cpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"dynNode.h\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "04_NodeAttributes/dynNode/Exercise - C++/dynNode.cpp",
    "content": "//\n// Copyright (C) \n// \n// File: dynNode.cpp\n//\n// Dependency Graph Node: dynNode\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n\n#include \"dynNode.h\"\n#include <maya/MGlobal.h>\n\n//- Assigning a unique node ID to your new node class.\n//- Ask ADN or Autodesk product support to reserve IDs for your company. You can\n//- reserve ID by block of 64, 128, 256, or 512 consecutive ID.\n//-\n//- 0x00001 is a temporary ID reserved for development. Never use that ID in a\n//- production environment.\n/*static*/ MTypeId dynNode::id( 0x00001 );\n\n//- Instantiate the static attributes of your node class.\n/*static*/ MObject dynNode::input;        \n/*static*/ MObject dynNode::output;   \n\t \n\n//- No MPxNode member function can be called from the MPxNode constructor. \n//- The postConstructor will get called immediately after the constructor \n//- so it is safe to call any MPxNode member function in postConstructor().\n//- TODO: Implement postConstructor(), create dynamic attribute and add it onto the node\n//...\n//...\n//...\n//...\n\n\n//- The setDependentsDirty() method allows attributeAffects relationships\n//- in a much more general way than via MPxNode::attributeAffects\n//- which is limited to static attributes only.\n//- The setDependentsDirty() method allows relationships to be established\n//- between any combination of dynamic and static attributes.\n//-\n//- Within a setDependentsDirty(), you get passed in the\n//- plug (the first argument \"dirtyPlug\"), which is being set dirty, \n//- and then, based upon which plug it is,you may choose to dirty any other \n//- plugs by adding them to the affectedPlugs list (the second argument \"plugArray\").\n//- Arguments:\n//- \tdirtyPlug - the plug which Maya sets dirty\n//- \tplugArray - an array of plugs which are affected by the first plug\n//- TODO: Implement setDependentsDirty() so that the dynamic attribute is affecting\n//- TODO: attribute \"output\"\n//...\n//...\n//...\n//...\n\n\n//- The initialize method is called to create and initialize all of the \n//- attributes and attribute dependencies for this node type. This is \n//- only called once when the node type is registered with Maya.\n//- Return Values: MS::kSuccess / MS::kFailure\n//-\nMStatus dynNode::initialize()\n{\n\t//- Initialize a float input attribute using the MFnNumericAttribute\n\t//- class. Make that attribute definition saved into Maya file (setStorable),\n\t//- and selectable in the channel box (setKeyable).\n\n\t//- Create a generic attribute using MFnNumericAttribute\n\tMFnNumericAttribute nAttr;\n\tdynNode::input = nAttr.create( \"input\", \"in\", MFnNumericData::kFloat, 0.0 );\n\t//- Attribute will be written to files when this type of node is stored\n \tnAttr.setStorable(true);\n\t//- Attribute is keyable and will show up in the channel box\n \tnAttr.setKeyable(true);\n\n\t//- Initialize a float output attribute using the MFnNumericAttribute\n\t//- class. Make that attribute is not saved into Maya file.\n\tdynNode::output = nAttr.create( \"output\", \"out\", MFnNumericData::kFloat, 0.0 );\n\t//- Attribute will not be written to files when this type of node is stored\n\tnAttr.setStorable(false);\n\n\t//- Now add the attribute to your node definition using the addAttribute()\n\t//- method.\n\taddAttribute( dynNode::input );\t\n\taddAttribute( dynNode::output );\n\t\n\t//- Finally tell Maya how the information should flow through your node.\n\t//- This will also tell Maya how the dirty flag is propagated in your node\n\t//- and ultimately in the Maya DG. To do this, use the attributeAffects()\n\t//- method to link your node' attributes together.\n\t//- Set up a dependency between the input and the output. This will cause\n\t//- the output to be marked dirty when the input changes. The output will\n\t//- then be recomputed the next time the value of the output is requested.\n\tattributeAffects( dynNode::input, dynNode::output );\n\n\t//- Return success to Maya\n\treturn MS::kSuccess;\n}\n\n//- This method computes the value of the given output plug based\n//- on the values of the input attributes.\n//- Arguments:\n//- \tplug - the plug to compute\n//- \tdata - object that provides access to the attributes for this node\nMStatus dynNode::compute( const MPlug& plug, MDataBlock& data )\n{\n\tMStatus returnStatus;\n \n\t//- Check which output attribute we have been asked to compute. If this \n\t//- node doesn't know how to compute it, you must return MS::kUnknownParameter.\n\n\tif( plug == dynNode::output )\n\t{\n\t\t//- Get a handle to the input attribute that we will need for the\n\t\t//- computation. If the value is being supplied via a connection \n\t\t//- in the dependency graph, then this call will cause all upstream  \n\t\t//- connections to be evaluated so that the correct value is supplied.\n\t\tMDataHandle inputData = data.inputValue( dynNode::input, &returnStatus );\n\n\t\t//- Read the input value from the handle.\n\t\tfloat inputValue = inputData.asFloat();\n\n\t\t\n\t\t//- Since output is affected by the dynamic attribute too, \n\t\t//- retrieve the dynamic attribute value\n\t\t//- TODO: Get a handle to the dynamic attribute and assign its\n\t\t//- TODO: value to a float variable \"dynValue\"\n\t\t//...\n\t\t//...\n\n\t\t//- Get a handle to the output attribute. This is similar to the\n\t\t//- \"inputValue\" call above except that no dependency graph \n\t\t//- computation will be done as a result of this call.\n\n\t\t//- Get a handle on the output attribute\n\t\tMDataHandle outputHandle = data.outputValue( dynNode::output );\n\n\t\t//- Set the new output value to the handle.\n\t\toutputHandle.set( inputValue + dynValue );\n\n\t\t//- Return success to Maya\n\t\treturn MS::kSuccess;\n\t}\n\n\t//- Tell Maya that we do not know how to handle this plug, but let's give a chance\n\t//- to our parent class to evaluate it.\n\treturn MS::kUnknownParameter;\n}\n"
  },
  {
    "path": "04_NodeAttributes/dynNode/Exercise - C++/dynNode.h",
    "content": "//\n// Copyright (C) \n// \n// File: dynNode.h\n//\n// Dependency Graph Node: dynNode\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#pragma once\n\n//- Include Maya necessary headers for our class\n#include <maya/MPxNode.h>\n#include <maya/MFnNumericAttribute.h>\n#include <maya/MFnTypedAttribute.h>\n#include <maya/MFnStringData.h>\n#include <maya/MTypeId.h> \n#include <maya/MPlug.h>\n#include <maya/MDataBlock.h>\n#include <maya/MDataHandle.h>\n#include <maya/MFnDependencyNode.h>\n#include <maya/MPlugArray.h>\n#include <maya/MFnDependencyNode.h>\n\n//- Derive a new class from the default Maya node proxy class.\nclass dynNode : public MPxNode\n{\npublic:\n\tdynNode() {\n\t\t//- Never do anything here which would affect Maya.\n\t\t//- Instead implement the virtual postConstructor() method.\n\t}\n\tvirtual ~dynNode() {}\n\n\t//- Declare the virtual compute() method.\n\tvirtual MStatus\t\tcompute( const MPlug& plug, MDataBlock& data );\n\n\t//- Declare/implement the static creator method.\n\t//- This method exists to give Maya a way to create new objects\n\t//- of this type. \n\tstatic  void*\t\tcreator() {\n\t\treturn new dynNode();\n\t}\n\n\t//- Declare the static initialize() method.\n\tstatic  MStatus\t\tinitialize();\n\n\t///- TODO: Declare the virtual postConstructor() method.\n\t//...\n\t\n\t//- TODO: Declare the virtual setDependentsDirty() method.\n\t//...\n\n\npublic:\n\t//- There needs to be a MObject handle declared for each attribute that\n\t//- the node will have.  These handles are needed for getting and setting\n\t//- the values later.\n\t//\n\tstatic  MObject\t\tinput;\t\t// input attribute\n\tstatic  MObject\t\toutput;\t\t// output attribute\n\n\t//- TODO: Declare a member variable to store the dynamic attribute \n\t//...\n\n\t//- This is a unique node ID for your new node class. It is declared\n\t//- static because it is common to all instance of that class.\n\t//-\n\t//- The typeid is a unique 32bit identifier that describes this node.\n\t//- It is used to save and retrieve nodes of this type from the binary\n\t//- file format. If it is not unique, it will cause file IO problems.\n\tstatic\tMTypeId\t\tid;\n};\n"
  },
  {
    "path": "04_NodeAttributes/dynNode/Exercise - C++/pluginMain.cpp",
    "content": "//\n// Copyright (C)  \n// \n// File: pluginMain.cpp\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n\n#include <maya/MFnPlugin.h>\n#include \"dynNode.h\"\n\nMStatus initializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is loaded into Maya.  It \n//\t\tregisters all of the services that this plug-in provides with \n//\t\tMaya.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{ \n\tMStatus   status;\n\tMFnPlugin plugin( obj, \"\", \"2008\", \"Any\");\n\n\t//- Register your node here, so Maya can use it and recognize it\n\t//- while reading/saving a file which has instance of this node type.\n\tstatus = plugin.registerNode( \"dynNode\", dynNode::id, dynNode::creator, dynNode::initialize );\n\n\tif (!status) {\n\t\tstatus.perror(\"registerNode\");\n\t\treturn status;\n\t}\n\treturn status;\n}\n\nMStatus uninitializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is unloaded from Maya. It \n//\t\tderegisters all of the services that it was providing.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{\n\tMStatus   status;\n\tMFnPlugin plugin( obj );\n\n\t\n\t//- Unregister your node here, so Maya stops using it.\n\tstatus = plugin.deregisterNode( dynNode::id );\n\n\tif (!status) {\n\t\tstatus.perror(\"deregisterNode\");\n\t\treturn status;\n\t}\n\n\treturn status;\n}\n"
  },
  {
    "path": "04_NodeAttributes/dynNode/Exercise - py/dynNode.py",
    "content": "# Copyright (C) \n# \n# Author: Autodesk Developer Network\n\n#For this exercise, search for the TODO keywords and follow the instructions in\n#comments. If you are unsure of what you need to do, feel free to ask the instructor\n#or look into the solution folder.\n#Each #... line is a line of code you need to write or complete.\n\nimport maya.OpenMaya as OpenMaya\nimport maya.OpenMayaMPx as OpenMayaMPx\nimport sys\n\n#- Assigning a unique node ID to your new node class.\n#- Ask ADN or Autodesk product support to reserve IDs for your company. You can\n#- reserve ID by block of 64, 128, 256, or 512 consecutive ID.\n#-\n#- 0x00001 is a temporary ID for reserved for development. Never use that ID in a\n#- production environment.\n\nkPluginNodeTypeName = \"dynNode\"\ndynNodeId = OpenMaya.MTypeId(0x00001)\n\n# Node definition\nclass dynNode(OpenMayaMPx.MPxNode):\n\n\taInput = OpenMaya.MObject()        \n\taOutput = OpenMaya.MObject()  \n\tdynAttr = OpenMaya.MObject()  \n\t\t\n\tdef __init__(self):\n\t\tOpenMayaMPx.MPxNode.__init__(self)\n\n\t#- No MPxNode member function can be called from the MPxNode constructor. \n\t#- The postConstructor will get called immediately after the constructor \n\t#- so it is safe to call any MPxNode member function in postConstructor().\n\t#- TODO: Implement postConstructor(), create dynamic attribute and add it onto the node\n\t#...\n\t#...\n\t#...\n\t#...\n\n\n\t#- The setDependentsDirty() method allows attributeAffects relationships\n\t#- in a much more general way than via MPxNode::attributeAffects\n\t#- which is limited to static attributes only.\n\t#- The setDependentsDirty() method allows relationships to be established\n\t#- between any combination of dynamic and static attributes.\n\t#-\n\t#- Within a setDependentsDirty(), you get passed in the\n\t#- plug (the first argument \"dirtyPlug\"), which is being set dirty, \n\t#- and then, based upon which plug it is,you may choose to dirty any other \n\t#- plugs by adding them to the affectedPlugs list (the second argument \"plugArray\").\n\t#- Arguments:\n\t#- \tdirtyPlug - the plug which Maya sets dirty\n\t#- \tplugArray - an array of plugs which are affected by the first plug\n\t#- TODO: Implement setDependentsDirty() so that the dynamic attribute is affecting\n\t#- TODO: attribute \"output\"\n\t#...\n\t#...\n\t#...\n\t#...\n\n\n\t\n\t#- This method computes the value of the given output plug based\n\t#- on the values of the input attributes.\n\t#- Arguments:\n\t#- \tplug - the plug to compute\n\t#- \tdata - object that provides access to the attributes for this node\n\tdef compute(self,plug,data):\n\t\t#- Check which output attribute we have been asked to compute. If this \n\t\t#- node doesn't know how to compute it, you must return MS::kUnknownParameter.\n\n\t\tif plug == dynNode.aOutput:\n\t\t\t#- Get a handle to the input attribute that we will need for the\n\t\t\t#- computation. If the value is being supplied via a connection \n\t\t\t#- in the dependency graph, then this call will cause all upstream  \n\t\t\t#- connections to be evaluated so that the correct value is supplied.\n\t\t\tinputData = data.inputValue(dynNode.aInput)\n\t\t\t#- Read the input value from the handle.\n\n\t\t\tinputValue = inputData.asFloat()\n\t\t\t\n\t\t\t#- Since output is affected by the dynamic attribute too, \n\t\t\t#- retrieve the dynamic attribute value\n\t\t\t#- TODO: Get a handle to the dynamic attribute and assign its\n\t\t\t#- TODO: value to a float variable \"dynValue\"\n\t\t\t#...\n\t\t\t#...\n\t\t\t\n\t\t\t#- Get a handle to the output attribute. This is similar to the\n\t\t\t#- \"inputValue\" call above except that no dependency graph \n\t\t\t#- computation will be done as a result of this call.\n\n\t\t\t#- Get a handle on the aOutput attribute\n\t\t\toutputHandle = data.outputValue(dynNode.aOutput)\n\t\t\t\n\t\t\t#- Set the new output value to the handle.\n\t\t\toutputHandle.setFloat( inputValue + dynValue )\n\t\t\t\n\t\t#- Tell Maya that we do not know how to handle this plug, but let's give a chance\n\t\t#- to our parent class to evaluate it.\n\t\telse:\n\t\t\treturn OpenMaya.kUnknownParameter\n\t\t\t\n\t\n# Creator\ndef nodeCreator():\n\treturn OpenMayaMPx.asMPxPtr( dynNode() )\n\n\n#- The initialize method is called to create and initialize all of the \n#- attributes and attribute dependencies for this node type. This is \n#- only called once when the node type is registered with Maya.\n#- Return Values: MS::kSuccess / MS::kFailure\ndef nodeInitializer():\n\n\t#- Initialize a float input attribute using the MFnNumericAttribute\n\t#- class. Make that attribute definition saved into Maya file (setStorable),\n\t#- and selectable in the channel box (setKeyable).\n\n\t#- Create a generic attribute using MFnNumericAttribute\n\tnAttr = OpenMaya.MFnNumericAttribute()\n\tdynNode.aInput = nAttr.create( \"input\", \"in\", OpenMaya.MFnNumericData.kFloat, 0.0 )\n\t#- Attribute will be written to files when this type of node is stored\n \tnAttr.setStorable(True)\n\t#- Attribute is keyable and will show up in the channel box\n \tnAttr.setKeyable(True)\n\n\t#- Initialize a float output attribute using the MFnNumericAttribute\n\t#- class. Make that attribute is not saved into Maya file.\n\tdynNode.aOutput = nAttr.create( \"output\", \"out\", OpenMaya.MFnNumericData.kFloat, 0.0 )\n\t#- Attribute will not be written to files when this type of node is stored\n\tnAttr.setStorable(False)\n\n\t#- Now add the attribute to your node definition using the addAttribute()\n\t#- method.\n\tdynNode.addAttribute( dynNode.aInput )\n\tdynNode.addAttribute( dynNode.aOutput )\n\t\n\t#- Finally tell Maya how the information should flow through your node.\n\t#- This will also tell Maya how the dirty flag is propagated in your node\n\t#- and ultimately in the Maya DG. To do this, use the attributeAffects()\n\t#- method to link your node' attributes together.\n\t#- Set up a dependency between the input and the output. This will cause\n\t#- the output to be marked dirty when the input changes. The output will\n\t#- then be recomputed the next time the value of the output is requested.\n\tdynNode.attributeAffects( dynNode.aInput, dynNode.aOutput )\n\n# Initialize the script plug-in\ndef initializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\tmplugin.registerNode( kPluginNodeTypeName, dynNodeId, nodeCreator, nodeInitializer )\n\texcept:\n\t\tsys.stderr.write( \"Failed to register node: %s\" % kPluginNodeTypeName )\n\t\traise\n\n# Uninitialize the script plug-in\ndef uninitializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\tmplugin.deregisterNode( dynNodeId )\n\texcept:\n\t\tsys.stderr.write( \"Failed to deregister node: %s\" % kPluginNodeTypeName )\n\t\traise"
  },
  {
    "path": "04_NodeAttributes/dynNode/Solution - C++/DynNode.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 2012\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"DynNode\", \"DynNode.vcxproj\", \"{CC44F4F1-DFF1-466C-AEC2-1F36FB80F568}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|x64 = Debug|x64\n\t\tRelease|x64 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{CC44F4F1-DFF1-466C-AEC2-1F36FB80F568}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{CC44F4F1-DFF1-466C-AEC2-1F36FB80F568}.Debug|x64.Build.0 = Debug|x64\n\t\t{CC44F4F1-DFF1-466C-AEC2-1F36FB80F568}.Release|x64.ActiveCfg = Release|x64\n\t\t{CC44F4F1-DFF1-466C-AEC2-1F36FB80F568}.Release|x64.Build.0 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "04_NodeAttributes/dynNode/Solution - C++/DynNode.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{CC44F4F1-DFF1-466C-AEC2-1F36FB80F568}</ProjectGuid>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup>\n    <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">Debug\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">Debug\\</IntDir>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Release\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Release\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <OutDir>C:\\MayaAPITraining\\plug-ins\\</OutDir>\n    <TargetExt>.mll</TargetExt>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2010\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>C:\\My Documents\\maya\\2010\\plug-ins\\dynNode.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2010\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/.pdb</ProgramDatabaseFile>\n      <RandomizedBaseAddress>false</RandomizedBaseAddress>\n      <DataExecutionPrevention>\n      </DataExecutionPrevention>\n      <ImportLibrary>Debug/.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2015\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>C:\\MayaAPITraining\\plug-ins\\dynNode.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2015\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/.pdb</ProgramDatabaseFile>\n      <RandomizedBaseAddress>false</RandomizedBaseAddress>\n      <DataExecutionPrevention>\n      </DataExecutionPrevention>\n      <ImportLibrary>Debug/.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/.pdb</ProgramDatabaseFile>\n      <RandomizedBaseAddress>false</RandomizedBaseAddress>\n      <DataExecutionPrevention>\n      </DataExecutionPrevention>\n      <ImportLibrary>Release/.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/.pdb</ProgramDatabaseFile>\n      <RandomizedBaseAddress>false</RandomizedBaseAddress>\n      <DataExecutionPrevention>\n      </DataExecutionPrevention>\n      <ImportLibrary>Release/.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"dynNode.cpp\" />\n    <ClCompile Include=\"pluginMain.cpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"dynNode.h\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "04_NodeAttributes/dynNode/Solution - C++/dynNode.cpp",
    "content": "//\n// Copyright (C) \n// \n// File: dynNode.cpp\n//\n// Dependency Graph Node: dynNode\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n\n#include \"dynNode.h\"\n#include <maya/MGlobal.h>\n\n//- Assigning a unique node ID to your new node class.\n//- Ask ADN or Autodesk product support to reserve IDs for your company. You can\n//- reserve ID by block of 64, 128, 256, or 512 consecutive ID.\n//-\n//- 0x00001 is a temporary ID for reserved for development. Never use that ID in a\n//- production environment.\n/*static*/ MTypeId dynNode::id( 0x00001 );\n\n//- Instantiate the static attributes of your node class.\n/*static*/ MObject dynNode::input;        \n/*static*/ MObject dynNode::output;   \n\t \n\n//- No MPxNode member function can be called from the MPxNode constructor. \n//- The postConstructor will get called immediately after the constructor \n//- so it is safe to call any MPxNode member function in postConstructor().\nvoid dynNode::postConstructor()\n{\n\t//- Create a dynamic float attribute and add it onto the node\n\tMFnNumericAttribute nAttr;\n\tdynAttr = nAttr.create( \"dynAttr\", \"da\", MFnNumericData::kFloat, 0.0 );\n\tnAttr.setStorable(true);\n\tnAttr.setKeyable(true);\n\n\t//- Add this dynamic attribute onto this node\n\t//- You cannot call addAttribute() directly, if you look into the MPxNode\n\t//- documentation, addAttribute()only works during the static initialization \n\t//- method of the user defined node class\n\tMObject thisNode = thisMObject();\n\tMFnDependencyNode depNode(thisNode);\n\tdepNode.addAttribute(dynAttr);\n}\n\n//- The setDependentsDirty() method allows attributeAffects relationships\n//- in a much more general way than via MPxNode::attributeAffects\n//- which is limited to static attributes only.\n//- The setDependentsDirty() method allows relationships to be established\n//- between any combination of dynamic and static attributes.\n//-\n//- Within a setDependentsDirty(), you get passed in the\n//- plug (the first argument \"dirtyPlug\"), which is being set dirty, \n//- and then, based upon which plug it is,you may choose to dirty any other \n//- plugs by adding them to the affectedPlugs list (the second argument \"plugArray\").\n//- Arguments:\n//- \tdirtyPlug - the plug which Maya sets dirty\n//- \tplugArray - an array of plugs which are affected by the first plug\nMStatus dynNode::setDependentsDirty(const MPlug &dirtyPlug, MPlugArray &plugArray)\n{\n\t//- This code shows how to make a dynamic attribute (dynAttr)\n\t//- affect a static attribute (output)\n\n\t//- Check if the dynamic attribute is set to dirty by Maya\n\tif( dirtyPlug.partialName() == \"da\" )\n\t{\t\t\n\t\t//- Set the output plug to be affected by this dynamic attribute\n\t\t//- by adding the output plug onto the plugArray \n\t\tMObject thisNode = thisMObject();\n\t\tMPlug outputPlug( thisNode, dynNode::output );\n\t\tplugArray.append(outputPlug);\n\t}\n\treturn MS::kSuccess;\n}\n\n\n//- The initialize method is called to create and initialize all of the \n//- attributes and attribute dependencies for this node type. This is \n//- only called once when the node type is registered with Maya.\n//- Return Values: MS::kSuccess / MS::kFailure\n//-\nMStatus dynNode::initialize()\n{\n\t//- Initialize a float input attribute using the MFnNumericAttribute\n\t//- class. Make that attribute definition saved into Maya file (setStorable),\n\t//- and selectable in the channel box (setKeyable).\n\n\t//- Create a generic attribute using MFnNumericAttribute\n\tMFnNumericAttribute nAttr;\n\tdynNode::input = nAttr.create( \"input\", \"in\", MFnNumericData::kFloat, 0.0 );\n\t//- Attribute will be written to files when this type of node is stored\n \tnAttr.setStorable(true);\n\t//- Attribute is keyable and will show up in the channel box\n \tnAttr.setKeyable(true);\n\n\t//- Initialize a float output attribute using the MFnNumericAttribute\n\t//- class. Make that attribute is not saved into Maya file.\n\tdynNode::output = nAttr.create( \"output\", \"out\", MFnNumericData::kFloat, 0.0 );\n\t//- Attribute will not be written to files when this type of node is stored\n\tnAttr.setStorable(false);\n\n\t//- Now add the attribute to your node definition using the addAttribute()\n\t//- method.\n\taddAttribute( dynNode::input );\t\n\taddAttribute( dynNode::output );\n\t\n\t//- Finally tell Maya how the information should flow through your node.\n\t//- This will also tell Maya how the dirty flag is propagated in your node\n\t//- and ultimately in the Maya DG. To do this, use the attributeAffects()\n\t//- method to link your node' attributes together.\n\t//- Set up a dependency between the input and the output. This will cause\n\t//- the output to be marked dirty when the input changes. The output will\n\t//- then be recomputed the next time the value of the output is requested.\n\tattributeAffects( dynNode::input, dynNode::output );\n\n\t//- Return success to Maya\n\treturn MS::kSuccess;\n}\n\n//- This method computes the value of the given output plug based\n//- on the values of the input attributes.\n//- Arguments:\n//- \tplug - the plug to compute\n//- \tdata - object that provides access to the attributes for this node\nMStatus dynNode::compute( const MPlug& plug, MDataBlock& data )\n{\n\tMStatus returnStatus;\n \n\t//- Check which output attribute we have been asked to compute. If this \n\t//- node doesn't know how to compute it, you must return MS::kUnknownParameter.\n\n\tif( plug == dynNode::output )\n\t{\n\t\t//- Get a handle to the input attribute that we will need for the\n\t\t//- computation. If the value is being supplied via a connection \n\t\t//- in the dependency graph, then this call will cause all upstream  \n\t\t//- connections to be evaluated so that the correct value is supplied.\n\t\tMDataHandle inputData = data.inputValue( dynNode::input, &returnStatus );\n\n\t\t//- Read the input value from the handle.\n\t\tfloat inputValue = inputData.asFloat();\n\n\t\t//- Since output is affected by the dynamic attribute too, \n\t\t//- retrieve the dynamic attribute value\n\t\tMDataHandle dynData = data.inputValue( dynAttr, &returnStatus );\n\t\tfloat dynValue = dynData.asFloat();\n\n\t\t//- Get a handle to the output attribute. This is similar to the\n\t\t//- \"inputValue\" call above except that no dependency graph \n\t\t//- computation will be done as a result of this call.\n\n\t\t//- Get a handle on the output attribute\n\t\tMDataHandle outputHandle = data.outputValue( dynNode::output );\n\n\t\t//- Set the new output value to the handle.\n\t\toutputHandle.set( inputValue + dynValue );\n\n\t\t//- Return success to Maya\n\t\treturn MS::kSuccess;\n\t}\n\n\t//- Tell Maya that we do not know how to handle this plug, but let's give a chance\n\t//- to our parent class to evaluate it.\n\treturn MS::kUnknownParameter;\n}\n"
  },
  {
    "path": "04_NodeAttributes/dynNode/Solution - C++/dynNode.h",
    "content": "//\n// Copyright (C) \n// \n// File: dynNode.h\n//\n// Dependency Graph Node: dynNode\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#pragma once\n\n//- Include Maya necessary headers for our class\n#include <maya/MPxNode.h>\n#include <maya/MFnNumericAttribute.h>\n#include <maya/MFnTypedAttribute.h>\n#include <maya/MFnStringData.h>\n#include <maya/MTypeId.h> \n#include <maya/MPlug.h>\n#include <maya/MDataBlock.h>\n#include <maya/MDataHandle.h>\n#include <maya/MFnDependencyNode.h>\n#include <maya/MPlugArray.h>\n#include <maya/MFnDependencyNode.h>\n\n//- Derive a new class from the default Maya node proxy class.\nclass dynNode : public MPxNode\n{\npublic:\n\tdynNode() {\n\t\t//- Never do anything here which would affect Maya.\n\t\t//- Instead implement the virtual postConstructor() method.\n\t}\n\tvirtual ~dynNode() {}\n\n\t//- Declare the virtual compute() method.\n\tvirtual MStatus\t\tcompute( const MPlug& plug, MDataBlock& data );\n\n\t//- Declare/implement the static creator method.\n\t//- This method exists to give Maya a way to create new objects\n\t//- of this type. \n\tstatic  void*\t\tcreator() {\n\t\treturn new dynNode();\n\t}\n\n\t//- Declare the static initialize() method.\n\tstatic  MStatus\t\tinitialize();\n\n\t//- Declare the virtual postConstructor() method.\n\tvirtual void postConstructor();\n\t//- Declare the virtual setDependentsDirty() method.\n\tvirtual MStatus setDependentsDirty(const MPlug &dirtyPlug,MPlugArray &plugArray);\n\npublic:\n\t//- There needs to be a MObject handle declared for each attribute that\n\t//- the node will have.  These handles are needed for getting and setting\n\t//- the values later.\n\t//\n\tstatic  MObject\t\tinput;\t\t// input attribute\n\tstatic  MObject\t\toutput;\t\t// output attribute\n\n\t//- Declare a member variable to store the dynamic attribute \n\tMObject dynAttr;\n\n\t//- This is a unique node ID for your new node class. It is declared\n\t//- static because it is common to all instance of that class.\n\t//-\n\t//- The typeid is a unique 32bit identifier that describes this node.\n\t//- It is used to save and retrieve nodes of this type from the binary\n\t//- file format. If it is not unique, it will cause file IO problems.\n\tstatic\tMTypeId\t\tid;\n};\n"
  },
  {
    "path": "04_NodeAttributes/dynNode/Solution - C++/pluginMain.cpp",
    "content": "//\n// Copyright (C)  \n// \n// File: pluginMain.cpp\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n\n#include <maya/MFnPlugin.h>\n#include \"dynNode.h\"\n\nMStatus initializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is loaded into Maya.  It \n//\t\tregisters all of the services that this plug-in provides with \n//\t\tMaya.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{ \n\tMStatus   status;\n\tMFnPlugin plugin( obj, \"\", \"2008\", \"Any\");\n\n\t//- Register your node here, so Maya can use it and recognize it\n\t//- while reading/saving a file which has instance of this node type.\n\tstatus = plugin.registerNode( \"dynNode\", dynNode::id, dynNode::creator, dynNode::initialize );\n\n\tif (!status) {\n\t\tstatus.perror(\"registerNode\");\n\t\treturn status;\n\t}\n\treturn status;\n}\n\nMStatus uninitializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is unloaded from Maya. It \n//\t\tderegisters all of the services that it was providing.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{\n\tMStatus   status;\n\tMFnPlugin plugin( obj );\n\n\t\n\t//- Unregister your node here, so Maya stops using it.\n\tstatus = plugin.deregisterNode( dynNode::id );\n\n\tif (!status) {\n\t\tstatus.perror(\"deregisterNode\");\n\t\treturn status;\n\t}\n\n\treturn status;\n}\n"
  },
  {
    "path": "04_NodeAttributes/dynNode/Solution - py/dynNode.py",
    "content": "#\n# Copyright (C) \n# \n# File: dynNode.py\n#\n# Dependency Graph Node: \n#\n# Author: Maya Plug-in Wizard 2.0\n#\n\nimport maya.OpenMaya as OpenMaya\nimport maya.OpenMayaMPx as OpenMayaMPx\nimport sys\n\n#- Assigning a unique node ID to your new node class.\n#- Ask ADN or Autodesk product support to reserve IDs for your company. You can\n#- reserve ID by block of 64, 128, 256, or 512 consecutive ID.\n#-\n#- 0x00001 is a temporary ID for reserved for development. Never use that ID in a\n#- production environment.\n\nkPluginNodeTypeName = \"dynNode\"\ndynNodeId = OpenMaya.MTypeId(0x00001)\n\n# Node definition\nclass dynNode(OpenMayaMPx.MPxNode):\n\taInput = OpenMaya.MObject()        \n\taOutput = OpenMaya.MObject()  \n\tdynAttr = OpenMaya.MObject()  \n\t\t\n\tdef __init__(self):\n\t\tOpenMayaMPx.MPxNode.__init__(self)\n\t\t\n\t#- This method computes the value of the given output plug based\n\t#- on the values of the input attributes.\n\t#- Arguments:\n\t#- \tplug - the plug to compute\n\t#- \tdata - object that provides access to the attributes for this node\n\tdef compute(self,plug,data):\n\t\t#- Check which output attribute we have been asked to compute. If this \n\t\t#- node doesn't know how to compute it, you must return MS::kUnknownParameter.\n\n\t\tif plug == dynNode.aOutput:\n\t\t\t#- Get a handle to the input attribute that we will need for the\n\t\t\t#- computation. If the value is being supplied via a connection \n\t\t\t#- in the dependency graph, then this call will cause all upstream  \n\t\t\t#- connections to be evaluated so that the correct value is supplied.\n\t\t\tinputData = data.inputValue(dynNode.aInput)\n\t\t\t#- Read the input value from the handle.\n\n\t\t\tinputValue = inputData.asFloat()\n\t\t\tprint inputValue\n\t\t\t\n\t\t\t#- Since output is affected by the dynamic attribute too, \n\t\t\t#- retrieve the dynamic attribute value\n\t\t\tdynData = data.inputValue(self.dynAttr)\n\t\t\tdynValue = dynData.asFloat()\n\t\t\tprint dynValue\n\t\t\t\n\t\t\t#- Get a handle to the output attribute. This is similar to the\n\t\t\t#- \"inputValue\" call above except that no dependency graph \n\t\t\t#- computation will be done as a result of this call.\n\n\t\t\t#- Get a handle on the aOutput attribute\n\t\t\toutputHandle = data.outputValue(dynNode.aOutput)\n\t\t\t\n\t\t\t#- Set the new output value to the handle.\n\t\t\tprint \"combined Value\", inputValue + dynValue \n\t\t\toutputHandle.setFloat( inputValue + dynValue )\n\t\t\t\n\t\t#- Tell Maya that we do not know how to handle this plug, but let's give a chance\n\t\t#- to our parent class to evaluate it.\n\t\telse:\n\t\t\treturn OpenMaya.kUnknownParameter\n\t\t\t\n\t#- No MPxNode member function can be called from the MPxNode constructor. \n\t#- The postConstructor will get called immediately after the constructor \n\t#- so it is safe to call any MPxNode member function in postConstructor().\n\tdef postConstructor(self):\n\t\t#- Create a dynamic float attribute and add it onto the node\n\t\tnAttr = OpenMaya.MFnNumericAttribute()\n\t\tself.dynAttr = nAttr.create( \"dynAttr\", \"da\", OpenMaya.MFnNumericData.kFloat, 0.0 )\n\t\tnAttr.setStorable(True)\n\t\tnAttr.setKeyable(True)\n\t\n\t\t#- Add this dynamic attribute onto this node\n\t\t#- You cannot call addAttribute() directly, if you look into the MPxNode\n\t\t#- documentation, addAttribute()only works during the static initialization \n\t\t#- method of the user defined node class\n\t\tthisNode = self.thisMObject()\n\t\tfnThisNode = OpenMaya.MFnDependencyNode(thisNode)\n\t\tprint \"Adding Dynamic Attribute\"\n\t\tfnThisNode.addAttribute(self.dynAttr)\n\n\t\n\t#- The setDependentsDirty() method allows attributeAffects relationships\n\t#- in a much more general way than via MPxNode::attributeAffects\n\t#- which is limited to static attributes only.\n\t#- The setDependentsDirty() method allows relationships to be established\n\t#- between any combination of dynamic and static attributes.\n\t#-\n\t#- Within a setDependentsDirty(), you get passed in the\n\t#- plug (the first argument \"dirtyPlug\"), which is being set dirty, \n\t#- and then, based upon which plug it is,you may choose to dirty any other \n\t#- plugs by adding them to the affectedPlugs list (the second argument \"plugArray\").\n\t#- Arguments:\n\t#- \tdirtyPlug - the plug which Maya sets dirty\n\t#- \tplugArray - an array of plugs which are affected by the first plug\n\tdef setDependentsDirty(self, dirtyPlug, plugArray):\n\t\t#- This code shows how to make a dynamic attribute (dynAttr)\n\t\t#- affect a static attribute (output)\n\t\n\t\t#- Check if the dynamic attribute is set to dirty by Maya\n\t\tif dirtyPlug == self.dynAttr:\n\t\t\t#- Set the output plug to be affected by this dynamic attribute\n\t\t\t#- by adding the output plug onto the plugArray \n\t\t\tthisNode = self.thisMObject()\n\t\t\ttry:\n\t\t\t\tplug = OpenMaya.MPlug(thisNode, dynNode.aOutput)\n\t\t\t\tplugArray.append(plug) \n\t\t\texcept:\n\t\t\t\tpass\n\t\t\t\t\n\t\treturn OpenMayaMPx.MPxNode.setDependentsDirty(self, dirtyPlug, plugArray) \n\n\n# Creator\ndef nodeCreator():\n\treturn OpenMayaMPx.asMPxPtr( dynNode() )\n\n\n#- The initialize method is called to create and initialize all of the \n#- attributes and attribute dependencies for this node type. This is \n#- only called once when the node type is registered with Maya.\n#- Return Values: MS::kSuccess / MS::kFailure\ndef nodeInitializer():\n\n\t#- Initialize a float input attribute using the MFnNumericAttribute\n\t#- class. Make that attribute definition saved into Maya file (setStorable),\n\t#- and selectable in the channel box (setKeyable).\n\n\t#- Create a generic attribute using MFnNumericAttribute\n\tnAttr = OpenMaya.MFnNumericAttribute()\n\tdynNode.aInput = nAttr.create( \"input\", \"in\", OpenMaya.MFnNumericData.kFloat, 0.0 )\n\t#- Attribute will be written to files when this type of node is stored\n \tnAttr.setStorable(True)\n\t#- Attribute is keyable and will show up in the channel box\n \tnAttr.setKeyable(True)\n\n\t#- Initialize a float output attribute using the MFnNumericAttribute\n\t#- class. Make that attribute is not saved into Maya file.\n\tdynNode.aOutput = nAttr.create( \"output\", \"out\", OpenMaya.MFnNumericData.kFloat, 0.0 )\n\t#- Attribute will not be written to files when this type of node is stored\n\tnAttr.setStorable(False)\n\n\t#- Now add the attribute to your node definition using the addAttribute()\n\t#- method.\n\tdynNode.addAttribute( dynNode.aInput )\n\tdynNode.addAttribute( dynNode.aOutput )\n\t\n\t#- Finally tell Maya how the information should flow through your node.\n\t#- This will also tell Maya how the dirty flag is propagated in your node\n\t#- and ultimately in the Maya DG. To do this, use the attributeAffects()\n\t#- method to link your node' attributes together.\n\t#- Set up a dependency between the input and the output. This will cause\n\t#- the output to be marked dirty when the input changes. The output will\n\t#- then be recomputed the next time the value of the output is requested.\n\tdynNode.attributeAffects( dynNode.aInput, dynNode.aOutput )\n\n# Initialize the script plug-in\ndef initializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\tmplugin.registerNode( kPluginNodeTypeName, dynNodeId, nodeCreator, nodeInitializer )\n\texcept:\n\t\tsys.stderr.write( \"Failed to register node: %s\" % kPluginNodeTypeName )\n\t\traise\n\n# Uninitialize the script plug-in\ndef uninitializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\tmplugin.deregisterNode( dynNodeId )\n\texcept:\n\t\tsys.stderr.write( \"Failed to deregister node: %s\" % kPluginNodeTypeName )\n\t\traise"
  },
  {
    "path": "04_NodeAttributes/simpleNode - with Typed Attr/Exercise - C++/pluginMain.cpp",
    "content": "//\n// Copyright (C)  \n// \n// File: pluginMain.cpp\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n\n#include <maya/MFnPlugin.h>\n#include \"simpleNode.h\"\n\nMStatus initializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is loaded into Maya.  It \n//\t\tregisters all of the services that this plug-in provides with \n//\t\tMaya.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{ \n\tMStatus   status;\n\tMFnPlugin plugin( obj, \"\", \"2009\", \"Any\");\n\n\t// Add plug-in feature registration here\n\t//\n\n\t//- Register your node here, so Maya can use it and recognize it\n\t//- while reading/saving a file which has instance of this node type.\n\tstatus = plugin.registerNode( \"simpleNode\", simpleNode::id, simpleNode::creator, simpleNode::initialize );\n\n\tif (!status) {\n\t\tstatus.perror(\"registerNode\");\n\t\treturn status;\n\t}\n\treturn status;\n}\n\nMStatus uninitializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is unloaded from Maya. It \n//\t\tderegisters all of the services that it was providing.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{\n\tMStatus   status;\n\tMFnPlugin plugin( obj );\n\n\t// Add plug-in feature deregistration here\n\t//\n\n\t//- Unregister your node here, so Maya stops using it.\n\tstatus = plugin.deregisterNode( simpleNode::id );\n\n\tif (!status) {\n\t\tstatus.perror(\"deregisterNode\");\n\t\treturn status;\n\t}\n\n\treturn status;\n}\n"
  },
  {
    "path": "04_NodeAttributes/simpleNode - with Typed Attr/Exercise - C++/simpleNode.cpp",
    "content": "//\n// Copyright (C) \n// \n// File: simpleNode.cpp\n//\n// Dependency Graph Node: simpleNode\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n\n#include \"simpleNode.h\"\n#include <maya/MGlobal.h>\n\n//- Assigning a unique node ID to your new node class.\n//- Ask ADN or Autodesk product support to reserve IDs for your company. You can\n//- reserve ID by block of 64, 128, 256, or 512 consecutive ID.\n//-\n//- 0x00001 is a temporary ID for reserved for development. Never use that ID in a\n//- production environment.\n/*static*/ MTypeId simpleNode::id( 0x00001 );\n\n\n//- Instantiate the static attributes of your node class.\n/*static*/ MObject simpleNode::input;        \n/*static*/ MObject simpleNode::output;        \n/*static*/ MObject simpleNode::descString;\t\t \n\n//- The initialize method is called to create and initialize all of the \n//- attributes and attribute dependencies for this node type. This is \n//- only called once when the node type is registered with Maya.\n//- Return Values: MS::kSuccess / MS::kFailure\n//-\nMStatus simpleNode::initialize()\n{\n\t//- Initialize a float input attribute using the MFnNumericAttribute\n\t//- class. Make that attribute definition saved into Maya file (setStorable),\n\t//- and selectable in the channel box (setKeyable).\n\n\t//- Create a generic attribute using MFnNumericAttribute\n\tMFnNumericAttribute nAttr;\n\tinput = nAttr.create( \"input\", \"in\", MFnNumericData::kFloat, 0.0 );\n\t//- Attribute will be written to files when this type of node is stored\n \tnAttr.setStorable(true);\n\t//- Attribute is keyable and will show up in the channel box\n \tnAttr.setKeyable(true);\n\n\t//- Initialize a float output attribute using the MFnNumericAttribute\n\t//- class. Make that attribute definition not saved into Maya file.\n\toutput = nAttr.create( \"output\", \"out\", MFnNumericData::kFloat, 0.0 );\n\t//- Attribute will not be written to files when this type of node is stored\n\tnAttr.setStorable(false);\n\t\n\n\t//- Initialize a string output attribute using the MFnTypedAttribute\n\t//- class.In order to specify the attribute default value, you will need to \n\t//- use the MFnStringData class, before creating the attribute itself.\n\n\n\t//- TODO: create a MFnTypedAttribute instance\n\t//...\n\n\t//- TODO: Use MFnStringData to create default value for this typed attribute \n\t//...\n\t//...\n\n\t//- TODO: create a string attribute using the above MFnTypedAttribute instance\n\t//- and use the above MObject as a default value for your string attribute\n\t//...\n\n\n\t//- Now add the attribute to your node definition using the addAttribute()\n\t//- method.\n\taddAttribute( input );\t\n\taddAttribute( output );\t\n\t//- TODO: Add the string attribute to the node type definition\n\t//...\n\t\n\t//- Finally tell Maya how the information should flow through your node.\n\t//- This will also tell Maya how the dirty flag is propagated in your node\n\t//- and ultimately in the Maya DG. To do this, use the attributeAffects()\n\t//- method to link your node' attributes together.\n\n\t//- Set up a dependency between the input and the output. This will cause\n\t//- the output to be marked dirty when the input changes. The output will\n\t//- then be recomputed the next time the value of the output is requested.\n\tattributeAffects( input, output );\n\n\t//- Return success to Maya\n\treturn MS::kSuccess;\n}\n\n//- This method computes the value of the given output plug based\n//- on the values of the input attributes.\n//- Arguments:\n//- \tplug - the plug to compute\n//- \tdata - object that provides access to the attributes for this node\nMStatus simpleNode::compute( const MPlug& plug, MDataBlock& data )\n{\n\tMStatus returnStatus;\n \n\t//- Check which output attribute we have been asked to compute. If this \n\t//- node doesn't know how to compute it, you must return MS::kUnknownParameter.\n\n\tif( plug == output )\n\t{\n\t\t//- Get a handle to the input attribute that we will need for the\n\t\t//- computation. If the value is being supplied via a connection \n\t\t//- in the dependency graph, then this call will cause all upstream  \n\t\t//- connections to be evaluated so that the correct value is supplied.\n\t\tMDataHandle inputData = data.inputValue( input, &returnStatus );\n\n\t\t//- Read the input value from the handle.\n\t\tfloat result = inputData.asFloat();\n\n\t\t//- Get a handle to the output attribute. This is similar to the\n\t\t//- \"inputValue\" call above except that no dependency graph \n\t\t//- computation will be done as a result of this call.\n\n\t\t//- Get a handle on the aOutput attribute\n\t\tMDataHandle outputHandle = data.outputValue( simpleNode::output );\n\n\t\t//- Set the new output value to the handle.\n\t\toutputHandle.set( result * 2 );\n\n\t\t//- Mark the destination plug as being clean. This will prevent the\n\t\t//- dependency graph from repeating this calculation until an input \n\t\t//- attribute of this node which affects this output attribute changes.\n\n\t\t//- Tell Maya the plug is now clean\n\t\tdata.setClean(plug);\n\n\n\t\t//- Return success to Maya\n\t\treturn MS::kSuccess;\n\t}\n\n\t//- Tell Maya that we do not know how to handle this plug, but let give a chance\n\t//- to our parent class to evaluate it.\n\treturn MS::kUnknownParameter;\n}\n"
  },
  {
    "path": "04_NodeAttributes/simpleNode - with Typed Attr/Exercise - C++/simpleNode.h",
    "content": "//\n// Copyright (C) \n// \n// File: simpleNode.h\n//\n// Dependency Graph Node: simpleNode\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#pragma once\n\n//- Include Maya necessary headers for our class\n#include <maya/MPxNode.h>\n#include <maya/MFnNumericAttribute.h>\n#include <maya/MFnTypedAttribute.h>\n#include <maya/MFnStringData.h>\n#include <maya/MTypeId.h> \n#include <maya/MPlug.h>\n#include <maya/MDataBlock.h>\n#include <maya/MDataHandle.h>\n\n//- Derive a new class from the default Maya node proxy class.\nclass simpleNode : public MPxNode\n{\npublic:\n\tsimpleNode() {\n\t\t//- Never do anything here which would affect Maya.\n\t\t//- Instead implement the virtual postConstructor() method.\n\t}\n\tvirtual ~simpleNode() {}\n\n\t//- Declare the virtual compute() method.\n\tvirtual MStatus\t\tcompute( const MPlug& plug, MDataBlock& data );\n\n\t//- Declare/implement the static creator method.\n\t//- This method exists to give Maya a way to create new objects\n\t//- of this type. \n\tstatic  void*\t\tcreator() {\n\t\treturn new simpleNode();\n\t}\n\n\t//- Declare the static initialize() method.\n\tstatic  MStatus\t\tinitialize();\n\npublic:\n\t// There needs to be a MObject handle declared for each attribute that\n\t// the node will have.  These handles are needed for getting and setting\n\t// the values later.\n\t//\n\tstatic  MObject\t\tinput;\t\t// input attribute\n\tstatic  MObject\t\toutput;\t\t// output attribute\n\tstatic\tMObject\t\tdescString; // Description string attribute describing the function of this node\n\n\t//- This is a unique node ID for your new node class. It is declared\n\t//- static because it is common to all instance of that class.\n\t//-\n\t//- The typeid is a unique 32bit identifier that describes this node.\n\t//- It is used to save and retrieve nodes of this type from the binary\n\t//- file format. If it is not unique, it will cause file IO problems.\n\n\tstatic\tMTypeId\t\tid;\n};\n"
  },
  {
    "path": "04_NodeAttributes/simpleNode - with Typed Attr/Exercise - C++/simpleNode.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 2012\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"simpleNode\", \"simpleNode.vcxproj\", \"{439648C5-792B-4918-AC04-5B034F382742}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|x64 = Debug|x64\n\t\tRelease|x64 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{439648C5-792B-4918-AC04-5B034F382742}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{439648C5-792B-4918-AC04-5B034F382742}.Debug|x64.Build.0 = Debug|x64\n\t\t{439648C5-792B-4918-AC04-5B034F382742}.Release|x64.ActiveCfg = Release|x64\n\t\t{439648C5-792B-4918-AC04-5B034F382742}.Release|x64.Build.0 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "04_NodeAttributes/simpleNode - with Typed Attr/Exercise - C++/simpleNode.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{439648C5-792B-4918-AC04-5B034F382742}</ProjectGuid>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup>\n    <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">Debug\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">Debug\\</IntDir>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Release\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Release\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <OutDir>C:\\MayaAPITraining\\plug-ins\\</OutDir>\n    <TargetExt>.mll</TargetExt>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2009\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/simpleNode.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>C:\\My Documents\\maya\\2009\\plug-ins\\simpleNode.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2009\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/simpleNode.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/simpleNode.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2015\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/simpleNode.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>C:\\MayaAPITraining\\plug-ins\\simpleNode.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2015\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/simpleNode.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/simpleNode.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/simpleNode.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\simpleNode.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/simpleNode.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/simpleNode.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/simpleNode.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\simpleNode.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/simpleNode.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/simpleNode.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"pluginMain.cpp\" />\n    <ClCompile Include=\"simpleNode.cpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"simpleNode.h\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "04_NodeAttributes/simpleNode - with Typed Attr/Exercise - py/simpleNode.py",
    "content": "# Copyright (C) \n# \n# Author: Autodesk Developer Network\n\n#For this exercise, search for the TODO keywords and follow the instructions in\n#comments. If you are unsure of what you need to do, feel free to ask the instructor\n#or look into the solution folder.\n#Each #... line is a line of code you need to write or complete.\n\nimport maya.OpenMaya as OpenMaya\nimport maya.OpenMayaMPx as OpenMayaMPx\n\n#- Assing a unique node ID to your new node class.\n#- Ask ADN or Autodesk product support to reserve IDs for your company. You can\n#- reserve ID by block of 64, 128, 256, or 512 consecutive ID.\n#-\n#- 0x80001 is a temporary ID for reserved for development. Never use that ID in a\n#- production environement.\nkPluginNodeTypeName = \"simpleNode\"\nsimpleNodeId = OpenMaya.MTypeId(0x80001)\n\n# Node definition\nclass simpleNode(OpenMayaMPx.MPxNode):\n\t# Node attributes\n\tinput = OpenMaya.MObject()\n\toutput = OpenMaya.MObject()\n\t#- TODO: Declare here the string attribute\n\t#- TODO: ...\n\t\n\tdef __init__(self):\n\t\tOpenMayaMPx.MPxNode.__init__(self)\n\t\t\n\t#- This method computes the value of the given output plug based\n\t#- on the values of the input attributes.\n\t#- Arguments:\n\t#- \tplug - the plug to compute\n\t#- \tdata - object that provides access to the attributes for this node\n\tdef compute(self,plug,dataBlock):\n\t\tif ( plug == simpleNode.output ):\n\t\t\t#- Get a handle to the input attribute that we will need for the\n\t\t\t#- computation. If the value is being supplied via a connection \n\t\t\t#- in the dependency graph, then this call will cause all upstream  \n\t\t\t#- connections to be evaluated so that the correct value is supplied.\n\t\t\tinputData = dataBlock.inputValue( simpleNode.input )\n\t\t\t\n\t\t\t#- Read the input value from the handle.\n\t\t\tresult = inputData.asFloat()\n\n\t\t\t#- Get a handle to the output attribute. This is similar to the\n\t\t\t#- \"inputValue\" call above except that no dependency graph \n\t\t\t#- computation will be done as a result of this call.\n\n\t\t\t#- Get a handle on the aOutput attribute\n\t\t\toutputHandle = dataBlock.outputValue( simpleNode.output )\n\n\t\t\t#- Set the new output value to the handle.\n\t\t\toutputHandle.setFloat( result * 2 );\n\n\t\t\t#- Mark the destination plug as being clean. This will prevent the\n\t\t\t#- dependency graph from repeating this calculation until an input \n\t\t\t#- attribute of this node which affects this output attribute changes.\n\n\t\t\t#- Tell Maya the plug is now clean\n\t\t\tdataBlock.setClean( plug )\n\n\t\t#- Tell Maya that we do not know how to handle this plug, but let give a chance\n\t\t#- to our parent class to evaluate it.\n\t\treturn OpenMaya.kUnknownParameter\n\n# Creator\ndef nodeCreator():\n\treturn OpenMayaMPx.asMPxPtr( simpleNode() )\n\n#- The initialize method is called to create and initialize all of the \n#- attributes and attribute dependencies for this node type. This is \n#- only called once when the node type is registered with Maya.\n#-\ndef nodeInitializer():\n\t#- Initialize a float input attribute using the MFnNumericAttribute\n\t#- class. Make that attribute definition saved into Maya file (setStorable),\n\t#- and selectable in the channel box (setKeyable).\n\n\t#- Create a generic attribute using MFnNumericAttribute\n\tnAttr = OpenMaya.MFnNumericAttribute()\n\tsimpleNode.input = nAttr.create( \"input\", \"in\", OpenMaya.MFnNumericData.kFloat, 0.0 )\n\t#- Attribute will be written to files when this type of node is stored\n \tnAttr.setStorable(1)\n\t#- Attribute is keyable and will show up in the channel box\n \tnAttr.setKeyable(1)\n\n\t#- Initialize a float output attribute using the MFnNumericAttribute\n\t#- class. Make that attribute definition not saved into Maya file.\n\tsimpleNode.output = nAttr.create( \"output\", \"out\", OpenMaya.MFnNumericData.kFloat, 0.0 )\n\t#- Attribute will not be written to files when this type of node is stored\n\tnAttr.setStorable(0)\n\t\n\t#- Initialize a string output attribute using the MFnTypedAttribute\n\t#- class.In order to specify the attribute default value, you will need to \n\t#- use the MFnStringData class, before creating the attribute itself.\n\n\n\t#- TODO: create a MFnTypedAttribute instance\n\t#...\n\n\t#- TODO: Use MFnStringData to create default value for this typed attribute \n\t#...\n\t#...\n\n\t#- TODO: create a string attribute using the above MFnTypedAttribute instance\n\t#- and use the above object as a default value for your string attribute\n\t#...\n\t\n\t#- Now add the attribute to your node definition using the addAttribute()\n\t#- method.\n\t#- Add the attributes we have created to the node\n\tsimpleNode.addAttribute( simpleNode.input );\n\tsimpleNode.addAttribute( simpleNode.output );\n\t#- TODO: Add the string attribute to the node type definition\n\t#...\n\t\n\t\n\t#- Finally tell Maya how the information should flow through your node.\n\t#- This will also tell Maya how the dirty flag is propagated in your node\n\t#- and ultimatelly in the Maya DG. To do this, use the attributeAffects()\n\t#- method to link your node' attributes together.\n\n\t#- Set up a dependency between the input and the output. This will cause\n\t#- the output to be marked dirty when the input changes. The output will\n\t#- then be recomputed the next time the value of the output is requested.\n\tsimpleNode.attributeAffects( simpleNode.input, simpleNode.output );\n\n# Initialize the script plug-in\ndef initializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\tmplugin.registerNode( kPluginNodeTypeName, simpleNodeId, nodeCreator, nodeInitializer )\n\texcept:\n\t\tsys.stderr.write( \"Failed to register node: %s\" % kPluginNodeTypeName )\n\t\traise\n\n# Uninitialize the script plug-in\ndef uninitializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\tmplugin.deregisterNode( simpleNodeId )\n\texcept:\n\t\tsys.stderr.write( \"Failed to deregister node: %s\" % kPluginNodeTypeName )\n\t\traise\n"
  },
  {
    "path": "04_NodeAttributes/simpleNode - with Typed Attr/Solution - C++/pluginMain.cpp",
    "content": "//\n// Copyright (C)  \n// \n// File: pluginMain.cpp\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n\n#include <maya/MFnPlugin.h>\n#include \"simpleNode.h\"\n\nMStatus initializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is loaded into Maya.  It \n//\t\tregisters all of the services that this plug-in provides with \n//\t\tMaya.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{ \n\tMStatus   status;\n\tMFnPlugin plugin( obj, \"\", \"2009\", \"Any\");\n\n\t// Add plug-in feature registration here\n\t//\n\n\t//- Register your node here, so Maya can use it and recognize it\n\t//- while reading/saving a file which has instance of this node type.\n\tstatus = plugin.registerNode( \"simpleNode\", simpleNode::id, simpleNode::creator, simpleNode::initialize );\n\n\tif (!status) {\n\t\tstatus.perror(\"registerNode\");\n\t\treturn status;\n\t}\n\treturn status;\n}\n\nMStatus uninitializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is unloaded from Maya. It \n//\t\tderegisters all of the services that it was providing.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{\n\tMStatus   status;\n\tMFnPlugin plugin( obj );\n\n\t// Add plug-in feature deregistration here\n\t//\n\n\t//- Unregister your node here, so Maya stops using it.\n\tstatus = plugin.deregisterNode( simpleNode::id );\n\n\tif (!status) {\n\t\tstatus.perror(\"deregisterNode\");\n\t\treturn status;\n\t}\n\n\treturn status;\n}\n"
  },
  {
    "path": "04_NodeAttributes/simpleNode - with Typed Attr/Solution - C++/simpleNode.cpp",
    "content": "//\n// Copyright (C) \n// \n// File: simpleNode.cpp\n//\n// Dependency Graph Node: simpleNode\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n\n#include \"simpleNode.h\"\n#include <maya/MGlobal.h>\n\n//- Assigning a unique node ID to your new node class.\n//- Ask ADN or Autodesk product support to reserve IDs for your company. You can\n//- reserve ID by block of 64, 128, 256, or 512 consecutive ID.\n//-\n//- 0x00001 is a temporary ID for reserved for development. Never use that ID in a\n//- production environment.\n/*static*/ MTypeId simpleNode::id( 0x00001 );\n\n//- Instantiate the static attributes of your node class.\n/*static*/ MObject simpleNode::input;        \n/*static*/ MObject simpleNode::output;   \n/*static*/ MObject simpleNode::descString;\t\t \n\n//- The initialize method is called to create and initialize all of the \n//- attributes and attribute dependencies for this node type. This is \n//- only called once when the node type is registered with Maya.\n//- Return Values: MS::kSuccess / MS::kFailure\n//-\nMStatus simpleNode::initialize()\n{\n\t//- Initialize a float input attribute using the MFnNumericAttribute\n\t//- class. Make that attribute definition saved into Maya file (setStorable),\n\t//- and selectable in the channel box (setKeyable).\n\n\t//- Create a generic attribute using MFnNumericAttribute\n\tMFnNumericAttribute nAttr;\n\tinput = nAttr.create( \"input\", \"in\", MFnNumericData::kFloat, 0.0 );\n\t//- Attribute will be written to files when this type of node is stored\n \tnAttr.setStorable(true);\n\t//- Attribute is keyable and will show up in the channel box\n \tnAttr.setKeyable(true);\n\n\t//- Initialize a float output attribute using the MFnNumericAttribute\n\t//- class. Make that attribute definition not saved into Maya file.\n\toutput = nAttr.create( \"output\", \"out\", MFnNumericData::kFloat, 0.0 );\n\t//- Attribute will not be written to files when this type of node is stored\n\tnAttr.setStorable(false);\n\t\n\t//- Initialize a string output attribute using the MFnTypedAttribute\n\t//- class.In order to specify the attribute default value, you will need to \n\t//- use the MFnStringData class, before creating the attribute itself.\n\n\t//- Create a string attribute using MFnTypedAttribute\n\tMFnTypedAttribute typedAttr;\n\t//- Use MFnStringData to implement default value of this attribute\n\tMFnStringData fnStringData;\n\tMString defaultString(\"description string for current node\");\n\tMObject defaultStringObj = fnStringData.create(defaultString);\n\tdescString = typedAttr.create(\"descString\", \"dStr\", MFnData::kString,defaultStringObj);\n\n\t//- Now add the attribute to your node definition using the addAttribute()\n\t//- method.\n\t//- Add the attributes we have created to the node\n\taddAttribute( input );\t\n\taddAttribute( output );\n\taddAttribute(descString);\n\t\n\t//- Finally tell Maya how the information should flow through your node.\n\t//- This will also tell Maya how the dirty flag is propagated in your node\n\t//- and ultimately in the Maya DG. To do this, use the attributeAffects()\n\t//- method to link your node' attributes together.\n\n\t//- Set up a dependency between the input and the output. This will cause\n\t//- the output to be marked dirty when the input changes. The output will\n\t//- then be recomputed the next time the value of the output is requested.\n\tattributeAffects( input, output );\n\n\t//- Return success to Maya\n\treturn MS::kSuccess;\n}\n\n//- This method computes the value of the given output plug based\n//- on the values of the input attributes.\n//- Arguments:\n//- \tplug - the plug to compute\n//- \tdata - object that provides access to the attributes for this node\nMStatus simpleNode::compute( const MPlug& plug, MDataBlock& data )\n{\n\tMStatus returnStatus;\n \n\t//- Check which output attribute we have been asked to compute. If this \n\t//- node doesn't know how to compute it, you must return MS::kUnknownParameter.\n\n\tif( plug == output )\n\t{\n\t\t//- Get a handle to the input attribute that we will need for the\n\t\t//- computation. If the value is being supplied via a connection \n\t\t//- in the dependency graph, then this call will cause all upstream  \n\t\t//- connections to be evaluated so that the correct value is supplied.\n\t\tMDataHandle inputData = data.inputValue( input, &returnStatus );\n\n\t\t//- Read the input value from the handle.\n\t\tfloat result = inputData.asFloat();\n\n\t\t//- Get a handle to the output attribute. This is similar to the\n\t\t//- \"inputValue\" call above except that no dependency graph \n\t\t//- computation will be done as a result of this call.\n\n\t\t//- Get a handle on the aOutput attribute\n\t\tMDataHandle outputHandle = data.outputValue( simpleNode::output );\n\n\t\t//- Set the new output value to the handle.\n\t\toutputHandle.set( result * 2 );\n\n\t\t//- Mark the destination plug as being clean. This will prevent the\n\t\t//- dependency graph from repeating this calculation until an input \n\t\t//- attribute of this node which affects this output attribute changes.\n\n\t\t//- Tell Maya the plug is now clean\n\t\tdata.setClean(plug);\n\n\t\t//- Return success to Maya\n\t\treturn MS::kSuccess;\n\t}\n\n\t//- Tell Maya that we do not know how to handle this plug, but let give a chance\n\t//- to our parent class to evaluate it.\n\treturn MS::kUnknownParameter;\n}\n"
  },
  {
    "path": "04_NodeAttributes/simpleNode - with Typed Attr/Solution - C++/simpleNode.h",
    "content": "//\n// Copyright (C) \n// \n// File: simpleNode.h\n//\n// Dependency Graph Node: simpleNode\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#pragma once\n\n//- Include Maya necessary headers for our class\n#include <maya/MPxNode.h>\n#include <maya/MFnNumericAttribute.h>\n#include <maya/MFnTypedAttribute.h>\n#include <maya/MFnStringData.h>\n#include <maya/MTypeId.h> \n#include <maya/MPlug.h>\n#include <maya/MDataBlock.h>\n#include <maya/MDataHandle.h>\n\n//- Derive a new class from the default Maya node proxy class.\nclass simpleNode : public MPxNode\n{\npublic:\n\tsimpleNode() {\n\t\t//- Never do anything here which would affect Maya.\n\t\t//- Instead implement the virtual postConstructor() method.\n\t}\n\tvirtual ~simpleNode() {}\n\n\t//- Declare the virtual compute() method.\n\tvirtual MStatus\t\tcompute( const MPlug& plug, MDataBlock& data );\n\n\t//- Declare/implement the static creator method.\n\t//- This method exists to give Maya a way to create new objects\n\t//- of this type. \n\tstatic  void*\t\tcreator() {\n\t\treturn new simpleNode();\n\t}\n\n\t//- Declare the static initialize() method.\n\tstatic  MStatus\t\tinitialize();\n\npublic:\n\t// There needs to be a MObject handle declared for each attribute that\n\t// the node will have.  These handles are needed for getting and setting\n\t// the values later.\n\t//\n\tstatic  MObject\t\tinput;\t\t// input attribute\n\tstatic  MObject\t\toutput;\t\t// output attribute\n\tstatic\tMObject\t\tdescString; // Description string attribute describing the function of this node\n\n\n\t//- This is a unique node ID for your new node class. It is declared\n\t//- static because it is common to all instance of that class.\n\t//-\n\t//- The typeid is a unique 32bit identifier that describes this node.\n\t//- It is used to save and retrieve nodes of this type from the binary\n\t//- file format. If it is not unique, it will cause file IO problems.\n\tstatic\tMTypeId\t\tid;\n};\n"
  },
  {
    "path": "04_NodeAttributes/simpleNode - with Typed Attr/Solution - C++/simpleNode.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 2012\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"simpleNode\", \"simpleNode.vcxproj\", \"{439648C5-792B-4918-AC04-5B034F382742}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|x64 = Debug|x64\n\t\tRelease|x64 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{439648C5-792B-4918-AC04-5B034F382742}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{439648C5-792B-4918-AC04-5B034F382742}.Debug|x64.Build.0 = Debug|x64\n\t\t{439648C5-792B-4918-AC04-5B034F382742}.Release|x64.ActiveCfg = Release|x64\n\t\t{439648C5-792B-4918-AC04-5B034F382742}.Release|x64.Build.0 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "04_NodeAttributes/simpleNode - with Typed Attr/Solution - C++/simpleNode.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{439648C5-792B-4918-AC04-5B034F382742}</ProjectGuid>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup>\n    <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">Debug\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">Debug\\</IntDir>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Release\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Release\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <OutDir>C:\\MayaAPITraining\\plug-ins\\</OutDir>\n    <TargetExt>.mll</TargetExt>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2009\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/simpleNode.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>C:\\My Documents\\maya\\2009\\plug-ins\\simpleNode.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2009\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/simpleNode.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/simpleNode.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2015\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/simpleNode.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>C:\\MayaAPITraining\\plug-ins\\simpleNode.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2015\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/simpleNode.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/simpleNode.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/simpleNode.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\simpleNode.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/simpleNode.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/simpleNode.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/simpleNode.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\simpleNode.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/simpleNode.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/simpleNode.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"pluginMain.cpp\" />\n    <ClCompile Include=\"simpleNode.cpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"simpleNode.h\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "04_NodeAttributes/simpleNode - with Typed Attr/Solution - py/simpleNode.py",
    "content": "#\n# Copyright (C) \n# \n# File: simpleNode.cpp\n#\n# Dependency Graph Node: simpleNode\n#\n# Author: Maya Plug-in Wizard 2.0\n#\n\nimport maya.OpenMaya as OpenMaya\nimport maya.OpenMayaMPx as OpenMayaMPx\n\n#- Assing a unique node ID to your new node class.\n#- Ask ADN or Autodesk product support to reserve IDs for your company. You can\n#- reserve ID by block of 64, 128, 256, or 512 consecutive ID.\n#-\n#- 0x80001 is a temporary ID for reserved for development. Never use that ID in a\n#- production environement.\nkPluginNodeTypeName = \"simpleNode\"\nsimpleNodeId = OpenMaya.MTypeId(0x80001)\n\n# Node definition\nclass simpleNode(OpenMayaMPx.MPxNode):\n\t# Node attributes\n\tinput = OpenMaya.MObject()\n\toutput = OpenMaya.MObject()\n\tdescString = OpenMaya.MObject()\n\t\n\tdef __init__(self):\n\t\tOpenMayaMPx.MPxNode.__init__(self)\n\t\t\n\t#- This method computes the value of the given output plug based\n\t#- on the values of the input attributes.\n\t#- Arguments:\n\t#- \tplug - the plug to compute\n\t#- \tdata - object that provides access to the attributes for this node\n\tdef compute(self,plug,dataBlock):\n\t\tif ( plug == simpleNode.output ):\n\t\t\t#- Get a handle to the input attribute that we will need for the\n\t\t\t#- computation. If the value is being supplied via a connection \n\t\t\t#- in the dependency graph, then this call will cause all upstream  \n\t\t\t#- connections to be evaluated so that the correct value is supplied.\n\t\t\tinputData = dataBlock.inputValue( simpleNode.input )\n\t\t\t\n\t\t\t#- Read the input value from the handle.\n\t\t\tresult = inputData.asFloat()\n\n\t\t\t#- Get a handle to the output attribute. This is similar to the\n\t\t\t#- \"inputValue\" call above except that no dependency graph \n\t\t\t#- computation will be done as a result of this call.\n\n\t\t\t#- Get a handle on the aOutput attribute\n\t\t\toutputHandle = dataBlock.outputValue( simpleNode.output )\n\n\t\t\t#- Set the new output value to the handle.\n\t\t\toutputHandle.setFloat( result * 2 );\n\n\t\t\t#- Mark the destination plug as being clean. This will prevent the\n\t\t\t#- dependency graph from repeating this calculation until an input \n\t\t\t#- attribute of this node which affects this output attribute changes.\n\n\t\t\t#- Tell Maya the plug is now clean\n\t\t\tdataBlock.setClean( plug )\n\n\t\t#- Tell Maya that we do not know how to handle this plug, but let give a chance\n\t\t#- to our parent class to evaluate it.\n\t\treturn OpenMaya.kUnknownParameter\n\n# Creator\ndef nodeCreator():\n\treturn OpenMayaMPx.asMPxPtr( simpleNode() )\n\n#- The initialize method is called to create and initialize all of the \n#- attributes and attribute dependencies for this node type. This is \n#- only called once when the node type is registered with Maya.\n#-\ndef nodeInitializer():\n\t#- Initialize a float input attribute using the MFnNumericAttribute\n\t#- class. Make that attribute definition saved into Maya file (setStorable),\n\t#- and selectable in the channel box (setKeyable).\n\n\t#- Create a generic attribute using MFnNumericAttribute\n\tnAttr = OpenMaya.MFnNumericAttribute()\n\tsimpleNode.input = nAttr.create( \"input\", \"in\", OpenMaya.MFnNumericData.kFloat, 0.0 )\n\t#- Attribute will be written to files when this type of node is stored\n \tnAttr.setStorable(1)\n\t#- Attribute is keyable and will show up in the channel box\n \tnAttr.setKeyable(1)\n\n\t#- Initialize a float output attribute using the MFnNumericAttribute\n\t#- class. Make that attribute definition not saved into Maya file.\n\tsimpleNode.output = nAttr.create( \"output\", \"out\", OpenMaya.MFnNumericData.kFloat, 0.0 )\n\t#- Attribute will not be written to files when this type of node is stored\n\tnAttr.setStorable(0)\n\t\n\t#- Initialize a string output attribute using the MFnTypedAttribute\n\t#- class.In order to specify the attribute default value, you will need to \n\t#- use the MFnStringData class, before creating the attribute itself.\n\n\t#- Create a MFnTypedAttribute instance\n\ttypedAttr = OpenMaya.MFnTypedAttribute()\n\t#- Use MFnStringData to create default value of this attribute\n\tfnStringData = OpenMaya.MFnStringData()\n\tdefaultStringObj = fnStringData.create(\"description string for current node\")\n\tsimpleNode.descString = typedAttr.create(\"descString\", \"dStr\", OpenMaya.MFnData.kString,defaultStringObj)\n\n\t#- Now add the attribute to your node definition using the addAttribute()\n\t#- method.\n\t#- Add the attributes we have created to the node\n\tsimpleNode.addAttribute( simpleNode.input );\t\n\tsimpleNode.addAttribute( simpleNode.output );\n\t#- Add the string attribute to the node type definition\n\tsimpleNode.addAttribute(simpleNode.descString);\n\t\n\t#- Finally tell Maya how the information should flow through your node.\n\t#- This will also tell Maya how the dirty flag is propagated in your node\n\t#- and ultimatelly in the Maya DG. To do this, use the attributeAffects()\n\t#- method to link your node' attributes together.\n\n\t#- Set up a dependency between the input and the output. This will cause\n\t#- the output to be marked dirty when the input changes. The output will\n\t#- then be recomputed the next time the value of the output is requested.\n\tsimpleNode.attributeAffects( simpleNode.input, simpleNode.output );\n\n# Initialize the script plug-in\ndef initializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\tmplugin.registerNode( kPluginNodeTypeName, simpleNodeId, nodeCreator, nodeInitializer )\n\texcept:\n\t\tsys.stderr.write( \"Failed to register node: %s\" % kPluginNodeTypeName )\n\t\traise\n\n# Uninitialize the script plug-in\ndef uninitializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\tmplugin.deregisterNode( simpleNodeId )\n\texcept:\n\t\tsys.stderr.write( \"Failed to deregister node: %s\" % kPluginNodeTypeName )\n\t\traise\n"
  },
  {
    "path": "05_DependencyGraph/retrieveWeight/Exercise - C++/pluginMain.cpp",
    "content": "//\n// Copyright (C) \n// \n// File: pluginMain.cpp\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n\n#include \"retrieveWeightCmd.h\"\n\n#include <maya/MFnPlugin.h>\n\nMStatus initializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is loaded into Maya.  It \n//\t\tregisters all of the services that this plug-in provides with \n//\t\tMaya.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{ \n\tMStatus   status;\n\tMFnPlugin plugin( obj, \"\", \"2009\", \"Any\");\n\n\tstatus = plugin.registerCommand( \"retrieveWeight\", retrieveWeightCmd::creator);\n\n\tif (!status) {\n\t\tstatus.perror(\"registerCommand\");\n\t\treturn status;\n\t}\n\n\treturn status;\n}\n\nMStatus uninitializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is unloaded from Maya. It \n//\t\tderegisters all of the services that it was providing.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{\n\tMStatus   status;\n\tMFnPlugin plugin( obj );\n\n\tstatus = plugin.deregisterCommand( \"retrieveWeight\" );\n\n\tif (!status) {\n\t\tstatus.perror(\"deregisterCommand\");\n\t\treturn status;\n\t}\n\n\treturn status;\n}\n"
  },
  {
    "path": "05_DependencyGraph/retrieveWeight/Exercise - C++/retrieveWeight.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 2012\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"retrieveWeight\", \"retrieveWeight.vcxproj\", \"{F784655E-05CD-477E-8AFD-79B576ED550B}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|x64 = Debug|x64\n\t\tRelease|x64 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{F784655E-05CD-477E-8AFD-79B576ED550B}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{F784655E-05CD-477E-8AFD-79B576ED550B}.Debug|x64.Build.0 = Debug|x64\n\t\t{F784655E-05CD-477E-8AFD-79B576ED550B}.Release|x64.ActiveCfg = Release|x64\n\t\t{F784655E-05CD-477E-8AFD-79B576ED550B}.Release|x64.Build.0 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "05_DependencyGraph/retrieveWeight/Exercise - C++/retrieveWeight.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{F784655E-05CD-477E-8AFD-79B576ED550B}</ProjectGuid>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup>\n    <_ProjectFileVersion>11.0.61030.0</_ProjectFileVersion>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <OutDir>Debug\\</OutDir>\n    <IntDir>Debug\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <OutDir>C:\\MayaAPITraining\\plug-ins\\</OutDir>\n    <TargetExt>.mll</TargetExt>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <OutDir>Release\\</OutDir>\n    <IntDir>Release\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2009\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>C:\\MayaAPITraining\\plug-ins\\retrieveWeight.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2009\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2015\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>C:\\MayaAPITraining\\plug-ins\\retrieveWeight.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2015\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"pluginMain.cpp\" />\n    <ClCompile Include=\"retrieveWeightCmd.cpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"retrieveWeightCmd.h\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "05_DependencyGraph/retrieveWeight/Exercise - C++/retrieveWeightCmd.cpp",
    "content": "//\n// Copyright (C) \n// \n// File: retrieveWeightCmd.cpp\n//\n// MEL Command: dagScan\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n\n#include \"retrieveWeightCmd.h\"\n#include <maya/MGlobal.h>\n#include <maya/MSelectionList.h>\n#include <maya/MFnDependencyNode.h>\n#include <maya/MPlug.h>\n\nMStatus retrieveWeightCmd::doIt(const MArgList&)\n{\n\tMStatus stat = MS::kSuccess;\n\n\tMObject blendShapeNode;\n\tMSelectionList selList;\n\n\t//- Get the selected blendShape node\n\tstat = MGlobal::getActiveSelectionList(selList);\n\n\tif(selList.length()!=0)\n\t{\n\t\tselList.getDependNode(0,blendShapeNode);\n\n\t\tMFnDependencyNode fnDep(blendShapeNode,&stat);\n\t\t\n\t\t//- TODO: Verify that the node is a Blend Shape\n\t\tif ( //... )\n\t\t{\n\t\t\tMString attrName(\"weight\");\n\t\t\tMPlug weightArrayPlug = fnDep.findPlug(attrName,&stat);\n\n\t\t\t//- TODO: Find out if this plug is a multi plug\n\t\t\tif( //... )\n\t\t\t{\n\t\t\t\t//- TODO: Get the name of the plug and print it\n\t\t\t\tMString plugName = //...\n\t\t\t\tcout<<\"Plug \"<<plugName<<\" is an array plug.\"<<endl;\n\t\t\t\t\n\t\t\t\t//- Find how many elements are in this multi plug\n\t\t\t\tint numberOfElem = weightArrayPlug.numElements();\n\t\t\t\tcout<<\"This plug has \"<<numberOfElem<<\" elements.\"<<endl;\n\n\t\t\t\t//- Traverse all the element plugs \n\t\t\t\tfor (int j = 0 ; j < numberOfElem; j++ )\n\t\t\t\t{\n\t\t\t\t\t//- You can also use like the following line, [], because bracket operator uses physical indexes\n\t\t\t\t\t//- MPlug elementPlug = weightArrayPlug [i];\n\n\t\t\t\t\tMPlug elementPlug = weightArrayPlug.elementByPhysicalIndex(j, &stat);\n\t\t\t\t\t\n\t\t\t\t\t//- Print out the element plug's physical index and logical index\n\t\t\t\t\tcout<<\"Physical index: \"<<j<<\";      \"<<\"Logical index: \"<<elementPlug.logicalIndex(&stat)<<endl;\n\n\t\t\t\t\t//- Print out the value in every element plug\n\t\t\t\t\tdouble valueElem;\n\t\t\t\t\tstat = elementPlug.getValue(valueElem);\n\t\t\t\t\tcout<<\"The value in this element plug is \"<<valueElem<<endl;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn stat;\n}\n\n"
  },
  {
    "path": "05_DependencyGraph/retrieveWeight/Exercise - C++/retrieveWeightCmd.h",
    "content": "//\n// Copyright (C) \n// \n// File: retrieveWeightCmd.h\n//\n// MEL Command: retrieveWeight\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#pragma once\n\n#include <maya/MPxCommand.h>\n\nclass retrieveWeightCmd\t: public MPxCommand\n{\n\npublic:\n\tretrieveWeightCmd() {}\n\tvirtual ~retrieveWeightCmd() {}\n\n\tvirtual MStatus doIt( const MArgList& );\n\n\tstatic void * creator() {\n\t\treturn new retrieveWeightCmd();\n\t}\n\n};\n"
  },
  {
    "path": "05_DependencyGraph/retrieveWeight/Exercise - py/retrieveWeight.py",
    "content": "# Copyright (C) \n# \n# Author: Autodesk Developer Network\n\n#For this exercise, search for the TODO keywords and follow the instructions in\n#comments. If you are unsure of what you need to do, feel free to ask the instructor\n#or look into the solution folder.\n#Each #... line is a line of code you need to write or complete.\n\nimport maya.OpenMaya as OpenMaya\nimport maya.OpenMayaMPx as OpenMayaMPx\nimport sys\n\nkPluginNodeTypeName = \"retrieveWeight\"\n\n# Node definition\nclass retrieveWeight(OpenMayaMPx.MPxCommand):\n\tdef __init__(self):\n\t\tOpenMayaMPx.MPxCommand.__init__(self)\n\t\t\n\tdef doIt(self, args):\n\t\n\n\t\tself.blendShapeNode = OpenMaya.MObject()\n\t\tselList = OpenMaya.MSelectionList()\n\n\t\t#- Get the selected blendShape node\n\t\tOpenMaya.MGlobal.getActiveSelectionList(selList)\n\n\t\tif selList.length()!=0:\n\n\t\t\tselList.getDependNode(0,self.blendShapeNode)\n\t\t\tfnDep = OpenMaya.MFnDependencyNode(self.blendShapeNode)\n\n\t\t\t#- TODO: Verify that the node is a Blend Shape\n\t\t\tif #...\n\n\t\t\t\tweightArrayPlug = fnDep.findPlug(\"weight\")\n\n\t\t\t\t#- TODO: Find out if this plug is a multi plug\n\t\t\t\tif  #...\n\n\t\t\t\t\t#- TODO: Get the name of the plug and print it\n\t\t\t\t\tplugName = #...\n\t\t\t\t\tprint \"Plug %s is an array plug.\" % plugName\n\n\t\t\t\t\t#- Find how many elements are in this multi plug\n\t\t\t\t\tnumberOfElem = weightArrayPlug.numElements()\n\t\t\t\t\tprint \"This plug has %s elements.\" % numberOfElem\n\n\t\t\t\t\t#- Traverse all the element plugs \n\t\t\t\t\tfor j in range(numberOfElem):\n\n\t\t\t\t\t\t#- You can also use like the following line, [], because bracket operator uses physical indexes\n\t\t\t\t\t\t#- MPlug elementPlug = weightArrayPlug [i]\n\n\t\t\t\t\t\telementPlug = weightArrayPlug.elementByPhysicalIndex(j)\n\n\t\t\t\t\t\t#- Print out the element plug's physical index and logical index\n\t\t\t\t\t\tprint \"Physical index: %s; Logical index: %s\" % (j, elementPlug.logicalIndex())\n\n\t\t\t\t\t\t#- TODO: Get the value in every element plug\n\t\t\t\t\t\tvalueElem = #...\n\t\t\t\t\t\tprint \"The value in this element plug is %f\" % valueElem\n\n\t\n# Creator\ndef nodeCreator():\n\treturn OpenMayaMPx.asMPxPtr( retrieveWeight() )\n\n# Initialize the script plug-in\ndef initializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\tmplugin.registerCommand( kPluginNodeTypeName, nodeCreator)\n\texcept:\n\t\tsys.stderr.write( \"Failed to register node: %s\" % kPluginNodeTypeName )\n\t\traise\n\n# Uninitialize the script plug-in\ndef uninitializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\tmplugin.deregisterCommand( kPluginNodeTypeName )\n\texcept:\n\t\tsys.stderr.write( \"Failed to deregister node: %s\" % kPluginNodeTypeName )\n\t\traise\n\t\t\n\n"
  },
  {
    "path": "05_DependencyGraph/retrieveWeight/Solution - C++/pluginMain.cpp",
    "content": "//\n// Copyright (C) \n// \n// File: pluginMain.cpp\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n\n#include \"retrieveWeightCmd.h\"\n\n#include <maya/MFnPlugin.h>\n\nMStatus initializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is loaded into Maya.  It \n//\t\tregisters all of the services that this plug-in provides with \n//\t\tMaya.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{ \n\tMStatus   status;\n\tMFnPlugin plugin( obj, \"\", \"2009\", \"Any\");\n\n\tstatus = plugin.registerCommand( \"retrieveWeight\", retrieveWeightCmd::creator);\n\n\tif (!status) {\n\t\tstatus.perror(\"registerCommand\");\n\t\treturn status;\n\t}\n\n\treturn status;\n}\n\nMStatus uninitializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is unloaded from Maya. It \n//\t\tderegisters all of the services that it was providing.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{\n\tMStatus   status;\n\tMFnPlugin plugin( obj );\n\n\tstatus = plugin.deregisterCommand( \"retrieveWeight\" );\n\n\tif (!status) {\n\t\tstatus.perror(\"deregisterCommand\");\n\t\treturn status;\n\t}\n\n\treturn status;\n}\n"
  },
  {
    "path": "05_DependencyGraph/retrieveWeight/Solution - C++/retrieveWeight.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 2012\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"retrieveWeight\", \"retrieveWeight.vcxproj\", \"{F784655E-05CD-477E-8AFD-79B576ED550B}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|x64 = Debug|x64\n\t\tRelease|x64 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{F784655E-05CD-477E-8AFD-79B576ED550B}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{F784655E-05CD-477E-8AFD-79B576ED550B}.Debug|x64.Build.0 = Debug|x64\n\t\t{F784655E-05CD-477E-8AFD-79B576ED550B}.Release|x64.ActiveCfg = Release|x64\n\t\t{F784655E-05CD-477E-8AFD-79B576ED550B}.Release|x64.Build.0 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "05_DependencyGraph/retrieveWeight/Solution - C++/retrieveWeight.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{F784655E-05CD-477E-8AFD-79B576ED550B}</ProjectGuid>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup>\n    <_ProjectFileVersion>11.0.61030.0</_ProjectFileVersion>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <OutDir>Debug\\</OutDir>\n    <IntDir>Debug\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <OutDir>C:\\MayaAPITraining\\plug-ins\\</OutDir>\n    <TargetExt>.mll</TargetExt>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <OutDir>Release\\</OutDir>\n    <IntDir>Release\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2009\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>C:\\MayaAPITraining\\plug-ins\\retrieveWeight.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2009\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2015\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>C:\\MayaAPITraining\\plug-ins\\retrieveWeight.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2015\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"pluginMain.cpp\" />\n    <ClCompile Include=\"retrieveWeightCmd.cpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"retrieveWeightCmd.h\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "05_DependencyGraph/retrieveWeight/Solution - C++/retrieveWeightCmd.cpp",
    "content": "//\n// Copyright (C) \n// \n// File: retrieveWeightCmd.cpp\n//\n// MEL Command: retrieveWeight\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n\n#include \"retrieveWeightCmd.h\"\n#include <maya/MGlobal.h>\n#include <maya/MSelectionList.h>\n#include <maya/MFnDependencyNode.h>\n#include <maya/MPlug.h>\n\nMStatus retrieveWeightCmd::doIt(const MArgList&)\n{\n\tMStatus stat = MS::kSuccess;\n\n\tMObject blendShapeNode;\n\tMSelectionList selList;\n\n\t//- Get the selected blendShape node\n\tstat = MGlobal::getActiveSelectionList(selList);\n\n\tif(selList.length()!=0)\n\t{\n\t\tselList.getDependNode(0,blendShapeNode);\n\n\t\tMFnDependencyNode fnDep(blendShapeNode,&stat);\n\t\t\n\t\t//- Verify that the node is a Blend Shape\n\t\tif (blendShapeNode.apiType() == MFn::kBlendShape )\n\t\t{\n\t\t\tMString attrName(\"weight\");\n\t\t\tMPlug weightArrayPlug = fnDep.findPlug(attrName,&stat);\n\n\t\t\t//- Find out if this plug is a multi plug\n\t\t\tif(weightArrayPlug.isArray(&stat))\n\t\t\t{\n\t\t\t\tMString plugName = weightArrayPlug.name(&stat);\n\t\t\t\tcout<<\"///////////////////////////////////////////////\"<<endl;\n\t\t\t\tcout<<\"Plug \"<<plugName<<\" is an array plug.\"<<endl;\n\t\t\t\t\n\t\t\t\t//- Find how many elements are in this multi plug\n\t\t\t\tint numberOfElem = weightArrayPlug.numElements();\n\t\t\t\tcout<<\"This plug has \"<<numberOfElem<<\" elements.\"<<endl;\n\n\t\t\t\t//- Traverse all the element plugs \n\t\t\t\tfor (int j = 0 ; j < numberOfElem; j++ )\n\t\t\t\t{\n\t\t\t\t\t//- You can also use like the following line, [], because bracket operator uses physical indexes\n\t\t\t\t\t//- MPlug elementPlug = weightArrayPlug [i];\n\n\t\t\t\t\tMPlug elementPlug = weightArrayPlug.elementByPhysicalIndex(j, &stat);\n\t\t\t\t\t\n\t\t\t\t\t//- Print out the element plug's physical index and logical index\n\t\t\t\t\tcout<<\"Physical index: \"<<j<<\";      \"<<\"Logical index: \"<<elementPlug.logicalIndex(&stat)<<endl;\n\n\t\t\t\t\t//- Print out the value in every element plug\n\t\t\t\t\tdouble valueElem;\n\t\t\t\t\tstat = elementPlug.getValue(valueElem);\n\t\t\t\t\tcout<<\"The value in this element plug is \"<<valueElem<<endl;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\treturn stat;\n}\n\n"
  },
  {
    "path": "05_DependencyGraph/retrieveWeight/Solution - C++/retrieveWeightCmd.h",
    "content": "//\n// Copyright (C) \n// \n// File: retrieveWeightCmd.h\n//\n// MEL Command: retrieveWeight\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#pragma once\n\n#include <maya/MPxCommand.h>\n\nclass retrieveWeightCmd\t: public MPxCommand\n{\n\npublic:\n\tretrieveWeightCmd() {}\n\tvirtual ~retrieveWeightCmd() {}\n\n\tvirtual MStatus doIt( const MArgList& );\n\n\tstatic void * creator() {\n\t\treturn new retrieveWeightCmd();\n\t}\n\n};\n"
  },
  {
    "path": "05_DependencyGraph/retrieveWeight/Solution - py/retrieveWeight.py",
    "content": "#\n# Copyright (C) \n# \n# File: retrieveWeight.py\n#\n# Dependency Graph Node: \n#\n# Author: Maya Plug-in Wizard 2.0\n\n\nimport maya.OpenMaya as OpenMaya\nimport maya.OpenMayaMPx as OpenMayaMPx\nimport sys\n\nkPluginNodeTypeName = \"retrieveWeight\"\n\n# Node definition\nclass retrieveWeight(OpenMayaMPx.MPxCommand):\n\tdef __init__(self):\n\t\tOpenMayaMPx.MPxCommand.__init__(self)\n\t\t\n\tdef doIt(self, args):\n\t\n\n\t\tself.blendShapeNode = OpenMaya.MObject()\n\t\tselList = OpenMaya.MSelectionList()\n\n\t\t#- Get the selected blendShape node\n\t\tOpenMaya.MGlobal.getActiveSelectionList(selList)\n\n\t\tif selList.length()!=0:\n\n\t\t\tselList.getDependNode(0,self.blendShapeNode)\n\t\t\tfnDep = OpenMaya.MFnDependencyNode(self.blendShapeNode)\n\n\t\t\t#- Verify that the node is a Blend Shape\n\t\t\tif self.blendShapeNode.apiType() == OpenMaya.MFn.kBlendShape:\n\n\t\t\t\tweightArrayPlug = fnDep.findPlug(\"weight\")\n\n\t\t\t\t#- Find out if this plug is a multi plug\n\t\t\t\tif weightArrayPlug.isArray():\n\n\t\t\t\t\tplugName = weightArrayPlug.name()\n\t\t\t\t\tprint \"Plug %s is an array plug.\" % plugName\n\n\t\t\t\t\t#- Find how many elements are in this multi plug\n\t\t\t\t\tnumberOfElem = weightArrayPlug.numElements()\n\t\t\t\t\tprint \"This plug has %s elements.\" % numberOfElem\n\n\t\t\t\t\t#- Traverse all the element plugs \n\t\t\t\t\tfor j in range(numberOfElem):\n\n\t\t\t\t\t\t#- You can also use like the following line, [], because bracket operator uses physical indexes\n\t\t\t\t\t\t#- MPlug elementPlug = weightArrayPlug [i]\n\n\t\t\t\t\t\telementPlug = weightArrayPlug.elementByPhysicalIndex(j)\n\n\t\t\t\t\t\t#- Print out the element plug's physical index and logical index\n\t\t\t\t\t\tprint \"Physical index: %s; Logical index: %s\" % (j, elementPlug.logicalIndex())\n\n\t\t\t\t\t\t#- Print out the value in every element plug\n\t\t\t\t\t\tvalueElem = elementPlug.asDouble()\n\t\t\t\t\t\tprint \"The value in this element plug is %f\" % valueElem\n\n\t\n# Creator\ndef nodeCreator():\n\treturn OpenMayaMPx.asMPxPtr( retrieveWeight() )\n\n# Initialize the script plug-in\ndef initializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\tmplugin.registerCommand( kPluginNodeTypeName, nodeCreator)\n\texcept:\n\t\tsys.stderr.write( \"Failed to register node: %s\" % kPluginNodeTypeName )\n\t\traise\n\n# Uninitialize the script plug-in\ndef uninitializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\tmplugin.deregisterCommand( kPluginNodeTypeName )\n\texcept:\n\t\tsys.stderr.write( \"Failed to deregister node: %s\" % kPluginNodeTypeName )\n\t\traise\n\t\t\n\n"
  },
  {
    "path": "06_MiscTools/sceneMsg/Exercise - C++/pluginMain.cpp",
    "content": "//\n// Copyright (C)  \n// \n// File: pluginMain.cpp\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n\n#include <maya/MFnPlugin.h>\n#include \"sceneMsgCmd.h\"\n\nMStatus initializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is loaded into Maya.  It \n//\t\tregisters all of the services that this plug-in provides with \n//\t\tMaya.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{ \n\tMStatus   status;\n\tMFnPlugin plugin( obj, \"\", \"2009\", \"Any\");\n\n\t// Add plug-in feature registration here\n\t//\n\tstatus = plugin.registerCommand(\"sceneMsgCmd\",sceneMsgCmd::creator);\n\n\treturn status;\n}\n\nMStatus uninitializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is unloaded from Maya. It \n//\t\tderegisters all of the services that it was providing.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{\n\tMStatus   status;\n\tMFnPlugin plugin( obj );\n\n\t// Add plug-in feature deregistration here\n\t//\n\tstatus = plugin.deregisterCommand(\"sceneMsgCmd\");\n\n\t//- TODO: You are responsible to remove all the callbacks you have registered in your plug-in code\n\tMCallbackIdArray tempIds = sceneMsgCmd::IDs;\n\tif (tempIds.length() != 0) \n\t\tstatus = //...\n\n\treturn status;\n}\n"
  },
  {
    "path": "06_MiscTools/sceneMsg/Exercise - C++/sceneMsgCmd.cpp",
    "content": "//\n// Copyright (C) \n// \n// File: \n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#include \"sceneMsgCmd.h\"\n\n/*static*/ MCallbackIdArray sceneMsgCmd::IDs;\n\nsceneMsgCmd::sceneMsgCmd()\n{\n\t//- Clean up callback id array\n\tIDs.clear();\n}\n\nMStatus sceneMsgCmd::doIt(const MArgList & args)\n{\n\treturn redoIt();\n}\n\nMStatus sceneMsgCmd::redoIt()\n{\n\tMStatus stat = MS::kSuccess;\n\n\t//- TODO: Register callback for MSceneMessage::kBeforeOpen message\n\tMCallbackId openCallbackId = //...\n\tIDs.append(openCallbackId);\n\n\t//- TODO: Register callback for MSceneMessage::kAfterNew message\n\tMCallbackId newCallbackId = //...\n\tIDs.append(newCallbackId);\n\n\t//- TODO: Register callback for MSceneMessage::kBeforeSave message\n\tMCallbackId saveCheckCallbackId = //...\n\tIDs.append(saveCheckCallbackId);\n\n\treturn stat;\n}\n\nMStatus sceneMsgCmd::undoIt()\n{\n\tMStatus stat = MS::kSuccess;\n\t// TODO: Remove all callbacks\n\tif(IDs.length()!= 0 ) \n\t\tstat = //...\n\treturn stat;\n}\n\n//- Message callbacks\nvoid openCallback(void* clienData)\n{\n\tcout<<\"The callback registered for MSceneMessage::kBeforeOpen is executed.\"<<endl;\n}\n\nvoid newCallback(void* clienData)\n{\n\tcout<<\"The callback registered for MSceneMessage::kAfterNew is executed.\"<<endl;\n}\n\nvoid saveCheckCallback(bool *retCode, void* clienData)\n{\n\tcout<<\"The callback registered for MSceneMessage::kBeforeSaveCheck is executed.\"<<endl;\n\t\n\t//- Abort the operation by setting retCode to point to false\n\t*retCode = false;\n\n\tcout<<\"Abort current operations...\"<<endl;\t\n}\n"
  },
  {
    "path": "06_MiscTools/sceneMsg/Exercise - C++/sceneMsgCmd.h",
    "content": "//\n// Copyright (C) \n// \n// File: \n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#pragma once\n\n#include <maya/MPxCommand.h>\n#include <maya/MCallbackIdArray.h> \n#include <maya/MSceneMessage.h>\n\nclass sceneMsgCmd : public MPxCommand\n{\npublic:\n\tsceneMsgCmd() ;\n\tvirtual ~sceneMsgCmd() {}\n\n\tvirtual MStatus doIt(const MArgList & args);\n\tvirtual MStatus undoIt();\n\tvirtual MStatus redoIt();\n\n\tvirtual bool isUndoable() const {\n\t\treturn (true) ;\n\t}\n\n\tstatic void * creator() {\n\t\treturn new sceneMsgCmd();\n\t}\n\npublic:\n\tstatic MCallbackIdArray IDs;  //- Member variable to record all callback Ids\n\n};\n\n//- Message callbacks\nvoid openCallback(void* clienData);\nvoid newCallback(void* clienData);\nvoid saveCheckCallback(bool *retCode, void* clienData);\n"
  },
  {
    "path": "06_MiscTools/sceneMsg/Exercise - C++/sceneMsgCmd.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 2012\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"sceneMsgCmd\", \"sceneMsgCmd.vcxproj\", \"{6598FA63-51E4-4A33-894E-DF4E5EF90A0F}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|x64 = Debug|x64\n\t\tRelease|x64 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{6598FA63-51E4-4A33-894E-DF4E5EF90A0F}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{6598FA63-51E4-4A33-894E-DF4E5EF90A0F}.Debug|x64.Build.0 = Debug|x64\n\t\t{6598FA63-51E4-4A33-894E-DF4E5EF90A0F}.Release|x64.ActiveCfg = Release|x64\n\t\t{6598FA63-51E4-4A33-894E-DF4E5EF90A0F}.Release|x64.Build.0 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "06_MiscTools/sceneMsg/Exercise - C++/sceneMsgCmd.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{6598FA63-51E4-4A33-894E-DF4E5EF90A0F}</ProjectGuid>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup>\n    <_ProjectFileVersion>11.0.61030.0</_ProjectFileVersion>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <OutDir>Debug\\</OutDir>\n    <IntDir>Debug\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <OutDir>C:\\MayaAPITraining\\plug-ins\\</OutDir>\n    <TargetExt>.mll</TargetExt>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <OutDir>Release\\</OutDir>\n    <IntDir>Release\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2009\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/sceneMsgCmd.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>C:\\MayaAPITraining\\plug-ins\\sceneMsgCmd.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2009\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/sceneMsgCmd.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/sceneMsgCmd.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2015\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/sceneMsgCmd.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>C:\\MayaAPITraining\\plug-ins\\sceneMsgCmd.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2015\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/sceneMsgCmd.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/sceneMsgCmd.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/sceneMsgCmd.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\sceneMsgCmd.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/sceneMsgCmd.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/sceneMsgCmd.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/sceneMsgCmd.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\sceneMsgCmd.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/sceneMsgCmd.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/sceneMsgCmd.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"pluginMain.cpp\" />\n    <ClCompile Include=\"sceneMsgCmd.cpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"sceneMsgCmd.h\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "06_MiscTools/sceneMsg/Exercise - py/sceneMsgCmd.py",
    "content": "# Copyright (C) \n# \n# Author: Autodesk Developer Network\n\n#For this exercise, search for the TODO keywords and follow the instructions in\n#comments. If you are unsure of what you need to do, feel free to ask the instructor\n#or look into the solution folder.\n#Each #... line is a line of code you need to write or complete.\n\nimport maya.OpenMaya as OpenMaya\nimport maya.OpenMayaMPx as OpenMayaMPx\nimport sys\n\nkPluginNodeTypeName = \"sceneMsgCmd\"\n\n\nIDs = OpenMaya.MCallbackIdArray()\n\n\ndef removeCallback(ID):\n\n\tfor i in range(ID.length()):\n\t\ttry:\n\t\t\t#- TODO: You are responsible to remove all the callbacks you have registered in your plug-in code\n\t\t\t#...\n\t\texcept:\n\t\t\tsys.stderr.write( \"Failed to remove callback\\n\" )\n\t\t\traise\n\n\ndef sceneMsgCmd():\n\t#- Clean up callback id array\n\tIDs.clear()\n\n#- Message callbacks\ndef openCallback(clienData):\n\tprint \"The callback registered for MSceneMessage::kBeforeOpen is executed.\"\n\ndef newCallback(clienData):\n\tprint \"The callback registered for MSceneMessage::kAfterNew is executed.\"\n\n\ndef saveCheckCallback(retCode, clienData):\n\tprint \"The callback registered for MSceneMessage::kBeforeSaveCheck is executed.\"\n\n\t#- Abort the operation by setting retCode to point to false\n\tretCode = False\n\n\tprint \"Abort current operations.../n\"\t\n\nclass sceneMsgCmd(OpenMayaMPx.MPxCommand):\n\n\tdef __init__(self):\n\t\tOpenMayaMPx.MPxCommand.__init__(self)\n\t\t\n\tdef doIt(self,argList):\n\t\treturn self.redoIt()\n\t\n\tdef redoIt(self):\n\t\t#- TODO: Register callback for MSceneMessage::kBeforeOpen message\n\t\topenCallbackId = #...\n\t\tIDs.append(openCallbackId)\n\n\t\t#- TODO: Register callback for MSceneMessage::kAfterNew message\n\t\tnewCallbackId = #...\n\t\tIDs.append(newCallbackId)\n\n\t\t#- TODO: Register callback for MSceneMessage::kBeforeSave message\n\t\tsaveCheckCallbackId = #...\n\t\tIDs.append(saveCheckCallbackId)\n\t\t\n\tdef undoIt(self):\n\t\tif IDs.length()!= 0: \n\t\t\tremoveCallback(IDs)\t\t\n\t\n# Creator\ndef nodeCreator():\n\treturn OpenMayaMPx.asMPxPtr( sceneMsgCmd() )\n\n# Initialize the script plug-in\ndef initializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\tmplugin.registerCommand( kPluginNodeTypeName, nodeCreator)\n\texcept:\n\t\tsys.stderr.write( \"Failed to register node: %s\" % kPluginNodeTypeName )\n\t\traise\n\n# Uninitialize the script plug-in\ndef uninitializePlugin(mobject):\n\n\t# Remove the callback\n\tif IDs.length()!= 0:\n\t\tremoveCallback( IDs )\n\t\t\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\tmplugin.deregisterCommand( kPluginNodeTypeName )\n\texcept:\n\t\tsys.stderr.write( \"Failed to deregister node: %s\" % kPluginNodeTypeName )\n\t\traise\n\t\t"
  },
  {
    "path": "06_MiscTools/sceneMsg/Solution - C++/pluginMain.cpp",
    "content": "//\n// Copyright (C)  \n// \n// File: pluginMain.cpp\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n\n#include <maya/MFnPlugin.h>\n#include \"sceneMsgCmd.h\"\n\nMStatus initializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is loaded into Maya.  It \n//\t\tregisters all of the services that this plug-in provides with \n//\t\tMaya.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{ \n\tMStatus   status;\n\tMFnPlugin plugin( obj, \"\", \"2009\", \"Any\");\n\n\t// Add plug-in feature registration here\n\t//\n\tstatus = plugin.registerCommand(\"sceneMsgCmd\",sceneMsgCmd::creator);\n\n\treturn status;\n}\n\nMStatus uninitializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is unloaded from Maya. It \n//\t\tderegisters all of the services that it was providing.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{\n\tMStatus   status;\n\tMFnPlugin plugin( obj );\n\n\t// Add plug-in feature deregistration here\n\t//\n\tstatus = plugin.deregisterCommand(\"sceneMsgCmd\");\n\n\t//- You are responsible to remove all the callbacks you have registered in your plug-in code\n\tMCallbackIdArray tempIds = sceneMsgCmd::IDs;\n\tif (tempIds.length() != 0) \n\t\tstatus = MSceneMessage::removeCallbacks(sceneMsgCmd::IDs);\n\n\treturn status;\n}\n"
  },
  {
    "path": "06_MiscTools/sceneMsg/Solution - C++/sceneMsgCmd.cpp",
    "content": "//\n// Copyright (C) \n// \n// File: sceneMsgCmd.cpp\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#include \"sceneMsgCmd.h\"\n\n/*static*/ MCallbackIdArray sceneMsgCmd::IDs;\n\nsceneMsgCmd::sceneMsgCmd()\n{\n\t//- Clean up callback id array\n\tIDs.clear();\n}\n\nMStatus sceneMsgCmd::doIt(const MArgList & args)\n{\n\treturn redoIt();\n}\n\nMStatus sceneMsgCmd::redoIt()\n{\n\tMStatus stat = MS::kSuccess;\n\n\t//- Register callback for MSceneMessage::kBeforeOpen message\n\tMCallbackId openCallbackId = MSceneMessage::addCallback(MSceneMessage::kBeforeOpen,(MMessage::MBasicFunction)openCallback, NULL,&stat);\n\tIDs.append(openCallbackId);\n\n\t//- Register callback for MSceneMessage::kAfterNew message\n\tMCallbackId newCallbackId = MSceneMessage::addCallback(MSceneMessage::kAfterNew,(MMessage::MBasicFunction)newCallback, NULL,&stat);\n\tIDs.append(newCallbackId);\n\n\t//- Register callback for MSceneMessage::kBeforeSave message\n\tMCallbackId saveCheckCallbackId = MSceneMessage::addCheckCallback(MSceneMessage::kBeforeSaveCheck,(MMessage::MCheckFunction)saveCheckCallback, NULL,&stat);\n\tIDs.append(saveCheckCallbackId);\n\n\treturn stat;\n}\n\nMStatus sceneMsgCmd::undoIt()\n{\n\tMStatus stat = MS::kSuccess;\n\tif(IDs.length()!= 0 ) \n\t\tstat = MSceneMessage::removeCallbacks(IDs);\n\treturn stat;\n}\n\n//- Message callbacks\nvoid openCallback(void* clienData)\n{\n\tcout<<\"The callback registered for MSceneMessage::kBeforeOpen is executed.\"<<endl;\n}\n\nvoid newCallback(void* clienData)\n{\n\tcout<<\"The callback registered for MSceneMessage::kAfterNew is executed.\"<<endl;\n}\n\nvoid saveCheckCallback(bool *retCode, void* clienData)\n{\n\tcout<<\"The callback registered for MSceneMessage::kBeforeSaveCheck is executed.\"<<endl;\n\t\n\t//- Abort the operation by setting retCode to point to false\n\t*retCode = false;\n\n\tcout<<\"Abort current operations...\"<<endl;\t\n}\n"
  },
  {
    "path": "06_MiscTools/sceneMsg/Solution - C++/sceneMsgCmd.h",
    "content": "//\n// Copyright (C) \n// \n// File: sceneMsgCmd.h\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#pragma once\n\n#include <maya/MPxCommand.h>\n#include <maya/MCallbackIdArray.h> \n#include <maya/MSceneMessage.h>\n\nclass sceneMsgCmd : public MPxCommand\n{\npublic:\n\tsceneMsgCmd() ;\n\tvirtual ~sceneMsgCmd() {}\n\n\tvirtual MStatus doIt(const MArgList & args);\n\tvirtual MStatus undoIt();\n\tvirtual MStatus redoIt();\n\n\tvirtual bool isUndoable() const {\n\t\treturn (true) ;\n\t}\n\n\tstatic void * creator() {\n\t\treturn new sceneMsgCmd();\n\t}\n\npublic:\n\tstatic MCallbackIdArray IDs;  //- Member variable to record all callback Ids\n\n};\n\n//- Message callbacks\nvoid openCallback(void* clienData);\nvoid newCallback(void* clienData);\nvoid saveCheckCallback(bool *retCode, void* clienData);\n"
  },
  {
    "path": "06_MiscTools/sceneMsg/Solution - C++/sceneMsgCmd.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 2012\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"sceneMsgCmd\", \"sceneMsgCmd.vcxproj\", \"{6598FA63-51E4-4A33-894E-DF4E5EF90A0F}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|x64 = Debug|x64\n\t\tRelease|x64 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{6598FA63-51E4-4A33-894E-DF4E5EF90A0F}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{6598FA63-51E4-4A33-894E-DF4E5EF90A0F}.Debug|x64.Build.0 = Debug|x64\n\t\t{6598FA63-51E4-4A33-894E-DF4E5EF90A0F}.Release|x64.ActiveCfg = Release|x64\n\t\t{6598FA63-51E4-4A33-894E-DF4E5EF90A0F}.Release|x64.Build.0 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "06_MiscTools/sceneMsg/Solution - C++/sceneMsgCmd.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{6598FA63-51E4-4A33-894E-DF4E5EF90A0F}</ProjectGuid>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup>\n    <_ProjectFileVersion>11.0.61030.0</_ProjectFileVersion>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <OutDir>Debug\\</OutDir>\n    <IntDir>Debug\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <OutDir>C:\\MayaAPITraining\\plug-ins\\</OutDir>\n    <TargetExt>.mll</TargetExt>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <OutDir>Release\\</OutDir>\n    <IntDir>Release\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2009\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/sceneMsgCmd.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>C:\\MayaAPITraining\\plug-ins\\sceneMsgCmd.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2009\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/sceneMsgCmd.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/sceneMsgCmd.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2015\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/sceneMsgCmd.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>C:\\MayaAPITraining\\plug-ins\\sceneMsgCmd.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2015\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/sceneMsgCmd.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/sceneMsgCmd.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/sceneMsgCmd.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\sceneMsgCmd.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/sceneMsgCmd.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/sceneMsgCmd.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/sceneMsgCmd.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\sceneMsgCmd.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/sceneMsgCmd.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/sceneMsgCmd.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"pluginMain.cpp\" />\n    <ClCompile Include=\"sceneMsgCmd.cpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"sceneMsgCmd.h\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "06_MiscTools/sceneMsg/Solution - py/sceneMsgCmd.py",
    "content": "#\n# Copyright (C) \n# \n# File: sceneMsgCmd.py\n#\n# Dependency Graph Node: \n#\n# Author: Maya Plug-in Wizard 2.0\n\n\nimport maya.OpenMaya as OpenMaya\nimport maya.OpenMayaMPx as OpenMayaMPx\nimport sys\n\nkPluginNodeTypeName = \"sceneMsgCmd\"\n\n\nIDs = OpenMaya.MCallbackIdArray()\n\n\ndef removeCallback(ID):\n\n\tfor i in range(ID.length()):\n\t\ttry:\n\t\t\tOpenMaya.MMessage.removeCallback( ID[i] )\n\t\texcept:\n\t\t\tsys.stderr.write( \"Failed to remove callback\\n\" )\n\t\t\traise\n\n\ndef sceneMsgCmd():\n\t#- Clean up callback id array\n\tIDs.clear()\n\n#- Message callbacks\ndef openCallback(clienData):\n\tprint \"The callback registered for MSceneMessage::kBeforeOpen is executed.\"\n\ndef newCallback(clienData):\n\tprint \"The callback registered for MSceneMessage::kAfterNew is executed.\"\n\n\ndef saveCheckCallback(retCode, clienData):\n\tprint \"The callback registered for MSceneMessage::kBeforeSaveCheck is executed.\"\n\n\t#- Abort the operation by setting retCode to point to false\n\tretCode = True\n\t#    OpenMaya.MScriptUtil.setBool(retCode, False)\n\n\tprint \"Abort current operations.../n\"\t\n\nclass sceneMsgCmd(OpenMayaMPx.MPxCommand):\n\n\tdef __init__(self):\n\t\tOpenMayaMPx.MPxCommand.__init__(self)\n\t\t\n\tdef doIt(self,argList):\n\t\treturn self.redoIt()\n\t\n\tdef redoIt(self):\n\t\t#- Register callback for MSceneMessage::kBeforeOpen message\n\t\topenCallbackId = OpenMaya.MSceneMessage.addCallback(OpenMaya.MSceneMessage.kBeforeOpen,openCallback, self)\n\t\tIDs.append(openCallbackId)\n\n\t\t#- Register callback for MSceneMessage::kAfterNew message\n\t\tnewCallbackId = OpenMaya.MSceneMessage.addCallback(OpenMaya.MSceneMessage.kAfterNew,newCallback, self)\n\t\tIDs.append(newCallbackId)\n\n\t\t#- Register callback for MSceneMessage::kBeforeSave message\n\t\tsaveCheckCallbackId = OpenMaya.MSceneMessage.addCheckCallback(OpenMaya.MSceneMessage.kBeforeSaveCheck,saveCheckCallback, self)\n\t\tIDs.append(saveCheckCallbackId)\n\t\t\n\tdef undoIt(self):\n\t\tif IDs.length()!= 0: \n\t\t\tremoveCallback(IDs)\n\t\t\t\n# Creator\ndef nodeCreator():\n\treturn OpenMayaMPx.asMPxPtr( sceneMsgCmd() )\n\n# Initialize the script plug-in\ndef initializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\tmplugin.registerCommand( kPluginNodeTypeName, nodeCreator)\n\texcept:\n\t\tsys.stderr.write( \"Failed to register node: %s\" % kPluginNodeTypeName )\n\t\traise\n\n# Uninitialize the script plug-in\ndef uninitializePlugin(mobject):\n\n\t# Remove the callback\n\tif IDs.length()!= 0:\n\t\tremoveCallback( IDs )\n\t\t\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\tmplugin.deregisterCommand( kPluginNodeTypeName )\n\texcept:\n\t\tsys.stderr.write( \"Failed to deregister node: %s\" % kPluginNodeTypeName )\n\t\traise\n\t\t"
  },
  {
    "path": "06_MiscTools/setUpTransCircle/Exercise - C++/AEtransCircleTemplate.mel",
    "content": "//-\n// ==========================================================================\n// Copyright (C) 1995 - 2006 Autodesk, Inc. and/or its licensors.  All \n// rights reserved.\n//\n// The coded instructions, statements, computer programs, and/or related \n// material (collectively the \"Data\") in these files contain unpublished \n// information proprietary to Autodesk, Inc. (\"Autodesk\") and/or its \n// licensors, which is protected by U.S. and Canadian federal copyright \n// law and by international treaties.\n//\n// The Data is provided for use exclusively by You. You have the right \n// to use, modify, and incorporate this Data into other products for \n// purposes authorized by the Autodesk software license agreement, \n// without fee.\n//\n// The copyright notices in the Software and this entire statement, \n// including the above license grant, this restriction and the \n// following disclaimer, must be included in all copies of the \n// Software, in whole or in part, and all derivative works of \n// the Software, unless such copies or derivative works are solely \n// in the form of machine-executable object code generated by a \n// source language processor.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND. \n// AUTODESK DOES NOT MAKE AND HEREBY DISCLAIMS ANY EXPRESS OR IMPLIED \n// WARRANTIES INCLUDING, BUT NOT LIMITED TO, THE WARRANTIES OF \n// NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR \n// PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE, OR \n// TRADE PRACTICE. IN NO EVENT WILL AUTODESK AND/OR ITS LICENSORS \n// BE LIABLE FOR ANY LOST REVENUES, DATA, OR PROFITS, OR SPECIAL, \n// DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES, EVEN IF AUTODESK \n// AND/OR ITS LICENSORS HAS BEEN ADVISED OF THE POSSIBILITY \n// OR PROBABILITY OF SUCH DAMAGES.\n//\n// ==========================================================================\n//+\n\n//AEtransCircleTemplate.mel\n\nglobal proc AEtransCircleTemplate( string $nodeName )\n{\n\t// Put our attributes into a scrolled layout field\n\n\teditorTemplate -beginScrollLayout;\n\n\t// The all go into the collapsable \"Parameters\" section\n\teditorTemplate -beginLayout \"Parameters\" -collapse false;\n\n\t   // Add a \"special\" control for the scale attribute that allow\n\t   // \"quick set\" options for scales of 5, 10, and 15.\n\t   editorTemplate -callCustom \"transCircleScaleNew\"\n\t   \t\t\t\t  \"transCircleScaleReplace\"\n\t\t\t\t\t  \"scale\";\n\n\t\t// Add the default controls for the scale and frames attributes\n\t\teditorTemplate -addControl \"scale\";\n\t\teditorTemplate -addControl \"frames\";\n\teditorTemplate -endLayout;\n\n\t// Create an \"Extras\" section and also add controls for any\n\t// attributes we have not explicitly mentioned.\n\teditorTemplate -addExtraControls;\n\n\teditorTemplate -endScrollLayout;\n\n\t// Tell the attribute editor not to display the attributes we\n\t// don't care about.\n\teditorTemplate -suppress \"inputTranslate\";\n\teditorTemplate -suppress \"input\";\n\teditorTemplate -suppress \"caching\";\n\teditorTemplate -suppress \"nodeState\";\n}\n\nglobal proc transCircleScaleNew( string $attrName )\n{\n\t// Maya the \"quick set\" control for the scale attribute\n\tradioButtonGrp\n\t\t-label \"Quick Scale\"\n\t\t-numberOfRadioButtons 3\n\t\t-label1 \"Five\"\n\t\t-data1 5\n\t\t-label2 \"Ten\"\n\t\t-data2 10\n\t\t-label3 \"Fifteen\"\n\t\t-data3 15\n\t\tscaleGrp;\n\tconnectControl scaleGrp $attrName;\n}\n\nglobal proc transCircleScaleReplace( string $attrName )\n{\n   // Install the connection between the radioButtonGrp and the\n   // actual scale attribute\n   connectControl scaleGrp $attrName;\n}\n"
  },
  {
    "path": "06_MiscTools/setUpTransCircle/Exercise - C++/pluginMain.cpp",
    "content": "//\n// Copyright (C)  \n// \n// File: pluginMain.cpp\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n\n#include <maya/MFnPlugin.h>\n#include \"setUpTransCircleCmd.h\"\n#include \"transCircleNode.h\"\n\nMStatus initializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is loaded into Maya.  It \n//\t\tregisters all of the services that this plug-in provides with \n//\t\tMaya.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{ \n\tMStatus   status;\n\tMFnPlugin plugin( obj, \"\", \"2009\", \"Any\");\n\n\t// Add plug-in feature registration here\n\t//\n\tstatus = plugin.registerCommand(\"setUpTransCircle\",setUpTransCircle::creator);\n\n\tstatus = plugin.registerNode( \"transCircle\", transCircle::id,transCircle::creator, transCircle::initialize );\n\t\n\tif (!status) {\n\t\tstatus.perror(\"registerNode\");\n\t\treturn status;\n\t}\n\n\treturn status;\n}\n\nMStatus uninitializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is unloaded from Maya. It \n//\t\tderegisters all of the services that it was providing.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{\n\tMStatus   status;\n\tMFnPlugin plugin( obj );\n\n\t// Add plug-in feature deregistration here\n\t//\n\tstatus = plugin.deregisterCommand(\"setUpTransCircle\");\n\n\tstatus = plugin.deregisterNode( transCircle::id );\n\n\tif (!status) {\n\t\tstatus.perror(\"deregisterNode\");\n\t\treturn status;\n\t}\n\n\treturn status;\n}\n"
  },
  {
    "path": "06_MiscTools/setUpTransCircle/Exercise - C++/setUpTransCircle.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 2012\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"setUpTransCircle\", \"setUpTransCircle.vcxproj\", \"{01F0506D-A851-4FE1-B0B9-30C6ABAE30FE}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|x64 = Debug|x64\n\t\tRelease|x64 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{01F0506D-A851-4FE1-B0B9-30C6ABAE30FE}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{01F0506D-A851-4FE1-B0B9-30C6ABAE30FE}.Debug|x64.Build.0 = Debug|x64\n\t\t{01F0506D-A851-4FE1-B0B9-30C6ABAE30FE}.Release|x64.ActiveCfg = Release|x64\n\t\t{01F0506D-A851-4FE1-B0B9-30C6ABAE30FE}.Release|x64.Build.0 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "06_MiscTools/setUpTransCircle/Exercise - C++/setUpTransCircle.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{01F0506D-A851-4FE1-B0B9-30C6ABAE30FE}</ProjectGuid>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup>\n    <_ProjectFileVersion>11.0.61030.0</_ProjectFileVersion>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <OutDir>Debug\\</OutDir>\n    <IntDir>Debug\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <OutDir>C:\\MayaAPITraining\\plug-ins\\</OutDir>\n    <TargetExt>.mll</TargetExt>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <OutDir>Release\\</OutDir>\n    <IntDir>Release\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2009\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>C:\\MayaAPITraining\\plug-ins\\setUpTransCircle.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2009\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2015\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>C:\\MayaAPITraining\\plug-ins\\setUpTransCircle.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2015\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"pluginMain.cpp\" />\n    <ClCompile Include=\"setUpTransCircleCmd.cpp\" />\n    <ClCompile Include=\"transCircleNode.cpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"setUpTransCircleCmd.h\" />\n    <ClInclude Include=\"transCircleNode.h\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "06_MiscTools/setUpTransCircle/Exercise - C++/setUpTransCircleCmd.cpp",
    "content": "//\n// Copyright (C) \n// \n// File: setUpTransCircleCmd.cpp\n//\n// MEL Command: setUpTransCircle\n//\n#include \"setUpTransCircleCmd.h\"\n#include \"transCircleNode.h\"\n\n#include <maya/MGlobal.h>\n#include <maya/MArgDatabase.h>\n#include <maya/MFnDagNode.h>\n#include <maya/MFnCamera.h>\n#include <maya/MFnLight.h>\n#include <maya/MColor.h>\n#include <maya/MDagPath.h>\n#include <maya/MFnNurbsSurface.h>\n#include <maya/MFnMesh.h>\n#include <maya/MSelectionList.h>\n#include <maya/MDagModifier.h>\n\n//- Here is what you need to set up the transCircle node\n//- createNode transCircle -n circleNode1;\n//- sphere -n sphere1 -r 1;\n//- sphere -n sphere2 -r 2;\n//- connectAttr sphere2.translate circleNode1.inputTranslate;\n//- connectAttr circleNode1.outputTranslate sphere1.translate;\n//- connectAttr time1.outTime circleNode1.input;\n\nMStatus setUpTransCircle::doIt( const MArgList& argList)\n{\n\tMStatus stat = MS::kSuccess;\n\t\n\t//- Create a transCircle node and two Nurbs spheres\n\tMString tranCircleType(\"transCircle\");\n\t//- TODO: Create a transCircle node\n\tMObject transCircle = //...\n\t//- TODO: Rename the node to \"circleNode1\" \n\t//...\n\n\t//- TODO: Use MDGMOdifier to simulate executing the following commands \n\t//- command \"sphere -n sphere1 -r 1;\" and command \"sphere -n sphere2 -r 2;\"\n\t//- TIPS: you should create a MString object first\n\t//...\n\t//...\n\t//...\n\t//...\n\t//- TODO: Now force these operation to be executed by calling the DG modifier doIt() method.\n\t//...\n\n//- The following code is one sample code if you want to simulate \"sphere -n sphere1 -r 1\" manually from MDGModifier and MDagModifier\n/*\n\tMObject testNode = dgMod.createNode(MString(\"makeNurbSphere\"),&stat);\n\n\tMFnDependencyNode nurbsSphereFn(testNode);\n\tMPlug radiusPlug = nurbsSphereFn.findPlug(\"radius\");\n\tradiusPlug.setFloat(1.0f);\n\tdgMod.doIt();\n\n\tMDagModifier dagMod;\n\tMObject nurbsTransform = dagMod.createNode(\"nurbsSurface\");\n\tdagMod.doIt();\n    MPlug outputPlug = nurbsSphereFn.findPlug(\"outputSurface\");\n\n\tMFnDagNode transformFn(nurbsTransform);\n\tMFnDagNode nurbsFn(transformFn.child(0));\n\tMPlug createPlug = nurbsFn.findPlug(\"create\");\n\n\tdagMod.connect(outputPlug, createPlug);\n\tdagMod.doIt();\n*/\n\n\tMSelectionList selList;\n\t//- Find the Nurbs sphere nodes and transCircle node\n\tMGlobal::getSelectionListByName(MString(\"sphere1\"),selList);\n\tMObject sphereDep;\n\tselList.getDependNode(0,sphereDep);\n\tselList.clear();\n\n\tMGlobal::getSelectionListByName(MString(\"sphere2\"),selList);\n\tMObject sphereTwoDep;\n\tselList.getDependNode(0,sphereTwoDep);\n\tselList.clear();\n\n\t//- Connect attributes between Nurbs sphere and transCircle node\n\tMFnDependencyNode fnSphere(sphereDep,&stat);\n\tMFnDependencyNode fnSphereTwo(sphereTwoDep,&stat);\n\tMFnDependencyNode fnTransCircleNode(transCircle,&stat);\n\n\tMObject inputTransAttr = fnTransCircleNode.attribute(MString(\"inputTranslate\"),&stat);\n\tMObject sphereTwoTranslateAttr = fnSphereTwo.attribute(MString(\"translate\"),&stat);\n\tdgMod.connect(sphereTwoDep,sphereTwoTranslateAttr,transCircle,inputTransAttr);\n\n\t//- TODO: Connect the \"outputTranslate\" circle node attribute with the \"translate\" \"sphere1\" node attribute\n\t//...\n\t//...\n\t//...\n\n\t//- Connect time1 node with transCircle node\n\tMObject timeNode;\n\tMGlobal::getSelectionListByName(MString(\"time1\"),selList);\n\tselList.getDependNode(0,timeNode);\n\tselList.clear();\n\n\tMFnDependencyNode fnTimeNode(timeNode);\n\tMObject timeAttr = fnTimeNode.attribute(MString(\"outTime\"),&stat);\n\tMObject inputAttr = fnTransCircleNode.attribute(MString(\"input\"),&stat);\n\tdgMod.connect(timeNode,timeAttr,transCircle,inputAttr);\n\n\t//- Now force these operation to be executed by calling the DG modifier doIt() method.\n\tstat = dgMod.doIt();\n\n\treturn stat;\n}\n\nMStatus setUpTransCircle::undoIt()\n{\n\treturn dgMod.undoIt();\n}\n\nMStatus setUpTransCircle::redoIt()\n{\n\treturn dgMod.doIt();\n}"
  },
  {
    "path": "06_MiscTools/setUpTransCircle/Exercise - C++/setUpTransCircleCmd.h",
    "content": "//\n// Copyright (C) \n// \n// File: setUpTransCircleCmd.h\n//\n// MEL Command: setUpTransCircle\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#pragma once\n\n#include <maya/MPxCommand.h>\n#include <maya/MDGModifier.h>\n\nclass MArgList;\n\nclass setUpTransCircle : public MPxCommand\n{\n\npublic:\n\tsetUpTransCircle() {}\n\tvirtual\t\t~setUpTransCircle() {}\n\n\tvirtual MStatus\tdoIt( const MArgList& );\n\tvirtual MStatus\t\tundoIt();\n\tvirtual MStatus\t\tredoIt();\n\n\tvirtual bool isUndoable() const {\n\t\treturn (true);\n\t}\n\n\tstatic void* creator() {\n\t\treturn new setUpTransCircle();\n\t}\n\nprivate:\n\tMDGModifier dgMod;\n\t\n};\n\n"
  },
  {
    "path": "06_MiscTools/setUpTransCircle/Exercise - C++/transCircleNode.cpp",
    "content": "//\n// Copyright (C) \n// \n// File: transCircleNode.cpp\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#include <maya/MString.h> \n#include <maya/MTypeId.h> \n#include <maya/MPlug.h>\n\n#include <maya/MFnNumericAttribute.h>\n\n#include <maya/MDataBlock.h>\n#include <maya/MDataHandle.h>\n\n#include <string.h>\n#include <maya/MIOStream.h>\n#include <math.h>\n\n#include \"transCircleNode.h\"\n\nMTypeId\ttransCircle::id( 0x80013 );\n\nMObject\ttransCircle::input;        \nMObject\ttransCircle::frames;\nMObject\ttransCircle::scale;\nMObject\ttransCircle::inputTranslate;\nMObject\ttransCircle::outputTranslate;\nMObject\ttransCircle::inputTranslateX;\nMObject\ttransCircle::inputTranslateY;\nMObject\ttransCircle::inputTranslateZ;\nMObject\ttransCircle::outputTranslateX;\nMObject\ttransCircle::outputTranslateY;\nMObject\ttransCircle::outputTranslateZ;\n\nMStatus transCircle::initialize()\n{\n\tMFnNumericAttribute nAttr;\n\tMStatus\t\t\t\tstat;\n\n\tinput = nAttr.create( \"input\", \"in\", MFnNumericData::kDouble, 0.0 );\n\tnAttr.setStorable(true);\n\n\tinputTranslateX = nAttr.create( \"inputTranslateX\", \"itX\", MFnNumericData::kDouble, 0.0 );\n\tnAttr.setStorable(true);\n\n\tinputTranslateY = nAttr.create( \"inputTranslateY\", \"itY\", MFnNumericData::kDouble, 0.0 );\n\tnAttr.setStorable(true);\n\n\tinputTranslateZ = nAttr.create( \"inputTranslateZ\", \"itZ\", MFnNumericData::kDouble, 0.0 );\n\tnAttr.setStorable(true);\n\n\tinputTranslate = nAttr.create( \"inputTranslate\", \"it\", \n\t\t\t\t\t\t\t\t\tinputTranslateX,\n\t\t\t\t\t\t\t\t\tinputTranslateY,\n\t\t\t\t\t\t\t\t\tinputTranslateZ );\n\tnAttr.setStorable(true);\n\tnAttr.setDefault(0.0,0.0,0.0);\n\n\toutputTranslateX = nAttr.create( \"outputTranslateX\", \"otX\", MFnNumericData::kDouble, 0.0 );\n\tnAttr.setWritable(false);\n\tnAttr.setStorable(true);\n\n\toutputTranslateY = nAttr.create( \"outputTranslateY\", \"otY\", MFnNumericData::kDouble, 0.0 );\n\tnAttr.setWritable(false);\n\tnAttr.setStorable(true);\n\n\toutputTranslateZ = nAttr.create( \"outputTranslateZ\", \"otZ\", MFnNumericData::kDouble, 0.0 );\n\tnAttr.setWritable(false);\n\tnAttr.setStorable(true);\n\n\toutputTranslate = nAttr.create( \"outputTranslate\", \"ot\", \n\t\t\t\t\t\t\t\t\toutputTranslateX,\n\t\t\t\t\t\t\t\t\toutputTranslateY,\n\t\t\t\t\t\t\t\t\toutputTranslateZ );\n\tnAttr.setWritable(false);\n\tnAttr.setStorable(true);\n\tnAttr.setDefault(0.0,0.0,0.0);\n\n\tscale = nAttr.create( \"scale\", \"sc\", MFnNumericData::kDouble, 10.0 );\n\tnAttr.setStorable(true);\n\n\tframes = nAttr.create( \"frames\", \"fr\", MFnNumericData::kDouble, 48.0 );\n\tnAttr.setStorable(true);\n\n\taddAttribute( inputTranslate );\n\taddAttribute( input );\n\taddAttribute( scale );\n\taddAttribute( frames );\n\taddAttribute( outputTranslate );\n\n\tattributeAffects( inputTranslateX, outputTranslateX );\n\tattributeAffects( inputTranslateY, outputTranslateY );\n\tattributeAffects( inputTranslateZ, outputTranslateZ );\n\tattributeAffects( inputTranslate, outputTranslateX );\n\tattributeAffects( inputTranslate, outputTranslateY );\n\tattributeAffects( inputTranslate, outputTranslateZ );\n\tattributeAffects( inputTranslate, outputTranslate );\n\tattributeAffects( input, outputTranslateX );\n\tattributeAffects( input, outputTranslateY );\n\tattributeAffects( scale, outputTranslateX );\n\tattributeAffects( scale, outputTranslateY );\n\tattributeAffects( frames, outputTranslateX );\n\tattributeAffects( frames, outputTranslateY );\n\n\treturn MS::kSuccess;\n}\n\nMStatus transCircle::compute( const MPlug& plug, MDataBlock& data )\n{\n    MStatus stat;\n \n\tbool k = ( plug == outputTranslateX ) |\n\t         ( plug == outputTranslateY ) |\n\t\t\t ( plug == outputTranslateZ ) |\n\t\t\t ( plug == outputTranslate );\n\tif (!k) return MS::kUnknownParameter;\n\n\tMDataHandle inputData = data.inputValue( input, &stat );\n\tMDataHandle scaleData = data.inputValue( scale, &stat );\n\tMDataHandle framesData = data.inputValue( frames, &stat );\n\tMDataHandle transData  = data.inputValue( inputTranslate, &stat ); \n\tdouble3& iTranslate = transData.asDouble3();\n\tdouble currentFrame = inputData.asDouble();\n\tdouble scaleFactor  = scaleData.asDouble();\n\tdouble framesPerCircle = framesData.asDouble();\n\tdouble angle = 6.2831853 * ( currentFrame/framesPerCircle );\n\tdouble3 oTranslate;\n\t\n\toTranslate[0] = iTranslate[0] + (sin( angle ) * scaleFactor);\n\toTranslate[1] = iTranslate[1] + 1.0;\n\toTranslate[2] = iTranslate[2] + (cos( angle ) * scaleFactor);\n\n\tMDataHandle otHandle = data.outputValue( outputTranslate ); \n\totHandle.set( oTranslate[0], oTranslate[1], oTranslate[2] );\n\tdata.setClean(plug);\n\n    return MS::kSuccess;\n}\n"
  },
  {
    "path": "06_MiscTools/setUpTransCircle/Exercise - C++/transCircleNode.h",
    "content": "//\n// Copyright (C) \n// \n// File: transCircleNode.h\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#pragma once\n\n#include <maya/MPxNode.h>\n\nclass transCircle : public MPxNode\n{\npublic:\n\ttransCircle() {}\n\tvirtual\t~transCircle() {}\n\n\tvirtual MStatus\t\tcompute( const MPlug& plug, MDataBlock& data );\n\tstatic  MStatus\t\tinitialize();\n\tstatic  void*\t\tcreator() {\n\t\treturn new transCircle();\n\t}\n\npublic:\n\tstatic  MObject\t\tinput;            // The input value.\n\tstatic  MObject\t\tinputTranslateX;  // The translate X value.  (input)\n\tstatic  MObject\t\tinputTranslateY;  // The translate Y value.  (input)\n\tstatic  MObject\t\tinputTranslateZ;  // The translate Z value.  (input)\n\tstatic  MObject\t\tinputTranslate;\n\tstatic  MObject\t\toutputTranslateX; // The translate X value.  (output)\n\tstatic  MObject\t\toutputTranslateY; // The translate Y value.  (output)\n\tstatic  MObject\t\toutputTranslateZ; // The translate Z value.  (output)\n\tstatic  MObject\t\toutputTranslate;\n\tstatic  MObject\t\tframes;           // Number of frames for one circle.\n\tstatic  MObject\t\tscale;            // Size of circle.\n\tstatic  MTypeId\t\tid;\n};\n"
  },
  {
    "path": "06_MiscTools/setUpTransCircle/Exercise - py/setUpTransCircle.py",
    "content": "# Copyright (C) \n# \n# Author: Autodesk Developer Network\n\n# For this exercise, search for the TODO keywords and follow the instructions in\n# comments. If you are unsure of what you need to do, feel free to ask the instructor\n# or look into the solution folder.\n# Each #... line is a line of code you need to write or complete.\n\nimport sys, math\n\nimport maya.OpenMaya as OpenMaya\nimport maya.OpenMayaMPx as OpenMayaMPx\n\nkPluginNodeTypeName = \"transCircle\"\nkPluginCmdTypeName = \"setUpTransCircle\"\n\nkPluginNodeId = OpenMaya.MTypeId(0x80013)\n\n# Node definition\nclass transCircle(OpenMayaMPx.MPxNode):\n\t# class variables\n\t# Node attributes\n\t#- Compound attributes in Maya are build from several individual attributes. In\n\t#- our example the translation vector is made of the x,y,z attributes, and the\n\t#- compound attribute itself.\n\taInput = OpenMaya.MObject()\n\taFrames = OpenMaya.MObject()\n\taScale = OpenMaya.MObject()\n\taInputTranslate = OpenMaya.MObject()\n\taInputTranslateX = OpenMaya.MObject()\n\taInputTranslateY = OpenMaya.MObject()\n\taInputTranslateZ = OpenMaya.MObject()\n\taOutputTranslate = OpenMaya.MObject()\n\taOutputTranslateX = OpenMaya.MObject()\n\taOutputTranslateY = OpenMaya.MObject()\n\taOutputTranslateZ = OpenMaya.MObject()\n\t\n\tdef __init__(self):\n\t\tOpenMayaMPx.MPxNode.__init__(self)\n\t#- This method computes the value of the given output plug based\n\t#- on the values of the input attributes.\n\t#- Arguments:\n\t#- \tplug - the plug to compute\n\t#- \tdata - object that provides access to the attributes for this node\n\tdef compute(self, plug, data):\n\t\tif (plug != transCircle.aOutputTranslateX and plug != transCircle.aOutputTranslateY and plug != transCircle.aOutputTranslateZ and plug != transCircle.aOutputTranslate):\n\t\t\treturn OpenMaya.kUnknownParameter\n\t\n\t\tinputData = data.inputValue( transCircle.aInput )\n\t\tscaleData = data.inputValue( transCircle.aScale )\n\t\tframesData = data.inputValue( transCircle.aFrames )\n\t\t\n\t\tcurrentFrame = inputData.asDouble()\n\t\tscaleFactor  = scaleData.asDouble()\n\t\tframesPerCircle = framesData.asDouble()\n\n\t\t#- Retrieve values on individual input translate attribute\n\t\tinputTranslateXHandle = data.inputValue(transCircle.aInputTranslateX)\n\t\tinputTranslateXData = inputTranslateXHandle.asDouble()\n\n\t\tinputTranslateYHandle = data.inputValue(transCircle.aInputTranslateY)\n\t\tinputTranslateYData = inputTranslateYHandle.asDouble()\n\n\t\tinputTranslateZHandle = data.inputValue(transCircle.aInputTranslateZ)\n\t\tinputTranslateZData = inputTranslateZHandle.asDouble()\n\t\t\n\t\t#- Calculate corresponding angle based on current frame \n\t\tangle = 6.2831853 * ( currentFrame/framesPerCircle )\n\t\t\n\t\t#- The value of output translate is input translate value plus the value of circular movement  \n\t\toutputTranslateXData = inputTranslateXData + (math.sin( angle ) * scaleFactor)\n\t\toutputTranslateYData = inputTranslateYData + 1.0\n\t\toutputTranslateZData = inputTranslateZData + (math.cos( angle ) * scaleFactor)\n\n\t\t#- Get a handle on the output attributes and set the new value.\n\t\toutputTranslateXHandle = data.outputValue( transCircle.aOutputTranslateX ) \n\t\toutputTranslateXHandle.setDouble(outputTranslateXData)\n\t\toutputTranslateYHandle = data.outputValue( transCircle.aOutputTranslateY ) \n\t\toutputTranslateYHandle.setDouble(outputTranslateYData)\n\n\t\toutputTranslateZHandle = data.outputValue( transCircle.aOutputTranslateZ ) \n\t\toutputTranslateZHandle.setDouble(outputTranslateZData)\n\t\t\n\t\t#- Tell Maya the plug is now clean\n\t\tdata.setClean(plug)\n\ndef nodeInitializer():\n\t\n\tnAttr = OpenMaya.MFnNumericAttribute()\n\t\n\ttransCircle.aInput = nAttr.create( \"input\", \"in\", OpenMaya.MFnNumericData.kDouble, 0.0 )\n\tnAttr.setStorable(True)\n\n\ttransCircle.aInputTranslateX = nAttr.create( \"inputTranslateX\", \"itX\", OpenMaya.MFnNumericData.kDouble, 0.0 )\n\tnAttr.setStorable(True)\n\n\ttransCircle.aInputTranslateY = nAttr.create( \"inputTranslateY\", \"itY\", OpenMaya.MFnNumericData.kDouble, 0.0 )\n\tnAttr.setStorable(True)\n\n\ttransCircle.aInputTranslateZ = nAttr.create( \"inputTranslateZ\", \"itZ\", OpenMaya.MFnNumericData.kDouble, 0.0 )\n\tnAttr.setStorable(True)\n\n\t#- Create compound input translate attributes and add individual input translate attributes\n\tcomAttr = OpenMaya.MFnCompoundAttribute()\n\ttransCircle.aInputTranslate = comAttr.create(\"inputTranslate\",\"it\")\n\tcomAttr.addChild(transCircle.aInputTranslateX)\n\tcomAttr.addChild(transCircle.aInputTranslateY)\n\tcomAttr.addChild(transCircle.aInputTranslateZ)\n\t\n\tcomAttr.setStorable(True)\n\n\ttransCircle.aOutputTranslateX = nAttr.create( \"outputTranslateX\", \"otX\", OpenMaya.MFnNumericData.kDouble, 0.0 )\n\tnAttr.setWritable(False)\n\tnAttr.setStorable(True)\n\n\ttransCircle.aOutputTranslateY = nAttr.create( \"outputTranslateY\", \"otY\", OpenMaya.MFnNumericData.kDouble, 0.0 )\n\tnAttr.setWritable(False)\n\tnAttr.setStorable(True)\n\n\ttransCircle.aOutputTranslateZ = nAttr.create( \"outputTranslateZ\", \"otZ\", OpenMaya.MFnNumericData.kDouble, 0.0 )\n\tnAttr.setWritable(False)\n\tnAttr.setStorable(True)\n\n\t#- Create compound output translate attributes and add individual output translate attributes\n\ttransCircle.aOutputTranslate = comAttr.create(\"outputTranslate\",\"ot\")\n\tcomAttr.addChild(transCircle.aOutputTranslateX)\n\tcomAttr.addChild(transCircle.aOutputTranslateY)\n\tcomAttr.addChild(transCircle.aOutputTranslateZ)\n\tcomAttr.setWritable(False)\n\tcomAttr.setStorable(True)\n\n\ttransCircle.aScale = nAttr.create( \"scale\", \"sc\", OpenMaya.MFnNumericData.kDouble, 10.0 )\n\tnAttr.setStorable(True)\n\n\ttransCircle.aFrames = nAttr.create( \"frames\", \"fr\", OpenMaya.MFnNumericData.kDouble, 48.0 )\n\tnAttr.setStorable(True)\n\n\ttransCircle.addAttribute( transCircle.aInputTranslate )\n\ttransCircle.addAttribute( transCircle.aInput )\n\ttransCircle.addAttribute( transCircle.aScale )\n\ttransCircle.addAttribute( transCircle.aFrames )\n\ttransCircle.addAttribute( transCircle.aOutputTranslate )\n\n\ttransCircle.attributeAffects( transCircle.aInputTranslateX, transCircle.aOutputTranslateX )\n\ttransCircle.attributeAffects( transCircle.aInputTranslateY, transCircle.aOutputTranslateY )\n\ttransCircle.attributeAffects( transCircle.aInputTranslateZ, transCircle.aOutputTranslateZ )\n\ttransCircle.attributeAffects( transCircle.aInputTranslate, transCircle.aOutputTranslateX )\n\ttransCircle.attributeAffects( transCircle.aInputTranslate, transCircle.aOutputTranslateY )\n\ttransCircle.attributeAffects( transCircle.aInputTranslate, transCircle.aOutputTranslateZ )\n\ttransCircle.attributeAffects( transCircle.aInputTranslate, transCircle.aOutputTranslate )\n\ttransCircle.attributeAffects( transCircle.aInput, transCircle.aOutputTranslateX )\n\ttransCircle.attributeAffects( transCircle.aInput, transCircle.aOutputTranslateY )\n\ttransCircle.attributeAffects( transCircle.aScale, transCircle.aOutputTranslateX )\n\ttransCircle.attributeAffects( transCircle.aScale, transCircle.aOutputTranslateY )\n\ttransCircle.attributeAffects( transCircle.aFrames, transCircle.aOutputTranslateX )\n\ttransCircle.attributeAffects( transCircle.aFrames, transCircle.aOutputTranslateY )\n\t\n# Creator\ndef nodeCreator():\n\treturn OpenMayaMPx.asMPxPtr( transCircle() )\n\t\n# Creators\ndef cmdCreator():\n\treturn OpenMayaMPx.asMPxPtr(setUpTransCircle())\n\n#- Here is what you need to set up the transCircle node\n#- createNode transCircle -n circleNode1\n#- sphere -n sphere1 -r 1\n#- sphere -n sphere2 -r 2\n#- connectAttr sphere2.translate circleNode1.inputTranslate\n#- connectAttr circleNode1.outputTranslate sphere1.translate\n#- connectAttr time1.outTime circleNode1.input\n\nclass setUpTransCircle(OpenMayaMPx.MPxCommand):\n\n\tdef __init__(self):\n\t\tOpenMayaMPx.MPxCommand.__init__(self)\n\t\tself.__dgMod = OpenMaya.MDGModifier()\n\t\t\n\tdef doIt(self,argList):\n\t\tglobal messageId\n\n\t\t#- Create a transCircle node and two Nurbs spheres\n\t\ttransCircle = OpenMaya.MObject()\n\t\ttransCircle = self.__dgMod.createNode(\"transCircle\")\n\t\t#- TODO: Rename the node to \"circleNode1\" \n\t\t#...\n\n\t\t#- TODO: Use MDGMOdifier to simulate executing the following commands \n\t\t#- command \"sphere -n sphere1 -r 1;\" and command \"sphere -n sphere2 -r 2;\"\n\t\t#...\n\t\t#...\n\t\t#...\n\t\t#...\n\t\t#- TODO: Now force these operation to be executed by calling the DG modifier doIt() method.\n\t\t#...\n\n\t\t#- The following code is one sample code if you want to simulate \"sphere -n sphere1 -r 1\" manually from MDGModifier and MDagModifier\n\t\t'''\n\t\ttestNode = OpenMaya.MObject()\n\t\ttestNode = self.__dgMod.createNode(\"makeNurbSphere\")\n\n\t\tnurbsSphereFn = OpenMaya.MFnDependencyNode(testNode)\n\t\tradiusPlug = OpenMaya.MPlug()\n\t\tradiusPlug = nurbsSphereFn.findPlug(\"radius\")\n\t\tradiusPlug.setFloat(1.0f)\n\t\tself.__dgMod.doIt()\n\n\t\tself.dagMod = OpenMaya.MDagModifier()\n\t\tnurbsTransform = OpenMaya.MObject()\n\t\tnurbsTransform = self.dagMod.createNode(\"nurbsSurface\")\n\t\tself.dagMod.doIt()\n\t\toutputPlug = OpenMaya.MPlug()\n\t\toutputPlug = nurbsSphereFn.findPlug(\"outputSurface\")\n\n\n\t\ttransformFn = OpenMaya.MFnDagNode(nurbsTransform)\n\t\tnurbsFn = OpenMaya.MFnDagNode(transformFn.child(0))\n\t\tcreatePlug = OpenMaya.MPlug()\n\t\tcreatePlug = nurbsFn.findPlug(\"create\")\n\n\t\tself.dagMod.connect(outputPlug, createPlug)\n\t\tself.dagMod.doIt()\n\t\t'''\n\n\t\tselList = OpenMaya.MSelectionList()\n\t\t#- Find the Nurbs sphere nodes and transCircle node\n\t\tOpenMaya.MGlobal.getSelectionListByName(\"sphere1\",selList)\n\t\tsphereDep = OpenMaya.MObject()\n\t\tselList.getDependNode(0,sphereDep)\n\t\tselList.clear()\n\n\t\tOpenMaya.MGlobal.getSelectionListByName(\"sphere2\",selList)\n\t\tsphereTwoDep = OpenMaya.MObject()\n\t\tselList.getDependNode(0,sphereTwoDep)\n\t\tselList.clear()\n\n\t\t#- Connect attributes between Nurbs sphere and transCircle node\n\t\tfnSphere= OpenMaya.MFnDependencyNode(sphereDep)\n\t\tfnSphereTwo = OpenMaya.MFnDependencyNode(sphereTwoDep)\n\t\tfnTransCircleNode= OpenMaya.MFnDependencyNode(transCircle)\n\n\t\tinputTransAttr = OpenMaya.MObject()\n\t\tinputTransAttr = fnTransCircleNode.attribute(\"inputTranslate\")\n\t\tsphereTwoTranslateAttr = OpenMaya.MObject()\n\t\tsphereTwoTranslateAttr = fnSphereTwo.attribute(\"translate\")\n\t\tself.__dgMod.connect(sphereTwoDep,sphereTwoTranslateAttr,transCircle,inputTransAttr)\n\n\t\t#- TODO: Connect the \"outputTranslate\" circle node attribute with the \"translate\" \"sphere1\" node attribute\n\t\t#...\n\t\t#...\n\t\t#...\n\t\t\n\t\t#- Connect time1 node with transCircle node\n\t\ttimeNode = OpenMaya.MObject()\n\t\tOpenMaya.MGlobal.getSelectionListByName(\"time1\",selList)\n\t\tselList.getDependNode(0,timeNode)\n\t\tselList.clear()\n\n\t\tfnTimeNode= OpenMaya.MFnDependencyNode(timeNode)\n\t\ttimeAttr = OpenMaya.MObject()\n\t\ttimeAttr = fnTimeNode.attribute(\"outTime\")\n\t\tinputAttr = OpenMaya.MObject()\n\t\tinputAttr = fnTransCircleNode.attribute(\"input\")\n\t\tself.__dgMod.connect(timeNode,timeAttr,transCircle,inputAttr)\n\n\t\t#- Now force these operation to be executed by calling the DG modifier doIt() method.\n\t\tself.__dgMod.doIt()\n\n\tdef isUndoable(self):\n\t\treturn True\n\t\n\tdef undoIt(self):\n\t\treturn self.__dgMod.undoIt()\n\t\n\tdef redoIt(self):\n\t\treturn self.__dgMod.doIt()\n\n# Initialize the script plug-in\ndef initializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\tmplugin.registerNode( kPluginNodeTypeName, kPluginNodeId, nodeCreator, nodeInitializer )\n\t\t\n\texcept:\n\t\tsys.stderr.write( \"Failed to register node: %s\" % kPluginNodeTypeName )\n\t\traise\n\ttry:\n\t\t\n\t\tmplugin.registerCommand( kPluginCmdTypeName, cmdCreator)\n\texcept:\n\t\tsys.stderr.write( \"Failed to register command: %s\" % kPluginCmdTypeName )\n\t\traise\n\n# Uninitialize the script plug-in\ndef uninitializePlugin(mobject):\n\n\t\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\t\n\ttry:\n\t\tmplugin.deregisterNode( kPluginNodeId)\n\t\t\n\texcept:\n\t\tsys.stderr.write( \"Failed to deregister node: %s\" % kPluginNodeTypeName )\n\t\traise\n\n\ttry:\n\t\t\n\t\tmplugin.deregisterCommand( kPluginCmdTypeName )\n\texcept:\n\t\tsys.stderr.write( \"Failed to deregister command: %s\" % kPluginCmdTypeName )\n\t\traise\n\n\t\t"
  },
  {
    "path": "06_MiscTools/setUpTransCircle/Solution - C++/AEtransCircleTemplate.mel",
    "content": "//-\n// ==========================================================================\n// Copyright (C) 1995 - 2006 Autodesk, Inc. and/or its licensors.  All \n// rights reserved.\n//\n// The coded instructions, statements, computer programs, and/or related \n// material (collectively the \"Data\") in these files contain unpublished \n// information proprietary to Autodesk, Inc. (\"Autodesk\") and/or its \n// licensors, which is protected by U.S. and Canadian federal copyright \n// law and by international treaties.\n//\n// The Data is provided for use exclusively by You. You have the right \n// to use, modify, and incorporate this Data into other products for \n// purposes authorized by the Autodesk software license agreement, \n// without fee.\n//\n// The copyright notices in the Software and this entire statement, \n// including the above license grant, this restriction and the \n// following disclaimer, must be included in all copies of the \n// Software, in whole or in part, and all derivative works of \n// the Software, unless such copies or derivative works are solely \n// in the form of machine-executable object code generated by a \n// source language processor.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND. \n// AUTODESK DOES NOT MAKE AND HEREBY DISCLAIMS ANY EXPRESS OR IMPLIED \n// WARRANTIES INCLUDING, BUT NOT LIMITED TO, THE WARRANTIES OF \n// NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR \n// PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE, OR \n// TRADE PRACTICE. IN NO EVENT WILL AUTODESK AND/OR ITS LICENSORS \n// BE LIABLE FOR ANY LOST REVENUES, DATA, OR PROFITS, OR SPECIAL, \n// DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES, EVEN IF AUTODESK \n// AND/OR ITS LICENSORS HAS BEEN ADVISED OF THE POSSIBILITY \n// OR PROBABILITY OF SUCH DAMAGES.\n//\n// ==========================================================================\n//+\n\n//AEtransCircleTemplate.mel\n\nglobal proc AEtransCircleTemplate( string $nodeName )\n{\n\t// Put our attributes into a scrolled layout field\n\n\teditorTemplate -beginScrollLayout;\n\n\t// The all go into the collapsable \"Parameters\" section\n\teditorTemplate -beginLayout \"Parameters\" -collapse false;\n\n\t   // Add a \"special\" control for the scale attribute that allow\n\t   // \"quick set\" options for scales of 5, 10, and 15.\n\t   editorTemplate -callCustom \"transCircleScaleNew\"\n\t   \t\t\t\t  \"transCircleScaleReplace\"\n\t\t\t\t\t  \"scale\";\n\n\t\t// Add the default controls for the scale and frames attributes\n\t\teditorTemplate -addControl \"scale\";\n\t\teditorTemplate -addControl \"frames\";\n\teditorTemplate -endLayout;\n\n\t// Create an \"Extras\" section and also add controls for any\n\t// attributes we have not explicitly mentioned.\n\teditorTemplate -addExtraControls;\n\n\teditorTemplate -endScrollLayout;\n\n\t// Tell the attribute editor not to display the attributes we\n\t// don't care about.\n\teditorTemplate -suppress \"inputTranslate\";\n\teditorTemplate -suppress \"input\";\n\teditorTemplate -suppress \"caching\";\n\teditorTemplate -suppress \"nodeState\";\n}\n\nglobal proc transCircleScaleNew( string $attrName )\n{\n\t// Maya the \"quick set\" control for the scale attribute\n\tradioButtonGrp\n\t\t-label \"Quick Scale\"\n\t\t-numberOfRadioButtons 3\n\t\t-label1 \"Five\"\n\t\t-data1 5\n\t\t-label2 \"Ten\"\n\t\t-data2 10\n\t\t-label3 \"Fifteen\"\n\t\t-data3 15\n\t\tscaleGrp;\n\tconnectControl scaleGrp $attrName;\n}\n\nglobal proc transCircleScaleReplace( string $attrName )\n{\n   // Install the connection between the radioButtonGrp and the\n   // actual scale attribute\n   connectControl scaleGrp $attrName;\n}\n"
  },
  {
    "path": "06_MiscTools/setUpTransCircle/Solution - C++/pluginMain.cpp",
    "content": "//\n// Copyright (C)  \n// \n// File: pluginMain.cpp\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n\n#include <maya/MFnPlugin.h>\n#include \"setUpTransCircleCmd.h\"\n#include \"transCircleNode.h\"\n\nMStatus initializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is loaded into Maya.  It \n//\t\tregisters all of the services that this plug-in provides with \n//\t\tMaya.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{ \n\tMStatus   status;\n\tMFnPlugin plugin( obj, \"\", \"2009\", \"Any\");\n\n\t// Add plug-in feature registration here\n\t//\n\tstatus = plugin.registerCommand(\"setUpTransCircle\",setUpTransCircle::creator);\n\n\tstatus = plugin.registerNode( \"transCircle\", transCircle::id,transCircle::creator, transCircle::initialize );\n\t\n\tif (!status) {\n\t\tstatus.perror(\"registerNode\");\n\t\treturn status;\n\t}\n\n\treturn status;\n}\n\nMStatus uninitializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is unloaded from Maya. It \n//\t\tderegisters all of the services that it was providing.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{\n\tMStatus   status;\n\tMFnPlugin plugin( obj );\n\n\t// Add plug-in feature deregistration here\n\t//\n\tstatus = plugin.deregisterCommand(\"setUpTransCircle\");\n\n\tstatus = plugin.deregisterNode( transCircle::id );\n\n\tif (!status) {\n\t\tstatus.perror(\"deregisterNode\");\n\t\treturn status;\n\t}\n\n\treturn status;\n}\n"
  },
  {
    "path": "06_MiscTools/setUpTransCircle/Solution - C++/setUpTransCircle.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 2012\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"setUpTransCircle\", \"setUpTransCircle.vcxproj\", \"{01F0506D-A851-4FE1-B0B9-30C6ABAE30FE}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|x64 = Debug|x64\n\t\tRelease|x64 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{01F0506D-A851-4FE1-B0B9-30C6ABAE30FE}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{01F0506D-A851-4FE1-B0B9-30C6ABAE30FE}.Debug|x64.Build.0 = Debug|x64\n\t\t{01F0506D-A851-4FE1-B0B9-30C6ABAE30FE}.Release|x64.ActiveCfg = Release|x64\n\t\t{01F0506D-A851-4FE1-B0B9-30C6ABAE30FE}.Release|x64.Build.0 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "06_MiscTools/setUpTransCircle/Solution - C++/setUpTransCircle.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{01F0506D-A851-4FE1-B0B9-30C6ABAE30FE}</ProjectGuid>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup>\n    <_ProjectFileVersion>11.0.61030.0</_ProjectFileVersion>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <OutDir>Debug\\</OutDir>\n    <IntDir>Debug\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <OutDir>C:\\MayaAPITraining\\plug-ins\\</OutDir>\n    <TargetExt>.mll</TargetExt>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <OutDir>Release\\</OutDir>\n    <IntDir>Release\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" />\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2009\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>C:\\MayaAPITraining\\plug-ins\\setUpTransCircle.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2009\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2015\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>C:\\MayaAPITraining\\plug-ins\\setUpTransCircle.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2015\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"pluginMain.cpp\" />\n    <ClCompile Include=\"setUpTransCircleCmd.cpp\" />\n    <ClCompile Include=\"transCircleNode.cpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"setUpTransCircleCmd.h\" />\n    <ClInclude Include=\"transCircleNode.h\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "06_MiscTools/setUpTransCircle/Solution - C++/setUpTransCircleCmd.cpp",
    "content": "//\n// Copyright (C) \n// \n// File: setUpTransCircleCmd.cpp\n//\n// MEL Command: setUpTransCircle\n//\n#include \"setUpTransCircleCmd.h\"\n#include \"transCircleNode.h\"\n\n#include <maya/MGlobal.h>\n#include <maya/MArgDatabase.h>\n#include <maya/MFnDagNode.h>\n#include <maya/MFnCamera.h>\n#include <maya/MFnLight.h>\n#include <maya/MColor.h>\n#include <maya/MDagPath.h>\n#include <maya/MFnNurbsSurface.h>\n#include <maya/MFnMesh.h>\n#include <maya/MSelectionList.h>\n#include <maya/MDagModifier.h>\n\n//- Here is what you need to set up the transCircle node\n//- createNode transCircle -n circleNode1;\n//- sphere -n sphere1 -r 1;\n//- sphere -n sphere2 -r 2;\n//- connectAttr sphere2.translate circleNode1.inputTranslate;\n//- connectAttr circleNode1.outputTranslate sphere1.translate;\n//- connectAttr time1.outTime circleNode1.input;\n\nMStatus setUpTransCircle::doIt( const MArgList& argList)\n{\n\tMStatus stat = MS::kSuccess;\n\t\n\t//- Create a transCircle node and two Nurbs spheres\n\tMString tranCircleType(\"transCircle\");\n\tMObject transCircle = dgMod.createNode(tranCircleType,&stat);\n\tdgMod.renameNode(transCircle,MString(\"circleNode1\"));\n\n\tMString creatingSphereCommand(\"sphere -n sphere1 -r 1;\");\n\tdgMod.commandToExecute(creatingSphereCommand);\n\tMString creatingSphereTwoCommand(\"sphere -n sphere2 -r 2;\");\n\tdgMod.commandToExecute(creatingSphereTwoCommand);\n\t//- ATTENTION: The above operations has to be executed first to make the connecting plugs \n\t//- code work.\n\t//- Now force these operation to be executed by calling the DG modifier doIt() method.\n\tdgMod.doIt();\n\n//- The following code is one sample code if you want to simulate \"sphere -n sphere1 -r 1\" manually from MDGModifier and MDagModifier\n/*\n\tMObject testNode = dgMod.createNode(MString(\"makeNurbSphere\"),&stat);\n\n\tMFnDependencyNode nurbsSphereFn(testNode);\n\tMPlug radiusPlug = nurbsSphereFn.findPlug(\"radius\");\n\tradiusPlug.setFloat(1.0f);\n\tdgMod.doIt();\n\n\tMDagModifier dagMod;\n\tMObject nurbsTransform = dagMod.createNode(\"nurbsSurface\");\n\tdagMod.doIt();\n    MPlug outputPlug = nurbsSphereFn.findPlug(\"outputSurface\");\n\n\tMFnDagNode transformFn(nurbsTransform);\n\tMFnDagNode nurbsFn(transformFn.child(0));\n\tMPlug createPlug = nurbsFn.findPlug(\"create\");\n\n\tdagMod.connect(outputPlug, createPlug);\n\tdagMod.doIt();\n*/\n\n\tMSelectionList selList;\n\t//- Find the Nurbs sphere nodes and transCircle node\n\tMGlobal::getSelectionListByName(MString(\"sphere1\"),selList);\n\tMObject sphereDep;\n\tselList.getDependNode(0,sphereDep);\n\tselList.clear();\n\n\tMGlobal::getSelectionListByName(MString(\"sphere2\"),selList);\n\tMObject sphereTwoDep;\n\tselList.getDependNode(0,sphereTwoDep);\n\tselList.clear();\n\n\t//- Connect attributes between Nurbs sphere and transCircle node\n\tMFnDependencyNode fnSphere(sphereDep,&stat);\n\tMFnDependencyNode fnSphereTwo(sphereTwoDep,&stat);\n\tMFnDependencyNode fnTransCircleNode(transCircle,&stat);\n\n\tMObject inputTransAttr = fnTransCircleNode.attribute(MString(\"inputTranslate\"),&stat);\n\tMObject sphereTwoTranslateAttr = fnSphereTwo.attribute(MString(\"translate\"),&stat);\n\tdgMod.connect(sphereTwoDep,sphereTwoTranslateAttr,transCircle,inputTransAttr);\n\n\tMObject outputTransAttr = fnTransCircleNode.attribute(MString(\"outputTranslate\"),&stat);\n\tMObject sphereTranslateAttr = fnSphere.attribute(MString(\"translate\"),&stat);\n\tdgMod.connect(transCircle,outputTransAttr,sphereDep,sphereTranslateAttr);\n\n\t//- Connect time1 node with transCircle node\n\tMObject timeNode;\n\tMGlobal::getSelectionListByName(MString(\"time1\"),selList);\n\tselList.getDependNode(0,timeNode);\n\tselList.clear();\n\n\tMFnDependencyNode fnTimeNode(timeNode);\n\tMObject timeAttr = fnTimeNode.attribute(MString(\"outTime\"),&stat);\n\tMObject inputAttr = fnTransCircleNode.attribute(MString(\"input\"),&stat);\n\tdgMod.connect(timeNode,timeAttr,transCircle,inputAttr);\n\n\t//- Now force these operation to be executed by calling the DG modifier doIt() method.\n\tstat = dgMod.doIt();\n\n\treturn stat;\n}\n\nMStatus setUpTransCircle::undoIt()\n{\n\treturn dgMod.undoIt();\n}\n\nMStatus setUpTransCircle::redoIt()\n{\n\treturn dgMod.doIt();\n}"
  },
  {
    "path": "06_MiscTools/setUpTransCircle/Solution - C++/setUpTransCircleCmd.h",
    "content": "//\n// Copyright (C) \n// \n// File: setUpTransCircleCmd.h\n//\n// MEL Command: setUpTransCircle\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#pragma once\n\n#include <maya/MPxCommand.h>\n#include <maya/MDGModifier.h>\n\nclass MArgList;\n\nclass setUpTransCircle : public MPxCommand\n{\n\npublic:\n\tsetUpTransCircle() {}\n\tvirtual\t\t~setUpTransCircle() {}\n\n\tvirtual MStatus\tdoIt( const MArgList& );\n\tvirtual MStatus\t\tundoIt();\n\tvirtual MStatus\t\tredoIt();\n\n\tvirtual bool isUndoable() const {\n\t\treturn (true);\n\t}\n\n\tstatic void* creator() {\n\t\treturn new setUpTransCircle();\n\t}\n\nprivate:\n\tMDGModifier dgMod;\n\t\n};\n\n"
  },
  {
    "path": "06_MiscTools/setUpTransCircle/Solution - C++/transCircleNode.cpp",
    "content": "//\n// Copyright (C) \n// \n// File: transCircleNode.cpp\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#include <maya/MString.h> \n#include <maya/MTypeId.h> \n#include <maya/MPlug.h>\n\n#include <maya/MFnNumericAttribute.h>\n\n#include <maya/MDataBlock.h>\n#include <maya/MDataHandle.h>\n\n#include <string.h>\n#include <maya/MIOStream.h>\n#include <math.h>\n\n#include \"transCircleNode.h\"\n\nMTypeId\ttransCircle::id( 0x80013 );\n\nMObject\ttransCircle::input;        \nMObject\ttransCircle::frames;\nMObject\ttransCircle::scale;\nMObject\ttransCircle::inputTranslate;\nMObject\ttransCircle::outputTranslate;\nMObject\ttransCircle::inputTranslateX;\nMObject\ttransCircle::inputTranslateY;\nMObject\ttransCircle::inputTranslateZ;\nMObject\ttransCircle::outputTranslateX;\nMObject\ttransCircle::outputTranslateY;\nMObject\ttransCircle::outputTranslateZ;\n\nMStatus transCircle::initialize()\n{\n\tMFnNumericAttribute nAttr;\n\tMStatus\t\t\t\tstat;\n\n\tinput = nAttr.create( \"input\", \"in\", MFnNumericData::kDouble, 0.0 );\n\tnAttr.setStorable(true);\n\n\tinputTranslateX = nAttr.create( \"inputTranslateX\", \"itX\", MFnNumericData::kDouble, 0.0 );\n\tnAttr.setStorable(true);\n\n\tinputTranslateY = nAttr.create( \"inputTranslateY\", \"itY\", MFnNumericData::kDouble, 0.0 );\n\tnAttr.setStorable(true);\n\n\tinputTranslateZ = nAttr.create( \"inputTranslateZ\", \"itZ\", MFnNumericData::kDouble, 0.0 );\n\tnAttr.setStorable(true);\n\n\tinputTranslate = nAttr.create( \"inputTranslate\", \"it\", \n\t\t\t\t\t\t\t\t\tinputTranslateX,\n\t\t\t\t\t\t\t\t\tinputTranslateY,\n\t\t\t\t\t\t\t\t\tinputTranslateZ );\n\tnAttr.setStorable(true);\n\tnAttr.setDefault(0.0,0.0,0.0);\n\n\toutputTranslateX = nAttr.create( \"outputTranslateX\", \"otX\", MFnNumericData::kDouble, 0.0 );\n\tnAttr.setWritable(false);\n\tnAttr.setStorable(true);\n\n\toutputTranslateY = nAttr.create( \"outputTranslateY\", \"otY\", MFnNumericData::kDouble, 0.0 );\n\tnAttr.setWritable(false);\n\tnAttr.setStorable(true);\n\n\toutputTranslateZ = nAttr.create( \"outputTranslateZ\", \"otZ\", MFnNumericData::kDouble, 0.0 );\n\tnAttr.setWritable(false);\n\tnAttr.setStorable(true);\n\n\toutputTranslate = nAttr.create( \"outputTranslate\", \"ot\", \n\t\t\t\t\t\t\t\t\toutputTranslateX,\n\t\t\t\t\t\t\t\t\toutputTranslateY,\n\t\t\t\t\t\t\t\t\toutputTranslateZ );\n\tnAttr.setWritable(false);\n\tnAttr.setStorable(true);\n\tnAttr.setDefault(0.0,0.0,0.0);\n\n\tscale = nAttr.create( \"scale\", \"sc\", MFnNumericData::kDouble, 10.0 );\n\tnAttr.setStorable(true);\n\n\tframes = nAttr.create( \"frames\", \"fr\", MFnNumericData::kDouble, 48.0 );\n\tnAttr.setStorable(true);\n\n\taddAttribute( inputTranslate );\n\taddAttribute( input );\n\taddAttribute( scale );\n\taddAttribute( frames );\n\taddAttribute( outputTranslate );\n\n\tattributeAffects( inputTranslateX, outputTranslateX );\n\tattributeAffects( inputTranslateY, outputTranslateY );\n\tattributeAffects( inputTranslateZ, outputTranslateZ );\n\tattributeAffects( inputTranslate, outputTranslateX );\n\tattributeAffects( inputTranslate, outputTranslateY );\n\tattributeAffects( inputTranslate, outputTranslateZ );\n\tattributeAffects( inputTranslate, outputTranslate );\n\tattributeAffects( input, outputTranslateX );\n\tattributeAffects( input, outputTranslateY );\n\tattributeAffects( scale, outputTranslateX );\n\tattributeAffects( scale, outputTranslateY );\n\tattributeAffects( frames, outputTranslateX );\n\tattributeAffects( frames, outputTranslateY );\n\n\treturn MS::kSuccess;\n}\n\nMStatus transCircle::compute( const MPlug& plug, MDataBlock& data )\n{\n    MStatus stat;\n \n\tbool k = ( plug == outputTranslateX ) |\n\t         ( plug == outputTranslateY ) |\n\t\t\t ( plug == outputTranslateZ ) |\n\t\t\t ( plug == outputTranslate );\n\tif (!k) return MS::kUnknownParameter;\n\n\tMDataHandle inputData = data.inputValue( input, &stat );\n\tMDataHandle scaleData = data.inputValue( scale, &stat );\n\tMDataHandle framesData = data.inputValue( frames, &stat );\n\tMDataHandle transData  = data.inputValue( inputTranslate, &stat ); \n\tdouble3& iTranslate = transData.asDouble3();\n\tdouble currentFrame = inputData.asDouble();\n\tdouble scaleFactor  = scaleData.asDouble();\n\tdouble framesPerCircle = framesData.asDouble();\n\tdouble angle = 6.2831853 * ( currentFrame/framesPerCircle );\n\tdouble3 oTranslate;\n\t\n\toTranslate[0] = iTranslate[0] + (sin( angle ) * scaleFactor);\n\toTranslate[1] = iTranslate[1] + 1.0;\n\toTranslate[2] = iTranslate[2] + (cos( angle ) * scaleFactor);\n\n\tMDataHandle otHandle = data.outputValue( outputTranslate ); \n\totHandle.set( oTranslate[0], oTranslate[1], oTranslate[2] );\n\tdata.setClean(plug);\n\n    return MS::kSuccess;\n}\n"
  },
  {
    "path": "06_MiscTools/setUpTransCircle/Solution - C++/transCircleNode.h",
    "content": "//\n// Copyright (C) \n// \n// File: transCircleNode.h\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#pragma once\n\n#include <maya/MPxNode.h>\n\nclass transCircle : public MPxNode\n{\npublic:\n\ttransCircle() {}\n\tvirtual\t~transCircle() {}\n\n\tvirtual MStatus\t\tcompute( const MPlug& plug, MDataBlock& data );\n\tstatic  MStatus\t\tinitialize();\n\tstatic  void*\t\tcreator() {\n\t\treturn new transCircle();\n\t}\n\npublic:\n\tstatic  MObject\t\tinput;            // The input value.\n\tstatic  MObject\t\tinputTranslateX;  // The translate X value.  (input)\n\tstatic  MObject\t\tinputTranslateY;  // The translate Y value.  (input)\n\tstatic  MObject\t\tinputTranslateZ;  // The translate Z value.  (input)\n\tstatic  MObject\t\tinputTranslate;\n\tstatic  MObject\t\toutputTranslateX; // The translate X value.  (output)\n\tstatic  MObject\t\toutputTranslateY; // The translate Y value.  (output)\n\tstatic  MObject\t\toutputTranslateZ; // The translate Z value.  (output)\n\tstatic  MObject\t\toutputTranslate;\n\tstatic  MObject\t\tframes;           // Number of frames for one circle.\n\tstatic  MObject\t\tscale;            // Size of circle.\n\tstatic  MTypeId\t\tid;\n};\n"
  },
  {
    "path": "06_MiscTools/setUpTransCircle/Solution - py/setUpTransCircle.py",
    "content": "# Copyright (C) \n# \n# Author: Autodesk Developer Network\n\nimport sys, math\n\nimport maya.OpenMaya as OpenMaya\nimport maya.OpenMayaMPx as OpenMayaMPx\n\nkPluginNodeTypeName = \"transCircle\"\nkPluginCmdTypeName = \"setUpTransCircle\"\n\nkPluginNodeId = OpenMaya.MTypeId(0x80013)\n\n# Node definition\nclass transCircle(OpenMayaMPx.MPxNode):\n\t# class variables\n\t# Node attributes\n\t#- Compound attributes in Maya are build from several individual attributes. In\n\t#- our example the translation vector is made of the x,y,z attributes, and the\n\t#- compound attribute itself.\n\taInput = OpenMaya.MObject()\n\taFrames = OpenMaya.MObject()\n\taScale = OpenMaya.MObject()\n\taInputTranslate = OpenMaya.MObject()\n\taInputTranslateX = OpenMaya.MObject()\n\taInputTranslateY = OpenMaya.MObject()\n\taInputTranslateZ = OpenMaya.MObject()\n\taOutputTranslate = OpenMaya.MObject()\n\taOutputTranslateX = OpenMaya.MObject()\n\taOutputTranslateY = OpenMaya.MObject()\n\taOutputTranslateZ = OpenMaya.MObject()\n\t\n\tdef __init__(self):\n\t\tOpenMayaMPx.MPxNode.__init__(self)\n\t#- This method computes the value of the given output plug based\n\t#- on the values of the input attributes.\n\t#- Arguments:\n\t#- \tplug - the plug to compute\n\t#- \tdata - object that provides access to the attributes for this node\n\tdef compute(self, plug, data):\n\t\tif (plug != transCircle.aOutputTranslateX and plug != transCircle.aOutputTranslateY and plug != transCircle.aOutputTranslateZ and plug != transCircle.aOutputTranslate):\n\t\t\treturn OpenMaya.kUnknownParameter\n\t\n\t\tinputData = data.inputValue( transCircle.aInput )\n\t\tscaleData = data.inputValue( transCircle.aScale )\n\t\tframesData = data.inputValue( transCircle.aFrames )\n\t\t\n\t\tcurrentFrame = inputData.asDouble()\n\t\tscaleFactor  = scaleData.asDouble()\n\t\tframesPerCircle = framesData.asDouble()\n\n\t\t#- Retrieve values on individual input translate attribute\n\t\tinputTranslateXHandle = data.inputValue(transCircle.aInputTranslateX)\n\t\tinputTranslateXData = inputTranslateXHandle.asDouble()\n\n\t\tinputTranslateYHandle = data.inputValue(transCircle.aInputTranslateY)\n\t\tinputTranslateYData = inputTranslateYHandle.asDouble()\n\n\t\tinputTranslateZHandle = data.inputValue(transCircle.aInputTranslateZ)\n\t\tinputTranslateZData = inputTranslateZHandle.asDouble()\n\t\t\n\t\t#- Calculate corresponding angle based on current frame \n\t\tangle = 6.2831853 * ( currentFrame/framesPerCircle )\n\t\t\n\t\t#- The value of output translate is input translate value plus the value of circular movement  \n\t\toutputTranslateXData = inputTranslateXData + (math.sin( angle ) * scaleFactor)\n\t\toutputTranslateYData = inputTranslateYData + 1.0\n\t\toutputTranslateZData = inputTranslateZData + (math.cos( angle ) * scaleFactor)\n\n\t\t#- Get a handle on the output attributes and set the new value.\n\t\toutputTranslateXHandle = data.outputValue( transCircle.aOutputTranslateX ) \n\t\toutputTranslateXHandle.setDouble(outputTranslateXData)\n\t\toutputTranslateYHandle = data.outputValue( transCircle.aOutputTranslateY ) \n\t\toutputTranslateYHandle.setDouble(outputTranslateYData)\n\n\t\toutputTranslateZHandle = data.outputValue( transCircle.aOutputTranslateZ ) \n\t\toutputTranslateZHandle.setDouble(outputTranslateZData)\n\t\t\n\t\t#- Tell Maya the plug is now clean\n\t\tdata.setClean(plug)\n\ndef nodeInitializer():\n\t\n\tnAttr = OpenMaya.MFnNumericAttribute()\n\t\n\ttransCircle.aInput = nAttr.create( \"input\", \"in\", OpenMaya.MFnNumericData.kDouble, 0.0 )\n\tnAttr.setStorable(True)\n\n\ttransCircle.aInputTranslateX = nAttr.create( \"inputTranslateX\", \"itX\", OpenMaya.MFnNumericData.kDouble, 0.0 )\n\tnAttr.setStorable(True)\n\n\ttransCircle.aInputTranslateY = nAttr.create( \"inputTranslateY\", \"itY\", OpenMaya.MFnNumericData.kDouble, 0.0 )\n\tnAttr.setStorable(True)\n\n\ttransCircle.aInputTranslateZ = nAttr.create( \"inputTranslateZ\", \"itZ\", OpenMaya.MFnNumericData.kDouble, 0.0 )\n\tnAttr.setStorable(True)\n\n\t#- Create compound input translate attributes and add individual input translate attributes\n\tcomAttr = OpenMaya.MFnCompoundAttribute()\n\ttransCircle.aInputTranslate = comAttr.create(\"inputTranslate\",\"it\")\n\tcomAttr.addChild(transCircle.aInputTranslateX)\n\tcomAttr.addChild(transCircle.aInputTranslateY)\n\tcomAttr.addChild(transCircle.aInputTranslateZ)\n\t\n\tcomAttr.setStorable(True)\n\n\ttransCircle.aOutputTranslateX = nAttr.create( \"outputTranslateX\", \"otX\", OpenMaya.MFnNumericData.kDouble, 0.0 )\n\tnAttr.setWritable(False)\n\tnAttr.setStorable(True)\n\n\ttransCircle.aOutputTranslateY = nAttr.create( \"outputTranslateY\", \"otY\", OpenMaya.MFnNumericData.kDouble, 0.0 )\n\tnAttr.setWritable(False)\n\tnAttr.setStorable(True)\n\n\ttransCircle.aOutputTranslateZ = nAttr.create( \"outputTranslateZ\", \"otZ\", OpenMaya.MFnNumericData.kDouble, 0.0 )\n\tnAttr.setWritable(False)\n\tnAttr.setStorable(True)\n\n\t#- Create compound output translate attributes and add individual output translate attributes\n\ttransCircle.aOutputTranslate = comAttr.create(\"outputTranslate\",\"ot\")\n\tcomAttr.addChild(transCircle.aOutputTranslateX)\n\tcomAttr.addChild(transCircle.aOutputTranslateY)\n\tcomAttr.addChild(transCircle.aOutputTranslateZ)\n\tcomAttr.setWritable(False)\n\tcomAttr.setStorable(True)\n\n\ttransCircle.aScale = nAttr.create( \"scale\", \"sc\", OpenMaya.MFnNumericData.kDouble, 10.0 )\n\tnAttr.setStorable(True)\n\n\ttransCircle.aFrames = nAttr.create( \"frames\", \"fr\", OpenMaya.MFnNumericData.kDouble, 48.0 )\n\tnAttr.setStorable(True)\n\n\ttransCircle.addAttribute( transCircle.aInputTranslate )\n\ttransCircle.addAttribute( transCircle.aInput )\n\ttransCircle.addAttribute( transCircle.aScale )\n\ttransCircle.addAttribute( transCircle.aFrames )\n\ttransCircle.addAttribute( transCircle.aOutputTranslate )\n\n\ttransCircle.attributeAffects( transCircle.aInputTranslateX, transCircle.aOutputTranslateX )\n\ttransCircle.attributeAffects( transCircle.aInputTranslateY, transCircle.aOutputTranslateY )\n\ttransCircle.attributeAffects( transCircle.aInputTranslateZ, transCircle.aOutputTranslateZ )\n\ttransCircle.attributeAffects( transCircle.aInputTranslate, transCircle.aOutputTranslateX )\n\ttransCircle.attributeAffects( transCircle.aInputTranslate, transCircle.aOutputTranslateY )\n\ttransCircle.attributeAffects( transCircle.aInputTranslate, transCircle.aOutputTranslateZ )\n\ttransCircle.attributeAffects( transCircle.aInputTranslate, transCircle.aOutputTranslate )\n\ttransCircle.attributeAffects( transCircle.aInput, transCircle.aOutputTranslateX )\n\ttransCircle.attributeAffects( transCircle.aInput, transCircle.aOutputTranslateY )\n\ttransCircle.attributeAffects( transCircle.aScale, transCircle.aOutputTranslateX )\n\ttransCircle.attributeAffects( transCircle.aScale, transCircle.aOutputTranslateY )\n\ttransCircle.attributeAffects( transCircle.aFrames, transCircle.aOutputTranslateX )\n\ttransCircle.attributeAffects( transCircle.aFrames, transCircle.aOutputTranslateY )\n\t\n# Creator\ndef nodeCreator():\n\treturn OpenMayaMPx.asMPxPtr( transCircle() )\n\t\n# Creators\ndef cmdCreator():\n\treturn OpenMayaMPx.asMPxPtr(setUpTransCircle())\n\n#- Here is what you need to set up the transCircle node\n#- createNode transCircle -n circleNode1\n#- sphere -n sphere1 -r 1\n#- sphere -n sphere2 -r 2\n#- connectAttr sphere2.translate circleNode1.inputTranslate\n#- connectAttr circleNode1.outputTranslate sphere1.translate\n#- connectAttr time1.outTime circleNode1.input\n\nclass setUpTransCircle(OpenMayaMPx.MPxCommand):\n\n\tdef __init__(self):\n\t\tOpenMayaMPx.MPxCommand.__init__(self)\n\t\tself.__dgMod = OpenMaya.MDGModifier()\n\t\t\n\tdef doIt(self,argList):\n\t\t#- Create a transCircle node and two Nurbs spheres\n\t\t#transCircle = OpenMaya.MObject()\n\t\ttransCircle = self.__dgMod.createNode(\"transCircle\")\n\t\tself.__dgMod.renameNode(transCircle,\"circleNode1\")\n\n\t\tcreatingSphereCommand = \"sphere -n sphere1 -r 1\"\n\t\tself.__dgMod.commandToExecute(creatingSphereCommand)\n\t\tcreatingSphereTwoCommand = \"sphere -n sphere2 -r 2\"\n\t\tself.__dgMod.commandToExecute(creatingSphereTwoCommand)\n\t\t\n\t\t#- ATTENTION: The above operations has to be executed first to make the connecting plugs \n\t\t#- code work.\n\t\t#- Now force these operation to be executed by calling the DG modifier doIt() method.\n\t\tself.__dgMod.doIt()\n\n\t\tselList = OpenMaya.MSelectionList()\n\t\t#- Find the Nurbs sphere nodes and transCircle node\n\t\tOpenMaya.MGlobal.getSelectionListByName(\"sphere1\",selList)\n\t\tsphereDep = OpenMaya.MObject()\n\t\tselList.getDependNode(0,sphereDep)\n\t\tselList.clear()\n\n\t\tOpenMaya.MGlobal.getSelectionListByName(\"sphere2\",selList)\n\t\tsphereTwoDep = OpenMaya.MObject()\n\t\tselList.getDependNode(0,sphereTwoDep)\n\t\tselList.clear()\n\n\t\t#- Connect attributes between Nurbs sphere and transCircle node\n\t\tfnSphere= OpenMaya.MFnDependencyNode(sphereDep)\n\t\tfnSphereTwo = OpenMaya.MFnDependencyNode(sphereTwoDep)\n\t\tfnTransCircleNode= OpenMaya.MFnDependencyNode(transCircle)\n\n\n\t\t\n\t\tinputTransAttr = fnTransCircleNode.attribute(\"inputTranslate\")\n\t\t\n\t\tsphereTwoTranslateAttr = fnSphereTwo.attribute(\"translate\")\n\t\tself.__dgMod.connect(sphereTwoDep,sphereTwoTranslateAttr,transCircle,inputTransAttr)\n\n\t\t\n\t\toutputTransAttr = fnTransCircleNode.attribute(\"outputTranslate\")\n\t\t\n\t\tsphereTranslateAttr = fnSphere.attribute(\"translate\")\n\t\tself.__dgMod.connect(transCircle,outputTransAttr,sphereDep,sphereTranslateAttr)\n\n\t\t#- Connect time1 node with transCircle node\n\t\ttimeNode = OpenMaya.MObject()\n\t\tOpenMaya.MGlobal.getSelectionListByName(\"time1\",selList)\n\t\tselList.getDependNode(0,timeNode)\n\t\tselList.clear()\n\n\t\tfnTimeNode= OpenMaya.MFnDependencyNode(timeNode)\n\t\ttimeAttr = OpenMaya.MObject()\n\t\ttimeAttr = fnTimeNode.attribute(\"outTime\")\n\t\tinputAttr = OpenMaya.MObject()\n\t\tinputAttr = fnTransCircleNode.attribute(\"input\")\n\t\tself.__dgMod.connect(timeNode,timeAttr,transCircle,inputAttr)\n\n\t\t#- Now force these operation to be executed by calling the DG modifier doIt() method.\n\t\tself.__dgMod.doIt()\n\n\tdef isUndoable(self):\n\t\treturn True\n\t\t\n\tdef undoIt(self):\n\t\n\t\treturn self.__dgMod.undoIt()\n\t\n\tdef redoIt(self):\n\t\treturn self.__dgMod.doIt()\n\n# Initialize the script plug-in\ndef initializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\tmplugin.registerNode( kPluginNodeTypeName, kPluginNodeId, nodeCreator, nodeInitializer )\n\t\t\n\texcept:\n\t\tsys.stderr.write( \"Failed to register node: %s\" % kPluginNodeTypeName )\n\t\traise\n\ttry:\n\t\tmplugin.registerCommand( kPluginCmdTypeName, cmdCreator)\n\t\t\n\texcept:\n\t\tsys.stderr.write( \"Failed to register command: %s\" % kPluginCmdTypeName )\n\t\traise\n\n# Uninitialize the script plug-in\ndef uninitializePlugin(mobject):\n\n\t\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\t\n\ttry:\n\t\tmplugin.deregisterNode( kPluginNodeId)\n\t\t\n\texcept:\n\t\tsys.stderr.write( \"Failed to deregister node: %s\" % kPluginNodeTypeName )\n\t\traise\n\n\ttry:\n\t\t\n\t\tmplugin.deregisterCommand( kPluginCmdTypeName )\n\texcept:\n\t\tsys.stderr.write( \"Failed to deregister command: %s\" % kPluginCmdTypeName )\n\t\traise\n\n\t\t"
  },
  {
    "path": "07_Locator/arrowLocator/Exercise - C++/arrowLocator.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 2012\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"arrowLocator\", \"arrowLocator.vcxproj\", \"{2A76853E-2C9D-4719-B6C7-6A787EEED416}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|x64 = Debug|x64\n\t\tRelease|x64 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{2A76853E-2C9D-4719-B6C7-6A787EEED416}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{2A76853E-2C9D-4719-B6C7-6A787EEED416}.Debug|x64.Build.0 = Debug|x64\n\t\t{2A76853E-2C9D-4719-B6C7-6A787EEED416}.Release|x64.ActiveCfg = Release|x64\n\t\t{2A76853E-2C9D-4719-B6C7-6A787EEED416}.Release|x64.Build.0 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "07_Locator/arrowLocator/Exercise - C++/arrowLocator.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{2A76853E-2C9D-4719-B6C7-6A787EEED416}</ProjectGuid>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup>\n    <_ProjectFileVersion>11.0.50727.1</_ProjectFileVersion>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <OutDir>Debug\\</OutDir>\n    <IntDir>Debug\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <OutDir>$(Platform)\\$(Configuration)\\</OutDir>\n    <IntDir>$(Platform)\\$(Configuration)\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <OutDir>Release\\</OutDir>\n    <IntDir>Release\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <OutDir>$(Platform)\\$(Configuration)\\</OutDir>\n    <IntDir>$(Platform)\\$(Configuration)\\</IntDir>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2014\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;OpenMayaUI.lib;opengl32.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>C:\\MayaAPITraining\\plug-ins\\arrowLocator.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2015\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <Midl>\n      <TargetEnvironment>X64</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2015\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;OpenMayaRender.lib;OpenMayaUI.lib;opengl32.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>C:\\MayaAPITraining\\plug-ins\\arrowLocator.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2015\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/.lib</ImportLibrary>\n      <TargetMachine>MachineX64</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;OpenMayaUI.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <Midl>\n      <TargetEnvironment>X64</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;OpenMayaUI.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/.lib</ImportLibrary>\n      <TargetMachine>MachineX64</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"arrowLocatorNode.cpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"arrowLocatorNode.h\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "07_Locator/arrowLocator/Exercise - C++/arrowLocatorNode.cpp",
    "content": "//\n// Copyright (C) \n// \n// File: arrowLocatorNode.cpp\n//\n// Dependency Graph Node: arrowLocator\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#include \"arrowLocatorNode.h\"\n\n#include <maya/MPlug.h>\n#include <maya/MDataBlock.h>\n#include <maya/MDataHandle.h>\n\n#include <maya/MGlobal.h>\n#include <maya/MFnDagNode.h>\n#include <maya/MFnUnitAttribute.h>\n#include <maya/MAngle.h>\n#include <maya/MColor.h>\n#include <maya/MPxManipContainer.h>\n\n//- Assign a unique node ID to your new node class.\n//- Ask ADN or Autodesk product support to reserve IDs for your company. You can\n//- reserve ID by block of 64, 128, 256, or 512 consecutive ID.\n//-\n//- 0x80002 is a temporary ID for reserved for development. Never use that ID in a\n//- production environement.\n/*static*/MTypeId arrowLocator::id( 0x80002 );\n\n//- Instantiate the static attribute of your node class.\n/*static*/MObject arrowLocator::windDirection;\n\n//- An array of points to draw our compass arrow in openGL\nstatic float arrow[][3] = { {2.00f, 0.0f, 0.0f} ,\n\t\t\t\t\t\t\t{-3.0f, 0.0f, 2.0f} ,\n\t\t\t\t\t\t\t{-2.0f, 0.0f, 0.0f} ,\n\t\t\t\t\t\t\t{-3.0f, 0.0f, -2.0f}}; \n\n//- Indices into the arrow array\nstatic GLuint triangleIndices[] = {0,1,2,0,2,3};\n\n//- The initialize method is called to create and initialize all of the \n//- attributes and attribute dependencies for this node type. This is \n//- only called once when the node type is registered with Maya.\n//- Return Values: MS::kSuccess / MS::kFailure\n//-\n/*static*/ MStatus arrowLocator::initialize()\n{\n\t//- Here we create a new attribute type that handles units: angle, distance or time\n\tMFnUnitAttribute uAttr;\n\t//- TODO: Create a angle attribute with long name \"windDirection\" and short name \"wd\"\n\twindDirection = //...\n\tuAttr.setStorable(true);\n\tuAttr.setWritable(true);\n\tuAttr.setReadable(true);\n\tuAttr.setKeyable(true);\n\t//- TODO: Set the min and max value this attribute can have 0, 2PI\n\t//...\n\t//...\n\tuAttr.setDefault(MAngle(0.0, MAngle::kRadians));\n\taddAttribute(windDirection);\n\n\treturn MS::kSuccess;\n}\n\n//- This method draw this locator in current scene by calling openGL functions\n//\t\tview -- 3D view that is being drawn into \n//\t\tpath -- path to this locator in the DAG \n//\t\tstyle -- style to draw object in \n//\t\tstatus -- selection status of object \n//\nvoid arrowLocator::draw(M3dView &view,const MDagPath & path,M3dView::DisplayStyle style, M3dView::DisplayStatus status)\n{\n\t//- TODO: Get a reference of current node\n\tMObject thisNode = //...\n\n\t//- We're in the draw routine, not the compute method\n\t//- therefore it is safe to grab plugs in the following way and\n\t//- get/set values.  You would never do something like this in\n\t//- the compute method because it might start a cycle in the\n\t//- graph.  Here we just need the value of our winddirection\n\t//- plug so that we can draw our arrow pointing the right way.\n\n\t//- TODO: Get the wind direction plug and get its angle value\n\t//...\n\tMAngle angle;\n\t//...\n\n\t//- Start drawing by OpenGL\n\tview.beginGL(); \n\t\n\t//- If the drawing style is shaded, set color and draw opaque shape\n\tif ( ( style == M3dView::kFlatShaded ) || ( style == M3dView::kGouraudShaded ) ) \n\t{\n\t\t//- Push to save current color settings\n\t\tglPushAttrib( GL_CURRENT_BIT );\n\t\tif ( status == M3dView::kActive ) \n\t\t{\n\t\t\tview.setDrawColor( 13, M3dView::kActiveColors );\n\t\t}\n\t\telse\n\t\t{\n\t\t\tview.setDrawColor( 13, M3dView::kDormantColors );\n\t\t}  \n\n\t\t//- Push the old matrix on the stack, rotate the current one,\n\t\t//- draw the shape, then pop the old matrix off the stack for\n\t\t//- maya to use again.\n\t\tglPushMatrix();\n\t\tglRotated(-angle.asDegrees(), 0.0, 1.0, 0.0);\n\t\t\tglBegin( GL_TRIANGLE_FAN );\n\t\t\tglVertex3f(arrow[0][0],arrow[0][1],arrow[0][2]);\n\t\t\tglVertex3f(arrow[1][0],arrow[1][1],arrow[1][2]);\n\t\t\tglVertex3f(arrow[2][0],arrow[2][1],arrow[2][2]);\n\t\t\tglEnd();\n\n\t\t\tglBegin( GL_TRIANGLE_FAN );\n\t\t\tglVertex3f(arrow[2][0],arrow[2][1],arrow[2][2]);\n\t\t\tglVertex3f(arrow[3][0],arrow[3][1],arrow[3][2]);\n\t\t\tglVertex3f(arrow[0][0],arrow[0][1],arrow[0][2]);\n\t\t\tglEnd();\n\t\tglPopMatrix();\n\n\t\tglPopAttrib();\n\t}\n\n\t//- Draw the outline of the arrow shape\n\tglPushMatrix();\n\tglRotated(-angle.asDegrees(), 0.0, 1.0, 0.0);\n\tglBegin( GL_LINE_STRIP);\n\tglVertex3f(arrow[0][0],arrow[0][1],arrow[0][2]);\n\tglVertex3f(arrow[1][0],arrow[1][1],arrow[1][2]);\n\tglVertex3f(arrow[2][0],arrow[2][1],arrow[2][2]);\n\tglEnd();\n\n\tglBegin( GL_LINE_STRIP );\n\tglVertex3f(arrow[2][0],arrow[2][1],arrow[2][2]);\n\tglVertex3f(arrow[3][0],arrow[3][1],arrow[3][2]);\n\tglVertex3f(arrow[0][0],arrow[0][1],arrow[0][2]);\n\tglEnd();\n\tglPopMatrix();\n\n\tview.endGL();\n}\n\n//- This method return the bounding box for this locator shape, \n//- providing a bounding box routine makes refresh and selection more efficient. \n//\nMBoundingBox arrowLocator::boundingBox() const\n{\n\tMPoint upLeftCorner(-3.0, 0.0, -2.0);\n\tMPoint downRightCorner(2.0, 0.0, 2.0);\n\tMBoundingBox boundingArea(upLeftCorner,downRightCorner);\n\treturn boundingArea;\n}\n\n\nvoid arrowLocator::getRotationAngle (arrowLocatorData * data){\n\t// Retrieve value of the angle attribute from the node\n\tMStatus status ;\n\t\n\tMObject node = thisMObject();\n\tMPlug wdPlug(node, windDirection);\n\tMAngle angle;\n\twdPlug.getValue(angle);\n\n\tdata->rotateAngle = angle;\n}\n\nclass arrowLocatorOverride : public MHWRender::MPxDrawOverride\n{\npublic:\n\tstatic MHWRender::MPxDrawOverride* Creator(const MObject& obj)\n\t{\n\t\treturn new arrowLocatorOverride(obj);\n\t}\n\n\tvirtual ~arrowLocatorOverride();\n\n\tvirtual MHWRender::DrawAPI supportedDrawAPIs() const;\n\n    virtual bool isBounded(\n        const MDagPath& objPath,\n        const MDagPath& cameraPath) const;\n\n\tvirtual MBoundingBox boundingBox(\n\t\tconst MDagPath& objPath,\n\t\tconst MDagPath& cameraPath) const;\n\n\tvirtual MUserData* prepareForDraw(\n\t\tconst MDagPath& objPath,\n\t\tconst MDagPath& cameraPath,\n\t\tconst MHWRender::MFrameContext& frameContext,\n\t\tMUserData* oldData);\n\n\tstatic void draw(\n\t\tconst MHWRender::MDrawContext& context,\n\t\tconst MUserData* data);\n\nprivate:\n\tarrowLocatorOverride(const MObject& obj);\n};\n\n\n\narrowLocatorOverride::arrowLocatorOverride(const MObject& obj)\n: MHWRender::MPxDrawOverride(obj, arrowLocatorOverride::draw)\n{\n}\n\narrowLocatorOverride::~arrowLocatorOverride()\n{\n}\n\nMHWRender::DrawAPI arrowLocatorOverride::supportedDrawAPIs() const\n{\n\treturn MHWRender::kOpenGL;\n}\n\nbool arrowLocatorOverride::isBounded(\n\tconst MDagPath& objPath,\n\tconst MDagPath& cameraPath) const\n{\n\treturn true;\n}\n\nMBoundingBox arrowLocatorOverride::boundingBox(\n\tconst MDagPath& objPath,\n\tconst MDagPath& cameraPath) const\n{\n\tMStatus status;\n\tMFnDependencyNode node(objPath.node(), &status);\n\tarrowLocator* locatorNode =\n\t\tdynamic_cast<arrowLocator*>(node.userNode());\n\treturn locatorNode->boundingBox();\n}\n\nMUserData* arrowLocatorOverride::prepareForDraw(\n\tconst MDagPath& objPath,\n\tconst MDagPath& cameraPath,\n\tconst MHWRender::MFrameContext& frameContext,\n\tMUserData* oldData)\n{\n\t// get the node\n\tMStatus status;\n\tMFnDependencyNode node(objPath.node(), &status);\n\tif (!status) return NULL;\n\tarrowLocator* locatorNode =\n\t\tdynamic_cast<arrowLocator*>(node.userNode());\n\tif (!locatorNode) return NULL;\n\n\t// access/create user data for draw callback\n\tarrowLocatorData* data =\n\t\tdynamic_cast<arrowLocatorData*>(oldData);\n\tif (!data)\n\t{\n\t\tdata = new arrowLocatorData();\n\t}\n\n\t// compute data and cache it\n\tlocatorNode->getRotationAngle(data) ;\n\n\treturn data;\n}\n\nvoid arrowLocatorOverride::draw(\n\tconst MHWRender::MDrawContext& context,\n\tconst MUserData* data)\n{\n\tMAngle rotationAngle;\n\n\tfloat color [3] ={ 0.0f, 1.0f, 0.0f } ;\n\n\t// data\n\tMStatus status;\n\tMHWRender::MStateManager* stateMgr = context.getStateManager();\n\tconst arrowLocatorData* locatorData =\n\t\tdynamic_cast<const arrowLocatorData*>(data);\n\tif (!stateMgr || !locatorData) return;\n\n\tif ( locatorData )\n\t\trotationAngle = locatorData->rotateAngle;\n\n\t// matrices\n\tconst MMatrix transform =\n\t\tcontext.getMatrix(MHWRender::MFrameContext::kWorldViewMtx, &status);\n\tif (status != MStatus::kSuccess) return;\n\tconst MMatrix projection =\n\t\tcontext.getMatrix(MHWRender::MFrameContext::kProjectionMtx, &status);\n\tif (status != MStatus::kSuccess) return;\n\n\t// get renderer\n\tMHWRender::MRenderer *theRenderer =MHWRender::MRenderer::theRenderer () ;\n\tif ( !theRenderer )\n\t\treturn ;\n\tif ( theRenderer->drawAPIIsOpenGL () ) {\n\t\t\n\t\tglPushAttrib(GL_CURRENT_BIT);\n\t\tglColor4fv(color);\n\n\t\tglPushMatrix();\n\t\tglRotated(-rotationAngle.asDegrees(), 0.0, 1.0, 0.0);\n\t\tglBegin( GL_LINE_STRIP);\n\t\tglVertex3f(arrow[0][0],arrow[0][1],arrow[0][2]);\n\t\tglVertex3f(arrow[1][0],arrow[1][1],arrow[1][2]);\n\t\tglVertex3f(arrow[2][0],arrow[2][1],arrow[2][2]);\n\t\tglEnd();\n\n\t\tglBegin( GL_LINE_STRIP );\n\t\tglVertex3f(arrow[2][0],arrow[2][1],arrow[2][2]);\n\t\tglVertex3f(arrow[3][0],arrow[3][1],arrow[3][2]);\n\t\tglVertex3f(arrow[0][0],arrow[0][1],arrow[0][2]);\n\t\tglEnd();\n\t\tglPopMatrix();\n\n\t}\n}\n\n\n\n\n\nMStatus initializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is loaded into Maya.  It \n//\t\tregisters all of the services that this plug-in provides with \n//\t\tMaya.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{ \n\tMStatus   status;\n\tMFnPlugin plugin( obj, \"\", \"2009\", \"Any\");\n\n\tstatus = plugin.registerNode( \"arrowLocator\", arrowLocator::id, arrowLocator::creator,\n\t\tarrowLocator::initialize, MPxNode::kLocatorNode,&arrowLocator::drawDbClassification);\n\n\tstatus = MHWRender::MDrawRegistry::registerDrawOverrideCreator (\n\t\tarrowLocator::drawDbClassification,\n\t\tarrowLocator::drawRegistrantId,\n\t\tarrowLocatorOverride::Creator) ;\n\n\tif (!status) {\n\t\tstatus.perror(\"registerNode\");\n\t\treturn status;\n\t}\n\n\treturn status;\n}\n\nMStatus uninitializePlugin( MObject obj)\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is unloaded from Maya. It \n//\t\tderegisters all of the services that it was providing.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{\n\tMStatus   status;\n\tMFnPlugin plugin( obj );\n\n\tstatus = plugin.deregisterNode( arrowLocator::id );\n\n\tMHWRender::MDrawRegistry::deregisterDrawOverrideCreator (\n\t\tarrowLocator::drawDbClassification,\n\t\tarrowLocator::drawRegistrantId) ;\n\n\tif (!status) {\n\t\tstatus.perror(\"deregisterNode\");\n\t\treturn status;\n\t}\n\n\treturn status;\n}\n"
  },
  {
    "path": "07_Locator/arrowLocator/Exercise - C++/arrowLocatorNode.h",
    "content": "//\n// Copyright (C) \n// \n// File: arrowLocatorNode.h\n//\n// Dependency Graph Node: arrowLocator\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#pragma once\n\n#include <maya/MPxLocatorNode.h>\n#include <maya/MFnNumericAttribute.h>\n#include <maya/MTypeId.h> \n#include <maya/M3dView.h>\n#include <maya/MDagPath.h>\n\n\n// Viewport 2.0 includes\n#include <maya/MDrawRegistry.h>\n#include <maya/MPxDrawOverride.h>\n#include <maya/MUserData.h>\n#include <maya/MDrawContext.h>\n#include <maya/MGlobal.h>\n#include <maya/MSelectionList.h>\n#include <maya/MViewport2Renderer.h>\n#include <maya/MHWGeometryUtilities.h>\n#include <maya/MStateManager.h>\n#include <maya/MShaderManager.h>\n#include <maya/MAngle.h>\n\n\n//- Macros to use to rotate the locator\n#define PI 3.14159265358979\n#define toDegree(rot) rot*(180.0/PI)\n\nclass arrowLocatorData : public MUserData\n{\npublic:\n\tMAngle rotateAngle ;\n\n\tarrowLocatorData() : MUserData(false) {} // don't delete after draw\n\tvirtual ~arrowLocatorData() {}\n};\n\nclass arrowLocator : public MPxLocatorNode\n{\npublic:\n\tarrowLocator() {}\n\tvirtual ~arrowLocator() {}\n\n\tvirtual void draw(M3dView &view,const MDagPath & path,M3dView::DisplayStyle style, M3dView::DisplayStatus status);\n\tvirtual MBoundingBox boundingBox() const;\n\tvirtual bool isBounded() const {\n\t\treturn true; //- This method should be overridden to return true if the user supplies a bounding box routine.\n\t}\n\n\n\tvoid getRotationAngle (arrowLocatorData * data );\n\n\tstatic MStatus\t\tinitialize();\n\n\tstatic void* creator() {\n\t\treturn new arrowLocator();\n\t}\n\n\t\n\n\t\npublic:\n\tstatic\tMTypeId\t\tid;\n\n\tstatic\tMString\t\tdrawDbClassification;\n\tstatic\tMString\t\tdrawRegistrantId;\n\n\tstatic MObject windDirection; //- This is an attribute representing the rotation angle\n\n};\n\n"
  },
  {
    "path": "07_Locator/arrowLocator/Exercise - py/arrowLocator.py",
    "content": "# Copyright (C) \n# \n# Author: Autodesk Developer Network\n\n#For this exercise, search for the TODO keywords and follow the instructions in\n#comments. If you are unsure of what you need to do, feel free to ask the instructor\n#or look into the solution folder.\n#Each #... line is a line of code you need to write or complete.\n\nimport sys, math\n\nimport maya.OpenMaya as OpenMaya\nimport maya.OpenMayaMPx as OpenMayaMPx\nimport maya.OpenMayaRender as OpenMayaRender\nimport maya.OpenMayaUI as OpenMayaUI\n\nkPluginNodeTypeName = \"arrowLocator\"\n\nkPluginNodeId = OpenMaya.MTypeId(0x80002)\n\nglRenderer = OpenMayaRender.MHardwareRenderer.theRenderer()\nglFT = glRenderer.glFunctionTable()\n\n#an array of points to draw our compass arrow in openGL\narrow = ( [2.00, 0.0, 0.0],\n[-3.0, 0.0, 2.0],\n[-2.0, 0.0, 0.0],\n[-3.0, 0.0, -2.0]) \n\n#indices into the arrow array\ntriangleIndices = [0,1,2,0,2,3]\n\n# Node definition\nclass arrowLocator(OpenMayaMPx.MPxLocatorNode):\n\twindDirection = OpenMaya.MObject()\n\t\n\tdef __init__(self):\n\t\tOpenMayaMPx.MPxLocatorNode.__init__(self)\n\t\t\n\n\tdef compute(self, plug, data):\n\t\treturn OpenMaya.kUnknownParameter\n\n\t#-\tThis method draw this locator in current scene by calling openGL functions\n\t#-\n\t#-\tArguments:\n\t#-\t\tview -- 3D view that is being drawn into \n\t#-\t\tpath -- path to this locator in the DAG \n\t#-\t\tstyle -- style to draw object in \n\t#-\t\tstatus -- selection status of object \n\t#-\n\tdef draw(self, view, path, style, status):\n\t\t##- TODO: Get a reference of current node\n\t\tthisNode = ##..\n\n\t\t#We're in the draw routine, not the Compute method\n\t\t#therefore it is safe to grab plugs in the following way and\n\t\t#get/set values.  You would never do something like this in\n\t\t#the compute method because it might start a cycle in the\n\t\t#graph.  Here we just need the value of our winddirection\n\t\t#plug so that we can draw our arrow pointing the right way.\n\t\t\n\t\t##- TODO: Get the wind direction plug and get its angle value\n\t\t##...\n\t\tangle = plug.asMAngle()\n\n\t\t#start drawing by OpenGL\n\t\tview.beginGL() \n\n\n\t\t#If the drawing style is shaded, set color and draw opaque shape\n\t\tif ((style == OpenMayaUI.M3dView.kFlatShaded) or (style == OpenMayaUI.M3dView.kGouraudShaded)):\n\t\t\t\n\t\t\t#Push to save current color settings\n\t\t\tglFT.glPushAttrib(OpenMayaRender.MGL_CURRENT_BIT )\n\n\t\t\tif (status == OpenMayaUI.M3dView.kActive):\n\t\t\t\tview.setDrawColor( 13, OpenMayaUI.M3dView.kActiveColors )\n\t\t\telse:\n\t\t\t\tview.setDrawColor( 13, OpenMayaUI.M3dView.kDormantColors )\n\t\t\t  \n\n\t\t\t#push the old matrix on the stack, rotate the current one,\n\t\t\t#draw the shape, then pop the old matrix off the stack for\n\t\t\t#maya to use again.\n\t\t\tglFT.glPushMatrix()\n\t\t\tglFT.glRotated(-angle.asDegrees(), 0.0, 1.0, 0.0)\n\t\t\tglFT.glBegin( OpenMayaRender.MGL_TRIANGLE_FAN )\n\t\t\tglFT.glVertex3f(arrow[0][0],arrow[0][1],arrow[0][2])\n\t\t\tglFT.glVertex3f(arrow[1][0],arrow[1][1],arrow[1][2])\n\t\t\tglFT.glVertex3f(arrow[2][0],arrow[2][1],arrow[2][2])\n\t\t\tglFT.glEnd()\n\n\t\t\tglFT.glBegin( OpenMayaRender.MGL_TRIANGLE_FAN )\n\t\t\tglFT.glVertex3f(arrow[2][0],arrow[2][1],arrow[2][2])\n\t\t\tglFT.glVertex3f(arrow[3][0],arrow[3][1],arrow[3][2])\n\t\t\tglFT.glVertex3f(arrow[0][0],arrow[0][1],arrow[0][2])\n\t\t\tglFT.glEnd()\n\t\t\tglFT.glPopMatrix()\n\n\t\t\tglFT.glPopAttrib()\n\t\t\n\n\t\t#Draw the outline of the arrow shape\n\t\tglFT.glPushMatrix()\n\t\tglFT.glRotated(-angle.asDegrees(), 0.0, 1.0, 0.0)\n\t\tglFT.glBegin( OpenMayaRender.MGL_LINE_STRIP)\n\t\tglFT.glVertex3f(arrow[0][0],arrow[0][1],arrow[0][2])\n\t\tglFT.glVertex3f(arrow[1][0],arrow[1][1],arrow[1][2])\n\t\tglFT.glVertex3f(arrow[2][0],arrow[2][1],arrow[2][2])\n\t\tglFT.glEnd()\n\n\t\tglFT.glBegin( OpenMayaRender.MGL_LINE_STRIP )\n\t\tglFT.glVertex3f(arrow[2][0],arrow[2][1],arrow[2][2])\n\t\tglFT.glVertex3f(arrow[3][0],arrow[3][1],arrow[3][2])\n\t\tglFT.glVertex3f(arrow[0][0],arrow[0][1],arrow[0][2])\n\t\tglFT.glEnd()\n\t\tglFT.glPopMatrix()\n\n\t\tview.endGL()\n\n\tdef isBounded(self):\n\t\treturn True\n\n\t#- This method return the bounding box for this locator shape, \n\t#- providing a bounding box routine makes refresh and selection more efficient. \n\t#\n\tdef boundingBox(self):\n\t\tupLeftCorner = OpenMaya.MPoint(-3.0, 0.0, -2.0)\n\t\tdownRightCorner = OpenMaya.MPoint(2.0, 0.0, 2.0)\n\n\t\tboundingArea = OpenMaya.MBoundingBox(upLeftCorner,downRightCorner)\n\t\treturn boundingArea\n\n\n# Creator\ndef nodeCreator():\n\treturn OpenMayaMPx.asMPxPtr( arrowLocator() )\n\n# initializer\ndef nodeInitializer():\n\t#Here we create a new attribute type that handles units: angle, distance or time\n\tuAttr = OpenMaya.MFnUnitAttribute()\n\t##TODO: Create a angle attribute with long name \"windDirection\" and short name \"wd\"\n\tarrowLocator.windDirection = ##...\n\tuAttr.setStorable(True)\n\tuAttr.setWritable(True)\n\tuAttr.setReadable(True)\n\tuAttr.setKeyable(True)\n\t##- TODO: Set the min and max value this attribute can have 0, 2PI\n\t##...\n\t##...\n\tuAttr.setDefault(OpenMaya.MAngle(0.0, OpenMaya.MAngle.kDegrees))\n\tarrowLocator.addAttribute(arrowLocator.windDirection)\n\t\n# Initialize the script plug-in\ndef initializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\t\n\t\tmplugin.registerNode( kPluginNodeTypeName, kPluginNodeId, nodeCreator, nodeInitializer, OpenMayaMPx.MPxNode.kLocatorNode )\n\texcept:\n\t\tsys.stderr.write( \"Failed to register node: %s\" % kPluginNodeTypeName )\n\t\traise\n\n# Uninitialize the script plug-in\ndef uninitializePlugin(mobject):\n\n\t\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\t\n\ttry:\n\t\t\n\t\tmplugin.deregisterNode( kPluginNodeId )\n\texcept:\n\t\tsys.stderr.write( \"Failed to deregister command: %s\" % kPluginNodeTypeName )\n\t\traise\n\n\t\t"
  },
  {
    "path": "07_Locator/arrowLocator/Solution - C++/arrowLocator.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 2012\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"arrowLocator\", \"arrowLocator.vcxproj\", \"{2A76853E-2C9D-4719-B6C7-6A787EEED416}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|x64 = Debug|x64\n\t\tRelease|x64 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{2A76853E-2C9D-4719-B6C7-6A787EEED416}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{2A76853E-2C9D-4719-B6C7-6A787EEED416}.Debug|x64.Build.0 = Debug|x64\n\t\t{2A76853E-2C9D-4719-B6C7-6A787EEED416}.Release|x64.ActiveCfg = Release|x64\n\t\t{2A76853E-2C9D-4719-B6C7-6A787EEED416}.Release|x64.Build.0 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "07_Locator/arrowLocator/Solution - C++/arrowLocator.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{2A76853E-2C9D-4719-B6C7-6A787EEED416}</ProjectGuid>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup>\n    <_ProjectFileVersion>11.0.50727.1</_ProjectFileVersion>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <OutDir>Debug\\</OutDir>\n    <IntDir>Debug\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <OutDir>$(Platform)\\$(Configuration)\\</OutDir>\n    <IntDir>$(Platform)\\$(Configuration)\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <OutDir>Release\\</OutDir>\n    <IntDir>Release\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <OutDir>$(Platform)\\$(Configuration)\\</OutDir>\n    <IntDir>$(Platform)\\$(Configuration)\\</IntDir>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2014\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;OpenMayaUI.lib;opengl32.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>C:\\MayaAPITraining\\plug-ins\\arrowLocator.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2015\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <Midl>\n      <TargetEnvironment>X64</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2015\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;OpenMayaRender.lib;OpenMayaUI.lib;opengl32.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>C:\\MayaAPITraining\\plug-ins\\arrowLocator.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2015\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/.lib</ImportLibrary>\n      <TargetMachine>MachineX64</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;OpenMayaUI.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <Midl>\n      <TargetEnvironment>X64</TargetEnvironment>\n    </Midl>\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2008\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;OpenMayaUI.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2008\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/.lib</ImportLibrary>\n      <TargetMachine>MachineX64</TargetMachine>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"arrowLocatorNode.cpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"arrowLocatorNode.h\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "07_Locator/arrowLocator/Solution - C++/arrowLocatorNode.cpp",
    "content": "//\n// Copyright (C) \n// \n// File: arrowLocatorNode.cpp\n//\n// Dependency Graph Node: arrowLocator\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#include \"arrowLocatorNode.h\"\n\n#include <maya/MFnPlugin.h>\n#include <maya/MPlug.h>\n#include <maya/MDataBlock.h>\n#include <maya/MDataHandle.h>\n\n#include <maya/MGlobal.h>\n#include <maya/MFnDagNode.h>\n#include <maya/MFnUnitAttribute.h>\n#include <maya/MAngle.h>\n#include <maya/MColor.h>\n#include <maya/MPxManipContainer.h>\n#include <maya/MPxDrawOverride.h>\n#include <maya/MHWGeometryUtilities.h>\n#include <maya/MStateManager.h>\n#include <maya/MDrawRegistry.h>\n#include <maya/MDrawContext.h>\n\n//- Assign a unique node ID to your new node class.\n//- Ask ADN or Autodesk product support to reserve IDs for your company. You can\n//- reserve ID by block of 64, 128, 256, or 512 consecutive ID.\n//-\n//- 0x80002 is a temporary ID for reserved for development. Never use that ID in a\n//- production environment.\n/*static*/MTypeId arrowLocator::id( 0x80002 );\n\nMString\tarrowLocator::drawDbClassification(\"drawdb/geometry/arrowLocator\");\nMString\tarrowLocator::drawRegistrantId(\"arrowLocatorNodePlugin\");\n\n//- Instantiate the static attribute of your node class.\n/*static*/MObject arrowLocator::windDirection;\n\n//- An array of points to draw our compass arrow in openGL\nstatic float arrow[][3] = { {2.00f, 0.0f, 0.0f} ,\n\t\t\t\t\t\t\t{-3.0f, 0.0f, 2.0f} ,\n\t\t\t\t\t\t\t{-2.0f, 0.0f, 0.0f} ,\n\t\t\t\t\t\t\t{-3.0f, 0.0f, -2.0f}}; \n\n//- Indices into the arrow array\nstatic GLuint triangleIndices[] = {0,1,2,0,2,3};\n\n//- The initialize method is called to create and initialize all of the \n//- attributes and attribute dependencies for this node type. This is \n//- only called once when the node type is registered with Maya.\n//- Return Values: MS::kSuccess / MS::kFailure\n//-\n/*static*/ MStatus arrowLocator::initialize()\n{\n\t//- Here we create a new attribute type that handles units: angle, distance or time\n\tMFnUnitAttribute uAttr;\n\twindDirection = uAttr.create(\"windDirection\", \"wd\", MFnUnitAttribute::kAngle, 0.0);\n\tuAttr.setStorable(true);\n\tuAttr.setWritable(true);\n\tuAttr.setReadable(true);\n\tuAttr.setKeyable(true);\n\tuAttr.setMin(0.0);\n\tuAttr.setMax(2*PI);\n\tuAttr.setDefault(MAngle(0.0, MAngle::kRadians));\n\taddAttribute(windDirection);\n\n\treturn MS::kSuccess;\n}\n\n//- This method draw this locator in current scene by calling openGL functions\n//\t\tview -- 3D view that is being drawn into \n//\t\tpath -- path to this locator in the DAG \n//\t\tstyle -- style to draw object in \n//\t\tstatus -- selection status of object \n//\nvoid arrowLocator::draw(M3dView &view,const MDagPath & path,M3dView::DisplayStyle style, M3dView::DisplayStatus status)\n{\n\tMObject thisNode = thisMObject();\n\n\t//- We're in the draw routine, not the compute method\n\t//- therefore it is safe to grab plugs in the following way and\n\t//- get/set values.  You would never do something like this in\n\t//- the compute method because it might start a cycle in the\n\t//- graph.  Here we just need the value of our winddirection\n\t//- plug so that we can draw our arrow pointing the right way.\n\tMPlug wdPlug(thisNode, windDirection);\n\tMAngle angle;\n\twdPlug.getValue(angle);\n\n\t//- Start drawing by OpenGL\n\tview.beginGL(); \n\t\n\t//- If the drawing style is shaded, set color and draw opaque shape\n\tif ( ( style == M3dView::kFlatShaded ) || ( style == M3dView::kGouraudShaded ) ) \n\t{\n\t\t//- Push to save current color settings\n\t\tglPushAttrib( GL_CURRENT_BIT );\n\t\tif ( status == M3dView::kActive ) \n\t\t{\n\t\t\tview.setDrawColor( 13, M3dView::kActiveColors );\n\t\t}\n\t\telse\n\t\t{\n\t\t\tview.setDrawColor( 13, M3dView::kDormantColors );\n\t\t}  \n\n\t\t//- Push the old matrix on the stack, rotate the current one,\n\t\t//- draw the shape, then pop the old matrix off the stack for\n\t\t//- maya to use again.\n\t\tglPushMatrix();\n\t\tglRotated(-angle.asDegrees(), 0.0, 1.0, 0.0);\n\t\t\tglBegin( GL_TRIANGLE_FAN );\n\t\t\tglVertex3f(arrow[0][0],arrow[0][1],arrow[0][2]);\n\t\t\tglVertex3f(arrow[1][0],arrow[1][1],arrow[1][2]);\n\t\t\tglVertex3f(arrow[2][0],arrow[2][1],arrow[2][2]);\n\t\t\tglEnd();\n\n\t\t\tglBegin( GL_TRIANGLE_FAN );\n\t\t\tglVertex3f(arrow[2][0],arrow[2][1],arrow[2][2]);\n\t\t\tglVertex3f(arrow[3][0],arrow[3][1],arrow[3][2]);\n\t\t\tglVertex3f(arrow[0][0],arrow[0][1],arrow[0][2]);\n\t\t\tglEnd();\n\t\tglPopMatrix();\n\n\t\tglPopAttrib();\n\t}\n\n\t//- Draw the outline of the arrow shape\n\tglPushMatrix();\n\tglRotated(-angle.asDegrees(), 0.0, 1.0, 0.0);\n\tglBegin( GL_LINE_STRIP);\n\tglVertex3f(arrow[0][0],arrow[0][1],arrow[0][2]);\n\tglVertex3f(arrow[1][0],arrow[1][1],arrow[1][2]);\n\tglVertex3f(arrow[2][0],arrow[2][1],arrow[2][2]);\n\tglEnd();\n\n\tglBegin( GL_LINE_STRIP );\n\tglVertex3f(arrow[2][0],arrow[2][1],arrow[2][2]);\n\tglVertex3f(arrow[3][0],arrow[3][1],arrow[3][2]);\n\tglVertex3f(arrow[0][0],arrow[0][1],arrow[0][2]);\n\tglEnd();\n\tglPopMatrix();\n\n\tview.endGL();\n}\n\n//- This method return the bounding box for this locator shape, \n//- providing a bounding box routine makes refresh and selection more efficient. \n//\nMBoundingBox arrowLocator::boundingBox() const\n{\n\tMPoint upLeftCorner(-3.0, 0.0, -2.0);\n\tMPoint downRightCorner(2.0, 0.0, 2.0);\n\tMBoundingBox boundingArea(upLeftCorner,downRightCorner);\n\treturn boundingArea;\n}\n\nvoid arrowLocator::getRotationAngle (arrowLocatorData * data){\n\t// Retrieve value of the angle attribute from the node\n\tMStatus status ;\n\t\n\tMObject node = thisMObject();\n\tMPlug wdPlug(node, windDirection);\n\tMAngle angle;\n\twdPlug.getValue(angle);\n\n\tdata->rotateAngle = angle;\n}\n\n\n\nclass arrowLocatorOverride : public MHWRender::MPxDrawOverride\n{\npublic:\n\tstatic MHWRender::MPxDrawOverride* Creator(const MObject& obj)\n\t{\n\t\treturn new arrowLocatorOverride(obj);\n\t}\n\n\tvirtual ~arrowLocatorOverride();\n\n\tvirtual MHWRender::DrawAPI supportedDrawAPIs() const;\n\n    virtual bool isBounded(\n        const MDagPath& objPath,\n        const MDagPath& cameraPath) const;\n\n\tvirtual MBoundingBox boundingBox(\n\t\tconst MDagPath& objPath,\n\t\tconst MDagPath& cameraPath) const;\n\n\tvirtual MUserData* prepareForDraw(\n\t\tconst MDagPath& objPath,\n\t\tconst MDagPath& cameraPath,\n\t\tconst MHWRender::MFrameContext& frameContext,\n\t\tMUserData* oldData);\n\n\tstatic void draw(\n\t\tconst MHWRender::MDrawContext& context,\n\t\tconst MUserData* data);\n\nprivate:\n\tarrowLocatorOverride(const MObject& obj);\n};\n\n\n\narrowLocatorOverride::arrowLocatorOverride(const MObject& obj)\n: MHWRender::MPxDrawOverride(obj, arrowLocatorOverride::draw)\n{\n}\n\narrowLocatorOverride::~arrowLocatorOverride()\n{\n}\n\nMHWRender::DrawAPI arrowLocatorOverride::supportedDrawAPIs() const\n{\n\treturn MHWRender::kOpenGL;\n}\n\nbool arrowLocatorOverride::isBounded(\n\tconst MDagPath& objPath,\n\tconst MDagPath& cameraPath) const\n{\n\treturn true;\n}\n\nMBoundingBox arrowLocatorOverride::boundingBox(\n\tconst MDagPath& objPath,\n\tconst MDagPath& cameraPath) const\n{\n\tMStatus status;\n\tMFnDependencyNode node(objPath.node(), &status);\n\tarrowLocator* locatorNode =\n\t\tdynamic_cast<arrowLocator*>(node.userNode());\n\treturn locatorNode->boundingBox();\n}\n\nMUserData* arrowLocatorOverride::prepareForDraw(\n\tconst MDagPath& objPath,\n\tconst MDagPath& cameraPath,\n\tconst MHWRender::MFrameContext& frameContext,\n\tMUserData* oldData)\n{\n\t// get the node\n\tMStatus status;\n\tMFnDependencyNode node(objPath.node(), &status);\n\tif (!status) return NULL;\n\tarrowLocator* locatorNode =\n\t\tdynamic_cast<arrowLocator*>(node.userNode());\n\tif (!locatorNode) return NULL;\n\n\t// access/create user data for draw callback\n\tarrowLocatorData* data =\n\t\tdynamic_cast<arrowLocatorData*>(oldData);\n\tif (!data)\n\t{\n\t\tdata = new arrowLocatorData();\n\t}\n\n\t// compute data and cache it\n\tlocatorNode->getRotationAngle(data) ;\n\n\treturn data;\n}\n\nvoid arrowLocatorOverride::draw(\n\tconst MHWRender::MDrawContext& context,\n\tconst MUserData* data)\n{\n\tMAngle rotationAngle;\n\n\tfloat color [3] ={ 0.0f, 1.0f, 0.0f } ;\n\n\t// data\n\tMStatus status;\n\tMHWRender::MStateManager* stateMgr = context.getStateManager();\n\tconst arrowLocatorData* locatorData =\n\t\tdynamic_cast<const arrowLocatorData*>(data);\n\tif (!stateMgr || !locatorData) return;\n\n\tif ( locatorData )\n\t\trotationAngle = locatorData->rotateAngle;\n\n\t// matrices\n\tconst MMatrix transform =\n\t\tcontext.getMatrix(MHWRender::MFrameContext::kWorldViewMtx, &status);\n\tif (status != MStatus::kSuccess) return;\n\tconst MMatrix projection =\n\t\tcontext.getMatrix(MHWRender::MFrameContext::kProjectionMtx, &status);\n\tif (status != MStatus::kSuccess) return;\n\n\t// get renderer\n\tMHWRender::MRenderer *theRenderer =MHWRender::MRenderer::theRenderer () ;\n\tif ( !theRenderer )\n\t\treturn ;\n\tif ( theRenderer->drawAPIIsOpenGL () ) {\n\t\t\n\t\tglPushAttrib(GL_CURRENT_BIT);\n\t\tglColor4fv(color);\n\n\t\tglPushMatrix();\n\t\tglRotated(-rotationAngle.asDegrees(), 0.0, 1.0, 0.0);\n\t\tglBegin( GL_LINE_STRIP);\n\t\tglVertex3f(arrow[0][0],arrow[0][1],arrow[0][2]);\n\t\tglVertex3f(arrow[1][0],arrow[1][1],arrow[1][2]);\n\t\tglVertex3f(arrow[2][0],arrow[2][1],arrow[2][2]);\n\t\tglEnd();\n\n\t\tglBegin( GL_LINE_STRIP );\n\t\tglVertex3f(arrow[2][0],arrow[2][1],arrow[2][2]);\n\t\tglVertex3f(arrow[3][0],arrow[3][1],arrow[3][2]);\n\t\tglVertex3f(arrow[0][0],arrow[0][1],arrow[0][2]);\n\t\tglEnd();\n\t\tglPopMatrix();\n\t}\n}\n\n\n\n\n\nMStatus initializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is loaded into Maya.  It \n//\t\tregisters all of the services that this plug-in provides with \n//\t\tMaya.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{ \n\tMStatus   status;\n\tMFnPlugin plugin( obj, \"\", \"2009\", \"Any\");\n\n\tstatus = plugin.registerNode( \"arrowLocator\", arrowLocator::id, arrowLocator::creator,\n\t\tarrowLocator::initialize, MPxNode::kLocatorNode,&arrowLocator::drawDbClassification);\n\n\tstatus = MHWRender::MDrawRegistry::registerDrawOverrideCreator (\n\t\tarrowLocator::drawDbClassification,\n\t\tarrowLocator::drawRegistrantId,\n\t\tarrowLocatorOverride::Creator) ;\n\n\tif (!status) {\n\t\tstatus.perror(\"registerNode\");\n\t\treturn status;\n\t}\n\n\treturn status;\n}\n\nMStatus uninitializePlugin( MObject obj)\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is unloaded from Maya. It \n//\t\tderegisters all of the services that it was providing.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{\n\tMStatus   status;\n\tMFnPlugin plugin( obj );\n\n\tstatus = plugin.deregisterNode( arrowLocator::id );\n\n\tMHWRender::MDrawRegistry::deregisterDrawOverrideCreator (\n\t\tarrowLocator::drawDbClassification,\n\t\tarrowLocator::drawRegistrantId) ;\n\n\tif (!status) {\n\t\tstatus.perror(\"deregisterNode\");\n\t\treturn status;\n\t}\n\n\treturn status;\n}\n"
  },
  {
    "path": "07_Locator/arrowLocator/Solution - C++/arrowLocatorNode.h",
    "content": "//\n// Copyright (C) \n// \n// File: arrowLocatorNode.h\n//\n// Dependency Graph Node: arrowLocator\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n#pragma once\n\n#include <maya/MPxLocatorNode.h>\n#include <maya/MFnNumericAttribute.h>\n#include <maya/MTypeId.h> \n#include <maya/M3dView.h>\n#include <maya/MDagPath.h>\n\n\n// Viewport 2.0 includes\n#include <maya/MDrawRegistry.h>\n#include <maya/MPxDrawOverride.h>\n#include <maya/MUserData.h>\n#include <maya/MDrawContext.h>\n#include <maya/MGlobal.h>\n#include <maya/MSelectionList.h>\n#include <maya/MViewport2Renderer.h>\n#include <maya/MHWGeometryUtilities.h>\n#include <maya/MStateManager.h>\n#include <maya/MShaderManager.h>\n#include <maya/MAngle.h>\n\n\n//- Macros to use to rotate the locator\n#define PI 3.14159265358979\n#define toDegree(rot) rot*(180.0/PI)\n\nclass arrowLocatorData : public MUserData\n{\npublic:\n\tMAngle rotateAngle ;\n\n\tarrowLocatorData() : MUserData(false) {} // don't delete after draw\n\tvirtual ~arrowLocatorData() {}\n};\n\nclass arrowLocator : public MPxLocatorNode\n{\npublic:\n\tarrowLocator() {}\n\tvirtual ~arrowLocator() {}\n\n\tvirtual void draw(M3dView &view,const MDagPath & path,M3dView::DisplayStyle style, M3dView::DisplayStatus status);\n\tvirtual MBoundingBox boundingBox() const;\n\tvirtual bool isBounded() const {\n\t\treturn true; //- This method should be overridden to return true if the user supplies a bounding box routine.\n\t}\n\n\n\tvoid getRotationAngle (arrowLocatorData * data );\n\n\tstatic MStatus\t\tinitialize();\n\n\tstatic void* creator() {\n\t\treturn new arrowLocator();\n\t}\n\n\t\n\n\t\npublic:\n\tstatic\tMTypeId\t\tid;\n\n\tstatic\tMString\t\tdrawDbClassification;\n\tstatic\tMString\t\tdrawRegistrantId;\n\n\tstatic MObject windDirection; //- This is an attribute representing the rotation angle\n\n};\n\n"
  },
  {
    "path": "07_Locator/arrowLocator/Solution - py/arrowLocator.py",
    "content": "#\n# Copyright (C) \n# \n# File: arrowLocator.py\n#\n# Dependency Graph Node: \n#\n# Author: Maya Plug-in Wizard 2.0\n\n\nimport sys, math\n\nimport maya.OpenMaya as OpenMaya\nimport maya.OpenMayaMPx as OpenMayaMPx\nimport maya.OpenMayaRender as OpenMayaRender\nimport maya.OpenMayaUI as OpenMayaUI\n\nkPluginNodeTypeName = \"arrowLocator\"\n\nkPluginNodeId = OpenMaya.MTypeId(0x80002)\n\nglRenderer = OpenMayaRender.MHardwareRenderer.theRenderer()\nglFT = glRenderer.glFunctionTable()\n\n#an array of points to draw our compass arrow in openGL\narrow = ( [2.00, 0.0, 0.0],\n[-3.0, 0.0, 2.0],\n[-2.0, 0.0, 0.0],\n[-3.0, 0.0, -2.0]) \n\n#indices into the arrow array\ntriangleIndices = [0,1,2,0,2,3]\n\n# Node definition\nclass arrowLocator(OpenMayaMPx.MPxLocatorNode):\n\twindDirection = OpenMaya.MObject()\n\t\n\tdef __init__(self):\n\t\tOpenMayaMPx.MPxLocatorNode.__init__(self)\n\t\t\n\n\tdef compute(self, plug, data):\n\t\treturn OpenMaya.kUnknownParameter\n\n\t#-\tThis method draw this locator in current scene by calling openGL functions\n\t#-\n\t#-\tArguments:\n\t#-\t\tview -- 3D view that is being drawn into \n\t#-\t\tpath -- path to this locator in the DAG \n\t#-\t\tstyle -- style to draw object in \n\t#-\t\tstatus -- selection status of object \n\t#-\n\tdef draw(self, view, path, style, status):\n\t\tthisNode = self.thisMObject()\n\n\t\t#We're in the draw routine, not the Compute method\n\t\t#therefore it is safe to grab plugs in the following way and\n\t\t#get/set values.  You would never do something like this in\n\t\t#the compute method because it might start a cycle in the\n\t\t#graph.  Here we just need the value of our winddirection\n\t\t#plug so that we can draw our arrow pointing the right way.\n\t\tplug = OpenMaya.MPlug(thisNode, arrowLocator.windDirection)\n\t\tangle = plug.asMAngle()\n\n\t\t#start drawing by OpenGL\n\t\tview.beginGL() \n\n\n\t\t#If the drawing style is shaded, set color and draw opaque shape\n\t\tif ((style == OpenMayaUI.M3dView.kFlatShaded) or (style == OpenMayaUI.M3dView.kGouraudShaded)):\n\t\t\t\n\t\t\t#Push to save current color settings\n\t\t\tglFT.glPushAttrib(OpenMayaRender.MGL_CURRENT_BIT )\n\n\t\t\tif (status == OpenMayaUI.M3dView.kActive):\n\t\t\t\tview.setDrawColor( 13, OpenMayaUI.M3dView.kActiveColors )\n\t\t\telse:\n\t\t\t\tview.setDrawColor( 13, OpenMayaUI.M3dView.kDormantColors )\n\t\t\t  \n\n\t\t\t#push the old matrix on the stack, rotate the current one,\n\t\t\t#draw the shape, then pop the old matrix off the stack for\n\t\t\t#maya to use again.\n\t\t\tglFT.glPushMatrix()\n\t\t\tglFT.glRotated(-angle.asDegrees(), 0.0, 1.0, 0.0)\n\t\t\tglFT.glBegin( OpenMayaRender.MGL_TRIANGLE_FAN )\n\t\t\tglFT.glVertex3f(arrow[0][0],arrow[0][1],arrow[0][2])\n\t\t\tglFT.glVertex3f(arrow[1][0],arrow[1][1],arrow[1][2])\n\t\t\tglFT.glVertex3f(arrow[2][0],arrow[2][1],arrow[2][2])\n\t\t\tglFT.glEnd()\n\n\t\t\tglFT.glBegin( OpenMayaRender.MGL_TRIANGLE_FAN )\n\t\t\tglFT.glVertex3f(arrow[2][0],arrow[2][1],arrow[2][2])\n\t\t\tglFT.glVertex3f(arrow[3][0],arrow[3][1],arrow[3][2])\n\t\t\tglFT.glVertex3f(arrow[0][0],arrow[0][1],arrow[0][2])\n\t\t\tglFT.glEnd()\n\t\t\tglFT.glPopMatrix()\n\n\t\t\tglFT.glPopAttrib()\n\t\t\n\n\t\t#Draw the outline of the arrow shape\n\t\tglFT.glPushMatrix()\n\t\tglFT.glRotated(-angle.asDegrees(), 0.0, 1.0, 0.0)\n\t\tglFT.glBegin( OpenMayaRender.MGL_LINE_STRIP)\n\t\tglFT.glVertex3f(arrow[0][0],arrow[0][1],arrow[0][2])\n\t\tglFT.glVertex3f(arrow[1][0],arrow[1][1],arrow[1][2])\n\t\tglFT.glVertex3f(arrow[2][0],arrow[2][1],arrow[2][2])\n\t\tglFT.glEnd()\n\n\t\tglFT.glBegin( OpenMayaRender.MGL_LINE_STRIP )\n\t\tglFT.glVertex3f(arrow[2][0],arrow[2][1],arrow[2][2])\n\t\tglFT.glVertex3f(arrow[3][0],arrow[3][1],arrow[3][2])\n\t\tglFT.glVertex3f(arrow[0][0],arrow[0][1],arrow[0][2])\n\t\tglFT.glEnd()\n\t\tglFT.glPopMatrix()\n\n\t\tview.endGL()\n\n\tdef isBounded(self):\n\t\treturn True\n\n\t#- This method return the bounding box for this locator shape, \n\t#- providing a bounding box routine makes refresh and selection more efficient. \n\t#\n\tdef boundingBox(self):\n\t\tupLeftCorner = OpenMaya.MPoint(-3.0, 0.0, -2.0)\n\t\tdownRightCorner = OpenMaya.MPoint(2.0, 0.0, 2.0)\n\n\t\tboundingArea = OpenMaya.MBoundingBox(upLeftCorner,downRightCorner)\n\t\treturn boundingArea\n\n\n# Creator\ndef nodeCreator():\n\treturn OpenMayaMPx.asMPxPtr( arrowLocator() )\n\n# initializer\ndef nodeInitializer():\n\t#Here we create a new attribute type that handles units: angle, distance or time\n\tuAttr = OpenMaya.MFnUnitAttribute()\n\tarrowLocator.windDirection = uAttr.create(\"windDirection\", \"wd\", OpenMaya.MFnUnitAttribute.kAngle)\n\tuAttr.setStorable(True)\n\tuAttr.setWritable(True)\n\tuAttr.setReadable(True)\n\tuAttr.setKeyable(True)\n\tuAttr.setMin(0.0)\n\tuAttr.setMax(2*math.pi)\n\tuAttr.setDefault(OpenMaya.MAngle(0.0, OpenMaya.MAngle.kDegrees))\n\tarrowLocator.addAttribute(arrowLocator.windDirection)\n\t\n# Initialize the script plug-in\ndef initializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\t\n\t\tmplugin.registerNode( kPluginNodeTypeName, kPluginNodeId, nodeCreator, nodeInitializer, OpenMayaMPx.MPxNode.kLocatorNode )\n\texcept:\n\t\tsys.stderr.write( \"Failed to register node: %s\" % kPluginNodeTypeName )\n\t\traise\n\n# Uninitialize the script plug-in\ndef uninitializePlugin(mobject):\n\n\t\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\t\n\ttry:\n\t\t\n\t\tmplugin.deregisterNode( kPluginNodeId )\n\texcept:\n\t\tsys.stderr.write( \"Failed to deregister command: %s\" % kPluginNodeTypeName )\n\t\traise\n\n\t\t"
  },
  {
    "path": "08_Manipulators/arrowLocatorManip/Exercise - C++/arrowLocatorManip.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 2012\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"arrowLocatorManip\", \"arrowLocatorManip.vcxproj\", \"{C05EECF5-6CF1-4302-A92B-24DDB374E61A}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|x64 = Debug|x64\n\t\tRelease|x64 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{C05EECF5-6CF1-4302-A92B-24DDB374E61A}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{C05EECF5-6CF1-4302-A92B-24DDB374E61A}.Debug|x64.Build.0 = Debug|x64\n\t\t{C05EECF5-6CF1-4302-A92B-24DDB374E61A}.Release|x64.ActiveCfg = Release|x64\n\t\t{C05EECF5-6CF1-4302-A92B-24DDB374E61A}.Release|x64.Build.0 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "08_Manipulators/arrowLocatorManip/Exercise - C++/arrowLocatorManip.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{C05EECF5-6CF1-4302-A92B-24DDB374E61A}</ProjectGuid>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup>\n    <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">Debug\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">Debug\\</IntDir>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Release\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Release\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <OutDir>C:\\MayaAPITraining\\plug-ins\\</OutDir>\n    <TargetExt>.mll</TargetExt>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2009\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/arrowLocatorManip.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;OpenMayaUI.lib;OpenGL32.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Debug\\arrowLocatorManip.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2009\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/arrowLocatorManip.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/arrowLocatorManip.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2015\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/arrowLocatorManip.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;OpenMayaUI.lib;OpenMayaRender.lib;OpenGL32.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>C:\\MayaAPITraining\\plug-ins\\arrowLocatorManip.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2015\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/arrowLocatorManip.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Debug/arrowLocatorManip.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2009\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/arrowLocatorManip.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;OpenMayaUI.lib;OpenGL32.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\arrowLocatorManip.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2009\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/arrowLocatorManip.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/arrowLocatorManip.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2009\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/arrowLocatorManip.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;OpenMayaUI.lib;OpenGL32.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\arrowLocatorManip.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2009\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/arrowLocatorManip.pdb</ProgramDatabaseFile>\n      <ImportLibrary>Release/arrowLocatorManip.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"arrowLocatorManipNode.cpp\" />\n    <ClCompile Include=\"arrowLocatorNode.cpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"arrowLocatorManipNode.h\" />\n    <ClInclude Include=\"arrowLocatorNode.h\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "08_Manipulators/arrowLocatorManip/Exercise - C++/arrowLocatorManipNode.cpp",
    "content": "//\n// Copyright (C) \n// \n// File: arrowLocatorManipNode.cpp\n//\n// Dependency Graph Node: arrowLocatorManip\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n\n#include \"arrowLocatorManipNode.h\"\n\n#include <maya/MPlug.h>\n#include <maya/MDataBlock.h>\n#include <maya/MDataHandle.h>\n#include <maya/MFnDependencyNode.h>\n#include <maya/MFnDiscManip.h>\n#include <maya/MAngle.h>\n\n#include <maya/MGlobal.h>\n\n//- You MUST change this to a unique value!!!  The id is a 32bit value used\n//- to identify this type of node in the binary file format.  \n//-\n//- change the following to a unique value and then erase this line \nMTypeId     arrowLocatorManip::id( 0x00003 );    \nMDagPath\tarrowLocatorManip::fDiscManip;\n\nMDagPath\tarrowLocatorManip::fNodePath;\n\narrowLocatorManip::arrowLocatorManip() {}\narrowLocatorManip::~arrowLocatorManip() {}\n\n\n//-\tThis method exists to give Maya a way to create new objects\n//- of this type. \n//-\n//-\tReturn Value:\n//-\t\ta new object of this type\n//-\nvoid* arrowLocatorManip::creator()\n{\n\treturn new arrowLocatorManip();\n}\n\n\n//- This method is called to create and initialize all of the attributes\n//- and attribute dependencies for this node type.  This is only called \n//-\tonce when the node type is registered with Maya.\n//-\n//-\tReturn Values:\n//-\t\tMS::kSuccess\n//-\t\tMS::kFailure\t\nMStatus arrowLocatorManip::initialize()\t\n{\n\tMStatus stat;\n\tstat = MPxManipContainer::initialize();\n\treturn stat;\n}\n\n\n//- Container manipulators are composed of one or more base manipulators. \n//- When base manipulators are added to a container manipulator, they are referred to \n//- as children of the container manipulator, and are added using the createChildren method. \nMStatus arrowLocatorManip::createChildren()\n{\n\tMStatus status = MStatus::kSuccess;\n\n\t//- TODO: Create a base disc manip and \n\t//- TODO: add it into this manip container, assign\n\t//- TODO: the returned value of the function call to member\n\t//- TODO: variable: \"fDiscManip\" \n\t//...\n\t//...\n\n\t//- Initialize the angle and starting position of this manipulator\n\tMPoint startPoint(0.0, 0.0, 0.0);\n\tMAngle startAngle(0.0,MAngle::kDegrees);\n\tMFnDiscManip fnDisc(fDiscManip,&status);\n\tfnDisc.setCenterPoint(startPoint);\n\tfnDisc.setAngle(startAngle);\n\n\treturn status;\n}\n\n//- This function is responsible to make the connection (association) \n//- between manipulators and the affected attributes. When a node in a scene \n//- is selected and user click on show manipulator tool, \n//- this function is called with the selected node.\n//- Arguments:\n//- \tdependNode - the node which is selected\nMStatus arrowLocatorManip::connectToDependNode(const MObject &dependNode)\n{\n\tMStatus status = MStatus::kSuccess;\n\n\t//- Find the \"windDirection\" plug on the selected node, which is the custom\n\t//- locator node.\n\tMFnDependencyNode fnDepNode(dependNode);\n\tMPlug rotationPlug = fnDepNode.findPlug(MString(\"windDirection\"),&status);\n\n\t//- TODO: Connect the \"windDirection\" plug with the disc manip\n\t//...\n\t//...\n\n\n\t//- Set up affecting relationship using conversion callback function\n\t//- We are using addPlugToManipConversionCallback so that whenever\n\t//- the custom locator moves, the dis manip moves with it.\n/*\tMFnDagNode fnDagNode(dependNode);\n\tfnDagNode.getPath(fNodePath);\n\tunsigned int centerPointIndex = fnDisc.centerIndex(&status);\n\taddPlugToManipConversionCallback(centerPointIndex,(plugToManipConversionCallback)&arrowLocatorManip::centerPointCallback);\n*/\n\n\n\t//- The following two functions are mandatory inside your\n\t//- connectToDependNode() function\n\tstatus = finishAddingManips();\n\tstatus = MPxManipContainer::connectToDependNode(dependNode);\n\t\n\treturn status;\n\n}\n\n//- This method is plugToManipConversionCallback function\n//- You implement it so that a specific component of the manipulator\n//- will be modified automatically when some plug value changes on \n//- the custom locator.\n//- Arguments:\n//- \tmanipIndex - the index of the component on the manip you want to affect, \n//-                  in this case, it is the center point of this manip\n//-\tReturn Values:\n//-\t\tMManipData object, which represents the updated value\n/*MManipData arrowLocatorManip::centerPointCallback(unsigned int manipIndex)\n{\n\tMStatus status;\n\n\t//Get parent transform node of the locator node\n\tMObject parentTransform = fNodePath.transform(&status);\n\n\t//Get the transform node DAG path\n\tMDagPath transformPath;\n\tMDagPath::getAPathTo(parentTransform,transformPath);\n\n\t//Retrieve world space translation\n\tMFnTransform fnTrans(transformPath,&status);\n\tMVector translation = fnTrans.getTranslation(MSpace::kWorld,&status);\n\n\tMFnNumericData numData;\n\tMObject numDataValue = numData.create(MFnNumericData::k3Double,&status);\n\tstatus = numData.setData3Double(translation.x,translation.y,translation.z);\n\n\tMManipData manipData(numDataValue);\n\treturn manipData;\n}\n*/\n\n//- This method is an optional method, you can use it to customize \n//- the drawing of your manipulator. \n//- If you are overriding this function, most likely you will use OpenGL calls, \n//- so opengl32.lib should be included in the linking libraries.\n//- Arguments:\n//- \tview - the 3d view where the manipulator will be drawn\n//-     path - the Dag path of this manipulator\n//-     style - the displaying style of this manipulator\n//-\t\tstatus - the displaying status of this manipulator, for example, it is active or not\nvoid arrowLocatorManip::draw(M3dView &view, const MDagPath &path, M3dView::DisplayStyle style, M3dView::DisplayStatus status)\n{\n\tMPxManipContainer::draw(view,path,style,status);\n\n}\n\n// Viewport 2.0 manipulator draw overrides\nvoid arrowLocatorManip::preDrawUI( const M3dView &view )\n{\n\t//Add code to prepare specific drawing\n}\n\nvoid arrowLocatorManip::drawUI(\n\tMHWRender::MUIDrawManager& drawManager,\n\tconst MHWRender::MFrameContext& frameContext ) const\n{\n\t//Add your specific drawing here, for now, this is empty, as\n\t//there is no specific drawing for this manipulator\n}\n"
  },
  {
    "path": "08_Manipulators/arrowLocatorManip/Exercise - C++/arrowLocatorManipNode.h",
    "content": "#ifndef _arrowLocatorManipNode\n#define _arrowLocatorManipNode\n//\n// Copyright (C) \n// \n// File: arrowLocatorManipNode.h\n//\n// Dependency Graph Node: arrowLocatorManip\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n\n#include <maya/MPxManipContainer.h>\n#include <maya/MTypeId.h> \n\n \nclass arrowLocatorManip : public MPxManipContainer\n{\npublic:\n\t\t\t\t\t\tarrowLocatorManip();\n\tvirtual\t\t\t\t~arrowLocatorManip(); \n\n\tstatic  void*\t\tcreator();\n\tstatic  MStatus\t\tinitialize();\n\tvirtual MStatus\t\tcreateChildren();\n\tvirtual MStatus\t\tconnectToDependNode(const MObject &dependNode);\n\tvirtual void\t\tdraw(M3dView &view, const MDagPath &path, M3dView::DisplayStyle style, M3dView::DisplayStatus status);\n\n\n//\tMManipData\t\tcenterPointCallback(unsigned int manipIndex);\t //callback function to update manipulator position based on node position\n\n\t// Viewport 2.0 manipulator draw overrides\n\tvirtual void\t\tpreDrawUI( const M3dView &view );\n\tvirtual void\t\tdrawUI( MHWRender::MUIDrawManager& drawManager,\n\t\t\t\t\t\t\t\t\t\tconst MHWRender::MFrameContext& frameContext) const;\npublic:\n\tstatic\tMTypeId\t\tid;\n\tstatic  MDagPath\tfDiscManip;     //This variable keeps a record of the base disc manip, which we add onto our manip container \n\n\tstatic  MDagPath    fNodePath;\t\t//This variable is very important, it is for getting a hold of the corresponding locator node \n\n};\n\n#endif\n"
  },
  {
    "path": "08_Manipulators/arrowLocatorManip/Exercise - C++/arrowLocatorNode.cpp",
    "content": "//\n// Copyright (C) \n// \n// File: arrowLocatorNode.cpp\n//\n// Dependency Graph Node: arrowLocator\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n\n#include \"arrowLocatorNode.h\"\n#include \"arrowLocatorManipNode.h\"\n\n#include <maya/MPlug.h>\n#include <maya/MDataBlock.h>\n#include <maya/MDataHandle.h>\n\n#include <maya/MGlobal.h>\n#include <maya/MFnDagNode.h>\n#include <maya/MFnUnitAttribute.h>\n#include <maya/MAngle.h>\n#include <maya/MColor.h>\n#include <maya/MPxManipContainer.h>\n#include <maya/MFnPlugin.h>\n\n// You MUST change this to a unique value!!!  The id is a 32bit value used\n// to identify this type of node in the binary file format.  \n//\n//change the following to a unique value \nMTypeId     arrowLocator::id( 0x00002 );\nMString\tarrowLocator::drawDbClassification(\"drawdb/geometry/arrowLocator\");\nMString\tarrowLocator::drawRegistrantId(\"arrowLocatorNodePlugin\");\n\n\nMObject     arrowLocator::windDirection;\n\n//an array of points to draw our compass arrow in openGL\nstatic float arrow[][3] = { {2.00f, 0.0f, 0.0f} ,\n\t\t\t\t\t\t\t{-3.0f, 0.0f, 2.0f} ,\n\t\t\t\t\t\t\t{-2.0f, 0.0f, 0.0f} ,\n\t\t\t\t\t\t\t{-3.0f, 0.0f, -2.0f}}; \n\n//indices into the arrow array\nstatic GLuint triangleIndices[] = {0,1,2,0,2,3};\n     \narrowLocator::arrowLocator() {}\narrowLocator::~arrowLocator() {}\n\nMStatus arrowLocator::compute( const MPlug& plug, MDataBlock& data )\n{\n\treturn MS::kSuccess;\n}\n\nvoid* arrowLocator::creator()\n{\n\treturn new arrowLocator();\n}\n\nMStatus arrowLocator::initialize()\n{\n\t//Here we create a new attribute type that handles units: angle, distance or time\n\tMFnUnitAttribute uAttr;\n\twindDirection = uAttr.create(\"windDirection\", \"wd\", MFnUnitAttribute::kAngle, 0.0);\n\tuAttr.setStorable(true);\n\tuAttr.setWritable(true);\n\tuAttr.setReadable(true);\n\tuAttr.setKeyable(true);\n\n\tuAttr.setDefault(MAngle(0.0, MAngle::kDegrees));\n\n\taddAttribute(windDirection);\n\n\t//- TODO: To make connection between your custom node and your custom \n\t//- TODO: manipulator node, you need to name your custom manipulator \n\t//- TODO: after your custom node type name, also in your custom node's initialize()\n\t//- TODO: function, you need to call MPxManipContainer::addToManipConnectTable().\n\t//- TODO: This method adds the user defined node as an entry in the manipConnectTable \n\t//- TODO: so that when this node is selected the user can use the show manip tool to \n\t//- TODO: get the user defined manipulator associated with this node.\n\t//...\n\n\treturn MS::kSuccess;\n}\n\n\n//-\tThis method draw this locator in current scene by calling openGL functions\n//-\n//-\tArguments:\n//-\t\tview -- 3D view that is being drawn into \n//-\t\tpath -- path to this locator in the DAG \n//-\t\tstyle -- style to draw object in \n//-\t\tstatus -- selection status of object \n//-\nvoid arrowLocator::draw(M3dView &view,const MDagPath & path,M3dView::DisplayStyle style, M3dView::DisplayStatus status)\n{\n\tMObject thisNode = thisMObject();\n\n\t//We're in the draw routine, not the Compute method\n\t//therefore it is safe to grab plugs in the following way and\n\t//get/set values.  You would never do something like this in\n\t//the compute method because it might start a cycle in the\n\t//graph.  Here we just need the value of our winddirection\n\t//plug so that we can draw our arrow pointing the right way.\n\tMPlug wdPlug(thisNode, windDirection);\n\n\tMAngle angle;\n\twdPlug.getValue(angle);\n\n\t//start drawing by OpenGL\n\tview.beginGL(); \n\t\n\n\t//If the drawing style is shaded, set color and draw opaque shape\n\tif ( ( style == M3dView::kFlatShaded ) || ( style == M3dView::kGouraudShaded ) ) \n\t{\n\t\t//Push to save current color settings\n\t\tglPushAttrib( GL_CURRENT_BIT );\n\n\t\tif ( status == M3dView::kActive ) \n\t\t{\n\t\t\tview.setDrawColor( 13, M3dView::kActiveColors );\n\t\t}else {\n\t\t\tview.setDrawColor( 13, M3dView::kDormantColors );\n\t\t}  \n\n\t\t//push the old matrix on the stack, rotate the current one,\n\t\t//draw the shape, then pop the old matrix off the stack for\n\t\t//maya to use again.\n\t\tglPushMatrix();\n\t\tglRotated(-angle.asDegrees(), 0.0, 1.0, 0.0);\n\t\t\tglBegin( GL_TRIANGLE_FAN );\n\t\t\tglVertex3f(arrow[0][0],arrow[0][1],arrow[0][2]);\n\t\t\tglVertex3f(arrow[1][0],arrow[1][1],arrow[1][2]);\n\t\t\tglVertex3f(arrow[2][0],arrow[2][1],arrow[2][2]);\n\t\t\tglEnd();\n\n\t\t\tglBegin( GL_TRIANGLE_FAN );\n\t\t\tglVertex3f(arrow[2][0],arrow[2][1],arrow[2][2]);\n\t\t\tglVertex3f(arrow[3][0],arrow[3][1],arrow[3][2]);\n\t\t\tglVertex3f(arrow[0][0],arrow[0][1],arrow[0][2]);\n\t\t\tglEnd();\n\t\tglPopMatrix();\n\n\t\tglPopAttrib();\n\t}\n\n\t//Draw the outline of the arrow shape\n\tglPushMatrix();\n\tglRotated(-angle.asDegrees(), 0.0, 1.0, 0.0);\n\tglBegin( GL_LINE_STRIP);\n\tglVertex3f(arrow[0][0],arrow[0][1],arrow[0][2]);\n\tglVertex3f(arrow[1][0],arrow[1][1],arrow[1][2]);\n\tglVertex3f(arrow[2][0],arrow[2][1],arrow[2][2]);\n\tglEnd();\n\n\tglBegin( GL_LINE_STRIP );\n\tglVertex3f(arrow[2][0],arrow[2][1],arrow[2][2]);\n\tglVertex3f(arrow[3][0],arrow[3][1],arrow[3][2]);\n\tglVertex3f(arrow[0][0],arrow[0][1],arrow[0][2]);\n\tglEnd();\n\tglPopMatrix();\n\n\tview.endGL();\n\n}\n\n\n//-\tThis method should be overridden to return true if the user supplies a bounding box routine.\nbool arrowLocator::isBounded() const\n{\n\treturn true;\n}\n\n//-\tThis method return the bounding box for this locator shape, \n//- providing a bounding box routine makes refresh and selection more efficient. \n//\nMBoundingBox arrowLocator::boundingBox() const\n{\n\n\tMPoint upLeftCorner(-3.0, 0.0, -2.0);\n\tMPoint downRightCorner(2.0, 0.0, 2.0);\n\n\tMBoundingBox boundingArea(upLeftCorner,downRightCorner);\n\treturn boundingArea;\n}\n\n\nvoid arrowLocator::getRotationAngle (arrowLocatorData * data){\n\t// Retrieve value of the angle attribute from the node\n\tMStatus status ;\n\t\n\tMObject node = thisMObject();\n\tMPlug wdPlug(node, windDirection);\n\tMAngle angle;\n\twdPlug.getValue(angle);\n\n\tdata->rotateAngle = angle;\n}\n\n\n\nclass arrowLocatorOverride : public MHWRender::MPxDrawOverride\n{\npublic:\n\tstatic MHWRender::MPxDrawOverride* Creator(const MObject& obj)\n\t{\n\t\treturn new arrowLocatorOverride(obj);\n\t}\n\n\tvirtual ~arrowLocatorOverride();\n\n\tvirtual MHWRender::DrawAPI supportedDrawAPIs() const;\n\n    virtual bool isBounded(\n        const MDagPath& objPath,\n        const MDagPath& cameraPath) const;\n\n\tvirtual MBoundingBox boundingBox(\n\t\tconst MDagPath& objPath,\n\t\tconst MDagPath& cameraPath) const;\n\n\tvirtual MUserData* prepareForDraw(\n\t\tconst MDagPath& objPath,\n\t\tconst MDagPath& cameraPath,\n\t\tconst MHWRender::MFrameContext& frameContext,\n\t\tMUserData* oldData);\n\n\tstatic void draw(\n\t\tconst MHWRender::MDrawContext& context,\n\t\tconst MUserData* data);\n\nprivate:\n\tarrowLocatorOverride(const MObject& obj);\n};\n\n\n\narrowLocatorOverride::arrowLocatorOverride(const MObject& obj)\n: MHWRender::MPxDrawOverride(obj, arrowLocatorOverride::draw)\n{\n}\n\narrowLocatorOverride::~arrowLocatorOverride()\n{\n}\n\nMHWRender::DrawAPI arrowLocatorOverride::supportedDrawAPIs() const\n{\n\treturn MHWRender::kOpenGL;\n}\n\nbool arrowLocatorOverride::isBounded(\n\tconst MDagPath& objPath,\n\tconst MDagPath& cameraPath) const\n{\n\treturn true;\n}\n\nMBoundingBox arrowLocatorOverride::boundingBox(\n\tconst MDagPath& objPath,\n\tconst MDagPath& cameraPath) const\n{\n\tMStatus status;\n\tMFnDependencyNode node(objPath.node(), &status);\n\tarrowLocator* locatorNode =\n\t\tdynamic_cast<arrowLocator*>(node.userNode());\n\treturn locatorNode->boundingBox();\n}\n\nMUserData* arrowLocatorOverride::prepareForDraw(\n\tconst MDagPath& objPath,\n\tconst MDagPath& cameraPath,\n\tconst MHWRender::MFrameContext& frameContext,\n\tMUserData* oldData)\n{\n\t// get the node\n\tMStatus status;\n\tMFnDependencyNode node(objPath.node(), &status);\n\tif (!status) return NULL;\n\tarrowLocator* locatorNode =\n\t\tdynamic_cast<arrowLocator*>(node.userNode());\n\tif (!locatorNode) return NULL;\n\n\t// access/create user data for draw callback\n\tarrowLocatorData* data =\n\t\tdynamic_cast<arrowLocatorData*>(oldData);\n\tif (!data)\n\t{\n\t\tdata = new arrowLocatorData();\n\t}\n\n\t// compute data and cache it\n\tlocatorNode->getRotationAngle(data) ;\n\n\treturn data;\n}\n\nvoid arrowLocatorOverride::draw(\n\tconst MHWRender::MDrawContext& context,\n\tconst MUserData* data)\n{\n\tMAngle rotationAngle;\n\n\tfloat color [3] ={ 0.0f, 1.0f, 0.0f } ;\n\n\t// data\n\tMStatus status;\n\tMHWRender::MStateManager* stateMgr = context.getStateManager();\n\tconst arrowLocatorData* locatorData =\n\t\tdynamic_cast<const arrowLocatorData*>(data);\n\tif (!stateMgr || !locatorData) return;\n\n\tif ( locatorData )\n\t\trotationAngle = locatorData->rotateAngle;\n\n\t// matrices\n\tconst MMatrix transform =\n\t\tcontext.getMatrix(MHWRender::MFrameContext::kWorldViewMtx, &status);\n\tif (status != MStatus::kSuccess) return;\n\tconst MMatrix projection =\n\t\tcontext.getMatrix(MHWRender::MFrameContext::kProjectionMtx, &status);\n\tif (status != MStatus::kSuccess) return;\n\n\t// get renderer\n\tMHWRender::MRenderer *theRenderer =MHWRender::MRenderer::theRenderer () ;\n\tif ( !theRenderer )\n\t\treturn ;\n\tif ( theRenderer->drawAPIIsOpenGL () ) {\n\t\t\n\t\tglMatrixMode(GL_MODELVIEW);\n\t\tglPushMatrix();\n\t\tglLoadMatrixd(transform.matrix[0]);\n\t\tglMatrixMode(GL_PROJECTION);\n\t\tglPushMatrix();\n\t\tglLoadMatrixd(projection.matrix[0]);\n\n\t\tglPushAttrib(GL_CURRENT_BIT);\n\t\tglColor4fv(color);\n\n\t\t//- Draw the outline of the arrow shape\n\t\tglBegin( GL_LINE_STRIP);\n\t\tglRotated(-rotationAngle.asDegrees(), 0.0, 1.0, 0.0);\n\t\tglVertex3f(arrow[0][0],arrow[0][1],arrow[0][2]);\n\t\tglVertex3f(arrow[1][0],arrow[1][1],arrow[1][2]);\n\t\tglVertex3f(arrow[2][0],arrow[2][1],arrow[2][2]);\n\t\tglEnd();\n\n\t\tglBegin( GL_LINE_STRIP );\n\t\tglVertex3f(arrow[2][0],arrow[2][1],arrow[2][2]);\n\t\tglVertex3f(arrow[3][0],arrow[3][1],arrow[3][2]);\n\t\tglVertex3f(arrow[0][0],arrow[0][1],arrow[0][2]);\n\t\tglEnd();\n\n\t\n\t\tglPopAttrib();\n\n\t\tglPopMatrix();\n\t\tglMatrixMode(GL_MODELVIEW);\n\t\tglPopMatrix();\n\n\t}\n}\n\nMStatus initializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is loaded into Maya.  It \n//\t\tregisters all of the services that this plug-in provides with \n//\t\tMaya.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{ \n\tMStatus   status;\n\tMFnPlugin plugin( obj, \"\", \"2009\", \"Any\");\n\n\tstatus = plugin.registerNode( \"arrowLocator\", arrowLocator::id, arrowLocator::creator,\n\t\tarrowLocator::initialize, MPxNode::kLocatorNode,&arrowLocator::drawDbClassification);\n\n\tstatus = MHWRender::MDrawRegistry::registerDrawOverrideCreator (\n\t\tarrowLocator::drawDbClassification,\n\t\tarrowLocator::drawRegistrantId,\n\t\tarrowLocatorOverride::Creator) ;\n\n\tif (!status) {\n\t\tstatus.perror(\"registerNode\");\n\t\treturn status;\n\t}\n\n\n\t//- Register custom manipulator for your custom locator node.\n\t//- In order to make it work, you need to name your custom manipulator \n\t//- after your custom node type name, also in your custom node's initialize()\n\t//- function, you need to call MPxManipContainer::addToManipConnectTable()\n\n\tstatus = plugin.registerNode( \"arrowLocatorManip\", arrowLocatorManip::id, arrowLocatorManip::creator,\n\t\tarrowLocatorManip::initialize,MPxNode::kManipContainer );\n\tif (!status) {\n\t\tstatus.perror(\"registerNode\");\n\t\treturn status;\n\t}\n\n\n\treturn status;\n}\n\nMStatus uninitializePlugin( MObject obj)\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is unloaded from Maya. It \n//\t\tderegisters all of the services that it was providing.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{\n\tMStatus   status;\n\tMFnPlugin plugin( obj );\n\n\tstatus = plugin.deregisterNode( arrowLocatorManip::id );\n\tif (!status) {\n\t\tstatus.perror(\"deregisterNode\");\n\t\treturn status;\n\t}\n\n\tstatus = plugin.deregisterNode( arrowLocator::id );\n\n\tMHWRender::MDrawRegistry::deregisterDrawOverrideCreator (\n\t\tarrowLocator::drawDbClassification,\n\t\tarrowLocator::drawRegistrantId) ;\n\n\tif (!status) {\n\t\tstatus.perror(\"deregisterNode\");\n\t\treturn status;\n\t}\n\n\treturn status;\n}\n"
  },
  {
    "path": "08_Manipulators/arrowLocatorManip/Exercise - C++/arrowLocatorNode.h",
    "content": "#ifndef _arrowLocatorNode\n#define _arrowLocatorNode\n//\n// Copyright (C) \n// \n// File: arrowLocatorNode.h\n//\n// Dependency Graph Node: arrowLocator\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n\n#include <maya/MPxLocatorNode.h>\n#include <maya/MFnNumericAttribute.h>\n#include <maya/MTypeId.h> \n#include <maya/M3dView.h>\n#include <maya/MDagPath.h>\n\n\n// Viewport 2.0 includes\n#include <maya/MDrawRegistry.h>\n#include <maya/MPxDrawOverride.h>\n#include <maya/MUserData.h>\n#include <maya/MDrawContext.h>\n#include <maya/MGlobal.h>\n#include <maya/MSelectionList.h>\n#include <maya/MViewport2Renderer.h>\n#include <maya/MHWGeometryUtilities.h>\n#include <maya/MStateManager.h>\n#include <maya/MShaderManager.h>\n#include <maya/MAngle.h>\n\n\n\n//- Macros to use to rotate the locator\n#define PI 3.14159265358979\n#define toDegree(rot) rot*(180.0/PI)\n\nclass arrowLocatorData : public MUserData\n{\npublic:\n\tMAngle rotateAngle ;\n\n\tarrowLocatorData() : MUserData(false) {} // don't delete after draw\n\tvirtual ~arrowLocatorData() {}\n};\n\nclass arrowLocator : public MPxLocatorNode\n{\npublic:\n\tarrowLocator();\n\tvirtual ~arrowLocator();\n\n\tMStatus compute( const MPlug& plug, MDataBlock& data );\n\tvirtual void draw(M3dView &view,const MDagPath & path,M3dView::DisplayStyle style, M3dView::DisplayStatus status);\n\tvirtual MBoundingBox boundingBox() const;\n\tvirtual bool isBounded() const;\n\n\n\tvoid getRotationAngle (arrowLocatorData * data );\n\n\tstatic MStatus\t\tinitialize();\n\n\tstatic void* creator();\n\n\tstatic\tMTypeId\t\tid;\n\n\tstatic\tMString\t\tdrawDbClassification;\n\tstatic\tMString\t\tdrawRegistrantId;\n\n\tstatic MObject windDirection; //- This is an attribute representing the rotation angle\n\n};\n\n\n#endif\n"
  },
  {
    "path": "08_Manipulators/arrowLocatorManip/Exercise - py/arrowLocatorManip.py",
    "content": "# Copyright (C) \n# \n# Author: Autodesk Developer Network\n\n#For this exercise, search for the TODO keywords and follow the instructions in\n#comments. If you are unsure of what you need to do, feel free to ask the instructor\n#or look into the solution folder.\n#Each #... line is a line of code you need to write or complete.\n\nimport sys, math\n\nimport maya.OpenMaya as OpenMaya\nimport maya.OpenMayaMPx as OpenMayaMPx\nimport maya.OpenMayaRender as OpenMayaRender\nimport maya.OpenMayaUI as OpenMayaUI\n\nkPluginManipNodeTypeName = \"arrowLocatorManip\"\nkPluginNodeTypeName = \"arrowLocator\"\n\nkPluginManipNodeId = OpenMaya.MTypeId(0x00003)\nkPluginNodeId = OpenMaya.MTypeId(0x00002)\n\nglRenderer = OpenMayaRender.MHardwareRenderer.theRenderer()\nglFT = glRenderer.glFunctionTable()\n\n#pi = 3.14159265358979\n\n#an array of points to draw our compass arrow in openGL\narrow = ( [2.00, 0.0, 0.0],\n[-3.0, 0.0, 2.0],\n[-2.0, 0.0, 0.0],\n[-3.0, 0.0, -2.0]) \n\n#indices into the arrow array\ntriangleIndices = [0,1,2,0,2,3]\n\n#def toDegree(rot):= rot*(180.0/PI)\n\n\n\nclass arrowLocatorManip(OpenMayaMPx.MPxManipContainer):\n\tdef __init__(self):\n\t\tOpenMayaMPx.MPxManipContainer.__init__(self)\n\t\tself.fDiscManip = OpenMaya.MDagPath()\n\t\tself.fNodePath = OpenMaya.MDagPath()\n\n\t#- Container manipulators are composed of one or more base manipulators. \n\t#- When base manipulators are added to a container manipulator, they are referred to \n\t#- as children of the container manipulator, and are added using the createChildren method. \n\tdef createChildren(self):\n\t\ttry:\n\t\t\t#- TODO: Create a base disc manip and \n\t\t\t#- TODO: add it into this manip container, assign\n\t\t\t#- TODO: the returned value of the function call to member\n\t\t\t#- TODO: variable: \"fDiscManip\" \n\t\t\t#...\n\t\t\t\n\t\t\t#- Initialize the angle and starting position of this manipulator\n\t\t\tstartPoint = OpenMaya.MPoint(0.0, 0.0, 0.0) \n\t\t\tstartAngle = OpenMaya.MAngle(0.0,OpenMaya.MAngle.kDegrees)\n\t\t\tfnDisc = OpenMayaUI.MFnDiscManip(self.fDiscManip)\n\t\t\tfnDisc.setCenterPoint(startPoint)\n\t\t\tfnDisc.setAngle(startAngle)\n\n\t\texcept:\n\t\t\tsys.stderr.write(\"ERROR: arrowLocatorManip.createChildren\\n\")\n\t\t\traise\t\t\n\n\t#- This function is responsible to make the connection (association) \n\t#- between manipulators and the affected attributes. When a node in a scene \n\t#- is selected and user click on show manipulator tool, \n\t#- this function is called with the selected node.\n\t#- Arguments:\n\t#- \tdependNode - the node which is selected\n\tdef connectToDependNode(self, node):\n\t\ttry:\n\t\t\t#- Find the \"windDirection\" plug on the selected node, which is the custom\n\t\t\t#- locator node.\n\t\t\tfnDepNode = OpenMaya.MFnDependencyNode(node)\n\t\t\trotationPlug = fnDepNode.findPlug(\"windDirection\")\n\n\t\t\t#- TODO: Connect the \"windDirection\" plug with the disc manip\n\t\t\t#...\n\t\t\t#...\n\n\n\t\t\t#- Set up affecting relationship using conversion callback function\n\t\t\t#- We are using addPlugToManipConversionCallback so that whenever\n\t\t\t#- the custom locator moves, the dis manip moves with it.\n\t\t\t#fnDagNode = OpenMaya.MFnDagNode(node)\n\t\t\t#fnDagNode.getPath(self.fNodePath)\n\t\t\t#centerPointIndex = fnDisc.centerIndex()\n\t\t\t#self.addPlugToManipConversion(centerPointIndex)\n\n\t\t\t#- The following two functions are mandatory inside your\n\t\t\t#- connectToDependNode() function\n\t\t\tself.finishAddingManips()\n\t\t\tOpenMayaMPx.MPxManipContainer.connectToDependNode(self, node)\n\n\t\texcept:\n\t\t\tsys.stderr.write(\"ERROR: arrowLocatorManip.connectToDependNode\\n\")\n\t\t\traise\n\n\t#- This method is an optional method, you can use it to customize \n\t#- the drawing of your manipulator. \n\t#- If you are overriding this function, most likely you will use OpenGL calls, \n\t#- so opengl32.lib should be included in the linking libraries.\n\t#- Arguments:\n\t#- \tview - the 3d view where the manipulator will be drawn\n\t#-     path - the Dag path of this manipulator\n\t#-     style - the displaying style of this manipulator\n\t#-\t\tstatus - the displaying status of this manipulator, for example, it is active or not\n\tdef draw(self, view, path, style, status):\n\t\tOpenMayaMPx.MPxManipContainer.draw(self, view, path, style, status)\n\n\t#- This method is plugToManipConversionCallback function\n\t#- You implement it so that a specific component of the manipulator\n\t#- will be modified automatically when some plug value changes on \n\t#- the custom locator.\n\t#- Arguments:\n\t#- \tmanipIndex - the index of the component on the manip you want to affect, \n\t#-                  in this case, it is the center point of this manip\n\t#-\tReturn Values:\n\t#-\t\tMManipData object, which represents the updated value\n\t'''def plugToManipConversion( self, manipIndex ):\n\t\ttry:\n\t\t\t#Get parent transform node of the locator node\n\t\t\t\n\t\t\tparentTransform = self.fNodePath.transform()\n\n\t\t\t#Get the transform node DAG path\n\t\t\ttransformPath = OpenMaya.MDagPath()\n\t\t\tOpenMaya.MDagPath.getAPathTo(parentTransform,transformPath)\n\n\t\t\t#Retrieve world space translation\n\t\t\tfnTrans = OpenMaya.MFnTransform(transformPath)\n\t\t\ttranslation = OpenMaya.MVector()\n\t\t\ttranslation = fnTrans.getTranslation(OpenMaya.MSpace.kWorld)\n\n\t\t\tnumData = OpenMaya.MFnNumericData()\n\t\t\tnumDataValue = numData.create(OpenMaya.MFnNumericData.k3Double)\n\t\t\tstatus = numData.setData3Double(translation.x,translation.y,translation.z)\n\t\t\tmanipData = OpenMayaUI.MManipData(numDataValue)\n\t\texcept:\n\t\t\tsys.stderr.write(\"ERROR: arrowManip.plugToManipConversion\\n\")\n\t\t\traise\n\n\t\treturn manipData'''\n\n# Node definition\nclass arrowLocator(OpenMayaMPx.MPxLocatorNode):\n\twindDirection = OpenMaya.MObject()\n\t\n\tdef __init__(self):\n\t\tOpenMayaMPx.MPxLocatorNode.__init__(self)\n\t\t\n\n\tdef compute(self, plug, data):\n\t\treturn OpenMaya.kUnknownParameter\n\n\t#-\tThis method draw this locator in current scene by calling openGL functions\n\t#-\n\t#-\tArguments:\n\t#-\t\tview -- 3D view that is being drawn into \n\t#-\t\tpath -- path to this locator in the DAG \n\t#-\t\tstyle -- style to draw object in \n\t#-\t\tstatus -- selection status of object \n\t#-\n\tdef draw(self, view, path, style, status):\n\t\tthisNode = self.thisMObject()\n\n\t\t#We're in the draw routine, not the Compute method\n\t\t#therefore it is safe to grab plugs in the following way and\n\t\t#get/set values.  You would never do something like this in\n\t\t#the compute method because it might start a cycle in the\n\t\t#graph.  Here we just need the value of our winddirection\n\t\t#plug so that we can draw our arrow pointing the right way.\n\t\tplug = OpenMaya.MPlug(thisNode, arrowLocator.windDirection)\n\t\tangle = plug.asMAngle()\n\n\t\t#start drawing by OpenGL\n\t\tview.beginGL() \n\n\n\t\t#If the drawing style is shaded, set color and draw opaque shape\n\t\tif ((style == OpenMayaUI.M3dView.kFlatShaded) or (style == OpenMayaUI.M3dView.kGouraudShaded)):\n\t\t\t\n\t\t\t#Push to save current color settings\n\t\t\tglFT.glPushAttrib(OpenMayaRender.MGL_CURRENT_BIT )\n\n\t\t\tif (status == OpenMayaUI.M3dView.kActive):\n\t\t\t\tview.setDrawColor( 13, OpenMayaUI.M3dView.kActiveColors )\n\t\t\telse:\n\t\t\t\tview.setDrawColor( 13, OpenMayaUI.M3dView.kDormantColors )\n\t\t\t  \n\n\t\t\t#push the old matrix on the stack, rotate the current one,\n\t\t\t#draw the shape, then pop the old matrix off the stack for\n\t\t\t#maya to use again.\n\t\t\tglFT.glPushMatrix()\n\t\t\tglFT.glRotated(-angle.asDegrees(), 0.0, 1.0, 0.0)\n\t\t\tglFT.glBegin( OpenMayaRender.MGL_TRIANGLE_FAN )\n\t\t\tglFT.glVertex3f(arrow[0][0],arrow[0][1],arrow[0][2])\n\t\t\tglFT.glVertex3f(arrow[1][0],arrow[1][1],arrow[1][2])\n\t\t\tglFT.glVertex3f(arrow[2][0],arrow[2][1],arrow[2][2])\n\t\t\tglFT.glEnd()\n\n\t\t\tglFT.glBegin( OpenMayaRender.MGL_TRIANGLE_FAN )\n\t\t\tglFT.glVertex3f(arrow[2][0],arrow[2][1],arrow[2][2])\n\t\t\tglFT.glVertex3f(arrow[3][0],arrow[3][1],arrow[3][2])\n\t\t\tglFT.glVertex3f(arrow[0][0],arrow[0][1],arrow[0][2])\n\t\t\tglFT.glEnd()\n\t\t\tglFT.glPopMatrix()\n\n\t\t\tglFT.glPopAttrib()\n\t\t\n\n\t\t#Draw the outline of the arrow shape\n\t\tglFT.glPushMatrix()\n\t\tglFT.glRotated(-angle.asDegrees(), 0.0, 1.0, 0.0)\n\t\tglFT.glBegin( OpenMayaRender.MGL_LINE_STRIP)\n\t\tglFT.glVertex3f(arrow[0][0],arrow[0][1],arrow[0][2])\n\t\tglFT.glVertex3f(arrow[1][0],arrow[1][1],arrow[1][2])\n\t\tglFT.glVertex3f(arrow[2][0],arrow[2][1],arrow[2][2])\n\t\tglFT.glEnd()\n\n\t\tglFT.glBegin( OpenMayaRender.MGL_LINE_STRIP )\n\t\tglFT.glVertex3f(arrow[2][0],arrow[2][1],arrow[2][2])\n\t\tglFT.glVertex3f(arrow[3][0],arrow[3][1],arrow[3][2])\n\t\tglFT.glVertex3f(arrow[0][0],arrow[0][1],arrow[0][2])\n\t\tglFT.glEnd()\n\t\tglFT.glPopMatrix()\n\n\t\tview.endGL()\n\n\tdef isBounded(self):\n\t\treturn True\n\n\t#- This method return the bounding box for this locator shape, \n\t#- providing a bounding box routine makes refresh and selection more efficient. \n\t#\n\tdef boundingBox(self):\n\t\tupLeftCorner = OpenMaya.MPoint(-3.0, 0.0, -2.0)\n\t\tdownRightCorner = OpenMaya.MPoint(2.0, 0.0, 2.0)\n\n\t\tboundingArea = OpenMaya.MBoundingBox(upLeftCorner,downRightCorner)\n\t\treturn boundingArea\n\n\n#- This method exists to give Maya a way to create new objects\n#- of this type.\ndef ManipNodeCreator():\n\treturn OpenMayaMPx.asMPxPtr( arrowLocatorManip() )\n\n#- This method is called to create and initialize all of the attributes\n#- and attribute dependencies for this node type.  This is only called \n#-\tonce when the node type is registered with Maya.\ndef ManipNodeInitializer():\n\tOpenMayaMPx.MPxManipContainer.initialize()\n\t\t\n# Creator\ndef nodeCreator():\n\treturn OpenMayaMPx.asMPxPtr( arrowLocator() )\n\n# initializer\ndef nodeInitializer():\n\t#Here we create a new attribute type that handles units: angle, distance or time\n\tuAttr = OpenMaya.MFnUnitAttribute()\n\tarrowLocator.windDirection = uAttr.create(\"windDirection\", \"wd\", OpenMaya.MFnUnitAttribute.kAngle)\n\tuAttr.setDefault(0.0)\n\tuAttr.setStorable(True)\n\tuAttr.setWritable(True)\n\tuAttr.setReadable(True)\n\tuAttr.setKeyable(True)\n\n\tuAttr.setDefault(OpenMaya.MAngle(0.0, OpenMaya.MAngle.kDegrees))\n\n\tarrowLocator.addAttribute(arrowLocator.windDirection)\n\n\t#- TODO: To make connection between your custom node and your custom \n\t#- TODO: manipulator node, you need to name your custom manipulator \n\t#- TODO: after your custom node type name, also in your custom node's initialize()\n\t#- TODO: function, you need to call MPxManipContainer::addToManipConnectTable().\n\t#- TODO: This method adds the user defined node as an entry in the manipConnectTable \n\t#- TODO: so that when this node is selected the user can use the show manip tool to \n\t#- TODO: get the user defined manipulator associated with this node.\n\t#...\n\t\n# Initialize the script plug-in\ndef initializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\tmplugin.registerNode( kPluginManipNodeTypeName, kPluginManipNodeId, ManipNodeCreator, ManipNodeInitializer, OpenMayaMPx.MPxNode.kManipContainer )\n\t\t\n\texcept:\n\t\tsys.stderr.write( \"Failed to register manip node: %s\" % kPluginManipNodeTypeName )\n\t\traise\n\ttry:\n\t\t\n\t\tmplugin.registerNode( kPluginNodeTypeName, kPluginNodeId, nodeCreator, nodeInitializer, OpenMayaMPx.MPxNode.kLocatorNode )\n\texcept:\n\t\tsys.stderr.write( \"Failed to register node: %s\" % kPluginNodeTypeName )\n\t\traise\n\n# Uninitialize the script plug-in\ndef uninitializePlugin(mobject):\n\n\t\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\t\n\ttry:\n\t\tmplugin.deregisterNode( kPluginManipNodeId)\n\t\t\n\texcept:\n\t\tsys.stderr.write( \"Failed to deregister node: %s\" % kPluginManipNodeTypeName )\n\t\traise\n\n\ttry:\n\t\t\n\t\tmplugin.deregisterNode( kPluginNodeId )\n\texcept:\n\t\tsys.stderr.write( \"Failed to deregister command: %s\" % kPluginNodeTypeName )\n\t\traise\n\n\t\t"
  },
  {
    "path": "08_Manipulators/arrowLocatorManip/Solution - C++/arrowLocatorManip.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 2012\nProject(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"arrowLocatorManip\", \"arrowLocatorManip.vcxproj\", \"{C05EECF5-6CF1-4302-A92B-24DDB374E61A}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|x64 = Debug|x64\n\t\tRelease|x64 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{C05EECF5-6CF1-4302-A92B-24DDB374E61A}.Debug|x64.ActiveCfg = Debug|x64\n\t\t{C05EECF5-6CF1-4302-A92B-24DDB374E61A}.Debug|x64.Build.0 = Debug|x64\n\t\t{C05EECF5-6CF1-4302-A92B-24DDB374E61A}.Release|x64.ActiveCfg = Release|x64\n\t\t{C05EECF5-6CF1-4302-A92B-24DDB374E61A}.Release|x64.Build.0 = Release|x64\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "08_Manipulators/arrowLocatorManip/Solution - C++/arrowLocatorManip.vcxproj",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<Project DefaultTargets=\"Build\" ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <ItemGroup Label=\"ProjectConfigurations\">\n    <ProjectConfiguration Include=\"Debug|Win32\">\n      <Configuration>Debug</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Debug|x64\">\n      <Configuration>Debug</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|Win32\">\n      <Configuration>Release</Configuration>\n      <Platform>Win32</Platform>\n    </ProjectConfiguration>\n    <ProjectConfiguration Include=\"Release|x64\">\n      <Configuration>Release</Configuration>\n      <Platform>x64</Platform>\n    </ProjectConfiguration>\n  </ItemGroup>\n  <PropertyGroup Label=\"Globals\">\n    <ProjectGuid>{C05EECF5-6CF1-4302-A92B-24DDB374E61A}</ProjectGuid>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.Default.props\" />\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"Configuration\">\n    <ConfigurationType>DynamicLibrary</ConfigurationType>\n    <PlatformToolset>v110</PlatformToolset>\n  </PropertyGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.props\" />\n  <ImportGroup Label=\"ExtensionSettings\">\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <ImportGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\" Label=\"PropertySheets\">\n    <Import Project=\"$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props\" Condition=\"exists('$(UserRootDir)\\Microsoft.Cpp.$(Platform).user.props')\" Label=\"LocalAppDataPlatform\" />\n  </ImportGroup>\n  <PropertyGroup Label=\"UserMacros\" />\n  <PropertyGroup>\n    <_ProjectFileVersion>10.0.40219.1</_ProjectFileVersion>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">Debug\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">Debug\\</IntDir>\n    <OutDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Release\\</OutDir>\n    <IntDir Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">Release\\</IntDir>\n  </PropertyGroup>\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <OutDir>C:\\MayaAPITraining\\plug-ins\\</OutDir>\n    <TargetExt>.mll</TargetExt>\n  </PropertyGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"WIN32\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2009\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/arrowLocatorManip.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;OpenMayaUI.lib;OpenGL32.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Debug\\arrowLocatorManip.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2009\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/arrowLocatorManip.pdb</ProgramDatabaseFile>\n      <RandomizedBaseAddress>false</RandomizedBaseAddress>\n      <DataExecutionPrevention>\n      </DataExecutionPrevention>\n      <ImportLibrary>Debug/arrowLocatorManip.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Debug|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS /Gm /EHac /ZI /I \".\" /D \"_DEBUG\"  /RTC1 /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>Disabled</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2015\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Debug/arrowLocatorManip.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /dll /incremental:yes /debug /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;OpenMayaRender.lib;OpenMayaUI.lib;OpenGL32.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>C:\\MayaAPITraining\\plug-ins\\arrowLocatorManip.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2015\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Debug/arrowLocatorManip.pdb</ProgramDatabaseFile>\n      <RandomizedBaseAddress>false</RandomizedBaseAddress>\n      <DataExecutionPrevention>\n      </DataExecutionPrevention>\n      <ImportLibrary>Debug/arrowLocatorManip.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|Win32'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2009\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/arrowLocatorManip.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;OpenMayaUI.lib;OpenGL32.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\arrowLocatorManip.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2009\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/arrowLocatorManip.pdb</ProgramDatabaseFile>\n      <RandomizedBaseAddress>false</RandomizedBaseAddress>\n      <DataExecutionPrevention>\n      </DataExecutionPrevention>\n      <ImportLibrary>Release/arrowLocatorManip.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemDefinitionGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|x64'\">\n    <ClCompile>\n      <AdditionalOptions>/GR /GS  /EHac /I \".\"  /c %(AdditionalOptions)</AdditionalOptions>\n      <Optimization>MaxSpeed</Optimization>\n      <AdditionalIncludeDirectories>C:\\Program Files\\Autodesk\\Maya2009\\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>\n      <PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;_AFXDLL;_MBCS;NT_PLUGIN;REQUIRE_IOSTREAM;%(PreprocessorDefinitions)</PreprocessorDefinitions>\n      <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>\n      <PrecompiledHeaderOutputFile>Release/arrowLocatorManip.pch</PrecompiledHeaderOutputFile>\n      <WarningLevel>Level3</WarningLevel>\n    </ClCompile>\n    <Link>\n      <AdditionalOptions>/subsystem:windows /incremental:no /machine:I386 /export:initializePlugin /export:uninitializePlugin %(AdditionalOptions)</AdditionalOptions>\n      <AdditionalDependencies>Foundation.lib;OpenMaya.lib;OpenMayaUI.lib;OpenGL32.lib;%(AdditionalDependencies)</AdditionalDependencies>\n      <OutputFile>Release\\arrowLocatorManip.mll</OutputFile>\n      <AdditionalLibraryDirectories>C:\\Program Files\\Autodesk\\Maya2009\\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>\n      <ProgramDatabaseFile>Release/arrowLocatorManip.pdb</ProgramDatabaseFile>\n      <RandomizedBaseAddress>false</RandomizedBaseAddress>\n      <DataExecutionPrevention>\n      </DataExecutionPrevention>\n      <ImportLibrary>Release/arrowLocatorManip.lib</ImportLibrary>\n    </Link>\n  </ItemDefinitionGroup>\n  <ItemGroup>\n    <ClCompile Include=\"arrowLocatorManipNode.cpp\" />\n    <ClCompile Include=\"arrowLocatorNode.cpp\" />\n  </ItemGroup>\n  <ItemGroup>\n    <ClInclude Include=\"arrowLocatorManipNode.h\" />\n    <ClInclude Include=\"arrowLocatorNode.h\" />\n  </ItemGroup>\n  <Import Project=\"$(VCTargetsPath)\\Microsoft.Cpp.targets\" />\n  <ImportGroup Label=\"ExtensionTargets\">\n  </ImportGroup>\n</Project>"
  },
  {
    "path": "08_Manipulators/arrowLocatorManip/Solution - C++/arrowLocatorManipNode.cpp",
    "content": "//\n// Copyright (C) \n// \n// File: arrowLocatorManipNode.cpp\n//\n// Dependency Graph Node: arrowLocatorManip\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n\n#include \"arrowLocatorManipNode.h\"\n\n#include <maya/MPlug.h>\n#include <maya/MDataBlock.h>\n#include <maya/MDataHandle.h>\n#include <maya/MFnDependencyNode.h>\n#include <maya/MFnDiscManip.h>\n#include <maya/MAngle.h>\n\n#include <maya/MGlobal.h>\n\n//- You MUST change this to a unique value!!!  The id is a 32bit value used\n//- to identify this type of node in the binary file format.  \n//-\n//- change the following to a unique value and then erase this line \nMTypeId     arrowLocatorManip::id( 0x00003 );    \nMDagPath\tarrowLocatorManip::fDiscManip;\n\nMDagPath\tarrowLocatorManip::fNodePath;\n\narrowLocatorManip::arrowLocatorManip() {}\narrowLocatorManip::~arrowLocatorManip() {}\n\n\n//-\tThis method exists to give Maya a way to create new objects\n//- of this type. \n//-\n//-\tReturn Value:\n//-\t\ta new object of this type\n//-\nvoid* arrowLocatorManip::creator()\n{\n\treturn new arrowLocatorManip();\n}\n\n\n//- This method is called to create and initialize all of the attributes\n//- and attribute dependencies for this node type.  This is only called \n//-\tonce when the node type is registered with Maya.\n//-\n//-\tReturn Values:\n//-\t\tMS::kSuccess\n//-\t\tMS::kFailure\t\nMStatus arrowLocatorManip::initialize()\t\n{\n\tMStatus stat;\n\tstat = MPxManipContainer::initialize();\n\treturn stat;\n}\n\n\n//- Container manipulators are composed of one or more base manipulators. \n//- When base manipulators are added to a container manipulator, they are referred to \n//- as children of the container manipulator, and are added using the createChildren method. \nMStatus arrowLocatorManip::createChildren()\n{\n\tMStatus status = MStatus::kSuccess;\n\n\t//- Add a base disc manip into this manip container\n\tMString manipName(\"angleManip\");\n\tMString angleName(\"yRotation\");\n\tfDiscManip = addDiscManip(manipName,angleName);\n\n\t//- Initialize the angle and starting position of this manipulator\n\tMPoint startPoint(0.0, 0.0, 0.0);\n\tMAngle startAngle(0.0,MAngle::kDegrees);\n\tMFnDiscManip fnDisc(fDiscManip,&status);\n\tfnDisc.setCenterPoint(startPoint);\n\tfnDisc.setAngle(startAngle);\n\n\treturn status;\n}\n\n//- This function is responsible to make the connection (association) \n//- between manipulators and the affected attributes. When a node in a scene \n//- is selected and user click on show manipulator tool, \n//- this function is called with the selected node.\n//- Arguments:\n//- \tdependNode - the node which is selected\nMStatus arrowLocatorManip::connectToDependNode(const MObject &dependNode)\n{\n\tMStatus status = MStatus::kSuccess;\n\n\t//- Find the \"windDirection\" plug on the selected node, which is the custom\n\t//- locator node.\n\tMFnDependencyNode fnDepNode(dependNode);\n\tMPlug rotationPlug = fnDepNode.findPlug(MString(\"windDirection\"),&status);\n\n\t//- Connect the \"windDirection\" plug with the base disc manip\n\tMFnDiscManip fnDisc(fDiscManip,&status);\n\tstatus = fnDisc.connectToAnglePlug(rotationPlug);\n\n\n\t//- Set up affecting relationship using conversion callback function\n\t//- We are using addPlugToManipConversionCallback so that whenever\n\t//- the custom locator moves, the dis manip moves with it.\n\tMFnDagNode fnDagNode(dependNode);\n\tfnDagNode.getPath(fNodePath);\n\tunsigned int centerPointIndex = fnDisc.centerIndex(&status);\n\taddPlugToManipConversionCallback(centerPointIndex,(plugToManipConversionCallback)&arrowLocatorManip::centerPointCallback);\n\n\n\t//- The following two functions are mandatory inside your\n\t//- connectToDependNode() function\n\tstatus = finishAddingManips();\n\tstatus = MPxManipContainer::connectToDependNode(dependNode);\n\t\n\treturn status;\n\n}\n\n//- This method is plugToManipConversionCallback function\n//- You implement it so that a specific component of the manipulator\n//- will be modified automatically when some plug value changes on \n//- the custom locator.\n//- Arguments:\n//- \tmanipIndex - the index of the component on the manip you want to affect, \n//-                  in this case, it is the center point of this manip\n//-\tReturn Values:\n//-\t\tMManipData object, which represents the updated value\nMManipData arrowLocatorManip::centerPointCallback(unsigned int manipIndex)\n{\n\tMStatus status;\n\n\t//Get parent transform node of the locator node\n\tMObject parentTransform = fNodePath.transform(&status);\n\n\t//Get the transform node DAG path\n\tMDagPath transformPath;\n\tMDagPath::getAPathTo(parentTransform,transformPath);\n\n\t//Retrieve world space translation\n\tMFnTransform fnTrans(transformPath,&status);\n\tMVector translation = fnTrans.getTranslation(MSpace::kWorld,&status);\n\n\tMFnNumericData numData;\n\tMObject numDataValue = numData.create(MFnNumericData::k3Double,&status);\n\tstatus = numData.setData3Double(translation.x,translation.y,translation.z);\n\n\tMManipData manipData(numDataValue);\n\treturn manipData;\n}\n\n//- This method is an optional method, you can use it to customize \n//- the drawing of your manipulator. \n//- If you are overriding this function, most likely you will use OpenGL calls, \n//- so opengl32.lib should be included in the linking libraries.\n//- Arguments:\n//- \tview - the 3d view where the manipulator will be drawn\n//-     path - the Dag path of this manipulator\n//-     style - the displaying style of this manipulator\n//-\t\tstatus - the displaying status of this manipulator, for example, it is active or not\nvoid arrowLocatorManip::draw(M3dView &view, const MDagPath &path, M3dView::DisplayStyle style, M3dView::DisplayStatus status)\n{\n\tMPxManipContainer::draw(view,path,style,status);\n\n}\n\n// Viewport 2.0 manipulator draw overrides\nvoid arrowLocatorManip::preDrawUI( const M3dView &view )\n{\n\t//Add code to prepare specific drawing\n}\n\nvoid arrowLocatorManip::drawUI(\n\tMHWRender::MUIDrawManager& drawManager,\n\tconst MHWRender::MFrameContext& frameContext ) const\n{\n\t//Add your specific drawing here, for now, this is empty, as\n\t//there is no specific drawing for this manipulator\n}\n"
  },
  {
    "path": "08_Manipulators/arrowLocatorManip/Solution - C++/arrowLocatorManipNode.h",
    "content": "#ifndef _arrowLocatorManipNode\n#define _arrowLocatorManipNode\n//\n// Copyright (C) \n// \n// File: arrowLocatorManipNode.h\n//\n// Dependency Graph Node: arrowLocatorManip\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n\n#include <maya/MPxManipContainer.h>\n#include <maya/MTypeId.h> \n\n \nclass arrowLocatorManip : public MPxManipContainer\n{\npublic:\n\t\t\t\t\t\tarrowLocatorManip();\n\tvirtual\t\t\t\t~arrowLocatorManip(); \n\n\tstatic  void*\t\tcreator();\n\tstatic  MStatus\t\tinitialize();\n\tvirtual MStatus\t\tcreateChildren();\n\tvirtual MStatus\t\tconnectToDependNode(const MObject &dependNode);\n\tvirtual void\t\tdraw(M3dView &view, const MDagPath &path, M3dView::DisplayStyle style, M3dView::DisplayStatus status);\n\n\n\tMManipData\t\tcenterPointCallback(unsigned int manipIndex);\t //callback function to update manipulator position based on node position\n\t\n\t// Viewport 2.0 manipulator draw overrides\n\tvirtual void\t\tpreDrawUI( const M3dView &view );\n\tvirtual void\t\tdrawUI( MHWRender::MUIDrawManager& drawManager,\n\t\t\t\t\t\t\t\t\t\tconst MHWRender::MFrameContext& frameContext) const;\n\npublic:\n\tstatic\tMTypeId\t\tid;\n\tstatic  MDagPath\tfDiscManip;     //This variable keeps a record of the base disc manip, which we add onto our manip container \n\n\tstatic  MDagPath    fNodePath;\t\t//This variable is very important, it is for getting a hold of the corresponding locator node \n\n};\n\n#endif\n"
  },
  {
    "path": "08_Manipulators/arrowLocatorManip/Solution - C++/arrowLocatorNode.cpp",
    "content": "//\n// Copyright (C) \n// \n// File: arrowLocatorNode.cpp\n//\n// Dependency Graph Node: arrowLocator\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n\n#include \"arrowLocatorNode.h\"\n#include \"arrowLocatorManipNode.h\"\n\n#include <maya/MPlug.h>\n#include <maya/MDataBlock.h>\n#include <maya/MDataHandle.h>\n\n#include <maya/MGlobal.h>\n#include <maya/MFnDagNode.h>\n#include <maya/MFnUnitAttribute.h>\n#include <maya/MAngle.h>\n#include <maya/MColor.h>\n#include <maya/MPxManipContainer.h>\n\n#include <maya/MFnPlugin.h>\n\n// You MUST change this to a unique value!!!  The id is a 32bit value used\n// to identify this type of node in the binary file format.  \n//\n//change the following to a unique value \nMTypeId     arrowLocator::id( 0x00002 );\nMString\tarrowLocator::drawDbClassification(\"drawdb/geometry/arrowLocator\");\nMString\tarrowLocator::drawRegistrantId(\"arrowLocatorNodePlugin\");\n\n\nMObject     arrowLocator::windDirection;\n\n//an array of points to draw our compass arrow in openGL\nstatic float arrow[][3] = { {2.00f, 0.0f, 0.0f} ,\n\t\t\t\t\t\t\t{-3.0f, 0.0f, 2.0f} ,\n\t\t\t\t\t\t\t{-2.0f, 0.0f, 0.0f} ,\n\t\t\t\t\t\t\t{-3.0f, 0.0f, -2.0f}}; \n\n//indices into the arrow array\nstatic GLuint triangleIndices[] = {0,1,2,0,2,3};\n\n\nMStatus arrowLocator::compute( const MPlug& plug, MDataBlock& data )\n{\n\treturn MS::kSuccess;\n}\n\n\n\nMStatus arrowLocator::initialize()\n{\n\t//Here we create a new attribute type that handles units: angle, distance or time\n\tMFnUnitAttribute uAttr;\n\twindDirection = uAttr.create(\"windDirection\", \"wd\", MFnUnitAttribute::kAngle, 0.0);\n\tuAttr.setStorable(true);\n\tuAttr.setWritable(true);\n\tuAttr.setReadable(true);\n\tuAttr.setKeyable(true);\n\n\tuAttr.setDefault(MAngle(0.0, MAngle::kDegrees));\n\n\taddAttribute(windDirection);\n\n\t//- To make connection between your custom node and your custom \n\t//- manipulator node, you need to name your custom manipulator \n\t//- after your custom node type name, also in your custom node's initialize()\n\t//- function, you need to call MPxManipContainer::addToManipConnectTable().\n\t//- This method adds the user defined node as an entry in the manipConnectTable \n\t//- so that when this node is selected the user can use the show manip tool to \n\t//- get the user defined manipulator associated with this node\n\tMPxManipContainer::addToManipConnectTable(id);\n\n\treturn MS::kSuccess;\n}\n\n\n//-\tThis method draw this locator in current scene by calling openGL functions\n//-\n//-\tArguments:\n//-\t\tview -- 3D view that is being drawn into \n//-\t\tpath -- path to this locator in the DAG \n//-\t\tstyle -- style to draw object in \n//-\t\tstatus -- selection status of object \n//-\nvoid arrowLocator::draw(M3dView &view,const MDagPath & path,M3dView::DisplayStyle style, M3dView::DisplayStatus status)\n{\n\tMObject thisNode = thisMObject();\n\n\t//We're in the draw routine, not the Compute method\n\t//therefore it is safe to grab plugs in the following way and\n\t//get/set values.  You would never do something like this in\n\t//the compute method because it might start a cycle in the\n\t//graph.  Here we just need the value of our winddirection\n\t//plug so that we can draw our arrow pointing the right way.\n\tMPlug wdPlug(thisNode, windDirection);\n\n\tMAngle angle;\n\twdPlug.getValue(angle);\n\n\t//start drawing by OpenGL\n\tview.beginGL(); \n\t\n\n\t//If the drawing style is shaded, set color and draw opaque shape\n\tif ( ( style == M3dView::kFlatShaded ) || ( style == M3dView::kGouraudShaded ) ) \n\t{\n\t\t//Push to save current color settings\n\t\tglPushAttrib( GL_CURRENT_BIT );\n\n\t\tif ( status == M3dView::kActive ) \n\t\t{\n\t\t\tview.setDrawColor( 13, M3dView::kActiveColors );\n\t\t}else {\n\t\t\tview.setDrawColor( 13, M3dView::kDormantColors );\n\t\t}  \n\n\t\t//push the old matrix on the stack, rotate the current one,\n\t\t//draw the shape, then pop the old matrix off the stack for\n\t\t//maya to use again.\n\t\tglPushMatrix();\n\t\tglRotated(-angle.asDegrees(), 0.0, 1.0, 0.0);\n\t\t\tglBegin( GL_TRIANGLE_FAN );\n\t\t\tglVertex3f(arrow[0][0],arrow[0][1],arrow[0][2]);\n\t\t\tglVertex3f(arrow[1][0],arrow[1][1],arrow[1][2]);\n\t\t\tglVertex3f(arrow[2][0],arrow[2][1],arrow[2][2]);\n\t\t\tglEnd();\n\n\t\t\tglBegin( GL_TRIANGLE_FAN );\n\t\t\tglVertex3f(arrow[2][0],arrow[2][1],arrow[2][2]);\n\t\t\tglVertex3f(arrow[3][0],arrow[3][1],arrow[3][2]);\n\t\t\tglVertex3f(arrow[0][0],arrow[0][1],arrow[0][2]);\n\t\t\tglEnd();\n\t\tglPopMatrix();\n\n\t\tglPopAttrib();\n\t}\n\n\t//Draw the outline of the arrow shape\n\tglPushMatrix();\n\tglRotated(-angle.asDegrees(), 0.0, 1.0, 0.0);\n\tglBegin( GL_LINE_STRIP);\n\tglVertex3f(arrow[0][0],arrow[0][1],arrow[0][2]);\n\tglVertex3f(arrow[1][0],arrow[1][1],arrow[1][2]);\n\tglVertex3f(arrow[2][0],arrow[2][1],arrow[2][2]);\n\tglEnd();\n\n\tglBegin( GL_LINE_STRIP );\n\tglVertex3f(arrow[2][0],arrow[2][1],arrow[2][2]);\n\tglVertex3f(arrow[3][0],arrow[3][1],arrow[3][2]);\n\tglVertex3f(arrow[0][0],arrow[0][1],arrow[0][2]);\n\tglEnd();\n\tglPopMatrix();\n\n\tview.endGL();\n\n}\n\n\n//-\tThis method should be overridden to return true if the user supplies a bounding box routine.\nbool arrowLocator::isBounded() const\n{\n\treturn true;\n}\n\n//-\tThis method return the bounding box for this locator shape, \n//- providing a bounding box routine makes refresh and selection more efficient. \n//\nMBoundingBox arrowLocator::boundingBox() const\n{\n\n\tMPoint upLeftCorner(-3.0, 0.0, -2.0);\n\tMPoint downRightCorner(2.0, 0.0, 2.0);\n\n\tMBoundingBox boundingArea(upLeftCorner,downRightCorner);\n\treturn boundingArea;\n}\n\n\n\n\nvoid arrowLocator::getRotationAngle (arrowLocatorData * data){\n\t// Retrieve value of the angle attribute from the node\n\tMStatus status ;\n\t\n\tMObject node = thisMObject();\n\tMPlug wdPlug(node, windDirection);\n\tMAngle angle;\n\twdPlug.getValue(angle);\n\n\tdata->rotateAngle = angle;\n}\n\n\n\nclass arrowLocatorOverride : public MHWRender::MPxDrawOverride\n{\npublic:\n\tstatic MHWRender::MPxDrawOverride* Creator(const MObject& obj)\n\t{\n\t\treturn new arrowLocatorOverride(obj);\n\t}\n\n\tvirtual ~arrowLocatorOverride();\n\n\tvirtual MHWRender::DrawAPI supportedDrawAPIs() const;\n\n    virtual bool isBounded(\n        const MDagPath& objPath,\n        const MDagPath& cameraPath) const;\n\n\tvirtual MBoundingBox boundingBox(\n\t\tconst MDagPath& objPath,\n\t\tconst MDagPath& cameraPath) const;\n\n\tvirtual MUserData* prepareForDraw(\n\t\tconst MDagPath& objPath,\n\t\tconst MDagPath& cameraPath,\n\t\tconst MHWRender::MFrameContext& frameContext,\n\t\tMUserData* oldData);\n\n\tstatic void draw(\n\t\tconst MHWRender::MDrawContext& context,\n\t\tconst MUserData* data);\n\nprivate:\n\tarrowLocatorOverride(const MObject& obj);\n};\n\n\n\narrowLocatorOverride::arrowLocatorOverride(const MObject& obj)\n: MHWRender::MPxDrawOverride(obj, arrowLocatorOverride::draw)\n{\n}\n\narrowLocatorOverride::~arrowLocatorOverride()\n{\n}\n\nMHWRender::DrawAPI arrowLocatorOverride::supportedDrawAPIs() const\n{\n\treturn MHWRender::kOpenGL;\n}\n\nbool arrowLocatorOverride::isBounded(\n\tconst MDagPath& objPath,\n\tconst MDagPath& cameraPath) const\n{\n\treturn true;\n}\n\nMBoundingBox arrowLocatorOverride::boundingBox(\n\tconst MDagPath& objPath,\n\tconst MDagPath& cameraPath) const\n{\n\tMStatus status;\n\tMFnDependencyNode node(objPath.node(), &status);\n\tarrowLocator* locatorNode =\n\t\tdynamic_cast<arrowLocator*>(node.userNode());\n\treturn locatorNode->boundingBox();\n}\n\nMUserData* arrowLocatorOverride::prepareForDraw(\n\tconst MDagPath& objPath,\n\tconst MDagPath& cameraPath,\n\tconst MHWRender::MFrameContext& frameContext,\n\tMUserData* oldData)\n{\n\t// get the node\n\tMStatus status;\n\tMFnDependencyNode node(objPath.node(), &status);\n\tif (!status) return NULL;\n\tarrowLocator* locatorNode =\n\t\tdynamic_cast<arrowLocator*>(node.userNode());\n\tif (!locatorNode) return NULL;\n\n\t// access/create user data for draw callback\n\tarrowLocatorData* data =\n\t\tdynamic_cast<arrowLocatorData*>(oldData);\n\tif (!data)\n\t{\n\t\tdata = new arrowLocatorData();\n\t}\n\n\t// compute data and cache it\n\tlocatorNode->getRotationAngle(data) ;\n\n\treturn data;\n}\n\nvoid arrowLocatorOverride::draw(\n\tconst MHWRender::MDrawContext& context,\n\tconst MUserData* data)\n{\n\tMAngle rotationAngle;\n\n\tfloat color [3] ={ 0.0f, 1.0f, 0.0f } ;\n\n\t// data\n\tMStatus status;\n\tMHWRender::MStateManager* stateMgr = context.getStateManager();\n\tconst arrowLocatorData* locatorData =\n\t\tdynamic_cast<const arrowLocatorData*>(data);\n\tif (!stateMgr || !locatorData) return;\n\n\tif ( locatorData )\n\t\trotationAngle = locatorData->rotateAngle;\n\n\t// matrices\n\tconst MMatrix transform =\n\t\tcontext.getMatrix(MHWRender::MFrameContext::kWorldViewMtx, &status);\n\tif (status != MStatus::kSuccess) return;\n\tconst MMatrix projection =\n\t\tcontext.getMatrix(MHWRender::MFrameContext::kProjectionMtx, &status);\n\tif (status != MStatus::kSuccess) return;\n\n\t// get renderer\n\tMHWRender::MRenderer *theRenderer =MHWRender::MRenderer::theRenderer () ;\n\tif ( !theRenderer )\n\t\treturn ;\n\tif ( theRenderer->drawAPIIsOpenGL () ) {\n\t\t\n\t\tglPushAttrib(GL_CURRENT_BIT);\n\t\tglColor4fv(color);\n\n\t\tglPushMatrix();\n\t\tglRotated(-rotationAngle.asDegrees(), 0.0, 1.0, 0.0);\n\t\tglBegin( GL_LINE_STRIP);\n\t\tglVertex3f(arrow[0][0],arrow[0][1],arrow[0][2]);\n\t\tglVertex3f(arrow[1][0],arrow[1][1],arrow[1][2]);\n\t\tglVertex3f(arrow[2][0],arrow[2][1],arrow[2][2]);\n\t\tglEnd();\n\n\t\tglBegin( GL_LINE_STRIP );\n\t\tglVertex3f(arrow[2][0],arrow[2][1],arrow[2][2]);\n\t\tglVertex3f(arrow[3][0],arrow[3][1],arrow[3][2]);\n\t\tglVertex3f(arrow[0][0],arrow[0][1],arrow[0][2]);\n\t\tglEnd();\n\t\tglPopMatrix();\n\n\t}\n}\n\nMStatus initializePlugin( MObject obj )\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is loaded into Maya.  It \n//\t\tregisters all of the services that this plug-in provides with \n//\t\tMaya.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{ \n\tMStatus   status;\n\tMFnPlugin plugin( obj, \"\", \"2009\", \"Any\");\n\n\tstatus = plugin.registerNode( \"arrowLocator\", arrowLocator::id, arrowLocator::creator,\n\t\tarrowLocator::initialize, MPxNode::kLocatorNode,&arrowLocator::drawDbClassification);\n\n\tstatus = MHWRender::MDrawRegistry::registerDrawOverrideCreator (\n\t\tarrowLocator::drawDbClassification,\n\t\tarrowLocator::drawRegistrantId,\n\t\tarrowLocatorOverride::Creator) ;\n\n\tif (!status) {\n\t\tstatus.perror(\"registerNode\");\n\t\treturn status;\n\t}\n\n\n\t//- Register custom manipulator for your custom locator node.\n\t//- In order to make it work, you need to name your custom manipulator \n\t//- after your custom node type name, also in your custom node's initialize()\n\t//- function, you need to call MPxManipContainer::addToManipConnectTable()\n\n\tstatus = plugin.registerNode( \"arrowLocatorManip\", arrowLocatorManip::id, arrowLocatorManip::creator,\n\t\tarrowLocatorManip::initialize,MPxNode::kManipContainer );\n\tif (!status) {\n\t\tstatus.perror(\"registerNode\");\n\t\treturn status;\n\t}\n\n\n\treturn status;\n}\n\nMStatus uninitializePlugin( MObject obj)\n//\n//\tDescription:\n//\t\tthis method is called when the plug-in is unloaded from Maya. It \n//\t\tderegisters all of the services that it was providing.\n//\n//\tArguments:\n//\t\tobj - a handle to the plug-in object (use MFnPlugin to access it)\n//\n{\n\tMStatus   status;\n\tMFnPlugin plugin( obj );\n\n\tstatus = plugin.deregisterNode( arrowLocatorManip::id );\n\tif (!status) {\n\t\tstatus.perror(\"deregisterNode\");\n\t\treturn status;\n\t}\n\n\tstatus = plugin.deregisterNode( arrowLocator::id );\n\n\tMHWRender::MDrawRegistry::deregisterDrawOverrideCreator (\n\t\tarrowLocator::drawDbClassification,\n\t\tarrowLocator::drawRegistrantId) ;\n\n\tif (!status) {\n\t\tstatus.perror(\"deregisterNode\");\n\t\treturn status;\n\t}\n\n\treturn status;\n}\n"
  },
  {
    "path": "08_Manipulators/arrowLocatorManip/Solution - C++/arrowLocatorNode.h",
    "content": "#ifndef _arrowLocatorNode\n#define _arrowLocatorNode\n//\n// Copyright (C) \n// \n// File: arrowLocatorNode.h\n//\n// Dependency Graph Node: arrowLocator\n//\n// Author: Maya Plug-in Wizard 2.0\n//\n\n#include <maya/MPxLocatorNode.h>\n#include <maya/MFnNumericAttribute.h>\n#include <maya/MTypeId.h> \n#include <maya/M3dView.h>\n#include <maya/MDagPath.h>\n\n\n// Viewport 2.0 includes\n#include <maya/MDrawRegistry.h>\n#include <maya/MPxDrawOverride.h>\n#include <maya/MUserData.h>\n#include <maya/MDrawContext.h>\n#include <maya/MGlobal.h>\n#include <maya/MSelectionList.h>\n#include <maya/MViewport2Renderer.h>\n#include <maya/MHWGeometryUtilities.h>\n#include <maya/MStateManager.h>\n#include <maya/MShaderManager.h>\n#include <maya/MAngle.h>\n\n\n\n//- Macros to use to rotate the locator\n#define PI 3.14159265358979\n#define toDegree(rot) rot*(180.0/PI)\n\nclass arrowLocatorData : public MUserData\n{\npublic:\n\tMAngle rotateAngle ;\n\n\tarrowLocatorData() : MUserData(false) {} // don't delete after draw\n\tvirtual ~arrowLocatorData() {}\n};\n\nclass arrowLocator : public MPxLocatorNode\n{\npublic:\n\tarrowLocator() {}\n\tvirtual ~arrowLocator() {}\n\n\tMStatus compute( const MPlug& plug, MDataBlock& data );\n\tvirtual void draw(M3dView &view,const MDagPath & path,M3dView::DisplayStyle style, M3dView::DisplayStatus status);\n\tvirtual MBoundingBox boundingBox() const;\n\tvirtual bool isBounded() const;\n\n\n\tvoid getRotationAngle (arrowLocatorData * data );\n\n\tstatic MStatus\t\tinitialize();\n\n\tstatic void* creator() {\n\t\treturn new arrowLocator();\n\t}\n\n\tstatic\tMTypeId\t\tid;\n\n\tstatic\tMString\t\tdrawDbClassification;\n\tstatic\tMString\t\tdrawRegistrantId;\n\n\tstatic MObject windDirection; //- This is an attribute representing the rotation angle\n\n};\n\n#endif\n"
  },
  {
    "path": "08_Manipulators/arrowLocatorManip/Solution - py/arrowLocatorManip.py",
    "content": "#\n# Copyright (C) \n# \n# File: arrowLocatorManip.py\n#\n# Dependency Graph Node: \n#\n# Author: Maya Plug-in Wizard 2.0\n\n\nimport sys, math\n\nimport maya.OpenMaya as OpenMaya\nimport maya.OpenMayaMPx as OpenMayaMPx\nimport maya.OpenMayaRender as OpenMayaRender\nimport maya.OpenMayaUI as OpenMayaUI\n\nkPluginManipNodeTypeName = \"arrowLocatorManip\"\nkPluginNodeTypeName = \"arrowLocator\"\n\nkPluginManipNodeId = OpenMaya.MTypeId(0x00003)\nkPluginNodeId = OpenMaya.MTypeId(0x00002)\n\nglRenderer = OpenMayaRender.MHardwareRenderer.theRenderer()\nglFT = glRenderer.glFunctionTable()\n\n#an array of points to draw our compass arrow in openGL\narrow = ( [2.00, 0.0, 0.0],\n[-3.0, 0.0, 2.0],\n[-2.0, 0.0, 0.0],\n[-3.0, 0.0, -2.0]) \n\n#indices into the arrow array\ntriangleIndices = [0,1,2,0,2,3]\n\n\nclass arrowLocatorManip(OpenMayaMPx.MPxManipContainer):\n\tdef __init__(self):\n\t\tOpenMayaMPx.MPxManipContainer.__init__(self)\n\t\tself.fDiscManip = OpenMaya.MDagPath()\n\t\tself.fNodePath = OpenMaya.MDagPath()\n\n\t#- Container manipulators are composed of one or more base manipulators. \n\t#- When base manipulators are added to a container manipulator, they are referred to \n\t#- as children of the container manipulator, and are added using the createChildren method. \n\tdef createChildren(self):\n\t\ttry:\n\t\t\t#- Add a base disc manip into this manip container\n\t\t\tself.fDiscManip = self.addDiscManip(\"angleManip\",\"yRotation\")\n\n\t\t\t#- Initialize the angle and starting position of this manipulator\n\t\t\tstartPoint = OpenMaya.MPoint(0.0, 0.0, 0.0) \n\t\t\tstartAngle = OpenMaya.MAngle(0.0,OpenMaya.MAngle.kDegrees)\n\t\t\tfnDisc = OpenMayaUI.MFnDiscManip(self.fDiscManip)\n\t\t\tfnDisc.setCenterPoint(startPoint)\n\t\t\tfnDisc.setAngle(startAngle)\n\n\t\texcept:\n\t\t\tsys.stderr.write(\"ERROR: arrowLocatorManip.createChildren\\n\")\n\t\t\traise\t\t\n\n\t#- This function is responsible to make the connection (association) \n\t#- between manipulators and the affected attributes. When a node in a scene \n\t#- is selected and user click on show manipulator tool, \n\t#- this function is called with the selected node.\n\t#- Arguments:\n\t#- \tdependNode - the node which is selected\n\tdef connectToDependNode(self, node):\n\t\ttry:\n\t\t\t#- Find the \"windDirection\" plug on the selected node, which is the custom\n\t\t\t#- locator node.\n\t\t\tfnDepNode = OpenMaya.MFnDependencyNode(node)\n\t\t\trotationPlug = fnDepNode.findPlug(\"windDirection\")\n\n\t\t\t#- Connect the \"windDirection\" plug with the base disc manip\n\t\t\tfnDisc = OpenMayaUI.MFnDiscManip(self.fDiscManip)\n\t\t\tfnDisc.connectToAnglePlug(rotationPlug)\n\n\n\t\t\t#- Set up affecting relationship using conversion callback function\n\t\t\t#- We are using addPlugToManipConversionCallback so that whenever\n\t\t\t#- the custom locator moves, the dis manip moves with it.\n\t\t\tfnDagNode = OpenMaya.MFnDagNode(node)\n\t\t\tfnDagNode.getPath(self.fNodePath)\n\t\t\tcenterPointIndex = fnDisc.centerIndex()\n\n\t\t\t#NOT Available in Python.\n\t\t\tself.addPlugToManipConversion(centerPointIndex)\n\n\t\t\t#- The following two functions are mandatory inside your\n\t\t\t#- connectToDependNode() function\n\t\t\tself.finishAddingManips()\n\t\t\tOpenMayaMPx.MPxManipContainer.connectToDependNode(self, node)\n\n\t\texcept:\n\t\t\tsys.stderr.write(\"ERROR: arrowLocatorManip.connectToDependNode\\n\")\n\t\t\traise\n\n\t#- This method is an optional method, you can use it to customize \n\t#- the drawing of your manipulator. \n\t#- If you are overriding this function, most likely you will use OpenGL calls, \n\t#- so opengl32.lib should be included in the linking libraries.\n\t#- Arguments:\n\t#- \tview - the 3d view where the manipulator will be drawn\n\t#-     path - the Dag path of this manipulator\n\t#-     style - the displaying style of this manipulator\n\t#-\t\tstatus - the displaying status of this manipulator, for example, it is active or not\n\tdef draw(self, view, path, style, status):\n\t\tOpenMayaMPx.MPxManipContainer.draw(self, view, path, style, status)\n\n\t#- This method is plugToManipConversionCallback function\n\t#- You implement it so that a specific component of the manipulator\n\t#- will be modified automatically when some plug value changes on \n\t#- the custom locator.\n\t#- Arguments:\n\t#- \tmanipIndex - the index of the component on the manip you want to affect, \n\t#-                  in this case, it is the center point of this manip\n\t#-\tReturn Values:\n\t#-\t\tMManipData object, which represents the updated value\n\tdef plugToManipConversion( self, manipIndex ):\n\t\ttry:\n\t\t\t#Get parent transform node of the locator node\n\t\t\t\n\t\t\tparentTransform = self.fNodePath.transform()\n\n\t\t\t#Get the transform node DAG path\n\t\t\ttransformPath = OpenMaya.MDagPath()\n\t\t\tOpenMaya.MDagPath.getAPathTo(parentTransform,transformPath)\n\n\t\t\t#Retrieve world space translation\n\t\t\tfnTrans = OpenMaya.MFnTransform(transformPath)\n\t\t\ttranslation = OpenMaya.MVector()\n\t\t\ttranslation = fnTrans.getTranslation(OpenMaya.MSpace.kWorld)\n\n\t\t\tnumData = OpenMaya.MFnNumericData()\n\t\t\tnumDataValue = numData.create(OpenMaya.MFnNumericData.k3Double)\n\t\t\tstatus = numData.setData3Double(translation.x,translation.y,translation.z)\n\t\t\tmanipData = OpenMayaUI.MManipData(numDataValue)\n\t\texcept:\n\t\t\tsys.stderr.write(\"ERROR: arrowManip.plugToManipConversion\\n\")\n\t\t\traise\n\n\t\treturn manipData\n\n# Node definition\nclass arrowLocator(OpenMayaMPx.MPxLocatorNode):\n\twindDirection = OpenMaya.MObject()\n\t\n\tdef __init__(self):\n\t\tOpenMayaMPx.MPxLocatorNode.__init__(self)\n\t\t\n\n\tdef compute(self, plug, data):\n\t\treturn OpenMaya.kUnknownParameter\n\n\t#-\tThis method draw this locator in current scene by calling openGL functions\n\t#-\n\t#-\tArguments:\n\t#-\t\tview -- 3D view that is being drawn into \n\t#-\t\tpath -- path to this locator in the DAG \n\t#-\t\tstyle -- style to draw object in \n\t#-\t\tstatus -- selection status of object \n\t#-\n\tdef draw(self, view, path, style, status):\n\t\tthisNode = self.thisMObject()\n\n\t\t#We're in the draw routine, not the Compute method\n\t\t#therefore it is safe to grab plugs in the following way and\n\t\t#get/set values.  You would never do something like this in\n\t\t#the compute method because it might start a cycle in the\n\t\t#graph.  Here we just need the value of our winddirection\n\t\t#plug so that we can draw our arrow pointing the right way.\n\t\tplug = OpenMaya.MPlug(thisNode, arrowLocator.windDirection)\n\t\tangle = plug.asMAngle()\n\n\t\t#start drawing by OpenGL\n\t\tview.beginGL() \n\n\n\t\t#If the drawing style is shaded, set color and draw opaque shape\n\t\tif ((style == OpenMayaUI.M3dView.kFlatShaded) or (style == OpenMayaUI.M3dView.kGouraudShaded)):\n\t\t\t\n\t\t\t#Push to save current color settings\n\t\t\tglFT.glPushAttrib(OpenMayaRender.MGL_CURRENT_BIT )\n\n\t\t\tif (status == OpenMayaUI.M3dView.kActive):\n\t\t\t\tview.setDrawColor( 13, OpenMayaUI.M3dView.kActiveColors )\n\t\t\telse:\n\t\t\t\tview.setDrawColor( 13, OpenMayaUI.M3dView.kDormantColors )\n\t\t\t  \n\n\t\t\t#push the old matrix on the stack, rotate the current one,\n\t\t\t#draw the shape, then pop the old matrix off the stack for\n\t\t\t#maya to use again.\n\t\t\tglFT.glPushMatrix()\n\t\t\tglFT.glRotated(-angle.asDegrees(), 0.0, 1.0, 0.0)\n\t\t\tglFT.glBegin( OpenMayaRender.MGL_TRIANGLE_FAN )\n\t\t\tglFT.glVertex3f(arrow[0][0],arrow[0][1],arrow[0][2])\n\t\t\tglFT.glVertex3f(arrow[1][0],arrow[1][1],arrow[1][2])\n\t\t\tglFT.glVertex3f(arrow[2][0],arrow[2][1],arrow[2][2])\n\t\t\tglFT.glEnd()\n\n\t\t\tglFT.glBegin( OpenMayaRender.MGL_TRIANGLE_FAN )\n\t\t\tglFT.glVertex3f(arrow[2][0],arrow[2][1],arrow[2][2])\n\t\t\tglFT.glVertex3f(arrow[3][0],arrow[3][1],arrow[3][2])\n\t\t\tglFT.glVertex3f(arrow[0][0],arrow[0][1],arrow[0][2])\n\t\t\tglFT.glEnd()\n\t\t\tglFT.glPopMatrix()\n\n\t\t\tglFT.glPopAttrib()\n\t\t\n\n\t\t#Draw the outline of the arrow shape\n\t\tglFT.glPushMatrix()\n\t\tglFT.glRotated(-angle.asDegrees(), 0.0, 1.0, 0.0)\n\t\tglFT.glBegin( OpenMayaRender.MGL_LINE_STRIP)\n\t\tglFT.glVertex3f(arrow[0][0],arrow[0][1],arrow[0][2])\n\t\tglFT.glVertex3f(arrow[1][0],arrow[1][1],arrow[1][2])\n\t\tglFT.glVertex3f(arrow[2][0],arrow[2][1],arrow[2][2])\n\t\tglFT.glEnd()\n\n\t\tglFT.glBegin( OpenMayaRender.MGL_LINE_STRIP )\n\t\tglFT.glVertex3f(arrow[2][0],arrow[2][1],arrow[2][2])\n\t\tglFT.glVertex3f(arrow[3][0],arrow[3][1],arrow[3][2])\n\t\tglFT.glVertex3f(arrow[0][0],arrow[0][1],arrow[0][2])\n\t\tglFT.glEnd()\n\t\tglFT.glPopMatrix()\n\n\t\tview.endGL()\n\n\tdef isBounded(self):\n\t\treturn True\n\n\t#- This method return the bounding box for this locator shape, \n\t#- providing a bounding box routine makes refresh and selection more efficient. \n\t#\n\tdef boundingBox(self):\n\t\tupLeftCorner = OpenMaya.MPoint(-3.0, 0.0, -2.0)\n\t\tdownRightCorner = OpenMaya.MPoint(2.0, 0.0, 2.0)\n\n\t\tboundingArea = OpenMaya.MBoundingBox(upLeftCorner,downRightCorner)\n\t\treturn boundingArea\n\n\n#- This method exists to give Maya a way to create new objects\n#- of this type.\ndef ManipNodeCreator():\n\treturn OpenMayaMPx.asMPxPtr( arrowLocatorManip() )\n\n#- This method is called to create and initialize all of the attributes\n#- and attribute dependencies for this node type.  This is only called \n#-\tonce when the node type is registered with Maya.\ndef ManipNodeInitializer():\n\tOpenMayaMPx.MPxManipContainer.initialize()\n\t\t\n# Creator\ndef nodeCreator():\n\treturn OpenMayaMPx.asMPxPtr( arrowLocator() )\n\n# initializer\ndef nodeInitializer():\n\t#Here we create a new attribute type that handles units: angle, distance or time\n\tuAttr = OpenMaya.MFnUnitAttribute()\n\tarrowLocator.windDirection = uAttr.create(\"windDirection\", \"wd\", OpenMaya.MFnUnitAttribute.kAngle)\n\tuAttr.setDefault(0.0)\n\tuAttr.setStorable(True)\n\tuAttr.setWritable(True)\n\tuAttr.setReadable(True)\n\tuAttr.setKeyable(True)\n\n\tuAttr.setDefault(OpenMaya.MAngle(0.0, OpenMaya.MAngle.kDegrees))\n\n\tarrowLocator.addAttribute(arrowLocator.windDirection)\n\n\t#- To make connection between your custom node and your custom \n\t#- manipulator node, you need to name your custom manipulator \n\t#- after your custom node type name, also in your custom node's initialize()\n\t#- function, you need to call MPxManipContainer::addToManipConnectTable().\n\t#- This method adds the user defined node as an entry in the manipConnectTable \n\t#- so that when this node is selected the user can use the show manip tool to \n\t#- get the user defined manipulator associated with this node\n\tOpenMayaMPx.MPxManipContainer.addToManipConnectTable(kPluginNodeId)\n\t\n# Initialize the script plug-in\ndef initializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\tmplugin.registerNode( kPluginManipNodeTypeName, kPluginManipNodeId, ManipNodeCreator, ManipNodeInitializer, OpenMayaMPx.MPxNode.kManipContainer )\n\t\t\n\texcept:\n\t\tsys.stderr.write( \"Failed to register manip node: %s\" % kPluginManipNodeTypeName )\n\t\traise\n\ttry:\n\t\t\n\t\tmplugin.registerNode( kPluginNodeTypeName, kPluginNodeId, nodeCreator, nodeInitializer, OpenMayaMPx.MPxNode.kLocatorNode )\n\texcept:\n\t\tsys.stderr.write( \"Failed to register node: %s\" % kPluginNodeTypeName )\n\t\traise\n\n# Uninitialize the script plug-in\ndef uninitializePlugin(mobject):\n\n\t\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\t\n\ttry:\n\t\tmplugin.deregisterNode( kPluginManipNodeId)\n\t\t\n\texcept:\n\t\tsys.stderr.write( \"Failed to deregister node: %s\" % kPluginManipNodeTypeName )\n\t\traise\n\n\ttry:\n\t\t\n\t\tmplugin.deregisterNode( kPluginNodeId )\n\texcept:\n\t\tsys.stderr.write( \"Failed to deregister command: %s\" % kPluginNodeTypeName )\n\t\traise\n\n\t\t"
  },
  {
    "path": "09_PythonAPI/helloWorld/Exercise - py/helloWorldCmd.py",
    "content": "#\n# Copyright (C) \n# \n# File: helloWorld.py\n#\n# Dependency Graph Node: arrowLocator\n#\n# Author: \n#\n\n#- Python script to execute to test the sample in the Maya script editor\n# import maya\n# maya.cmds.loadPlugin(\"helloWorldCmd.py\")\n# maya.cmds.spHelloWorld()\n\n#- TODO: Import all the necessary modules here\n#import sys\n#import maya.OpenMaya as OpenMaya\n#import maya.OpenMayaMPx as OpenMayaMPx\n\nkPluginCmdName = \"spHelloWorld\"\n\n# Command\nclass scriptedCommand(OpenMayaMPx.MPxCommand):\n#- TODO: Add Implementation of __init__(self) and doIt(self,argList)\n#\tdef __init__(self):\n#\t\tOpenMayaMPx.MPxCommand.__init__(self)\n#\n#\tdef doIt(self,argList):\n#\t\tprint \"Hello World!\"\n\n\n# Creator\ndef cmdCreator():\n#- TODO: Implement the creator and apply asMPxPtr() to it\n#\treturn OpenMayaMPx.asMPxPtr( scriptedCommand() )\n\t\n# Initialize the script plug-in\ndef initializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n#- TODO: Register this custom command                \n#\t\tmplugin.registerCommand( kPluginCmdName, cmdCreator )\n\texcept:\n\t\tsys.stderr.write( \"Failed to register command: %s\\n\" % kPluginCmdName )\n\t\traise\n\n# Uninitialize the script plug-in\ndef uninitializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n#- TODO: Deregister this custom command                 \n#\t\tmplugin.deregisterCommand( kPluginCmdName )\n\texcept:\n\t\tsys.stderr.write( \"Failed to unregister command: %s\\n\" % kPluginCmdName )\n\t\traise\n"
  },
  {
    "path": "09_PythonAPI/helloWorld/Solution - py/helloWorldCmd.py",
    "content": "#\n# Copyright (C) \n# \n# File: helloWorld.py\n#\n# Dependency Graph Node: arrowLocator\n#\n# Author: \n#\n\n#- Python script to execute to test the sample in the Maya script editor\n# import maya\n# maya.cmds.loadPlugin(\"helloWorldCmd.py\")\n# maya.cmds.spHelloWorld()\n\n#- Import all the necessary modules here\nimport sys\nimport maya.OpenMaya as OpenMaya\nimport maya.OpenMayaMPx as OpenMayaMPx\n\nkPluginCmdName = \"spHelloWorld\"\n\n# Command\nclass scriptedCommand(OpenMayaMPx.MPxCommand):\n\tdef __init__(self):\n\t\tOpenMayaMPx.MPxCommand.__init__(self)\n\tdef doIt(self,argList):\n\t\tprint \"Hello World!\"\n\n# Creator\ndef cmdCreator():\n\treturn OpenMayaMPx.asMPxPtr( scriptedCommand() )\n\t\n# Initialize the script plug-in\ndef initializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\tmplugin.registerCommand( kPluginCmdName, cmdCreator )\n\texcept:\n\t\tsys.stderr.write( \"Failed to register command: %s\\n\" % kPluginCmdName )\n\t\traise\n\n# Uninitialize the script plug-in\ndef uninitializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\tmplugin.deregisterCommand( kPluginCmdName )\n\texcept:\n\t\tsys.stderr.write( \"Failed to unregister command: %s\\n\" % kPluginCmdName )\n\t\traise\n"
  },
  {
    "path": "09_PythonAPI/sineNode/Exercise - py/sineNode.py",
    "content": "#\n# Copyright (C) \n# \n# File: sineNode.py\n#\n# Dependency Graph Node: sineNode\n#\n# Author: \n#\n\n#- TODO: Import all the necessary modules here\n#import math, sys\n#import maya.OpenMaya as OpenMaya\n#import maya.OpenMayaMPx as OpenMayaMPx\n\nkPluginNodeTypeName = \"spSineNode\"\n\n#- TODO: Allocate a type id for your custom node\n#sineNodeId = OpenMaya.MTypeId(0x87000)\n\n# Node definition\nclass sineNode(OpenMayaMPx.MPxNode):\n\n#- TODO: Define your class variables\n#\tinput = OpenMaya.MObject()\n#\toutput = OpenMaya.MObject()\n\tdef __init__(self):\n                OpenMayaMPx.MPxNode.__init__(self)\n\n#- TODO: Add Implementation of compute\n#        def compute(self,plug,dataBlock):\n\t\tif ( plug == sineNode.output ):\n#- TODO: Get handle of input attribute and data from the handle\n#\t\t\tdataHandle = dataBlock.inputValue( sineNode.input )\t\t\t\n#\t\t\tinputFloat = dataHandle.asFloat()\n\t\t\tresult = math.sin( inputFloat ) * 10.0\n\t\t\toutputHandle = dataBlock.outputValue( sineNode.output )\n\t\t\toutputHandle.setFloat( result )\n\t\t\tdataBlock.setClean( plug )\n\n\t\treturn OpenMaya.kUnknownParameter\n\n# creator\ndef nodeCreator():\n#- TODO: Implement the creator and apply asMPxPtr() to it\n#       return OpenMayaMPx.asMPxPtr( sineNode() )\n\n# initializer\ndef nodeInitializer():\n\t# input\n#- TODO: Create an input attribute with name \"input\"\t\n#\tnAttr = OpenMaya.MFnNumericAttribute()\n#\tsineNode.input = nAttr.create( \"input\", \"in\", OpenMaya.MFnNumericData.kFloat, 0.0 )\n\tnAttr.setStorable(1)\n\t# output\n\tnAttr = OpenMaya.MFnNumericAttribute()\n\tsineNode.output = nAttr.create( \"output\", \"out\", OpenMaya.MFnNumericData.kFloat, 0.0 )\n\tnAttr.setStorable(1)\n\tnAttr.setWritable(1)\n#- TODO: Add attributes and set up relationship\n#\tsineNode.addAttribute( sineNode.input )\n#\tsineNode.addAttribute( sineNode.output )\n#\tsineNode.attributeAffects( sineNode.input, sineNode.output )\n\t\n# Initialize the script plug-in\ndef initializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n#- TODO: Register this custom node                \n#\t\tmplugin.registerNode( kPluginNodeTypeName, sineNodeId, nodeCreator, nodeInitializer )\n\texcept:\n\t\tsys.stderr.write( \"Failed to register node: %s\" % kPluginNodeTypeName )\n\t\traise\n\n# Uninitialize the script plug-in\ndef uninitializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n#- TODO: Deregister this custom node                 \n#\t\tmplugin.deregisterNode( sineNodeId )\n\texcept:\n\t\tsys.stderr.write( \"Failed to deregister node: %s\" % kPluginNodeTypeName )\n\t\traise\n\t\n"
  },
  {
    "path": "09_PythonAPI/sineNode/Solution - py/sineNode.py",
    "content": "#\n# Copyright (C) \n# \n# File: sineNode.py\n#\n# Dependency Graph Node: sineNode\n#\n# Author: \n#\n\nimport math, sys\n\nimport maya.OpenMaya as OpenMaya\nimport maya.OpenMayaMPx as OpenMayaMPx\n\nkPluginNodeTypeName = \"spSineNode\"\n\nsineNodeId = OpenMaya.MTypeId(0x87000)\n\n# Node definition\nclass sineNode(OpenMayaMPx.MPxNode):\n\t# class variables\n\tinput = OpenMaya.MObject()\n\toutput = OpenMaya.MObject()\n\tdef __init__(self):\n\t\tOpenMayaMPx.MPxNode.__init__(self)\n\tdef compute(self,plug,dataBlock):\n\t\tif ( plug == sineNode.output ):\n\t\t\tdataHandle = dataBlock.inputValue( sineNode.input )\n\t\t\t\n\t\t\tinputFloat = dataHandle.asFloat()\n\t\t\tresult = math.sin( inputFloat ) * 10.0\n\t\t\toutputHandle = dataBlock.outputValue( sineNode.output )\n\t\t\toutputHandle.setFloat( result )\n\t\t\tdataBlock.setClean( plug )\n\n\t\treturn OpenMaya.kUnknownParameter\n\n# creator\ndef nodeCreator():\n\treturn OpenMayaMPx.asMPxPtr( sineNode() )\n\n# Initializer\ndef nodeInitializer():\n\t# input\n\tnAttr = OpenMaya.MFnNumericAttribute()\n\tsineNode.input = nAttr.create( \"input\", \"in\", OpenMaya.MFnNumericData.kFloat, 0.0 )\n\tnAttr.setStorable(1)\n\t# output\n\tnAttr = OpenMaya.MFnNumericAttribute()\n\tsineNode.output = nAttr.create( \"output\", \"out\", OpenMaya.MFnNumericData.kFloat, 0.0 )\n\tnAttr.setStorable(1)\n\tnAttr.setWritable(1)\n\t# add attributes\n\tsineNode.addAttribute( sineNode.input )\n\tsineNode.addAttribute( sineNode.output )\n\tsineNode.attributeAffects( sineNode.input, sineNode.output )\n\t\n# Initialize the script plug-in\ndef initializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\tmplugin.registerNode( kPluginNodeTypeName, sineNodeId, nodeCreator, nodeInitializer )\n\texcept:\n\t\tsys.stderr.write( \"Failed to register node: %s\" % kPluginNodeTypeName )\n\t\traise\n\n# Uninitialize the script plug-in\ndef uninitializePlugin(mobject):\n\tmplugin = OpenMayaMPx.MFnPlugin(mobject)\n\ttry:\n\t\tmplugin.deregisterNode( sineNodeId )\n\texcept:\n\t\tsys.stderr.write( \"Failed to deregister node: %s\" % kPluginNodeTypeName )\n\t\traise\n\t\n"
  },
  {
    "path": "09_PythonAPI/sineNode/sineNode-setup.mel",
    "content": "polySphere;\ncreateNode spSineNode -n sine1;\nconnectAttr time1.outTime sine1.input;\nconnectAttr time1.outTime pSphere1.translateX;\nconnectAttr sine1.output pSphere1.translateY;"
  },
  {
    "path": "10_PythonAdvanced/examples/ShotServer.py",
    "content": "\n#-\n# ==========================================================================\n# Copyright (C) 2008 Autodesk, Inc. and/or its licensors.  All \n# rights reserved.\n#\n# The coded instructions, statements, computer programs, and/or related \n# material (collectively the \"Data\") in these files contain unpublished \n# information proprietary to Autodesk, Inc. (\"Autodesk\") and/or its \n# licensors, which is protected by U.S. and Canadian federal copyright \n# law and by international treaties.\n#\n# The Data is provided for use exclusively by You. You have the right \n# to use, modify, and incorporate this Data into other products for \n# purposes authorized by the Autodesk software license agreement, \n# without fee.\n#\n# The copyright notices in the Software and this entire statement, \n# including the above license grant, this restriction and the \n# following disclaimer, must be included in all copies of the \n# Software, in whole or in part, and all derivative works of \n# the Software, unless such copies or derivative works are solely \n# in the form of machine-executable object code generated by a \n# source language processor.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND. \n# AUTODESK DOES NOT MAKE AND HEREBY DISCLAIMS ANY EXPRESS OR IMPLIED \n# WARRANTIES INCLUDING, BUT NOT LIMITED TO, THE WARRANTIES OF \n# NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR \n# PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE, OR \n# TRADE PRACTICE. IN NO EVENT WILL AUTODESK AND/OR ITS LICENSORS \n# BE LIABLE FOR ANY LOST REVENUES, DATA, OR PROFITS, OR SPECIAL, \n# DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES, EVEN IF AUTODESK \n# AND/OR ITS LICENSORS HAS BEEN ADVISED OF THE POSSIBILITY \n# OR PROBABILITY OF SUCH DAMAGES.\n#\n# ==========================================================================\n#+\n\n# This is a simple example of how to set up a client/server system within\n# Python. The example server takes requests for shots to work on and\n# responds with the information for a new shot.\n#\n# To try out the example, do the following:\n#\n# 1) Change the SERVER setting below to reflect the system on which you\n#    will run the server.\n#\n# 2) On the server system, execute the startServer() function.\n#\n# 3) On a client system, create a Shot instance to serve as your \"old\"\n#    shot (you can use the 'makeSampleShot' function if you're lazy)\n#    and pass it to the requestNewShot() function. That will send your\n#    request to the server and return a new Shot instance from the server.\n#\n# 4) Print the 'shot' field of the returned Shot and you'll see that it\n#    is different from the old shot.\n#\n# 5) On any system, execute the stopServer() function to shut down the\n#    server.\n#\n# In addition, saveShotDefaults() can be used to save a shot to the\n# 'shotDefaults' file in the user's home directory. You can then exit\n# Maya/Python and the next time you run it use loadShotDefaults() to\n# get the shot info back.\n\n\n# The SERVER setting below assumes that the server and the clients are\n# all running on the same machine. If that is not the case then change\n# then set SERVER to be either the name or IP address of the machine on\n# which the server is running.\nSERVER = 'localhost'\nPORT = 50507\n\n\nimport cPickle\nimport os\nimport socket\n\n#----------------- Classes ------------------------\nclass Shot:\n\tdef __init__(self):\n\t\tself.user = None\n\t\tself.production = None\n\t\tself.sequence = None\n\t\tself.scene = None\n\t\tself.shot = None\n\n\nclass ShotRequest:\n\tdef __init__(self):\n\t\tself.type = None\n\t\tself.shot = None\n\n\n#----------------- Save/Restore Shot Info ---------\n\n# Save the shot to the user's 'shotDefaults' file.\ndef saveShotDefaults(shotInfo):\n\ttry:\n\t\thome = os.environ['HOME']\n\t\tfileName = os.path.join(home, 'shotDefaults')\n\t\tfile = open(fileName, 'wb')\n\t\tpickler = cPickle.Pickler(file, 2)\n\t\tpickler.dump(shotInfo)\n\t\tfile.close()\n\texcept:\n\t\tpass\n\n\n# Load the shot info from the user's 'shotDefaults' file.\ndef loadShotDefaults():\n\ttry:\n\t\thome = os.environ['HOME']\n\t\tfileName = os.path.join(home, 'shotDefaults')\n\t\tfile = open(fileName, 'rb')\n\t\tunpickler = cPickle.Unpickler(file)\n\t\tshotInfo = unpickler.load()\n\t\tfile.close()\n\texcept:\n\t\t# We couldn't get the user's defaults so\n\t\t# let's just create an empty Shot.\n\t\tshotInfo = Shot()\n\n\treturn shotInfo\n\n\n\n#----------------- Server Functions ---------------\n\n# Start the shot server.\ndef startServer():\n\t# Create a socket for listening for requests.\n\ts = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n\thost = ''\n\tport = PORT\n\ts.bind((host, port))\n\ts.listen(5)\n\n\twhile True:\n\t\t# Wait for a sender to connect.\n\t\tconn, sender = s.accept()\n\n\t\t# Get the request string and unpickle it.\n\t\trequestStr = conn.recv(4096)\n\t\trequest = cPickle.loads(requestStr)\n\n\t\t# Handle the request.\n\t\tif request.type == 'Stop':\n\t\t\tconn.close()\n\t\t\tbreak\n\t\telif request.type == 'NewShot':\n\t\t\tnewShot = _getNextShot(request.shot)\n\n\t\t\t# Pickle the new shot into a string\n\t\t\t# and send it back to the requestor.\n\t\t\tresponseStr = cPickle.dumps(newShot)\n\t\t\tconn.send(responseStr)\n\n\t\t# Close the connection to the client.\n\t\tconn.close()\n\n\t# Close our listening socket.\n\ts.close()\n\n\n# Shut down the shot server.\ndef stopServer():\n\t# Connect to the server's socket.\n\ts = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n\thost = SERVER\n\tport = PORT\n\ts.connect((host, port))\n\t\n\t# Create a stop request.\n\trequest = ShotRequest()\n\trequest.type = 'Stop'\n\n\t# Pickle the request into a string and send it\n\t# to the server.\n\trequestStr = cPickle.dumps(request, 2)\n\ts.send(requestStr)\n\n\t# There won't be a response, so close the connection.\n\ts.close()\n\n\n# Trivial implementation which simply increments\n# the shot and scene fields. A proper implementation\n# would maintain a database of shots and search it\n# for the next available one.\ndef _getNextShot(oldShot):\n\tif oldShot.shot == None:\n\t\toldShot.shot = 1\n\telse:\n\t\tprint \"%s completed shot (%s, %d, %d, %d)\" % (oldShot.user, oldShot.production, oldShot.scene, oldShot.sequence, oldShot.shot)\n\t\toldShot.shot += 1\n\n\tif oldShot.shot > 8:\n\t\toldShot.shot = 1\n\n\t\tif oldShot.scene == None:\n\t\t\toldShot.scene = 1\n\t\telse:\n\t\t\toldShot.scene += 1\n\n\tprint \"%s assigned shot (%s, %d, %d, %d)\" % (oldShot.user, oldShot.production, oldShot.scene, oldShot.sequence, oldShot.shot)\n\n\treturn oldShot\n\n\n#----------------- Client Functions ---------------\n\n# Convenience function to generate a sample Shot.\ndef makeSampleShot():\n\tshot = Shot()\n\tshot.user = \"Kristine Middlemiss\"\n\tshot.production = \"2009 Games Developer Conference\"\n\tshot.sequence = 1\n\tshot.scene = 1\n\tshot.shot = 0\n\treturn shot\n\n\n# Convenience function to display a Shot object's contents.\ndef dumpShot(shot):\n\tprint\n\tprint \"User:       %s\" % shot.user\n\tprint \"Production: %s\" % shot.production\n\tprint \"Scene:      %d\" % shot.scene\n\tprint \"Sequence:   %d\" % shot.sequence\n\tprint \"Shot:       %d\" % shot.shot\n\tprint\n\n\n# Request a new shot to work on. You have to pass in your old\n# shot so that the server can give you a shot which is close\n# to it. (E.g. same scene)\ndef requestNewShot(oldShot):\n\tif oldShot == None:\n\t\traise ValueError, 'Old shot is not valid.'\n\n\t# Create the request object.\n\trequest = ShotRequest()\n\trequest.type = 'NewShot'\n\trequest.shot = oldShot\n\n\t# Create a socket and connect it to the server.\n\ts = socket.socket(socket.AF_INET, socket.SOCK_STREAM)\n\thost = SERVER\n\tport = PORT\n\ts.connect((host, port))\n\t\n\t# Pickle the request into a string and send it\n\t# to the server.\n\trequestStr = cPickle.dumps(request, 2)\n\ts.send(requestStr)\n\n\t# Read the server's response into a string and\n\t# unpickle it into a Shot object.\n\tresponseStr = s.recv(4096)\n\tnewShot = cPickle.loads(responseStr)\n\n\ts.close()\n\n\treturn newShot\n\n"
  },
  {
    "path": "10_PythonAdvanced/examples/alt_str.py",
    "content": "\n#-\n# ==========================================================================\n# Copyright (C) 2008 Autodesk, Inc. and/or its licensors.  All \n# rights reserved.\n#\n# The coded instructions, statements, computer programs, and/or related \n# material (collectively the \"Data\") in these files contain unpublished \n# information proprietary to Autodesk, Inc. (\"Autodesk\") and/or its \n# licensors, which is protected by U.S. and Canadian federal copyright \n# law and by international treaties.\n#\n# The Data is provided for use exclusively by You. You have the right \n# to use, modify, and incorporate this Data into other products for \n# purposes authorized by the Autodesk software license agreement, \n# without fee.\n#\n# The copyright notices in the Software and this entire statement, \n# including the above license grant, this restriction and the \n# following disclaimer, must be included in all copies of the \n# Software, in whole or in part, and all derivative works of \n# the Software, unless such copies or derivative works are solely \n# in the form of machine-executable object code generated by a \n# source language processor.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND. \n# AUTODESK DOES NOT MAKE AND HEREBY DISCLAIMS ANY EXPRESS OR IMPLIED \n# WARRANTIES INCLUDING, BUT NOT LIMITED TO, THE WARRANTIES OF \n# NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR \n# PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE, OR \n# TRADE PRACTICE. IN NO EVENT WILL AUTODESK AND/OR ITS LICENSORS \n# BE LIABLE FOR ANY LOST REVENUES, DATA, OR PROFITS, OR SPECIAL, \n# DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES, EVEN IF AUTODESK \n# AND/OR ITS LICENSORS HAS BEEN ADVISED OF THE POSSIBILITY \n# OR PROBABILITY OF SUCH DAMAGES.\n#\n# ==========================================================================\n#+\n\n# This example shows how to override a class's __str__() method so that\n# it displays its contents in a more readable manner.\n\nimport maya.OpenMaya as om\n\n# -------------- MVector --------------------\n\n# Print out an MVector using its default __str__() method.\nv = om.MVector(1, 2, 3)\nprint \"With it's default __str__() method an MVector prints like this:\", v\n\n# Define a method to format an MVector into a string.\ndef MVector_str(self):\n\treturn \"(%g, %g, %g)\" % (self.x, self.y, self.z)\n\n# Save MVector's existing __str__() method.\noldMVector_str = om.MVector.__str__\n\n# Replace MVector's __str__() method with our own.\nom.MVector.__str__ = MVector_str\n\n# Try printing the vector again.\nprint \"With our replacement __str__() method it prints like this:\", v\n\n# Restore the original __str__() method.\nom.MVector.__str__ = oldMVector_str\n\nprint\n\n# -------------- MIntArray ------------------\n\n# Print out a sparse MIntArray using its default __str__() method.\nsparse = om.MIntArray(100)\nsparse[7] = -3\nsparse[20] = 13\nsparse[82] = 6\n\nprint \"A sparse MIntArray of 100 elements prints like this:\", sparse\n\n# Replacement for MIntArray's __str__() method\n# which compresses long sequences of identical values.\ndef compressedMIntArray_str(self):\n\ts = \"[\"\n\tcount = 0\n\tprev = None\n\tfor i in self:\n\t\tif i == prev:\n\t\t\tcount += 1\n\t\telse:\n\t\t\tif prev != None:\n\t\t\t\ts += compressSeq(count, prev) + \", \"\n\t\t\tcount = 1\n\t\t\tprev = i\n\n\ts += compressSeq(count, prev) + \"]\"\n\treturn s\n\n# Helper function which returns a string containing\n# 'count' copies of 'value'.\n# If 'count' is three or less then they are returned as\n# a comma-separated list, otherwise they are returned\n# in 'value * count' notation. E.g. '3*24' means a\n# sequence of 24 values of 3.\ndef compressSeq(count, value):\n\tif count > 0:\n\t\tif count > 3:\n\t\t\ts = str(value) + \"*\" + str(count)\n\t\telse:\n\t\t\ts = str(value)\n\t\t\tfor i in range(1, count):\n\t\t\t\ts += \", \" + str(value)\n\telse:\n\t\ts = \"\"\n\treturn s\n\n# Save MIntArray's existing __str__() method.\noldMIntArray_str = om.MIntArray.__str__\n\n# Replace MIntArray's __str__() method with our own.\nom.MIntArray.__str__ = compressedMIntArray_str\n\n# Try printing the array again.\nprint \"With our replacement __str__() method it prints like this:\", sparse\n\n# Restore the original __str__() method.\nom.MIntArray.__str__ = oldMIntArray_str\n"
  },
  {
    "path": "10_PythonAdvanced/examples/cppCentroid.cpp",
    "content": "\n//-\n// ==========================================================================\n// Copyright (C) 2008 Autodesk, Inc. and/or its licensors.  All \n// rights reserved.\n//\n// The coded instructions, statements, computer programs, and/or related \n// material (collectively the \"Data\") in these files contain unpublished \n// information proprietary to Autodesk, Inc. (\"Autodesk\") and/or its \n// licensors, which is protected by U.S. and Canadian federal copyright \n// law and by international treaties.\n//\n// The Data is provided for use exclusively by You. You have the right \n// to use, modify, and incorporate this Data into other products for \n// purposes authorized by the Autodesk software license agreement, \n// without fee.\n//\n// The copyright notices in the Software and this entire statement, \n// including the above license grant, this restriction and the \n// following disclaimer, must be included in all copies of the \n// Software, in whole or in part, and all derivative works of \n// the Software, unless such copies or derivative works are solely \n// in the form of machine-executable object code generated by a \n// source language processor.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND. \n// AUTODESK DOES NOT MAKE AND HEREBY DISCLAIMS ANY EXPRESS OR IMPLIED \n// WARRANTIES INCLUDING, BUT NOT LIMITED TO, THE WARRANTIES OF \n// NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR \n// PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE, OR \n// TRADE PRACTICE. IN NO EVENT WILL AUTODESK AND/OR ITS LICENSORS \n// BE LIABLE FOR ANY LOST REVENUES, DATA, OR PROFITS, OR SPECIAL, \n// DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES, EVEN IF AUTODESK \n// AND/OR ITS LICENSORS HAS BEEN ADVISED OF THE POSSIBILITY \n// OR PROBABILITY OF SUCH DAMAGES.\n//\n// ==========================================================================\n//+\n\n#include <Python.h>\n\n#include <maya/MDagPath.h>\n#include <maya/MFnMesh.h>\n#include <maya/MPoint.h>\n#include <maya/MPointArray.h>\n#include <maya/MSelectionList.h>\n\nstatic PyObject* cppCentroid_mesh(PyObject*, PyObject* args)\n{\n\t//\tRetrieve the name of the mesh from the argument list.\n\tconst char*\tmeshName;\n\tif (!PyArg_ParseTuple(args, \"s:mesh\", &meshName))\n\t{\n\t\treturn NULL;\n\t}\n\n\t// Get the mesh's dag path.\n\tMSelectionList\tslist;\n\tslist.add(meshName);\n\n\tMDagPath\t\tpath;\n\tslist.getDagPath(0, path);\n\n\tif (!path.hasFn(MFn::kMesh))\n\t{\n\t\treturn PyErr_Format(PyExc_ValueError, \"'%s' is not a mesh.\", meshName);\n\t}\n\n\t// Get the mesh's vertex positions.\n\tMFnMesh\t\tmeshFn(path);\n\tMPointArray\tverts;\n\n\tmeshFn.getPoints(verts, MSpace::kWorld);\n\n\tunsigned int numVerts = verts.length();\n\tif (numVerts == 0)\n\t{\n\t\treturn PyErr_Format(PyExc_ValueError, \"Mesh '%s' has no vertices.\", meshName);\n\t}\n\n\t// Add all the vertex positions together.\n\tdouble x = 0.0;\n\tdouble y = 0.0;\n\tdouble z = 0.0;\n\n\tfor (unsigned int i = 0; i < numVerts; ++i)\n\t{\n\t\tMPoint& p = verts[i];\n\t\tx += p.x;\n\t\ty += p.y;\n\t\tz += p.z;\n\t}\n\n\t// Calculate the average position.\n\tdouble divisor = 1.0 / (double)numVerts;\n\t\n\tx *= divisor;\n\ty *= divisor;\n\tz *= divisor;\n\n\t//\tReturn a tuple containing the average of the vertex positions.\n\treturn Py_BuildValue(\"(ddd)\", x, y, z);\n}\n\n\nstatic PyMethodDef cppCentroidMethods[] =\n{\n\t{ \"mesh\", cppCentroid_mesh, METH_VARARGS, \"Find the centroid of a mesh.\" },\n\t{ NULL, NULL, 0, NULL }\n};\n\n\nextern \"C\" PyMODINIT_FUNC initcppCentroid()\n{\n\tPy_InitModule(\"cppCentroid\", cppCentroidMethods);\n}\n"
  },
  {
    "path": "10_PythonAdvanced/examples/dist.py",
    "content": "# Simple test function for demonstrating pdb debugger.\ndef distance(p1, p2):\n\tdist = 0\n\tif len(p1) == len(p2):\n\t\tfor i in range(0, len(p1)):\n\t\t\tdiff = p1[i] - p2[i]\n\t\t\tdist += diff*diff\n\t\t\tdist = dist**0.5\n\treturn dist\n\n\n"
  },
  {
    "path": "10_PythonAdvanced/examples/guipdb.py",
    "content": "#-\n# ==========================================================================\n# Copyright (C) 2008 Autodesk, Inc. and/or its licensors.  All \n# rights reserved.\n#\n# The coded instructions, statements, computer programs, and/or related \n# material (collectively the \"Data\") in these files contain unpublished \n# information proprietary to Autodesk, Inc. (\"Autodesk\") and/or its \n# licensors, which is protected by U.S. and Canadian federal copyright \n# law and by international treaties.\n#\n# The Data is provided for use exclusively by You. You have the right \n# to use, modify, and incorporate this Data into other products for \n# purposes authorized by the Autodesk software license agreement, \n# without fee.\n#\n# The copyright notices in the Software and this entire statement, \n# including the above license grant, this restriction and the \n# following disclaimer, must be included in all copies of the \n# Software, in whole or in part, and all derivative works of \n# the Software, unless such copies or derivative works are solely \n# in the form of machine-executable object code generated by a \n# source language processor.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND. \n# AUTODESK DOES NOT MAKE AND HEREBY DISCLAIMS ANY EXPRESS OR IMPLIED \n# WARRANTIES INCLUDING, BUT NOT LIMITED TO, THE WARRANTIES OF \n# NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR \n# PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE, OR \n# TRADE PRACTICE. IN NO EVENT WILL AUTODESK AND/OR ITS LICENSORS \n# BE LIABLE FOR ANY LOST REVENUES, DATA, OR PROFITS, OR SPECIAL, \n# DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES, EVEN IF AUTODESK \n# AND/OR ITS LICENSORS HAS BEEN ADVISED OF THE POSSIBILITY \n# OR PROBABILITY OF SUCH DAMAGES.\n#\n# ==========================================================================\n#+\n\n# This example demonstrates how to provide Python's pdb debugger with\n# a basic graphical interface when run within Maya.\n#\n# To use it, execute the 'run' with an argument consisting of the\n# function call to be debugged, as a string. E.g:\n#\n#\tguipdb.run('myFunc(12, \"hello\")')\n\nimport pdb\nimport sys\nimport os\nimport maya.cmds as cmds\n\n\n# All that pdb requires of its input object are 'read' and 'readline'\n# methods.\n#\n# This class is a drop-in replacement for Maya's sys.stdin which will\n# bring up a GUI customized for use with pdb.\nclass DebuggerStandardInput:\n\tdef readline( self ):\n\t\treturn self._getUserDebugResponse()\n\t\t\n\tdef read( self ):\n\t\treturn self._getUserDebugResponse()\n\t\n\tdef _getUserDebugResponse(self):\n\t\tresult = cmds.promptDialog(\n\t\t\ttitle='Simple Debugger',\n\t\t\tmessage='Debugger command:',\n\t\t\tbutton=['Step Into', 'Step Over','Command'],\n\t\t\tdefaultButton='StepInto')\n\n\t\tif result == 'Command':\n\t\t\tresult = cmds.promptDialog(query=True, text=True)\n\t\telif result == 'Step Over':\n\t\t\tresult = 'n'\n\t\telif result == 'Step Into':\n\t\t\tresult = 's'\n\t\treturn result\n\n\n# All that pdb requires of its output object are 'write', 'writeline'\n# and 'flush' methods.\n#\n# This class is a drop-in replacement for Maya's sys.stdout which will\n# filter out unwanted prompts from pdb.\nclass DebuggerStandardOutput:\n\tdef __init__(self, orig_stdout):\n\t\tself.orig_stdout = orig_stdout\n\n\tdef write(self, msgoutput):\n\t\tline = msgoutput.strip()\n\t\t# If this is a pdb prompt, toss it away.\n\t\tif line[:5] == \"(Pdb)\":\n\t\t\tline = \"\\n\"\n\t\tself.orig_stdout.write(line)\n\n\tdef writelines(self, msgSeq):\n\t\tfor l in msgSeq:\n\t\t\tself.write(l)\n\n\tdef flush(self):\n\t\treturn None\n\n\n# Run our GUI version of pdb on a command string.\ndef run(command):\n\t# Save Maya's current stdin and stdout.\n\torig_stdin = sys.stdin\n\torig_stdout = sys.stdout\n\n\t# Replace stdin and stdout with instances of our own classes.\n\tsys.stdin = DebuggerStandardInput()\n\tsys.stdout = DebuggerStandardOutput(orig_stdout)\n\n\t# Run pdb.\n\tpdb.run(command)\n\n\t# Restore Maya's original stdin and stdout.\n\tsys.stdin = orig_stdin\n\tsys.stdout = orig_stdout\n"
  },
  {
    "path": "10_PythonAdvanced/examples/guipdb1.py",
    "content": "#-\n# ==========================================================================\n# Copyright (C) 2008 Autodesk, Inc. and/or its licensors.  All \n# rights reserved.\n#\n# The coded instructions, statements, computer programs, and/or related \n# material (collectively the \"Data\") in these files contain unpublished \n# information proprietary to Autodesk, Inc. (\"Autodesk\") and/or its \n# licensors, which is protected by U.S. and Canadian federal copyright \n# law and by international treaties.\n#\n# The Data is provided for use exclusively by You. You have the right \n# to use, modify, and incorporate this Data into other products for \n# purposes authorized by the Autodesk software license agreement, \n# without fee.\n#\n# The copyright notices in the Software and this entire statement, \n# including the above license grant, this restriction and the \n# following disclaimer, must be included in all copies of the \n# Software, in whole or in part, and all derivative works of \n# the Software, unless such copies or derivative works are solely \n# in the form of machine-executable object code generated by a \n# source language processor.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND. \n# AUTODESK DOES NOT MAKE AND HEREBY DISCLAIMS ANY EXPRESS OR IMPLIED \n# WARRANTIES INCLUDING, BUT NOT LIMITED TO, THE WARRANTIES OF \n# NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR \n# PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE, OR \n# TRADE PRACTICE. IN NO EVENT WILL AUTODESK AND/OR ITS LICENSORS \n# BE LIABLE FOR ANY LOST REVENUES, DATA, OR PROFITS, OR SPECIAL, \n# DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES, EVEN IF AUTODESK \n# AND/OR ITS LICENSORS HAS BEEN ADVISED OF THE POSSIBILITY \n# OR PROBABILITY OF SUCH DAMAGES.\n#\n# ==========================================================================\n#+\n\n# This example demonstrates how to provide Python's pdb debugger with\n# a basic graphical interface when run within Maya.\n#\n# To use it, execute the 'run' with an argument consisting of the\n# function call to be debugged, as a string. E.g:\n#\n#\tguipdb.run('myFunc(12, \"hello\")')\n\nimport pdb\nimport sys\nimport os\nimport maya.cmds as cmds\n\n\n# All that pdb requires of its input object are 'read' and 'readline'\n# methods.\n#\n# This class is a drop-in replacement for Maya's sys.stdin which will\n# bring up a GUI customized for use with pdb.\nclass DebuggerStandardInput:\n\tdef readline( self ):\n\t\tif 'MAYA_IGNORE_DIALOGS' in os.environ:\n\t\t\treturn '\\n'\n\t\telse:\n\t\t\treturn self._getUserDebugResponse()\n\t\t\n\tdef read( self ):\n\t\treturn self._getUserDebugResponse()\n\t\n\tdef _getUserDebugResponse(self):\n\t\tresult = cmds.promptDialog(\n\t\t\ttitle='Simple Debugger',\n\t\t\tmessage='Debugger command:',\n\t\t\tbutton=['Step Into', 'Step Over','Command'],\n\t\t\tdefaultButton='Command')\n\n\t\tif result == 'Command':\n\t\t\tresult = cmds.promptDialog(query=True, text=True)\n\t\telif result == 'Step Over':\n\t\t\tresult = 'n'\n\t\telif result == 'Step Into':\n\t\t\tresult = 's'\n\t\treturn result\n\n\n# All that pdb requires of its output object are 'write', 'writeline'\n# and 'flush' methods.\n#\n# This class is a drop-in replacement for Maya's sys.stdout which will\n# filter out unwanted prompts from pdb.\nclass DebuggerStandardOutput:\n\tdef __init__(self, orig_stdout):\n\t\tself.orig_stdout = orig_stdout\n\n\tdef write(self, msgoutput):\n\t\tline = msgoutput.strip()\n\t\t# If this is a pdb prompt, toss it away.\n\t\tif line[:5] == \"(Pdb)\":\n\t\t\tline = \"\\n\"\n\t\tself.orig_stdout.write(line)\n\n\tdef writelines(self, msgSeq):\n\t\tfor l in msgSeq:\n\t\t\tself.write(l)\n\n\tdef flush(self):\n\t\treturn None\n\n\n# Run our GUI version of pdb on a command string.\ndef run(command):\n\t# Save Maya's current stdin and stdout.\n\torig_stdin = sys.stdin\n\torig_stdout = sys.stdout\n\n\t# Replace stdin and stdout with instances of our own classes.\n\tsys.stdin = DebuggerStandardInput()\n\n\t# Run pdb.\n\tpdb.run(command)\n\n\t# Restore Maya's original stdin and stdout.\n\tsys.stdin = orig_stdin\n\tsys.stdout = orig_stdout\n"
  },
  {
    "path": "10_PythonAdvanced/examples/pyCentroid.py",
    "content": "#-\n# ==========================================================================\n# Copyright (C) 2008 Autodesk, Inc. and/or its licensors.  All \n# rights reserved.\n#\n# The coded instructions, statements, computer programs, and/or related \n# material (collectively the \"Data\") in these files contain unpublished \n# information proprietary to Autodesk, Inc. (\"Autodesk\") and/or its \n# licensors, which is protected by U.S. and Canadian federal copyright \n# law and by international treaties.\n#\n# The Data is provided for use exclusively by You. You have the right \n# to use, modify, and incorporate this Data into other products for \n# purposes authorized by the Autodesk software license agreement, \n# without fee.\n#\n# The copyright notices in the Software and this entire statement, \n# including the above license grant, this restriction and the \n# following disclaimer, must be included in all copies of the \n# Software, in whole or in part, and all derivative works of \n# the Software, unless such copies or derivative works are solely \n# in the form of machine-executable object code generated by a \n# source language processor.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND. \n# AUTODESK DOES NOT MAKE AND HEREBY DISCLAIMS ANY EXPRESS OR IMPLIED \n# WARRANTIES INCLUDING, BUT NOT LIMITED TO, THE WARRANTIES OF \n# NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR \n# PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE, OR \n# TRADE PRACTICE. IN NO EVENT WILL AUTODESK AND/OR ITS LICENSORS \n# BE LIABLE FOR ANY LOST REVENUES, DATA, OR PROFITS, OR SPECIAL, \n# DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES, EVEN IF AUTODESK \n# AND/OR ITS LICENSORS HAS BEEN ADVISED OF THE POSSIBILITY \n# OR PROBABILITY OF SUCH DAMAGES.\n#\n# ==========================================================================\n#+\n\nimport maya.OpenMaya as om\n\n\n# Return the centroid of a mesh.\ndef mesh(meshName):\n\t# Get the mesh's dag path.\n\tsList = om.MSelectionList()\n\tsList.add(meshName)\n\tpath = om.MDagPath()\n\tsList.getDagPath(0, path)\n\n\tif not path.hasFn(om.MFn.kMesh):\n\t\traise ValueError, \"'\" + meshName + \"' is not a mesh.\"\n\n\t# Get the mesh's vertex positions.\n\tmeshFn = om.MFnMesh(path)\n\tverts = om.MPointArray()\n\tmeshFn.getPoints(verts, om.MSpace.kWorld)\n\tnumVerts = verts.length()\n\n\tif numVerts == 0:\n\t\traise ValueError, \"Mesh '\" + meshName + \"' has no vertices.\"\n\n\t# Add all the vertex positions together.\n\tx = 0.0\n\ty = 0.0\n\tz = 0.0\n\n\tfor i in range(0, numVerts):\n\t\tpt = verts[i]\n\t\tx += pt.x\n\t\ty += pt.y\n\t\tz += pt.z\n\t\n\t# Calculate the average position.\n\tdivisor = 1.0 / numVerts\n\tx *= divisor\n\ty *= divisor\n\tz *= divisor\n\n\treturn (x, y, z)\n"
  },
  {
    "path": "README.md",
    "content": "Maya-Training-Material\n======================\n\nAbout this materials...\n-----------------------\nThis is the Maya API training material we are using to train people \non the Maya C++/Python API.\n\n* Materials provided here are from our two day classroom trainings. \n  You can also use this for self-learning. \n\n* This is to introduce you to the fundamentals of Maya API to get \n  you started. (Not meant to provide a complete coverage of \n  Maya API nor C++/Python/.NET Framework.) \n\n* Materials are in Python and C++. Labs exercises are provided \n  in two languages. Powerpoint presentation is mainly Python \n  unless C++ specific. \n\n* Disclaimer: We are aware that materials is not free of errors. \n  We intend to correct them as we encounter. We hope this will \n  be still useful for you to get started with Maya API programming. \n\nGood luck!  \n\n\n--------\n\n## License\n\nThis sample is licensed under the terms of the [MIT License](http://opensource.org/licenses/MIT). Please see the [LICENSE](LICENSE) file for full details.\n\n\n## Written by\n\nAutodesk Developer Network <br />\nMarch 2013 <br />\nhttp://www.autodesk.com/adn <br />\n"
  }
]