For the pymxs equivalent of this topic, see Performing Inspection of Classes and Objects in pymxs.
Many 3ds Max features are implemented as plug-ins and expose properties at run-time using a mechanism called a parameter block. This is hidden from MAXScript users, but in Python these properties are accessible explicitly using a ParameterBlock class, which is accessible on any Animatable derived class via the Animatable.GetParameterBlock() function or the equivalent Animatable.ParameterBlock property.
Many of these run-time parameters are documented in the MAXScript documentation, and in most cases, the names of the parameters are the same as those of MAXScript.
You can set or query the dynamic parameters of 3ds Max objects via the ParameterBlock class. The ParameterBlock class wraps the parameters exposed via 3ds Max's IParamBlock and IParamBlock2 classes. Examples of these types of parameters are the radius of a sphere object and the angle of a bend modifier.
Unlike MAXScript, when you access a parameter, you do not get the value of the parameter, rather you get a Parameter instance that wraps the parameter, and you then get/set properties on that Parameter instance.
Set your parameters via the ParameterBlock class, for example, as follows:
obj = MaxPlus.Factory.CreateGeomObject(MaxPlus.ClassIds.Sphere)
obj.ParameterBlock.Radius.Value = 5.0
node = MaxPlus.Factory.CreateNode(obj)Unlike MAXScript, parameters are searched for only on the object specified. Thus, if you have an INode instance and you access its ParameterBlock, you get the ParameterBlock on the node itself. You can also access parameters on the base object via INode.BaseObject, for example, as follows:
obj = MaxPlus.Factory.CreateGeomObject(MaxPlus.ClassIds.Cylinder)
node = MaxPlus.Factory.CreateNode(obj)
node.BaseObject.ParameterBlock.Radius.Value = 10.0
node.BaseObject.ParameterBlock.Height.Value = 30.0Use the help command as follows to obtain the list of methods and properties of ParameterBlock:
import MaxPlus
help(MaxPlus.ParameterBlock) A ParameterBlock holds a list of Parameters. To query the Parameters available in the ParameterBlock that you set for your object, do as follows:
obj = MaxPlus.Factory.CreateGeomObject(MaxPlus.ClassIds.Sphere)
for p in obj.ParameterBlock.Parameters:
print p.Name, p.Valuep in obj.ParameterBlock.Parameters retrieves each of the Parameters from the ParameterBlock. The name and current value for each of the Parameters are then printed out.
The names of the dynamic properties exposed by ParameterBlock are not case sensitive.
The Parameter class also has its own set of methods and properties. To query these, do as follows:
import MaxPlus
help(MaxPlus.Parameter)A description of its methods and properties is as follows:
Parameter.Controller / Parameter.GetController(), Parameter.SetController() - get/set the controller on the parameter. For example, if you animate the radius of a sphere, mySphereObj.ParameterBlock.Radius.Controller would return the controller for the radius. An error occurs if you attempt to set a non-animatable or read-only property.
Parameter.IsAnimatable / Parameter.IsAnimatable() - determine if the Parameter is animatable.
Parameter.IsArrayData / Parameter.IsArrayData() - determine if the Parameter is a type of array. Parameter.GetValue() returns an array containing values at the current time.
Parameter.IsArrayParameter / Parameter.IsArrayParameter() - determine if the Parameter is a specific type of array, where the Parameter can be cast to ArrayParameter via
ap = MaxPlus.ArrayParameter._CastFrom(p)See [ArrayParameters] for more information.
Parameter.IsObsolete / Parameter.IsObsolete() - determine if the Parameter was defined as obsolete by the object. When you enumerate over the Parameters in a ParameterBlock, obsolete Parameters are not included. But you can still access them by name. This prevents breakage of scripts when a Parameter becomes obsolete.
Parameter.IsReadOnly / Parameter.IsReadOnly() - determine if the Parameter is read-only.
Parameter.Name / Parameter.GetName() - obtain the name of the Parameter.
Parameter.TabIndex / Parameter.GetTabIndex() - Allow Parameters to point to a specific item within an ArrayParameter. Read only.
Parameter.Type / Parameter.GetType() - The numeric type associated with the Parameter. Read only. The types forParameters is a subset of the types for FPValues. See Executing Python in 3ds Max.
Parameter.Value / Parameter.GetValue(), Parameter.SetValue() - get/set the value of the Parameter. An error occurs if you try to set a Parameter that is read only, or the value specified cannot be converted to the type expected by the Parameter. For example, you can't assign a string to a float parameter.
Parameter.ReplaceController() / Parameter.SetController() - If a Parameter already has a controller assigned to it, Parameter.ReplaceController() will attempt to copy information from the existing controller to the controller being assigned. Parameter.SetController() will not copy the information.
There are two implementations of Parameter.SetController():
SetController(Parameter self, Control c)
SetController(Parameter self, Control c, bool preserveFrame0Value) By default, preserveFrame0Value is set to true; therefore, if you choose the first implementation, or set preserveFrame0Value to True, then the controller takes on the existing value of the parameter at frame 0. For example, if a controller is assigned to the radius property using Parameter.SetController(), and the existing value of radius is 50; after assigning the controller, the frame 0 value of the controller is also 50.
If Parameter.IsArrayData is True, Parameter.Value will return a list containing the current values for the parameter. This list is not connected to the Parameter, and changing the size or contents of the list does not affect the value of the Parameter. If Parameter.IsReadOnly and Parameter.IsArrayParameter are False, then after modifying the list, you can assign the list back to the Parameter by assigning it to the Parameter.Value property.
For certain Parameter types, such as FPTypeConstants.Angle (Type value 5), the parameter value shown in the UI, MAXScript, and Python is not the same as the value stored in the Parameter. Instead, dimensioning is applied to the UI/MAXScript/Python value while Parameter holds the internal data value (undimensioned). In the case of FPTypeConstants.Angle, the displayed value is in degrees, while the stored value is in radians. This dimensioning is normally invisible to the user, but can come into play when dealing with controllers assigned to these parameters, as the controllers will store the actual value (that is, the internal data value), and the dimensioning information is not held by the controller (a controller can be assigned to multiple parameters with different dimensioning).
The parameter types with dimensioning are:
FPTypeConstants.Rgb (Type value 2) - displayed: 0-255; stored: 0-1
FPTypeConstants.Angle (Type value 5) - displayed: degrees; stored: radians
FPTypeConstants.PercentFraction (Type value 6) - displayed: 0-100; stored: 0-1
FPTypeConstants.Hsv (Type value 10) - displayed: 0-255; stored: 0-1
FPTypeConstants.ColorChannel (Type value 11) - displayed: 0-255; stored: 0-1
FPTypeConstants.RgbTab (Type value 2050) - displayed: 0-255; stored: 0-1
FPTypeConstants.AngleTab (Type value 2053) - displayed: degrees; stored: radians
FPTypeConstants.PercentFractionTab (Type value 2054) - displayed: 0-100; stored: 0-1
FPTypeConstants.HsvTab (Type value 2058) - displayed: 0-255; stored: 0-1
FPTypeConstants.ColorChannelTab (Type value 2059) - displayed: 0-255; stored: 0-1
You can access a Parameter to get or set its properties or call its methods by doing any of the following:
\<Parameterblock>.<name>; for example, obj.ParameterBlock.Radius.Value = 10.0\<Parameterblock>.GetParamByName(<name>); for example, obj.ParameterBlock.GetParamByName('Radius').Value = 10.0\<Parameterblock>.GetItem(<index>); for example, obj.ParameterBlock.GetItem(0).Value = 10.0An ArrayParameter can be thought of an array of Parameters. As mentioned above, if IsArrayParameter is set to true, you can cast your Parameter to an ArrayParameter by doing the following:
ap = MaxPlus.ArrayParameter._CastFrom(p)To obtain the methods and properties of ArrayParameter, do as follows:
import MaxPlus
help(MaxPlus.ArrayParameter)In addition to the methods and properties for Parameter, ArrayParameter also has the following properties and methods:
ArrayParameter.IsResizable / ArrayParameter.IsResizable() - get whether the array is resizable.ArrayParameter.NumItems / ArrayParameter.Count() - get the number of items. To resize, use ArrayParameter.SetCount().ArrayParameter.Delete() - method that allows you to resize the array by deleting items.ArrayParameter.Insert() - method that allows you to resize the array by inserting an item.ArrayParameter.Append() - method that allows you to resize the array by appending an item. Delete(), Insert(), and Append() are not commonly used methods. They are only used for certain kinds of plug-ins, such as scripted custom attributes, and are targeted towards advanced users.
Each item in an ArrayParameter is a Parameter. To enumerate through this array, do as follows:
pa = MaxPlus.ArrayParameter._CastFrom(p)
for v in pa.Items:The following example demonstrates how to get the properties for the ArrayParameter, then enumerate across its items and obtain each item's properties.
pa = MaxPlus.ArrayParameter._CastFrom(p)
print ' ', pa.Name, pa.Type, pa.IsObsolete, pa.IsAnimatable, pa.IsReadOnly, pa.IsArrayData, pa.Value
for v in pa.Items:
print ' ', v.TabIndex, v.Name, v.Type, v.IsObsolete, v.IsAnimatable, v.IsReadOnly, v.IsArrayData, v.ValueThe following example creates a material, then enumerates through each Parameter in the ParameterBlock. Then, for Parameters where Parameter.IsArrayData is true, it prints out each value in the array. For Parameters where Parameter.IsArrayParameter is true, it casts the Parameter to an ArrayParameter, then prints out the properties of the ArrayParameter. Then, it iterates through each Parameter in the ArrayParameter and prints out the properties for each Parameter.
import MaxPlus
# Define a method to print array data
def printArrayData(indent, v):
count = len(v)
print '%s#(' % indent,
for i in xrange(count):
if i != (count-1):
print '%s, ' % str(v[i]),
else:
print '%s' % str(v[i]),
print ')'
# Create a standard material
obj = MaxPlus.Factory.CreateMaterial(MaxPlus.ClassIds.Standardmaterial)
# Enumerate across Parameters and print out the properties of each Parameter
for p in obj.ParameterBlock.Parameters:
print ' ', p.Name, p.Type, p.IsObsolete, p.IsAnimatable, p.IsReadOnly, p.IsArrayData, p.Value
# If IsArrayData is true, then print out the array data
if p.IsArrayData:
v = p.Value
printArrayData(' ', v)
# If IsArrayParameter is true, then cast the Parameter to an ArrayParameter
if p.IsArrayParameter:
pa = MaxPlus.ArrayParameter._CastFrom(p)
#print out the properties of the ArrayParameter
print ' ', pa.Name, pa.Type, pa.IsObsolete, pa.IsAnimatable, pa.IsReadOnly, pa.IsArrayData, pa.NumItems, pa.IsResizable, pa.Value
# For each Parameter in each ArrayParameter, print out its properties
for v in pa:
print ' ', v.TabIndex, v.Name, v.Type, v.IsObsolete, v.IsAnimatable, v.IsReadOnly, v.IsArrayData, v.Value