Public Member Functions | Public Attributes

FaceClusterList Class Reference

This reference page is linked to from the following overview topics: Mesh Related Classes.


Search for all occurrences

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.

#include <meshadj.h>

Inheritance diagram for FaceClusterList:
Inheritance graph
[legend]

List of all members.

Public Member Functions

DllExport  FaceClusterList (Mesh *mesh, AdjFaceList &adj, float angle, BOOL useSel=TRUE)
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

Constructor & Destructor Documentation

DllExport FaceClusterList ( Mesh mesh,
AdjFaceList adj,
float  angle,
BOOL  useSel = TRUE 
)
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.
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

DWORD operator[] ( int  i ) [inline]
Remarks:
Access operator. Returns the cluster ID for face i.
{ return clust[i]; }
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.)
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.
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.)
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

DWORD count

FaceClusterList FaceClusterList FaceClusterList FaceClusterList FaceClusterList FaceClusterList FaceClusterList FaceClusterList FaceClusterList FaceClusterList
FaceClusterList FaceClusterList FaceClusterList FaceClusterList FaceClusterList FaceClusterList FaceClusterList FaceClusterList FaceClusterList FaceClusterList