3ds Max USD API Reference
|
Welcome to the 3ds Max USD SDK. This package enables customization of the 3ds Max USD component, specifically the ability to customize import and export operations. It is important to use the SDK version that targets your version of 3ds Max (2021, 2022, 2023, or 2024). Extensions created using this SDK are extensions to the 3ds Max USD component, not stand-alone 3ds Max plug-ins, and so must be registered accordingly (see below).
Using this SDK, the 3ds Max USD export can be extended to support 3rd party objects and materials, and to add custom data that is not currently exported in the default 3ds Max USD system.
For example, the 3ds Max USD plugin currently exports standard lights, cameras, shapes, helpers and mesh nodes. You might have defined a 3ds Max node which has its own USD schema or extended type. Using this SDK, you can properly handle the export rather than relying on the default fallback mesh export method.
The initial focus is on extending the default 3ds Max USD export implementation.
The 3ds Max USD SDK contains:
/maxusd
- The main SDK, containing headers and libraries/maxsdk
- The 3ds Max C++ SDK, for the target 3ds Max version. The APIs in this SDK provide access to 3ds Max itself, for example scene data, which might be needed by the 3ds Max USD extension./Pixar_USD
- Pixar USD headers and libraries, including those to support HDF5 and MaterialX./Python
- A Python environment./samples
- A set of C++ and Python sample projects that illustrate how to use the APIs in this SDK. See Samples below./spdlog
- A fast, open source logging library.The requirements for using this SDK are the same as the 3ds Max SDK.
The SDK contains a set of sample projects to illustrate how to implement the available APIs. The samples are available in C++ and Python. They are constructed to be easily added individually as application plugins to 3ds Max. Remember however that those extensions are not 3ds Max plugins but are plugins to the 3ds Max USD plugin, and are registered in a different way.
ShaderWriter
that exports glTFMaterial to UsdPreviewSurface. This is a minimal, non-exhaustive example.PrimWriter
that exports 3ds Max spheres to USD native spheres. ExportChaser
to expose user properties and custom attributes to a USD custom data node.The following is an overview on the set of classes included in the SDK.
Defines a class that translates a 3ds Max material to a UsdShade prim. The shader writer is specific to the shading schema it supports (UsdPreviewSurface
, MaterialX
, etc.). The shader writer is registered to a specific material type.
Registry mapping of 3ds Max materials and the shader writers exporting those material types. Loads the registered ShaderWriter
plugin required at material export.
Registry keeping a list of possible material targets (conversion to) when exporting 3ds Max materials to USD (by default, UsdPreviewSurface
is the material target). The list of available shading mode exporters is also kept in the registry. It enables you to register exporters that may use another material schema (for example Renderman UsdRiMaterialAPI
).
Cycles through the material list extracted from the exported 3ds Max nodes and calls the proper shader writer. A shading mode exporter implements the pre, export and post methods of the material export. A default exporter is already implemented.
Defines a class translating a 3ds Max node to a UsdGeom prim. The prim writer can be written to be type-specific or support a larger family type. It is up to the prim writer to define which nodes it exports.
Registry keeping a list of possible prim writers available at export.
Defines a plugin that runs after the core 3ds Max USD export. This should ideally be used to make small changes or to add attributes in a non-destructive way. Chasers need to be very careful as to not modify the structure of the USD file.
Registry mapping between the ExportChaser and their 'name'.
Plugins need to link against the maxsdk
, pxrusd
and the maxUsd
(from the 3ds Max USD component) core.lib;maxutil.lib;maxUsd.lib and 3dsmax_<usdlibs>.lib
maxsdk
and pxrusd
artifacts are the ones listed in the artifact file from the 3ds Max USD component.The PrimWriterRegistry
, the ShaderWriterRegistry
and the ShaderModeRegistry
use the PlugRegistry
concept from USD.
See the USD Registry Reference for more information.
Plugins are registered by providing a path or paths to JSON files that describe the location, structure and contents of the plugin. The standard name for these files in plugInfo.json
. The Info sub-section in the plugInfo schema contains those nested properties:
MaxUsd
: Required property identifying the 3ds Max Info block.PrimWriter
: Optional property stating the current plugin contains PrimWriters.ShadingModePlugin
: Optional property stating the current plugin contains a ShadingMode definition.ShaderWriter
: Optional property stating the current plugin contains ShaderWriters.providesTranslator
: Required property listing the translated 3ds Max material; the strings making up the array are the material non-localized names.ExportChaser
: Option property stating the current plugin contains an ExportChaser.Here is a possible sample plugInfo.json
file declaring a C++ plugin containing the implementation of:
In case of a Python plugin, the plugin script location must part of the Python path (this can be achieved in a startup script with the Python command sys.path.insert
).
For the USD PlugRegistry to find the plugInfo.json
file, the file directory must be registered.
Again, this can be achieved in a 3ds Max startup script for the plugin, or you can use the environment variable PXR_PLUGINPATH_NAME to define the USD plugin path (the path where the plugInfo.json
file is located).
Regardless of the type of plugin, C++ or Python, to register your plugin you'll need to add a registration script to your 3ds Max plugin in the "post-start-up scripts parts", these USD plugins need to be loaded only when Max is ready to be interacted with and NOT be loaded by the 3ds Max plugin itself prior to that. You can find examples of such scripts in the SDK sample projects.
When creating a C++ plugin (.dll), it should be a separate project from your actual 3ds Max plugin. USD plugin DLLs should be loaded via the USD plugin API, USD does not expect the DLL to be already loaded when the plugin is loaded - and if it is, that can create issues.
For a C++ plugin it is also very important to set the project option "Remove unreferenced code and data" to NO. Not doing so could cause the Macro to be optimized out and the Writer to never be properly registered.
New Python module maxUsd
located with component installed files in Contents/bin/python. The Python path is already added to the list of directories that should be searched for modules when using import.
To import the 3ds Max USD Python module, a user can simply use import maxUsd
.
It contains the ShaderWriter base class from which material writers need to inherit from. A ShaderWriter instance is created for each material needing translation.
Two methods need to be implemented to have functional ShaderWriter:
maxUsd.ShaderWriter.ContextSupport::Supported
, or Unsupported
, or that the class acts as a Fallback
.USDSceneBuilderOptions
To register the ShaderWriter to use for the supported materials:
The only element exposed to Python from the shading mode registry is the ability to register conversion type (or material target).
The name
is used directly in the render option string as one of the valid values of the "Materials export to" option of the USD export dialog.
The render context
will be used to specialize the binding point. See UsdShadeMaterial documentation for details. A value of UsdShadeTokens->universalRenderContext
should be used if the resulting UsdShade nodes are written using an API shared by multiple renderers, like UsdPreviewSurface. For UsdShade nodes targeting a specific rendering engine, please define a custom render context understood by the renderer.
The nice name
is the name displayed in the "Materials export to" option of the USD export dialog.
The description
is displayed as a tooltip in the "Materials export to" option of the USD export dialog.
It contains the PrimWriter base class from which object/prim writers need to inherit from. The PrimWriter is only responsible for providing translation of the 3dsMax Object referenced by the received Node. It should therefor not attempt to handle instancing, material assignment, and the transform of the Node itself. Instancing is handled by the calling code - if an object is instanced across multiple nodes, the PrimWriter is only called once, on the first node referencing the instanced object. The required Xform prim hierarchy is already generated. Similarly, the Node's transform is applied by the calling code, on the UsdGeomXformable prim built by the PrimWriter, after it is run. If the USD prim is not a UsdGeomXformable, a warning is raised, but it doesn't prevent the export from continuing.
The instanced PrimWriters are not linked to a specific 3ds Max object. The writers will be called and evaluated for each node in the scene tree. Therefore the methods all receives a parameter nodeHandle
, the MAXScript unique NodeHandle on the 3ds Max Node being exported.
The methods that may need overriding definitions:
maxUsd.PrimWriter.ContextSupport::Supported
, Fallback
, Unsupported
)SdfChangeBlock
, so the prim writers are not responsible for creating the prims. The type specified here is mostly a hint for that first creation pass, if required, it can be overriden from the Write()
method (by defining a prim at the same path with a different type). Unless we are always forcing the creation of an Xform prim (see RequireXformPrim()
), we should return an Xformable type here, otherwise it will not be possible to apply the node's transform onto the prim later on (an error will be raised in this scenario).suggestedName
is what the base implementation uses, from the node's name, and uniqueness amongst siblings is ensured.maxUsd.XformSplitRequirement.ForOffsetObjects
: This should be the case for most objects, this means we require an Xform if an object offset is applied to the object. Indeed, object offset transforms should not be inherited, so we need an Xform prim to encode the node's transform (the children of the node will export to children of this prim), and another for the object itself, which will be exported to a prim under that Xform. It will contain the object offset transform, and it will not have children.maxUsd.XformSplitRequirement.Always
: For cases where we always need to have a separate prim for the node's transform. This could be the case if we need to add an inherent transform to the object's prim, part of the translation, and we never want that transform to be inherited.maxUsd.XformSplitRequirement.Never
: To be used if we know we never want to split the node's transform from its object. For example we could be baking the object offset transform into the geometry itself - in this scenario, we avoid the need of an extra Xform entirely.To register a PrimWriter
It contains the ExportChaser base class from which export chasers need to inherit from. A ExportChaser instance is created at each export and called at the end of the export process. Two methods need to be implemented to have functional ExportChaser:
factoryContext
(detailed below) contains the context details for the export.To register the ExportChaser
This exposes the FactoryContext
, the argument received by the ExportChaser constructor.
USDSceneBuilderOptions
It contains the class USDSceneBuilderOptions which exposes the export arguments from the current export context:
maxUsd.MappedAttributeBuilder.Type.Color3fArray
, FloatArray
, Float2Array
, Float3Array
, TexCoord2fArray
, TexCoord3fArray
)maxUsd.FileFormat.Binary
, ASCII
, USDZ
)maxUsd.NormalsMode.AsPrimVar
, AsAttribute
, None
)maxUsd.MeshFormat.FromScene
, TriMesh
, PolyMesh
)maxUsd.TimeMode.AnimationRange
, CurrentFrame
, ExplicitFrame
, FrameRange
)maxUsd.UpAxis.Y
or Z
)maxUsd.Log.Level.Off
, Error
, Warn
, Info
)