diff --git a/sandbox/extras/maya/INSTALL.txt b/sandbox/extras/maya/INSTALL.txt deleted file mode 100644 index c243b9490a..0000000000 --- a/sandbox/extras/maya/INSTALL.txt +++ /dev/null @@ -1,55 +0,0 @@ -NOTE: for some features to work you may need to build the latest version of appleseed, for instructions on how to do this please visit the following address: - -http://appleseedhq.net/wiki/building-appleseed - -NOTE: for the latest version of this plugin visit the Mayaseed github page: - -https://github.com/jonathantopf/mayaseed - - - -INSTALLATION -------- - -To install mayaseed just open 'open_me_to_install.ma' and it should guide you through the steps to install. If this doesnt work or you'd prefer to install in manually you just need to edit your userSetup.mel file which should be here: - -Mac: /Users//Library/Preferences/Autodesk/maya//scripts -Windows Vista and higher: C:\Users\\Documents\maya\\scripts (you may have My Documents instead of Documents) -Windows XP and lower: C:\Documents and Settings\username\My Documents\maya\\scripts -Linux: /usr/aw/userconfig/maya//scripts - -If cou dont have one of these files thats ok, just create a plain text file with a .mel extention and edit that. - -So copy the following lines to your useSetup.mel file - - - - -// mayaseed ------------------------------------------------------------------------------- - -$env_script_path = `getenv MAYA_SCRIPT_PATH`; -$env_plugin_path = `getenv MAYA_PLUG_IN_PATH`; -putenv MAYA_SCRIPT_PATH ($env_script_path + "/scripts"); -$env_script_path = `getenv MAYA_SCRIPT_PATH`; -putenv MAYA_SCRIPT_PATH ($env_script_path + "/graphics"); -putenv MAYA_PLUG_IN_PATH ($env_plugin_path + "/plugins"); - - -// mayaseed ------------------------------------------------------------------------------- - - - - -This just tells maya to search in your install directory for the mayaseed plugin when it starts up. You will also want to replace any occurences of with the path to your mayaseed install directory, so for example I would replace the following line: - -putenv MAYA_SCRIPT_PATH ($env_script_path + ":/plugins"); - -with this: - -putenv MAYA_PLUG_IN_PATH ($env_plugin_path + ":/projects/mayaseed/plugins"); - - -Finally you will want to start up Maya and enable the plugin, to do this choose window > settings preferences > plugin manager and load 'mayaseed.py', you will also want to click autoload so you don't have to do this step every time Maya loads. - -That should be everything, if everythign has gone to plan you shuld have a new menu called mayaseed where you can create new ms_renderSettings nodes. This exporter is very much a work in progress and many improvements/features are planned for the future. Also please submit any bugs/feature requests as this is meant to be practical and usable software and I'd love to hear how it is being used. - -jon diff --git a/sandbox/extras/maya/README.txt b/sandbox/extras/maya/README.txt index d62e416d86..6b81f17bb8 100644 --- a/sandbox/extras/maya/README.txt +++ b/sandbox/extras/maya/README.txt @@ -1 +1,5 @@ -Mayaseed is a maya plugin and for exporting camera, material and geometry data to the appleseed renderer. Mayaseed is released under the MIT licence. Enjoy, jt \ No newline at end of file +Mayaseed is a Maya plugin for exporting camera, material and geometry data to the appleseed renderer. + +Mayaseed documentation is available here: http://appleseedhq.net/documentation/mayaseed. + +Mayaseed is released under the MIT licence. \ No newline at end of file diff --git a/sandbox/extras/maya/docs/01_About_Mayaseed.html b/sandbox/extras/maya/docs/01_About_Mayaseed.html deleted file mode 100644 index 2003fa148a..0000000000 --- a/sandbox/extras/maya/docs/01_About_Mayaseed.html +++ /dev/null @@ -1,228 +0,0 @@ - - - - - - - - -

Mayaseed docs

- -

About Mayaseed

- -

What is Mayaseed?

- -

Mayaseed is a plugin for Maya that exports geometry, light and materials to the Applsessed renderer. Mayaseed has been tested and runs on Maya 2010 or newer, it should also run on older versions but has not been tested.

- -

What is appleseed?

- -

appleseed is an open source physically based raytracing renderer that does a whole bunch of cool things that a lot of other open source renderers don't. Take a look here.

- -

http://appleseedhq.net/

- -

Mayaseed Licence

- -

Mayaseed is released under the MIT licence -Like Appleseed Mayaseed is released under the MIT licence which means its free to use and modify to your hearts content.

- -

How it's made

- -

Mayaseed is Written mainly in Python with a little bit of MEL so its cross platform and easy to modify. You can find more about the structure of the plugin in the Plugin structure section. New releases will be announced on the Appleseed website here:

- -

http://appleseedhq.net/blog/jon

- -

You can also download the latest development snapshot from the appleseed gitHub page here:

- -

https://github.com/jonathantopf/Mayaseed

- -

Because Mayaseed is only written by one person (Jonathan Topf) and that person is not a professional developer by any stretch of the imagination you may encounter a bug from time to time. If you do find a bug file a report and ill try to fix it, heres the link for bug reports.

- -

https://github.com/jonathantopf/Mayaseed/issues?direction=desc&sort=created&state=open

- - - \ No newline at end of file diff --git a/sandbox/extras/maya/docs/02_Installation.html b/sandbox/extras/maya/docs/02_Installation.html deleted file mode 100644 index b9f47ab586..0000000000 --- a/sandbox/extras/maya/docs/02_Installation.html +++ /dev/null @@ -1,241 +0,0 @@ - - - - - - - - -

Mayaseed docs

- -

Installation

- -

To install Mayaseed just open 'openmeto_install.ma' and it should guide you through the steps to install. If this doesnt work or you'd prefer to install in manually you just need to edit your userSetup.mel file which should be here:

- -
Mac: /Users/<username>/Library/Preferences/Autodesk/maya/<maya version>/scripts
-
-Windows Vista and higher: C:\Users\<username>\Documents\maya\<maya version>\scripts (you may have My Documents instead of Documents)
-
-Windows XP and lower: C:\Documents and Settings\username\My Documents\maya\<maya version>\scripts
-
-Linux: /usr/aw/userconfig/maya/<maya version>/scripts
-
- -

If you don't have one of these files thats ok, just create a plain text file with a .mel extension and edit that.

- -

So copy the following lines to your useSetup.mel file

- -
// mayaseed  --------------
-
-$env_script_path = `getenv MAYA_SCRIPT_PATH`;
-$env_plugin_path = `getenv MAYA_PLUG_IN_PATH`;
-putenv MAYA_SCRIPT_PATH ($env_script_path + "<mayaseed_root>/scripts");
-$env_script_path = `getenv MAYA_SCRIPT_PATH`;
-putenv MAYA_SCRIPT_PATH ($env_script_path + "<mayaseed_root>/graphics");
-putenv MAYA_PLUG_IN_PATH ($env_plugin_path + "<mayaseed root>/plugins");
-
-
-// mayaseed  --------------
-
- -

This just tells maya to search in your install directory for the Mayaseed plugin when it starts up. You will also want to replace any occurences of with the path to your Mayaseed install directory, so for example I would replace the following line:

- -
putenv MAYA_SCRIPT_PATH ($env_script_path + ":<mayaseed root>/plugins");
-
- -

with this:

- -
putenv MAYA_PLUG_IN_PATH ($env_plugin_path + ":/projects/mayaseed/plugins");
-
- -

Finally you will want to start up Maya and enable the plugin, to do this choose Window -> Settings Preferences -> Plugin manager and load 'mayaseed.py', you will also want to click autoload so you don't have to do this step every time Maya loads.

- -

That should be everything, if everything has gone to plan you should have a new menu called Mayaseed where you can create new ms_renderSettings nodes. This exporter is very much a work in progress and many improvements/features are planned for the future. Also please submit any bugs/feature requests as this is meant to be practical and usable software and I'd love to hear how it is being used.

- - - \ No newline at end of file diff --git a/sandbox/extras/maya/docs/03_Getting_Started.html b/sandbox/extras/maya/docs/03_Getting_Started.html deleted file mode 100644 index 26d6b6fd4b..0000000000 --- a/sandbox/extras/maya/docs/03_Getting_Started.html +++ /dev/null @@ -1,229 +0,0 @@ - - - - - - - - -

Mayaseed docs

- -

Getting started

- -

The Mayaseed menu

- -

The Mayaseed menu will appear when the plugin is correctly installed, if you can't see it make sure the plugin installed correctly and is enabled.

- -

The Render Settings node

- -

The ms_renderSettings (render settings) node is the workhorse of Mayaseed, it contains most of the settings to control your export and is also one of the places where you can launch the export. To export your scene you only need one ms_renderSettings node but it is also possible to have many per scene, this can be useful for making proxy resolution renders or exporting for different render passes.

- -
-

Note: The ms_renderSettings node's attributes are organised in a way that mirrors the internal file structure, so if an attribute seems like its in a strange place there is a good reason. By using Mayaseed you are also learning about appleseed at the same time.

-
- -

Your first export

- -

To export a scene you first need to create a render settings node, to do this choose Mayaseed -> create render settings node.

- -

Now in the attribute editor you can Set up your export

- -
-

Note: if you deselect a render settings node then you can easily re select it by choosing Mayaseed -> Select render setting node

-
- -

To set up your first export you will only really need to do two things; set up your output destination and choose your render camera.

- -

First you will need to set your output directory, and then choose a name for your output file, both attributes are in the export settings section of the renderSettings node.

- -

Next you need to choose your render camera in the output settings.

- -

That should be all you need for your first export, not all you need to do is click the blue Export button at the top of your Render Settings node's attribute editor.

- - - \ No newline at end of file diff --git a/sandbox/extras/maya/docs/04_Node_Reference.html b/sandbox/extras/maya/docs/04_Node_Reference.html deleted file mode 100644 index 328b91c67a..0000000000 --- a/sandbox/extras/maya/docs/04_Node_Reference.html +++ /dev/null @@ -1,457 +0,0 @@ - - - - - - - - -

Mayaseed docs

- -

Node reference

- -

This section contains information on the nodes that make up the Mayaseed plugin and their atributes.

- -

ms_renderSettings node

- -

The ms_renderSettings (render settings) node is the biggest node in the Mayaseed plugin and contains most of the attributes that you will use to control your export.

- -

It is also one of the places where you can start your export from, at the top of the render settings node's attribute editor there is a blue button marked Export use this button to start your export.

- -

The following section is a list of attributes in the render settings node and a description of their functions.

- -
-

Note: The ms_renderSettings node's attributes are organised in a way that mirrors the internal file structure, so if an attribute seems like its in a strange place there is a good reason. By using Mayaseed you are also learning about appleseed at the same time.

-
- -

Export settings section

- -
Output Directory
- -

This is where you tell Mayaseed where to export the appleseed scene file and other relevant files to.

- -
Output File
- -

This is where you choose the name of your output file, the # character will be replaced with the frame number padded to 5 characters. So my_scene.#.appleseed will export as my_scene.00001.appleseed`.

- -
Convert Shading Nodes To Textures
- -

Use this checkbox to convert maya shading networks to textures on export. If a color attribute has a shading network attached Mayaseed will check to see the shading network is a texture node, if not with this option checked Mayaseed will bake the shading network to an exr image.

- -
Overwrite Existing EXRs
- -

If this checkbox is checked then Maya will convert and overwrite texture files with every export.

- -
Export Motion Blur
- -

This attribute is only a placeholder at this point.

- -
Shutter Open Time
- -

This attribute is only a placeholder at this point.

- -
Shutter Close Time
- -

This attribute is only a placeholder at this point.

- -
Export Animation
- -

This attribute is only a placeholder at this point.

- -
Animation Start Frame
- -

This attribute is only a placeholder at this point.

- -
Animation End Frame
- -

This attribute is only a placeholder at this point.

- -

Environment Settings section

- -
Environment
- -

A Maya scene can contain many environment nodes, here you can select which environment node to use in your export and also create new ones.

- -

Camera Settings Section

- -
Export All Cameras
- -

Although appleseed can only use one camera at a time it is possible to have more than one included in the scene file, use this checkbox to export all the maya cameras.

- -
Export All Cameras As Thinlens
- -

Appleseed has two types of cameras: Pinhole and Thinlens, the main difference being that a Thinlens camera can simulate depth of field and the Pinhole cannot. By default Mayaseed will export cameras with depth of field turned off as Pinhole and with depth of field turned on as Thinlens. Use this option to force Mayaseed to export all cameras as Thinlens.

- -

Assembly Settings Section

- -
-

Note: Appleseed uses the concept of Assembles to divide up the scene into smaller components.

-
- -
Interpret Sets As Assemblies
- -

With this option checked Mayaseed will export any sets containing geometry as an assembly.

- -
Double Sided Shading
- -

Use this option to turn on double shading in your appleseed scene file. Double shading causes geometry to be rendered on both sides of the shading normal. This can help reduce rendering artifacts especially on low poly geometry with smoothed normals.

- -

Output Settings Section

- -
Camera
- -

Use this attribute to select the camera you would like to export.

- -
-

Note: If you do not select a camera the export will fail.

-
- -
Resolution Width
- -

This attribute sets the width of the framebuffer.

- -
Resolution Height
- -

This attribute sets the height of the framebuffer.

- -
Color Space
- -

This sets the color space that appleseed will use, the default is sRGB.

- -

Configuration Settings Section

- -

Appleseed configurations contain information on the rendering method and quality setting of a render. Appleseed can have an arbitrarily high number of these render settings but must contain at least two, an Interactive Config and a Final config. These configurations control the quality of appleseed's default interactive render and final render. Without checking Export Custom Interactive COnfig or Export Custom Final Config Mayaseed will export a default settings.

- -

Both Interactive Config and Final COnfig have the following attributes.

- -
Lighting Engine
- -

This drop-down menu currently has two options: Path Tracing and Distributed Ray Tracing. Path tracing is more physically accurate and will compute color bleeding and caustics whereas distributed ray tracing is slower but less accurate.

- -
Min Samples
- -

Use this attribute to set the minimum render samples.

- -
Max Samples
- -

Use this attribute to set the maximum render samples.

- -
Max Ray Depth
- -

Max Ray depth controls the maximum number of bounces that a ray can go through. Higher numbers are more accurate but slower to render.

- -
Light Samples
- -

This attribute controls the number of samples per light.

- -

ms_environment node

- -

The ms_environment (environment) node is used to control the environment settings for your export. Right now it could easily be implemented in the render settings node but when environment transformations are implemented in appleseed it will be useful to have the environment node as a separate entity with its own transform node.

- -

Below is a list of the node's attributes and their functions.

- -
Model
- -

This drop down menu contains the different types of environment models that appleseed provides(below).

- -
    -
  • Constant Environment
  • -
  • Gradient Environment
  • -
  • Latitude Longitude Map
  • -
  • Mirrorball Map
  • -
- -
Constant Exitance
- -

Use this attribute if you have selected Constant Environment as your model.

- -
-

Note: only modify the color of this attribute, connecting a shading network will have no effect.

-
- -
Gradient Horizon Exitance
- -

Use this attribute to set the horizon color of the evironment if you have selected Gradient Environment as your model.

- -
-

Note: only modify the color of this attribute, connecting a shading network will have no effect.

-
- -
Gradient Zenith Exitance
- -

Use this attribute to set the zenith (highest point) color of the environment if you have selected Gradient Environment as your model.

- -
-

Note: only modify the color of this attribute, connecting a shading network will have no effect

-
- -
Latitude Longitude Exitance
- -

Attach a texture node to this attribute if you have selected Latitude Longitude Map as your environment model. The image should be in latitude longitude format for correct results.

- -
Mirror Ball Exitance
- -

Attach a texture node to this attribute if you have selected Mirror Ball Map as your environment model.

- -

Maya shaders

- -

Mayaseed will automatically translate maya shaders as best as possible to appleseed shaders but this often isn't perfect, when automatic shader translation isn't enough you can add a Custom Shader Translation. With an object or shader selected you can Choose Mayaseed -> Add Custom Shader Translationto add some Mayaseed specific attributes to your shader.

- -
-

Note: Custom shader translation is an experimental feature and is still limited in functionality.

-
- -

Once you have added a custom shader translation to your shader you will now find three new attributes in the Extra Attributes section of the Shaders attribute editor, the following is a list of the attributes and their functions.

- -

Mayaseed BSDF

- -

The Mayaseed BSDF drop-down menu lets you choose the BSDF model that Mayaseed will translate your shader to on export. BSDF stands for Bidirectional scattering distribution function and controls how light is reflected off the surface of an object. Although appleseed contains more BSDF options Mayaseed only supports the following BSDF's.

- -
    -
  • Labertian
  • -
  • Ashikhmin-Shirley
  • -
  • Kleeman
  • -
  • Specular_BSDF
  • -
  • <None>
  • -
- -

Mayaseed EDF

- -

The Mayaseed EDF drop-down menu lets you choose the EDF model that Mayaseed will translate your shader to on export. EDF stands for emittance distribution function and controls how light is emitted from a surface. Mayaseed has the following 2 options available:

- -
    -
  • <None>
  • -
  • Diffuse
  • -
- -

Mayaseed Surface Shader

- -

The Mayaseed Surface Shader controls how an object is rendered when it is directly visible to the camera. By default this is set to Physical which means that the object will be rendered according to the BSDF, this is usually the most physically accurate setting. Mayaseed has the following options available:

- -
    -
  • Physical
  • -
  • Constant
  • -
  • <None>
  • -
- -

Menu reference

- -

The Mayaseed menu will appear when the plugin is correctly installed, if you cant see it make sure the plugin installed correctly and is enabled.

- -

The following section contains all the items in the Mayaseed menu and their uses.

- -

Add Render Settings Node

- -

Use this to create a new instance of the ms_renderSettings node.

- -

Select Render Settings Node

- -

Use this to select any ms_renderSettings nodes that exist in the maya scene.

- -

Add Environment Node

- -

Use this to create a new instance of the ms_environment node.

- -

Select Environment Node

- -

Use this to select any ms_environment nodes that exist in the maya scene.

- -

Add Custom Shader Translation

- -

With a shader or an object selected use this to add a custom shader translation to a shader, more in the Maya Shaders section of the

- -

Remove Custom Shader Translation

- -

Use this to remove a custom shader translation from a Maya shader

- -

About

- -

Show information about Mayaseed.

- - - \ No newline at end of file diff --git a/sandbox/extras/maya/docs/05_Menu_Reference.html b/sandbox/extras/maya/docs/05_Menu_Reference.html deleted file mode 100644 index 44cb1781b4..0000000000 --- a/sandbox/extras/maya/docs/05_Menu_Reference.html +++ /dev/null @@ -1,231 +0,0 @@ - - - - - - - - -

Mayaseed docs

- -

Menu reference

- -

The Mayaseed menu will appear when the plugin is correctly installed, if you cant see it make sure the plugin installed correctly and is enabled.

- -

The following section contains all the items in the Mayaseed menu and their uses.

- -

Add Render Settings Node

- -

Use this to create a new instance of the ms_renderSettings node.

- -

Select Render Settings Node

- -

Use this to select any ms_renderSettings nodes that exist in the maya scene.

- -

Add Environment Node

- -

Use this to create a new instance of the ms_environment node.

- -

Select Environment Node

- -

Use this to select any ms_environment nodes that exist in the maya scene.

- -

Add Custom Shader Translation

- -

With a shader or an object selected use this to add a custom shader translation to a shader, more in the Maya Shaders section of the

- -

Remove Custom Shader Translation

- -

Use this to remove a custom shader translation from a Maya shader

- -

About

- -

Show information about Mayaseed.

- - - \ No newline at end of file diff --git a/sandbox/extras/maya/docs/06_Python_Module_Reference.html b/sandbox/extras/maya/docs/06_Python_Module_Reference.html deleted file mode 100644 index 1414322771..0000000000 --- a/sandbox/extras/maya/docs/06_Python_Module_Reference.html +++ /dev/null @@ -1,310 +0,0 @@ - - - - - - - - -

Mayaseed docs

- -

Python Module reference

- -

With mayaseed correctly installed you also have the following new python modules available to you.

- -
    -
  • ms_commands
  • -
  • ms_export
  • -
- -

ms_commands module

- -

ms_commands is where all the common functions, classes and variables reside, this section describes them.

- -

Variable: ms_commands.MAYASEED_VERSION

- -

This variable will return the current Mayaseed version.

- -

Variable: ms_commands.MAYASEED_URL

- -

This variable will return the URL of the Mayaseed website.

- -

Variable: ms_commands.APPLESEED_URL

- -

This variable will return the URL of the appleseed website.

- -

Variable: ms_commands.ROOT_DIRECTORY

- -

This variable will return the URL of the Mayaseed install's root directory.

- -

Function: ms_commands.addShadingAttribs()

- -

With an object or shader selected use this function to add custom shader translation attributes to a shader.

- -

Function: ms_commands.removeShadingAttribs()

- -

With an object or shader selected use this function to remove custom shader translation attributes to a shader

- -

Class: ms_commands.MsInfoDial()

- -

This function shows the Mayaseed info dialogue.

- -

Function: ms_commands.normalizeRGB(Tuple[Float:R,Float:G,Float:B]: Color) Returns Tuple[Float:R,Float:G,Float:B,Float:M]

- -

Use this function normalises a 3 value [R,G,B] tuple and returns a normalised tuple with the RGB values normalised to a 0-1 range with a 4th multiplier value.

- -

Function: ms_commands.convertConnectionToImage(String:shader, String:attribute, String:dest_file, Int:resolution=1024) Returns String:dest_file

- -

This function will bake a given shading connection to an image file.

- -
Argument: String:shader
- -

Name of the shader. e.g. "Lambert1"

- -
Argument: String:attribute
- -

The name of the attribute you want to bake. e.g. "Color"

- -
Argument: String:dest_file
- -

The destination of the file you'd like to export

- -
Argument: Int:resolution
- -

The resolution of the image you would like to bake, images are always square.

- -

Function: convertTexToExr(String:file_path, String:dest_dir, Boolean: overwrite=True) Returns String:dest_file

- -

Use this function to convert an image to an .exr file using the imf_copy utility that ships with maya. The function returns a string containing the path to the destination file.

- -
Argument: String:file_path
- -

File path of the image to be converted.

- -
Argument: String:dest_dir
- -

The directory that you would like to save the converted image to.

- -
-

Note: The converted image will have the same name as the source file but with the .exr extension.

-
- -
Argument: Boolean:overwrite = True
- -

By default Mayaseed will overwrite any images that have the same name as the output file, set this argument to false if you want to cancel image conversion for existing images

- -

Function: ms_commands.shapeIsExportable(String:node_name) Returns Boolean

- -

This function will check to see if a maya shape node is exportable based on whether it is visible and is a valid shape node.

- -
Argument: String:node_name
- -

This string is the name of the node you wish to check

- -

Function: ms_commands.hasShaderConnected(String:node_name) Returns Boolean

- -

This function checks whether a shape node has a shader connected.

- -
Argument: String:node_name
- -

This string is the name of the shape node you want to check.

- -

ms_export module

- -

This module contains the main bulk of the code that handles the export and essentially only has one useful function.

- -

Function: msexport.export(String:rendersettings_node)

- -

This function is the workhorse of Mayaseed and does all the work in translating, exporting and writing your scene to disk based on the settings from your render settings node.

- -
Argument: String:String:rendersettingsnode
- -

This string is the name of the render settings node that contains the settings of your export.

- - - \ No newline at end of file diff --git a/sandbox/extras/maya/docs/07_Plugin_Structure.html b/sandbox/extras/maya/docs/07_Plugin_Structure.html deleted file mode 100644 index 9c397f373c..0000000000 --- a/sandbox/extras/maya/docs/07_Plugin_Structure.html +++ /dev/null @@ -1,286 +0,0 @@ - - - - - - - - -

Mayaseed docs

- -

Plugin structure

- -

You will find the following files and folders inside the Mayaseed src directory that make up the Mayaseed plugin.

- -
    -
  • graphics (directory) - -
      -
    • mayaseed_graphic.png
    • -
  • -
  • INSTALL.txt
  • -
  • Mayaseed_Docs.html
  • -
  • Mayaseed_Docs.md
  • -
  • openmeto_install.ma
  • -
  • plugins (directory) - -
      -
    • mayaseed.py
    • -
  • -
  • README.txt
  • -
  • scripts - -
      -
    • about.txt
    • -
    • AEms_environmentTemplate.mel
    • -
    • AEms_renderSettingsTemplate.mel
    • -
    • mayaseed.ui
    • -
    • ms_commands.py
    • -
    • ms_export.py
    • -
    • ms_menu.py
    • -
  • -
- -

graphics (directory)

- -

The graphics directory contains any graphics used in the ui.

- -

INSTALL.txt

- -

This file contains instructions on how to install Mayaseed, the instructions are mirrored in the Mayaseed docs but are included here just in case.

- -

Mayaseed_Docs.md & Mayaseed_Docs.html

- -

Mayaseed_Docs.html is generated from the Mayaseed_Docs.md file. The .md file is a plain text file formatted using the markdown language.

- -

open_me_to_install.ma

- -

open_me_to_install.ma is a regular maya file that contains a python script node that executes on opening. The python script adds the Mayaseed plugins and scripts directory to the maya PATH so that maya can find the source files.

- -

plugins (directory)

- -

This directory contains the main plugin python file meaning it contains a single file that defines the Mayaseed nodes.

- -

mayaseed.py

- -

This file contains the code that defines the msrenderSettings node and the msenvironment node.

- -

README.txt

- -

Simple text file containing information about Mayaseed.

- -

scripts (directory)

- -

The scripts directory contain all the functions, classes and attribute editor templates plus a few other things.

- -

about.txt

- -

about.txt contains the text that the About Mayaseed dialogue displays.

- -

AEms_environmentTemplate.mel

- -

This file describes how the ms_environment node is displayed in the attribute editor.

- -

AEms_renderSettingsTemplate.mel

- -

This file describes how the ms_renderSettings node is displayed in the attribute editor.

- -

ms_commands.py

- -

ms_commands.py contains commands used in the Mayaseed menu and utility variables,functions and classes for the ms_export module.

- -

ms_export.py

- -

ms_export.py contains the export() function that does most of the hard work in translating the maya scene to the .appleseed format. Broadly speaking a writeXML object is handed down through each XML entity in the appleseed scene description writing to the file as it goes.

- -

ms_menu

- -

This python script sets up the Mayaseed menu and is called by mayaseed.py in the initializePlugin() function. The uninitializePlugin() function also calls this module to delete the Mayaseed menu when the plugin is unloaded.

- - - \ No newline at end of file diff --git a/sandbox/extras/maya/docs/src/01_About_Mayaseed.md b/sandbox/extras/maya/docs/src/01_About_Mayaseed.md deleted file mode 100644 index 89b987598f..0000000000 --- a/sandbox/extras/maya/docs/src/01_About_Mayaseed.md +++ /dev/null @@ -1,35 +0,0 @@ -Mayaseed docs -============= - - -About Mayaseed --------------- - -###What is Mayaseed?### - -Mayaseed is a plugin for Maya that exports geometry, light and materials to the Applsessed renderer. Mayaseed has been tested and runs on Maya 2010 or newer, it should also run on older versions but has not been tested. - -###What is appleseed?### - -appleseed is an open source physically based raytracing renderer that does a whole bunch of cool things that a lot of other open source renderers don't. Take a look here. - -http://appleseedhq.net/ - -###Mayaseed Licence### - -Mayaseed is released under the MIT licence -Like Appleseed Mayaseed is released under the MIT licence which means its free to use and modify to your hearts content. - -###How it's made### - -Mayaseed is Written mainly in Python with a little bit of MEL so its cross platform and easy to modify. You can find more about the structure of the plugin in the **Plugin structure** section. New releases will be announced on the Appleseed website here: - -http://appleseedhq.net/blog/jon - -You can also download the latest development snapshot from the appleseed gitHub page here: - -https://github.com/jonathantopf/Mayaseed - -Because Mayaseed is only written by one person ([Jonathan Topf](http://www.jonathantopf.com/)) and that person is not a professional developer by any stretch of the imagination you may encounter a bug from time to time. If you do find a bug file a report and ill try to fix it, heres the link for bug reports. - -https://github.com/jonathantopf/Mayaseed/issues?direction=desc&sort=created&state=open diff --git a/sandbox/extras/maya/docs/src/02_Installation.md b/sandbox/extras/maya/docs/src/02_Installation.md deleted file mode 100644 index 9eadb6fd81..0000000000 --- a/sandbox/extras/maya/docs/src/02_Installation.md +++ /dev/null @@ -1,49 +0,0 @@ -Mayaseed docs -============= - - -Installation -------------------- - -To install Mayaseed just open 'open_me_to_install.ma' and it should guide you through the steps to install. If this doesnt work or you'd prefer to install in manually you just need to edit your userSetup.mel file which should be here: - - Mac: /Users//Library/Preferences/Autodesk/maya//scripts - - Windows Vista and higher: C:\Users\\Documents\maya\\scripts (you may have My Documents instead of Documents) - - Windows XP and lower: C:\Documents and Settings\username\My Documents\maya\\scripts - - Linux: /usr/aw/userconfig/maya//scripts - -If you don't have one of these files thats ok, just create a plain text file with a .mel extension and edit that. - -So copy the following lines to your useSetup.mel file - - - // mayaseed -------------- - - $env_script_path = `getenv MAYA_SCRIPT_PATH`; - $env_plugin_path = `getenv MAYA_PLUG_IN_PATH`; - putenv MAYA_SCRIPT_PATH ($env_script_path + "/scripts"); - $env_script_path = `getenv MAYA_SCRIPT_PATH`; - putenv MAYA_SCRIPT_PATH ($env_script_path + "/graphics"); - putenv MAYA_PLUG_IN_PATH ($env_plugin_path + "/plugins"); - - - // mayaseed -------------- - - -This just tells maya to search in your install directory for the Mayaseed plugin when it starts up. You will also want to replace any occurences of with the path to your Mayaseed install directory, so for example I would replace the following line: - - putenv MAYA_SCRIPT_PATH ($env_script_path + ":/plugins"); - -with this: - - putenv MAYA_PLUG_IN_PATH ($env_plugin_path + ":/projects/mayaseed/plugins"); - - -Finally you will want to start up Maya and enable the plugin, to do this choose **Window -> Settings Preferences -> Plugin manager** and load 'mayaseed.py', you will also want to click autoload so you don't have to do this step every time Maya loads. - -That should be everything, if everything has gone to plan you should have a new menu called Mayaseed where you can create new ms_renderSettings nodes. This exporter is very much a work in progress and many improvements/features are planned for the future. Also please submit any bugs/feature requests as this is meant to be practical and usable software and I'd love to hear how it is being used. - - diff --git a/sandbox/extras/maya/docs/src/03_Getting_Started.md b/sandbox/extras/maya/docs/src/03_Getting_Started.md deleted file mode 100644 index 26227a8b2a..0000000000 --- a/sandbox/extras/maya/docs/src/03_Getting_Started.md +++ /dev/null @@ -1,34 +0,0 @@ -Mayaseed docs -============= - - -Getting started ---------------- - -###The Mayaseed menu### - -The Mayaseed menu will appear when the plugin is correctly installed, if you can't see it make sure the plugin installed correctly and is enabled. - - -###The Render Settings node### - -The ms\_renderSettings (render settings) node is the workhorse of Mayaseed, it contains most of the settings to control your export and is also one of the places where you can launch the export. To export your scene you only need one ms\_renderSettings node but it is also possible to have many per scene, this can be useful for making proxy resolution renders or exporting for different render passes. - ->Note: The ms_renderSettings node's attributes are organised in a way that mirrors the internal file structure, so if an attribute seems like its in a strange place there is a good reason. By using Mayaseed you are also learning about appleseed at the same time. - -###Your first export### - -To export a scene you first need to create a render settings node, to do this choose **Mayaseed -> create render settings node**. - -Now in the attribute editor you can Set up your export - ->Note: if you deselect a render settings node then you can easily re select it by choosing Mayaseed -> Select render setting node - -To set up your first export you will only really need to do two things; set up your output destination and choose your render camera. - -First you will need to set your output directory, and then choose a name for your output file, both attributes are in the export settings section of the renderSettings node. - -Next you need to choose your render camera in the output settings. - -That should be all you need for your first export, not all you need to do is click the blue **Export** button at the top of your Render Settings node's attribute editor. - diff --git a/sandbox/extras/maya/docs/src/04_Node_Reference.md b/sandbox/extras/maya/docs/src/04_Node_Reference.md deleted file mode 100644 index c3327d6a9a..0000000000 --- a/sandbox/extras/maya/docs/src/04_Node_Reference.md +++ /dev/null @@ -1,253 +0,0 @@ -Mayaseed docs -============= - - -Node reference --------------- - -This section contains information on the nodes that make up the Mayaseed plugin and their atributes. - - -###ms_renderSettings node### - -The ms\_renderSettings (render settings) node is the biggest node in the Mayaseed plugin and contains most of the attributes that you will use to control your export. - -It is also one of the places where you can start your export from, at the top of the render settings node's attribute editor there is a blue button marked **Export** use this button to start your export. - -The following section is a list of attributes in the render settings node and a description of their functions. - ->Note: The ms_renderSettings node's attributes are organised in a way that mirrors the internal file structure, so if an attribute seems like its in a strange place there is a good reason. By using Mayaseed you are also learning about appleseed at the same time. - - -####Export settings section#### - -#####Output Directory##### - -This is where you tell Mayaseed where to export the appleseed scene file and other relevant files to. - -#####Output File##### - -This is where you choose the name of your output file, the `#` character will be replaced with the frame number padded to 5 characters. So `my_scene.#.appleseed` will export as my_scene.00001.appleseed`. - -#####Convert Shading Nodes To Textures##### - -Use this checkbox to convert maya shading networks to textures on export. If a color attribute has a shading network attached Mayaseed will check to see the shading network is a texture node, if not with this option checked Mayaseed will bake the shading network to an exr image. - -#####Overwrite Existing EXRs##### - -If this checkbox is checked then Maya will convert and overwrite texture files with every export. - -#####Export Motion Blur##### - -This attribute is only a placeholder at this point. - -#####Shutter Open Time##### - -This attribute is only a placeholder at this point. - -#####Shutter Close Time##### - -This attribute is only a placeholder at this point. - -#####Export Animation##### - -This attribute is only a placeholder at this point. - -#####Animation Start Frame##### - -This attribute is only a placeholder at this point. - -#####Animation End Frame##### - -This attribute is only a placeholder at this point. - - -####Environment Settings section#### - -#####Environment##### - -A Maya scene can contain many environment nodes, here you can select which environment node to use in your export and also create new ones. - - -####Camera Settings Section#### - -#####Export All Cameras##### - -Although appleseed can only use one camera at a time it is possible to have more than one included in the scene file, use this checkbox to export all the maya cameras. - -#####Export All Cameras As Thinlens##### - -Appleseed has two types of cameras: **Pinhole** and **Thinlens**, the main difference being that a Thinlens camera can simulate depth of field and the Pinhole cannot. By default Mayaseed will export cameras with depth of field turned off as Pinhole and with depth of field turned on as Thinlens. Use this option to force Mayaseed to export all cameras as Thinlens. - - -####Assembly Settings Section#### - -> Note: Appleseed uses the concept of Assembles to divide up the scene into smaller components. - -#####Interpret Sets As Assemblies##### - -With this option checked Mayaseed will export any sets containing geometry as an assembly. - -#####Double Sided Shading##### - -Use this option to turn on double shading in your appleseed scene file. Double shading causes geometry to be rendered on both sides of the shading normal. This can help reduce rendering artifacts especially on low poly geometry with smoothed normals. - - -####Output Settings Section#### - -#####Camera##### - -Use this attribute to select the camera you would like to export. - -> Note: If you do not select a camera the export will fail. - -#####Resolution Width##### - -This attribute sets the width of the framebuffer. - -#####Resolution Height##### - -This attribute sets the height of the framebuffer. - -#####Color Space##### - -This sets the color space that appleseed will use, the default is **sRGB**. - - -####Configuration Settings Section#### - -Appleseed configurations contain information on the rendering method and quality setting of a render. Appleseed can have an arbitrarily high number of these render settings but must contain at least two, an **Interactive Config** and a **Final config**. These configurations control the quality of appleseed's default interactive render and final render. Without checking **Export Custom Interactive COnfig** or **Export Custom Final Config** Mayaseed will export a default settings. - -Both Interactive Config and Final COnfig have the following attributes. - -#####Lighting Engine##### - -This drop-down menu currently has two options: **Path Tracing** and **Distributed Ray Tracing**. Path tracing is more physically accurate and will compute color bleeding and caustics whereas distributed ray tracing is slower but less accurate. - -#####Min Samples##### - -Use this attribute to set the minimum render samples. - -#####Max Samples##### - -Use this attribute to set the maximum render samples. - -#####Max Ray Depth##### - -Max Ray depth controls the maximum number of bounces that a ray can go through. Higher numbers are more accurate but slower to render. - -#####Light Samples##### - -This attribute controls the number of samples per light. - - - -###ms_environment node### - -The ms\_environment (environment) node is used to control the environment settings for your export. Right now it could easily be implemented in the render settings node but when environment transformations are implemented in appleseed it will be useful to have the environment node as a separate entity with its own transform node. - -Below is a list of the node's attributes and their functions. - -#####Model##### - -This drop down menu contains the different types of environment models that appleseed provides(below). - -+ Constant Environment -+ Gradient Environment -+ Latitude Longitude Map -+ Mirrorball Map - -#####Constant Exitance##### - -Use this attribute if you have selected **Constant Environment** as your model. - -> Note: only modify the color of this attribute, connecting a shading network will have no effect. - -#####Gradient Horizon Exitance##### - -Use this attribute to set the horizon color of the evironment if you have selected **Gradient Environment** as your model. - -> Note: only modify the color of this attribute, connecting a shading network will have no effect. - -#####Gradient Zenith Exitance##### - -Use this attribute to set the zenith (highest point) color of the environment if you have selected **Gradient Environment** as your model. - -> Note: only modify the color of this attribute, connecting a shading network will have no effect - -#####Latitude Longitude Exitance##### - -Attach a texture node to this attribute if you have selected **Latitude Longitude Map** as your environment model. The image should be in latitude longitude format for correct results. - -#####Mirror Ball Exitance##### - -Attach a texture node to this attribute if you have selected **Mirror Ball Map** as your environment model. - - -###Maya shaders### - -Mayaseed will automatically translate maya shaders as best as possible to appleseed shaders but this often isn't perfect, when automatic shader translation isn't enough you can add a **Custom Shader Translation**. With an object or shader selected you can Choose **Mayaseed -> Add Custom Shader Translation**to add some Mayaseed specific attributes to your shader. - -> Note: Custom shader translation is an experimental feature and is still limited in functionality. - -Once you have added a custom shader translation to your shader you will now find three new attributes in the **Extra Attributes** section of the Shaders attribute editor, the following is a list of the attributes and their functions. - -####Mayaseed BSDF#### - -The **Mayaseed BSDF** drop-down menu lets you choose the BSDF model that Mayaseed will translate your shader to on export. BSDF stands for Bidirectional scattering distribution function and controls how light is reflected off the surface of an object. Although appleseed contains more BSDF options Mayaseed only supports the following BSDF's. - -+ Labertian -+ Ashikhmin-Shirley -+ Kleeman -+ Specular_BSDF -+ \ - -####Mayaseed EDF#### - -The **Mayaseed EDF** drop-down menu lets you choose the EDF model that Mayaseed will translate your shader to on export. EDF stands for **emittance distribution function** and controls how light is emitted from a surface. Mayaseed has the following 2 options available: - -+ \ -+ Diffuse - -####Mayaseed Surface Shader#### - -The **Mayaseed Surface Shader** controls how an object is rendered when it is directly visible to the camera. By default this is set to **Physical** which means that the object will be rendered according to the BSDF, this is usually the most physically accurate setting. Mayaseed has the following options available: - -+ Physical -+ Constant -+ \ - - -Menu reference --------------- -The Mayaseed menu will appear when the plugin is correctly installed, if you cant see it make sure the plugin installed correctly and is enabled. - -The following section contains all the items in the Mayaseed menu and their uses. - -###Add Render Settings Node### - -Use this to create a new instance of the ms\_renderSettings node. - -###Select Render Settings Node### - -Use this to select any ms\_renderSettings nodes that exist in the maya scene. - -###Add Environment Node### - -Use this to create a new instance of the ms\_environment node. - -###Select Environment Node### - -Use this to select any ms\_environment nodes that exist in the maya scene. - -###Add Custom Shader Translation### - -With a shader or an object selected use this to add a custom shader translation to a shader, more in the **Maya Shaders** section of the - -###Remove Custom Shader Translation### - -Use this to remove a custom shader translation from a Maya shader - -###About ### - -Show information about Mayaseed. diff --git a/sandbox/extras/maya/docs/src/05_Menu_Reference.md b/sandbox/extras/maya/docs/src/05_Menu_Reference.md deleted file mode 100644 index 7934f0d991..0000000000 --- a/sandbox/extras/maya/docs/src/05_Menu_Reference.md +++ /dev/null @@ -1,37 +0,0 @@ -Mayaseed docs -============= - - -Menu reference --------------- -The Mayaseed menu will appear when the plugin is correctly installed, if you cant see it make sure the plugin installed correctly and is enabled. - -The following section contains all the items in the Mayaseed menu and their uses. - -###Add Render Settings Node### - -Use this to create a new instance of the ms\_renderSettings node. - -###Select Render Settings Node### - -Use this to select any ms\_renderSettings nodes that exist in the maya scene. - -###Add Environment Node### - -Use this to create a new instance of the ms\_environment node. - -###Select Environment Node### - -Use this to select any ms\_environment nodes that exist in the maya scene. - -###Add Custom Shader Translation### - -With a shader or an object selected use this to add a custom shader translation to a shader, more in the **Maya Shaders** section of the - -###Remove Custom Shader Translation### - -Use this to remove a custom shader translation from a Maya shader - -###About ### - -Show information about Mayaseed. diff --git a/sandbox/extras/maya/docs/src/06_Python_Module_Reference.md b/sandbox/extras/maya/docs/src/06_Python_Module_Reference.md deleted file mode 100644 index 8e9884e8b9..0000000000 --- a/sandbox/extras/maya/docs/src/06_Python_Module_Reference.md +++ /dev/null @@ -1,136 +0,0 @@ -Mayaseed docs -============= - - -Python Module reference ------------------------ - -With mayaseed correctly installed you also have the following new python modules available to you. - -+ ms_commands -+ ms_export - -###ms_commands module### - -**ms_commands** is where all the common functions, classes and variables reside, this section describes them. - - -####Variable: ms\_commands.MAYASEED_VERSION##### - -This variable will return the current Mayaseed version. - - -####Variable: ms\_commands.MAYASEED_URL#### - -This variable will return the URL of the Mayaseed website. - - -####Variable: ms\_commands.APPLESEED_URL#### - -This variable will return the URL of the appleseed website. - - -####Variable: ms\_commands.ROOT_DIRECTORY#### - -This variable will return the URL of the Mayaseed install's root directory. - - -####Function: ms\_commands.addShadingAttribs()#### - -With an object or shader selected use this function to add custom shader translation attributes to a shader. - - -####Function: ms\_commands.removeShadingAttribs()#### - -With an object or shader selected use this function to remove custom shader translation attributes to a shader - - -####Class: ms\_commands.MsInfoDial()#### - -This function shows the Mayaseed info dialogue. - - -####Function: ms\_commands.normalizeRGB(Tuple[Float:R,Float:G,Float:B]: Color) Returns Tuple[Float:R,Float:G,Float:B,Float:M]#### - -Use this function normalises a 3 value [R,G,B] tuple and returns a normalised tuple with the RGB values normalised to a 0-1 range with a 4th multiplier value. - - -####Function: ms\_commands.convertConnectionToImage(String:shader, String:attribute, String:dest\_file, Int:resolution=1024) Returns String:dest\_file - -This function will bake a given shading connection to an image file. - -#####Argument: String:shader##### - -Name of the shader. e.g. "Lambert1" - - -#####Argument: String:attribute##### - -The name of the attribute you want to bake. e.g. "Color" - - -#####Argument: String:dest\_file##### - -The destination of the file you'd like to export - - -#####Argument: Int:resolution##### - -The resolution of the image you would like to bake, images are always square. - - -####Function: convertTexToExr(String:file\_path, String:dest\_dir, Boolean: overwrite=True) Returns String:dest_file#### - -Use this function to convert an image to an .exr file using the **imf_copy** utility that ships with maya. The function returns a string containing the path to the destination file. - - -#####Argument: String:file\_path##### - -File path of the image to be converted. - - -#####Argument: String:dest\_dir##### - -The directory that you would like to save the converted image to. - -> Note: The converted image will have the same name as the source file but with the .exr extension. - - -#####Argument: Boolean:overwrite = True##### - -By default Mayaseed will overwrite any images that have the same name as the output file, set this argument to false if you want to cancel image conversion for existing images - - -####Function: ms\_commands.shapeIsExportable(String:node\_name) Returns Boolean - -This function will check to see if a maya shape node is exportable based on whether it is visible and is a valid shape node. - - -#####Argument: String:node_name##### - -This string is the name of the node you wish to check - - -####Function: ms\_commands.hasShaderConnected(String:node\_name) Returns Boolean#### - -This function checks whether a shape node has a shader connected. - - -#####Argument: String:node\_name##### - -This string is the name of the shape node you want to check. - - -###ms_export module### - -This module contains the main bulk of the code that handles the export and essentially only has one useful function. - - -####Function: ms_export.export(String:render_settings_node)#### - -This function is the workhorse of Mayaseed and does all the work in translating, exporting and writing your scene to disk based on the settings from your render settings node. - - -#####Argument: String:String:render_settings_node##### - -This string is the name of the render settings node that contains the settings of your export. \ No newline at end of file diff --git a/sandbox/extras/maya/docs/src/07_Plugin_Structure.md b/sandbox/extras/maya/docs/src/07_Plugin_Structure.md deleted file mode 100644 index 4abd78df76..0000000000 --- a/sandbox/extras/maya/docs/src/07_Plugin_Structure.md +++ /dev/null @@ -1,97 +0,0 @@ -Mayaseed docs -============= - - -Plugin structure ----------------- - -You will find the following files and folders inside the Mayaseed **src** directory that make up the Mayaseed plugin. - -+ graphics (directory) - + mayaseed_graphic.png -+ INSTALL.txt -+ Mayaseed_Docs.html -+ Mayaseed_Docs.md -+ open_me_to_install.ma -+ plugins (directory) - + mayaseed.py -+ README.txt -+ scripts - + about.txt - + AEms_environmentTemplate.mel - + AEms_renderSettingsTemplate.mel - + mayaseed.ui - + ms_commands.py - + ms_export.py - + ms_menu.py - -###graphics (directory)### - -The **graphics** directory contains any graphics used in the ui. - - -###INSTALL.txt## - -This file contains instructions on how to install Mayaseed, the instructions are mirrored in the Mayaseed docs but are included here just in case. - - -###Mayaseed\_Docs.md & Mayaseed_Docs.html### - -**Mayaseed\_Docs.html** is generated from the **Mayaseed\_Docs.md** file. The .md file is a plain text file formatted using the markdown language. - - -###open\_me\_to\_install.ma### - -**open\_me\_to\_install.ma** is a regular maya file that contains a python script node that executes on opening. The python script adds the Mayaseed plugins and scripts directory to the maya PATH so that maya can find the source files. - - -###plugins (directory)### - -This directory contains the main plugin python file meaning it contains a single file that defines the Mayaseed nodes. - - -###mayaseed.py### - -This file contains the code that defines the ms_renderSettings node and the ms_environment node. - - -###README.txt### - -Simple text file containing information about Mayaseed. - - -###scripts (directory)### - -The scripts directory contain all the functions, classes and attribute editor templates plus a few other things. - - -###about.txt### - -**about.txt** contains the text that the **About Mayaseed** dialogue displays. - - -###AEms\_environmentTemplate.mel### - -This file describes how the ms_environment node is displayed in the attribute editor. - - -###AEms\_renderSettingsTemplate.mel### - -This file describes how the ms_renderSettings node is displayed in the attribute editor. - - -###ms\_commands.py### - -**ms\_commands.py** contains commands used in the Mayaseed menu and utility variables,functions and classes for the **ms\_export** module. - - -###ms\_export.py### - -**ms\_export.py** contains the **export()** function that does most of the hard work in translating the maya scene to the .appleseed format. Broadly speaking a **writeXML** object is handed down through each XML entity in the appleseed scene description writing to the file as it goes. - - -###ms\_menu### - -This python script sets up the Mayaseed menu and is called by **mayaseed.py** in the **initializePlugin()** function. The **uninitializePlugin()** function also calls this module to delete the Mayaseed menu when the plugin is unloaded. - - diff --git a/sandbox/extras/maya/graphics/mayaseed_graphic.png b/sandbox/extras/maya/graphics/mayaseed.png similarity index 100% rename from sandbox/extras/maya/graphics/mayaseed_graphic.png rename to sandbox/extras/maya/graphics/mayaseed.png diff --git a/sandbox/extras/maya/plugins/mayaseed.py b/sandbox/extras/maya/plugins/mayaseed.py index f79f5caada..5ca4ce44b6 100644 --- a/sandbox/extras/maya/plugins/mayaseed.py +++ b/sandbox/extras/maya/plugins/mayaseed.py @@ -1,15 +1,17 @@ -# Copyright (c) 2012 Jonathan Topf +# +# Copyright (c) 2012 Jonathan Topf +# # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: - +# # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. - +# # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -17,12 +19,15 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. +# -import sys + +import sys import maya.OpenMaya as OpenMaya import maya.OpenMayaMPx as OpenMayaMPx import maya.OpenMayaRender as OpenMayaRender import maya.OpenMayaUI as OpenMayaUI +import maya.cmds as cmds import inspect import os import os.path @@ -33,38 +38,41 @@ import ms_menu -#**************************************************************************************************************************************************************************************************** -# ms_renderSettings node **************************************************************************************************************************************************************************** -#**************************************************************************************************************************************************************************************************** + +#-------------------------------------------------------------------------------------------------- +# ms_renderSettings node. +#-------------------------------------------------------------------------------------------------- ms_renderSettings_nodeTypeName = "ms_renderSettings" ms_renderSettings_nodeTypeId = OpenMaya.MTypeId(0x00333) class ms_renderSettings(OpenMayaMPx.MPxNode): - def __init__(self): OpenMayaMPx.MPxNode.__init__(self) def ms_renderSettings_nodeCreator(): - return OpenMayaMPx.asMPxPtr( ms_renderSettings() ) + return OpenMayaMPx.asMPxPtr(ms_renderSettings()) def ms_renderSettings_nodeInitializer(): - #define attributes #export button -------------------------------------------- export_button_string = OpenMaya.MFnStringData().create("/") export_button_string_Attr = OpenMaya.MFnTypedAttribute() - ms_renderSettings.export_button = export_button_string_Attr.create("export", "export", OpenMaya.MFnData.kString, export_button_string) + ms_renderSettings.export_button = export_button_string_Attr.create("export", "export", OpenMaya.MFnData.kString, export_button_string) - #export file settings ------------------------------------- - #output directory attribute - output_dir_string = OpenMaya.MFnStringData().create("/") + # output directory + output_dir_string = OpenMaya.MFnStringData().create(os.path.join("", "Mayaseed")) output_dir_Attr = OpenMaya.MFnTypedAttribute() - ms_renderSettings.output_dir = output_dir_Attr.create("output_directory", "out_dir", OpenMaya.MFnData.kString, output_dir_string) - #output file attribute - output_file_string = OpenMaya.MFnStringData().create("file_name.#.appleseed") + ms_renderSettings.output_dir = output_dir_Attr.create("output_directory", "out_dir", OpenMaya.MFnData.kString, output_dir_string) + + # output file + output_file_string = OpenMaya.MFnStringData().create(".#.appleseed") output_file_Attr = OpenMaya.MFnTypedAttribute() - ms_renderSettings.output_file = output_file_Attr.create("output_file", "out_file", OpenMaya.MFnData.kString, output_file_string) + ms_renderSettings.output_file = output_file_Attr.create("output_file", "out_file", OpenMaya.MFnData.kString, output_file_string) + + #export maya lights + export_maya_lights_nAttr = OpenMaya.MFnNumericAttribute() + ms_renderSettings.export_maya_lights = export_maya_lights_nAttr.create("export_maya_lights", "export_maya_lights", OpenMaya.MFnNumericData.kBoolean, True) #convert textures to exr convert_textures_to_exr_nAttr = OpenMaya.MFnNumericAttribute() @@ -74,23 +82,37 @@ def ms_renderSettings_nodeInitializer(): convert_shading_nodes_to_textures_nAttr = OpenMaya.MFnNumericAttribute() ms_renderSettings.convert_shading_nodes_to_textures = convert_shading_nodes_to_textures_nAttr.create("convert_shading_nodes_to_textures", "convert_shading_nodes", OpenMaya.MFnNumericData.kBoolean, True) - #overwrite existing exrs - overwrite_existing_exrs_nAttr = OpenMaya.MFnNumericAttribute() - ms_renderSettings.overwrite_existing_exrs = overwrite_existing_exrs_nAttr.create("overwrite_existing_exrs", "overwrite_exrs", OpenMaya.MFnNumericData.kBoolean, True) + # overwrite existing textures + overwrite_existing_textures_nAttr = OpenMaya.MFnNumericAttribute() + ms_renderSettings.overwrite_existing_textures = overwrite_existing_textures_nAttr.create("overwrite_existing_textures", "overwrite_exrs", OpenMaya.MFnNumericData.kBoolean, True) + + #export camera blur + export_camera_blur_nAttr = OpenMaya.MFnNumericAttribute() + ms_renderSettings.export_camera_blur = export_camera_blur_nAttr.create("export_camera_blur", "camera_blur", OpenMaya.MFnNumericData.kBoolean, True) - #export motion blur - export_motion_blur_nAttr = OpenMaya.MFnNumericAttribute() - ms_renderSettings.export_motion_blur = export_motion_blur_nAttr.create("export_motion_blur", "motion_blur", OpenMaya.MFnNumericData.kBoolean, True) + #export transformation blur + export_transformation_blur_nAttr = OpenMaya.MFnNumericAttribute() + ms_renderSettings.export_transformation_blur = export_transformation_blur_nAttr.create("export_transformation_blur", "transformation_blur", OpenMaya.MFnNumericData.kBoolean, True) + + #export deformation blur + export_deformation_blur_nAttr = OpenMaya.MFnNumericAttribute() + ms_renderSettings.export_deformation_blur = export_deformation_blur_nAttr.create("export_deformation_blur", "deformation_blur", OpenMaya.MFnNumericData.kBoolean, True) + + #motion samples + motion_samples_AttrInt = OpenMaya.MFnNumericAttribute() + ms_renderSettings.motion_samples = motion_samples_AttrInt.create("motion_samples", "motion_samples", OpenMaya.MFnNumericData.kInt, 2) + motion_samples_AttrInt.setHidden(False) + motion_samples_AttrInt.setKeyable(True) #shutter open time shutter_open_AttrFloat = OpenMaya.MFnNumericAttribute() - ms_renderSettings.shutter_open = shutter_open_AttrFloat.create("shutter_open_time", "shutter_open", OpenMaya.MFnNumericData.kFloat, 0) + ms_renderSettings.shutter_open_time = shutter_open_AttrFloat.create("shutter_open_time", "shutter_open_time", OpenMaya.MFnNumericData.kFloat, 0) shutter_open_AttrFloat.setHidden(False) shutter_open_AttrFloat.setKeyable(True) #shutter close time shutter_close_AttrFloat = OpenMaya.MFnNumericAttribute() - ms_renderSettings.shutter_close = shutter_close_AttrFloat.create("shutter_close_time", "shutter_close", OpenMaya.MFnNumericData.kFloat, 1) + ms_renderSettings.shutter_close_time = shutter_close_AttrFloat.create("shutter_close_time", "shutter_close_time", OpenMaya.MFnNumericData.kFloat, 1) shutter_close_AttrFloat.setHidden(False) shutter_close_AttrFloat.setKeyable(True) @@ -110,6 +132,10 @@ def ms_renderSettings_nodeInitializer(): end_frame_AttrInt.setHidden(False) end_frame_AttrInt.setKeyable(False) + #export animated textures + export_animated_textures_nAttr = OpenMaya.MFnNumericAttribute() + ms_renderSettings.export_animated_textures = export_animated_textures_nAttr .create("export_animated_textures", "animated_textures", OpenMaya.MFnNumericData.kBoolean, False) + #environent ----------------------------------------------- #environment message environment_msgAttr = OpenMaya.MFnMessageAttribute() @@ -125,14 +151,12 @@ def ms_renderSettings_nodeInitializer(): #interpret sets as assemblies bool attribute interpret_sets_as_assemblies_nAttr = OpenMaya.MFnNumericAttribute() ms_renderSettings.interpret_sets_as_assemblies = interpret_sets_as_assemblies_nAttr.create("interpret_sets_as_assemblies", "sets_as_assemblies", OpenMaya.MFnNumericData.kBoolean) - #double sided shading bool attribute - double_sided_shading_nAttr = OpenMaya.MFnNumericAttribute() - ms_renderSettings.double_sided_shading = double_sided_shading_nAttr.create("double_sided_shading", "double_shade", OpenMaya.MFnNumericData.kBoolean) - + #output --------------------------------------------------- #camera camera_msgAttr = OpenMaya.MFnMessageAttribute() ms_renderSettings.camera = camera_msgAttr.create("camera", "cam") + #color space color_space_enumAttr = OpenMaya.MFnEnumAttribute() ms_renderSettings.color_space = color_space_enumAttr.create("color_space", "col_space") @@ -143,126 +167,231 @@ def ms_renderSettings_nodeInitializer(): #resolution width samples width_AttrInt = OpenMaya.MFnNumericAttribute() - ms_renderSettings.width = width_AttrInt.create("resolution_width", "width", OpenMaya.MFnNumericData.kInt, 1280) + ms_renderSettings.width = width_AttrInt.create("frame_width", "width", OpenMaya.MFnNumericData.kInt, 1280) width_AttrInt.setHidden(False) width_AttrInt.setKeyable(True) #resolution height samples height_AttrInt = OpenMaya.MFnNumericAttribute() - ms_renderSettings.height = height_AttrInt.create("resolution_height", "height", OpenMaya.MFnNumericData.kInt, 720) + ms_renderSettings.height = height_AttrInt.create("frame_height", "height", OpenMaya.MFnNumericData.kInt, 720) height_AttrInt.setHidden(False) height_AttrInt.setKeyable(True) - - #configurations ------------------------------------------- - #custom interactive config - export_custom_interactive_config_nAttr = OpenMaya.MFnNumericAttribute() - ms_renderSettings.export_custom_interactive_config = export_custom_interactive_config_nAttr.create("export_custom_interactive_config", "export_interactive", OpenMaya.MFnNumericData.kBoolean) - #lighting engine - custom_interactive_config_lghting_engine_enumAttr = OpenMaya.MFnEnumAttribute() - ms_renderSettings.custom_interactive_config_lghting_engine = custom_interactive_config_lghting_engine_enumAttr.create("interactive_lighting_engine", "interactive_engine") - custom_interactive_config_lghting_engine_enumAttr.addField("Path Tracing", 0) - custom_interactive_config_lghting_engine_enumAttr.addField("Distributed Ray Tracing", 1) - #min samples - custom_interactive_config_min_samples_AttrInt = OpenMaya.MFnNumericAttribute() - ms_renderSettings.custom_interactive_config_min_samples = custom_interactive_config_min_samples_AttrInt.create("interactive_min_samples", "interactive_min_samples", OpenMaya.MFnNumericData.kInt, 1) - custom_interactive_config_min_samples_AttrInt.setHidden(False) - custom_interactive_config_min_samples_AttrInt.setKeyable(True) - #max samples - custom_interactive_config_max_samples_AttrInt = OpenMaya.MFnNumericAttribute() - ms_renderSettings.custom_interactive_config_max_samples = custom_interactive_config_max_samples_AttrInt.create("interactive_max_samples", "interactive_max_samples", OpenMaya.MFnNumericData.kInt, 4) - custom_interactive_config_max_samples_AttrInt.setHidden(False) - custom_interactive_config_max_samples_AttrInt.setKeyable(True) - #max ray depth - custom_interactive_config_max_ray_depth_AttrInt = OpenMaya.MFnNumericAttribute() - ms_renderSettings.custom_interactive_config_max_ray_depth = custom_interactive_config_max_ray_depth_AttrInt.create("interactive_max_ray_depth", "interactive_ray_depth", OpenMaya.MFnNumericData.kInt, 4) - custom_interactive_config_max_ray_depth_AttrInt.setHidden(False) - custom_interactive_config_max_ray_depth_AttrInt.setKeyable(True) - #light samples - custom_interactive_config_light_samples_AttrInt = OpenMaya.MFnNumericAttribute() - ms_renderSettings.custom_interactive_config_light_samples = custom_interactive_config_light_samples_AttrInt.create("interactive_light_samples", "interactive_light_samples", OpenMaya.MFnNumericData.kInt, 16) - custom_interactive_config_light_samples_AttrInt.setHidden(False) - custom_interactive_config_light_samples_AttrInt.setKeyable(True) - #custom final config export_custom_final_config_nAttr = OpenMaya.MFnNumericAttribute() - ms_renderSettings.export_custom_final_config = export_custom_final_config_nAttr.create("export_custom_final_config", "export_final", OpenMaya.MFnNumericData.kBoolean) + ms_renderSettings.export_custom_final_config = export_custom_final_config_nAttr.create("export_custom_final_config", "export_final", OpenMaya.MFnNumericData.kBoolean, True) + #lighting engine - custom_final_config_lghting_engine_enumAttr = OpenMaya.MFnEnumAttribute() - ms_renderSettings.custom_final_config_lghting_engine = custom_final_config_lghting_engine_enumAttr.create("final_lighting_engine", "final_engine") - custom_final_config_lghting_engine_enumAttr.addField("Path Tracing", 0) - custom_final_config_lghting_engine_enumAttr.addField("Distributed Ray Tracing", 1) - #min samples - custom_final_config_min_samples_AttrInt = OpenMaya.MFnNumericAttribute() - ms_renderSettings.custom_final_config_min_samples = custom_final_config_min_samples_AttrInt.create("final_min_samples", "final_min_samples", OpenMaya.MFnNumericData.kInt, 1) - custom_final_config_min_samples_AttrInt.setHidden(False) - custom_final_config_min_samples_AttrInt.setKeyable(True) - #max samples - custom_final_config_max_samples_AttrInt = OpenMaya.MFnNumericAttribute() - ms_renderSettings.custom_final_config_max_samples = custom_final_config_max_samples_AttrInt.create("final_max_samples", "final_max_samples", OpenMaya.MFnNumericData.kInt, 4) - custom_final_config_max_samples_AttrInt.setHidden(False) - custom_final_config_max_samples_AttrInt.setKeyable(True) - #max ray depth - custom_final_config_max_ray_depth_AttrInt = OpenMaya.MFnNumericAttribute() - ms_renderSettings.custom_final_config_max_ray_depth = custom_final_config_max_ray_depth_AttrInt.create("final_max_ray_depth", "final_ray_depth", OpenMaya.MFnNumericData.kInt, 4) - custom_final_config_max_ray_depth_AttrInt.setHidden(False) - custom_final_config_max_ray_depth_AttrInt.setKeyable(True) - #light samples - custom_final_config_light_samples_AttrInt = OpenMaya.MFnNumericAttribute() - ms_renderSettings.custom_final_config_light_samples = custom_final_config_light_samples_AttrInt.create("final_light_samples", "final_light_samples", OpenMaya.MFnNumericData.kInt, 16) - custom_final_config_light_samples_AttrInt.setHidden(False) - custom_final_config_light_samples_AttrInt.setKeyable(True) + final_config_lighting_engine_enumAttr = OpenMaya.MFnEnumAttribute() + ms_renderSettings.final_config_lighting_engine = final_config_lighting_engine_enumAttr.create("final_lighting_engine", "final_engine") + final_config_lighting_engine_enumAttr.addField("Path Tracing", 0) + final_config_lighting_engine_enumAttr.addField("Distributed Ray Tracing", 1) + + #min_samples + min_samples_AttrInt = OpenMaya.MFnNumericAttribute() + ms_renderSettings.min_samples = min_samples_AttrInt.create("min_samples", "min_samples", OpenMaya.MFnNumericData.kInt, 1) + min_samples_AttrInt.setHidden(False) + min_samples_AttrInt.setKeyable(True) + + #max_samples + max_samples_AttrInt = OpenMaya.MFnNumericAttribute() + ms_renderSettings.max_samples = max_samples_AttrInt.create("max_samples", "max_samples", OpenMaya.MFnNumericData.kInt, 1) + max_samples_AttrInt.setHidden(False) + max_samples_AttrInt.setKeyable(True) + + #drt_settings + #dl_bsdf_samples + drt_dl_bsdf_samples_AttrInt = OpenMaya.MFnNumericAttribute() + ms_renderSettings.drt_dl_bsdf_samples = drt_dl_bsdf_samples_AttrInt.create("drt_dl_bsdf_samples", "drt_dl_bsdf_samples", OpenMaya.MFnNumericData.kInt, 1) + drt_dl_bsdf_samples_AttrInt.setHidden(False) + drt_dl_bsdf_samples_AttrInt.setKeyable(True) + + #dl_light_samples + drt_dl_light_samples_AttrInt = OpenMaya.MFnNumericAttribute() + ms_renderSettings.drt_dl_light_samples = drt_dl_light_samples_AttrInt.create("drt_dl_light_samples", "drt_dl_light_samples", OpenMaya.MFnNumericData.kInt, 1) + drt_dl_light_samples_AttrInt.setHidden(False) + drt_dl_light_samples_AttrInt.setKeyable(True) + + #enable_ibl + drt_enable_iblnAttr = OpenMaya.MFnNumericAttribute() + ms_renderSettings.drt_enable_ibl = drt_enable_iblnAttr.create("drt_enable_ibl", "drt_enable_ibl", OpenMaya.MFnNumericData.kBoolean, True) + + #ibl_bsdf_samples + drt_ibl_bsdf_samples_AttrInt = OpenMaya.MFnNumericAttribute() + ms_renderSettings.drt_ibl_bsdf_samples = drt_ibl_bsdf_samples_AttrInt.create("drt_ibl_bsdf_samples", "drt_ibl_bsdf_samples", OpenMaya.MFnNumericData.kInt, 1) + drt_ibl_bsdf_samples_AttrInt.setHidden(False) + drt_ibl_bsdf_samples_AttrInt.setKeyable(True) + + #ibl_env_samples + drt_ibl_env_samples_AttrInt = OpenMaya.MFnNumericAttribute() + ms_renderSettings.drt_ibl_env_samples = drt_ibl_env_samples_AttrInt.create("drt_ibl_env_samples", "drt_ibl_env_samples", OpenMaya.MFnNumericData.kInt, 1) + drt_ibl_env_samples_AttrInt.setHidden(False) + drt_ibl_env_samples_AttrInt.setKeyable(True) + + #max_path_length + drt_max_path_length_AttrInt = OpenMaya.MFnNumericAttribute() + ms_renderSettings.drt_max_path_length = drt_max_path_length_AttrInt.create("drt_max_path_length", "drt_max_path_length", OpenMaya.MFnNumericData.kInt, 0) + drt_max_path_length_AttrInt.setHidden(False) + drt_max_path_length_AttrInt.setKeyable(True) + + #rr_min_path_length + drt_rr_min_path_length_AttrInt = OpenMaya.MFnNumericAttribute() + ms_renderSettings.drt_rr_min_path_length = drt_rr_min_path_length_AttrInt.create("drt_rr_min_path_length", "drt_rr_min_path_length", OpenMaya.MFnNumericData.kInt, 1) + drt_rr_min_path_length_AttrInt.setHidden(False) + drt_rr_min_path_length_AttrInt.setKeyable(True) + + #pt settings + #dl_light_samples + pt_dl_light_samples_AttrInt = OpenMaya.MFnNumericAttribute() + ms_renderSettings.pt_dl_light_samples = pt_dl_light_samples_AttrInt.create("pt_dl_light_samples", "pt_dl_light_samples", OpenMaya.MFnNumericData.kInt, 1) + pt_dl_light_samples_AttrInt.setHidden(False) + pt_dl_light_samples_AttrInt.setKeyable(True) + + #enable_caustics + pt_enable_causticsnAttr = OpenMaya.MFnNumericAttribute() + ms_renderSettings.pt_enable_caustics = pt_enable_causticsnAttr.create("pt_enable_caustics", "pt_enable_caustics", OpenMaya.MFnNumericData.kBoolean, False) + + #enable_dl + pt_enable_dlnAttr = OpenMaya.MFnNumericAttribute() + ms_renderSettings.pt_enable_dl = pt_enable_dlnAttr.create("pt_enable_dl", "pt_enable_dl", OpenMaya.MFnNumericData.kBoolean, True) + + #enable_ibl + pt_enable_iblnAttr = OpenMaya.MFnNumericAttribute() + ms_renderSettings.pt_enable_ibl = pt_enable_iblnAttr.create("pt_enable_ibl", "pt_enable_ibl", OpenMaya.MFnNumericData.kBoolean, True) + + #ibl_bsdf_samples + pt_ibl_bsdf_samples_AttrInt = OpenMaya.MFnNumericAttribute() + ms_renderSettings.pt_ibl_bsdf_samples = pt_ibl_bsdf_samples_AttrInt.create("pt_ibl_bsdf_samples", "pt_ibl_bsdf_samples", OpenMaya.MFnNumericData.kInt, 1) + pt_ibl_bsdf_samples_AttrInt.setHidden(False) + pt_ibl_bsdf_samples_AttrInt.setKeyable(True) + + #ibl_env_samples + pt_ibl_env_samples_AttrInt = OpenMaya.MFnNumericAttribute() + ms_renderSettings.pt_ibl_env_samples = pt_ibl_env_samples_AttrInt.create("pt_ibl_env_samples", "pt_ibl_env_samples", OpenMaya.MFnNumericData.kInt, 1) + pt_ibl_env_samples_AttrInt.setHidden(False) + pt_ibl_env_samples_AttrInt.setKeyable(True) + + #max_path_length + pt_max_path_length_AttrInt = OpenMaya.MFnNumericAttribute() + ms_renderSettings.pt_max_path_length = pt_max_path_length_AttrInt.create("pt_max_path_length", "pt_max_path_length", OpenMaya.MFnNumericData.kInt, 3) + pt_max_path_length_AttrInt.setHidden(False) + pt_max_path_length_AttrInt.setKeyable(True) + + #next_event_estimation + pt_next_event_estimationnAttr = OpenMaya.MFnNumericAttribute() + ms_renderSettings.pt_next_event_estimation = pt_next_event_estimationnAttr.create("pt_next_event_estimation", "pt_next_event_estimation", OpenMaya.MFnNumericData.kBoolean, True) + + #rr_min_path_length + pt_rr_min_path_length_AttrInt = OpenMaya.MFnNumericAttribute() + ms_renderSettings.pt_rr_min_path_length = pt_rr_min_path_length_AttrInt.create("pt_rr_min_path_length", "pt_rr_min_path_length", OpenMaya.MFnNumericData.kInt, 3) + pt_rr_min_path_length_AttrInt.setHidden(False) + pt_rr_min_path_length_AttrInt.setKeyable(True) + + #generic tile renderer + #filter_size + gtr_filter_size_AttrInt = OpenMaya.MFnNumericAttribute() + ms_renderSettings.gtr_filter_size = gtr_filter_size_AttrInt.create("gtr_filter_size", "gtr_filter_size", OpenMaya.MFnNumericData.kInt, 2) + gtr_filter_size_AttrInt.setHidden(False) + gtr_filter_size_AttrInt.setKeyable(True) + + #min_samples + gtr_min_samples_AttrInt = OpenMaya.MFnNumericAttribute() + ms_renderSettings.gtr_min_samples = gtr_min_samples_AttrInt.create("gtr_min_samples", "gtr_min_samples", OpenMaya.MFnNumericData.kInt, 8) + gtr_min_samples_AttrInt.setHidden(False) + gtr_min_samples_AttrInt.setKeyable(True) + + #max_samples + gtr_max_samples_AttrInt = OpenMaya.MFnNumericAttribute() + ms_renderSettings.gtr_max_samples = gtr_max_samples_AttrInt.create("gtr_max_samples", "gtr_max_samples", OpenMaya.MFnNumericData.kInt, 64) + gtr_max_samples_AttrInt.setHidden(False) + gtr_max_samples_AttrInt.setKeyable(True) + + #max_contrast + gtr_max_contrast_AttrFloat = OpenMaya.MFnNumericAttribute() + ms_renderSettings.gtr_max_contrast = gtr_max_contrast_AttrFloat.create("gtr_max_contrast", "gtr_max_contrast", OpenMaya.MFnNumericData.kFloat, 0.004) + gtr_max_contrast_AttrFloat.setHidden(False) + gtr_max_contrast_AttrFloat.setKeyable(True) + + #max_variation + gtr_max_variation_AttrFloat = OpenMaya.MFnNumericAttribute() + ms_renderSettings.gtr_max_variation = gtr_max_variation_AttrFloat.create("gtr_max_variation", "gtr_max_variation", OpenMaya.MFnNumericData.kFloat, 0.15) + gtr_max_variation_AttrFloat.setHidden(False) + gtr_max_variation_AttrFloat.setKeyable(True) + + #sampler enum + gtr_sampler_enumAttr = OpenMaya.MFnEnumAttribute() + ms_renderSettings.gtr_sampler = gtr_sampler_enumAttr.create("gtr_sampler", "gtr_sampler") + gtr_sampler_enumAttr.addField("uniform", 0) + gtr_sampler_enumAttr.addField("adaptive", 1) + + #profile export + profile_export_nAttr = OpenMaya.MFnNumericAttribute() + ms_renderSettings.profile_export = profile_export_nAttr.create("profile_export", "profile_export", OpenMaya.MFnNumericData.kBoolean, False) # add attributes - try: - ms_renderSettings.addAttribute(ms_renderSettings.export_button) - - ms_renderSettings.addAttribute(ms_renderSettings.output_dir) - ms_renderSettings.addAttribute(ms_renderSettings.output_file) - ms_renderSettings.addAttribute(ms_renderSettings.convert_shading_nodes_to_textures) - ms_renderSettings.addAttribute(ms_renderSettings.convert_textures_to_exr) - ms_renderSettings.addAttribute(ms_renderSettings.overwrite_existing_exrs) - ms_renderSettings.addAttribute(ms_renderSettings.export_motion_blur) - ms_renderSettings.addAttribute(ms_renderSettings.shutter_open) - ms_renderSettings.addAttribute(ms_renderSettings.shutter_close) - ms_renderSettings.addAttribute(ms_renderSettings.export_animation) - ms_renderSettings.addAttribute(ms_renderSettings.start_frame) - ms_renderSettings.addAttribute(ms_renderSettings.end_frame) - - ms_renderSettings.addAttribute(ms_renderSettings.environment) - ms_renderSettings.addAttribute(ms_renderSettings.export_all_cameras) - ms_renderSettings.addAttribute(ms_renderSettings.export_all_cameras_as_thin_lens) - - ms_renderSettings.addAttribute(ms_renderSettings.interpret_sets_as_assemblies) - ms_renderSettings.addAttribute(ms_renderSettings.double_sided_shading) - ms_renderSettings.addAttribute(ms_renderSettings.camera) - ms_renderSettings.addAttribute(ms_renderSettings.color_space) - ms_renderSettings.addAttribute(ms_renderSettings.width) - ms_renderSettings.addAttribute(ms_renderSettings.height) - - ms_renderSettings.addAttribute(ms_renderSettings.export_custom_interactive_config) - ms_renderSettings.addAttribute(ms_renderSettings.custom_interactive_config_lghting_engine) - ms_renderSettings.addAttribute(ms_renderSettings.custom_interactive_config_min_samples) - ms_renderSettings.addAttribute(ms_renderSettings.custom_interactive_config_max_samples) - ms_renderSettings.addAttribute(ms_renderSettings.custom_interactive_config_max_ray_depth) - ms_renderSettings.addAttribute(ms_renderSettings.custom_interactive_config_light_samples) - - ms_renderSettings.addAttribute(ms_renderSettings.export_custom_final_config) - ms_renderSettings.addAttribute(ms_renderSettings.custom_final_config_lghting_engine) - ms_renderSettings.addAttribute(ms_renderSettings.custom_final_config_min_samples) - ms_renderSettings.addAttribute(ms_renderSettings.custom_final_config_max_samples) - ms_renderSettings.addAttribute(ms_renderSettings.custom_final_config_max_ray_depth) - ms_renderSettings.addAttribute(ms_renderSettings.custom_final_config_light_samples) - except: - sys.stderr.write( "Failed to create attributes of %s node\n" % ms_renderSettings_nodeTypeName ) - - - -#**************************************************************************************************************************************************************************************************** -# ms_environment node ******************************************************************************************************************************************************************************* -#**************************************************************************************************************************************************************************************************** - - + ms_renderSettings.addAttribute(ms_renderSettings.export_button) + + ms_renderSettings.addAttribute(ms_renderSettings.output_dir) + ms_renderSettings.addAttribute(ms_renderSettings.output_file) + ms_renderSettings.addAttribute(ms_renderSettings.convert_shading_nodes_to_textures) + ms_renderSettings.addAttribute(ms_renderSettings.export_maya_lights) + ms_renderSettings.addAttribute(ms_renderSettings.convert_textures_to_exr) + ms_renderSettings.addAttribute(ms_renderSettings.overwrite_existing_textures) + ms_renderSettings.addAttribute(ms_renderSettings.export_camera_blur) + ms_renderSettings.addAttribute(ms_renderSettings.export_transformation_blur) + ms_renderSettings.addAttribute(ms_renderSettings.export_deformation_blur) + ms_renderSettings.addAttribute(ms_renderSettings.motion_samples) + ms_renderSettings.addAttribute(ms_renderSettings.shutter_open_time) + ms_renderSettings.addAttribute(ms_renderSettings.shutter_close_time) + ms_renderSettings.addAttribute(ms_renderSettings.export_animation) + ms_renderSettings.addAttribute(ms_renderSettings.start_frame) + ms_renderSettings.addAttribute(ms_renderSettings.end_frame) + ms_renderSettings.addAttribute(ms_renderSettings.export_animated_textures) + + ms_renderSettings.addAttribute(ms_renderSettings.environment) + ms_renderSettings.addAttribute(ms_renderSettings.export_all_cameras) + ms_renderSettings.addAttribute(ms_renderSettings.export_all_cameras_as_thin_lens) + + ms_renderSettings.addAttribute(ms_renderSettings.interpret_sets_as_assemblies) + ms_renderSettings.addAttribute(ms_renderSettings.camera) + ms_renderSettings.addAttribute(ms_renderSettings.color_space) + ms_renderSettings.addAttribute(ms_renderSettings.width) + ms_renderSettings.addAttribute(ms_renderSettings.height) + + ms_renderSettings.addAttribute(ms_renderSettings.export_custom_final_config) + + ms_renderSettings.addAttribute(ms_renderSettings.final_config_lighting_engine) + ms_renderSettings.addAttribute(ms_renderSettings.min_samples) + ms_renderSettings.addAttribute(ms_renderSettings.max_samples) + + ms_renderSettings.addAttribute(ms_renderSettings.drt_dl_bsdf_samples) + ms_renderSettings.addAttribute(ms_renderSettings.drt_dl_light_samples) + ms_renderSettings.addAttribute(ms_renderSettings.drt_enable_ibl) + ms_renderSettings.addAttribute(ms_renderSettings.drt_ibl_bsdf_samples) + ms_renderSettings.addAttribute(ms_renderSettings.drt_ibl_env_samples) + ms_renderSettings.addAttribute(ms_renderSettings.drt_max_path_length) + ms_renderSettings.addAttribute(ms_renderSettings.drt_rr_min_path_length) + ms_renderSettings.addAttribute(ms_renderSettings.pt_dl_light_samples) + ms_renderSettings.addAttribute(ms_renderSettings.pt_enable_caustics) + ms_renderSettings.addAttribute(ms_renderSettings.pt_enable_dl) + ms_renderSettings.addAttribute(ms_renderSettings.pt_enable_ibl) + ms_renderSettings.addAttribute(ms_renderSettings.pt_ibl_bsdf_samples) + ms_renderSettings.addAttribute(ms_renderSettings.pt_ibl_env_samples) + ms_renderSettings.addAttribute(ms_renderSettings.pt_max_path_length) + ms_renderSettings.addAttribute(ms_renderSettings.pt_next_event_estimation) + ms_renderSettings.addAttribute(ms_renderSettings.pt_rr_min_path_length) + ms_renderSettings.addAttribute(ms_renderSettings.gtr_filter_size) + ms_renderSettings.addAttribute(ms_renderSettings.gtr_min_samples) + ms_renderSettings.addAttribute(ms_renderSettings.gtr_max_samples) + ms_renderSettings.addAttribute(ms_renderSettings.gtr_max_contrast) + ms_renderSettings.addAttribute(ms_renderSettings.gtr_max_variation) + ms_renderSettings.addAttribute(ms_renderSettings.gtr_sampler) + + ms_renderSettings.addAttribute(ms_renderSettings.profile_export) + +#-------------------------------------------------------------------------------------------------- +# ms_environment node. +#-------------------------------------------------------------------------------------------------- ms_environment_nodeTypeName = "ms_environment" ms_environment_nodeTypeId = OpenMaya.MTypeId(0x10211) @@ -272,16 +401,14 @@ def ms_renderSettings_nodeInitializer(): class ms_environment(OpenMayaMPx.MPxLocatorNode): def __init__(self): - OpenMayaMPx.MPxLocatorNode.__init__(self) def draw(self, view, path, style, status): - view.beginGL() glFT.glEnable(OpenMayaRender.MGL_BLEND) - #draw sphere + # draw sphere glFT.glBegin(OpenMayaRender.MGL_LINE_STRIP) glFT.glVertex3f(3.06161699787e-16, 5.0, -8.04061324838e-16) @@ -374,7 +501,7 @@ def draw(self, view, path, style, status): glFT.glVertex3f(0.5, -0.5, 3.0) glFT.glEnd() - #Appleseed logo + # appleseed logo glFT.glBegin(OpenMayaRender.MGL_LINE_STRIP) glFT.glVertex3f(4.99999602985, 6.24639415266, 0.0) @@ -453,97 +580,108 @@ def draw(self, view, path, style, status): glFT.glEnd() glFT.glDisable(OpenMayaRender.MGL_BLEND) - - view.endGL() + view.endGL() def ms_environment_nodeCreator(): return OpenMayaMPx.asMPxPtr(ms_environment()) def ms_environment_nodeInitializer(): - #environment type + # environment type model_enumAttr = OpenMaya.MFnEnumAttribute() ms_environment.model = model_enumAttr.create("model", "model") model_enumAttr.addField("Constant Environment", 0) - model_enumAttr.addField("Gradient Cnvironment", 1) + model_enumAttr.addField("Gradient Environment", 1) model_enumAttr.addField("Latitude Longitude Map", 2) model_enumAttr.addField("Mirrorball Map", 3) - #model_enumAttr.setDefault(0) - #constant exitance + + # constant exitance constant_exitance_nAttr = OpenMaya.MFnNumericAttribute() - ms_environment.constant_exitance = constant_exitance_nAttr.createColor( "constant_exitance", "const_exitance") - constant_exitance_nAttr.setDefault(0.5,0.5,0.5) + ms_environment.constant_exitance = constant_exitance_nAttr.createColor("constant_exitance", "const_exitance") + constant_exitance_nAttr.setDefault(0.5, 0.5, 0.5) constant_exitance_nAttr.setKeyable(True) - #gradient horizon exitance + + # gradient horizon exitance gradient_horizon_exitance_nAttr = OpenMaya.MFnNumericAttribute() - ms_environment.gradient_horizon_exitance = gradient_horizon_exitance_nAttr.createColor( "gradient_horizon_exitance", "grad_horizon_exitance") - gradient_horizon_exitance_nAttr.setDefault(0.5,0.5,0.5) + ms_environment.gradient_horizon_exitance = gradient_horizon_exitance_nAttr.createColor("gradient_horizon_exitance", "grad_horizon_exitance") + gradient_horizon_exitance_nAttr.setDefault(0.5, 0.5, 0.5) gradient_horizon_exitance_nAttr.setKeyable(True) - #gradient zenith exitance + + # gradient zenith exitance gradient_zenith_exitance_nAttr = OpenMaya.MFnNumericAttribute() - ms_environment.gradient_zenith_exitance = gradient_zenith_exitance_nAttr.createColor( "gradient_zenith_exitance", "grad_zenith_exitance") - gradient_zenith_exitance_nAttr.setDefault(0.5,0.5,0.5) + ms_environment.gradient_zenith_exitance = gradient_zenith_exitance_nAttr.createColor("gradient_zenith_exitance", "grad_zenith_exitance") + gradient_zenith_exitance_nAttr.setDefault(0.5, 0.5, 0.5) gradient_zenith_exitance_nAttr.setKeyable(True) - #latitude longitude exitance + + # latitude longitude exitance latitude_longitude_exitance_nAttr = OpenMaya.MFnNumericAttribute() - ms_environment.latitude_longitude_exitance = latitude_longitude_exitance_nAttr.createColor( "latitude_longitude_exitance", "lat_long_exitance") - latitude_longitude_exitance_nAttr.setDefault(0.5,0.5,0.5) + ms_environment.latitude_longitude_exitance = latitude_longitude_exitance_nAttr.createColor("latitude_longitude_exitance", "lat_long_exitance") + latitude_longitude_exitance_nAttr.setDefault(0.5, 0.5, 0.5) latitude_longitude_exitance_nAttr.setKeyable(True) - #mirror ball exitance + + # mirror ball exitance mirror_ball_exitance_nAttr = OpenMaya.MFnNumericAttribute() - ms_environment.mirror_ball_exitance = mirror_ball_exitance_nAttr.createColor( "mirror_ball_exitance", "mball_exitance") - mirror_ball_exitance_nAttr.setDefault(0.5,0.5,0.5) + ms_environment.mirror_ball_exitance = mirror_ball_exitance_nAttr.createColor("mirror_ball_exitance", "mball_exitance") + mirror_ball_exitance_nAttr.setDefault(0.5, 0.5, 0.5) mirror_ball_exitance_nAttr.setKeyable(True) - # add attribute + # exitance multiplier + exitance_multiplier_AttrFloat = OpenMaya.MFnNumericAttribute() + ms_environment.exitance_multiplier = exitance_multiplier_AttrFloat.create("exitance_multiplier", "exitance_multiplier", OpenMaya.MFnNumericData.kFloat, 1) + exitance_multiplier_AttrFloat.setHidden(False) + exitance_multiplier_AttrFloat.setKeyable(True) + + # add attributes try: - ms_environment.addAttribute( ms_environment.model ) - ms_environment.addAttribute( ms_environment.constant_exitance ) - ms_environment.addAttribute( ms_environment.gradient_horizon_exitance ) - ms_environment.addAttribute( ms_environment.gradient_zenith_exitance ) - ms_environment.addAttribute( ms_environment.latitude_longitude_exitance ) - ms_environment.addAttribute( ms_environment.mirror_ball_exitance ) + ms_environment.addAttribute(ms_environment.model) + ms_environment.addAttribute(ms_environment.constant_exitance) + ms_environment.addAttribute(ms_environment.gradient_horizon_exitance) + ms_environment.addAttribute(ms_environment.gradient_zenith_exitance) + ms_environment.addAttribute(ms_environment.latitude_longitude_exitance) + ms_environment.addAttribute(ms_environment.mirror_ball_exitance) + ms_environment.addAttribute(ms_environment.exitance_multiplier) except: - sys.stderr.write( "Failed to create attributes of %s node", kPluginNodeTypeName ) + sys.stderr.write("Failed to create attributes of %s node", kPluginNodeTypeName) - return OpenMaya.MStatus.kSuccess - -#**************************************************************************************************************************************************************************************************** -# initialize nodes node ***************************************************************************************************************************************************************************** -#**************************************************************************************************************************************************************************************************** + +#-------------------------------------------------------------------------------------------------- +# ms_environment node. +#-------------------------------------------------------------------------------------------------- def initializePlugin(obj): - #register nodes plugin = OpenMayaMPx.MFnPlugin(obj) + try: plugin.registerNode(ms_environment_nodeTypeName, ms_environment_nodeTypeId, ms_environment_nodeCreator, ms_environment_nodeInitializer, OpenMayaMPx.MPxNode.kLocatorNode) except: - sys.stderr.write( "Failed to register node: %s" % ms_environment_nodeTypeName) - + sys.stderr.write("Failed to register node: %s" % ms_environment_nodeTypeName) + try: - plugin.registerNode( ms_renderSettings_nodeTypeName, ms_renderSettings_nodeTypeId, ms_renderSettings_nodeCreator, ms_renderSettings_nodeInitializer ) + plugin.registerNode(ms_renderSettings_nodeTypeName, ms_renderSettings_nodeTypeId, ms_renderSettings_nodeCreator, ms_renderSettings_nodeInitializer) except: - sys.stderr.write( "Failed to register command: %s\n" % ms_renderSettings_nodeTypeName ) - - #create menu + sys.stderr.write("Failed to register node: %s\n" % ms_renderSettings_nodeTypeName) + + # load objExport plugin if its not loaded yet + try: + if not cmds.pluginInfo('objExport', query=True, loaded=True): + cmds.loadPlugin('objExport') + except: + print 'objExport plugin could not be loaded, cannot load mayaseed' + ms_menu.createMenu() ms_menu.buildMenu() def uninitializePlugin(obj): - #deregister nodes plugin = OpenMayaMPx.MFnPlugin(obj) + try: plugin.deregisterNode(ms_environment_nodeTypeId) except: - sys.stderr.write( "Failed to deregister node: %s" % ms_environment_nodeTypeName) + sys.stderr.write("Failed to deregister node: %s" % ms_environment_nodeTypeName) try: - plugin.deregisterNode( ms_renderSettings_nodeTypeId ) + plugin.deregisterNode(ms_renderSettings_nodeTypeId) except: - sys.stderr.write( "Failed to unregister node: %s\n" % ms_renderSettings_nodeTypeName ) + sys.stderr.write("Failed to deregister node: %s\n" % ms_renderSettings_nodeTypeName) - #delete menu ms_menu.deleteMenu() - - - diff --git a/sandbox/extras/maya/plugins/ms_appleseed_material.py b/sandbox/extras/maya/plugins/ms_appleseed_material.py new file mode 100644 index 0000000000..6b88209bae --- /dev/null +++ b/sandbox/extras/maya/plugins/ms_appleseed_material.py @@ -0,0 +1,260 @@ + +# +# Copyright (c) 2012 Jonathan Topf +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +# + +# + +import sys +import maya.OpenMaya as OpenMaya +import maya.OpenMayaMPx as OpenMayaMPx +import maya.cmds as cmds + +# Plug-in information: +kPluginNodeName = 'ms_appleseed_material' +kPluginNodeClassify = 'shader/surface' +kPluginNodeId = OpenMaya.MTypeId(0x00334) + +########################################################## +# Plug-in +########################################################## +class appleseed_material(OpenMayaMPx.MPxNode): + # Define the static variables to which we will assign the node's attributes + # in nodeInitializer() defined below. + surfacePointAttribute = OpenMaya.MObject() + outColorAttribute = OpenMaya.MObject() + hardwareColorAttribute = OpenMaya.MObject() + + render_layerAttribute = OpenMaya.MObject() + BSDF_frontAttribute = OpenMaya.MObject() + EDF_frontAttribute = OpenMaya.MObject() + surface_shader_frontAttribute = OpenMaya.MObject() + alpha_mapAttribute = OpenMaya.MObject() + normal_map_frontAttribute = OpenMaya.MObject() + + + + def __init__(self): + ''' Constructor. ''' + OpenMayaMPx.MPxNode.__init__(self) + +########################################################## +# Plug-in compute. +########################################################## + + def compute(self, pPlug, pDataBlock): + + if (( pPlug == appleseed_material.outColorAttribute ) or ( pPlug == appleseed_material.hardwareColorAttribute )): + + # Get the data handles corresponding to your attributes among the values in the data block. + surfacePointDataHandle = pDataBlock.inputValue( appleseed_material.surfacePointAttribute ) + BSDF_frontDataHandle = pDataBlock.inputValue( appleseed_material.BSDF_frontAttribute ) + hardwareColorDataHandle = pDataBlock.inputValue( appleseed_material.hardwareColInAttribute ) + + # Obtain the (x,y,z) location of the currently rendered point in camera coordinates. + surfacePoint = surfacePointDataHandle.asFloatVector() + + # Get the BSDF_front and hardware Color values. + BSDF_frontValue = BSDF_frontDataHandle.asFloatVector() + hardwareValue = hardwareColorDataHandle.asFloatVector() + + outColor = OpenMaya.MFloatVector(0.5, 0.5, 0.5) + hardwareColor = OpenMaya.MFloatVector(0.5, 0.5, 0.5) + + outColor.x = hardwareValue.x + outColor.y = hardwareValue.y + outColor.z = hardwareValue.z + + # Write to the output data. + outColorDataHandle = pDataBlock.outputValue( appleseed_material.outColorAttribute ) + outColorDataHandle.setMFloatVector( outColor ) + outColorDataHandle.setClean() + + hardwareColorDataHandle = pDataBlock.outputValue( appleseed_material.hardwareColorAttribute ) + hardwareColorDataHandle.setMFloatVector( hardwareColor ) + hardwareColorDataHandle.setClean() + + # cmds.setAttr(+'.hardwareColor', 1,0,0) + + else: + return OpenMaya.kUnknownParameter + + + +########################################################## +# Plug-in initialization. +########################################################## +def nodeCreator(): + + return OpenMayaMPx.asMPxPtr( appleseed_material() ) + +def nodeInitializer(): + + # Create a numeric attribute function set, since our attributes will all be defined by numeric types. + numericAttributeFn = OpenMaya.MFnNumericAttribute() + + #================================== + # INPUT NODE ATTRIBUTE(S) + #================================== + # - The (x,y,z) point on the surface defined according to the camera's frame of reference. + # > (!) Important: the 'pointCamera' string relates to the samplerInfo maya node. + # > This value is supplied by the render sampler at computation time. + appleseed_material.surfacePointAttribute = numericAttributeFn.createPoint('pointCamera', 'p') + numericAttributeFn.setStorable(False) + numericAttributeFn.setHidden(True) + appleseed_material.addAttribute( appleseed_material.surfacePointAttribute ) + + #render_layer Attribute + #output directory attribute + render_layer_string = OpenMaya.MFnStringData().create("default_render_layer") + render_layer_Attr = OpenMaya.MFnTypedAttribute() + appleseed_material.render_layer = render_layer_Attr.create("render_layer", "render_layer", OpenMaya.MFnData.kString, render_layer_string) + appleseed_material.addAttribute( appleseed_material.render_layer ) + + #duplicate front attributes on back + duplicate_front_on_back_nAttr = OpenMaya.MFnNumericAttribute() + appleseed_material.duplicate_front_on_back = duplicate_front_on_back_nAttr.create("duplicate_front_attributes_on_back", "duplicate_front_on_back", OpenMaya.MFnNumericData.kBoolean, True) + appleseed_material.addAttribute( appleseed_material.duplicate_front_on_back ) + + # front *************************** + + #enable front + enable_front_nAttr = OpenMaya.MFnNumericAttribute() + appleseed_material.enable_front = enable_front_nAttr.create("enable_front_material", "enable_front", OpenMaya.MFnNumericData.kBoolean, True) + appleseed_material.addAttribute( appleseed_material.enable_front ) + + #BSDF_front Attribute + appleseed_material.BSDF_frontAttribute = numericAttributeFn.createColor( 'BSDF_front_color', 'BSDF_front' ) + numericAttributeFn.setStorable( True ) + numericAttributeFn.setDefault( 0.0,0.0,0.0 ) + appleseed_material.addAttribute( appleseed_material.BSDF_frontAttribute ) + + #EDF_front Attribute + appleseed_material.EDF_frontAttribute = numericAttributeFn.createColor( 'EDF_front_color', 'EDF_front' ) + numericAttributeFn.setStorable( True ) + numericAttributeFn.setDefault( 0.0,0.0,0.0 ) + appleseed_material.addAttribute( appleseed_material.EDF_frontAttribute ) + + #surface_shader_front Attribute + appleseed_material.surface_shader_frontAttribute = numericAttributeFn.createColor( 'surface_shader_front_color', 'surface_shader_front' ) + numericAttributeFn.setStorable( True ) + numericAttributeFn.setDefault( 0.0,0.0,0.0 ) + appleseed_material.addAttribute( appleseed_material.surface_shader_frontAttribute ) + + #normal_map_front Attribute + appleseed_material.normal_map_frontAttribute = numericAttributeFn.createColor( 'normal_map_front_color', 'normal_map_front' ) + numericAttributeFn.setStorable( True ) + numericAttributeFn.setDefault( 0.0,0.0,0.0 ) + appleseed_material.addAttribute( appleseed_material.normal_map_frontAttribute ) + + # back *************************** + + #enable back + enable_back_nAttr = OpenMaya.MFnNumericAttribute() + appleseed_material.enable_back = enable_back_nAttr.create("enable_back_material", "enable_back", OpenMaya.MFnNumericData.kBoolean, True) + appleseed_material.addAttribute( appleseed_material.enable_back ) + + #BSDF_back Attribute + appleseed_material.BSDF_backAttribute = numericAttributeFn.createColor( 'BSDF_back_color', 'BSDF_back' ) + numericAttributeFn.setStorable( True ) + numericAttributeFn.setDefault( 0.0,0.0,0.0 ) + appleseed_material.addAttribute( appleseed_material.BSDF_backAttribute ) + + #EDF_back Attribute + appleseed_material.EDF_backAttribute = numericAttributeFn.createColor( 'EDF_back_color', 'EDF_back' ) + numericAttributeFn.setStorable( True ) + numericAttributeFn.setDefault( 0.0,0.0,0.0 ) + appleseed_material.addAttribute( appleseed_material.EDF_backAttribute ) + + #surface_shader_back Attribute + appleseed_material.surface_shader_backAttribute = numericAttributeFn.createColor( 'surface_shader_back_color', 'surface_shader_back' ) + numericAttributeFn.setStorable( True ) + numericAttributeFn.setDefault( 0.0,0.0,0.0 ) + appleseed_material.addAttribute( appleseed_material.surface_shader_backAttribute ) + + #normal_map_back Attribute + appleseed_material.normal_map_backAttribute = numericAttributeFn.createColor( 'normal_map_back_color', 'normal_map_back' ) + numericAttributeFn.setStorable( True ) + numericAttributeFn.setDefault( 0.0,0.0,0.0 ) + appleseed_material.addAttribute( appleseed_material.normal_map_backAttribute ) + + + + #alpha_map Attribute + appleseed_material.alpha_mapAttribute = numericAttributeFn.createColor( 'alpha_map_color', 'alpha_map' ) + numericAttributeFn.setStorable( True ) + numericAttributeFn.setDefault( 0.0,0.0,0.0 ) + appleseed_material.addAttribute( appleseed_material.alpha_mapAttribute ) + + #hardware Color Attribute + appleseed_material.hardwareColInAttribute = numericAttributeFn.createColor( 'hardware_color_in', 'hci' ) + numericAttributeFn.setStorable( True ) + numericAttributeFn.setDefault( 0.5,0.5,0.5 ) + appleseed_material.addAttribute( appleseed_material.hardwareColInAttribute ) + + + #================================== + # OUTPUT NODE ATTRIBUTE(S) + #================================== + # - The pixel color output. + # > This value is computed in our appleseed_material.compute() method, and should not be stored. + appleseed_material.outColorAttribute = numericAttributeFn.createColor( 'outColor', 'oc') + numericAttributeFn.setStorable( False ) + numericAttributeFn.setWritable( False ) + numericAttributeFn.setReadable( True ) + numericAttributeFn.setHidden( False ) + appleseed_material.addAttribute( appleseed_material.outColorAttribute ) + + + appleseed_material.hardwareColorAttribute = numericAttributeFn.createColor( 'hardwareColor', 'hc') + numericAttributeFn.setStorable( False ) + numericAttributeFn.setWritable( False ) + numericAttributeFn.setReadable( True ) + numericAttributeFn.setHidden( False ) + appleseed_material.addAttribute( appleseed_material.hardwareColorAttribute ) + + #================================== + # NODE ATTRIBUTE DEPENDENCIES + #================================== + # - All the input attributes affect the computation of the pixel color output (outColor). + appleseed_material.attributeAffects( appleseed_material.BSDF_frontAttribute, appleseed_material.outColorAttribute ) + appleseed_material.attributeAffects( appleseed_material.BSDF_frontAttribute, appleseed_material.hardwareColorAttribute ) + appleseed_material.attributeAffects( appleseed_material.hardwareColInAttribute, appleseed_material.outColorAttribute ) + +def initializePlugin( mobject ): + ''' Initializes the plug-in. ''' + mplugin = OpenMayaMPx.MFnPlugin( mobject ) + try: + mplugin.registerNode( kPluginNodeName, kPluginNodeId, nodeCreator, + nodeInitializer, OpenMayaMPx.MPxNode.kDependNode, kPluginNodeClassify ) + except: + sys.stderr.write( "Failed to register node: " + kPluginNodeName ) + raise + +def uninitializePlugin( mobject ): + ''' Unitializes the plug-in. ''' + mplugin = OpenMayaMPx.MFnPlugin( mobject ) + try: + mplugin.deregisterNode( kPluginNodeId ) + except: + sys.stderr.write( "Failed to deregister node: " + kPluginNodeName ) + raise + diff --git a/sandbox/extras/maya/plugins/ms_appleseed_shading_node.py b/sandbox/extras/maya/plugins/ms_appleseed_shading_node.py new file mode 100644 index 0000000000..a596406c22 --- /dev/null +++ b/sandbox/extras/maya/plugins/ms_appleseed_shading_node.py @@ -0,0 +1,123 @@ + +# +# Copyright (c) 2012 Jonathan Topf +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. +# + + +import sys +import maya.OpenMaya as OpenMaya +import maya.OpenMayaMPx as OpenMayaMPx +import maya.cmds as cmds + +# Plug-in information: +kPluginNodeName = 'ms_appleseed_shading_node' +kPluginNodeClassify = 'utility/color' +kPluginNodeId = OpenMaya.MTypeId(0x00335) + +########################################################## +# Plug-in +########################################################## +class appleseed_shading_node(OpenMayaMPx.MPxNode): + outColorAttribute = OpenMaya.MObject() + inColorAttribute = OpenMaya.MObject() + + def __init__(self): + ''' Constructor. ''' + OpenMayaMPx.MPxNode.__init__(self) + +########################################################## +# Plug-in compute. +########################################################## + + def compute(self, pPlug, pDataBlock): + + if ( pPlug == appleseed_shading_node.outColorAttribute ): + + inColorDataHandle = pDataBlock.inputValue( appleseed_material.inColorAttribute ) + + inColorValue = inColorDataHandle.asFloatVector() + + outColor = OpenMaya.MFloatVector(0, 0, 0) + + outColor.x = inColorValue.x + outColor.y = inColorValue.y + outColor.z = inColorValue.z + + outColorDataHandle = pDataBlock.outputValue( appleseed_shading_node.outColorAttribute ) + outColorDataHandle.setMFloatVector( outColor ) + outColorDataHandle.setClean() + + else: + return OpenMaya.kUnknownParameter + + + +########################################################## +# Plug-in initialization. +########################################################## +def nodeCreator(): + + return OpenMayaMPx.asMPxPtr( appleseed_shading_node() ) + +def nodeInitializer(): + + # Create a numeric attribute function set, since our attributes will all be defined by numeric types. + numericAttributeFn = OpenMaya.MFnNumericAttribute() + + + #================================== + # inpuut NODE ATTRIBUTE(S) + #================================== + appleseed_shading_node.inColorAttribute = numericAttributeFn.createColor( 'incolor', 'ic' ) + numericAttributeFn.setStorable( True ) + numericAttributeFn.setHidden( True ) + numericAttributeFn.setDefault( 0.5,0.5,0.5 ) + appleseed_shading_node.addAttribute( appleseed_shading_node.inColorAttribute ) + + #================================== + # OUTPUT NODE ATTRIBUTE(S) + #================================== + appleseed_shading_node.outColorAttribute = numericAttributeFn.createColor( 'outColor', 'oc') + numericAttributeFn.setStorable( False ) + numericAttributeFn.setWritable( False ) + numericAttributeFn.setReadable( True ) + numericAttributeFn.setHidden( False ) + appleseed_shading_node.addAttribute( appleseed_shading_node.outColorAttribute ) + + +def initializePlugin( mobject ): + ''' Initializes the plug-in. ''' + mplugin = OpenMayaMPx.MFnPlugin( mobject ) + try: + mplugin.registerNode( kPluginNodeName, kPluginNodeId, nodeCreator, nodeInitializer, OpenMayaMPx.MPxNode.kDependNode, kPluginNodeClassify ) + except: + sys.stderr.write( "Failed to register node: " + kPluginNodeName ) + raise + +def uninitializePlugin( mobject ): + ''' Unitializes the plug-in. ''' + mplugin = OpenMayaMPx.MFnPlugin( mobject ) + try: + mplugin.deregisterNode( kPluginNodeId ) + except: + sys.stderr.write( "Failed to deregister node: " + kPluginNodeName ) + raise + diff --git a/sandbox/extras/maya/plugins/ms_export_obj_2012.bundle b/sandbox/extras/maya/plugins/ms_export_obj_2012.bundle new file mode 100644 index 0000000000..5f580a7d30 Binary files /dev/null and b/sandbox/extras/maya/plugins/ms_export_obj_2012.bundle differ diff --git a/sandbox/extras/maya/plugins/ms_export_obj_2013.bundle b/sandbox/extras/maya/plugins/ms_export_obj_2013.bundle new file mode 100644 index 0000000000..3f3d2fac62 Binary files /dev/null and b/sandbox/extras/maya/plugins/ms_export_obj_2013.bundle differ diff --git a/sandbox/extras/maya/plugins/ms_export_obj_2013.mll b/sandbox/extras/maya/plugins/ms_export_obj_2013.mll new file mode 100644 index 0000000000..39f381cf8b Binary files /dev/null and b/sandbox/extras/maya/plugins/ms_export_obj_2013.mll differ diff --git a/sandbox/extras/maya/scripts/AEms_appleseed_materialTemplate.mel b/sandbox/extras/maya/scripts/AEms_appleseed_materialTemplate.mel new file mode 100644 index 0000000000..bab2588eb4 --- /dev/null +++ b/sandbox/extras/maya/scripts/AEms_appleseed_materialTemplate.mel @@ -0,0 +1,55 @@ +// Copyright (c) 2012 Jonathan Topf + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +global proc AEms_appleseed_materialTemplate( string $nodeName ) +{ + editorTemplate -beginScrollLayout; + + editorTemplate -beginLayout "Main Attributes" -collapse 0; + + editorTemplate -addControl "render_layer"; + + editorTemplate -addSeparator; + editorTemplate -addControl "enable_front_material"; + editorTemplate -addControl "BSDF_front_color"; + editorTemplate -addControl "EDF_front_color"; + editorTemplate -addControl "surface_shader_front_color"; + editorTemplate -addControl "normal_map_front_color"; + + editorTemplate -addSeparator; + editorTemplate -addControl "enable_back_material"; + editorTemplate -addControl "duplicate_front_attributes_on_back"; + editorTemplate -addControl "BSDF_back_color"; + editorTemplate -addControl "EDF_back_color"; + editorTemplate -addControl "surface_shader_back_color"; + editorTemplate -addControl "normal_map_back_color"; + + editorTemplate -addSeparator; + + editorTemplate -addControl "alpha_map_color"; + editorTemplate -endLayout; + + // include/call base class/node attributes + AEdependNodeTemplate $nodeName; + + editorTemplate -addExtraControls; + editorTemplate -endScrollLayout; +} + diff --git a/sandbox/extras/maya/scripts/AEms_appleseed_shading_nodeTemplate.mel b/sandbox/extras/maya/scripts/AEms_appleseed_shading_nodeTemplate.mel new file mode 100644 index 0000000000..ed21c66596 --- /dev/null +++ b/sandbox/extras/maya/scripts/AEms_appleseed_shading_nodeTemplate.mel @@ -0,0 +1,39 @@ +// Copyright (c) 2012 Jonathan Topf + +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: + +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. + +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +global proc AEms_appleseed_shading_nodeTemplate( string $nodeName ) +{ + //AEswatchDisplay $nodeName; + //editorTemplate -beginScrollLayout; + + //editorTemplate -beginLayout "Main Attributes" -collapse 0; + //editorTemplate -endLayout; + + +// AEhardwareTextureTemplate $nodeName +// ("hardwareColor diffuse"); + + // include/call base class/node attributes + AEdependNodeTemplate $nodeName; + + editorTemplate -addExtraControls; + editorTemplate -endScrollLayout; +} + diff --git a/sandbox/extras/maya/scripts/AEms_environmentTemplate.mel b/sandbox/extras/maya/scripts/AEms_environmentTemplate.mel index adf9056d6d..1d560cd62e 100644 --- a/sandbox/extras/maya/scripts/AEms_environmentTemplate.mel +++ b/sandbox/extras/maya/scripts/AEms_environmentTemplate.mel @@ -22,13 +22,14 @@ global proc AEms_environmentTemplate(string $nodeName) { editorTemplate -beginScrollLayout; - editorTemplate -beginLayout "Appleseed Projection" -collapse false; + editorTemplate -beginLayout "appleseed Projection" -collapse false; editorTemplate -addControl "model"; editorTemplate -addControl "constant_exitance"; editorTemplate -addControl "gradient_horizon_exitance"; editorTemplate -addControl "gradient_zenith_exitance"; editorTemplate -addControl "latitude_longitude_exitance"; editorTemplate -addControl "mirror_ball_exitance"; + editorTemplate -addControl "exitance_multiplier"; editorTemplate -endLayout; diff --git a/sandbox/extras/maya/scripts/AEms_renderSettingsTemplate.mel b/sandbox/extras/maya/scripts/AEms_renderSettingsTemplate.mel index a7d705a882..c907f5108c 100644 --- a/sandbox/extras/maya/scripts/AEms_renderSettingsTemplate.mel +++ b/sandbox/extras/maya/scripts/AEms_renderSettingsTemplate.mel @@ -1,15 +1,17 @@ - // Copyright (c) 2012 Jonathan Topf +// +// Copyright (c) 2012 Jonathan Topf +// // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: - +// // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. - +// // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -19,232 +21,278 @@ // THE SOFTWARE. -// procedure to get connected node of an attribute +//-------------------------------------------------------------------------------------------------- +// Utility function to get connected node of an attribute. +//-------------------------------------------------------------------------------------------------- -global proc string getConnectedNode(string $nodeName){ +global proc string getConnectedNode(string $nodeName) { string $nodes[] = `listConnections($nodeName)`; return $nodes[0]; } -// procedures for -callCustom folderPicker ---------------------------------------- +//-------------------------------------------------------------------------------------------------- +// Directory browser. +//-------------------------------------------------------------------------------------------------- -global proc AEfileBrowse(string $attr){ - rowLayout -nc 3; - text -label "Output directory"; - textField -fileName `getAttr $attr` LocationText; - symbolButton -image "navButtonBrowse.xpm" -c ("loadPopup(\"" + $attr + "\")"); - setParent ..; - -} - -global proc AEfileBrowseRepeat(string $attr){ - textField -e -fileName `getAttr $attr` LocationText; +global proc AEfileBrowse(string $attr) { + rowLayout -nc 3; + text -label "Output Directory"; + textField -fileName `getAttr $attr` LocationText; + symbolButton -image "navButtonBrowse.xpm" -c ("loadPopup(\"" + $attr + "\")"); + setParent ..; } -global proc loadPopup(string $attr){ - string $loc[0] = `fileDialog2 -fm 3 -okc "save"`; - - if ($loc[0] != ""){ - setAttr -type "string" $attr $loc[0]; - textField -e -fileName `getAttr $attr` LocationText; - } -} - -// procedure for -callCustom render button ---------------------------------------- -global proc AEexportButton(string $attr){ - string $nodeNameTokens[]; - tokenize $attr "." $nodeNameTokens; - string $export_command = "python(\"import ms_export\\nms_export.export(\\\"" + $nodeNameTokens[0] + "\\\")\")"; - print $export_command; - button -label "Export scene" -width 200 -height 30 -bgc 0 0.6 0.8 -ebg false -c $export_command; +global proc AEfileBrowseRepeat(string $attr) { + textField -e -fileName `getAttr $attr` LocationText; } -global proc AE_edit_export_button(string $attr){ +global proc loadPopup(string $attr) { + string $loc[0] = `fileDialog2 -fm 3 -okc "save"`; + + if ($loc[0] != "") { + setAttr -type "string" $attr $loc[0]; + textField -e -fileName `getAttr $attr` LocationText; + } +} + + +//-------------------------------------------------------------------------------------------------- +// Export button. +//-------------------------------------------------------------------------------------------------- + +global proc AEexportButton(string $attr) { + string $nodeNameTokens[]; + tokenize $attr "." $nodeNameTokens; + string $export_command = "python(\"import ms_export\\nms_export.export(\\\"" + $nodeNameTokens[0] + "\\\")\")"; + print $export_command; + button -label "Export" -width 200 -height 30 -bgc 0 0.6 0.8 -ebg false -c $export_command; } +global proc AE_edit_export_button(string $attr) { +} -// procedures for environment option menu ---------------------------------------- - -global proc AEcustomEnvironmentMenuCreate(string $attr){ - // get actual node name - string $nodeNameTokens[]; - tokenize $attr "." $nodeNameTokens; - int $newStringLength = size($nodeNameTokens[0]); - string $nodeName = `substring $nodeNameTokens[0] 1 $newStringLength`; - string $currentEnvironmentConnectionTransform = `getConnectedNode($nodeName + ".environment")`; - string $currentEnvironmentConnectionTransformRelatives[] = {""}; - if ($currentEnvironmentConnectionTransform != ""){ - $currentEnvironmentConnectionTransformRelatives = `listRelatives $currentEnvironmentConnectionTransform`; - } - string $currentEnvironmentConnection = $currentEnvironmentConnectionTransformRelatives[0]; - - optionMenuGrp -label "Environmnets" -cc ("setEnvironmentConnection " + $nodeName) customEnvironmentMenu; - string $environments[] = `ls -type "ms_environment"`; - menuItem -label ""; - for ($item in $environments){ - menuItem -label $item; - } - print ($currentEnvironmentConnection + "****\n\n"); - if ($currentEnvironmentConnection != ""){ - optionMenuGrp -e -v $currentEnvironmentConnection customEnvironmentMenu; - } - button -l " select " -h 20 -w 50 -c ("AEselecConnectedEnvironmentNode " + $nodeName) -p customEnvironmentMenu; - button -l " + " -h 20 -c ("createMsEnvironmentNode " + $nodeName ) -p customEnvironmentMenu; +//-------------------------------------------------------------------------------------------------- +// Environment picker. +//-------------------------------------------------------------------------------------------------- + +global proc AEcustomEnvironmentMenuCreate(string $attr) { + // get actual node name + string $nodeNameTokens[]; + tokenize $attr "." $nodeNameTokens; + int $newStringLength = size($nodeNameTokens[0]); + string $nodeName = `substring $nodeNameTokens[0] 1 $newStringLength`; + string $currentEnvironmentConnectionTransform = `getConnectedNode($nodeName + ".environment")`; + string $currentEnvironmentConnectionTransformRelatives[] = {""}; + if ($currentEnvironmentConnectionTransform != "") { + $currentEnvironmentConnectionTransformRelatives = `listRelatives $currentEnvironmentConnectionTransform`; + } + string $currentEnvironmentConnection = $currentEnvironmentConnectionTransformRelatives[0]; + + optionMenuGrp -label "Environment" -cc ("setEnvironmentConnection " + $nodeName) customEnvironmentMenu; + string $environments[] = `ls -type "ms_environment"`; + menuItem -label ""; + for ($item in $environments) { + menuItem -label $item; + } + print ($currentEnvironmentConnection + "****\n\n"); + if ($currentEnvironmentConnection != "") { + optionMenuGrp -e -v $currentEnvironmentConnection customEnvironmentMenu; + } + button -l " select " -h 20 -w 50 -c ("AEselecConnectedEnvironmentNode " + $nodeName) -p customEnvironmentMenu; + button -l " + " -h 20 -c ("createMsEnvironmentNode " + $nodeName ) -p customEnvironmentMenu; } -global proc AEselecConnectedEnvironmentNode(string $nodeName){ - string $connectedNode = `getConnectedNode($nodeName + ".environment")`; - if ($connectedNode != ""){ - select -r $connectedNode; - } + +global proc AEselecConnectedEnvironmentNode(string $nodeName) { + string $connectedNode = `getConnectedNode($nodeName + ".environment")`; + if ($connectedNode != "") { + select -r $connectedNode; + } } -global proc AEcustomEnvironmentMenuEdit(string $nodeName){ - deleteUI customEnvironmentMenu; +global proc AEcustomEnvironmentMenuEdit(string $nodeName) { + deleteUI customEnvironmentMenu; AEcustomEnvironmentMenuCreate($nodeName); } -global proc setEnvironmentConnection(string $nodeName){ - string $newSelection = `optionMenuGrp -q -v customEnvironmentMenu`; - $newSelectionAttr = $newSelection + ".nodeState"; - string $environmentConnectionName = $nodeName + ".environment"; - string $currentEnvironmentConnection = `getConnectedNode($nodeName + ".environment")`; - if ($currentEnvironmentConnection != ""){ - $currentEnvironmentConnection = $currentEnvironmentConnection + ".nodeState"; - //disconnectAttr $currentEnvironmentConnection $environmentConnectionName; - select $nodeName; - } - if ($newSelection != ""){ - print ("connecting "+$newSelectionAttr+" and "+$environmentConnectionName+"\n"); - connectAttr -f $newSelectionAttr $environmentConnectionName; - } +global proc setEnvironmentConnection(string $nodeName) { + string $newSelection = `optionMenuGrp -q -v customEnvironmentMenu`; + $newSelectionAttr = $newSelection + ".nodeState"; + string $environmentConnectionName = $nodeName + ".environment"; + string $currentEnvironmentConnection = `getConnectedNode($nodeName + ".environment")`; + if ($currentEnvironmentConnection != "") { + $currentEnvironmentConnection = $currentEnvironmentConnection + ".nodeState"; + select $nodeName; + } + if ($newSelection != "") { + print ("connecting "+$newSelectionAttr+" and "+$environmentConnectionName+"\n"); + connectAttr -f $newSelectionAttr $environmentConnectionName; + } } -global proc createMsEnvironmentNode(string $nodeName){ - string $node = `createNode "ms_environment"`; - connectAttr -f ($node + ".nodeState") ($nodeName + ".environment"); +global proc createMsEnvironmentNode(string $nodeName) { + string $node = `createNode "ms_environment"`; + connectAttr -f ($node + ".nodeState") ($nodeName + ".environment"); } -// procedures for camera option menu ---------------------------------------- -global proc AEcustomCameraMenuCreate(string $attr){ - - // get actual node name - string $nodeNameTokens[]; - tokenize $attr "." $nodeNameTokens; - int $newStringLength = size($nodeNameTokens[0]); - string $nodeName = `substring $nodeNameTokens[0] 1 $newStringLength`; - print $nodeName; - - //string $currentCameraConnection = `getConnectedNode($nodeName + ".camera")`; - string $customCameraMenuCommand = "setCameraConnection " + $nodeName; - optionMenuGrp -label "Cameras" -cc $customCameraMenuCommand customCameraMenu; - string $cameras[] = `ls -cameras`; - menuItem -label ""; - for ($item in $cameras){ - menuItem -label $item; - } - - - string $currentCameraConnectionTransform = `getConnectedNode($nodeName + ".camera")`; - string $currentCameraConnectionTransformRelatives[] = {""}; - if ($currentCameraConnectionTransform != ""){ - $currentCameraConnectionTransformRelatives = `listRelatives $currentCameraConnectionTransform`; - } - string $currentCameraConnection = $currentCameraConnectionTransformRelatives[0]; - - - if ($currentCameraConnection != ""){ - optionMenuGrp -e -v $currentCameraConnection customCameraMenu; - } + +//-------------------------------------------------------------------------------------------------- +// Camera picker. +//-------------------------------------------------------------------------------------------------- + +global proc AEcustomCameraMenuCreate(string $attr) { + // get actual node name + string $nodeNameTokens[]; + tokenize $attr "." $nodeNameTokens; + int $newStringLength = size($nodeNameTokens[0]); + string $nodeName = `substring $nodeNameTokens[0] 1 $newStringLength`; + print $nodeName; + + string $customCameraMenuCommand = "setCameraConnection " + $nodeName; + optionMenuGrp -label "Camera" -cc $customCameraMenuCommand customCameraMenu; + string $cameras[] = `ls -cameras`; + menuItem -label ""; + for ($item in $cameras) { + string $is_orthographic = `getAttr ($item + ".orthographic")`; + if ($is_orthographic == 0) { + menuItem -label $item; + } + } + + string $currentCameraConnectionTransform = `getConnectedNode($nodeName + ".camera")`; + string $currentCameraConnectionTransformRelatives[] = {""}; + if ($currentCameraConnectionTransform != "") { + $currentCameraConnectionTransformRelatives = `listRelatives $currentCameraConnectionTransform`; + } + string $currentCameraConnection = $currentCameraConnectionTransformRelatives[0]; + + if ($currentCameraConnection != "") { + optionMenuGrp -e -v $currentCameraConnection customCameraMenu; + } } - -global proc AEcustomCameraMenuEdit(string $nodeName){ - deleteUI customCameraMenu; + +global proc AEcustomCameraMenuEdit(string $nodeName) { + deleteUI customCameraMenu; AEcustomCameraMenuCreate($nodeName); } -global proc setCameraConnection(string $nodeName){ - string $newSelection = `optionMenuGrp -q -v customCameraMenu`; - $newSelectionAttr = $newSelection + ".nodeState"; - string $cameraConnectionName = $nodeName + ".camera"; - string $currentCameraConnection = `getConnectedNode($nodeName + ".camera")`; - if ($currentCameraConnection != ""){ - $currentCameraConnection = $currentCameraConnection + ".nodeState"; - //disconnectAttr $currentCameraConnection $cameraConnectionName; - } - if ($newSelection != ""){ - connectAttr -f $newSelectionAttr $cameraConnectionName; - } +global proc setCameraConnection(string $nodeName) { + string $newSelection = `optionMenuGrp -q -v customCameraMenu`; + $newSelectionAttr = $newSelection + ".nodeState"; + string $cameraConnectionName = $nodeName + ".camera"; + string $currentCameraConnection = `getConnectedNode($nodeName + ".camera")`; + if ($currentCameraConnection != "") { + $currentCameraConnection = $currentCameraConnection + ".nodeState"; + } + if ($newSelection != "") { + connectAttr -f $newSelectionAttr $cameraConnectionName; + } else { + if ($currentCameraConnection != ""){ + string $cams[] = `listConnections ($nodeName + ".camera")`; + disconnectAttr ($cams[0] + "Shape.nodeState") ($nodeName + ".camera"); + } + } } -// layout definition --------------------------------------------------------- -global proc AEms_renderSettingsTemplate(string $nodeName) -{ - editorTemplate -callCustom "AEexportButton" "AE_edit_export_button" "export"; - editorTemplate -beginScrollLayout; - editorTemplate -beginLayout "Export settings" -collapse false; - editorTemplate -callCustom "AEfileBrowse" "AEfileBrowseRepeat" "output_directory"; - editorTemplate -addControl "output_file"; - editorTemplate -addControl "convert_shading_nodes_to_textures"; - editorTemplate -addSeparator; - editorTemplate -addControl "convert_textures_to_exr"; - editorTemplate -addSeparator; - editorTemplate -addControl "overwrite_existing_exrs"; - editorTemplate -addSeparator; - editorTemplate -addControl "export_motion_blur"; - editorTemplate -addControl "shutter_open"; - editorTemplate -addControl "shutter_close"; - editorTemplate -addSeparator; - editorTemplate -addControl "export_animation"; - editorTemplate -addControl "animation_start_frame"; - editorTemplate -addControl "animation_end_frame"; - editorTemplate -endLayout; - - editorTemplate -beginLayout "Environment settings" -collapse true; - editorTemplate -callCustom "AEcustomEnvironmentMenuCreate" "AEcustomEnvironmentMenuEdit" "environment"; - editorTemplate -endLayout; - - editorTemplate -beginLayout "Camera settings" -collapse true; - editorTemplate -addControl "export_all_cameras"; - editorTemplate -addSeparator; - editorTemplate -addControl "export_all_cameras_as_thinlens"; - editorTemplate -endLayout; +//-------------------------------------------------------------------------------------------------- +// Layout definition. +//-------------------------------------------------------------------------------------------------- + +global proc AEms_renderSettingsTemplate(string $nodeName) { + editorTemplate -beginNoOptimize; + + editorTemplate -callCustom "AEexportButton" "AE_edit_export_button" "export"; + + editorTemplate -beginScrollLayout; + editorTemplate -beginLayout "Export Settings" -collapse false; + editorTemplate -addControl "output_directory"; + editorTemplate -addControl "output_file"; + editorTemplate -addSeparator; + editorTemplate -addControl "convert_shading_nodes_to_textures"; + editorTemplate -label "Convert Textures to OpenEXR" -addControl "convert_textures_to_exr"; + editorTemplate -label "Overwrite Existing Textures Files" -addControl "overwrite_existing_textures"; + editorTemplate -addSeparator; + editorTemplate -addControl "export_maya_lights"; + editorTemplate -addSeparator; + editorTemplate -label "Export Camera Transformation Motion Blur" -addControl "export_camera_blur"; + editorTemplate -label "Export Assembly Transformation Motion Blur" -addControl "export_transformation_blur"; + editorTemplate -label "Export Object Deformation Motion Blur" -addControl "export_deformation_blur"; + + editorTemplate -addControl "motion_samples"; + editorTemplate -addControl "shutter_open_time"; + editorTemplate -addControl "shutter_close_time"; + editorTemplate -addSeparator; + editorTemplate -addControl "export_animation"; + editorTemplate -addControl "animation_start_frame"; + editorTemplate -addControl "animation_end_frame"; + editorTemplate -addControl "export_animated_textures"; + editorTemplate -endLayout; + + editorTemplate -beginLayout "Output Settings" -collapse true (uiRes("m_AElocatorTemplate.kLocatorAttributes")); + editorTemplate -callCustom "AEcustomCameraMenuCreate" "AEcustomCameraMenuEdit" "camera"; + editorTemplate -addControl "frame_width"; + editorTemplate -addControl "frame_height"; + editorTemplate -addControl "color_space"; + editorTemplate -endLayout; + + editorTemplate -beginLayout "Environment Settings" -collapse true; + editorTemplate -callCustom "AEcustomEnvironmentMenuCreate" "AEcustomEnvironmentMenuEdit" "environment"; + editorTemplate -endLayout; + + editorTemplate -beginLayout "Camera Settings" -collapse true; + editorTemplate -addControl "export_all_cameras"; + editorTemplate -addSeparator; + editorTemplate -addControl "export_all_cameras_as_thinlens"; + editorTemplate -endLayout; - editorTemplate -beginLayout "Assembly settings" -collapse true; - editorTemplate -addControl "interpret_sets_as_assemblies"; - editorTemplate -addSeparator; - editorTemplate -addControl "double_sided_shading"; - editorTemplate -endLayout; - - editorTemplate -beginLayout "Output settings" -collapse true (uiRes("m_AElocatorTemplate.kLocatorAttributes")); - editorTemplate -callCustom "AEcustomCameraMenuCreate" "AEcustomCameraMenuEdit" "camera"; - editorTemplate -addControl "resolution_width"; - editorTemplate -addControl "resolution_height"; - editorTemplate -addControl "color_space"; - editorTemplate -endLayout; - - editorTemplate -beginLayout "Configuration settings" -collapse true; - editorTemplate -addControl "export_custom_interactive_config"; - editorTemplate -addControl "interactive_lighting_engine"; - editorTemplate -addControl "interactive_min_samples"; - editorTemplate -addControl "interactive_max_samples"; - editorTemplate -addControl "interactive_max_ray_depth"; - editorTemplate -addControl "interactive_light_samples"; - editorTemplate -addSeparator; - editorTemplate -addControl "export_custom_final_config"; - editorTemplate -addControl "final_lighting_engine"; - editorTemplate -addControl "final_min_samples"; - editorTemplate -addControl "final_max_samples"; - editorTemplate -addControl "final_max_ray_depth"; - editorTemplate -addControl "final_light_samples"; - editorTemplate -endLayout; - - - AEdependNodeTemplate $nodeName; // add any base class attributes - - editorTemplate -addExtraControls; // add any other attributes - //editorTemplate -suppress "attrbute"; - - editorTemplate -endScrollLayout; -} \ No newline at end of file + editorTemplate -beginLayout "Assembly Settings" -collapse true; + editorTemplate -addControl "interpret_sets_as_assemblies"; + editorTemplate -addSeparator; + editorTemplate -endLayout; + + editorTemplate -beginLayout "Configuration Settings" -collapse true; + editorTemplate -addControl "export_custom_final_config"; + editorTemplate -addControl "min_samples"; + editorTemplate -addControl "max_samples"; + editorTemplate -addControl "gtr_sampler"; + editorTemplate -addControl "gtr_filter_size"; + editorTemplate -addControl "gtr_min_samples"; + editorTemplate -addControl "gtr_max_samples"; + editorTemplate -addControl "gtr_max_contrast"; + editorTemplate -addControl "gtr_max_variation"; + editorTemplate -addControl "final_lighting_engine"; + + editorTemplate -beginLayout "DRT Settings" -collapse true; + editorTemplate -addControl "drt_dl_bsdf_samples"; + editorTemplate -addControl "drt_dl_light_samples"; + editorTemplate -addControl "drt_enable_ibl"; + editorTemplate -addControl "drt_ibl_bsdf_samples"; + editorTemplate -addControl "drt_ibl_env_samples"; + editorTemplate -addControl "drt_max_path_length"; + editorTemplate -addControl "drt_rr_min_path_length"; + editorTemplate -endLayout; + + editorTemplate -beginLayout "PT Settings" -collapse true; + editorTemplate -addControl "pt_dl_light_samples"; + editorTemplate -addControl "pt_enable_caustics"; + editorTemplate -addControl "pt_enable_dl"; + editorTemplate -addControl "pt_enable_ibl"; + editorTemplate -addControl "pt_ibl_bsdf_samples"; + editorTemplate -addControl "pt_ibl_env_samples"; + editorTemplate -addControl "pt_max_path_length"; + editorTemplate -addControl "pt_next_event_estimation"; + editorTemplate -addControl "pt_rr_min_path_length"; + editorTemplate -endLayout; + editorTemplate -endLayout; + + editorTemplate -beginLayout "Advanced Settings" -collapse true; + editorTemplate -addControl "profile_export"; + editorTemplate -endLayout; + + AEdependNodeTemplate $nodeName; // add any base class attributes + editorTemplate -addExtraControls; // add any other attributes + editorTemplate -endScrollLayout; + + editorTemplate -endNoOptimize; +} diff --git a/sandbox/extras/maya/scripts/about.txt b/sandbox/extras/maya/scripts/about.txt index f9b7b4af38..629c0b7276 100644 --- a/sandbox/extras/maya/scripts/about.txt +++ b/sandbox/extras/maya/scripts/about.txt @@ -1 +1 @@ -Mayaseed is a maya script and gui for exporting camera, material and geometry data to the appleseed renderer. Mayaseed is released under the MIT licence. \ No newline at end of file +Mayaseed is a Maya plugin for exporting camera, material and geometry data to the appleseed renderer. Mayaseed is released under the MIT licence. \ No newline at end of file diff --git a/sandbox/extras/maya/scripts/appleseedEntityDefs.xml b/sandbox/extras/maya/scripts/appleseedEntityDefs.xml new file mode 100644 index 0000000000..b703379d80 --- /dev/null +++ b/sandbox/extras/maya/scripts/appleseedEntityDefs.xml @@ -0,0 +1,888 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/sandbox/extras/maya/scripts/mayaseed.ui b/sandbox/extras/maya/scripts/mayaseed.ui index 7f1375ae44..475c8b2fd9 100644 --- a/sandbox/extras/maya/scripts/mayaseed.ui +++ b/sandbox/extras/maya/scripts/mayaseed.ui @@ -57,7 +57,7 @@ - mayaseed_graphic.png + mayaseed.png false diff --git a/sandbox/extras/maya/scripts/ms_commands.py b/sandbox/extras/maya/scripts/ms_commands.py index 51f5849a0e..7172257dd7 100644 --- a/sandbox/extras/maya/scripts/ms_commands.py +++ b/sandbox/extras/maya/scripts/ms_commands.py @@ -1,15 +1,17 @@ -# Copyright (c) 2012 Jonathan Topf +# +# Copyright (c) 2012 Jonathan Topf +# # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: - +# # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. - +# # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -17,74 +19,34 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. - +# import maya.cmds as cmds -import maya.mel +import maya.mel as mel import maya.utils as mu import os import sys import inspect import subprocess +from xml.dom.minidom import parseString +import ms_export_obj +import random -#**************************************************************************************************************************************************************************************************** -# constant vars ************************************************************************************************************************************************************************************* -#**************************************************************************************************************************************************************************************************** +#-------------------------------------------------------------------------------------------------- +# Constants. +#-------------------------------------------------------------------------------------------------- -MAYASEED_VERSION = '0.1.7' +MAYASEED_VERSION = '0.1.8' MAYASEED_URL = 'https://github.com/jonathantopf/mayaseed' APPLESEED_URL = 'http://appleseedhq.net/' ROOT_DIRECTORY = os.path.split((os.path.dirname(inspect.getfile(inspect.currentframe()))))[0] -#**************************************************************************************************************************************************************************************************** -# utilitiy functions & classes ********************************************************************************************************************************************************************** -#**************************************************************************************************************************************************************************************************** -# -# addMsShadingAttribs function ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- -# - -def addShadingAttribs(): - shaderName = False - try: - shape = cmds.listRelatives(cmds.ls(sl=True)[0], s=True)[0] - shadingEngine = cmds.listConnections(shape, t='shadingEngine')[0] - shaderName = cmds.connectionInfo((shadingEngine + ".surfaceShader"),sourceFromDestination=True).split('.')[0] - except: - print '# No objects with shader connectoins selectd' - if shaderName: - if not cmds.objExists(shaderName + '.mayaseed_bsdf'): - cmds.addAttr(shaderName, ln='mayaseed_bsdf', at='enum', en='Lambertian:Ashikhmin-Shirley:Kelemen:Specular_BRDF:') - cmds.addAttr(shaderName, ln='mayaseed_edf', at='enum', en=':Diffuse') - cmds.addAttr(shaderName, ln='mayaseed_surface_shader', at='enum', en='Physical:Constant:') - else: - print '# {0} already has Mayaseed shader attributes'.format(shaderName) - -# -# removeMsShadingAttribs function ------------------------------------------------------------------------------------------------------------------------------------------------------------------- -# - -def removeShadingAttribs(): - shaderName = '' - try: - shape = cmds.listRelatives(cmds.ls(sl=True)[0], s=True)[0] - shadingEngine = cmds.listConnections(shape, t='shadingEngine')[0] - shaderName = cmds.connectionInfo((shadingEngine + ".surfaceShader"),sourceFromDestination=True).split('.')[0] - except: - print '# No objects with shader connectoins selectd' - if shaderName: - if cmds.objExists(shaderName + '.mayaseed_bsdf'): - cmds.deleteAttr(shaderName, at='mayaseed_bsdf') - cmds.deleteAttr(shaderName, at='mayaseed_edf') - cmds.deleteAttr(shaderName, at='mayaseed_surface_shader') - else: - print '# {0} has no Mayaseed shader attributes to remove'.format(shaderName) - -# -# show info dialogue ------------------------------------------------------------------------------------------------------------------------------------------------------------------- -# +#-------------------------------------------------------------------------------------------------- +# Show About dialog. +#-------------------------------------------------------------------------------------------------- class msInfoDial(): def __init__(self): @@ -94,9 +56,9 @@ def __init__(self): cmds.columnLayout(rs=10, columnOffset=['both', 20], width=600) cmds.rowLayout(numberOfColumns=2) cmds.text('', width=30) - cmds.image(image=os.path.join(ROOT_DIRECTORY, 'graphics', 'mayaseed_graphic.png')) + cmds.image(image=os.path.join(ROOT_DIRECTORY, 'graphics', 'mayaseed.png')) cmds.setParent('..') - cmds.text('version: ' + MAYASEED_VERSION) + cmds.text('Version: ' + MAYASEED_VERSION) cmds.text(open(os.path.join(ROOT_DIRECTORY, 'scripts', 'about.txt'),'r').read(), width=500, wordWrap=True, al='left') cmds.rowLayout(numberOfColumns=4) cmds.button( label='Mayaseed website', command=('import webbrowser\nwebbrowser.open_new_tab("http://www.jonathantopf.com/mayaseed/")')) @@ -110,10 +72,11 @@ def __init__(self): cmds.setParent('..') cmds.text('') cmds.showWindow(window) - -# -# clamp RGB values ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- -# + + +#-------------------------------------------------------------------------------------------------- +# Normalize an RGB color. +#-------------------------------------------------------------------------------------------------- def normalizeRGB(color): R = color[0] @@ -132,96 +95,568 @@ def normalizeRGB(color): G = G / M B = B / M - return (R,G,B,M) + return (R, G, B, M) -# -# convert shader connection to image --------------------------------------------------------------------------------------------------------------------------------------------------------------------- -# -def convertConnectionToImage(shader, attribute, dest_file, resolution=1024): +#-------------------------------------------------------------------------------------------------- +# Convert shader connection to image. +#-------------------------------------------------------------------------------------------------- + +def convertConnectionToImage(shader, attribute, dest_file, resolution=1024, pass_through=False): + + dest_dir = os.path.split(dest_file)[0] + if not os.path.exists(dest_dir): + os.makedirs(dest_dir) + if not cmds.objExists(shader+'.'+attribute): print 'error converting texture, no object named {0} exists'.format(shader+'.'+attribute) else: connection = cmds.listConnections(shader+'.'+attribute) if not connection: - print 'nothing connected to {0}'.format(plug_name) + print 'nothing connected to {0}, skipping conversion'.format(plug_name) + elif pass_through == True: + print '{0}: skipping conversion'.format(plug_name) else: cmds.hyperShade(objects=shader) connected_object = cmds.ls(sl=True)[0] print connected_object cmds.convertSolidTx(connection[0] ,connected_object ,fileImageName=dest_file, antiAlias=True, bm=3, fts=True, sp=True, alpha=True, doubleSided=True, resolutionX=resolution, resolutionY=resolution) - return dest_file - + + return dest_file + + +#-------------------------------------------------------------------------------------------------- +# Convert textures to OpenEXR format. +#-------------------------------------------------------------------------------------------------- + +def findPathToImfCopy(): + + # + # Values of maya_base_path: + # + # Maya 2012 Maya 2013 + # -------------------------------------------------------------------------- + # Mac OS X maya2012/Maya.app/Contents maya2013/Maya.app/Contents + # Windows Maya2012 Maya2013 + # Linux ? ? + # + # Locations of imf_copy: + # + # Maya 2012 Maya 2013 + # -------------------------------------------------------------------------- + # Mac OS X maya2012/Maya.app/Contents/bin maya2013/mentalray/bin + # Windows Maya2012\bin Maya2013\mentalray\bin + # Linux ? ? + # + + maya_base_path = os.path.split(sys.path[0])[0] + imf_copy_path = None + + if mel.eval('getApplicationVersionAsFloat()') >= 2013.0: + if sys.platform == 'darwin': + imf_copy_path = os.path.join(maya_base_path, '..', '..', 'mentalray', 'bin') + elif sys.platform == 'win32': + imf_copy_path = os.path.join(maya_base_path, 'mentalray', 'bin') + else: + imf_copy_path = os.path.join(maya_base_path, 'bin') -# -# convert texture to exr --------------------------------------------------------------------------------------------------------------------------------------------------------------------- -# + return None if imf_copy_path is None else os.path.join(imf_copy_path, 'imf_copy') -def convertTexToExr(file_path, dest_dir, overwrite=True): - if os.path.exists(file_path): - dest_file = os.path.join(dest_dir, os.path.splitext(os.path.split(file_path)[1])[0] + '.exr') - if (overwrite == False) and (os.path.exists(dest_file)): - print '# {0} exists, skipping conversion'.format(dest_file) - else: - imf_copy_path = os.path.join(os.path.split(sys.path[0])[0], 'bin', 'imf_copy') - if not os.path.exists(dest_dir): - os.mkdir(dest_dir) - p = subprocess.Popen([imf_copy_path, file_path, dest_file]) - return dest_file - else: - print '# error: {0} does not exist'.format(file_path) +def convertTexToExr(file_path, dest_dir, overwrite=True, pass_through=False): + dest_file = os.path.join(dest_dir, os.path.splitext(os.path.split(file_path)[1])[0] + '.exr') -# -# check if an object is exportable --------------------------------------------------------------------------------------------------------------------------------------------------------------------- -# + if not os.path.exists(file_path): + print "# error: {0} does not exist".format(file_path) + return dest_file + + if pass_through: + print "# skipping conversion of {0}".format(file_path) + return dest_file + + if os.path.exists(dest_file) and not overwrite: + print "# {0} already exists, skipping conversion".format(dest_file) + return dest_file + + imf_copy_path = findPathToImfCopy() + + if imf_copy_path is None: + print "# error: cannot convert {0}, imf_copy utility not found".format(file_path) + return dest_file + + if not os.path.exists(dest_dir): + os.mkdir(dest_dir) + + # -r: make a tiled OpenEXR file + # -t: set the tile dimensions + args = [imf_copy_path, "-r", "-t 32", file_path, dest_file] + + + if sys.platform == 'win32': + # http://stackoverflow.com/questions/2935704/running-shell-commands-without-a-shell-window + p = subprocess.Popen(args, creationflags=0x08000000) + p.wait() + elif sys.platform == 'darwin': + p = subprocess.Popen(args) + p.wait() + + return dest_file + + +#-------------------------------------------------------------------------------------------------- +# Check if an object is exportable. +#-------------------------------------------------------------------------------------------------- def shapeIsExportable(node_name): - - #check the node exists + # check if the node exists if not cmds.objExists(node_name): return False - - #check if the node has a visibility attribute meaning ita a dag node + + # check if the node has a visibility attribute meaning it's a DAG node if not cmds.attributeQuery('visibility', node=node_name, exists=True): return False - - #check visibility flag - if not cmds.getAttr(node_name+'.visibility'): - return False - - #check to see if its an intermediate mesh + # check visibility flag + if not cmds.getAttr(node_name + '.visibility'): + return False + # check to see if it's an intermediate mesh if cmds.attributeQuery('intermediateObject', node=node_name, exists=True): - if cmds.getAttr(node_name+'.intermediateObject'): + if cmds.getAttr(node_name + '.intermediateObject'): return False - - #is it in a hidden display layer - if (cmds.attributeQuery('overrideEnabled', node=node_name, exists=True) and cmds.getAttr(node_name+'.overrideEnabled')): - if not cmds.getAttr(node_name+'.overrideVisibility'): + + # check if it is a hidden display layer + if cmds.attributeQuery('overrideEnabled', node=node_name, exists=True) and cmds.getAttr(node_name + '.overrideEnabled'): + if not cmds.getAttr(node_name + '.overrideVisibility'): return False - - #has it got a parent and is it visible + + # has it got a parent and is it visible? if cmds.listRelatives(node_name, parent=True): if not shapeIsExportable(cmds.listRelatives(node_name, parent=True)[0]): return False return True - -def hasShaderConnected(node_name): - #check that the shape has a shader connected + +#-------------------------------------------------------------------------------------------------- +# Check if an object has a shader connected. +#-------------------------------------------------------------------------------------------------- + +def hasShaderConnected(node_name): + # check that the shape has a shader connected if not cmds.listConnections(node_name, t='shadingEngine'): return False - else: - shadingEngine = cmds.listConnections(node_name, t='shadingEngine')[0] - if not cmds.connectionInfo((shadingEngine + '.surfaceShader'),sourceFromDestination=True).split('.')[0]: - return False + shadingEngine = cmds.listConnections(node_name, t='shadingEngine')[0] + if not cmds.connectionInfo(shadingEngine + '.surfaceShader', sourceFromDestination=True).split('.')[0]: + return False + return True +#-------------------------------------------------------------------------------------------------- +# read entity defs xml file and return dict +#-------------------------------------------------------------------------------------------------- + + +def getEntityDefs(xml_file_path, list=False): + nodes = dict() + + class Node(): + def __init__(self, name, type): + self.name = name + self.type = type + self.attributes = dict() + + class Attribute(): + def __init__(self, name): + self.name = name + self.label = name + self.type = 'entity' + self.default_value = '' + self.entity_types = [] + file = open(xml_file_path,'r') + data = file.read() + file.close() + dom = parseString(data) + for entity in dom.getElementsByTagName('entity'): + + #create new dict entry to store the node info + nodes[entity.getAttribute('model')] = Node(entity.getAttribute('model'), entity.getAttribute('type')) + + for child in entity.childNodes: + if child.nodeName =='parameters': + + #add an attribute and give it a name + nodes[entity.getAttribute('model')].attributes[child.getAttribute('name')] = Attribute(child.getAttribute('name')) + + #itterate over child nodes and check that they are nodes not text + for param in child.childNodes: + if not param.nodeName == '#text': + + #node is a parameter with single value + if param.nodeName == 'parameter': + + #get attribute type + if param.getAttribute('name') == 'widget': + nodes[entity.getAttribute('model')].attributes[child.getAttribute('name')].type = param.getAttribute('value') + + elif param.getAttribute('name') == 'default': + nodes[entity.getAttribute('model')].attributes[child.getAttribute('name')].default_value = param.getAttribute('value') + + elif param.getAttribute('name') == 'label': + nodes[entity.getAttribute('model')].attributes[child.getAttribute('name')].label = param.getAttribute('value') + + #node is a parameter with multiple values + elif param.nodeName == 'parameters': + + #if the node contains entity types we are interested + if param.getAttribute('name') == 'entity_types': + for node in param.childNodes: + if not param.nodeName == '#text': + if node.nodeName == 'parameter': + nodes[entity.getAttribute('model')].attributes[child.getAttribute('name')].entity_types.append(node.getAttribute('name')) + + if list: + print 'Found the following appleseed nodes:\n' + + for node_key in nodes.iterkeys(): + print ' ' + nodes[node_key].name + + print ' type : ' + nodes[node_key].type + print ' attributes : ' + + for attr_key in nodes[node_key].attributes.iterkeys(): + print ' name : ' + nodes[node_key].attributes[attr_key].name + print ' type : ' + nodes[node_key].attributes[attr_key].type + print ' label : ' + nodes[node_key].attributes[attr_key].label + print ' default : ' + nodes[node_key].attributes[attr_key].default_value + print ' allowed connections : ' + for entity_type in nodes[node_key].attributes[attr_key].entity_types: + print ' ' + entity_type + print'' + + print'\n' + + return nodes + + +#-------------------------------------------------------------------------------------------------- +# Add color attribute to node. +#-------------------------------------------------------------------------------------------------- + +def addColorAttr(node_name, attribute_name, default_value=(0,0,0)): + cmds.addAttr(node_name, longName=attribute_name, usedAsColor=True, attributeType='float3') + cmds.addAttr(node_name, longName=(attribute_name + '_R'), attributeType='float', parent=attribute_name) + cmds.addAttr(node_name, longName=(attribute_name + '_G'), attributeType='float', parent=attribute_name) + cmds.addAttr(node_name, longName=(attribute_name + '_B'), attributeType='float', parent=attribute_name) + cmds.setAttr(node_name + '.' + attribute_name, default_value[0], default_value[1], default_value[2]) + + +#-------------------------------------------------------------------------------------------------- +# Create shading node. +#-------------------------------------------------------------------------------------------------- + +def createShadingNode(model, entity_defs_obj=False): + if entity_defs_obj: + entity_defs = entity_defs_obj + else: + entity_defs = getEntityDefs(os.path.join(ROOT_DIRECTORY, 'scripts', 'appleseedEntityDefs.xml')) + + shading_node_name = cmds.shadingNode('ms_appleseed_shading_node', asUtility=True, name=model) + + cmds.addAttr(shading_node_name, longName='node_model', dt="string") + cmds.setAttr((shading_node_name + '.node_model'), model, type="string", lock=True) + + cmds.addAttr(shading_node_name, longName='node_type', dt="string") + cmds.setAttr((shading_node_name + '.node_type'), entity_defs[model].type, type="string", lock=True) + + for entity_key in entity_defs.keys(): + if entity_key == model: + for attr_key in entity_defs[entity_key].attributes.keys(): + if entity_defs[entity_key].attributes[attr_key].type == 'entity_picker': + + # if there is a default value, use it + if entity_defs[entity_key].attributes[attr_key].default_value: + default_value = float(entity_defs[entity_key].attributes[attr_key].default_value) + print default_value + addColorAttr(shading_node_name, attr_key, (default_value,default_value,default_value)) + else: + addColorAttr(shading_node_name, attr_key) + + elif entity_defs[entity_key].attributes[attr_key].type == 'text_box': + cmds.addAttr(shading_node_name, longName=attr_key, dt="string") + cmds.setAttr((shading_node_name + '.' + attr_key), entity_defs[entity_key].attributes[attr_key].default_value, type="string") + + return shading_node_name + + +#-------------------------------------------------------------------------------------------------- +# Get file texture node file name with correct frame number. +#-------------------------------------------------------------------------------------------------- + +def getFileTextureName(file_node): + maya_file_texture_name = cmds.getAttr(file_node + '.fileTextureName') + + if sys.platform == 'darwin': + maya_file_texture_name = maya_file_texture_name.replace('\\', '/') + elif sys.platform == 'win32': + maya_file_texture_name = maya_file_texture_name.replace('/', '\\') + + if os.path.exists(maya_file_texture_name): + file_texture_name = maya_file_texture_name + else: + project_directory = cmds.workspace(q=True, rd=True) + file_name = os.path.split(maya_file_texture_name)[1] + project_relative_path = os.path.join(project_directory, 'sourceimages', file_name) + if os.path.exists(project_relative_path): + file_texture_name = project_relative_path + cmds.warning("file not found: {0}, using equivalent texture from sourceimages".format(maya_file_texture_name)) + else: + error_msg = "file not found: {0}".format(maya_file_texture_name) + cmds.error(error_msg) + raise RuntimeError(error_msg) + + if cmds.getAttr(file_node + '.useFrameExtension'): + split_file_texture_name = maya_file_texture_name.split('.') + frame_ofset = cmds.getAttr(file_node + '.frameOffset') + current_frame = cmds.currentTime(q=True) + frame_padding = len(split_file_texture_name[1]) + frame_number = str(int(current_frame + frame_ofset)).zfill(frame_padding) + file_texture_name = split_file_texture_name[0] + '.' + frame_number + '.' + split_file_texture_name[2] + + return file_texture_name + + +#-------------------------------------------------------------------------------------------------- +# Export .obj file. +# This function is a wrapper for the C++ obj exporter. +#-------------------------------------------------------------------------------------------------- + +def export_obj(object_name, file_path, overwrite=True): + directory = os.path.split(file_path)[0] + + if not os.path.exists(directory): + os.makedirs(directory) + + safe_file_path = file_path.replace('\\', '\\\\') + mel.eval('ms_export_obj -mesh "{0}" -filePath "{1}"'.format(object_name, safe_file_path)) + + +#-------------------------------------------------------------------------------------------------- +# Legalize a name. +#-------------------------------------------------------------------------------------------------- + +def legalizeName(filename): + filename = filename.replace('\\', '_') + filename = filename.replace('/', '_') + filename = filename.replace(':', '_') + filename = filename.replace('*', '_') + filename = filename.replace('?', '_') + filename = filename.replace('"', '') + filename = filename.replace('<', '_') + filename = filename.replace('>', '_') + filename = filename.replace('|', '_') + return filename + + +#-------------------------------------------------------------------------------------------------- +# List objects by shader. +#-------------------------------------------------------------------------------------------------- + +def listObjectsByShader(shader): + shading_engine = cmds.listConnections(shader, type='shadingEngine')[0] + return cmds.listConnections(shading_engine, type='mesh') + + +#-------------------------------------------------------------------------------------------------- +# Get connected node. +#-------------------------------------------------------------------------------------------------- + +def getConnectedNode(connection): + connections = cmds.listConnections(connection, destination=False, source=True) + return None if connections is None else connections[0] + + +#-------------------------------------------------------------------------------------------------- +# Material conversion. +#-------------------------------------------------------------------------------------------------- + +def convertAllMaterials(): + materials = cmds.ls(mat=True) + if not materials: + cmds.warning('no materials in the scene') + return + + for material in materials: + convertMaterial(material) + +def convertSelectedMaterials(): + materials = cmds.ls(sl=True, mat=True) + + if not materials: + cmds.warning('no materials selected') + return + + for material in materials: + convertMaterial(material) + +def convertMaterial(material): + material_type = cmds.nodeType(material) + + if material_type == 'phong' or material_type == 'blinn': + convertPhongBlinnMaterial(material) + elif material_type == 'ms_appleseed_material': + pass + elif material_type == 'surfaceShader': + convert_surface_shader_material(material) + elif material_type == 'lambert': + convert_lambert_material(material) + else: + cmds.warning("don't know how to convert material of type '{0}'".format(material_type)) + +def convertPhongBlinnMaterial(material): + print '// converting shader', material + + new_material_node = cmds.shadingNode('ms_appleseed_material', asShader=True, name=(material + '_translation')) + + # set random hardware color + cmds.setAttr(new_material_node + '.hardware_color_in', random.random(), random.random(), random.random(), type='float3') + + color_connection = getConnectedNode(material + '.color') + specular_color_connection = getConnectedNode(material + '.specularColor') + transparency_connection = getConnectedNode(material + '.transparency') + # bump_connection = getConnectedNode(material + '.bumpMapping') + + bsdf = createShadingNode('ashikhmin_brdf') + cmds.connectAttr(bsdf + '.outColor', new_material_node + '.BSDF_front_color') + + # edf = createShadingNode('diffuse_edf') + # cmds.connectAttr(edf + '.outColor', new_material_node + '.EDF_color') + + surface_shader = createShadingNode('physical_surface_shader') + cmds.connectAttr(surface_shader + '.outColor', new_material_node + '.surface_shader_front_color') + + # diffuse + color_value = cmds.getAttr(material + '.color')[0] + cmds.setAttr(bsdf + '.diffuse_reflectance', color_value[0], color_value[1], color_value[2], type='float3') + if color_connection: + print("connecting {0}.outColor to {1}.diffuse_reflectance".format(color_connection, bsdf)) + cmds.connectAttr(color_connection + '.outColor', bsdf + '.diffuse_reflectance') + + # glossy + color_value = cmds.getAttr(material + '.specularColor')[0] + cmds.setAttr(bsdf + '.glossy_reflectance', color_value[0], color_value[1], color_value[2], type='float3') + if specular_color_connection: + print("connecting {0}.outColor to {1}.glossy_reflectance".format(specular_color_connection, bsdf)) + cmds.connectAttr(specular_color_connection + '.outColor', bsdf + '.glossy_reflectance') + + # transparency + color_value = cmds.getAttr(material + '.transparency')[0] + cmds.setAttr(new_material_node + '.alpha_map_color', color_value[0], color_value[1], color_value[2], type='float3') + if transparency_connection: + print("connecting {0}.outColor to {1}.alpha_map_color".format(transparency_connection, new_material_node)) + cmds.connectAttr(transparency_connection + '.outColor', new_material_node + '.alpha_map_color') + + # shininess + material_type = cmds.nodeType(material) + if material_type == 'phong': + shininess = cmds.getAttr(material + '.cosinePower') + elif material_type == 'blinn': + # 0..1 -> 100..0 + shininess = 100.0 * (1.0 - cmds.getAttr(material + '.eccentricity')) + else: + shininess = 0.0 + shininess = max(shininess, 0.0) + cmds.setAttr(bsdf + '.shininess_u', shininess, shininess, shininess, type='float3') + cmds.setAttr(bsdf + '.shininess_v', shininess, shininess, shininess, type='float3') + + material_shading_group = cmds.listConnections(material, type='shadingEngine') + if material_shading_group != None: + cmds.connectAttr(new_material_node + '.outColor', material_shading_group[0] + '.surfaceShader', force=True) + + +def convert_surface_shader_material(material): + print '// converting shader', material + + new_material_node = cmds.shadingNode('ms_appleseed_material', asShader=True, name=(material + '_translation')) + + # set random hardware color + cmds.setAttr(new_material_node + '.hardware_color_in', random.random(), random.random(), random.random(), type='float3') + + out_color_connection = getConnectedNode(material + '.outColor') + out_transparency_connection = getConnectedNode(material + '.outTransparency') + + surface_shader = createShadingNode('constant_surface_shader') + cmds.connectAttr(surface_shader + '.outColor', new_material_node + '.surface_shader_front_color') + + # color + color_value = cmds.getAttr(material + '.outColor')[0] + cmds.setAttr(surface_shader + '.color', color_value[0], color_value[1], color_value[2], type='float3') + if out_color_connection: + print("connecting {0}.outColor to {1}.color".format(out_color_connection, surface_shader)) + cmds.connectAttr(out_color_connection + '.outColor', surface_shader + '.color') + + # transparency + color_value = cmds.getAttr(material + '.outTransparency')[0] + cmds.setAttr(new_material_node + '.alpha_map_color', color_value[0], color_value[1], color_value[2], type='float3') + if out_transparency_connection: + print("connecting {0}.outColor to {1}.alpha_map_color".format(out_transparency_connection, new_material_node)) + cmds.connectAttr(out_transparency_connection + '.outColor', new_material_node + '.alpha_map_color') + + material_shading_group = cmds.listConnections(material, type='shadingEngine') + if material_shading_group != None: + cmds.connectAttr(new_material_node + '.outColor', material_shading_group[0] + '.surfaceShader', force=True) + + +def convert_lambert_material(material): + print '// converting shader', material + + new_material_node = cmds.shadingNode('ms_appleseed_material', asShader=True, name=(material + '_translation')) + + # set random hardware color + cmds.setAttr(new_material_node + '.hardware_color_in', random.random(), random.random(), random.random(), type='float3') + + color_connection = getConnectedNode(material + '.color') + transparency_connection = getConnectedNode(material + '.transparency') + + brdf = createShadingNode('lambertian_brdf') + surface_shader = createShadingNode('physical_surface_shader') + + cmds.connectAttr(brdf + '.outColor', new_material_node + '.BSDF_front_color') + cmds.connectAttr(surface_shader + '.outColor', new_material_node + '.surface_shader_front_color') + + + # color + color_value = cmds.getAttr(material + '.color')[0] + cmds.setAttr(brdf + '.reflectance', color_value[0], color_value[1], color_value[2], type='float3') + if color_connection: + print("connecting {0}.outColor to {1}.reflectance".format(color_connection, surface_shader)) + cmds.connectAttr(color_connection + '.outColor', brdf + '.reflectance') + + # transparency + color_value = cmds.getAttr(material + '.transparency')[0] + cmds.setAttr(new_material_node + '.alpha_map_color', color_value[0], color_value[1], color_value[2], type='float3') + if transparency_connection: + print("connecting {0}.outColor to {1}.alpha_map_color".format(transparency_connection, new_material_node)) + cmds.connectAttr(transparency_connection + '.outColor', new_material_node + '.alpha_map_color') + + material_shading_group = cmds.listConnections(material, type='shadingEngine') + if material_shading_group != None: + cmds.connectAttr(new_material_node + '.outColor', material_shading_group[0] + '.surfaceShader', force=True) + + + +#-------------------------------------------------------------------------------------------------- +# returns list of materials connecetd to mesh. +#-------------------------------------------------------------------------------------------------- + +def get_attached_materials(mesh_name): + shading_engine = cmds.listConnections(mesh_name, t='shadingEngine') + if shading_engine: + return cmds.listConnections(shading_engine[0] + ".surfaceShader") + else: + return None diff --git a/sandbox/extras/maya/scripts/ms_commands.pyc b/sandbox/extras/maya/scripts/ms_commands.pyc deleted file mode 100644 index ef41aaaac1..0000000000 Binary files a/sandbox/extras/maya/scripts/ms_commands.pyc and /dev/null differ diff --git a/sandbox/extras/maya/scripts/ms_export.py b/sandbox/extras/maya/scripts/ms_export.py index 57fcd845b5..5af44b61bb 100644 --- a/sandbox/extras/maya/scripts/ms_export.py +++ b/sandbox/extras/maya/scripts/ms_export.py @@ -1,15 +1,17 @@ -# Copyright (c) 2012 Jonathan Topf +# +# Copyright (c) 2012 Jonathan Topf +# # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: - +# # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. - +# # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -17,11 +19,11 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. - +# import maya.cmds as cmds -import maya.mel +import maya.mel as mel import maya.utils as mu import os import time @@ -29,90 +31,152 @@ import subprocess import sys import ms_commands +import ms_export_obj +import time inch_to_meter = 0.02539999983236 +#-------------------------------------------------------------------------------------------------- +# WriteXml class. +#-------------------------------------------------------------------------------------------------- +class WriteXml(): + spaces_per_indentation_level = 4 -#**************************************************************************************************************************************************************************************************** -# utilitiy functions & classes ********************************************************************************************************************************************************************** -#**************************************************************************************************************************************************************************************************** - - -# -# writeXml class -- -# - -class WriteXml(): #(file_path) - spaces_per_indentation_level = 4 - def __init__(self, f_path): - self.file_path = f_path + def __init__(self, file_path): self.indentation_level = 0 self.file_object = None try: - self.file_object = open(self.file_path, 'w') #open file for editing - + self.file_object = open(file_path, 'w') except IOError: - cmds.error('IO error: file not accesable') - raise RuntimeError('IO error: file not accesable') - return - - def startElement(self,str): - self.file_object.write(((self.indentation_level * self.spaces_per_indentation_level) * ' ') + "<" + str + '>\n') + error_msg = "IO error: failed to open {0} for writing.".format(file_path) + cmds.error(error_msg) + raise RuntimeError(error_msg) + + def startElement(self, str): + self.appendLine("<" + str + ">") self.indentation_level += 1 def endElement(self, str): self.indentation_level -= 1 - self.file_object.write(((self.indentation_level * self.spaces_per_indentation_level) * ' ') + '\n') + self.appendLine("") def appendElement(self, str): - self.file_object.write(((self.indentation_level * self.spaces_per_indentation_level) * ' ') + '<' + str + '/>\n') - + self.appendLine("<" + str + "/>") + + def appendParameter(self, name, value): + self.appendLine(''.format(name, value)) + def appendLine(self, str): - self.file_object.write(((self.indentation_level * self.spaces_per_indentation_level) * ' ') + str + '\n') - + self.file_object.write(self.indentation_string() + str + "\n") + def close(self): - self.file_object.close() #close file + self.file_object.close() + def indentation_string(self): + return (self.indentation_level * self.spaces_per_indentation_level) * " " -# -# writeTransform function -- -# -def writeTransform(doc, scale = 1, transform = [[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]]): - doc.startElement('transform') - doc.appendElement('scaling value="{0}"'.format(scale)) - doc.startElement('matrix') +#-------------------------------------------------------------------------------------------------- +# cancelExport function. +#-------------------------------------------------------------------------------------------------- - doc.appendLine('{0:.15f} {1:.15f} {2:.15f} {3:.15f}'.format(transform[0][0], transform[1][0], transform[2][0], transform[3][0])) - doc.appendLine('{0:.15f} {1:.15f} {2:.15f} {3:.15f}'.format(transform[0][1], transform[1][1], transform[2][1], transform[3][1])) - doc.appendLine('{0:.15f} {1:.15f} {2:.15f} {3:.15f}'.format(transform[0][2], transform[1][2], transform[2][2], transform[3][2])) - doc.appendLine('{0:.15f} {1:.15f} {2:.15f} {3:.15f}'.format(transform[0][3], transform[1][3], transform[2][3], transform[3][3])) +def checkExportCancelled(): + if cmds.progressWindow(query=True, isCancelled=True): + cmds.progressWindow(endProgress=1) + raise RuntimeError('Export Cancelled') - doc.endElement('matrix') - doc.endElement('transform') -# -# load params function -# +#-------------------------------------------------------------------------------------------------- +# writeTransform function. +#-------------------------------------------------------------------------------------------------- + +def writeTransform(doc, scale = 1, object=False, motion=False, motion_samples=2): + if motion: + start_time = cmds.currentTime(query=True) + + if motion_samples < 2: + print('Motion samples is set too low, must be at least 2, using 2.') + motion_samples = 2 + + sample_interval = 1.0 / (motion_samples - 1) + + cmds.select(object) + + for i in range(motion_samples): + new_time = start_time + (sample_interval * i) + cmds.currentTime(new_time) + cmds.refresh() + + if object: + m = cmds.xform(object, query=True, ws=True, matrix=True) + transform = [m[0],m[1],m[2],m[3]], [m[4],m[5],m[6],m[7]], [m[8],m[9],m[10],m[11]], [m[12],m[13],m[14],m[15]] + else: + transform = [[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]] + + doc.startElement('transform time="{0:03}"'.format(i)) + doc.appendElement('scaling value="{0}"'.format(scale)) + doc.startElement('matrix') + + doc.appendLine('{0:.15f} {1:.15f} {2:.15f} {3:.15f}'.format(transform[0][0], transform[1][0], transform[2][0], transform[3][0])) + doc.appendLine('{0:.15f} {1:.15f} {2:.15f} {3:.15f}'.format(transform[0][1], transform[1][1], transform[2][1], transform[3][1])) + doc.appendLine('{0:.15f} {1:.15f} {2:.15f} {3:.15f}'.format(transform[0][2], transform[1][2], transform[2][2], transform[3][2])) + doc.appendLine('{0:.15f} {1:.15f} {2:.15f} {3:.15f}'.format(transform[0][3], transform[1][3], transform[2][3], transform[3][3])) + + doc.endElement('matrix') + doc.endElement('transform') + + cmds.currentTime(start_time) + cmds.select(cl=True) + + else: + + transform = [[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]] + if (object): + m = cmds.xform(object, query=True, ws=True, matrix=True) + transform = [m[0],m[1],m[2],m[3]], [m[4],m[5],m[6],m[7]], [m[8],m[9],m[10],m[11]], [m[12],m[13],m[14],m[15]] + + doc.startElement('transform') + doc.appendElement('scaling value="{0}"'.format(scale)) + doc.startElement('matrix') + + doc.appendLine('{0:.15f} {1:.15f} {2:.15f} {3:.15f}'.format(transform[0][0], transform[1][0], transform[2][0], transform[3][0])) + doc.appendLine('{0:.15f} {1:.15f} {2:.15f} {3:.15f}'.format(transform[0][1], transform[1][1], transform[2][1], transform[3][1])) + doc.appendLine('{0:.15f} {1:.15f} {2:.15f} {3:.15f}'.format(transform[0][2], transform[1][2], transform[2][2], transform[3][2])) + doc.appendLine('{0:.15f} {1:.15f} {2:.15f} {3:.15f}'.format(transform[0][3], transform[1][3], transform[2][3], transform[3][3])) + + doc.endElement('matrix') + doc.endElement('transform') + + +#-------------------------------------------------------------------------------------------------- +# getMayaParams function. +#-------------------------------------------------------------------------------------------------- def getMayaParams(render_settings_node): print('getting params from ui') - #comile regular expression to check for non numeric chracters - is_numeric = re.compile('^[0-9]+$') - + params = {'error':False} - + + params['entityDefs'] = ms_commands.getEntityDefs(os.path.join(ms_commands.ROOT_DIRECTORY, 'scripts', 'appleseedEntityDefs.xml')) + #main settings params['outputDir'] = cmds.getAttr(render_settings_node + '.output_directory') params['fileName'] = cmds.getAttr(render_settings_node + '.output_file') params['convertShadingNodes'] = cmds.getAttr(render_settings_node + '.convert_shading_nodes_to_textures') params['convertTexturesToExr'] = cmds.getAttr(render_settings_node + '.convert_textures_to_exr') - params['overwriteExistingExrs'] = cmds.getAttr(render_settings_node + '.overwrite_existing_exrs') + params['overwrite_existing_textures'] = cmds.getAttr(render_settings_node + '.overwrite_existing_textures') params['fileName'] = cmds.getAttr(render_settings_node + '.output_file') - params['exportMotionBlur'] = cmds.getAttr(render_settings_node + '.export_motion_blur') - params['exportAnimation'] = cmds.getAttr(render_settings_node + '.export_animation') + params['export_camera_blur'] = cmds.getAttr(render_settings_node + '.export_camera_blur') + params['exportMayaLights'] = cmds.getAttr(render_settings_node + '.export_maya_lights') + params['export_transformation_blur'] = cmds.getAttr(render_settings_node + '.export_transformation_blur') + params['export_deformation_blur'] = cmds.getAttr(render_settings_node + '.export_deformation_blur') + params['motion_samples'] = cmds.getAttr(render_settings_node + '.motion_samples') + params['export_animation'] = cmds.getAttr(render_settings_node + '.export_animation') + params['animation_start_frame'] = cmds.getAttr(render_settings_node + '.animation_start_frame') + params['animation_end_frame'] = cmds.getAttr(render_settings_node + '.animation_end_frame') + params['animatedTextures'] = cmds.getAttr(render_settings_node + '.export_animated_textures') params['scene_scale'] = 1 #Advanced options @@ -143,13 +207,13 @@ def getMayaParams(render_settings_node): params['matDefaultBSDF'] = 'Lambertian' params['matDefaultEDF'] = 'None' params['matDefaultSurfaceShader'] = 'Physical' - params['matDoubleShade'] = cmds.getAttr(render_settings_node + '.double_sided_shading') # output if cmds.listConnections(render_settings_node + '.camera'): params['outputCamera'] = cmds.listConnections(render_settings_node + '.camera')[0] else: - cmds.warning('no camera connected to ' + render_settings_node) + cmds.warning("no camera connected to {0}, using \"persp\"".format(render_settings_node)) + params['outputCamera'] = 'persp' if cmds.getAttr(render_settings_node + '.color_space') == 1: params['outputColorSpace'] = 'linear_rgb' @@ -160,35 +224,265 @@ def getMayaParams(render_settings_node): else: params['outputColorSpace'] = 'srgb' - params['outputResWidth'] = cmds.getAttr(render_settings_node + '.width') - params['outputResHeight'] = cmds.getAttr(render_settings_node + '.height') - - # configurations - # custom intercative config - params['customInteractiveConfigCheck'] = cmds.getAttr(render_settings_node + '.export_custom_interactive_config') - params['customInteractiveConfigEngine'] = cmds.getAttr(render_settings_node + '.interactive_lighting_engine') - params['customInteractiveConfigMinSamples'] = cmds.getAttr(render_settings_node + '.interactive_min_samples') - params['customInteractiveConfigMaxSamples'] = cmds.getAttr(render_settings_node + '.interactive_max_samples') - params['customInteractiveConfigMaxRayDepth'] = cmds.getAttr(render_settings_node + '.interactive_max_ray_depth') - params['customInteractiveConfigLightSamples'] = cmds.getAttr(render_settings_node + '.interactive_light_samples') + params['output_res_width'] = cmds.getAttr(render_settings_node + '.width') + params['output_res_height'] = cmds.getAttr(render_settings_node + '.height') + # configuration # custom Final config params['customFinalConfigCheck'] = cmds.getAttr(render_settings_node + '.export_custom_final_config') params['customFinalConfigEngine'] = cmds.getAttr(render_settings_node + '.final_lighting_engine') - params['customFinalConfigMinSamples'] = cmds.getAttr(render_settings_node + '.final_min_samples') - params['customFinalConfigMaxSamples'] = cmds.getAttr(render_settings_node + '.final_max_samples') - params['customFinalConfigMaxRayDepth'] = cmds.getAttr(render_settings_node + '.final_max_ray_depth') - params['customFinalConfigLightSamples'] = cmds.getAttr(render_settings_node + '.final_light_samples') - return(params) + params['customFinalConfigMinSamples'] = cmds.getAttr(render_settings_node + '.min_samples') + params['customFinalConfigMaxSamples'] = cmds.getAttr(render_settings_node + '.max_samples') + + + params['drtDLBSDFSamples'] = cmds.getAttr(render_settings_node + '.drt_dl_bsdf_samples') + params['drtDLLightSamples'] = cmds.getAttr(render_settings_node + '.drt_dl_light_samples') + params['drtEnableIBL'] = cmds.getAttr(render_settings_node + '.drt_enable_ibl') + params['drtIBLBSDFSamples'] = cmds.getAttr(render_settings_node + '.drt_ibl_bsdf_samples') + params['drtIBLEnvSamples'] = cmds.getAttr(render_settings_node + '.drt_ibl_env_samples') + params['drtMaxPathLength'] = cmds.getAttr(render_settings_node + '.drt_max_path_length') + params['drtRRMinPathLength'] = cmds.getAttr(render_settings_node + '.drt_rr_min_path_length') + + params['ptDLLightSamples'] = cmds.getAttr(render_settings_node + '.pt_dl_light_samples') + params['ptEnableCaustics'] = cmds.getAttr(render_settings_node + '.pt_enable_caustics') + params['ptEnableDL'] = cmds.getAttr(render_settings_node + '.pt_enable_dl') + params['ptEnableIBL'] = cmds.getAttr(render_settings_node + '.pt_enable_ibl') + params['ptIBLBSDFSamples'] = cmds.getAttr(render_settings_node + '.pt_ibl_bsdf_samples') + params['ptIBLEnvSamples'] = cmds.getAttr(render_settings_node + '.pt_ibl_env_samples') + params['ptMaxPathLength'] = cmds.getAttr(render_settings_node + '.pt_max_path_length') + params['ptNextEventEstimation'] = cmds.getAttr(render_settings_node + '.pt_next_event_estimation') + params['ptRRMinPathLength'] = cmds.getAttr(render_settings_node + '.pt_rr_min_path_length') + + params['gtrFilterSize'] = cmds.getAttr(render_settings_node + '.gtr_filter_size') + params['gtrMinSamples'] = cmds.getAttr(render_settings_node + '.gtr_min_samples') + params['gtrMaxSamples'] = cmds.getAttr(render_settings_node + '.gtr_max_samples') + params['gtrMaxContrast'] = cmds.getAttr(render_settings_node + '.gtr_max_contrast') + params['gtrMaxVariation'] = cmds.getAttr(render_settings_node + '.gtr_max_variation') + + if cmds.getAttr(render_settings_node + '.gtr_sampler') == 0: + params['gtrSampler'] = 'uniform' + else: + params['gtrSampler'] = 'adaptive' + + # select obj exporter + if cmds.pluginInfo(('ms_export_obj_' + str(int(mel.eval('getApplicationVersionAsFloat()')))), query=True, r=True): + params['obj_exporter'] = ms_commands.export_obj + else: + cmds.warning("no compiled obj exporter present, exporting using python obj exporter") + params['obj_exporter'] = ms_export_obj.export -#**************************************************************************************************************************************************************************************************** -# entity classes ************************************************************************************************************************************************************************************ -#**************************************************************************************************************************************************************************************************** -# -# color object --- -# + return params + +#-------------------------------------------------------------------------------------------------- +# GetMayaScene function. +#-------------------------------------------------------------------------------------------------- + +def get_maya_scene(params): + + """ Parses the maya scene and returns a list of root transforms with the relevant children """ + + start_time = cmds.currentTime(query=True) + + # the maya scene is stored as a list of root transforms that contain mesh's/geometry/lights as children + maya_root_transforms = [] + + # find all root transforms and create Mtransforms from them + for maya_transform in cmds.ls(tr=True): + if not cmds.listRelatives(maya_transform, ap=True): + maya_root_transforms.append(MTransform(params, maya_transform, None)) + + motion_samples = params['motion_samples'] + if motion_samples < 2: + motion_samples = 2 + + start_time = cmds.currentTime(query=True) + start_frame = int(start_time) + end_frame = start_frame + sample_increment = 1.0 / (motion_samples - 1) + + if params['export_animation']: + start_frame = params['animation_start_frame'] + end_frame = params['animation_end_frame'] + + if params['export_transformation_blur'] or params['export_deformation_blur'] or params['export_camera_blur']: + end_frame += 1 + + # add motion samples + current_frame = start_frame + + while current_frame <= end_frame: + cmds.currentTime(current_frame) + + if params['export_transformation_blur']: + for transform in maya_root_transforms: + for descendant_transform in transform.descendant_transforms: + descendant_transform.add_transform_sample() + + if params['export_deformation_blur']: + for transform in maya_root_transforms: + for mesh in transform.descendant_meshes: + mesh.add_deform_sample() + + if params['export_camera_blur']: + for transform in maya_root_transforms: + for camera in transform.descendant_cameras: + camera.add_matrix_sample() + + print cmds.currentTime(query=True) + current_frame += sample_increment + + # add code to export textures here + + + # return to pre-export time + cmds.currentTime(start_time) + + return maya_root_transforms + + +#-------------------------------------------------------------------------------------------------- +# MTransform class. +#-------------------------------------------------------------------------------------------------- + +class MTransform(): + + """ lightweight class representing info for a maya transform node """ + + def __init__(self, params, maya_transform_name, parent): + self.name = maya_transform_name + self.safe_name = ms_commands.legalizeName(self.name) + self.parent = parent + self.matricies = [] + self.child_cameras = [] + self.descendant_cameras = [] + self.child_meshes = [] + self.descendant_meshes = [] + self.child_lights = [] + self.descendant_lights = [] + self.child_transforms = [] + self.descendant_transforms = [] + + # get children + mesh_names = cmds.listRelatives(self.name, type='mesh') + if mesh_names != None: + for mesh_name in mesh_names: + self.child_meshes.append(MMesh(params, mesh_name, self)) + + light_names = cmds.listRelatives(self.name, type='light') + if light_names != None: + for light_name in light_names: + self.child_lights.append(MLight(params, light_name, self)) + + camera_names = cmds.listRelatives(self.name, type='camera') + if camera_names != None: + for camera_name in camera_names: + self.child_cameras.append(MCamera(params, camera_name, self)) + + transform_names = cmds.listRelatives(self.name, type='transform') + if transform_names != None: + for transform_name in transform_names: + new_transform = MTransform(params, transform_name, self) + self.child_transforms.append(new_transform) + + # add descendants + self.descendant_cameras += new_transform.child_cameras + self.descendant_meshes += new_transform.child_meshes + self.descendant_lights += new_transform.child_lights + self.descendant_transforms += new_transform.child_transforms + + def add_transform_sample(): + pass + +#-------------------------------------------------------------------------------------------------- +# MTransformChild class. +#-------------------------------------------------------------------------------------------------- + +class MTransformChild(): + + """ base class for all classes representing maya scene entities """ + + def __init__(self, params, maya_entity_name, MTransform_object): + self.params = params + self.name = maya_entity_name + self.safe_name = ms_commands.legalizeName(self.name) + self.transform = MTransform_object + +#-------------------------------------------------------------------------------------------------- +# MMesh class. +#-------------------------------------------------------------------------------------------------- + +class MMesh(MTransformChild): + + """ lightweight class representing maya mesh data """ + + def __init__(self, params, maya_mesh_name, MTransform_object): + MTransformChild.__init__(self, params, maya_mesh_name, MTransform_object) + self.material_names = ms_commands.get_attached_materials(self.name) + + def add_deform_sample(): + pass + + def export_obj(export_dir): + pass + +#-------------------------------------------------------------------------------------------------- +# MLight class. +#-------------------------------------------------------------------------------------------------- + +class MLight(MTransformChild): + + """ lightweight class representing maya light data """ + + def __init__(self, params, maya_light_name, MTransform_object): + MTransformChild.__init__(self, params, maya_light_name, MTransform_object) + self.color = cmds.getAttr(self.name + '.color') + self.multiplier = cmds.getAttr(self.name+'.intensity') + self.decay = cmds.getAttr(self.name+'.decayRate') + self.model = cmds.nodeType(self.name) + if self.model == 'spotLight': + self.inner_angle = cmds.getAttr(self.name + '.coneAngle') + self.outer_angle = cmds.getAttr(self.name + '.coneAngle') + cmds.getAttr(self.name + '.penumbraAngle') + + + +#-------------------------------------------------------------------------------------------------- +# MCamera class. +#-------------------------------------------------------------------------------------------------- + +class MCamera(MTransformChild): + + """ lightweight class representing maya camera data """ + + def __init__(self, params, maya_camera_name, MTransform_object): + MTransformChild.__init__(self, params, maya_camera_name, MTransform_object) + self.world_space_matricies = [] + + self.dof = (self.name + '.depthOfField' ) + self.focal_distance = cmds.getAttr(self.name + '.focusDistance') + self.focal_length = float(cmds.getAttr(self.name + '.focalLength')) / 1000 + self.f_stop = cmds.getAttr(self.name + '.fStop') + + maya_resolution_aspect = float(self.params['output_res_width']) / float(self.params['output_res_height']) + maya_film_aspect = cmds.getAttr(self.name + '.horizontalFilmAperture') / cmds.getAttr(self.name + '.verticalFilmAperture') + + if maya_resolution_aspect > maya_film_aspect: + self.film_width = float(cmds.getAttr(self.name + '.horizontalFilmAperture')) * inch_to_meter + self.film_height = self.film_width / maya_resolution_aspect + else: + self.film_height = float(cmds.getAttr(self.name + '.verticalFilmAperture')) * inch_to_meter + self.film_width = self.film_height * maya_resolution_aspect + + def add_matrix_sample(): + pass + + + + +#-------------------------------------------------------------------------------------------------- +# Color class. +#-------------------------------------------------------------------------------------------------- class Color(): def __init__(self, name, color, multiplier): @@ -199,19 +493,14 @@ def __init__(self, name, color, multiplier): self.wavelength_range = '400.0 700.0' self.alpha = 1.0 - print self.name - print self.color - print self.multiplier - - - def writeXML(self, doc): print('writing color {0}'.format(self.name)) - doc.startElement('color name="{0}"'.format(self.name)) - doc.appendElement('parameter name="color" value="{0:.6f} {1:.6f} {2:.6f}"'.format(self.color[0], self.color[1], self.color[2])) - doc.appendElement('parameter name="color_space" value="{0}"'.format(self.color_space)) - doc.appendElement('parameter name="multiplier" value="{0}"'.format(self.multiplier)) - doc.appendElement('parameter name="alpha" value="{0}"'.format(self.alpha)) + doc.startElement('color name="{0}"'.format(self.name)) + doc.appendParameter('color', '{0:.6f} {1:.6f} {2:.6f}'.format(self.color[0], self.color[1], self.color[2])) + doc.appendParameter('color_space', self.color_space) + doc.appendParameter('multiplier', self.multiplier) + doc.appendParameter('alpha', self.alpha) + doc.startElement('values') doc.appendLine('{0:.6f} {1:.6f} {2:.6f}'.format(self.color[0], self.color[1], self.color[2])) doc.endElement('values') @@ -220,199 +509,351 @@ def writeXML(self, doc): doc.endElement('alpha') doc.endElement('color') -# -# texture class -- -# + +#-------------------------------------------------------------------------------------------------- +# Texture class. +#-------------------------------------------------------------------------------------------------- class Texture(): - def __init__(self, name, file_name, color_space='srgb'): + def __init__(self, name, file_name, color_space='srgb', alpha_as_luminance=False): self.name = name - self.file_name = file_name + + directory = ms_commands.legalizeName(os.path.split(file_name)[0]) + filename = ms_commands.legalizeName(os.path.split(file_name)[1]) + self.filepath = os.path.join(directory, filename) + self.color_space = color_space + + if alpha_as_luminance: + self.alpha_mode = 'luminance' + else: + self.alpha_mode = 'alpha_channel' + def writeXMLObject(self, doc): print('writing texture object {0}'.format(self.name)) doc.startElement('texture name="{0}" model="disk_texture_2d"'.format(self.name)) - doc.appendElement('parameter name="color_space" value="{0}"'.format(self.color_space)) - doc.appendElement('parameter name="filename" value="{0}"'.format(self.file_name)) + doc.appendParameter('color_space', self.color_space) + doc.appendParameter('filename', self.filepath) doc.endElement('texture') + def writeXMLInstance(self, doc): print('writing texture instance {0}_inst'.format(self.name)) doc.startElement('texture_instance name="{0}_inst" texture="{0}"'.format(self.name, self.name)) - doc.appendElement('parameter name="addressing_mode" value="clamp"') - doc.appendElement('parameter name="filtering_mode" value="bilinear"') + doc.appendParameter('addressing_mode', 'clamp') + doc.appendParameter('filtering_mode', 'bilinear') + doc.appendParameter('alpha_mode', self.alpha_mode) doc.endElement('texture_instance') -# -# light object -- -# + +#-------------------------------------------------------------------------------------------------- +# Light class. +#-------------------------------------------------------------------------------------------------- class Light(): - def __init__(self, params, name): + def __init__(self, params, name, model='point_light'): self.params = params self.name = name + self.model = model self.color_name = self.name + '_exitance' self.color = cmds.getAttr(self.name+'.color')[0] self.multiplier = cmds.getAttr(self.name+'.intensity') self.decay = cmds.getAttr(self.name+'.decayRate') - m = cmds.getAttr(self.name+'.matrix') - self.transform = [m[0],m[1],m[2],m[3]], [m[4],m[5],m[6],m[7]], [m[8],m[9],m[10],m[11]], [m[12],m[13],m[14],m[15]] + self.inner_angle = None + self.outer_angle = None + def writeXML(self, doc): print('writing light: {0}'.format(self.name)) - doc.startElement('light name="{0}" model="point_light"'.format(self.name)) - doc.appendElement('parameter name="exitance" value="{0}"'.format(self.color_name)) - writeTransform(doc, 1, self.transform) + doc.startElement('light name="{0}" model="{1}"'.format(self.name, self.model)) + + # add spot light attribs if they exist + if self.model == 'spot_light': + doc.appendParameter('inner_angle', self.inner_angle) + doc.appendParameter('outer_angle', self.outer_angle) + + doc.appendParameter('exitance', self.color_name) + + writeTransform(doc, self.params['scene_scale'], self.name, self.params['export_transformation_blur'], self.params['motion_samples']) doc.endElement('light') -# -# shader object -- -# -class Material(): #object transform name - def __init__(self, params, name, bsdf=None, edf=None, surface_shader=None): +#-------------------------------------------------------------------------------------------------- +# Material class. +#-------------------------------------------------------------------------------------------------- + +class Material(): + def __init__(self, params, maya_node): self.params = params - self.name = name - self.shader_type = cmds.nodeType(self.name) - self.bsdf = bsdf - self.edf = edf - self.surface_shader = surface_shader - self.bsdf_color = (0.5, 0.5, 0.5, 1) - self.bsdf_texture = None - self.edf_color = (0,0,0,1) - self.edf_texture = None - self.specular_color = (0,0,0,1) - self.specular_texture = None - - #for shaders with color & incandescence attributes interpret them as bsdf and edf - if (self.shader_type == 'lambert') or (self.shader_type == 'blinn') or (self.shader_type == 'phong') or (self.shader_type == 'phongE'): - self.bsdf_color = ms_commands.normalizeRGB(cmds.getAttr(self.name+'.color')[0]) - self.edf_color = ms_commands.normalizeRGB(cmds.getAttr(self.name+'.incandescence')[0]) - color_connection = cmds.connectionInfo((self.name + '.color'), sourceFromDestination=True).split('.')[0] - incandecence_connection = cmds.connectionInfo((self.name+'.incandescence'), sourceFromDestination=True).split('.')[0] - if color_connection: - if cmds.nodeType(color_connection) == 'file': - print('# texture connected to {0}'.format(self.name + '.color')) - if params['convertTexturesToExr']: - self.bsdf_texture = ('textures/' + os.path.split(ms_commands.convertTexToExr(cmds.getAttr(color_connection+ '.fileTextureName'), os.path.join(params['outputDir'], 'textures'), params['overwriteExistingExrs']))[1]) - else: - self.bsdf_texture = cmds.getAttr(color_connection+ '.fileTextureName') - elif params['convertShadingNodes']: - #convert connection to exr - temp_dir = os.path.join(self.params['outputDir'],'temp') - temp_file = os.path.join(temp_dir, (color_connection + '.iff')) - ms_commands.convertConnectionToImage(self.name, 'color', temp_file, 1024) - self.bsdf_texture = ('textures/' + os.path.split(ms_commands.convertTexToExr(temp_file, os.path.join(params['outputDir'], 'textures'), params['overwriteExistingExrs']))[1]) - - - if incandecence_connection: - if cmds.nodeType(incandecence_connection) == 'file': - print('texture connected to {0}'.format(self.name + '.incandescence')) - if params['convertTexturesToExr']: - self.edf_texture = ('textures/' + os.path.split(ms_commands.convertTexToExr(cmds.getAttr(incandecence_connection+ '.fileTextureName'), os.path.join(params['outputDir'], 'textures'), params['overwriteExistingExrs']))[1]) - else: - self.edf_texture = cmds.getAttr(incandecence_connection+ '.fileTextureName') - else: - #convert connection to exr - temp_file = os.path.join(params['outputDir'], 'temp_files', (incandecence_connection + '.iff')) - ms_commands.convertConnectionToImage(self.name, 'incandescence', temp_file, 1024) - self.edf_texture = ('textures/' + os.path.split(ms_commands.convertTexToExr(temp_file, os.path.join(params['outputDir'], 'textures'), params['overwriteExistingExrs']))[1]) - - - - #get specular conponent for shaders which have one - elif (self.shader_type == 'blinn') or (self.shader_type == 'phong') or (self.shader_type == 'phongE'): - self.specular_color = ms_commands.normalizeRGB(cmds.getAttr(self.name+'.specularColor')[0]) - specular_connection = cmds.connectionInfo((self.name + '.specularColor'), sourceFromDestination=True).split('.')[0] - if specular_connection: - if cmds.nodeType(specular_connection) == 'file': - print('texture connected to {0}'.format(self.name + '.specularColor')) - if params['convertTexturesToExr']: - self.specular_texture = ('textures/' + os.path.split(ms_commands.convertTexToExr(cmds.getAttr(specular_connection+ '.fileTextureName'), os.path.join(params['outputDir'], 'textures'), params['overwriteExistingExrs']))[1]) + self.name = maya_node + self.safe_name = ms_commands.legalizeName(self.name) + self.duplicate_shaders = cmds.getAttr(self.name + '.duplicate_front_attributes_on_back') + self.shading_nodes = [] + self.colors = [] + self.textures = [] + self.enable_front = cmds.getAttr(self.name + '.enable_front_material') + self.enable_back = cmds.getAttr(self.name + '.enable_back_material') + + self.bsdf_front = self.getMayaAttr(self.name + '.BSDF_front_color') + self.edf_front = self.getMayaAttr(self.name + '.EDF_front_color') + self.surface_shader_front = self.getMayaAttr(self.name + '.surface_shader_front_color') + self.normal_map_front = self.getMayaAttr(self.name + '.normal_map_front_color') + self.alpha_map = self.getMayaAttr(self.name + '.alpha_map_color') + if self.alpha_map != None: + self.alpha_map.alpha_mode = 'luminance' + + #only use front shaders on back if box is checked + if not self.duplicate_shaders: + self.bsdf_back = self.getMayaAttr(self.name + '.BSDF_back_color') + self.edf_back = self.getMayaAttr(self.name + '.EDF_back_color') + self.surface_shader_back = self.getMayaAttr(self.name + '.surface_shader_back_color') + self.normal_map_back = self.getMayaAttr(self.name + '.normal_map_back_color') + + self.shading_nodes += [self.bsdf_front, + self.bsdf_back, + self.edf_front, + self.edf_back, + self.surface_shader_front, + self.surface_shader_back] + + self.textures = self.textures + [self.normal_map_front, + self.normal_map_back, + self.alpha_map] + + else: + self.bsdf_back, self.edf_back, self.surface_shader_back, self.normal_map_back = self.bsdf_front, self.edf_front, self.surface_shader_front, self.normal_map_front + + self.shading_nodes += [self.bsdf_front, + self.edf_front, + self.surface_shader_front] + + self.textures += [self.normal_map_front, self.alpha_map] + + def getMayaAttr(self, attr_name): + connection = cmds.listConnections(attr_name) + if connection: + if cmds.nodeType(connection[0]) == 'ms_appleseed_shading_node': + shading_node = ShadingNode(self.params, connection[0]) + self.shading_nodes = self.shading_nodes + [shading_node] + shading_node.getChildren() + self.colors += shading_node.colors + self.textures += shading_node.textures + return shading_node + + elif cmds.nodeType(connection[0]) == 'file': + maya_texture_file = ms_commands.getFileTextureName(connection[0]) + texture = ms_commands.convertTexToExr(maya_texture_file, self.params['absolute_tex_dir'], overwrite=self.params['overwrite_existing_textures'], pass_through=False) + texture_node = Texture((connection[0] + '_texture'), (os.path.join(self.params['tex_dir'], os.path.split(texture)[1])), color_space='srgb') + attribute_value = (texture_node.name + '_inst') + self.textures += [texture_node] + return texture_node + + else: + return None + + def getShadingNodes(self): + return self.shading_nodes + + def writeXML(self, doc): + if self.duplicate_shaders: + if self.enable_front: + print('writing material {0}'.format(self.name)) + doc.startElement('material name="{0}" model="generic_material"'.format(self.name)) + if self.bsdf_front: + doc.appendParameter('bsdf', self.bsdf_front.name) + if self.edf_front: + doc.appendParameter('edf', self.edf_front.name) + doc.appendParameter('surface_shader', self.surface_shader_front.name) + if self.alpha_map: + doc.appendParameter('alpha_map', self.alpha_map.name + '_inst') + if self.normal_map_front: + doc.appendParameter('normal_map', self.normal_map_front.name + '_inst') + doc.endElement('material') + else: + if self.enable_front: + print('writing material {0}_front'.format(self.name)) + doc.startElement('material name="{0}_front" model="generic_material"'.format(self.name)) + if self.bsdf_front: + doc.appendParameter('bsdf', self.bsdf_front.name) + if self.edf_front: + doc.appendParameter('edf', self.edf_front.name) + doc.appendParameter('surface_shader', self.surface_shader_front.name) + if self.alpha_map: + doc.appendParameter('alpha_map', self.alpha_map.name + '_inst') + if self.normal_map_front: + doc.appendParameter('normal_map', self.normal_map_front.name + '_inst') + doc.endElement('material') + if self.enable_back: + print('writing material {0}_back'.format(self.name)) + doc.startElement('material name="{0}_back" model="generic_material"'.format(self.name)) + if self.bsdf_back: + doc.appendParameter('bsdf', self.bsdf_back.name) + if self.edf_back: + doc.appendParameter('edf', self.edf_back.name) + doc.appendParameter('surface_shader', self.surface_shader_back.name) + if self.alpha_map: + doc.appendParameter('alpha_map', self.alpha_map.name + '_inst') + if self.normal_map_back: + doc.appendParameter('normal_map', self.normal_map_back.name + '_inst') + doc.endElement('material') + +#-------------------------------------------------------------------------------------------------- +# ShadingNode class. +#-------------------------------------------------------------------------------------------------- + +class ShadingNode(): + def __init__(self, params, name, attributes=False, node_type=False, model=False): + self.params = params + self.name = name + self.type = node_type # bsdf etc + self.model = model # ashikhmin-shirley etc + self.child_shading_nodes = [] + self.attributes = dict() + self.colors = [] + self.textures = [] + + #if the node comes with attributes to initialize with then use them + if attributes: + self.attributes = attributes + + #else find them from maya + else: + self.type = cmds.getAttr(self.name + '.node_type') #bsdf, edf etc + self.model = cmds.getAttr(self.name + '.node_model') #lambertian etc + + + #add the correct attributes based on the entity defs xml + for attribute_key in params['entityDefs'][self.model].attributes.keys(): + self.attributes[attribute_key] = '' + + for attribute_key in self.attributes.keys(): + maya_attribute = self.name + '.' + attribute_key + + #create variable to story the final string value + attribute_value = '' + + #if the attribute is a color/entity + + if params['entityDefs'][self.model].attributes[attribute_key].type == 'entity_picker': + + #get attribute color value + attribute_color = cmds.getAttr(maya_attribute)[0] + connected_node = None + + #check for connected node + connection = cmds.listConnections(maya_attribute, destination=False, source=True) + if connection: + connected_node = connection[0] + + #if there is a node connected + if connected_node: + + #if the node is an appleseed shading node + if cmds.nodeType(connected_node) == 'ms_appleseed_shading_node': + shading_node = ShadingNode(self.params, connected_node) + attribute_value = shading_node.name + self.child_shading_nodes = self.child_shading_nodes + [shading_node] + shading_node.child_shading_nodes + self.colors += shading_node.colors + self.textures = self.textures + shading_node.textures + + #else if its a maya texture node + elif cmds.nodeType(connected_node) == 'file': + maya_texture_file = ms_commands.getFileTextureName(connected_node) + texture = ms_commands.convertTexToExr(maya_texture_file, params['absolute_tex_dir'], overwrite=self.params['overwrite_existing_textures'], pass_through=False) + texture_node = Texture((connected_node + '_texture'), (os.path.join(params['tex_dir'], os.path.split(texture)[1])), color_space='srgb') + attribute_value = (texture_node.name + '_inst') + self.textures += [texture_node] + + # if the node is unrecognized, bake it + else: + if self.params['convertShadingNodes']: + print '***********', maya_attribute + print '***********', connection + print '***********', connected_node + print '***********', self.name + print '***********', attribute_key + #convert texture and get path + output_texture = os.path.join(params['tex_dir'], (connected_node + '.exr')) + texture = ms_commands.convertConnectionToImage(self.name, attribute_key, output_texture, resolution=1024) + texture_node = Texture((connected_node + '_texture'), (os.path.join(params['tex_dir'], os.path.split(texture)[1])), color_space='srgb') + attribute_value = (texture_node.name + '_inst') + self.textures += [texture_node] + + # no node is connected, just use the color value else: - self.specular_texture = cmds.getAttr(specular_connection+ '.fileTextureName') + # if that color is gray interpret the R value as a 1-dimensional value + if (attribute_color[0] == attribute_color[1]) and (attribute_color[0] == attribute_color[2]): + attribute_value = str(attribute_color[0]) + + # if its not black it must be a color so create a color node + elif attribute_color != (0,0,0): + color_name = self.name + '_' + attribute_key + '_color' + normalized_color = ms_commands.normalizeRGB(attribute_color) + color_node = Color(color_name, normalized_color[:3], normalized_color[3]) + attribute_value = color_node.name + self.colors += [color_node] + + elif params['entityDefs'][self.model].attributes[attribute_key].type == 'dropdown_list': + pass + # the node must be a text entity else: - #convert connection to exr - temp_file = os.path.join(params['outputDir'], 'temp_files', (specular_connection + '.iff')) - ms_commands.convertConnectionToImage(self.name, 'specularColor', temp_file, 1024) - self.specular_texture = ('textures/' + os.path.split(ms_commands.convertTexToExr(temp_file, os.path.join(params['outputDir'], 'textures'), params['overwriteExistingExrs']))[1]) - - #for surface shaders interpret outColor as bsdf and edf - elif self.shader_type == 'surfaceShader': - self.edf_color = ms_commands.normalizeRGB(cmds.getAttr(self.name+'.outColor')[0]) - self.bsdf_color = self.edf_color - - - outColor_connection = cmds.connectionInfo((self.name+'.outColor'), sourceFromDestination=True).split('.')[0] - if outColor_connection: - if cmds.nodeType(outColor_connection) == 'file': - print('texture connected to {0}'.format(self.name + '.outColor')) - if params['convertTexturesToExr']: - self.bsdf_texture = ('textures/' + os.path.split(ms_commands.convertTexToExr(cmds.getAttr(outColor_connection+ '.fileTextureName'), os.path.join(params['outputDir'], 'textures'), params['overwriteExistingExrs']))[1]) - else: - self.bsdf_texture = cmds.getAttr(outColor_connection+ '.fileTextureName') + attribute_value = str(cmds.getAttr(maya_attribute)) - self.edf_texture = self.bsdf_texture - else: - #convert connection to exr - temp_file = os.path.join(params['outputDir'], 'temp_files', (outColor_connection + '.iff')) - ms_commands.convertConnectionToImage(self.name, 'outColor', temp_file, 1024) - self.edf_texture = ('textures/' + os.path.split(ms_commands.convertTexToExr(temp_file, os.path.join(params['outputDir'], 'textures'), params['overwriteExistingExrs']))[1]) + # add attribute to dict + self.attributes[attribute_key] = attribute_value - else: - self.bsdf_texture = None - self.edf_texture = None + def getChildren(self): + return self.child_shading_nodes - #else use default shader - else: - cmds.error('no valid texture connected to {0} using default'.format(self.name)) - self.name = 'default_texture' + def writeXML(self, doc): + print('writing shading node {0}'.format(self.name)) + doc.startElement('{0} name="{1}" model="{2}"'.format(self.type, self.name, self.model)) - def writeXML(self,doc): + #add the relevant parameters + for attribute_key in self.attributes.keys(): + #only output the attribute if it has a value + if self.attributes[attribute_key]: + doc.appendParameter(attribute_key, self.attributes[attribute_key]) - print('writing material {0}'.format(self.name)) - doc.startElement('material name="{0}" model="generic_material"'.format(self.name)) - if self.bsdf: - doc.appendElement('parameter name="bsdf" value="{0}"'.format(self.bsdf)) - if self.edf: - doc.appendElement('parameter name="edf" value="{0}"'.format(self.edf)) - if self.surface_shader: - doc.appendElement('parameter name="surface_shader" value="{0}"'.format(self.surface_shader)) - doc.endElement('material') + doc.endElement(self.type) -# -# bsdf class -- -# + +#-------------------------------------------------------------------------------------------------- +# Bsdf class. +#-------------------------------------------------------------------------------------------------- class Bsdf(): def __init__(self, name, model, bsdf_params): self.name = name self.model = model self.bsdf_params = bsdf_params + def writeXML(self, doc): print('writing bsdf {0}'.format(self.name)) doc.startElement('bsdf name="{0}" model="{1}"'.format(self.name, self.model)) for param in self.bsdf_params: - doc.appendElement('parameter name="{0}" value="{1}"'.format(param, self.bsdf_params[param])) + doc.appendParameter(param, self.bsdf_params[param]) doc.endElement('bsdf') -# -# edf class -- -# + +#-------------------------------------------------------------------------------------------------- +# Edf class. +#-------------------------------------------------------------------------------------------------- class Edf(): def __init__(self, name, model, edf_params): self.name = name self.model = model self.edf_params = edf_params + def writeXML(self, doc): print('writing bsdf {0}'.format(self.name)) doc.startElement('edf name="{0}" model="{1}"'.format(self.name, self.model)) for param in self.edf_params: - doc.appendElement('parameter name="{0}" value="{1}"'.format(param, self.edf_params[param])) + doc.appendParameter(param, self.edf_params[param]) doc.endElement('edf') -# -# surface shader class -- -# + +#-------------------------------------------------------------------------------------------------- +# SurfaceShader class. +#-------------------------------------------------------------------------------------------------- class SurfaceShader(): def __init__(self, name, model, surface_shader_params=None): @@ -424,28 +865,28 @@ def writeXML(self, doc): doc.startElement('surface_shader name="{0}" model="{1}"'.format(self.name, self.model)) if self.model == 'constant_surface_shader': for param in self.surface_shader_params: - doc.appendElement('parameter name="{0}" value="{1}"'.format(param, self.surface_shader_params[param])) + doc.appendParameter(param, self.surface_shader_params[param]) doc.endElement('surface_shader') -# -# camera class -- -# +#-------------------------------------------------------------------------------------------------- +# Camera class. +#-------------------------------------------------------------------------------------------------- -class Camera(): #(camera_name) +class Camera(): def __init__(self, params, cam): self.params = params - if self.params['sceneCameraDefaultThinLens'] or cmds.getAttr(cam+'.depthOfField'): + if self.params['sceneCameraDefaultThinLens'] or cmds.getAttr(cam + '.depthOfField'): self.model = 'thinlens_camera' - self.f_stop = cmds.getAttr(cam+'.fStop') - self.focal_distance = cmds.getAttr(cam+'.focusDistance') - self.diaphram_blades = 0 - self.diaphram_tilt_angle = 0.0 + self.f_stop = cmds.getAttr(cam + '.fStop') + self.focal_distance = cmds.getAttr(cam + '.focusDistance') + self.diaphragm_blades = 0 + self.diaphragm_tilt_angle = 0.0 else: self.model = 'pinhole_camera' self.name = cam - maya_resolution_aspect = float(params['outputResWidth'])/float(params['outputResHeight']) + maya_resolution_aspect = float(params['output_res_width']) / float(params['output_res_height']) maya_film_aspect = cmds.getAttr(cam + '.horizontalFilmAperture') / cmds.getAttr(cam + '.verticalFilmAperture') if maya_resolution_aspect > maya_film_aspect: @@ -455,32 +896,35 @@ def __init__(self, params, cam): self.film_height = float(cmds.getAttr(self.name + '.verticalFilmAperture')) * inch_to_meter self.film_width = self.film_height * maya_resolution_aspect - - self.focal_length = float(cmds.getAttr(self.name+'.focalLength')) / 1000 + # transpose camera matrix -> XXX0, YYY0, ZZZ0, XYZ1 - m = cmds.getAttr(cam+'.matrix') + m = cmds.xform(cam, query=True, ws=True, matrix=True) self.transform = [m[0],m[1],m[2],m[3]], [m[4],m[5],m[6],m[7]], [m[8],m[9],m[10],m[11]], [m[12],m[13],m[14],m[15]] def writeXML(self, doc): print('writing camera: {0}'.format(self.name)) doc.startElement('camera name="{0}" model="{1}"'.format(self.name, self.model)) - doc.appendElement('parameter name="film_dimensions" value="{0} {1}"'.format(self.film_width, self.film_height)) - doc.appendElement('parameter name="focal_length" value="{0}"'.format(self.focal_length)) + + doc.appendParameter('film_dimensions', '{0} {1}'.format(self.film_width, self.film_height)) + doc.appendParameter('focal_length', self.focal_length) + if self.model == 'thinlens_camera': print('exporting ' + self.name + ' as thinlens camera') - doc.appendElement('parameter name="focal_distance" value="{0}"'.format(self.focal_distance)) - doc.appendElement('parameter name="f_stop" value="{0}"'.format(self.f_stop)) - doc.appendElement('parameter name="diaphragm_blades" value="{0}"'.format(self.diaphram_blades)) - doc.appendElement('parameter name="diaphragm_tilt_angle" value="{0}"'.format(self.diaphram_tilt_angle)) + doc.appendParameter('focal_distance', self.focal_distance) + doc.appendParameter('f_stop', self.f_stop) + doc.appendParameter('diaphragm_blades', self.diaphragm_blades) + doc.appendParameter('diaphragm_tilt_angle', self.diaphragm_tilt_angle) + #output transform matrix - writeTransform(doc, self.params['scene_scale'], self.transform) + writeTransform(doc, self.params['scene_scale'], self.name, self.params['export_camera_blur'], self.params['motion_samples']) + doc.endElement('camera') -# -# environment class -- -# +#-------------------------------------------------------------------------------------------------- +# Environment class. +#-------------------------------------------------------------------------------------------------- class Environment(): def __init__(self, params, name, shader, edf): @@ -488,480 +932,401 @@ def __init__(self, params, name, shader, edf): self.name = name self.environment_shader = shader self.environment_edf = edf + def writeXML(self, doc): print('writing environment: ' + self.name) doc.startElement('environment name="{0}" model="generic_environment"'.format(self.name)) - doc.appendElement('parameter name="environment_edf" value="{0}"'.format(self.environment_edf)) - doc.appendElement('parameter name="environment_shader" value="{0}"'.format(self.environment_shader)) + doc.appendParameter('environment_edf', self.environment_edf) doc.endElement('environment') -# -# environment shader class -- -# + +#-------------------------------------------------------------------------------------------------- +# EnvironmentShader class. +#-------------------------------------------------------------------------------------------------- class EnvironmentShader(): def __init__(self, name, edf): self.name = name self.edf = edf + def writeXML(self, doc): print('writing environment shader: ' + self.name) doc.startElement('environment_shader name="{0}" model="edf_environment_shader"'.format(self.name)) - doc.appendElement('parameter name="environment_edf" value="{0}"'.format(self.edf)) + doc.appendParameter('environment_edf', self.edf) doc.endElement('environment_shader') -# -# environment edf class -- -# + +#-------------------------------------------------------------------------------------------------- +# EnvironmentEdf class. +#-------------------------------------------------------------------------------------------------- class EnvironmentEdf(): def __init__(self, name, model, edf_params): self.name = name self.model = model self.edf_params = edf_params + def writeXML(self, doc): print('writing environment edf: ' + self.name) doc.startElement('environment_edf name="{0}" model="{1}"'.format(self.name, self.model)) for param in self.edf_params: - doc.appendElement('parameter name ="{0}" value="{1}"'.format(param, self.edf_params[param])) + doc.appendParameter(param, self.edf_params[param]) doc.endElement('environment_edf') -# -# geometry class -- -# + +#-------------------------------------------------------------------------------------------------- +# Geometry class. +#-------------------------------------------------------------------------------------------------- class Geometry(): def __init__(self, params, name, output_file, assembly='main_assembly'): + checkExportCancelled() self.params = params self.name = name - #get name in heirarchy - self.heirarchy_name = name + self.safe_name = ms_commands.legalizeName(name) + + self.hierarchy_name = name + self.material_nodes = [] + self.shading_nodes = [] + self.colors = [] + self.textures = [] current_object = name while cmds.listRelatives(current_object, parent=True): current_object = cmds.listRelatives(current_object, parent=True)[0] - self.heirarchy_name = current_object + ' ' + self.heirarchy_name + self.hierarchy_name = current_object + ' ' + self.hierarchy_name self.output_file = output_file self.assembly = assembly + + # get material name - shape = cmds.listRelatives(self.name, s=True)[0] - shadingEngine = None - if not (cmds.listConnections(shape, t='shadingEngine')): - cmds.error('no shader connected to ' + shape) + shape_node = cmds.listRelatives(self.name, shapes=True)[0] + + #get list of unique shading engines + shading_engines = set(cmds.listConnections(shape_node, t='shadingEngine')) + + if shading_engines: + for shading_engine in shading_engines: + connected_material = cmds.listConnections(shading_engine + ".surfaceShader") + if connected_material != None: + if cmds.nodeType(connected_material[0]) == 'ms_appleseed_material': + # this is an appleseed material + new_material = Material(self.params, connected_material[0]) + self.material_nodes.append(new_material) + self.shading_nodes = self.shading_nodes + new_material.getShadingNodes() + self.colors = self.colors + new_material.colors + self.textures = self.textures + new_material.textures + else: + cmds.warning("no appleseed material or shader translation connected to {0}".format(self.name)) else: - shadingEngine = cmds.listConnections(shape, t='shadingEngine')[0] - self.material = cmds.connectionInfo((shadingEngine + ".surfaceShader"),sourceFromDestination=True).split('.')[0] #find the attribute the surface shader is plugged into athen split off the attribute name to leave the shader name - - # transpose camera matrix -> XXX0, YYY0, ZZZ0, XYZ1 - m = cmds.getAttr(name+'.matrix') + cmds.warning("no shading engine connected to {0}".format(self.name)) + + # transpose matrix -> XXX0, YYY0, ZZZ0, XYZ1 + m = cmds.xform(name, query=True, ws=True, matrix=True) self.transform = [m[0],m[1],m[2],m[3]], [m[4],m[5],m[6],m[7]], [m[8],m[9],m[10],m[11]], [m[12],m[13],m[14],m[15]] + def getMaterials(self): + return self.material_nodes + + def getShadingNodes(self): + return self.shading_nodes + def writeXMLInstance(self, doc): - print('writing objecct instance: '+self.name) - doc.startElement('object_instance name="{0}.0_inst" object="{1}.0"'.format(self.name, self.name)) - writeTransform(doc) - doc.appendElement('assign_material slot="0" side="front" material="{0}"'.format(self.material)) - if self.params['matDoubleShade']: - doc.appendElement('assign_material slot="0" side="back" material="{0}"'.format(self.material)) + print('writing object instance: '+ self.name) + doc.startElement('object_instance name="{0}.0_inst" object="{1}.0"'.format(self.safe_name, self.safe_name)) + + if self.params['export_transformation_blur']: + # write 0 transform as the assembly will handle that + writeTransform(doc) + else: + writeTransform(doc, self.params['scene_scale'], self.name) + + for material in self.material_nodes: + if material.duplicate_shaders: + if material.enable_front: + doc.appendElement('assign_material slot="{0}" side="front" material="{1}"'.format(material.name, material.name)) + if material.enable_back: + doc.appendElement('assign_material slot="{0}" side="back" material="{1}"'.format(material.name, material.name)) + else: + if material.enable_front: + doc.appendElement('assign_material slot="{0}" side="front" material="{1}_front"'.format(material.name, material.name)) + if material.enable_back: + doc.appendElement('assign_material slot="{0}" side="back" material="{1}_back"'.format(material.name, material.name)) doc.endElement('object_instance') -# -# assembly object -- -# + + +#-------------------------------------------------------------------------------------------------- +# Assembly class. +#-------------------------------------------------------------------------------------------------- class Assembly(): - def __init__(self, params, name='main_assembly'): + def __init__(self, params, name='main_assembly', object_list=False, position_from_object=False): + checkExportCancelled() self.params = params - self.name = name + self.name = ms_commands.legalizeName(name) + self.position_from_object = position_from_object self.light_objects = [] - self.geo_objects = dict() - self.material_objects = dict() - self.color_objects = dict() - self.texture_objects = dict() - self.surface_shader_objects = dict() - self.bsdf_objects = dict() - self.edf_objects = dict() - - #if name is default populate list with all lights otherwise just lights from set with the same name as the object - if (self.name == 'main_assembly'): - for light_shape in cmds.ls(lights=True): - self.light_objects.append(Light(self.params, cmds.listRelatives(light_shape, ad=True, ap=True)[0])) - else: - for light_shape in cmds.listRelatives(self.name, typ='light'): - self.light_objects.append(Light(self.params, cmds.listRelatives(light_shape, ad=True, ap=True)[0])) - #add light colors to list - for light_object in self.light_objects: - self.addColor(light_object.color_name, light_object.color, light_object.multiplier) - - if not len(self.light_objects): - cmds.warning('no light present in: ' + self.name) - - #if name is default populate list with all geometry otherwise just geometry from set with the same name as the object - if (self.name == 'main_assembly'): - #create a list of all geometry objects and itterate over them - for geo in cmds.ls(typ='mesh'): - if (ms_commands.shapeIsExportable(geo) and ms_commands.hasShaderConnected(geo)): - geo_transform = cmds.listRelatives(geo, ad=True, ap=True)[0] + self.geo_objects = [] + self.material_objects = [] + self.shading_node_objects = [] + self.color_objects = [] + self.texture_objects = [] + + # add shape nodes as geo objects + if object_list: + for object in object_list: + if cmds.nodeType(object) == 'mesh': + geo_transform = cmds.listRelatives(object, ad=True, ap=True)[0] if not (geo_transform in self.geo_objects): - self.geo_objects[geo_transform] = Geometry(self.params, geo_transform, ('geo/'+self.name+'.obj'), self.name) - else: - for geo in cmds.listConnections(self.name, sh=True): - if (ms_commands.shapeIsExportable(geo) and ms_commands.hasShaderConnected(geo)): - geo_transform = cmds.listRelatives(geo, ad=True, ap=True)[0] - if not geo_transform in self.geo_objects: - self.geo_objects[geo_transform] = Geometry(self.params, geo_transform, ('geo/'+self.name+'.obj'), self.name) - - #populate list with individual materials - for geo in self.geo_objects: - self.addMaterial(self.geo_objects[geo].material) - #if there are no objects in the scene raise error - if not len(self.geo_objects): - cmds.error('no objects present in ' + self.name) - raise RuntimeError('no objects present in ' + self.name) - - def addColor(self, name, value, multiplier=1): - if not name in self.color_objects: - self.color_objects[name] = Color(name, value, multiplier) + geo_filename = self.name + '.obj' + geo_filepath = os.path.join(self.params['geo_dir'], geo_filename) + self.geo_objects.append(Geometry(self.params, geo_transform, geo_filepath, self.name)) + elif (cmds.nodeType(object) == 'pointLight') and self.params['exportMayaLights']: + light_transform = cmds.listRelatives(object, ad=True, ap=True)[0] + if not (light_transform in self.light_objects): + self.light_objects.append(Light(self.params, cmds.listRelatives(object, ad=True, ap=True)[0])) + elif (cmds.nodeType(object) == 'spotLight') and self.params['exportMayaLights']: + light_transform = cmds.listRelatives(object, ad=True, ap=True)[0] + if not (light_transform in self.light_objects): + light_object = Light(self.params, cmds.listRelatives(object, ad=True, ap=True)[0]) + light_object.model = 'spot_light' + light_object.inner_angle = cmds.getAttr(object + '.coneAngle') + light_object.outer_angle = cmds.getAttr(object + '.coneAngle') + cmds.getAttr(object + '.penumbraAngle') + self.light_objects.append(light_object) + + # add light colors to list + for light_object in self.light_objects: + light_color_object = Color(light_object.color_name, light_object.color, light_object.multiplier) + self.color_objects.append(light_color_object) - def addTexture(self, name, file_name): - if not name in self.texture_objects: - self.texture_objects[name] = Texture(name, file_name) - - def addEDF(self, material, type): - edf_params = dict() - if type == 'Diffuse': - if material.edf_texture: - self.addTexture(material.name + '_exitance', material.edf_texture) - edf_params['exitance'] = (material.name + '_exitance_inst') - else: - self.addColor((material.name + '_exitance'), material.edf_color[0:3], material.edf_color[3]) - edf_params['exitance'] = material.name + '_exitance' - self.edf_objects[material.name + '_edf'] = Edf(material.name + '_edf', 'diffuse_edf', edf_params) - - def addBSDF(self, material, type): - print('translating {0} to {1} BSDF'.format(material.name, type)) - bsdf_params = dict() - if type == 'Lambertian': - #add reflectence component - if material.bsdf_texture: - self.addTexture(material.name + '_reflectance', material.bsdf_texture) - bsdf_params['reflectance'] = (material.name + '_reflectance_inst') - else: - self.addColor((material.name + '_reflectance'), material.bsdf_color[0:3], material.bsdf_color[3]) - bsdf_params['reflectance'] = material.name + '_reflectance' - self.bsdf_objects[material.name + '_bsdf'] = Bsdf(material.name + '_bsdf', 'lambertian_brdf', bsdf_params) - - elif type =='Ashikhmin-Shirley': - bsdf_params['shininess_u'] = 0.5 - bsdf_params['shininess_v'] = 0.5 - # add diffuse reflectence component - if material.bsdf_texture: - self.addTexture(material.name + '_diffuse_reflectance', material.bsdf_texture) - bsdf_params['diffuse_reflectance'] = (material.name + '_diffuse_reflectance_inst') - else: - self.addColor(material.name + '_diffuse_reflectance', material.bsdf_color[0:3], material.bsdf_color[3]) - bsdf_params['diffuse_reflectance'] = material.name + '_diffuse_reflectance' - #add glossy reflectence component - if material.specular_texture: - self.addTexture(material.name + '_glossy_reflectance', material.specular_texture) - bsdf_params['glossy_reflectance'] = material.name + '_glossy_reflectance' - else: - self.addColor(material.name + '_glossy_reflectance', material.specular_color[0:3], material.bsdf_color[3]) - bsdf_params['glossy_reflectance'] = material.name + '_glossy_reflectance' - self.bsdf_objects[material.name + '_bsdf'] = Bsdf(material.name + '_bsdf', 'ashikhmin_brdf', bsdf_params) - - elif type == 'Kelemen': - bsdf_params['roughness'] = 0.5 - #add matte_reflectance component - if material.bsdf_texture: - self.addTexture(material.name + '_matte_reflectance', material.bsdf_texture) - bsdf_params['matte_reflectance'] = (material.name + '_matte_reflectance_inst') - else: - self.addColor(material.name + '_matte_reflectance', material.bsdf_color[0:3], material.bsdf_color[3]) - bsdf_params['matte_reflectance'] = material.name + '_matte_reflectance' - #add specular_reflectance component - if material.specular_texture: - self.addTexture(material.name + '_specular_reflectance', material.specular_texture) - bsdf_params['specular_reflectance'] = material.name + '_specular_reflectance' - else: - self.addColor(material.name + '_specular_reflectance', material.bsdf_color[0:3], material.bsdf_color[3]) - bsdf_params['specular_reflectance'] = material.name + '_specular_reflectance' - self.bsdf_objects[material.name + '_bsdf'] = Bsdf(material.name + '_bsdf', 'kelemen_brdf', bsdf_params) - - elif type == 'Specular_BRDF': - #add reflectence component - if material.bsdf_texture: - self.addTexture(material.name + '_reflectance', material.bsdf_texture) - bsdf_params['reflectance'] = (material.name + '_reflectance_inst') + # populate material, shading node and color list + for geo in self.geo_objects: + if geo.getMaterials() != None: + self.material_objects = self.material_objects + geo.getMaterials() else: - self.addColor((material.name + '_reflectance'), material.bsdf_color[0:3], material.bsdf_color[3]) - bsdf_params['reflectance'] = material.name + '_reflectance' - self.bsdf_objects[material.name + '_bsdf'] = Bsdf(material.name + '_bsdf', 'specular_brdf', bsdf_params) - + cmds.warning("no material connected to {0}".format(geo.name)) + self.shading_node_objects = self.shading_node_objects + geo.getShadingNodes() + self.color_objects = self.color_objects + geo.colors + self.texture_objects = self.texture_objects + geo.textures - def addSurfaceShader(self, material, name, type): - if not name in self.surface_shader_objects: - surface_shader_params = dict() - model=None - #check surface shader type and add appropriate parameters to dict - if type == 'Physical': - model = 'physical_surface_shader' - elif type == 'Constant': - model = 'constant_surface_shader' - #if surface_shader is set to constant, take color or texture from material bsdf - if material.bsdf_texture: - self.addTexture(material.name + '_surface_shader_color', material.bsdf_texture) - surface_shader_params['color'] = (material.name + '_surface_shader_color_inst ') - else: - self.addColor((material.name + '_surface_shader_color'), material.bsdf_color[0:3], material.bsdf_color[3]) - surface_shader_params['color'] = material.name + '_surface_shader_color' - elif type == 'Ambient Occlusion': - cmds.error('atempting to set {0} surface shader to ambient occlusion'.format(name)) - cmds.error('ambient occlusion not implimented yet') - print('adding {0} surface shader to {0}'.format(type, name)) - self.surface_shader_objects[name] = SurfaceShader(name, model, surface_shader_params) - - - def addMaterial(self, name): - if not name in self.material_objects: - self.material_objects[name] = Material(self.params, name) - - self.material_objects[name].bsdf = None - self.material_objects[name].edf = None - self.material_objects[name].surface_shader = None - - #if custom shader translation attribs exists use them - if cmds.objExists(name + '.mayaseed_bsdf'): - if not (cmds.getAttr(name+'.mayaseed_bsdf', asString=True) == ''): - self.material_objects[name].bsdf = (name + '_bsdf') - self.addBSDF(self.material_objects[name], cmds.getAttr(name+'.mayaseed_bsdf', asString=True)) - if not (cmds.getAttr(name+'.mayaseed_edf', asString=True) == ''): - self.material_objects[name].edf = (name + '_edf') - self.addEDF(self.material_objects[name], cmds.getAttr(name+'.mayaseed_edf', asString=True)) - if not (cmds.getAttr(name+'.mayaseed_surface_shader', asString=True) == ''): - self.material_objects[name].surface_shader = (name + '_surface_shader') - self.addSurfaceShader(self.material_objects[name], name + '_surface_shader', cmds.getAttr(name+'.mayaseed_surface_shader', asString=True)) - - else: #create bsdf,edf & surface shader based on defaults - #create bsdf - if self.material_objects[name].shader_type == 'lambert': - if not self.params['matLambertBSDF'] == 'None': - self.material_objects[name].bsdf = (name + '_bsdf') - self.addBSDF(self.material_objects[name], self.params['matLambertBSDF']) - - elif self.material_objects[name].shader_type == 'blinn': - if not self.params['matBlinnBSDF'] == 'None': - self.material_objects[name].bsdf = (name + '_bsdf') - self.addBSDF(self.material_objects[name], self.params['matBlinnBSDF']) - - elif self.material_objects[name].shader_type == 'phong' or self.material_objects[name].shader_type == 'phongE': - if not self.params['matPhongBSDF'] == 'None': - self.material_objects[name].bsdf = (name + '_bsdf') - self.addBSDF(self.material_objects[name], self.params['matPhongBSDF']) - - elif self.material_objects[name].shader_type == 'surfaceShader': - if not self.params['matSurfaceShaderBSDF'] == 'None': - self.material_objects[name].bsdf = (name + '_bsdf') - self.addBSDF(self.material_objects[name], self.params['matSurfaceShaderBSDF']) - - else: - if not self.params['matDefaultBSDF'] == 'None': - self.material_objects[name].bsdf = (name + '_bsdf') - self.addBSDF(self.material_objects[name], self.params['matDefaultBSDF']) - - #create edf - if self.material_objects[name].shader_type == 'lambert': - if not self.params['matLambertEDF'] == 'None': - self.material_objects[name].edf = (name + '_edf') - self.addEDF(self.material_objects[name], self.params['matLambertEDF']) - - elif self.material_objects[name].shader_type == 'blinn': - if not self.params['matBlinnEDF'] == 'None': - self.material_objects[name].edf = (name + '_edf') - self.addEDF(self.material_objects[name], self.params['matBlinnEDF']) - - elif self.material_objects[name].shader_type == 'phong' or self.material_objects[name].shader_type == 'phongE': - if not self.params['matPhongEDF'] == 'None': - self.material_objects[name].edf = (name + '_edf') - self.addEDF(self.material_objects[name], self.params['matPhongEDF']) - - elif self.material_objects[name].shader_type == 'surfaceShader': - if not self.params['matSurfaceShaderEDF'] == 'None': - self.material_objects[name].edf = (name + '_edf') - self.addEDF(self.material_objects[name], self.params['matSurfaceShaderEDF']) - else: - if not self.params['matDefaultEDF'] == 'None': - self.material_objects[name].edf = (name + '_edf') - self.addEDF(self.material_objects[name], self.params['matDefaultEDF']) - - #create surface - if self.material_objects[name].shader_type == 'lambert': - if not self.params['matLambertSurfaceShader'] == 'None': - if self.params['matLambertSurfaceShader'] == 'Physical': - self.material_objects[name].surface_shader = ('Physical_surface_shader') - self.addSurfaceShader(self.material_objects[name], 'Physical_surface_shader', self.params['matLambertSurfaceShader']) - else: - self.material_objects[name].surface_shader = (name + '_surface_shader') - self.addSurfaceShader(self.material_objects[name], name + '_surface_shader', self.params['matLambertSurfaceShader']) - - elif self.material_objects[name].shader_type == 'blinn': - if not self.params['matBlinnSurfaceShader'] == 'None': - if self.params['matBlinnSurfaceShader'] == 'Physical': - self.material_objects[name].surface_shader = ('Physical_surface_shader') - self.addSurfaceShader(self.material_objects[name], 'Physical_surface_shader', self.params['matBlinnSurfaceShader']) - else: - self.material_objects[name].surface_shader = (name + '_surface_shader') - self.addSurfaceShader(self.material_objects[name], name + '_surface_shader', self.params['matBlinnSurfaceShader']) - - elif self.material_objects[name].shader_type == 'phong' or self.material_objects[name].shader_type == 'phongE': - if not self.params['matPhongSurfaceShader'] == 'None': - if self.params['matPhongSurfaceShader'] == 'Physical': - self.material_objects[name].surface_shader = ('Physical_surface_shader') - self.addSurfaceShader(self.material_objects[name], 'Physical_surface_shader', self.params['matPhongSurfaceShader']) - else: - self.material_objects[name].surface_shader = (name + '_surface_shader') - self.addSurfaceShader(self.material_objects[name], name + '_surface_shader', self.params['matPhongSurfaceShader']) - - elif self.material_objects[name].shader_type == 'surfaceShader': - if not self.params['matSurfaceShaderSurfaceShader'] == 'None': - if self.params['matSurfaceShaderSurfaceShader'] == 'Physical': - self.material_objects[name].surface_shader = ('Physical_surface_shader') - self.addSurfaceShader(self.material_objects[name], 'Physical_surface_shader', self.params['matSurfaceShaderSurfaceShader']) - else: - self.material_objects[name].surface_shader = (name + '_surface_shader') - self.addSurfaceShader(self.material_objects[name], name + '_surface_shader', self.params['matSurfaceShaderSurfaceShader']) - - else: - if not self.params['matDefaultSurfaceShader'] == 'None': - if self.params['matDefaultSurfaceShader'] == 'Physical': - self.material_objects[name].surface_shader = ('Physical_surface_shader') - self.addSurfaceShader(self.material_objects[name], 'Physical_surface_shader', self.params['matDefaultSurfaceShader']) - else: - self.material_objects[name].surface_shader = (name + '_surface_shader') - self.addSurfaceShader(self.material_objects[name], name + '_surface_shader', self.params['matDefaultSurfaceShader']) + # materials + unsorted_materials = self.material_objects + self.material_objects = dict() + for material in unsorted_materials: + if not material.name in self.material_objects: + self.material_objects[material.name] = material + self.material_objects = self.material_objects.values() + + # shading nodes + unsorted_shading_nodes = self.shading_node_objects + self.shading_node_objects = dict() + for shading_node in unsorted_shading_nodes: + if shading_node != None: + if not shading_node.name in self.shading_node_objects: + self.shading_node_objects[shading_node.name] = shading_node + self.shading_node_objects = self.shading_node_objects.values() + + # colors + unsorted_colors = self.color_objects + self.color_objects = dict() + for color in unsorted_colors: + if not color.name in self.color_objects: + self.color_objects[color.name] = color + self.color_objects = self.color_objects.values() + # textures + unsorted_textures = self.texture_objects + self.texture_objects = dict() + for texture in unsorted_textures: + if texture!= None: + if not texture.name in self.texture_objects: + self.texture_objects[texture.name] = texture + self.texture_objects = self.texture_objects.values() - def writeXML(self, doc): print('writing assembly: {0}'.format(self.name)) doc.startElement('assembly name="{0}"'.format(self.name)) - #write colors + # write colors for col in self.color_objects: - self.color_objects[col].writeXML(doc) + col.writeXML(doc) - #write texture objects + # write texture objects for tex in self.texture_objects: - self.texture_objects[tex].writeXMLObject(doc) - #write texture instances + tex.writeXMLObject(doc) + + # write texture instances for tex in self.texture_objects: - self.texture_objects[tex].writeXMLInstance(doc) + tex.writeXMLInstance(doc) - #write bsdfs - for bsdf in self.bsdf_objects: - self.bsdf_objects[bsdf].writeXML(doc) + # write bsdfs + for shading_node in self.shading_node_objects: + if shading_node.type == 'bsdf': + shading_node.writeXML(doc) - #write eddfs - for edf in self.edf_objects: - self.edf_objects[edf].writeXML(doc) + # write edfs + for shading_node in self.shading_node_objects: + if shading_node.type == 'edf': + shading_node.writeXML(doc) - #write surface shaders - for surface_shader in self.surface_shader_objects: - self.surface_shader_objects[surface_shader].writeXML(doc) + # write surface shaders + for shading_node in self.shading_node_objects: + if shading_node.type == 'surface_shader': + shading_node.writeXML(doc) - #write materials + # write materials for material in self.material_objects: - self.material_objects[material].writeXML(doc) - - #export and write .obj object + material.writeXML(doc) + + # export and write objects for geo in self.geo_objects: - #export geo - cmds.select(geo) - output_file = os.path.join(self.params['outputDir'], 'geo', (geo + '.obj')) - print geo - print output_file - cmds.file(output_file, force=True, options='groups=0;ptgroups=0;materials=0;smoothing=0;normals=1', typ='OBJexport',pr=True, es=True) - cmds.select(cl=True) - #write xml - doc.startElement('object name="{0}" model="mesh_object"'.format(geo)) - doc.appendElement('parameter name="filename" value="geo/{0}.obj"'.format(geo)) + file_name = ms_commands.legalizeName(geo.name) + + doc.startElement('object name="{0}" model="mesh_object"'.format(file_name)) + + if self.params['export_deformation_blur']: + # store the start time of the export + start_time = cmds.currentTime(query=True) + motion_samples = self.params['motion_samples'] + if motion_samples < 2: + cmds.warning("motion samples is set too low, must be at least 2; using 2") + motion_samples = 2 + sample_interval = 1.0 / (motion_samples - 1) + + cmds.currentTime(cmds.currentTime(query=True) - 1) + + doc.startElement('parameters name="filename"') + + for i in range(motion_samples): + frame = start_time + sample_interval * i + print("exporting frame {0}".format(frame)) + + cmds.currentTime(frame) + cmds.refresh() + + obj_filename = "{0}.{1:03}.obj".format(file_name, i) + doc.appendParameter("{0:03}".format(i), "{0}/{1}".format(self.params['geo_dir'], obj_filename)) + + # write the OBJ file to disk + obj_filepath = os.path.join(self.params['absolute_geo_dir'], obj_filename) + checkExportCancelled() + self.params['obj_exporter'](geo.name, obj_filepath, overwrite=True) + + doc.endElement('parameters') + + cmds.currentTime(start_time) + else: + obj_filename = file_name + ".obj" + doc.appendParameter('filename', os.path.join(self.params['geo_dir'], obj_filename)) + + # write the OBJ file to disk + obj_filepath = os.path.join(self.params['absolute_geo_dir'], obj_filename) + checkExportCancelled() + self.params['obj_exporter'](geo.name, obj_filepath) + + self.params['progress_bar_progress'] += self.params['progress_bar_incriments'] + cmds.progressWindow(edit=True, progress=self.params['progress_bar_progress']) + doc.endElement('object') - - #write lights - for light_name in self.light_objects: - light_name.writeXML(doc) - - #write geo object instances + + # write lights + for light_object in self.light_objects: + light_object.writeXML(doc) + + # write geo object instances for geo in self.geo_objects: - self.geo_objects[geo].writeXMLInstance(doc) - + geo.writeXMLInstance(doc) + doc.endElement('assembly') doc.startElement('assembly_instance name="{0}_inst" assembly="{1}"'.format(self.name, self.name)) - writeTransform(doc, self.params['scene_scale']) + + # if transformation blur is set output the transform with motion from the position_from_object variable + if self.params['export_transformation_blur']: + writeTransform(doc, self.params['scene_scale'], self.position_from_object, True, self.params['motion_samples']) + else: + writeTransform(doc, self.params['scene_scale']) doc.endElement('assembly_instance') -# -# scene class -- -# + +#-------------------------------------------------------------------------------------------------- +# Scene class. +#-------------------------------------------------------------------------------------------------- class Scene(): def __init__(self,params): + checkExportCancelled() self.params = params self.assembly_list = [] self.color_objects = dict() self.texture_objects = dict() + self.assembly_objects = dict() - #setup environment + # setup environment if self.params['environment']: - self.environment = Environment(self.params, self.params['environment'], (self.params['environment'] + '_env_shader'), (self.params['environment'] + '_env_edf')) + env_name = self.params['environment'] + self.environment = Environment(self.params, env_name, (env_name + '_env_shader'), env_name + '_env_edf') - #retrieve model and param values from ui - environment_edf_model_enum = cmds.getAttr(self.params['environment'] + '.model') + env_edf_model_enum = cmds.getAttr(env_name + '.model') env_edf_params = dict() - if environment_edf_model_enum == 0: + + if env_edf_model_enum == 0: environment_edf_model = 'constant_environment_edf' - environment_color = ms_commands.normalizeRGB(cmds.getAttr(self.params['environment']+'.constant_exitance')[0]) + + environment_color = ms_commands.normalizeRGB(cmds.getAttr(env_name + '.constant_exitance')[0]) self.addColor('constant_env_exitance', environment_color[0:3], environment_color[3]) - env_edf_params['exitance'] = 'constant_env_exitance' - elif environment_edf_model_enum == 1: + env_edf_params['exitance'] = 'constant_env_exitance' + + elif env_edf_model_enum == 1: environment_edf_model = 'gradient_environment_edf' - horizon_exitance = ms_commands.normalizeRGB(cmds.getAttr(self.params['environment']+'.gradient_horizon_exitance')[0]) + horizon_exitance = ms_commands.normalizeRGB(cmds.getAttr(env_name + '.gradient_horizon_exitance')[0]) self.addColor('gradient_env_horizon_exitance', horizon_exitance[0:3], horizon_exitance[3]) - zenith_exitance = ms_commands.normalizeRGB(cmds.getAttr(self.params['environment']+'.gradient_zenith_exitance')[0]) + zenith_exitance = ms_commands.normalizeRGB(cmds.getAttr(env_name + '.gradient_zenith_exitance')[0]) self.addColor('gradient_env_zenith_exitance', zenith_exitance[0:3], zenith_exitance[3]) env_edf_params['horizon_exitance'] = 'gradient_env_horizon_exitance' env_edf_params['zenith_exitance'] = 'gradient_env_zenith_exitance' - elif environment_edf_model_enum == 2: - lat_long_connection = cmds.connectionInfo((self.params['environment'] + '.latitude_longitude_exitance'), sourceFromDestination=True).split('.')[0] + elif env_edf_model_enum == 2: environment_edf_model = 'latlong_map_environment_edf' - if lat_long_connection: - if cmds.nodeType(lat_long_connection) == 'file': - self.addTexture(self.params['environment'] + '_latlong_edf_map', cmds.getAttr(lat_long_connection + '.fileTextureName')) - env_edf_params['exitance'] = self.params['environment'] + '_latlong_edf_map_inst' - env_edf_params['horizontal_shift'] = 0 - env_edf_params['vertical_shift'] = 0 + + exitance_connection = cmds.connectionInfo(env_name + '.latitude_longitude_exitance', sourceFromDestination=True).split('.')[0] + if exitance_connection: + if cmds.nodeType(exitance_connection) == 'file': + maya_texture_file = ms_commands.getFileTextureName(exitance_connection) + texture_file = ms_commands.convertTexToExr(maya_texture_file, params['absolute_tex_dir'], self.params['overwrite_existing_textures']) + self.addTexture(env_name + '_latlong_edf_map', os.path.join(params['tex_dir'], os.path.split(texture_file)[1])) + + env_edf_params['exitance'] = env_name + '_latlong_edf_map_inst' + env_edf_params['exitance_multiplier'] = cmds.getAttr(env_name + '.exitance_multiplier') + env_edf_params['horizontal_shift'] = 0.0 + env_edf_params['vertical_shift'] = 0.0 else: - cmds.error('no texture connected to {0}.latitude_longitude_exitance'.format(self.params['environment'])) + cmds.error('no texture connected to {0}.latitude_longitude_exitance'.format(env_name)) - elif environment_edf_model_enum == 3: - mirrorball_edf_connection = cmds.connectionInfo((self.params['environment'] + '.mirror_ball_exitance'), sourceFromDestination=True).split('.')[0] + elif env_edf_model_enum == 3: environment_edf_model = 'mirrorball_map_environment_edf' - if mirrorball_edf_connection: - if cmds.nodeType(mirrorball_edf_connection) == 'file': - self.addTexture(self.params['environment'] + '_mirrorball_map_environment_edf', cmds.getAttr(mirrorball_edf_connection + '.fileTextureName')) - env_edf_params['exitance'] = self.params['environment'] + '_mirrorball_map_environment_edf_inst' + + exitance_connection = cmds.connectionInfo(env_name + '.mirror_ball_exitance', sourceFromDestination=True).split('.')[0] + if exitance_connection: + if cmds.nodeType(exitance_connection) == 'file': + maya_texture_name = ms_commands.getFileTextureName(exitance_connection) + texture_file = ms_commands.convertTexToExr(maya_texture_name, params['absolute_tex_dir'], self.params['overwrite_existing_textures']) + self.addTexture(env_name + '_mirrorball_map_environment_edf', os.path.join(params['tex_dir'], os.path.split(texture_file)[1])) + + env_edf_params['exitance'] = env_name + '_mirrorball_map_environment_edf_inst' + env_edf_params['exitance_multiplier'] = cmds.getAttr(env_name + '.exitance_multiplier') else: - cmds.error('no texture connected to {0}.mirrorball_exitance'.format(self.params['environment'])) + cmds.error('no texture connected to {0}.mirrorball_exitance'.format(env_name)) else: - cmds.error('no environment model selected for ' + self.params['environment']) - - self.environment_edf = EnvironmentEdf((self.params['environment'] + '_env_edf'), environment_edf_model, env_edf_params) - self.environment_shader = EnvironmentShader((self.params['environment'] + '_env_shader'), (self.params['environment'] + '_env_edf')) + cmds.error("no environment model selected for {0}".format(env_name)) + + self.environment_edf = EnvironmentEdf(env_name + '_env_edf', environment_edf_model, env_edf_params) + self.environment_shader = EnvironmentShader(env_name + '_env_shader', env_name + '_env_edf') else: self.environment = None @@ -976,147 +1341,240 @@ def addTexture(self, name, file_name): def writeXML(self, doc): print('writing scene element') + doc.startElement('scene') - #write current camera + # write current camera camera_instance = Camera(self.params, self.params['outputCamera']) camera_instance.writeXML(doc) - - #write colors + + # write colors for col in self.color_objects: self.color_objects[col].writeXML(doc) - - #write texture objects + + # write texture objects for tex in self.texture_objects: + print 'writing texture', self.texture_objects[tex].name self.texture_objects[tex].writeXMLObject(doc) - #write texture instances + # write texture instances for tex in self.texture_objects: self.texture_objects[tex].writeXMLInstance(doc) - #if tehre is an environment write it + # if there is an environment write it if self.environment: self.environment_edf.writeXML(doc) self.environment_shader.writeXML(doc) self.environment.writeXML(doc) - #export assemblies - #get maya geometry - shape_list = cmds.ls(g=True, v=True) - geo_transform_list = [] - for g in shape_list: - # add first connected transform to the list - geo_transform_list.append(cmds.listRelatives(g, ad=True, ap=True)[0]) - - #populate a list of assemblies - for g in geo_transform_list: - set = cmds.listSets(object=g) - if set: - if not set[0] in self.assembly_list: - self.assembly_list.append(cmds.listSets(object=g)[0]) - - #create assemblys if any assembly names are present otherwise create default assembly - if self.assembly_list: - #for each assemply in assembly_list create an object and output its XML - for assembly in self.assembly_list: - new_assembly = Assembly(self.params, assembly) - new_assembly.writeXML(doc) + # write assemblies + shape_list = cmds.ls(g=True, v=True, noIntermediate=True) + light_list = cmds.ls(lt=True, v=True) + + self.params['progress_bar_incriments'] = 100.0 / len(shape_list) + self.params['progress_bar_progress'] = 0 + + if self.params['export_transformation_blur']: + for geo in shape_list: + checkExportCancelled() + if ms_commands.shapeIsExportable(geo): + # add first connected transform to the list + geo_transform = cmds.listRelatives(geo, ad=True, ap=True)[0] + geo_assembly = Assembly(self.params, geo_transform + '_assembly', [geo], geo_transform) + geo_assembly.writeXML(doc) + + for light in light_list: + light_transform = cmds.listRelatives(light, ad=True, ap=True)[0] + light_assembly = Assembly(self.params, light_transform + '_assembly', [light], light_transform) + light_assembly.writeXML(doc) else: - print('no populated maya sets present, using default "main_assembly"') - new_assembly = Assembly(self.params, 'main_assembly') - new_assembly.writeXML(doc) + assembly = Assembly(self.params, "assembly", light_list + shape_list) + assembly.writeXML(doc) + doc.endElement('scene') -# -# output class -- -# + +#-------------------------------------------------------------------------------------------------- +# Output class. +#-------------------------------------------------------------------------------------------------- class Output(): def __init__(self, params): self.params = params + def writeXML(self, doc): doc.startElement('output') doc.startElement('frame name="beauty"') - doc.appendElement('parameter name="camera" value="{0}"'.format(self.params['outputCamera'])) - doc.appendElement('parameter name="color_space" value="{0}"'.format(self.params['outputColorSpace'])) - doc.appendElement('parameter name="resolution" value="{0} {1}"'.format(self.params['outputResWidth'], self.params['outputResHeight'])) + doc.appendParameter('camera', self.params['outputCamera']) + doc.appendParameter('color_space', self.params['outputColorSpace']) + doc.appendParameter('resolution', '{0} {1}'.format(self.params['output_res_width'], self.params['output_res_height'])) doc.endElement('frame') doc.endElement('output') -# -# configurations class -- -# + +#-------------------------------------------------------------------------------------------------- +# Configurations class. +#-------------------------------------------------------------------------------------------------- class Configurations(): def __init__(self, params): self.params = params - def writeXML(self,doc): - doc.startElement("configurations") + + def writeXML(self, doc): print('writing configurations') - #if 'customise interactive configuration' is set read customised values - if self.params['customInteractiveConfigCheck']: - print('writing custom interactive config') - doc.startElement('configuration name="interactive" base="base_interactive"') - engine = '' - if self.params['customInteractiveConfigEngine'] == 'Path Tracing': - engine = "pt" - else: - engine = "drt" - doc.appendElement('parameter name="lighting_engine" value="{0}"'.format(engine)) - doc.startElement('parameters name="{0}"'.format(engine)) - doc.appendElement('parameter name="max_path_length" value="{0}"'.format(self.params['customInteractiveConfigMaxRayDepth'])) - doc.endElement('parameters') - doc.appendElement('parameter name="min_samples" value="{0}"'.format(self.params['customInteractiveConfigMinSamples'])) - doc.appendElement('parameter name="max_samples" value="{0}"'.format(self.params['customInteractiveConfigMaxSamples'])) - doc.endElement('configuration') - else:# otherwise add default configurations - print('writing default interactive config') - doc.appendElement('configuration name="interactive" base="base_interactive"') + + doc.startElement("configurations") + + # add base interactive config + doc.appendElement('configuration name="interactive" base="base_interactive"') #if 'customise final configuration' is set read customised values if self.params['customFinalConfigCheck']: print('writing custom final config') doc.startElement('configuration name="final" base="base_final"') - engine = '' - if cmds.optionMenu('ms_customFinalConfigEngine', query=True, value=True) == "Path Tracing": + + if self.params['customFinalConfigEngine'] == 0: engine = 'pt' else: engine = 'drt' - doc.appendElement('parameter name="lighting_engine" value="{0}"'.format(engine)) - doc.startElement('parameters name="{0}"'.format(engine)) - doc.appendElement('parameter name="max_path_length" value="{0}"'.format(self.params['customFinalConfigMaxRayDepth'])) + doc.appendParameter('lighting_engine', engine) + doc.appendParameter('min_samples', self.params['customFinalConfigMaxSamples']) + doc.appendParameter('max_samples', self.params['customFinalConfigMaxSamples']) + + doc.startElement('parameters name="drt"') + doc.appendParameter('dl_bsdf_samples', self.params['drtDLBSDFSamples']) + doc.appendParameter('dl_light_samples', self.params['drtDLLightSamples']) + doc.appendParameter('enable_ibl', self.params['drtEnableIBL']) + doc.appendParameter('ibl_bsdf_samples', self.params['drtIBLBSDFSamples']) + doc.appendParameter('ibl_env_samples', self.params['drtIBLEnvSamples']) + doc.appendParameter('max_path_length', self.params['drtMaxPathLength']) + doc.appendParameter('rr_min_path_length', self.params['drtRRMinPathLength']) + doc.endElement("parameters") + + doc.startElement('parameters name="pt"') + doc.appendParameter('dl_light_samples', self.params['ptDLLightSamples']) + + if self.params['ptEnableCaustics']: + doc.appendParameter('enable_caustics', 'true') + else: + doc.appendParameter('enable_caustics', 'false') + + if self.params['ptEnableDL']: + doc.appendParameter('enable_dl', 'true') + else: + doc.appendParameter('enable_dl', 'false') + + if self.params['ptEnableIBL']: + doc.appendParameter('enable_ibl', 'true') + else: + doc.appendParameter('enable_ibl', 'false') + + doc.appendParameter('ibl_bsdf_samples', self.params['ptIBLBSDFSamples']) + doc.appendParameter('ibl_env_samples', self.params['ptIBLEnvSamples']) + doc.appendParameter('max_path_length', self.params['ptMaxPathLength']) + + if self.params['ptNextEventEstimation']: + doc.appendParameter('next_event_estimation', 'true') + else: + doc.appendParameter('next_event_estimation', 'false') + + doc.appendParameter('rr_min_path_length', self.params['ptRRMinPathLength']) + doc.endElement("parameters") + + doc.startElement('parameters name="generic_tile_renderer"') + doc.appendParameter('filter_size', self.params['gtrFilterSize']) + doc.appendParameter('max_contrast', self.params['gtrMaxContrast']) + doc.appendParameter('max_samples', self.params['gtrMaxSamples']) + doc.appendParameter('max_variation', self.params['gtrMaxVariation']) + doc.appendParameter('min_samples', self.params['gtrMinSamples']) + doc.appendParameter('sampler', self.params['gtrSampler']) doc.endElement('parameters') - doc.appendElement('parameter name="min_samples" value="{0}"'.format(self.params['customFinalConfigMinSamples'])) - doc.appendElement('parameter name="max_samples" value="{0}"'.format(self.params['customFinalConfigMaxSamples'])) + doc.endElement("configuration") + else:# otherwise add default configurations print('writing default final config') doc.appendElement('configuration name="final" base="base_final"') - # begin adding custom configurations + doc.endElement('configurations') - -#**************************************************************************************************************************************************************************************************** -# export function *********************************************************************************************************************************************************************************** -#**************************************************************************************************************************************************************************************************** -def export(render_settings_node): +#-------------------------------------------------------------------------------------------------- +# Main export function. +#-------------------------------------------------------------------------------------------------- + +def safe_make_dirs(path): + if not os.path.exists(path): + os.makedirs(path) + +def export_container(render_settings_node): params = getMayaParams(render_settings_node) - if not params['error']: - #make output directories if they dont exists - if not os.path.exists(os.path.join(params['outputDir'],'temp')): - os.makedirs(os.path.join(params['outputDir'],'temp')) - if not os.path.exists(os.path.join(params['outputDir'],'geo')): - os.makedirs(os.path.join(params['outputDir'],'geo')) - if not os.path.exists(os.path.join(params['outputDir'],'textures')): - os.makedirs(os.path.join(params['outputDir'],'textures')) - - #begin export + + # create progres bar + params['progress_amount'] = 0 + cmds.progressWindow(title='Exporting', progress=params['progress_amount'], status='Exporting ' + render_settings_node, isInterruptable=True) + + + if params['error']: + cmds.error("error validating UI attributes") + raise RuntimeError("check script editor for details") + + # compute the base output directory + scene_filepath = cmds.file(q=True, sceneName=True) + scene_basename = os.path.splitext(os.path.basename(scene_filepath))[0] + project_directory = cmds.workspace(q=True, rd=True) + params['outputDir'] = params['outputDir'].replace("", project_directory) + params['outputDir'] = os.path.join(params['outputDir'], scene_basename) + + if params['export_animation']: + start_frame = params['animation_start_frame'] + end_frame = params['animation_end_frame'] + else: + start_frame = cmds.currentTime(query=True) + end_frame = start_frame + + start_time = time.time() + + current_frame = start_frame + original_time = cmds.currentTime(query=True) + + # loop through frames and perform export + while (current_frame <= end_frame): + # todo: add check for Escape being held down here to cancel an export + + # todo: is this necessary, since we're already doing it when exporting geometry? + cmds.currentTime(current_frame) + frame_name = '{0:04}'.format(int(current_frame)) + + # compute the output file path + filename = params['fileName'] + filename = filename.replace("", scene_basename) + filename = filename.replace("#", frame_name) + filepath = os.path.join(params['outputDir'], filename) + + # directory for geometry + params['geo_dir'] = os.path.join(frame_name, "geometry") + params['absolute_geo_dir'] = os.path.join(params['outputDir'], params['geo_dir']) + + # directory for textures + params['tex_dir'] = 'textures' + if params['animatedTextures']: + params['tex_dir'] = os.path.join(frame_name, params['tex_dir']) + params['absolute_tex_dir'] = os.path.join(params['outputDir'], params['tex_dir']) + + # create directories if they don't exist yet + safe_make_dirs(params['absolute_geo_dir']) + safe_make_dirs(params['absolute_tex_dir']) + + params['skipTextures'] = False + print('beginning export') - print('opening output file: ' + params['fileName']) - doc = WriteXml('{0}/{1}'.format(params['outputDir'], params['fileName'].replace("#",'{0:05}'.format(int(cmds.currentTime(query=True)))))) - doc.appendLine('') # XML format string - doc.appendLine(''.format(ms_commands.MAYASEED_VERSION)) + print('opening output file {0}'.format(filepath)) + + doc = WriteXml(filepath) + doc.appendLine('') + doc.appendLine(''.format(ms_commands.MAYASEED_VERSION)) + print('writing project element') doc.startElement('project') scene_element = Scene(params) @@ -1128,15 +1586,33 @@ def export(render_settings_node): doc.endElement('project') doc.close() - print('export finished') + current_frame += 1 - else: - cmds.error('error validating ui attributes ') - raise RuntimeError('check script editor for details') + # only export textures for the first frame + if not params['animatedTextures']: + params['skipTextures'] = True + + cmds.currentTime(original_time) + cmds.select(render_settings_node) + + # Compute and report export time. + export_time = time.time() - start_time + export_message = "Export completed in {0:.1f} seconds.".format(export_time) + print(export_message) + # end progress bar + cmds.progressWindow(endProgress=1) + cmds.confirmDialog(title="Export Completed", icon='information', message=export_message, button="OK") +def export(render_settings_node): + if cmds.getAttr(render_settings_node + '.profile_export'): + import cProfile + command = 'import ms_export\nms_export.export_container("' + render_settings_node + '")' + cProfile.run(command) + else: + export_container(render_settings_node) diff --git a/sandbox/extras/maya/scripts/ms_export.pyc b/sandbox/extras/maya/scripts/ms_export.pyc deleted file mode 100644 index 6882b36bb1..0000000000 Binary files a/sandbox/extras/maya/scripts/ms_export.pyc and /dev/null differ diff --git a/sandbox/extras/maya/scripts/ms_export_obj.py b/sandbox/extras/maya/scripts/ms_export_obj.py new file mode 100644 index 0000000000..64ec095048 --- /dev/null +++ b/sandbox/extras/maya/scripts/ms_export_obj.py @@ -0,0 +1,119 @@ +# Copyright (c) 2012 Jonathan Topf + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + + +import maya.cmds as cmds +import maya.OpenMaya as OpenMaya +import ms_commands +import os + +SCRIPT_VERSION = '0.1.2' + +def export(object_name, file_path, overwrite=True): + export_dir = os.path.split(file_path)[0] + + if not os.path.exists(export_dir): + os.makedirs(export_dir) + + if (not os.path.exists(file_path)) or overwrite: + try: + file_object = open(file_path, 'w') + except IOError: + error_msg = 'IO error: failed to open {0} for writing.'.format(file_path) + cmds.error(error_msg) + raise RuntimeError(error_msg) + + #write file info + file_object.write('# File generated by ms_export_obj.py version {0} from mayaseed version: {1}\n'.format(SCRIPT_VERSION,ms_commands.MAYASEED_VERSION)) + file_object.write('# {0}\n\n'.format(object_name)) + + sel = OpenMaya.MSelectionList() + sel.add(str(object_name)) + mesh_dag_path = OpenMaya.MDagPath() #create dag path object + sel.getDagPath(0,mesh_dag_path) #retreive dag path of object + + mesh = OpenMaya.MFnMesh(mesh_dag_path) #create mesh object + iter_polys = OpenMaya.MItMeshPolygon( mesh.object() ) #create iter object + + transform_space_enum = 2 #2 = object_space + + #cerate point array to hold the points from the mesh + point_array = OpenMaya.MPointArray() + mesh.getPoints(point_array) + #write the points to disk + i=0 + while i < point_array.length(): + point = point_array[i] + file_object.write('v {0} {1} {2}\n'.format(point.x, point.y, point.z)) + i += 1 + + file_object.write('\n') + + #create MFloatArray for u's and v's to store values + u_array = OpenMaya.MFloatArray() + v_array = OpenMaya.MFloatArray() + mesh.getUVs(u_array, v_array) + #write u's and v's to disk + i=0 + while i < u_array.length(): + file_object.write('vt {0} {1}\n'.format(u_array[i], v_array[i])) + i +=1 + + file_object.write('\n') + + normal_array = OpenMaya.MFloatVectorArray() + mesh.getNormals(normal_array, transform_space_enum) + #write normals to disk + i = 0 + while i < normal_array.length(): + normal = normal_array[i] + file_object.write('vn {0} {1} {2}\n'.format(normal.x, normal.y, normal.z)) + i += 1 + + file_object.write('\n') + + #iterate over polys + while not iter_polys.isDone(): + + #start face definition + file_object.write('f ') + + i=0 + while i < iter_polys.polygonVertexCount(): + + #to get uv index we need to create an int pointer because the api is just wrappers for c++ + util = OpenMaya.MScriptUtil() + util.createFromInt(0) + uv_pInt = util.asIntPtr() + uv_index = OpenMaya.MScriptUtil() + uv_index.createFromInt(0) + iter_polys.getUVIndex(i, uv_pInt) + + + file_object.write('{0}/{1}/{2} '.format(iter_polys.vertexIndex(i) + 1, uv_index.getInt(uv_pInt) + 1, iter_polys.normalIndex(i) + 1)) + + i += 1 + + #next could just write individual polys like this, but would be good if you could weed out shared verts + file_object.write('\n') + iter_polys.next() + + file_object.close() + print 'finished exporting', object_name diff --git a/sandbox/extras/maya/scripts/ms_menu.py b/sandbox/extras/maya/scripts/ms_menu.py index 6751c48d4f..25fd914955 100644 --- a/sandbox/extras/maya/scripts/ms_menu.py +++ b/sandbox/extras/maya/scripts/ms_menu.py @@ -1,15 +1,17 @@ -# Copyright (c) 2012 Jonathan Topf +# +# Copyright (c) 2012 Jonathan Topf +# # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: - +# # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. - +# # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE @@ -17,15 +19,14 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. +# import maya.cmds as cmds import maya.mel import maya.utils as mu import __main__ - -#**************************************************************************************************************************************************************************************************** -# create ms_menu ************************************************************************************************************************************************************************************ -#**************************************************************************************************************************************************************************************************** +import ms_commands +import os def createMenu(): try: @@ -35,38 +36,67 @@ def createMenu(): gMainWindow = maya.mel.eval('$temp1=$gMainWindow') mayaseed_menu = cmds.menu('ms_menu', parent=gMainWindow, label='Mayaseed', tearOff=True ) - __main__.mayaseed_menu = mayaseed_menu #add the menu to the main namespace - -#**************************************************************************************************************************************************************************************************** -# build ms_menu function **************************************************************************************************************************************************************************** -#**************************************************************************************************************************************************************************************************** - + __main__.mayaseed_menu = mayaseed_menu # add the menu to the main namespace def buildMenu(): cmds.menu('ms_menu', edit=True, deleteAllItems=True, pmc=('import ms_menu\nms_menu.buildMenu()')) - cmds.menuItem(label='Add Render Settings Node', parent='ms_menu', command='import maya.cmds\nmaya.cmds.createNode("ms_renderSettings")') #need to import maya.cmds module otehrwise cmds isnt recognised - cmds.menuItem('menu_select_render_settings', subMenu=True, label='Select Render settings Node', to=True, parent='ms_menu') - #list menuSettings nodes - renderSettingss = cmds.ls(type='ms_renderSettings') - for renderSetting in renderSettingss: - cmds.menuItem(label=renderSetting, parent='menu_select_render_settings', command=('import maya.cmds as cmds\ncmds.select("{0}")'.format(renderSetting))) - + # Add/Select Render Settings Node + cmds.menuItem(label='Add Render Settings Node', parent='ms_menu', command='import maya.cmds\nmaya.cmds.createNode("ms_renderSettings")') + cmds.menuItem('menu_select_render_settings', subMenu=True, label='Select Render Settings Node', to=True, parent='ms_menu') + for render_settings_node in cmds.ls(type='ms_renderSettings'): + cmds.menuItem(label=render_settings_node, parent='menu_select_render_settings', command=('import maya.cmds as cmds\ncmds.select("{0}")'.format(render_settings_node))) + + # Add/Select Environment Node cmds.menuItem(divider=True, parent='ms_menu') - cmds.menuItem(label='Add Environment Node', parent='ms_menu', command='import maya.cmds\nmaya.cmds.createNode("ms_environment")') #need to import maya.cmds module otehrwise cmds isnt recognised + cmds.menuItem(label='Add Environment Node', parent='ms_menu', command='import maya.cmds\nmaya.cmds.createNode("ms_environment")') cmds.menuItem('menu_select_environment', subMenu=True, label='Select Environment Node', to=True, parent='ms_menu') - #list environment nodes - environments = cmds.ls(type='ms_environment') - for environment in environments: + for environment in cmds.ls(type='ms_environment'): cmds.menuItem(label=environment, parent='menu_select_environment', command=('import maya.cmds as cmds\ncmds.select("{0}")'.format(environment))) cmds.menuItem(divider=True, parent='ms_menu') - cmds.menuItem(label='Add custom shader translation', parent='ms_menu', command='import ms_commands\nms_commands.addShadingAttribs()') - cmds.menuItem(label='Remove custom shader translation', parent='ms_menu', command='import ms_commands\nms_commands.removeShadingAttribs()') - + cmds.menuItem(label='Create Material', parent='ms_menu', command=('import maya.cmds as cmds\ncmds.shadingNode("ms_appleseed_material", asShader=True)')) + + # Load entity definitions + entity_defs = ms_commands.getEntityDefs(os.path.join(ms_commands.ROOT_DIRECTORY, 'scripts', 'appleseedEntityDefs.xml')) + + # Create BSDF + cmds.menuItem('menu_create_BSDF', subMenu=True, label='Create BSDF', to=True, parent='ms_menu') + for entity_key in entity_defs.keys(): + if entity_defs[entity_key].type == 'bsdf': + command = 'import ms_commands\nms_commands.createShadingNode("' + entity_key + '")' + cmds.menuItem(label=entity_key, parent='menu_create_BSDF', command=command) + + # Create EDF + cmds.menuItem('menu_create_EDF', subMenu=True, label='Create EDF', to=True, parent='ms_menu') + for entity_key in entity_defs.keys(): + if entity_defs[entity_key].type == 'edf': + command = 'import ms_commands\nms_commands.createShadingNode("' + entity_key + '")' + cmds.menuItem(label=entity_key, parent='menu_create_EDF', command=command) + + # Create Surface Shader + cmds.menuItem('menu_create_surface_shader', subMenu=True, label='Create Surface Shader', to=True, parent='ms_menu') + for entity_key in entity_defs.keys(): + if entity_defs[entity_key].type == 'surface_shader': + command = 'import ms_commands\nms_commands.createShadingNode("' + entity_key + '")' + cmds.menuItem(label=entity_key, parent='menu_create_surface_shader', command=command) + + # convert materials cmds.menuItem(divider=True, parent='ms_menu') - cmds.menuItem(label='About', parent='ms_menu', command='import ms_commands\nms_commands.msInfoDial()') + cmds.menuItem('menu_convert_maya_materials', subMenu=True, label='Convert Maya materials', to=True, parent='ms_menu') + + cmds.menuItem(label='Selected Materials', parent='menu_convert_maya_materials', command='import ms_commands\nms_commands.convertSelectedMaterials()') + cmds.menuItem(label='All Materials', parent='menu_convert_maya_materials', command='import ms_commands\nms_commands.convertAllMaterials()') + # Export + cmds.menuItem(divider=True, parent='ms_menu') + cmds.menuItem('menu_export', subMenu=True, label='Export', to=True, parent='ms_menu') + for render_settings_node in cmds.ls(type='ms_renderSettings'): + cmds.menuItem(label=render_settings_node, parent='menu_export', command=('import ms_export \nms_export.export("{0}")'.format(render_settings_node))) + + # About + cmds.menuItem(divider=True, parent='ms_menu') + cmds.menuItem(label='About', parent='ms_menu', command='import ms_commands\nms_commands.msInfoDial()') def deleteMenu(): cmds.deleteUI('ms_menu') diff --git a/sandbox/extras/maya/scripts/ms_menu.pyc b/sandbox/extras/maya/scripts/ms_menu.pyc deleted file mode 100644 index b13d052d2e..0000000000 Binary files a/sandbox/extras/maya/scripts/ms_menu.pyc and /dev/null differ diff --git a/sandbox/extras/maya/scripts/resources.qrc b/sandbox/extras/maya/scripts/resources.qrc deleted file mode 100644 index 5632fac8a3..0000000000 --- a/sandbox/extras/maya/scripts/resources.qrc +++ /dev/null @@ -1,5 +0,0 @@ - - - mayaToAppleseedGraphic.png - - diff --git a/sandbox/extras/maya/tools/render_sequence.py b/sandbox/extras/maya/tools/render_sequence.py new file mode 100644 index 0000000000..4a059e40c0 --- /dev/null +++ b/sandbox/extras/maya/tools/render_sequence.py @@ -0,0 +1,161 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright (c) 2012 Jonathan Topf + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +# THE SOFTWARE. + +# +# You will need PySide to run this script. +# Download it here: http://qt-project.org/wiki/PySideDownloads +# + +import sys +from PySide import QtGui, QtCore +import os +import subprocess +import re + +class RenderSequence_GUI(QtGui.QWidget): + def __init__(self): + super(RenderSequence_GUI, self).__init__() + self.initUI() + + def initUI(self): + main_layout = QtGui.QVBoxLayout() + self.setLayout(main_layout) + + # appleseed cli layout + binary_layout = QtGui.QHBoxLayout() + binary_layout.addWidget(QtGui.QLabel("Directory of appleseed.cli:")) + self.bin_dir = QtGui.QLineEdit('/projects/appleseed/sandbox/bin/Release') + binary_layout.addWidget(self.bin_dir) + main_layout.addLayout(binary_layout) + + # src layout + src_layout = QtGui.QHBoxLayout() + src_button = QtGui.QPushButton('Select File', self) + self.src_text = QtGui.QLineEdit() + self.sequence_check = QtGui.QCheckBox('Render Entire Sequence') + src_layout.addWidget(src_button) + src_layout.addWidget(self.src_text) + src_layout.addWidget(self.sequence_check) + main_layout.addLayout(src_layout) + + # dest layout + dest_layout = QtGui.QHBoxLayout() + dest_button = QtGui.QPushButton('Select Output Folder', self) + self.dest_text = QtGui.QLineEdit() + render_button = QtGui.QPushButton('Render', self) + dest_layout.addWidget(dest_button) + dest_layout.addWidget(self.dest_text) + dest_layout.addWidget(render_button) + main_layout.addLayout(dest_layout) + + # connections + src_button.clicked.connect(self.getSrcDir) + dest_button.clicked.connect(self.getDestDir) + render_button.clicked.connect(self.export) + + self.setGeometry(300, 300, 600, 30) + self.setWindowTitle('appleseed Render Sequence') + self.show() + + def getDestDir(self): + self.dest_text.setText(QtGui.QFileDialog.getExistingDirectory(caption='Choose Output Directory')) + + def getSrcDir(self): + self.src_text.setText(QtGui.QFileDialog.getOpenFileName()[0]) + + def export(self): + cli_path = os.path.join(self.bin_dir.text(), 'appleseed.cli') + src_file_path = self.src_text.text() + dest_dir_path = self.dest_text.text() + file_list = [src_file_path] + + if self.sequence_check.checkState(): + file_list = self.findSequence(src_file_path) + + for file in file_list: + output_file_name = os.path.splitext(os.path.split(file)[1])[0] + '.png' + output_file_path = os.path.join(dest_dir_path, output_file_name) + + print "Rendering {0} to {1}...".format(file, output_file_name) + + subprocess.call([cli_path, '-o', output_file_path, file, '-r 1 1']) + + print "Done." + + def findSequence(self, src_file): + if os.path.exists(src_file): + # get directory name and file name + dir_name, file_name = os.path.split(src_file) + + # define regular expression that checks for sequences of numbers + numeric_seq_regex = re.compile('\d+') + + # variables to store the position of the first digit of the number, last digit position, and the string that contains the number + start_pos = 0 + end_pos = 0 + seq_start_number = 0 + + # get the variables from the src file string + for num_seq in numeric_seq_regex.finditer(file_name): + start_pos = num_seq.start() + end_pos = num_seq.end() + seq_start_number = int(num_seq.group()) + + iter_file_name = file_name # holds the current file name in the loop looking for sequence files + current_itter_pos = seq_start_number # holds current number that will be searched for in file name + iter_files = [] # list of found file names + + while os.path.exists(os.path.join(dir_name, iter_file_name)): + # add the file name that just passes the existence test + iter_files.append(os.path.join(dir_name, iter_file_name)) + current_itter_pos += 1 + + # split file name into character list + iter_chars = list(iter_file_name) + + # create a new list of chars that contains the numeric portion of the file name + iter_num_chars = list(str(current_itter_pos).zfill(end_pos - start_pos)) + + # substitute the file number portion of the file name + i = start_pos + while i < end_pos: + iter_chars[i] = iter_num_chars[i - start_pos] + i += 1 + + # join the char list and set the iter file name ready for existence checking + iter_file_name = ''.join(iter_chars) + + # list the files that have been found + print "Found the following files:" + for file in iter_files: + print file + + return iter_files + +def main(): + app = QtGui.QApplication(sys.argv) + ex = RenderSequence_GUI() + sys.exit(app.exec_()) + +if __name__ == '__main__': + main() diff --git a/sandbox/extras/maya/tools/watch_folder.py b/sandbox/extras/maya/tools/watch_folder.py new file mode 100644 index 0000000000..496bde76cc --- /dev/null +++ b/sandbox/extras/maya/tools/watch_folder.py @@ -0,0 +1,166 @@ +from xml.dom.minidom import parseString +import os +import sys +import time +from datetime import datetime +import shutil + + +CLI_PATH = '/projects/appleseed/sandbox/bin/Release/appleseed.cli' +FLAGS = '' + +print '\n\n\n' + +#define helper class for printing colored text +class printc(): + @staticmethod + def warning(text): + if os.system == 'darwin': + print '\033[93m' + text + '\033[0m' + else: + print text + + @staticmethod + def error(text): + if os.system == 'darwin': + print '\033[91m' + text + '\033[0m' + else: + print text + + @staticmethod + def success(text): + if os.system == 'darwin': + print '\033[92m' + text + '\033[0m' + else: + print text + + + +def getDepends(xml_file_path): + + depend_list = [] + + file = open(xml_file_path,'r') + directory = os.path.split(xml_file_path)[0] + data = file.read() + file.close() + + dom = parseString(data) + + for entity in dom.getElementsByTagName('parameter'): + if entity.getAttribute('name') == 'filename': + + file_name_attr = entity.getAttribute('value') + + + if (sys.platform == 'win32') or (sys.platform == 'win64'): + file_name_attr = file_name_attr.replace('/', '\\') + else: + file_name_attr = file_name_attr.replace('\\', '/') + + depend_list.append( os.path.join( directory, file_name_attr) ) + + + + + return depend_list + + +def listAppleseedFiles(directory_path): + directory_entities = os.listdir(directory_path) + files = [] + appleseed_files = [] + for entity in directory_entities: + file_path = os.path.join(directory_path, entity) + if os.path.isfile(file_path): + if os.path.splitext(file_path)[1] == '.appleseed': + appleseed_files.append(file_path) + + + + return appleseed_files + + +def isRenderable(file): + print '\n' + depend_name_text = ('Dependencies for ' + os.path.split(file)[1]) + print depend_name_text + print len(depend_name_text) * '-' + is_renderable = True + for depend in getDepends(file): + if os.path.exists(os.path.join(depend)): + printc.success('EXISTS ' + depend) + else: + printc.error('MISSING ' + depend) + is_renderable = False + return is_renderable + + + + +def main(): + + working_dir = os.getcwd() + + # make folder to put rendered appleseed files into + if not os.path.exists(os.path.join(working_dir, 'done')): + os.mkdir(os.path.join(working_dir, 'done')) + + # make folder to put rendered images into + if not os.path.exists(os.path.join(working_dir, 'output')): + os.mkdir(os.path.join(working_dir, 'output')) + + while (True): + appleseed_files = listAppleseedFiles(working_dir) + + #if any appleseed files have been found + if len(appleseed_files): + for appleseed_file in appleseed_files: + if isRenderable(appleseed_file): + + + printc.warning('\n\n:::: RENDERING ' + appleseed_file + ' ::::\n\n') + + #create shell command + appleseed_file_name = os.path.split(appleseed_file)[1] + output_file_name = os.path.splitext(appleseed_file_name)[0] + '.png' + output_file_path = os.path.join(working_dir, 'output', output_file_name) + + command = CLI_PATH + ' -o ' + output_file_path + ' ' + appleseed_file + + #execute command + return_value = os.system(command) + + #if the return value isnt 0 then somehtign may have gone wrong + if not return_value == 0: + printc.warning('File may not have rendered correctly: ' + appleseed_file) + + move_dest = os.path.join(working_dir, 'done', os.path.split(appleseed_file)[1]) + shutil.move(appleseed_file,move_dest) + + break + else: + print '\n', datetime.now(), os.path.split(appleseed_file)[1], ': Missing dependencies' + else: + print '\n', datetime.now(), ': Nothing to render' + time.sleep(3) + + +if __name__ == '__main__': + main() + + + + + + + + + + + + + + + +