Share

MAXtoA Scripted Plug-ins

Available in 3ds Max 2018 and higher: MAXScript provides a simple way to create a "wrapper" plug-in with a custom UI for Arnold nodes. This approach is for plug-ins that are not shaders - shader plug-ins use a different approach.

A MAXtoA plug-in uses specially-named parameters that the MAXtoA translator understands. MAXtoA ignores other parameters and the internals of the plug-in, whether it contains logic or wraps another existing 3ds Max class. 3ds Max sees the wrapped class and plug-in logic, which will show up in the UI (viewport, modifier stack, etc depending on plug-in type), and Arnold (via MAXtoA) reacts only to the special parameters, using them to instantiate some particular Arnold node and set parameters on it accordingly.

The following plug-in types can be extended:

  • Geometry - Any scripted geometry plugin can be turned into any Arnold shape node.
  • Cameras - A scripted camera can be turned into any Arnold camera node.
  • Modifiers on Lights - A scripted modifier applied to an Arnold Light can be turned into any Arnold light filter node.

Parameter Layout and Naming

MAXtoA looks for exposed parameters that following a specific naming convention, and acts on those parameters accordingly. The parameter names that MAXtoA recognizes are:

  • arnold_node: This parameter must be of type #string and contains the name of the Arnold node to be instantiated for this particular script.
  • arnold_node_xxx: This is the way to set parameter named xxx on the Arnold node. That is, anything following the prefix "arnold_node_" is taken to be the parameter name. The parameter type in the scripted plug-in must match what the Arnold node expects.
  • arnold_link*xxx: This is the way to set parameter xxx as a link to a shader on the Arnold node. Anything following the prefix "arnold_link_" is taken to be the parameter name on the Arnold node. If the value of the parameter (which must be of type #texmap) is non-empty, the output of that texmap (or rather the Arnold shader implementing that texmap) will be connected to the Arnold node's input, and the value will come from it, replacing the value given by any arnold_node*xxx parameter, if present.
  • arnold_decl*xxx: This declares user-defined parameters before they are used. Anything following the "arnold_decl_" prefix is taken to be the parameter name. The parameter itself must be of type #string and contain an Arnold parameter declaration string, for example "constant FLOAT" for a float value.

Parameters are processed in the order they appear in the script, from top to bottom. Declarations must precede usage.

Enum Parameters

Arnold parameters of type enum are normally represented by and integer value starting at zero. However, MAXScript dropdown controls are one-based. Therefore, MAXtoA translates enum type parameters to one-based arrays to support dropdowns in plug-in UIs. This snippet illustrates how enums are defined and wired to a UI control.

Enum Snippet

parameters main rollout:params
(
   . . .
   arnold_node_mode type:#integer default:2 ui:mode
   . . .
)
  
rollout params " Parameters"
(
   . . .
   dropdownlist mode "Mode" items:#("Blend", "Mix", "Replace", "Add", "Sub")
   . . .
)

The parameter on the scripted node (the parameter named arnold_node_mode) will have values 1, 2, 3, 4 or 5 based on what is selected by the dropdown, however, the value actually sent to Arnold will be 0, 1, 2, 3, or 4.

Example: A Spherical Camera Plug-in

This example creates a new camera type, derived from FreeCamera, named "Spherical Cam" in the Arnold category, which simply turns on the Arnold spherical_camera node. This script sets no other parameters.

Example

plugin Camera arnold_spherical_camera
extends:FreeCamera
name:"Spherical Cam"
classID:#(135251,542126)
category:"Arnold"
replaceUI:true
(
parameters main rollout:params
    (
        arnold_node type:#string default:"spherical_camera"
    )
  
    rollout params "Example Parameters"
    (
        
    )
)

Example: Sphere Geometry Plug-in

This example creates a new geometry type in the Arnold category called "Sphere". It extends the built-in 3ds Max sphere, so it shows up in the viewport as such. But Arnold will actually be given the mathematically exact "sphere" shape node when rendering.

Most of the code in this example enables geometry creation with the mouse and to keeping that in sync with the parameter defining the Arnold object. A much simpler piece of code could have been written had we completely ignored the wrapped object; we could have set the UI in the rollout to apply directly to the Arnold style parameters, which means no updateArnold() function would have been needed, and it could have been only a few lines.

Example

plugin Geometry Arnold_Sphere
name:"Sphere"
classID:#(0xf00df103, 0xc55744a1)
category:"Arnold"
extends:Sphere
replaceUI:true
(
    local lastSize, meshObj
    parameters pblock rollout:params
    (
        arnold_node type:#string default:"sphere"
        arnold_node_radius type:#float default:1.0
        arnold_node_center type:#point3 default:[0.0,0.0,0.0]
      
        radius type:#float animatable:true ui:radius default:1.0
    )

    fn fmax val1 val2 = if val1 > val2 then val1 else val2

    fn updateArnold =
    (
          -- Modify the Arnold Sphere
          arnold_node_radius = delegate.radius
    )
        
    tool create
    (
        on mousePoint click do
        case click of
        (
            1: nodeTM.translation = gridPoint
            2: #stop
        )
        on mouseMove click do
        (
            if click == 2 then (            
                radius = delegate.radius = fmax (abs gridDist.x) (abs gridDist.y)
                updateArnold()
            )
        )
    )  
  
    rollout params "Sphere Parameters"
    (
        Spinner radius "Radius:" range:[0, 1e9, 1]

        on radius changed val do (
            delegate.radius = val
            updateArnold()
        )
    )
)

The key part of this code is the Arnold-specific parameter declarations:

arnold_node type:#string default:"sphere"
arnold_node_radius type:#float default:1.0
arnold_node_center type:#point3 default:[0.0,0.0,0.0]

These parameters tell Arnold to build a node named ‘sphere’ and assign its ‘radius’ parameter of type float and the ‘center’ parameter of type point with the value from these variables.

Had we needed custom declared user variables (which are needed, for example, in the volume node), it would have looked like this:

arnold_node type:#string default:"volume"
arnold_node_min type:#point3 default:[-0.5,-0.5,0] 
arnold_node_max type:#point3 default:[0.5,0.5,1] 
arnold_node_dso type:#string default:"volume_openvdb"
        
arnold_decl_filename type:#string default:"constant STRING"
arnold_node_filename type:#filename default:"smoke.vdb"
        
arnold_decl_bounds_slack type:#string default:"constant FLOAT"
arnold_node_bounds_slack type:#float default:0.0

This would instantiate a node called volume as before, and set its min, max and dso parameters. But the rest of the parameters (due to the plug-in nature of volumes) are user defined, so we need to define a string parameter called "filename", a float parameter called "bounds_slack" and so on and so on.

Example: Gobo Filter Plug-in

This example is a stripped down version of the Arnold Gobo filter modifier plugin (located in <3dsmax>\Plugins\maxscript\arnoldlight_gobofilter.ms). It show case how you can add UI controls to support both a color picker and a Texmap lookup. The Arnold target parameter here is gobo.slidemap.

Example

plugin modifier Arnold_Light_Gobo
name:~ARNOLD_LIGHT_FILTER_GOBO_NAME~
category:"Arnold"

classID:#(0xf00df10d,0x4001a10d)

extends:ArnoldLightFilterModifier replaceUI:true version:1
(
  parameters main rollout:params
  (
    arnold_node type:#string default:"gobo"  
arnold_node_slidemap type:#color ui:slidemapcolor default:[255,255,255]
    arnold_link_slidemap type:#texturemap ui:slidemap
  )
  rollout params ~ARNOLD_LIGHT_FILTER_GOBO_ROLLOUT_NAME~
  (
      colorpicker slidemapcolor "Color" color:[255,255,255] modal:false
      mapButton slidemap "Map"
  )
)

Was this information helpful?