getClassInstances

The getClassInstances function available in 3ds Max 7 and higher returns an array of all instances of a specified class that exist in a scene.

It was previously available through the Avguard DLX 3rd party MAXScript extension.

Until 3ds Max 2011, the function was looking for the class instances by enumerating the animatable tree. There are many cases where the subAnims of an object are a subset of the references held by an object, so instances present in the scene were being missed.

Starting with 3ds Max 2011, getClassInstances() can search for class instances in a variety of ways depending on its arguments, including the two new ones: processAllAnimatables: and processChildren: .

The syntax is:

getClassInstances <MAXClass> processAllAnimatables:<bool> target:<MAXObject> asTrackViewPick:<bool> processChildren:<bool>

<MAXClass> specifies the class whose instances are being searched for.

processAllAnimatables:

If processAllAnimatables:true is specified in 3ds Max 2011 or higher, all existing objects, even those not present in the scene, are tested to see if they are instances of the specified class. These objects include, for example, objects held only by MAXscript values.

When processAllAnimatables:true is specified, no other keyword parameters are applicable and are ignored.

The default value for this parameter is false .

target:

If target : is specified, only the hierarchy for that target is searched.

If target : is not specified, the entire scene under the scene root is searched. The scene in this case refers not only to the node hierarchy, but also the Material Editor, Track View, and others.

asTrackViewPick:

If asTrackViewPick:true is specified, each use of a class instance is returned as a TrackViewPick value.

If asTrackViewPick:true is specified, the hierarchy that is searched is the Animatable tree under the target. There are lots of cases where the subAnims of an object are a subset of the references held by an object, so class instances present in the scene might be missed. The Animatable tree is the tree shown in TrackView.

If asTrackViewPick:false is specified or not supplied, each class instance is returned, and the hierarchy that is searched is the Reference tree under the target.

The default value for this parameter is false .

processChildren:

If processChildren:true is specified in 3ds Max 2011 or higher, children scene nodes are also searched as part of the Animatable or Reference hierarchy.

The default value for this parameter is false unless no target is specified, the scene root node (rootNode) is specified, or the scene root (rootScene) is specified, in which case the default is true .

EXAMPLE

--Create two spheres, and an instance of one of the spheres:
resetMaxFile #noPrompt
s1 = sphere()
s2 = sphere pos:[100,0,0]
s3 = instance s1
s3.pos = [-100,0,0]

OUTPUT:

OK 
$Sphere:Sphere01 @ [0.000000,0.000000,0.000000] 
$Sphere:Sphere02 @ [100.000000,0.000000,0.000000] 
$Sphere:Sphere03 @ [0.000000,0.000000,0.000000] [-100,0,0] 

EXECUTE:

tvps=getClassInstances sphere asTrackViewPick:true
for tvp in tvps do
(
print tvp.anim
print tvp.client
print tvp.subNum
print tvp.name
print tvp.client[tvp.subNum]
)

OUTPUT:

#(TrackViewPick:"Object (Sphere)", TrackViewPick:"Object (Sphere)", TrackViewPick:"Object (Sphere)")
Sphere
$Sphere:Sphere001 @ [0.000000,0.000000,0.000000]
4
"Object (Sphere)"
SubAnim:Object__Sphere
Sphere
$Sphere:Sphere002 @ [100.000000,0.000000,0.000000]
4
"Object (Sphere)"
SubAnim:Object__Sphere
Sphere
$Sphere:Sphere003 @ [-100.000000,0.000000,0.000000]
4
"Object (Sphere)"
SubAnim:Object__Sphere
OK

NOW EXECUTE:

objs=getClassInstances sphere
for obj in objs do print (refs.dependents obj) #nomap

OUTPUT:

#(Sphere, Sphere)
#($Sphere:Sphere003 @ [-100.000000,0.000000,0.000000], $Sphere:Sphere001 @ [0.000000,0.000000,0.000000], ReferenceTarget:NodeRefMgr)
#($Sphere:Sphere002 @ [100.000000,0.000000,0.000000])
OK

CONCLUSION:

As one of the spheres is instanced, three TrackViewPick values are returned, but only two class instances are returned.

EXPLORING ARGUMENT COMBINATIONS:

t1 = bitmaptex filename:"t1.bmp" name:#Sphere_DiffuseMap
t2 = bitmaptex filename:"t2.bmp" name:#Teapot_DiffuseMap
t3 = bitmaptex filename:"t3.bmp" name:#Displace
t4 = bitmaptex filename:"t4.bmp" name:#VolSelect
t5 = bitmaptex filename:"t5.bmp" name:#HairDens
t6 = bitmaptex filename:"t6.bmp" name:#NoWhere
t7 = bitmaptex filename:"t7.bmp" name:#MEdit
t8 = bitmaptex filename:"t8.bmp" name:#NodeCustAttrib
t9 = bitmaptex filename:"t9.bmp" name:#ObjCustAttrib
s = sphere material:(standard showInViewport:true)
t = teapot material:(standard showInViewport:true) pos:[0,50,0] parent:s
s.material.diffusemap = t1
s.material.specularmap = t1
t.material.diffusemap = mix mask:t2
addModifier s (displace map:t3 strength:10)
addModifier t (volumeSelect texture:t4)
addModifier s (HairMod())
s.modifiers[1].maps[1] = t5
s.modifiers[1].mapEnables[1] = true
meditmaterials[1] = t7
g=geosphere()
testCADef = attributes testCA
(
parameters main
(
map type:#texturemap
)
)
CustAttributes.add g testCADef BaseObject:false
CustAttributes.add g testCADef BaseObject:true
g.testCA.map = t8
g.baseobject.testCA.map = t9

OUTPUT:

Sphere_DiffuseMap:Bitmap
Teapot_DiffuseMap:Bitmap
Displace:Bitmap
VolSelect:Bitmap
HairDens:Bitmap
NoWhere:Bitmap
medit:Bitmap
NodeCustAttrib:Bitmap
ObjCustAttrib:Bitmap
$Sphere:Sphere001 @ [0.000000,0.000000,0.000000]
$Teapot:Teapot001 @ [0.000000,50.000000,0.000000]
Sphere_DiffuseMap:Bitmap
Sphere_DiffuseMap:Bitmap
Mix:Mix
OK
OK
OK
HairDens:Bitmap
true
medit:Bitmap
$GeoSphere:GeoSphere001 @ [0.000000,0.000000,0.000000]
<AttributeDef:testCA>
true
true
NodeCustAttrib:Bitmap
ObjCustAttrib:Bitmap

TEST 1:

for b in getClassInstances bitmaptex do
format "Name : %, Texture name : %, Affected Nodes : %\n" b.name b.filename (refs.dependentNodes b)

TEST 1 OUTPUT

Name : medit, Texture --> Name : t7.bmp , Affected Nodes : #()
Name : Sphere_DiffuseMap, Texture --> Name : t1.bmp, Affected Nodes : #($Object:Sphere001 @ [0.000000,0.000000,0.000000])
Name : Teapot_DiffuseMap, Texture --> Name : t2.bmp, Affected Nodes : #($Editable_Mesh:Teapot001 @ [0.000000,50.000000,0.000000])
Name : VolSelect, Texture --> Name : t4.bmp, Affected Nodes : #($Editable_Mesh:Teapot001 @ [0.000000,50.000000,0.000000])
Name : Displace , Texture --> Name : t3.bmp, Affected Nodes : #($Object:Sphere001 @ [0.000000,0.000000,0.000000])
Name : HairDens, Texture --> Name : t5.bmp, Affected Nodes : #($Object:Sphere001 @ [0.000000,0.000000,0.000000])
Name : ObjCustAttrib, Texture name : t9.bmp, Affected Nodes : #()
Name : NodeCustAttrib, Texture name : t8.bmp, Affected Nodes : #($GeoSphere:GeoSphere001 @ [0.000000,0.000000,0.000000])

TEST 2

for b in getClassInstances bitmaptex target:rootnode do
format "Name : %, Texture name : %, Affected Nodes : %\n" b.name b.filename (refs.dependentNodes b)

TEST 2 OUTPUT

Name : VolSelect, Texture --> Name : t4.bmp, Affected Nodes : #($Editable_Mesh:Teapot001 @ [0.000000,50.000000,0.000000])
Name : Teapot_DiffuseMap, Texture --> Name : t2.bmp, Affected Nodes : #($Editable_Mesh:Teapot001 @ [0.000000,50.000000,0.000000])
Name : Displace, Texture --> Name : t3.bmp, Affected Nodes : #($Object:Sphere001 @ [0.000000,0.000000,0.000000])
Name : HairDens, Texture --> Name : t5.bmp, Affected Nodes : #($Object:Sphere001 @ [0.000000,0.000000,0.000000])
Name : Sphere_DiffuseMap, Texture --> Name : t1.bmp, Affected Nodes : #($Object:Sphere001 @ [0.000000,0.000000,0.000000])
Name : ObjCustAttrib, Texture name : t9.bmp, Affected Nodes : #()
Name : NodeCustAttrib, Texture name : t8.bmp, Affected Nodes : #($GeoSphere:GeoSphere001 @ [0.000000,0.000000,0.000000])

TEST 3

for b in getClassInstances bitmaptex target:s do
format "Name : %, Texture name : %, Affected Nodes : %\n" b.name b.filename (refs.dependentNodes b)

TEST 3 OUTPUT

Name : Displace, Texture --> Name : t3.bmp, Affected Nodes : #($Object:Sphere001 @ [0.000000,0.000000,0.000000])
Name : HairDens, Texture --> Name : t5.bmp, Affected Nodes : #($Object:Sphere001 @ [0.000000,0.000000,0.000000])
Name : Sphere_DiffuseMap, Texture --> Name : t1.bmp, Affected Nodes : #($Object:Sphere001 @ [0.000000,0.000000,0.000000])

TEST 4

for b in getClassInstances bitmaptex target:s processChildren:true do
format "Name : %, Texture name : %, Affected Nodes : %\n" b.name b.filename (refs.dependentNodes b)

TEST 4 OUTPUT

Name : VolSelect, Texture --> Name : t4.bmp, Affected Nodes : #($Editable_Mesh:Teapot001 @ [0.000000,50.000000,0.000000])
Name : Teapot_DiffuseMap, Texture --> Name : t2.bmp, Affected Nodes : #($Editable_Mesh:Teapot001 @ [0.000000,50.000000,0.000000])
Name : Displace, Texture --> Name : t3.bmp, Affected Nodes : #($Object:Sphere001 @ [0.000000,0.000000,0.000000])
Name : HairDens, Texture --> Name : t5.bmp, Affected Nodes : #($Object:Sphere001 @ [0.000000,0.000000,0.000000])
Name : Sphere_DiffuseMap, Texture --> Name : t1.bmp, Affected Nodes : #($Object:Sphere001 @ [0.000000,0.000000,0.000000])

TEST 5

for b in getClassInstances bitmaptex target:g do
format "Name : %, Texture name : %, Affected Nodes : %\n" b.name b.filename (refs.dependentNodes b)

TEST 5 OUTPUT

Name : ObjCustAttrib, Texture name : t9.bmp, Affected Nodes : #()
Name : NodeCustAttrib, Texture name : t8.bmp, Affected Nodes : #($GeoSphere:GeoSphere001 @ [0.000000,0.000000,0.000000])

TEST 6

for b in getClassInstances bitmaptex processAllAnimatables:true do
format "Name : %, Texture name : %, Affected Nodes : %\n" b.name b.filename (refs.dependentNodes b)

TEST 6 OUTPUT

Name : Sphere_DiffuseMap, Texture --> Name : t1.bmp, Affected Nodes : #($Object:Sphere001 @ [0.000000,0.000000,0.000000])
Name : Teapot_DiffuseMap, Texture --> Name : t2.bmp, Affected Nodes : #($Editable_Mesh:Teapot001 @ [0.000000,50.000000,0.000000])
Name : Displace, Texture --> Name : t3.bmp, Affected Nodes : #($Object:Sphere001 @ [0.000000,0.000000,0.000000])
Name : VolSelect, Texture --> Name : t4.bmp, Affected Nodes : #($Editable_Mesh:Teapot001 @ [0.000000,50.000000,0.000000])
Name : HairDens, Texture --> Name : t5.bmp, Affected Nodes : #($Object:Sphere001 @ [0.000000,0.000000,0.000000])
Name : NoWhere, Texture --> Name : t6.bmp, Affected Nodes : #()
Name : medit, Texture --> Name : t7.bmp, Affected Nodes : #()
Name : ObjCustAttrib, Texture name : t9.bmp, Affected Nodes : #()
Name : NodeCustAttrib, Texture name : t8.bmp, Affected Nodes : #($GeoSphere:GeoSphere001 @ [0.000000,0.000000,0.000000])

TEST 7

for b in getClassInstances bitmaptex asTrackViewPick:true do
format "Name : %, Texture name : %, Client: %, subAnim: %, Affected Nodes : %" b.anim.name b.anim.filename b.client b.subnum (refs.dependentNodes b.anim)

TEST 7 OUTPUT

Name : Sphere_DiffuseMap, Texture name : t1.bmp, Client: ReferenceTarget:ReferenceTarget, subAnim: 4 , Affected Nodes : #($Object:Sphere001 @ [0.000000,0.000000,0.000000])
Name : Sphere_DiffuseMap, Texture name : t1.bmp, Client: ReferenceTarget:ReferenceTarget, subAnim: 6 , Affected Nodes : #($Object:Sphere001 @ [0.000000,0.000000,0.000000])
Name : Teapot_DiffuseMap, Texture name : t2.bmp, Client: Mix:Mix, subAnim: 4, Affected Nodes : #($Editable_Mesh:Teapot001 @ [0.000000,50.000000,0.000000])
Name : medit, Texture name : t7.bmp, Client: #meditMaterials(), subAnim: 1, Affected Nodes : #()
Name : Displace, Texture name : t3.bmp, Client: Displace:Displace, subAnim: 3, Affected Nodes : #($Object:Sphere001 @ [0.000000,0.000000,0.000000])

TEST 8

for b in getClassInstances bitmaptex target:s asTrackViewPick:true do
format "Name : %, Texture name : %, Client: %, subAnim: %, Affected Nodes : %\n" b.anim.name b.anim.filename b.client b.subnum (refs.dependentNodes b.anim)

TEST 8 OUTPUT

Name : Displace, Texture name : t3.bmp, Client: Displace:Displace, subAnim: 3 , Affected Nodes : #($Object:Sphere001 @ [0.000000,0.000000,0.000000])
Name : Sphere_DiffuseMap, Texture name : t1.bmp, Client: ReferenceTarget:ReferenceTarget, subAnim: 4 , Affected Nodes : #($Object:Sphere001 @ [0.000000,0.000000,0.000000])
Name : Sphere_DiffuseMap, Texture name : t1.bmp, Client: ReferenceTarget:ReferenceTarget, subAnim: 6 , Affected Nodes : #($Object:Sphere001 @ [0.000000,0.000000,0.000000])

TEST 9

for b in getClassInstances bitmaptex target:s processChildren:true asTrackViewPick:true do
format "Name : %, Texture name : %, Client: %, subAnim: %, Affected Nodes : %\n" b.anim.name b.anim.filename b.client b.subnum (refs.dependentNodes b.anim)

TEST 9 OUTPUT

Name : Displace, Texture name : t3.bmp, Client: Displace:Displace, subAnim: 3, Affected Nodes : #($Object:Sphere001 @ [0.000000,0.000000,0.000000])
Name : Sphere_DiffuseMap, Texture name : t1.bmp, Client: ReferenceTarget:ReferenceTarget, subAnim: 4, Affected Nodes : #($Object:Sphere001 @ [0.000000,0.000000,0.000000])
Name : Sphere_DiffuseMap, Texture name : t1.bmp, Client: ReferenceTarget:ReferenceTarget, subAnim: 6, Affected Nodes : #($Object:Sphere001 @ [0.000000,0.000000,0.000000])
Name : Teapot_DiffuseMap, Texture name : t2.bmp, Client: Mix:Mix, subAnim: 4, Affected Nodes : #($Editable_Mesh:Teapot001 @ [0.000000,50.000000,0.000000])

See Also