Share

Performing Inspection of Classes and Objects in pymxs

There are several functions you can use to inspect objects and classes in pymxs. This topic discusses the most commonly used functions, but there are many more. See the MAXScript Help topic 'Class and Object Inspector Functions', and 'showInterfaces Inspector Function' for more detailed information.

apropos()

This function searches and prints out information about global variables by name pattern and class of contents. Globals include things like classes, structs (such as polyop, which contains functions for working with EditablePoly objects), and functions. The apropos() function takes three parameters:

pymxs.runtime.apropos(pattern_string, [implicitWild=true|false], [to=pymxs_stream])
  • pattern_string is a string used to match the names of globals.
  • implicitWild is optional, and specifies whether there is an implicit wildcard character at the beginning and end of the pattern string. The default is true.
  • to specifies an optional stream to send output to.
Note:

Functions that would send output to the listener when executed in MAXScript do not do so in pymxs. For this reason the optional to parameter is actually required in order to obtain useful information from this function.

For example, to get all the globals that contain the string 'plane':

res=pymxs.runtime.stringStream('')
pymxs.runtime.apropos('plane',to=res)
print(res)

Which produces this output:

StringStream:'PxUpdateGroundPlane (MAXScriptFunction): PxUpdateGroundPlane()
gw.dualPlane (<internal>): SystemGlobal:dualPlane
meshOps.startSlicePlane (Primitive): startSlicePlane()
Planet (const MAXClass): Planet
meshop.moveVertsToPlane (Primitive): moveVertsToPlane()
PFPlaneMeshWrapper (const MAXClass): PFPlaneMeshWrapper
g_thePlane (UndefinedClass): undefined
Plane_Angle (const MAXClass): Plane_Angle
PlaneAngleManip (const MAXClass): Plane_Angle
polyOps.resetPlane (Primitive): resetPlane()
polyOps.startSlicePlane (Primitive): startSlicePlane()
Plane (const MAXClass): Plane
skinOps.gizmoResetRotationPlane (Primitive): gizmoResetRotationPlane()
SectionPlane (const UndefinedClass): undefined
polyop.moveFacesToPlane (Primitive): moveFacesToPlane()
polyop.resetSlicePlane (Primitive): resetSlicePlane()
polyop.getSlicePlane (Primitive): getSlicePlane()
polyop.setSlicePlane (Primitive): setSlicePlane()
polyop.inSlicePlaneMode (Primitive): inSlicePlaneMode()
polyop.moveEdgesToPlane (Primitive): moveEdgesToPlane()
polyop.moveVertsToPlane (Primitive): moveVertsToPlane()

To refine this search to only those globals beginning with 'plane', we can turn off implicit wildcards, and supply one only at the end of the string:

res=pymxs.runtime.stringStream('')
pymxs.runtime.apropos('plane*', implicitWild=false, to=res)
print(res)

Which produces a much shorter output:

Planet (const MAXClass): Planet
Plane_Angle (const MAXClass): Plane_Angle
PlaneAngleManip (const MAXClass): Plane_Angle
Plane (const MAXClass): Plane

showClass() and showProperties()

The showClass() and showProperties() functions are useful for inspecting specific pymxs classes and their properties. The showClass() function takes a string, while showProperties() takes an object. The showProperties() function has the advantage that it can show dynamic properties that might have been created on the object after it was created.

The showClass() function has the following form:

pymxs.runtime.showClass(pattern_string, [to=pymxs_stream])
  • pattern_string is a string to match against class names. By default this is an exact match, so 'box' will only match the Box class. You can add wildcards to expand the match. For example, 'box*' will also match BoxGizmo and Box_2_Global_Utility.
  • to is an optional output stream, though in the pymxs context it is the only way to get useful output from this function.

The placement of wildcards in the pattern string affects the results found:

  • 'path*' -- all 3ds Max classes starting with 'path'
  • 'noise.*' -- all the accessible properties on the Noise texture map
  • ':mod' -- all the modifier classes
  • '*.rad' -- all the classes with a property name containing 'rad'
  • '*:controller' -- all the classes that have 'controller' in their superclass name

For example, to get the classID and properties of the Sphere class:

res = pymxs.runtime.stringStream('')
pymxs.runtime.showClass('sphere.*', to=res)
print(res)

Which results in:

Sphere : GeometryClass {11,0}
  .typeinCreationMethod (Creation_Method) : integer
  .typeInPos (Type_in_Position) : point3
  .typeInRadius (Radius) : float
  .radius : worldUnits
  .segs (Segments) : integer
  .smooth : boolean
  .hemisphere : float
  .chop (Squash) : integer
  .recenter : boolean
  .mapCoords (Generate_Texture_Coords) : boolean
  .slice (Slice_On/sliceon) : boolean
  .sliceFrom (Slice_From) : angle
  .sliceTo (Slice_To) : angle

The showProperties() function displays the properties of an object that is a specific instance of a class. It has the form:

pymxs.runtime.showProperties(pymxs_object, [pattern_string], [to=pymxs_stream])
  • pymxs_object is an object that derives from the MAXWrapper class
  • pattern_string is an optional wildcard pattern to apply to properties to be inspected
  • to is an optional output stream, though in the pymxs context it is the only way to get useful output from this function.

For example, to get all the properties for a sphere object:

s = pymxs.runtime.sphere()
res = pymxs.runtime.stringStream('')
pymxs.runtime.showProperties(s, to=res)
print(res)

After which the result stream res contains:

  .typeinCreationMethod (Creation_Method) : integer
  .typeInPos (Type_in_Position) : point3
  .typeInRadius (Radius) : float
  .radius : worldUnits
  .segs (Segments) : integer
  .smooth : boolean
  .hemisphere : float
  .chop (Squash) : integer
  .recenter : boolean
  .mapCoords (Generate_Texture_Coords) : boolean
  .slice (Slice_On/sliceon) : boolean
  .sliceFrom (Slice_From) : angle
  .sliceTo (Slice_To) : angle
  .realWorldMapSize : boolean

showInterfaces()

In pymxs, the methods that an object can use are contained in one or more interfaces associated with that object's class. The showInterfaces() function can be used to inspect those interfaces and the methods they contain. The showIntefaces() function has the form:

showInterfaces(pymxs_object, [to=pymxs_stream])
  • pymxs_object is the 3ds Max object, class or node to be inspected
  • to is an optional output stream, though in the pymxs context it is the only way to get useful output from this function.

For example to view all the interfaces and associated methods on an Editable_Poly object:

t = pymxs.runtime.teapot()
pymxs.runtime.convertTo(t, pymxs.runtime.editable_Poly)
res = pymxs.runtime.stringStream('')
pymxs.runtime.showInterfaces(t, to=res)
print(res)

The res stringStream will contain a large number of methods, as the EditablePoly interface exposes a lot of functionality:

 Interface: EditablePoly
   Properties:
    .edgeChamferType : enum : Read|Write
       edgeChamferType enums: {#Standard|#Quad}
    .edgeChamferQuadIntersections : boolean : Read|Write
   Methods:
    <bool>Hide <enum>mnSelLevel flags:<DWORD>
       mnSelLevel enums: {#Object|#Vertex|#Edge|#Face|#CurrentLevel}
       flags default value: 1
    <bool>unhideAll <enum>mnSelLevel
       mnSelLevel enums: {#Object|#Vertex|#Edge|#Face|#CurrentLevel}
    <void>namedSelCopy <string>Name
    
    ... etc

Was this information helpful?