Class MNTempData

3DS Max Plug-In SDK

Class MNTempData

See Also: Class BaseInterfaceServer, Class MNMesh, Class MNFaceClusters, Class MNEdgeClusters , Class MNFaceElement, Class MNChamferData

class MNTempData : public BaseInterfaceServer

Description:

This class is available in release 4.0 and later only.

This is a class for caching face and edge clusters, vertex normals, and other derived data about an MNMesh. There is a SetMesh() method to set the current mesh that the TempData is based on, then there's a series of methods to update the cache and return some sort of derived data. All of these methods follow the form:

 

DerivedData *MNTempData::DData(parameters);

 

DerivedData is the container for the derived data requested (often a simple table, though there are some specialized classes returned from some methods). If the data has already been computed, the parameters are ignored and the cached data is returned. Otherwise, the data is computed from the parameters and the

current mesh.

There are no procedures in place to detect changes in parameters or the mesh since the last time a method was called, so it's the calling routine's responsibility to free invalid structures. If you know that only certain pipeline channels, such as GEOM_CHANNEL, have changed, you can use the Invalidate(DWORD partsChanged) method. (GEOM_CHANNEL would free the distances-to-selected-vertices, for example, but not the Edge Clusters.)

In particular, there is no way for the MNTempData to know when its mesh pointer is no longer valid, so it's vital that the calling routine clear the mesh (with SetMesh(NULL)) or stop using the MNTempData when this happens.

All data members are private. They basically consist of a series of pointers which are initialized to NULL and then filled with allocated derived data as requested. There is also a NULL-initialized, private mesh pointer which is set with SetMesh(). Editable Poly uses this class to hold all the varieties of temporary, cached data it creates -- examples are vertex normals and face clusters.

To use MNTempData, just set it to your mesh and start asking for stuff:

 

MyAlgorithm (MNMesh *m) {

MNTempData mtd(m);

// Get Edge Clusters.

MNEdgeClusters *eclust = mtd.EdgeClusters ();

}

Methods:

public:

Prototype:

MNTempData ();

Remarks:

Constructor. Sets all data members to NULL.

Prototype:

MNTempData (MNMesh *m);

Remarks:

Constructor. Sets the internal mesh pointer to the mesh passed. (Sets all other data members to NULL.)

Parameters:

MNMesh *m

The internal mesh pointer to set.

Prototype:

~MNTempData ();

Remarks:

Destructor.

Prototype:

void SetMesh (MNMesh *m);

Remarks:

Sets the internal mesh pointer to m.

Parameters:

MNMesh *m

The internal mesh pointer to set.

Default Implementation:

{ mesh = m; }

Prototype:

MNFaceClusters *FaceClusters (DWORD clusterFlags=MN_SEL);

Remarks:

This method returns a face cluster list, which groups selected faces into "clusters" for transformation. See Class MNFaceClusters for more information. If cached, the cache is returned. Otherwise a cache is allocated and computed from the current mesh.

Parameters:

DWORD clusterFlags=MN_SEL

The face flags to cluster the faces by. For instance, with the default value, faces are clustered by their selection.

Prototype:

MNEdgeClusters *EdgeClusters (DWORD clusterFlags=MN_SEL);

Remarks:

Returns an edge cluster list, which groups selected edges into "clusters" for applying transforms. See Class MNEdgeClusters for more information. If cached, the cache is returned. Otherwise a cache is allocated and computed from the current mesh.

Parameters:

DWORD clusterFlags=MN_SEL

The edge flags to cluster the edges by. For instance, with the default value, edges are clustered by their selection.

Prototype:

Tab<int> *VertexClusters (int sl, DWORD clusterFlags=MN_SEL);

Remarks:

This method returns an index of which cluster, if any, each vertex is in. If cached, the cache is returned. Otherwise a cache is allocated and computed from the current mesh and the parameter.

Parameters:

int sl

The selection level. This should be either MNM_SL_EDGE or MNM_SL_FACE, to indicate whether the vertex cluster information should be based on edge or face clusters. Note that this parameter is ignored if there's already a vertex cluster cache.

DWORD clusterFlags=MN_SEL

The edge or face flags to cluster the edges or faces by. For instance, with the default value, edges or faces are clustered by their selection. Note that this parameter is ignored if there's already a vertex cluster cache.

Return Value:

A table of DWORD's is returned, one for each vertex. If (VertexClusters(sl))[i] is UNDEFINED, vertex i is not in any cluster. Otherwise, the value for vertex i is the cluster index.

Prototype:

Tab<Point3> *ClusterNormals (int sl, DWORD clusterFlags=MN_SEL);

Remarks:

This method returns average normals for each cluster. If cached, the cache is returned. Otherwise a cache is allocated and computed from the current mesh and the parameter. Note that cluster centers and normals are computed and cached at the same time, when you call either method.

Parameters:

int sl

The selection level. This should be either MNM_SL_EDGE or MNM_SL_FACE, to indicate whether the vertex cluster information should be based on edge or face clusters. Note that this parameter is ignored if there's already a cluster normal cache.

DWORD clusterFlags=MN_SEL

The edge or face flags to cluster the edges or faces by. For instance, with the default value, edges or faces are clustered by their selection. Note that this parameter is ignored if there's already a cluster normal cache.

Return Value:

A table of Point3's is returned, one for each cluster. The values are already normalized to length 1.

Prototype:

Tab<Point3> *ClusterCenters (int sl, DWORD clusterFlags=MN_SEL);

Remarks:

This method returns mean centers for each cluster. If cached, the cache is returned. Otherwise a cache is allocated and computed from the current mesh and the parameter. Note that cluster centers and normals are computed and cached at the same time, when you call either method.

Parameters:

int sl

Selection level. This should be either MNM_SL_EDGE or MNM_SL_FACE, to indicate whether the clusters we're talking about are the edge or face clusters. Note that this parameter is ignored if there's already a cluster center cache.

DWORD clusterFlags=MN_SEL

The edge or face flags to cluster the edges or faces by. For instance, with the default value, edges or faces are clustered by their selection. Note that this parameter is ignored if there's already a cluster center cache.

Return Value:

A table of Point3's is returned, one for each cluster.

Prototype:

Matrix3 ClusterTM (int clust);

Remarks:

This method uses the current cluster center and normal caches to return the "objectspace to clusterspace" transform. This is the tranform of the "local" axis in moving edge or face clusters in Editable Poly. If the cluster centers and normals have not been cached, the identity matrix is returned; thus the control over whether this is an edge or face cluster is handled by the last call to ClusterCenters or ClusterNormals.

Parameters:

int clust

The cluster you want the transform for.

Prototype:

Tab<Point3> *VertexNormals ();

Remarks:

This method returns a table of local average normals for vertices. These normals are computed using the MNMesh::GetVertexNormal() method, wherein each face's contribution to the vertex normal is weighted by the face angle at the vertex.

Prototype:

Tab<float> *VSWeight (BOOL useEdgeDist, int edgeIts, BOOL ignoreBack, float falloff, float pinch, float bubble, DWORD selFlags=MN_SEL);

Remarks:

This method returns Vertex Selection weights (for soft selection). If cached, the cache is returned. Otherwise a cache is allocated and computed from the current mesh and the parameters. Weights are based on the standard soft selection falloff from the currently selected vertices.

Note: If useEdgeDist is FALSE, this is an n-log-n algorithm: it compares every vertex not in the cluster with every vertex in it. If useEdgeDist is TRUE, the time it takes is proportional to the number of verts in the cluster times edgeIts.

Parameters:

BOOL useEdgeDist

If set to TRUE, the distance between vertices is computed along edges. If set to FALSE, it's computed directly through space.

int edgeIts

This indicates the maximum number of edges the algorithm may travel along in finding the distance between vertices. (Maximum path length.)

BOOL ignoreBack

If set to TRUE, vertices with a normal (as computed in VertexNormals) that points more than 90 degrees away from the average normal of the selection are not given any partial selections. They're either 1 if selected or 0 otherwise.

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.

DWORD selFlags=MN_SEL

Indicates what flag defines the hard selection we're basing this soft selection on.

Return Value:

A table of float values, one per vertex, that are 1.0 if the vertex is in the current selection, 0.0 if it's more than falloff distance (or more than edgeIts edges, if (useEdgeDist)), and AffectRegionFunction((*SelectionDist(useEdgeDist, edgeIts)), falloff, pinch, bubble) otherwise.

Prototype:

Tab<float> *SelectionDist (BOOL useEdgeDist, int edgeIts, DWORD selFlags=MN_SEL);

Remarks:

This method computes the current distance of each vertex from the current selection. If cached, the cache is returned. Otherwise a cache is allocated and computed from the current mesh and the parameters. The term "Selected verts" below refers to the vertices that are selected in the mesh's current selection level. See the Mesh method GetTempSel() for details.

NOTE: If useEdgeDist is FALSE, this is an n-log-n algorithm: it compares every nonselected vertex with every selected one. If useEdgeDist is TRUE, the time it takes is proportional to the number of selected vertices times edgeIts.

Parameters:

BOOL useEdgeDist

If set to TRUE, the distance between vertices is computed along edges. If set to FALSE, it's computed directly through space.

int edgeIts

This indicates the maximum number of edges the algorithm may travel along in finding the distance between vertices. (Maximum path length.).

DWORD selFlags=MN_SEL

Indicates what flag defines the hard selection we're basing this soft selection on.

Return Value:

A table consisting of one float value per vertex. If this value is 0, the vertex is either selected or on top of a selected vertex. Otherwise it represents the distance to the closest selected vertex. If useEdgeDist is TRUE, values of -1.0 are returned for vertices with no edgeIts-length path to a selected vertex.

Prototype:

Tab<float> *ClusterDist (int sl, DWORD clusterFlags, int clustId, BOOL useEdgeDist, int edgeIts);

Remarks:

This method computes the current distance of each vertex from the specified cluster. If cached, the cache is returned. Otherwise a cache is allocated and computed from the current mesh and the parameters.

NOTE: If useEdgeDist is FALSE, this is an n-log-n algorithm: it compares every vertex not in the cluster with every vertex in it. If useEdgeDist is TRUE, the time it takes is proportional to the number of verts in the cluster times edgeIts.

Parameters:

int sl

Indicates whether we should use edges (MNM_SL_EDGE) or faces (MNM_SL_FACE) to construct the clusters, if needed.

DWORD clusterFlags

The edge or face flags to cluster the edges or faces by. For instance, if clusterFlags==MN_SEL, edges or faces are clustered by selection.

int clustId

The ID of the cluster we're measuring distance from.

BOOL useEdgeDist

If set to TRUE, the distance between vertices is computed along edges. If set to FALSE, it's computed directly through space.

int edgeIts

This indicates the maximum number of edges the algorithm may travel along in finding the distance between vertices. (Maximum path length.)

Return Value:

A table consisting of one float value per vertex. If this value is 0, the vertex is either selected or on top of a vertex in the cluster. Otherwise it represents the distance to the closest selected vertex. If useEdgeDist is TRUE, values of -1.0 are returned for vertices with no edgeIts-length path to a vertex in the cluster.

Prototype:

Tab<Point3> *OutlineDir (int extrusionType, DWORD clusterFlags=MN_SEL);

Remarks:

This method produces the "Outline" direction of all vertices, based on the current face selection. "Outlining" is the direction vertices move to move edges of the current face selection outward at a constant rate. They are not set to length 1, but rather to whatever "rate" best makes the outline edges move most consistently, without changing their angles.

Parameters:

int extrusionType

This is one of MESH_EXTRUDE_CLUSTER or MESH_EXTRUDE_LOCAL, to indicate whether vertices should move according to cluster or local face normals.

DWORD clusterFlags=MN_SEL

The face flags to cluster the faces by. For instance, if left at the default value, faces are clustered by selection. Note that this parameter is ignored if the extrusionType is LOCAL.

Prototype:

MNChamferData *ChamferData();

Remarks:

This method returns the cache of a ChamferData for use in the MNMesh Chamfer methods. Unlike other MeshTempData methods, this method makes no calculations based on the current mesh, but merely supplies a memory cache. (Computing this information is left to the MNMesh methods GetExtrudeDirection, ChamferVertices, and ChamferEdges.)

Prototype:

void Invalidate (DWORD part);

Remarks:

This method invalidates all data based on the specified part of the mesh. In the following chart, the columns represent the channels GEOM_CHANNEL (G), TOPO_CHANNEL (T), SELECT_CHANNEL (S), and SUBSEL_TYPE_CHANNEL (U). X's indicate dependency of the specified data cache on the given channel.

 

Method to get cache

G

T

S

U

 

 

 

 

 

FaceClusters

 

X

X

 

EdgeClusters

 

X

X

 

VertexClusters

 

X

X

X

ClusterCenters

X

X

X

X

ClusterNormals

X

X

X

X

VertexNormals

X

X

 

 

SelectionDist

X

X

X

X

ClusterDist

X

X

X

X

VSWeight

X

X

X

X

 

NOTE: ChamferData and the Outline direction info are handled separately in freeChamferData and freeBevelInfo.

Parameters:

DWORD part

One or more of the following channels: GEOM_CHANNEL, TOPO_CHANNEL, SELECT_CHANNEL, SUBSEL_TYPE_CHANNEL.

Prototype:

void InvalidateDistances ();

Remarks:

This method Uncaches (frees) the distance dependent data returned by VSWeight, SelectionDist, and ClusterDist.

Prototype:

void InvalidateSoftSelection ();

Remarks:

This method frees the VSWeight data (but not the underlying distance-from-selection info). This is useful, e.g., if the mesh has not changed, but you wish to change the falloff, pinch, or bubble parameters to get new vertex selection weights.

Prototype:

void freeClusterDist ();

Remarks:

This method is mainly for internal use, this frees just the cluster distance data.

Prototype:

void freeBevelInfo ();

Remarks:

This method frees only the outlining data.

Prototype:

void freeChamferData();

Remarks:

This method frees only the chamfer data structure.

Prototype:

void freeAll ();

Remarks:

This method frees all cached data of any kind.

Global Functions

The following global methods are also available for use, though the related methods in the MNTempData class are more highly recommended.

Prototype:

void SelectionDistance (MNMesh & mesh, float *selDist, DWORD selFlags);

Remarks:

This function computes the current distance of each vertex from the current selection. NOTE: This is an n-log-n algorithm: it compares every non-selected vertex with every selected one.

Parameters:

MNMesh & mesh

The mesh we're computing distances in.

float *selDist

A pointer to an array of floats of size mesh.VNum(). This array is filled in with one float value per vertex. If this value is 0, the vertex is either selected or "on top of" a selected vertex. Otherwise it represents the distance to the closest selected vertex.

DWORD selFlags

Indicates what flag defines the hard selection we're basing this soft selection on. (MN_SEL is generally best.)

Prototype:

void SelectionDistance (MNMesh & mesh, float *selDist, int iters, DWORD selFlags);

Remarks:

This function computes the current distance of each vertex from the current selection, along paths of edges. NOTE: This is an n-log-n algorithm: it compares every non-selected vertex with every selected one.

Parameters:

MNMesh & mesh

The mesh we're computing distances in.

float *selDist

A pointer to an array of floats of size mesh.VNum(). This array is filled in with one float value per vertex. If this value is 0, the vertex is either selected or "on top of" a selected vertex. Otherwise it represents the distance to the closest selected vertex. Values of -1 are used to indicate vertices that are more that iters edges away from any selected vertex.

int iters

This indicates the maximum number of edges the algorithm may travel along in finding the distance between vertices. (Maximum path length.).

DWORD selFlags

Indicates what flag defines the hard selection we're basing this soft selection on. (MN_SEL is generally best.)

Prototype:

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

Remarks:

Computes the current distance of each vertex from the specified cluster. If cached, the cache is returned. Otherwise a cache is allocated and computed from the current mesh and the parameters.

NOTE: This is an n-log-n algorithm for each cluster: it compares every vertex not in the cluster with every vertex in it.

Parameters:

MNMesh & mesh

The MNMesh these cluster distances are based on.

int numClusts

The number of clusters available.

int *vclust

A pointer into the vertex cluster table.

Tab<float> **clustDist

An array of pointers to tables which will be filled with one float value per vertex. The table pointed to by clustDist[i] contains the cluster distances for cluster i. Note that clustDist must be allocated, for instance by clustDist = new (Tab<float>*)[numClusts], and must have its members allocated, for instance by clustDist[i] = new Tab<float>, by the calling routine. If a value in a table is 0, the vertex is either selected or on top of a vertex in the cluster. Otherwise it represents the distance to the closest selected vertex. If useEdgeDist is TRUE, values of -1.0 are returned for vertices with no edgeIts-length path to a vertex in the cluster.

Prototype:

void ClustDistances (MNMesh & mesh, int numClusts, int *vclust, Tab<float> **clustDist, int iters);

Remarks:

Computes the current distance of each vertex from the specified cluster. If cached, the cache is returned. Otherwise a cache is allocated and computed from the current mesh and the parameters.

NOTE: This algorithm takes time proportional to the number of verts in each cluster times iters times the number of clusters.

Parameters:

MNMesh & mesh

The MNMesh these cluster distances are based on.

int numClusts

The number of clusters available.

int *vclust

A pointer into the vertex cluster table.

Tab<float> **clustDist

An array of pointers to tables which will be filled with one float value per vertex. The table pointed to by clustDist[i] contains the cluster distances for cluster i. Note that clustDist must be allocated, for instance by clustDist = new (Tab<float> *)[numClusts], and must have its members allocated, for instance by clustDist[i] = new Tab<float>, by the calling routine. If a value in a table is 0, the vertex is either selected or on top of a vertex in the cluster. Otherwise it represents the distance to the closest selected vertex. Values of -1.0 are returned for vertices with no iters-length path to a vertex in the cluster.

int iters

The maximum edge path length to compute distance along (in number of edges).