3ds Max C++ API Reference
FaceClusterList Class Reference

#include <meshadj.h>

+ Inheritance diagram for FaceClusterList:

Public Member Functions

DllExport FaceClusterList (Mesh *mesh, AdjFaceList &adj, float angle, BOOL useSel=TRUE, const Point3 *faceNormals=nullptr)
 
DllExport FaceClusterList (BitArray &fsel, AdjFaceList &adj)
 
DWORD operator[] (int i)
 
DllExport void MakeVertCluster (Mesh &mesh, Tab< DWORD > &vclust)
 
DllExport void GetNormalsCenters (Mesh &mesh, Tab< Point3 > &norm, Tab< Point3 > &ctr)
 
DllExport void GetBorder (DWORD clustID, AdjFaceList &af, Tab< DWORD > &cbord)
 
DllExport void GetOutlineVectors (Mesh &m, AdjFaceList &af, Tab< Point3 > &cnorms, Tab< Point3 > &odir)
 

Public Attributes

DWORDTab clust
 
DWORD count
 

Additional Inherited Members

- Static Public Member Functions inherited from MaxHeapOperators
static UtilExport voidoperator new (size_t size)
 Standard new operator used to allocate objects If there is insufficient memory, an exception will be thrown. More...
 
static UtilExport voidoperator new (size_t size, const std::nothrow_t &e)
 Standard new operator used to allocate objects if there is insufficient memory, NULL will be returned. More...
 
static UtilExport voidoperator new (size_t size, const char *filename, int line)
 New operator used to allocate objects that takes the filename and line number where the new was called If there is insufficient memory, an exception will be thrown. More...
 
static UtilExport voidoperator new (size_t size, int block_type, const char *filename, int line)
 New operator used to allocate objects that takes the type of memory, filename and line number where the new was called If there is insufficient memory, an exception will be thrown. More...
 
static UtilExport voidoperator new (size_t size, const std::nothrow_t &e, const char *filename, int line)
 New operator used to allocate objects that takes the filename and line number where the new was called If there is insufficient memory, NULL will be returned. More...
 
static UtilExport voidoperator new (size_t size, unsigned long flags)
 New operator used to allocate objects that takes extra flags to specify special operations If there is insufficient memory, an exception will be thrown. More...
 
static UtilExport voidoperator new (size_t size, const std::nothrow_t &e, unsigned long flags)
 New operator used to allocate objects that takes extra flags to specify special operations If there is insufficient memory, NULL will be returned. More...
 
static UtilExport voidoperator new[] (size_t size)
 New operator used to allocate arrays of objects If there is insufficient memory, an exception will be thrown. More...
 
static UtilExport voidoperator new[] (size_t size, const std::nothrow_t &e)
 New operator used to allocate arrays of objects If there is insufficient memory, NULL will be returned. More...
 
static UtilExport voidoperator new[] (size_t size, const char *filename, int line)
 New operator used to allocate arrays of objects If there is insufficient memory, an exception will be thrown. More...
 
static UtilExport voidoperator new[] (size_t size, int block_type, const char *filename, int line)
 New operator used to allocate arrays of objects. More...
 
static UtilExport voidoperator new[] (size_t size, const std::nothrow_t &e, const char *filename, int line)
 New operator used to allocate arrays of objects If there is insufficient memory, NULL will be returned. More...
 
static UtilExport voidoperator new[] (size_t size, unsigned long flags)
 New operator used to allocate arrays of objects If there is insufficient memory, an exception will be thrown. More...
 
static UtilExport voidoperator new[] (size_t size, const std::nothrow_t &e, unsigned long flags)
 New operator used to allocate arrays of objects If there is insufficient memory, NULL will be returned. More...
 
static UtilExport void operator delete (void *ptr)
 Standard delete operator used to deallocate an object If the pointer is invalid, an exception will be thrown. More...
 
static UtilExport void operator delete (void *ptr, const std::nothrow_t &e)
 Standard delete operator used to deallocate an object If the pointer is invalid, nothing will happen. More...
 
static UtilExport void operator delete (void *ptr, const char *filename, int line)
 Delete operator used to deallocate an object that takes the filename and line number where the delete was called If the pointer is invalid, an exception will be thrown. More...
 
static UtilExport void operator delete (void *ptr, int block_type, const char *filename, int line)
 Delete operator used to deallocate an object that takes the type of memory, filename and line number where the delete was called If the pointer is invalid, an exception will be thrown. More...
 
static UtilExport void operator delete (void *ptr, const std::nothrow_t &e, const char *filename, int line)
 Delete operator used to deallocate an object that takes the filename and line number where the delete was called If the pointer is invalid, nothing will happen. More...
 
static UtilExport void operator delete (void *ptr, unsigned long flags)
 Delete operator used to deallocate an object that takes extra flags to specify special operations If the pointer is invalid, an exception will be thrown. More...
 
static UtilExport void operator delete (void *ptr, const std::nothrow_t &e, unsigned long flags)
 Delete operator used to deallocate an object that takes extra flags to specify special operations If the pointer is invalid, nothing will happen. More...
 
static UtilExport void operator delete[] (void *ptr)
 Standard delete operator used to deallocate an array of objects If the pointer is invalid, an exception will be thrown. More...
 
static UtilExport void operator delete[] (void *ptr, const std::nothrow_t &e)
 Standard delete operator used to deallocate an array of objects If the pointer is invalid, nothing will happen. More...
 
static UtilExport void operator delete[] (void *ptr, const char *filename, int line)
 Delete operator used to deallocate an array of objects that takes the filename and line number where the delete was called If the pointer is invalid, an exception will be thrown. More...
 
static UtilExport void operator delete[] (void *ptr, int block_type, const char *filename, int line)
 Delete operator used to deallocate an array of objects that takes the type of memory, filename and line number where the delete was called If the pointer is invalid, an exception will be thrown. More...
 
static UtilExport void operator delete[] (void *ptr, const std::nothrow_t &e, const char *filename, int line)
 Delete operator used to deallocate an array of objects that takes the filename and line number where the delete was called If the pointer is invalid, nothing will happen. More...
 
static UtilExport void operator delete[] (void *ptr, unsigned long flags)
 Delete operator used to deallocate an array of objects that takes extra flags to specify special operations If the pointer is invalid, an exception will be thrown. More...
 
static UtilExport void operator delete[] (void *ptr, const std::nothrow_t &e, unsigned long flags)
 Delete operator used to deallocate an array of objects that takes extra flags to specify special operations If the pointer is invalid, an exception will be thrown. More...
 
static UtilExport voidoperator new (size_t size, void *placement_ptr)
 Placement new operator. More...
 
static UtilExport void operator delete (void *ptr, void *placement_ptr)
 Placement delete operator. More...
 
static UtilExport voidaligned_malloc (size_t size, size_t alignment)
 Allocates memory on a specified alignment boundary. More...
 
static UtilExport voidaligned_realloc (void *ptr, size_t size, size_t alignment)
 Reallocates memory on a specified alignment boundary. More...
 
static UtilExport void aligned_free (void *ptr)
 Frees a block of memory that was allocated with aligned_malloc/aligned_realloc. More...
 

Detailed Description

See also
Class AdjFaceList, Class BitArray.

Description:
This is a list of face "clusters" for a given mesh. A typical application would be in Edit(able) Mesh, where the user has selected two separate groups of faces on different parts of the mesh and wants to extrude them both, or rotate both around their local centers. Each "cluster" is a contiguous group of selected faces. Like AdjEdgeLists and AdjFaceLists, this class is only defined in relation to some mesh.

This class may be used to group faces together based on the angle between their normals or by their selection status.

All methods of this class are implemented by the system. Note that the functionality provided by this class is not available in the 1.0 release of the SDK. Later releases (1.1, 1.2, etc) do support it.
Data Members:
DWORDTab clust;

The cluster number (id), one for each face. Non-selected faces have UNDEFINED for their id.

The cluster IDs of all the faces – this table has size mesh::numFaces. clust[i] is UNDEFINED if face i is not in any cluster (ie is unselected).

DWORD count;

The number of clusters.

Constructor & Destructor Documentation

◆ FaceClusterList() [1/2]

DllExport FaceClusterList ( Mesh mesh,
AdjFaceList adj,
float  angle,
BOOL  useSel = TRUE,
const Point3 faceNormals = nullptr 
)
Remarks
Constructor. This version separates clusters using a minimum angle and optionally the selection set. A developer creates one of these cluster lists by specifying the mesh, the face list and an angle. What is built is a cluster number for each face identifying what cluster it is in.

For example, if you create one of these for a sphere and set the angle threshold to 90 degrees, you would get back one cluster, and the cluster id for everything would be 0. If you ran it on a box, and you set the angle to < 90 degrees, you would get back 6 ids. Two faces in the box would have id 0, two would have id 1, etc.
Parameters:
Mesh *mesh

The mesh to create the list for.

AdjFaceList& adj

The face list for this mesh.

float angle

The maximum angle (in radians) that can be used in joining adjacent faces into the same cluster.

BOOL useSel

If FALSE, selection is ignored and all faces are grouped into clusters by angle. If TRUE, only selected faces are grouped into clusters, but angle is still relevant. Non-selected faces will have UNDEFINED for their id.

const Point3* faceNormals

Optional optimization parameter to pass in a precomputed face normal list.

◆ FaceClusterList() [2/2]

DllExport FaceClusterList ( BitArray fsel,
AdjFaceList adj 
)
Remarks
Constructor. This version separates clusters using the selection set. In this case a cluster is defined as a set of faces that are selected and are adjacent. For example you could have a sphere with some faces selected on one side, and another group of faces selected on the other side. Each group of adjacent and selected faces would comprise clusters within the mesh. This is used for example by the axis tripods in 3ds Max where each selected group of faces gets their own coordinate system.

In this case the unselected faces will not be in any cluster. These store the value UNDEFINED for their id.
Parameters:
BitArray& fsel

This bit array defines the face selected state that the clusters will be grouped by. Each bit in the bit array corresponds to the parallel index in the mesh face table.

AdjFaceList& adj

The face list for this mesh.

Member Function Documentation

◆ operator[]()

DWORD operator[] ( int  i)
inline
Remarks
Access operator. Returns the cluster ID for face i.
379 { return clust[i]; }
DWORDTab clust
Definition: meshadj.h:328

◆ MakeVertCluster()

DllExport void MakeVertCluster ( Mesh mesh,
Tab< DWORD > &  vclust 
)
Remarks
Creates a list of cluster IDs for vertices.
Parameters:
Mesh &mesh

The mesh associated with this FaceClusterList.

Tab<DWORD> &vclust

This is where the output goes: vclust is set to size mesh.numVerts, and the value of each entry in this table tells which cluster the vertex has been assigned to, based on the faces it's on. If vertex "v" is not in any clusters (ie none of the faces that use it are in any clusters), vclust[v] is UNDEFINED.

In cases where a vertex is in two clusters, the larger face index is dominant. (In other words, if a vertex 6 is on faces 2 and 7, which are in two separate clusters, and face 9, which isn't in any cluster, it gets its cluster ID from face 7. This can happen if two selection regions touch at a vertex instead of along an edge.)

◆ GetNormalsCenters()

DllExport void GetNormalsCenters ( Mesh mesh,
Tab< Point3 > &  norm,
Tab< Point3 > &  ctr 
)
Remarks
Computes average normals and centers for all face clusters. Within a cluster, normals are weighted by the area of the face – a face twice as big contributes twice as much to the cluster normal. (Mathematically, we just total up the non-normalized cross-products of each face, which are equivalent to 2*(area)*(face normal). Then we normalize the cluster total.) Face centers are directly averaged, without weighting.
Parameters:
Mesh &mesh

The mesh associated with this FaceClusterList.

Tab<Point3> &norm

The average normal table to store the results in. This is set to size FaceClusterList::count, the number of clusters.

Tab<Point3> &ctr

The average center table to store the results in. This is set to size FaceClusterList::count, the number of clusters.

◆ GetBorder()

DllExport void GetBorder ( DWORD  clustID,
AdjFaceList af,
Tab< DWORD > &  cbord 
)
Remarks
Each face cluster is a set of faces connected by shared edges. This method finds a cluster's boundary, which can be expressed as a sequence of edges on faces in the cluster (where the other side of each edge has no face or has a face not in this cluster). If there is more than one boundary, as for instance in the faces that make up the letter "o" in a ShapeMerge with Text, both boundaries are returned in no particular order.
Parameters:
DWORD clustID

The cluster to get the border of.

AdjFaceList &af

The adjacent face list associated with this FaceClusterList.

Tab<DWORD> &cbord

The table where the output goes. If there are no borders (as for instance in a sphere with all faces selected), it remains empty. Otherwise, this is filled with a series of edge indices, then an UNDEFINED to mark the end of each border. So for instance if this cluster represents the front face of a default box, cbord will contain 4 edge indices and an UNDEFINED. If the cluster represents all the side faces of a cylinder, but not the top or bottom, there are two borders: on 24-sided cylinder, you'd get the 24 edge indices representing the bottom lip of the cylinder, then an UNDEFINED, then the 24 edge indices representing the top lip, followed by another UNDEFINED. (As elsewhere, edges are indexed by face*3+eid, where face is the face (in the cluster) the edge is on, and eid is the index of the edge on that face.)

◆ GetOutlineVectors()

DllExport void GetOutlineVectors ( Mesh m,
AdjFaceList af,
Tab< Point3 > &  cnorms,
Tab< Point3 > &  odir 
)
Remarks
This creates "outline" directions for the vertices on the edge of the clusters. These are used in Edit(able) Mesh's new "Bevel" operation (when you Bevel by "Group"). These vectors, which are all perpendicular to the cluster normals, point in the direction and speed vertices must travel in order to move the edges out at a consistent rate without changing the shape of the outline of the cluster.

To see how this works, create a Prism in 3ds Max ("Extended Primitives") with dimensions like 20 x 40 x 40 x 40, and apply an Edit Mesh. Select all the faces on the top of the prism, and spin the Bevel spinner up and down. Notice that the vertex at the sharpest point moves faster than the other 2, but that the edges all remain parallel to their original positions. The essence of Outlining is that the edges move at a constant rate, and the vertices move faster or slower to make this happen. (This strategy is also used in the Bevel and Path Bevel modifiers.)
Parameters:
Mesh & m

The mesh associated with this FaceClusterList

AdjFaceList &af

The adjacent face list associated with this FaceClusterList

Tab<Point3> &cnorms

The cluster normals, as computed by GetNormalsCenters

Tab<Point3> &odir

A table to put the outline direction result in. This is set to size mesh.numVerts. Entries for vertices that are not on a cluster border are all (0,0,0). Entries for cluster border vertices are scaled, such that if you move all vertices the specified amount, each cluster's border edges will move by one 3ds Max unit.
Operators:

Member Data Documentation

◆ clust

DWORDTab clust

◆ count

DWORD count