Accessing Material Properties

This section covers how the various properties of a material may be retrieved from a node in the scene. These are properties such as color, mapping parameters, bitmaps used, etc.

3ds Max Multi/Sub-Object Material

Next, let's consider access to the properties a multi-material. If the Class_ID returned is MULTI_CLASS_ID then it's a m material. The multi-material is a plugin that uses the MtlID assigned to each face of a mesh as an index into the list of sub-materials. There are methods of the Face class getMatID() and setMatID() to access the MtlID for each face. Additionally, the Mesh class has methods

getFaceMtlIndex(inti)
setFaceMtlIndex(inti, MtlID id).

Note that the meaning of this material index assigned to the face is specific to the type of material. A third party developer could write a material that used the ID in an entirely different manner than 3ds Max does.

For a multi-material, a developer can use the methods of MtlBase:

NumSubMtls()
GetSubMtl(i)
SetSubMtl(i, Mtl* m)

to access the sub materials. Note that some 3ds Max primitive have pre-assigned material ids (such as the Box and the Hedra). Since the object is not really aware of the material, it can happen that the material ID on a face is higher than the total number of sub materials in a material. Developers should look at the number of sub materials on the material, and use a modulo function to bring the material ID of the face down to a legal value before trying to access it.

The following code demonstrates access to material and texture properties. It shows how the ClassIDs are checked for the material and the texture map. It also demonstrates how to access materials properties using the StdMat class and the bitmap properties using the BitmapTex class.

// Test of access to material and texture map properties of a selected node.
// This code determines if the two sided flag is set for the material
// and retrieves the U and V tiling options for the diffuse texture.
// It checks if the material is a 3ds Max Standard material, and if the diffuse
// texture map is a 3ds Max Bitmap texture.
#include "stdmat.h"
void Utility::Test (Interface *ip)
{
   BOOLtwo;
   floatutile, vtile;
   TSTR buf;
 
   // Get the material and texture properties from the node.
   if (ip->GetSelNodeCount() < 1) return;
   INode *node = ip->GetSelNode(0);
 
   // Get the material from the node
   Mtl *m = node->GetMtl();
   if (!m) return; // No material assigned
 
   // See if it's a Standard material
   if (m->ClassID() == Class_ID(DMTL_CLASS_ID, 0))
   {
     // It is -- Access the two sided property of the material
     StdMat* std = (StdMat *)m;
     two = std->GetTwoSided();
 
     // Access the Diffuse map and see if it's a Bitmap texture
     Texmap *tmap = m->GetSubTexmap( ID_DI);
     if (tmap->ClassID() == Class_ID(BMTEX_CLASS_ID, 0))
     {
      // It is -- Access the UV tiling settings at time 0.
       BitmapTex *bmt = (BitmapTex*) tmap;
       StdUVGen *uv = bmt->GetUVGen();
      utile = uv->GetUScl(0);
      vtile = uv->GetVScl(0);
      buf.printf(_T("Two sided=%d, U Tile = %.1f, V Tile = %.1f"),
      two, utile, vtile);
      MessageBox(ip->GetMAXHWnd(), buf, _T("Info..."),
      MB_ICONINFORMATION);
     }
   }
}