Class EdgeClusterList

3DS Max Plug-In SDK

Class EdgeClusterList

See Also: Class Mesh.

class EdgeClusterList

Description:

This class is available in release 3.0 and later only.

This is a list of edge "clusters" for a given mesh. A typical application would be in Edit(able) Mesh, where the user has selected a two separate groups of edges 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 edges. Like AdjEdgeLists and AdjFaceLists, this class is only defined in relation to some mesh.

Note: for construction of this list, an edge is considered selected on both sides if it's selected on either. If you select the diagonal on top of a box, you probably only selected one of (face 2, edge 2 = 8) or (face 3, edge 2 = 11). But edges 8 and 11 will both be in the same cluster.

Data Members:

public:

DWORDTab clust;

The cluster IDs of all the edges -- this table has size mesh::numFaces*3. clust[i] is UNDEFINED if edge i is not in any cluster (ie is totally unselected).

DWORD count;

The number of clusters.

Methods:

public:

Prototype:

EdgeClusterList(Mesh &mesh,BitArray &esel,AdjEdgeList &adj);

Remarks:

Constructor.

Creates an edge cluster list from the current selection. All adjacent selected edges are grouped into the same cluster.

Parameters:

Mesh &mesh

The mesh associated with this EdgeClusterList.

BitArray &esel

The bit array containing the edge selection data for the mesh.

AdjEdgeList &adj

The adjacent edge list for the mesh.

Prototype:

DWORD ID(int f, int e) {return clust[f*3+e];};

Remarks:

Returns the cluster ID for face f, edge e.

Parameters:

int f

The index of the face in the mesh.

int e

The index of the edge in the mesh.

Prototype:

void MakeVertCluster(Mesh &mesh, Tab<DWORD> &vclust);

Remarks:

Creates a list of cluster IDs for vertices.

Parameters:

Mesh &mesh

The mesh associated with this EdgeClusterList.

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 edges it's on. If vertex "v" is not in any clusters (ie none of the edges that use it are in any clusters), vclust[v] is UNDEFINED.

Prototype:

void GetNormalsCenters(Mesh &mesh, Tab<Point3> & norm, Tab<Point3> & ctr);

Remarks:

This method extracts normal and center information for the various clusters of the mesh.

Parameters:

Mesh &mesh

The mesh to evaluate.

Tab<Point3> & norm

This table has its sizes set to the number of clusters in the cluster list. Normals are computed as the normalized average of the area-normal vectors of all faces in the cluster.

Tab<Point3> & ctr

This table has its sizes set to the number of clusters in the cluster list. Centers are the average location of the face centers or edge centers -- thus a point on three faces or edges in the same cluster has more weight than a point on one face in the cluster.

Prototype:

DWORD operator[](int i);

Remarks:

Access operator. Returns the cluster ID for edge i (indexed as 3*face+edge).

The following functions are not part of a class but are available for use:

Function:

float AffectRegionFunction(float dist, float falloff, float pinch, float bubble);

Remarks:

This function is available in release 3.0 and later only.

This is the standard affect region function, based on a distance and the three affect region parameters (same as the editable mesh).

This function is a cubic curve which returns 1 at distance 0, 0 if distance is greater than falloff, and other values for distance between 0 and falloff. To "see" this function graphed, look at the curve in the Soft Selection parameters in Edit Mesh, Editable Mesh, Mesh Select, or Volume Select. This function currently is constructed as follows:

 float u = ((falloff - dist)/falloff);

 float u2 = u*u, s = 1.0f-u;

 return (3*u*bubble*s + 3*u2*(1.0f-pinch))*s + u*u2;"

Parameters:

float dist

The distance to the selection. The method for computing this distance is up to the developer; for example in Mesh Select, it's the distance to the nearest selected vertex, while in Volume Select (with a box or sphere selection region) it's the distance to the selection volume.

float falloff

The limit distance of the effect. If distance > falloff, the function will always return 0.

float pinch

Use this to affect the tangency of the curve near distance=0. Positive values produce a pointed tip, with a negative slope at 0, while negative values produce a dimple, with positive slope.

float bubble

Use this to change the curvature of the function. A value of 1.0 produces a half-dome. As you reduce this value, the sides of the dome slope more steeply. Negative values lower the base of the curve below 0.

Return Value:

Returns the strength of the Affect Region function at the given distance. (In selection modifiers, this is the "soft selection" amount, the amount it's considered selected. A vertex at a distance with a return value of .25, for instance, will be affected 1/4 as strongly in a deformation as a fully selected vertex.)

Function:

void MatrixFromNormal(Point3& normal, Matrix3& mat);

Remarks:

This function is available in release 3.0 and later only.

This function creates a matrix with the normal as a Z-axis. The X and Y axes are chosen arbitrarily.

Parameters:

Point3& normal

The input normal is specified here.

Matrix3& mat

The output matrix.

Function:

void AverageVertexNormals(Mesh & mesh, Tab<Point3> & vnormals);

Remarks:

This function is available in release 3.0 and later only.

This function creates vertex normals that are weighted averages of faces using each vertexSmoothing groups are not used in these computations -- the normals are those you would expect with a totally smooth mesh.

Parameters:

Mesh & mesh

The mesh whose average vertex normals are computed.

Tab<Point3> & vnormals

The output vertex normals. . This will be set to size mesh.numVerts.

Function:

Point3 AverageSelVertNormal(Mesh& mesh);

Remarks:

This function is available in release 3.0 and later only.

This function computes and returns the average normal of a group of selected vertices.

Parameters:

Mesh& mesh

The mesh to check. The function uses mesh.vertSel to check for selected verts.

Function:

Point3 AverageSelVertCenter(Mesh& mesh);

Remarks:

This function is available in release 3.0 and later only.

This function computes and returns the average center of a group of selected vertices.

Parameters:

Mesh& mesh

The mesh to check. The function uses mesh.vertSel to check for selected verts.

Function:

void DeselectHiddenFaces(Mesh &mesh);

Remarks:

This function is available in release 3.0 and later only.

Removes hidden faces from the mesh.faceSel selection array.

Parameters:

Mesh& mesh

The mesh to check.

Function:

void DeselectHiddenEdges(Mesh &mesh);

Remarks:

This function is available in release 3.0 and later only.

This function removes edges on hidden faces from the mesh.edgeSel selection array.

Parameters:

Mesh& mesh

The mesh to check.

Function:

void HiddenFacesToVerts(Mesh &mesh, BitArray &alsoHide);

Remarks:

This function is available in release 3.0 and later only.

This function hides vertices that are only used by hidden faces. If alsoHide has size mesh.numVerts, it is used to indicate other vertices that should also be hidden. Note that passing mesh.vertHide as alsoHide will NOT WORK, as mesh.vertHide is overwritten before alsoHide is read.

Parameters:

Mesh &mesh

The mesh to check.

BitArray &alsoHide

If specified, this is used to indicates other vertices that should also be hidden.

Function:

void SelectionDistance(Mesh & mesh, float *selDist);

Remarks:

This function is available in release 3.0 and later only.

This function computes distances from selected vertices (as indicated by mesh.VertexTempSel()) to non-selected ones.

NOTE: This is an order-of-n-squared algorithm. Each unselected vert is compared with each selected vert. So, if you have a mesh with 1000 sel verts and 1000 unsel verts, this involves a million compares.

Parameters:

Mesh & mesh

The mesh to check.

float *selDist

This is assumed to be a float array of size mesh.numVerts. It is set to -1 for all verts if there is no selection. Otherwise, selected vertices have a value of 0, and nonselected vertices have the distance to the nearest selected vertex.

Function:

void SelectionDistance(Mesh & mesh, float *selDist, int iters, AdjEdgeList *ae=NULL);

Remarks:

This function is available in release 3.0 and later only.

This function computes distances from selected vertices (as indicated by mesh.VertexTempSel()) to non-selected ones along edge paths. selDist is assumed to be a float array of size mesh.numVerts. selDist is set to -1 for all verts if there is no selection. Otherwise, selected vertices have selDist value 0; non-selected vertices that are "iters" or fewer edges away from a selected vertex are assigned the shortest edge-path distance to a selected vertex; and non-selected vertices that are more than iters edges away are set to -1. The AdjEdgeList is computed by the algorithm if the one passed is NULL; otherwise you can save time by passing a cached one in.

This is NOT an n-squared algorithm like the one above. It's more a sort of order-of-n-times-(iters-squared).

Parameters:

Mesh & mesh

The mesh to check.

float *selDist

An array of floats of size mesh.numVerts.

int iters

If 0, Selection Distance is computed from each vertex to the nearest selected vertex, regardless of topology. This is a VERY EXPENSIVE ALGORITHM, which takes almost 4 times as long for twice as many vertices. If iters is non-zero, it represents the number of edges one should "travel" in trying to find the nearest selected vertex -- this means that it only takes twice as long for twice as many verts. (This is like the Edge Distance parameter in EMesh's Soft Selection dialog.) If iters is 0, ae is irrelevant and may be left as NULL. If iters is nonzero, an Adjacent Edge List is required, and will be computed internally from the mesh if ae is NULL. (If you've got an AdjEdgeList for this mesh handy, pass it in, otherwise don't worry about it.)

Note also that if iters is nonzero, the distance is computed along the edges, not directly through space. If there is no selected vertex within an iters-length path, a vertex is assigned a 0 selection value.

AdjEdgeList *ae=NULL

The optional adjacent edge list.

Function:

void ClustDistances(Mesh & mesh, DWORD numClusts, DWORD *vclust, Tab<float> **clustDist);

Remarks:

This function is available in release 3.0 and later only.

Computes distances from nonselected vertices in the mesh to each of the vertex clusters. This is a VERY EXPENSIVE ALGORITHM, which takes almost 4 times as long for twice as many vertices.

Preparation for this method would typically look like:

// given Mesh msh, FaceClusterList fclust:

Tab<DWORD> vclust;

fclust.MakeVertCluster (msh, vclust);

Tab<float> ** clustDist;

clustDist = new (Tab<float> *)[fclust.count];

for (int i=0; i<fclust.count; i++) clustDist[i] = new Tab<float>;

ClustDistances (mesh, fclust.count, vclust.Addr(0), clustDist);

Then (*clustDist[c])[v] would give the distance from vertex v in the mesh to the vertices of cluster c.

Parameters:

Mesh &mesh

The mesh the clusters are based on.

DWORD numClusts

The number of clusters in this mesh.

DWORD *vclust

A pointer to an array of vertex cluster IDs. Typically this is a pointer to the data in the table created by EdgeClusterList::GetVertClusters or FaceClusterList::GetVertClusters.

Tab<float> **clustDist

This is an array of <numClusts> pointers to tables that will be used to store distances from various clusters. Each table will be set to the ize of mesh.numVerts and filled with distances to the cluster that table represents.

Function:

void ClustDistances(Mesh & mesh, DWORD numClusts, DWORD *vclust, Tab<float> **clustDist, int iters, AdjEdgeList *ae=NULL);

Remarks:

This function is available in release 3.0 and later only.

Computes distances from nonselected vertices in the mesh to each of the vertex clusters. Unlike the other version which doesn't have an iters or ae parameter, this is a linear algorithm which computes distance along a finite number of edges.

Preparation for this method would typically look like:

// given Mesh msh, FaceClusterList fclust:

Tab<DWORD> vclust;

fclust.MakeVertCluster (msh, vclust);

Tab<float> ** clustDist;

clustDist = new (Tab<float> *)[fclust.count];

for (int i=0; i<fclust.count; i++) clustDist[i] = new Tab<float>;

ClustDistances(mesh, fclust.count, vclust.Addr(0), clustDist);

Then (*clustDist[c])[v] would give the distance from vertex v in the mesh to the vertices of cluster c.

Parameters: 

Mesh & mesh

The mesh the clusters are based on.

DWORD numClusts

The number of clusters in this mesh.

DWORD *vclust

A pointer to an array of vertex cluster IDs. Typically this is a pointer to the data in the table created by EdgeClusterList::GetVertClusters or FaceClusterList::GetVertClusters.

Tab<float> **clustDist

This is an array of <numClusts> pointers to tables that will be used to store distances from various clusters. Each table will be set to the ize of mesh.numVerts and filled with distances to the cluster that table represents.

int iters

The maximum number of edges to travel along looking for a vertex in the given cluster.

AdjEdgeList *ae=NULL

Edge length computations require an adjacent edge list. If you don't pass one in this parameter, it'll have to construct its own from the mesh.