Editable_Mesh : GeometryClass and TriMesh : Value

Editable_Mesh is the class of node objects that are the result of collapsing a modifier stack to an editable mesh object. Many of the mesh operations in MAXScript that modify meshes will only work on Editable_Mesh scene nodes.

The TriMesh class is a MAXScript value wrapper for the low-level 3ds max SDK Mesh class used extensively in mesh-based objects and modifiers in 3ds max. Meshes hold the actual vertex and face arrays, and so on, in a triangular mesh. For example, an Editable_Mesh object contains an instance of a Mesh. The prime purpose of the TriMesh class is to allow scripted primitive object plug-ins to access and build the Mesh object inside geometry objects. This class has a large range of mesh manipulation and construction functions, corresponding to the low-level mesh operations on Editable Mesh scene nodes.

The properties and methods described in this topic are applicable to both Editable_Mesh objects and TriMesh values are signified by a value type of <mesh>. The properties and methods applicable to just TriMesh values are signified by a value type of <trimesh>.

Warning: Meshes created by MAXScript are triMesh values.

See also

Notes

  1. Only the update() function updates the mesh's internal caches and images in 3ds max viewports. This is because updates can be computationally expensive and you don't want them performed on every function call. However, you must make sure you do call the update() function after a series of changes and before the mesh is to be worked on in 3ds max or by other functions in MAXScript.

  2. Coordinates are given in the MAXScript working coordinate system.

  3. If the update() function is called on an object that is selected and currently open in the Modify panel, it will drop the current selection in order to avoid a potential crash in 3ds max, which at the moment, does not support scripted changes to an object open in the Modify panel.

  4. If you are creating or modifying a mesh, and have not yet run update() on the mesh, 3ds max will crash if you minimize and then maximize the 3ds max window. This is because an only partially created mesh is created, and the internal 3ds max mesh structure is left in an unstable state.

Constructors (Editable_Mesh)

mesh [ length:<integer> ] [ width:<integer> ] \

[ lengthsegs:<integer> ] [ widthsegs:<integer> ]

Creates a flat rectangular mesh with the given size and number of segments. The default length and width are 50, the default number of segments is 5.

mesh [ numverts:<number> ] [ numfaces:<number> ]

Creates a mesh of the given geometry but with no topology (i.e., no faces or edges). You have to individually place the vertices and create the faces from the vertices. The default number of vertices and faces are 36 and 50, respectively.

mesh vertices:<array_of_point3s>         \

     faces:<array_of_point3s>            \

[ materialIDs:<array_of_integers> ] \

[ tverts:<array_of_point3s> ]

Creates a mesh from an array of vertices and faces. Each Point3 value in the vertices array specifies the position of the vertex in the current coordinate system. Each Point3 value in the faces array specifies the 3 vertex indices that form the face. The materialIDs array specifies the material ID to be assigned to each face. Each Point3 value in the tverts array specifies the UVW coordinates of the texture vertices. See Texture Mapping in the methods section for more information on texture vertices.

An example of construction a mesh using this form of the constructor is:

mesh vertices:#([0,0,0],[10,0,0],[0,10,0],[10,10,0]) \

faces:#([1,2,3],[2,4,3]) materialIDS:#(1,2)

collapseStack <node>                        -- mapped

Collapses the object space modifiers out of a stack, leaving a resultant Editable Mesh as the base object of the node. If there are no object space modifiers in the stack when this is called, no action is taken. So, if you want to force an object to be an editable mesh (for example, for the mesh operation listed below), you can apply a null modifier and then collapse the stack:

addModifier $foo (normalModifier())

collapseStack $foo

collapseStack() does not collapse the effect of any world space modifiers (including bindings to space warps). The world space modifiers remain on the object's stack. To collapse an object to a mesh use the snapshot() method.

snapshot <node>                             -- mapped

This function provides functionality similar to the SnapShot tool in 3ds max. It generates a new node that contains a copy of the world-state mesh of the source <node> at the time that the snapshot is made. Any existing modifiers are collapsed out of the new node and the mesh snapshot accounts for any space warps currently applied.

convertToMesh <node>                        -- mapped

Converts appropriate scene object types into Editable Meshes. It is similar to collapseStack() in that it will remove all object space modifiers present, but unlike collapseStack() it will always replace the base object with an editable mesh version, even if there are no modifiers present.

It can be applied to any object that an Edit Mesh modifier can work on, such as geometry and shapes, but not helpers, space warps, lights, etc.

convertTo <node> [ TriMeshGeometry | Mesh ]   -- mapped

Converts appropriate scene object types into Editable Meshes. Operates in an identical manner to convertToMesh().

Constructors (TriMesh)

TriMesh()

Creates an empty TriMesh. Use the methods listed below to build the mesh.

<node>.mesh

Extracts a copy of a node's world state if it is convertible to a mesh.

<editable_mesh_baseobject>.mesh

Extracts a copy of base object's mesh.

<trimesh>.mesh

Extracts a copy of another TriMesh's mesh.

Notes

GeometryClass boolean operations also create editable_mesh objects.

Operators

The following operators perform boolean operations on meshes. These operations destructively modify the first operand mesh to contain the boolean result, as do the same boolean <node> operations.

<mesh> + <mesh>    -- union

<mesh> - <mesh>    -- difference

<mesh> * <mesh>    -- intersection

Properties

<mesh>.numverts                    Integer

Get or set the number of vertices

<mesh>.numfaces                    Integer

Get or set the number of faces

<mesh>.numtverts                   Integer

Get or set the number of texture vertices

<mesh>.numcpvverts                 Integer

Get or set the number of color-per-vertex vertices

<mesh>.mesh                        TriMesh

Reading this property yields a copy of the mesh, taken from after any modifiers are applied, but before any space warps are applied. Assigning to this property sets the mesh to the TriMesh value given. You can use this property, along with copy() and the <node_or_baseobject>.mesh property to build a TriMesh from other objects' meshes.

The following properties are not applicable to TriMeshes:

<mesh>.selectedVerts               VertexArray

Get the currently selected vertices of the Editable_Mesh object. See VertexSelection Values.

<mesh>.verts                       VertexArray

Get all of the vertices of the Editable_Mesh object. See VertexSelection Values.

<mesh>.selectedFaces               FaceArray

Get the currently selected faces of the Editable_Mesh object. See FaceSelection Values.

<mesh>.Faces                       FaceArray

Get all of the faces of the Editable_Mesh object. See FaceSelection Values.

<mesh>.selectedEdges               EdgeArray

Get the currently selected edges of the Editable_Mesh object. See EdgeSelection Values.

<mesh>.Edges                       EdgeArray

Get all of the edges of the Editable_Mesh object. See EdgeSelection Values.

<mesh>.displacementMapping         Boolean

Get or set whether to perform displacement mapping for the Editable_Mesh object. There is no corresponding user interface element for this property.

<mesh>.subdivisionDisplacement     Boolean

Get or set whether to perform subdivision displacement for the Editable_Mesh object. This property corresponds to the Subdivision Displacement checkbox in the Surface Properties rollout.

<mesh>.splitMesh                   Boolean

Get or set whether to split the mesh during subdivision displacement. This property corresponds to the Split Mesh checkbox in the Surface Properties rollout. Setting this property will enable subdivisionDisplacement if it is set to false.

You can both read and assign to the above properties with the exception of the properties that return a VertexSelection, FaceSelection, or EdgeSelection. If you assign numbers to them to add room for more vertices or faces, the mesh will lose all current topology/geometry (i.e., vertices, faces, and edges), assuming you want to rebuild it from scratch. If you want to retain the current topology/geometry, use the setNumVerts(), setNumTVerts() and setNumFaces() methods described below.

Up to N vertex coordinates are available as properties on Editable_Mesh objects, where N is the number of vertices in the mesh. A vertex is available as a property once a controller has been assigned to the vertex. Controllers can be assigned to vertices using the animateVertex() method described in Scripting Vertex and Control Point Animation. For example, if a sphere object is collapsed to an Editable_Mesh, and some of its vertices are animated, the properties for the vertices would be similar to:

$Sphere01.vertex_209    Point3  value: [7.9,-40.0,0.0]   -- animatable

$Sphere01.vertex_210    Point3  value: [-7.8,-39.3,-7.9] -- animatable

$Sphere01.vertex_211    Point3  value: [0.0,-40.0,-7.9]  -- animatable

Methods

The following methods operate on the base object in a node if no object space modifiers are present. If object space modifiers are present, the mesh get operations access the world-state mesh, after the object space modifiers have been applied. The mesh set operations only work on base object Editable Meshes and signal an error if there are object space modifiers present, informing you that the mesh is not changeable when modifiers are present. You can convert objects to Editable Meshes with the collapseStack(), snapshot(), and convertToMesh() methods. If there are no object space modifiers present, both get and set operations work on the base editable mesh object.

Because the mesh get operations require a mesh, the combination of base object and modifiers must yield a mesh at the top of the modifier stack. This excludes combinations such as Patch base-objects and deformer modifiers such as bend and twist, because they pass a patch object, not a mesh up the stack. Applying an Edit Mesh modifier always forces the world-state object to be a mesh.

If world space modifiers are present, the mesh get operations access the world-state mesh, after any object space modifiers have been applied, but before the world space modifiers have been applied. Currently you can not access the position of vertices as affected by world space modifiers. The mesh set operations will work if only world space modifiers are applied to the object. Setting a vertices position in such a case will set it's position before the world space modifiers have been applied. You can create a new mesh object using the snapshot() method which accounts for the effects of world space modifiers.

The update() method makes any scripted changes to a base object mesh visible to 3ds max and you must call this function at some point after modifying a mesh so that 3ds max sees a valid mesh. Because this update can be a compute-intensive operation, it is made available as a separate function so you perform many changes on a mesh and then invoke the update just once to signal all the changes to 3ds max.

All vertex and face indexes start at 1, following the other indexing conventions in MAXScript. All coordinates used are relative to the current working coordinate system.

General Methods

update <mesh> [ geometry:<boolean> ] [ topology:<boolean> ] \

[ normals:<boolean> ]      -- mapped

The three optional keyword arguments provide control over the kind of updating done to the mesh. If the geometry: argument is true, the geometry cache is rebuilt (normals and edge list) and the mesh's bounding box is invalidated. If the topology: argument is true, the edge and strip databases will be rebuilt. If normals: is true, the face normals are computed. All flags default to true, so that a simple call to update() causes a complete reconstruction of all the caches.

attach <mesh> <node>

Corresponds to the mesh attach function in the Editable Mesh Modify panel allowing you to construct a mesh by adding complete objects to it. Extracts the mesh from <node> (first converting to a mesh if need), adds it to <mesh> which must be an Editable Mesh object and then deletes <node>. The materials and material IDs in <node> are merged into <node> using the default settings for the attach operation in the Editable Mesh Modify panel. This method is not applicable to TriMeshes.

meshop.attach {<target_editable_mesh_node> | <target_mesh>}

{<source_node> | <source_mesh>} \ targetNode:<node=unsupplied>

sourceNode:<node=unsupplied> \ attachMat:<{#neither | #MatToID |

#IDToMat}=#neither> condenseMat:<boolean=true> \ deleteSourceNode:<boolean=true>

Attaches the source mesh to the target mesh. If the target or source is specified as a mesh rather than a node, the mesh is attached using the local coordinate system of the mesh, and no material correction is performed. To get around this, if the target or source is a mesh, the corresponding targetNode or sourceNode named parameter is checked to see if a node is specified and, if it is, the transform and material for that node is used. If the source or target is specified as a node, the corresponding targetNode or sourceNode named parameter is not checked. The attachMat and condenseMat options correspond to the attach options in editable mesh.

condenseMat is applicable only if attachMat:#IDToMat is specified. If deleteSourceNode:false is not specified, and the source was specified as a node, or as a mesh and a sourceNode was specified, the source node is deleted after the attach.

Examples:

meshop.attach $.baseobject $sphere02 targetNode:$

meshop.attach $box01 $box02 attachMat:#IDToMat

condenseMat:true deleteSourceNode:false

meshop.getUIParam <mesh> <param_name>

meshop.getUIParam <node> [ <modifier_or_index> ] <param_name>

meshop.setUIParam <mesh> <param_name> { <float> | <boolean> }

meshop.setUIParam <node> [ <modifier_or_index> ] <param_name> { <number> | <boolean> }

Get/set a user-interface value. The optional <modifier_or_index> identifies the Edit Mesh modifier on the given scene object to set the parameter value for. These methods are UI-dependent, and require that the specified editable mesh or Edit Mesh modifier be currently displayed in the Modify panel. The valid param_name values, their meaning, and parameter value type are:

#SelByVert Selection - By Vertex (boolean)

#IgBack Selection - Ignore Backfacing (boolean)

#IgnoreVis Selection - Ignore Visibile Edges (boolean)

#PolyThresh Selection - Planar Threshold (number)

#SoftSel Soft Selection - Use Soft Selection (boolean)

#SSUseEDist Soft Selection - Edge Distance (boolean)

#SSEDist Soft Selection - Edge Distance (number) [note: if value hasn't been changed, returns a value of 0]

#SSBack Soft Selection - Ignore Backfacing (boolean) [note: this is the inverse of the UI element]

#Falloff Soft Selection - Falloff (number)

#Pinch Soft Selection - Pinch (number)

#Bubble Soft Selection - Bubble (number)

#WeldDist Weld - Distance (number)

#WeldBoxSize Weld - Box Size in Pixels (number)

#ExtrudeType Extrude/Chamfer (boolean) [note: true - Group; false - Local]

#ShowVNormals Show Vertex Normals (boolean)

#ShowFNormals Show Face Normals (boolean)

#NormalSize Normal Scale (number)

Vertex methods

meshop.breakVerts <Mesh mesh> <vertlist>

For each vertex in <vertlist>, N-1 new vertices are created at the same location, where N is the number of faces using that vertex. Each of these faces will use one of these vertices.

meshop.chamferVerts <Mesh mesh> <vertlist> <float amount>

Chamfers the specified vertices by the specified amount.

meshop.cloneVerts <Mesh mesh> <vertlist>

Clones the specified vertices.

meshop.cutVert <Mesh mesh> <int start_vert> <point3 destination> <point3 projdir> node:<node=unsupplied>

If <mesh> is a node, or if <mesh> is an Editable Mesh and <node> is specified, destination and projdir are in the current coordinate system context. If <mesh> is an Editable Mesh and <node> is not specified, destination and projdir are in the mesh's local coordinate system.

Returns the index of the new vertex if created, or undefined if no vertex was created.

meshop.deleteIsoVerts <Mesh mesh>

Deletes all vertices not used by a face.

meshop.deleteVerts <Mesh mesh> <vertlist>

Deletes the specified vertices.

meshop.detachVerts <Mesh mesh> <vertlist> delete:<boolean=true> asMesh:<boolean=false>

Detaches the faces used by the specified vertices. If <delete> is true, the faces are deleted after being detached. If <delete> is false, the faces are not deleted. If <asMesh> is true, the faces are detached and returned as a Mesh value. If <asMesh> is false, the faces are detached as an element in the mesh and a value of OK is returned.

meshop.getHiddenVerts <Mesh mesh>

Returns a bitarray of size=(#vertices in mesh) with bits set for all vertices that are hidden.

meshop.getIsoVerts <Mesh mesh>

Returns a bitarray of size=(#vertices in mesh) with bits set for all vertices that are not used by a face.

meshop.getNumVerts <Mesh mesh>

Returns the number of vertices in the mesh.

meshop.getVert <Mesh mesh> <int vertIndex> node:<node=unsupplied>

Returns the position of the specified vertex. If <mesh> is a node, or if <mesh> is an Editable Mesh or a Mesh value and <node> is specified, the position returned is in the current coordinate system context. If <mesh> is an Editable Mesh or a Mesh value and <node> is not specified, the return value is in the mesh's local coordinate system.

meshop.getVertexAngles <Mesh mesh> <vertlist>

This method calculates, for each vertex, the sum of the angles of this vertex's corner in each face it's on. So for instance, a point lying in the middle of a grid would always have vertex angle 2*PI, whereas a corner of a box would only have 270. Returns an array of size=(#vertices in mesh). The array element for any vertices not specified in <vertlist> will contain the value 0.

meshop.getVertsByColor <Mesh mesh> <color color> <float red_thresh> <float green_thresh> <float blue_thresh>  channel:<int=0>

Returns the vertices whose vertex color is within the color range as a <bitarray>. The range values should be in the range of 0 to 255.

meshop.getVertsByColor <Mesh mesh> <point3 uvw> <Float u_thresh> <Float v_thresh> <Float w_thresh>  channel:<int=0>

Returns the vertices whose vertex UVW is within the UVW range as a <bitarray>. The range values should be in the range of 0 to 1.

meshop.makeVertsPlanar <Mesh mesh> <vertlist>

Moves the specified vertices so that they are planar.

meshop.minVertexDistanceFrom <Mesh mesh> <int vertIndex> <vertlist>

Returns the minimal distance from <vertIndex> to the vertices specified in <vertlist>.

meshop.minVertexDistancesFrom <Mesh mesh> <vertlist> <int iterations>

This function computes distances from selected vertices (as indicated by <vertlist>) to non-selected ones along edge paths. Returns an array of size=(#vertices in mesh). Each element in this array is set to -1 if there is no selection. Otherwise, selected vertices have an array element value of 0; non-selected vertices that are <iterations> 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 <iterations> edges away are set to -1. If <iterations> is 0, the distances are 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 <iterations> 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.)

meshop.moveVert <Mesh mesh> <vertlist> <point3 offset> node:<node=unsupplied>

Moves the specified vertices by <offset>. If <mesh> is a node, or if <mesh> is an Editable Mesh or a Mesh value and <node> is specified, the offset is in the current coordinate system context. If <mesh> is an Editable Mesh or a Mesh value and <node> is not specified, the offset is in the mesh's local coordinate system.

meshop.moveVertsToPlane <Mesh mesh> <vertlist> <point3 normal> <float offset> node:<node=unsupplied>

Moves the specified vertices into the specified plane. The target plane is defined as all points which, when DotProd'd with N, return offset. All vertices are moved along the normal vector N. If <mesh> is a node, or if <mesh> is an Editable Mesh or a Mesh value and <node> is specified, the normal is in the current coordinate system context. If <mesh> is an Editable Mesh or a Mesh value and <node> is not specified, the normal is in the mesh's local coordinate system.

meshop.setHiddenVerts <Mesh mesh> <vertlist>

Sets the specified vertices as hidden, and non-specified vertices as visible.

meshop.setNumVerts <Mesh mesh> <int>

Sets the number of vertices in the mesh. Any new vertices are created at [0,0,0] in the mesh's local coordinate system.

meshop.setVert <Mesh mesh> <vertlist> <point3 pos> node:<node=unsupplied>

Moves the specified vertices to the specified position. If <mesh> is a node, or if <mesh> is an Editable Mesh or a Mesh value and <node> is specified, the position is in the current coordinate system context. If <mesh> is an Editable Mesh or a Mesh value and <node> is not specified, the position is in the mesh's local coordinate system.

meshop.setVertColor <Mesh mesh> <int mapChannel> <vertlist> <Color color>

Sets the vertex color for the specified vertices in the specified <mapChannel>.

meshop.weldVertsByThreshold <Mesh mesh> <vertlist> <float threshold>

Welds the specified vertices that are within the threshold distance.

meshop.weldVerts - renamed to weldVertSet

meshop.weldVertSet <Mesh mesh> <vertlist> weldpoint:<point3=unsupplied> node:<node=unsupplied>

Welds the specified vertices. If <weldpoint> is specified, the resulting vertex is positioned at that point. The result is put at the average location of the selected vertices. If <mesh> is a node, or if <mesh> is an Editable Mesh or a Mesh value and <node> is specified, the position is in the current coordinate system context. If <mesh> is an Editable Mesh or a Mesh value and <node> is not specified, the position is in the mesh's local coordinate system. If <weldpoint> is not specified, the resulting vertex is positioned at the average location of the specified vertices.

Vertex data methods

meshop.setNumVDataChannels <Mesh mesh> <Integer count> keep:<boolean=false>]

Sets the number of vertex data channels available. The number of vertex data channels can be set from 0 to 100. The first ten channels are for Discreet's use only. If keep is false or not specified, the old channel data is discarded. If true, the old channel data is retained after the resize. The predefined channels are:

channel 1: Soft Selection

channel 2 Vertex weights (for NURMS MeshSmooth)

channel 3 Vertex Alpha values

channel 4 Cornering values for subdivision use

meshop.getNumVDataChannels <Mesh mesh>

Returns the number of vertex data channels available as an <integer>.

meshop.setVDataChannelSupport <Mesh mesh> <Integer vdChannel> <Boolean support>

Sets whether the specified vertex data channel is supported or not. If support is true, and the channel support state is currently false, a new vertex data array of the same size as the number of vertices in the mesh is allocated. If support is false, and the channel support state is currently true, the existing vertex data channel array is deallocated. If support and the current channel support state are both the same, no action is performed. setNumVDataChannels() is automatically called if the specified vertex data channel is not available. vdChannel index values are 1-based, with channels 1 and 2 being the Vertex Soft Selection and Vertex Weight channels.

meshop.getVDataChannelSupport <Mesh mesh> <Integer vdChannel>

Returns whether the specified vertex data channel is supported.

meshop.getVDataValue <Mesh mesh> <Integer vdChannel> <Integer vert_index>

Returns the floating point data value associated with vertex vert_index in vertex data channel vdChannel as a <float>.

meshop.setVDataValue <Mesh mesh> <Integer vdChannel> <Integer vert_index> <Float value>

Sets the floating point data value associated with vertex vert_index in vertex data channel vdChannel.

meshop.freeVData <Mesh mesh> <Integer vdChannel>

Deallocates the existing vertex data channel array and turns off the vertex data channel support state.

Edge methods

meshop.chamferEdges <Mesh mesh> <edgelist> <float amount>

Chamfers the specified edges by the specified amount.

meshop.cloneEdges <Mesh mesh> <edgelist>

Clones the specified edges.

meshop.collapseEdges <Mesh mesh> <edgelist>

Collapses the specified edges.

meshop.cutEdge <Mesh mesh> <int edge1> <float prop1> <int edge2> <float prop2> <point3 projdir> node:<node=unsupplied>

If <mesh> is a node, or if <mesh> is an Editable Mesh and <node> is specified, projdir is in the current coordinate system context. If <mesh> is an Editable Mesh and <node> is not specified, projdir is in the mesh's local coordinate system.

Returns the index of the new vertex if created, or undefined if no vertex was created.

meshop.deleteEdges <Mesh mesh> <edgelist> delIsoVerts:<boolean=true>

Deletes the specified edges. If <delIsoVerts> is true, any isolated vertices are deleted.

meshop.divideEdge <Mesh mesh> <int edgeIndex> <float edgef> visDiag1:<boolean=false> visDiag2:<boolean=false> fixNeighbors:<boolean=true> split:<boolean=false>

Divides the specified edge at a fractional distance of <edgef> along its length. <visDiag1> and <visDiag2> specify whether each of the two new edges will be visible. If <fixNeighbors> is true, the face on the other side of this edge, that is, the "reverse face", should be divided as well to prevent the introduction of a seam. If <split> is true, separate vertices for the two halves of the edge will be created, splitting the mesh open along the diagonal(s).

meshop.divideEdges <Mesh mesh> <edgelist>

Divides all the specified edges in half, creating new points and subdividing faces.

meshop.edgeTessellate <Mesh mesh> <facelist> <float tension>

Tessellates the specified edges. This algorithm is exactly the one used in the Tessellate modifier, when operating on Faces and Edge SO elements.

<tension> specifies the tension for the edge tessellation. This value should be fairly small, between 0 and .5, and corresponds to the value in the Tessellate, Edit Mesh, or Editable Mesh UI's divided by 400.

meshop.extrudeEdges <Mesh mesh> <edgelist> <float height> dir:<{<point3 dir> | #independent | #common}=#independent> node:<node=unsupplied>

Creates new edges corresponding to the specified edges, and then moves the new edges by <height>. The direction the edges are moved is determined by <dir>. If <dir> is a point3 value, the edges will be moved in that direction. (If <mesh> is a node, or if <mesh> is an Editable Mesh or a Mesh value and <node> is specified, the direction is in the current coordinate system context. If <mesh> is an Editable Mesh or a Mesh value and <node> is not specified, the direction is in the mesh's local coordinate system.) If dir:#independent is specified, the edges are moved based on the normals of the faces using the edge. If dir:#common is specified, the edges are moved based on the normals of the face clusters using the edge.

meshop.getEdgesUsingVert <Mesh mesh> <vertlist>

Returns a bitarray of size=(#edges in mesh) with bits set for all edges that use the specified vertices.

meshop.getOpenEdges <Mesh mesh>

Returns a bitarray of size=(#edges in mesh) with bits set for all edges that are used by a single face.

meshop.turnEdges - renamed to turnEdge, still showing in index

meshop.turnEdge <Mesh mesh> <int edgeIndex>

Turns the specified edge. Only works on edges that have a face on both sides. These two faces are considered as a quad, where this edge is the diagonal, and remapped so that the diagonal flows the other way, between the vertices that were opposite this edge on each face.

Face methods

meshop.bevelFaces <Mesh mesh> <facelist> <float height> <float outline> dir:<{<point3 dir> | #independent | #common}=#independent> node:<node=unsupplied>

Moves the specified faces by <height> and outlines them by <outline>. The direction the faces are moved is determined by <dir>. If <dir> is a point3 value, the faces will be moved in that direction. (If <mesh> is a node, or if <mesh> is an Editable Mesh or a Mesh value and <node> is specified, the direction is in the current coordinate system context. If <mesh> is an Editable Mesh or a Mesh value and <node> is not specified, the direction is in the mesh's local coordinate system.) If dir:#independent is specified, the faces are moved based on the individual face normals. If dir:#common is specified, the faces are moved based on the face cluster normals.

meshop.cloneFaces <Mesh mesh> <facelist>

Clones the specified faces.

meshop.collapseFaces <Mesh mesh> <facelist>

Collapses the specified faces.

meshop.cutFace <Mesh mesh> <int face> <point3 start> <point3 destination> <point3 projdir> node:<node=unsupplied>

If <mesh> is a node, or if <mesh> is an Editable Mesh and <node> is specified, start, destination, and projdir are in the current coordinate system context. If <mesh> is an Editable Mesh and <node> is not specified, start, destination, and projdir are in the mesh's local coordinate system.

Returns the index of the new vertex if created, or undefined if no vertex was created.

meshop.deleteFaces <Mesh mesh> <facelist> delIsoVerts:<boolean=true>

Deletes the specified faces. If <delIsoVerts> is true, any isolated vertices are deleted.

meshop.detachFaces <Mesh mesh> <facelist> delete:<boolean=true> asMesh:<boolean=false>

Detaches the specified faces. If <delete> is true, the faces are deleted after being detached. If <delete> is false, the faces are not deleted. If <asMesh> is true, the faces are detached and returned as a Mesh value. If <asMesh> is false, the faces are detached as an element in the mesh and a value of OK is returned.

meshop.divideFace <Mesh mesh> <int faceIndex> baryCoord:<point3=unsupplied>

Divides the specified face. If <baryCoord> is specified, the new vertex will be created at the corresponding position. If <baryCoord> is not specified, the new vertex will be created at the center of the face.

meshop.divideFaceByEdges <Mesh mesh> <int faceIndex> <int edge1Index> <float edge1f> <int edge2Index> <float edge2f> fixNeighbors:<boolean=true> split:<boolean=false>

Divides the specifed face. New vertices are created on the specified edges at the specified fractional distance along their length. If <fixNeighbors> is true, the face on the other side of the edges, that is, the "reverse faces", should be divided as well to prevent the introduction of a seam. If <split> is true, separate vertices for the two halves of the edges will be created, splitting the mesh open along the diagonal(s).

meshop.divideFaces <Mesh mesh> <facelist>

Divides the specified faces, with new vertices created at the center of the faces.

meshop.explodeAllFaces <Mesh mesh> <float threshold>

"Explodes" the mesh into separate elements.

<threshold> specifies the angle between faces that indicates whether they should be in the same or different element.

meshop.explodeFaces <Mesh mesh> <facelist> <float threshold>

"Explodes" the specified faces into separate elements.

<threshold> specifies the angle between faces that indicates whether they should be in the same or different element.

meshop.extrudeFaces <Mesh mesh> <facelist> <float height> <float outline> dir:<{<point3 dir> | #independent | #common}=#independent> node:<node=unsupplied>

Creates new faces corresponding to the specified faces, and then moves the new faces by <height> and outlines them by <outline>. The direction the faces are moved is determined by <dir>. If <dir> is a point3 value, the faces will be moved in that direction. (If <mesh> is a node, or if <mesh> is an Editable Mesh or a Mesh value and <node> is specified, the direction is in the current coordinate system context. If <mesh> is an Editable Mesh or a Mesh value and <node> is not specified, the direction is in the mesh's local coordinate system.) If dir:#independent is specified, the faces are moved based on the individual face normals. If dir:#common is specified, the faces are moved based on the face cluster normals.

meshop.getBaryCoords <Mesh mesh> <int faceIndex> <point3 pos> node:<node=unsupplied>

The barycentric coordinates of the specified point in the plane of the specified face, relative to the face. If <mesh> is a node, or if <mesh> is an Editable Mesh or a Mesh value and <node> is specified, the position is in the current coordinate system context. If <mesh> is an Editable Mesh or a Mesh value and <node> is not specified, the position is in the mesh's local coordinate system.

meshop.getElementsUsingFace <Mesh mesh> <facelist> fence:<facelist=unsupplied>

Returns a bitarray of size=(#faces in mesh) with bits set for all faces in elements where at least one face in the element is specified in <facelist>. If <fence> is specified, its faces are considered as barriers to the element and are not processed.

meshop.getFaceCenter <Mesh mesh> <int faceIndex> node:<node=unsupplied>

Returns the face center of the specified face. If <mesh> is a node, or if <mesh> is an Editable Mesh or a Mesh value and <node> is specified, the position is in the current coordinate system context. If <mesh> is an Editable Mesh or a Mesh value and <node> is not specified, the position is in the mesh's local coordinate system.

meshop.getFaceRNormals <Mesh mesh> <int faceIndex> node:<node=unsupplied>

Returns a three element array of the render normals for the face's three vertices. If <mesh> is a node, or if <mesh> is an Editable Mesh or a Mesh value and <node> is specified, the position is in the current coordinate system context. If <mesh> is an Editable Mesh or a Mesh value and <node> is not specified, the position is in the mesh's local coordinate system.

meshop.getFacesUsingVert <Mesh mesh> <vertlist>

Returns a bitarray of size=(#faces in mesh) with bits set for all faces that use the specified vertices.

meshop.getHiddenFaces <Mesh mesh>

Returns a bitarray of size=(#faces in mesh) with bits set for all faces that are hidden.

meshop.getNumFaces <Mesh mesh>

Returns the number of faces in the mesh.

meshop.getVertsUsedOnlyByFaces <Mesh mesh> <facelist>

Returns a bitarray of size=(#vertices in mesh) with bits set for all vertices used by the specified faces.

meshop.makeFacesPlanar <Mesh mesh> <facelist>

Moves the specified faces so that they are planar.

meshop.removeDegenerateFaces <Mesh mesh>

Deletes any degenerate faces in the mesh. A degenerate face has two or more equal vertex indices.

meshop.removeIllegalFaces <Mesh mesh>

Deletes any illegal faces in the mesh. An illegal face has one or more vertex indices that are out of range.

meshop.setHiddenFaces <Mesh mesh> <facelist>

Sets the specified faces as hidden, and non-specified faces as visible.

meshop.setNumFaces <Mesh mesh> <int>

Sets the number of faces in the mesh.

Mesh methods

meshop.createPolygon <Mesh mesh> <vertIndex array> smGroup:<int=0> matID:<int=1>

Creates a set of faces using the specified vertices. The order of the vertices in the faces is the order in the vertex array. The polygon may be nonconvex, but should be (roughly) coplanar.

<smGroup> and <matID> specify the smoothing group data and material ID number assigned to the new faces.

meshop.cut <Mesh mesh> <int edge1Index> <float edge1f> <int edge2Index> <float edge2f> <point3 normal> fixNeighbors:<boolean=true> split:<boolean=true> node:<node=unsupplied>

Cuts the mesh from a point on one edge to a point on another, along a line drawn by looking at the mesh from a particular viewpoint.

<edge1Index> specifies the edge that the cut starts on.

<edge1f> specifies the fractional distance along the edge to start the cut from.

<edge2Index> specifies the edge that the cut ends on.

<edge2f> specifies the fractional distance along the edge to finish the cut on.

<normal> specifies the direction of view. The cut will take place on this "side" of the mesh, in the plane formed by this vector and the direction from the start to the end.

If <fixNeighbors> is true, the faces on the other side of each end of the cut should be split to prevent splits at the ends. If <split> is true, the cut will split the mesh apart. If false, the cut will just refine the mesh by adding geometry. If <mesh> is a node, or if <mesh> is an Editable Mesh or a Mesh value and <node> is specified, the normal is in the current coordinate system context. If <mesh> is an Editable Mesh or a Mesh value and <node> is not specified, the normal is in the mesh's local coordinate system.

meshop.getPolysUsingVert <Mesh mesh> <vertlist> ignoreVisEdges:<boolean=false> threshhold:<float=45.>

Returns a bitarray of size=(#faces in mesh) with bits set for all faces that are in 'polygons' containing the specified vertices. The definition of a polygon is all faces sharing invisible edges with edge angles below the threshhold angle. The default threshhold angle is 45 degrees. If ignoreVisEdges is set to true, the edge visibility is ignored but the threshhold is still relevant.

meshop.optimize <Mesh mesh> <float normalThreshold> <float edgeThreshold> <float bias> <float maxEdge> saveMatBoundries:<boolean=true> saveSmoothBoundries:<boolean=true> autoEdge:<boolean=true>

Reduces the mesh in complexity by reducing the number of faces based on a surface normal threshold. Adjacent faces whose difference in surface normal angle falls below <normalThreshold> will be collapsed into a single triangle. If <autoEdge> is true, when the angle between adjacent surface normals is less than <edgeThreshold> the edge will be invisible. When optimizing mesh objects, as the optimization increases, you can get lots of long skinny 'degenerate' triangles (that cause rendering artifacts). Increasing <bias> keeps triangles from becoming degenerate. The range of values is from 0 to 1 (where 0 turns bias off). Values close to 1 reduce the amount of optimization in favor of maintaining equilateral triangles. A <maxEdge> value > 0 will prevent the optimize function from creating edges longer than this value. If this parameter is <=0 no limit is placed on the length of the edges. If <saveMatBoundries> is true, faces won't be collapsed across a material boundary. If <saveSmoothBoundries> is true, faces won't be collapsed across a dissimilar smoothing group boundary.

meshop.slice <Mesh mesh> <facelist> <point3 normal> <float offset> separate:<boolean=false> delete:<boolean=false> node:<node=unsupplied>

Slices the mesh along the specified slicing plane. The slicing plane is defined as all points which, when DotProd'd with <normal>, return <offset>. <normal> should be normalized.

<separate> specifies whether the slice should separate the mesh into two separate elements (true) or just refine the existing mesh by splitting faces (false).

<delete> specifies whether the slice should remove the portion of the mesh "below" the slicing plane, where "below" is defined as the area where DotProd (p,<normal>) - <offset> < 0. If <delete> is true, <separate> is ignored. If <mesh> is a node, or if <mesh> is an Editable Mesh or a Mesh value and <node> is specified, the normal is in the current coordinate system context. If <mesh> is an Editable Mesh or a Mesh value and <node> is not specified, the normal is in the mesh's local coordinate system.

copy <trimesh>

Yields a copy of the source TriMesh.

delete <trimesh>

Clears out the TriMesh's geometry and topology, effectively freeing its memory.

The following method is not applicable to TriMeshes:

animateVertex <mesh> <vertex_spec>

Applies controllers to the specified vertices of the Editable_Mesh, where <vertex_spec> is one of:

<integer_index>

<integer_index_array>

#all

By assigning controllers to the vertices, the vertices are added to the Master subAnim and appear as animatables in the Track View, allowing further scripting of the vertices. For example,

animateVertex $Sphere01 #all

The vertices to be animated are specified by index number or with the keyword #all to animate all vertices.

See also Class and Object Inspector Functions and Scripting Vertex and Control Point Animation for details on accessing the Editable_Mesh vertices. The controller values assigned to the vertices is in object space. See Using Node Transform Properties for information on converting between world space to object space.

The setMesh() method enables bulk changes to a mesh via arrays of vertices, faces, tverts, etc. setMesh() has the following forms:

setMesh <mesh> [ numverts:<integer> ] [ numfaces:<integer> ]

Resets the mesh to the given geometry but with no topology (i.e., no faces or edges). Any current mesh data is lost. You have to individually place the vertices and create the faces from the vertices. The default number of vertices and faces are 36 and 50, respectively.

setMesh <mesh> [ vertices:<array_of_point3s> ]     \

               [ faces:<array_of_point3s> ]        \

[ materialIDs:<array_of_integers> ] \

[ tverts:<array_of_point3s> ]

Resets the mesh based on the given arrays. Only those portions of the mesh that are specified are reset. For example, if only the vertices parameter is specified, the existing face data is retained. Each Point3 value in the vertices array specifies the position of the vertex in the current coordinate system. Each Point3 value in the faces array specifies the 3 vertex indices that form the face. The materialIDs array specifies the material ID to be assigned to each face. Each Point3 value in the tverts array specifies the UVW coordinates of the texture vertices. See Texture Mapping in the methods section for more information on texture vertices.

setMesh <mesh> [ length:<integer> ] [ width:<integer> ] [ lengthsegs:<integer> ] \

[ widthhsegs:<integer> ]

Resets the mesh with a flat rectangular mesh with the given size and number of segments. The default length and width are 50, the default number of segments is 5.

setMesh <mesh> <trimesh>

Sets the mesh to a copy of the source TriMesh.

Mapping methods û General

meshop.deleteIsoMapVertsAll <Mesh mesh>

For all mapping channels, deletes all mapping vertices that are not used by a mapping face.

meshop.freeMapChannel <Mesh mesh> <int mapChannel>

Deletes the map vertex and face arrays for the specified channel, and sets their count to 0.

meshop.getMapFacesUsingMapVert <Mesh mesh> <int mapChannel> <mapVertlist>

Returns a bitarray of size=(#map faces for channel in mesh) with bits set for all map faces that use the specified map vertices.

meshop.getMapVertsUsingMapFace <Mesh mesh> <int mapChannel> <mapFacelist>

Returns a bitarray of size=(#map vertices for channel in mesh) with bits set for all map vertices that use the specified map faces.

meshop.setFaceAlpha <Mesh mesh> <int mapChannel> <facelist> <float alpha>

For the specified map channel, sets the map vertex color to value between 0 (transparent) and 1 (opaque) for the map vertices used by the map faces associated with the specified faces.

meshop.setFaceColor <Mesh mesh> <int mapChannel> <facelist> <color color>

For the specified map channel, sets the map vertex color to <color> for the map vertices used by the map faces associated with the specified faces.

meshop.setVertAlpha <Mesh mesh> <int mapChannel> <vertlist> <float alpha>

For the specified map channel, sets the map vertex color to a value between 0 (transparent) and 1 (opaque) for the map vertices associated with the specified mesh vertices.

meshop.setVertColor <Mesh mesh> <int mapChannel> <vertlist> <color color>

For the specified map channel, sets the map vertex color to <color> for the specified map vertices.

meshop.setNumMaps <Mesh mesh> <int count> keep:<boolean=false>

Sets the number of map channels available. The number of map channels can be set from 2 to 100. Map channels 1 and 2 are the Vertex Color and default Texture Map channels. If keep is false, the old mapping information is discarded. If true, the old mapping information is retained after the resize.

meshop.getNumMaps <Mesh mesh>

Returns the number of map channels available as an <integer>.

meshop.setMapSupport <Mesh mesh> <Integer mapChannel> <Boolean support>

Sets whether the specified mapping channel is supported or not. If support is true, and the channel support state is currently false, a new map face array of the same size as the number of faces in the mesh is allocated, but no map vertex array is allocated. If support is false, and the channel support state is currently true, existing map channel face and vertex arrays are deallocated. If support and the current channel support state are both the same, no action is performed. SetNumMaps() is automatically called if the specified map channel is not available.

mapChannel index values are 0-based, with Map channels 0 and 1 being the Vertex Color and default Texture Map channels.

meshop.getMapSupport <Mesh mesh> <Integer mapChannel>

Returns whether the specified map channel is supported. This signifies that a map face array is present, but not necessarily a map vertex array.

meshop.setNumMapVerts <Mesh mesh> <Integer mapChannel> <Integer count> keep:<boolean=FALSE>

Sets the number of vertices for the map channel, initializing the map vertex array. If keep is false or not specified, the old map vertex information is discarded. If true, the old map vertex information is retained after the resize.

meshop.getNumMapVerts <Mesh mesh> <Integer mapChannel>

Returns the number of vertices for the map channel as an <integer>.

meshop.setNumMapFaces <Mesh mesh> <Integer mapChannel> <Integer count> keep:<boolean=false> keepCount:<int=0>

Sets the number of faces for the map channel. If keep is false or not specified, the old map face information is discarded. If true, the old map face information from the number of faces specified by keepCount is retained after the resize. Dangerous to use with map channels 0 and 1, so miminum mapChannel value is 2.

meshop.getNumMapFaces <Mesh mesh> <Integer mapChannel>

Returns the number of faces for the map channel as an <integer>.

meshop.setMapVert <Mesh mesh> <Integer mapChannel> <Integer index> <Point3 xyz>

Sets the coordinates of the specified map vertex.

meshop.getMapVert <Mesh mesh> <Integer mapChannel> <Integer index>

Returns the coordinates of the specified map vertex as a <point3>.

meshop.setMapFace <Mesh mesh> <Integer mapChannel> <Integer index> <Point3 face>

Sets the map vertices for the specified map face.

meshop.getMapFace <Mesh mesh> <Integer mapChannel> <Integer index>

Returns the vertices of the specified map face as a <point3>.

meshop.makeMapPlanar <Mesh mesh> <Integer mapChannel>

Applies a simple planar mapping to the specified channel. This is done by copying the mesh topology and vertex locations into the map, resizing the face and vertex arrays if necessary.

meshop.getIsoMapVerts <Mesh mesh> <Integer mapChannel>

Returns a <bitarray> with a bit set for each isolated map vertex (unrefereced by any map face) for the specified channel.

meshop.deleteMapVertSet <Mesh mesh> <Integer mapChannel> {<BitArray set> | <Integer index> | <integer array>}

Deletes the specified map vertices. Returns a <bitarray> with a bit set for each map face that used one of the deleted map vertices. Normally, you should delete or modify the map faces using the map vertices before deleting the map vertices, as after the vertex deletion you can't tell which vertex on a face was a vertex that was deleted.

meshop.freeMapVerts <Mesh mesh> <Integer mapChannel>

Deallocates the map vertex array and sets the number of map vertices to 0.

meshop.freeMapFaces <Mesh mesh> <Integer mapChannel>

Deallocates the map face array and sets the number of map faces to 0.

meshop.applyUVWMap <TriMesh mesh> {<#planar | #cylindrical | #spherical | #ball | #box> | <#face>} \ utile:<float=1.0> vtile:<float=1.0> wtile:<float=1.0> uflip:<boolean=false> vflip:<boolean=false> wflip:<boolean=false> cap:<boolean=true> tm:<Matrix3=identity matrix>

channel:<int=1>

Applies the specified mapping type to the mapping channel.

utile/vtile/wtile - Number of tiles in the U/V/W directions.

uflip/vflip/wflip - U/V/W are mirrored if true.

cap - used with #cylindrical. If true, then any face normal that is pointing more vertically than horizontally will be mapped using planar coordinates.

tm - defines the mapping space. As each point is mapped, it is multiplied by this matrix, and then it is mapped.

channel - the mapping channel the mapping is applied to, defaults to channel 1.

meshop.buildMapFaces <Mesh mesh> <Integer mapChannel> <Boolean keep>

Sets the number of map faces to the number of mesh faces, retaining existing mapping data if keep is true. Deletes any map vertices that are not used by the map faces.

meshop.defaultMapFaces  <Mesh mesh> <Integer mapChannel> <Integer count>

Sets the number of map faces to the number of mesh faces, and the number of map vertices to the number of mesh vertices. The map face vertices are set to the same vertex index as the corresponding mesh face vertices (i.e., there will be a 1-to-1 correspondence between map faces/vertices and the mesh faces/vertices). The map vertex UVW coordinates are set to the normalized (0 to 1) position of the corresponding mesh vertex in the mesh's bounding box.

Mapping methods û Color per vertex channel (Channel 0)

meshop.getNumCPVVerts <Mesh mesh>

Returns the number of Color Per Vertex mapping channel vertices.

meshop.setNumCPVVerts <Mesh mesh> <int>

Sets the number of Color Per Vertex mapping channel vertices.

Mapping methods û Default texture mapping channel (Channel 1)

meshop.getNumTVerts <Mesh mesh>

Returns the number of Default Texture mapping channel vertices.

meshop.setNumTVerts <Mesh mesh> <int>

Sets the number of Default Texture mapping channel vertices.

Data methods û Vertex selection weight channel (Channel 1)

meshop.getVSelectWeight <Mesh mesh> <int vertIndex>

Returns the Vertex Selection Weight data value for the specified vertex.

meshop.setVSelectWeight <Mesh mesh> <vertlist> <float weight>

Sets the Vertex Selection Weight data value for the specified vertex.

meshop.resetVSelectWeights <Mesh mesh>

Sets the Vertex Selection Weight data value to 1.0 for all vertices.

meshop.supportVSelectWeights <Mesh mesh>

Enables support of the Vertex Selection Weight channel.

meshop.freeVSelectWeights <Mesh mesh>

Deletes (deallocates) the Vertex Selection Weight data array.

Data methods û Vertex weight channel (Channel 2)

meshop.getVertWeight <Mesh mesh> <int vertIndex>

Returns the Vertex Weight data value for the specified vertex.

meshop.setVertWeight <Mesh mesh> <vertlist> <float weight>

Sets the Vertex Weight data value for the specified vertex.

meshop.resetVertWeights <Mesh mesh>

Sets the Vertex Weight data value to 1.0 for all vertices.

meshop.supportVertWeights <Mesh mesh>

Enables support of the Vertex Weight channel.

meshop.freeVertWeights <Mesh mesh>

Deletes (deallocates) the Vertex Weight data array.

Data methods û Vertex Alpha channel (Channel 3)

meshop.getVAlpha <Mesh mesh> <int vertIndex>

Returns the Vertex Alpha data value for the specified vertex.

meshop.setVAlpha <Mesh mesh> <vertlist> <float alpha>

Sets the Vertex Alpha data value for the specified vertex.

meshop.resetVAlphas <Mesh mesh>

Sets the Vertex Alpha data value to 1.0 for all vertices.

meshop.supportVAlphas <Mesh mesh>

Enables support of the Vertex Alpha channel.

meshop.freeVAlphas <Mesh mesh>

Deletes (deallocates) the Vertex Alpha data array.

Data methods û Vertex corner channel (Channel 4)

meshop.getVertCorner <Mesh mesh> <int vertIndex>

Returns the Vertex Corner data value for the specified vertex.

meshop.setVertCorner <Mesh mesh> <vertlist> <float weight>

Sets the Vertex Corner data value for the specified vertex.

meshop.resetVertCorners <Mesh mesh>

Sets the Vertex Corner data value to 0.0 for all vertices.

meshop.supportVertCorners <Mesh mesh>

Enables support of the Vertex Corner channel.

meshop.freeVertCorners <Mesh mesh>

Deletes (deallocates) the Vertex Corner data array.

Editable mesh UI property methods

meshop.getAffectBackfacing <Mesh mesh> -- editable mesh only

meshop.setAffectBackfacing <Mesh mesh> <boolean> -- editable mesh only

meshop.getBubble <Mesh mesh> -- editable mesh only

meshop.setBubble <Mesh mesh> <float> -- editable mesh only

meshop.getDisplacementMapping <Mesh mesh> -- editable mesh only

meshop.setDisplacementMapping <Mesh mesh> <boolean> -- editable mesh only

meshop.getExtrusionType <Mesh mesh> -- editable mesh only

meshop.setExtrusionType <Mesh mesh> <int> -- editable mesh only

meshop.getFalloff <Mesh mesh> -- editable mesh only

meshop.setFalloff <Mesh mesh> <float> -- editable mesh only

meshop.getIgnoreBackfacing <Mesh mesh> -- editable mesh only

meshop.setIgnoreBackfacing <Mesh mesh> <boolean> -- editable mesh only

meshop.getIgnoreVisEdges <Mesh mesh> -- editable mesh only

meshop.setIgnoreVisEdges <Mesh mesh> <boolean> -- editable mesh only

meshop.getNormalSize <Mesh mesh> -- editable mesh only

meshop.setNormalSize <Mesh mesh> <float> -- editable mesh only

meshop.getPinch <Mesh mesh> -- editable mesh only

meshop.setPinch <Mesh mesh> <float> -- editable mesh only

meshop.getPlanarThreshold <Mesh mesh> -- editable mesh only

meshop.setPlanarThreshold <Mesh mesh> <float> -- editable mesh only

meshop.getSelByVertex <Mesh mesh> -- editable mesh only

meshop.setSelByVertex <Mesh mesh> <boolean> -- editable mesh only

meshop.getShowFNormals <Mesh mesh> -- editable mesh only

meshop.setShowFNormals <Mesh mesh> <boolean> -- editable mesh only

meshop.getShowVNormals <Mesh mesh> -- editable mesh only

meshop.setShowVNormals <Mesh mesh> <boolean> -- editable mesh only

meshop.getSoftSel <Mesh mesh> -- editable mesh only

meshop.setSoftSel <Mesh mesh> <boolean> -- editable mesh only

meshop.getSplitMesh <Mesh mesh> -- editable mesh only

meshop.setSplitMesh <Mesh mesh> <boolean> -- editable mesh only

meshop.getSSEdgeDist <Mesh mesh> -- editable mesh only

meshop.setSSEdgeDist <Mesh mesh> <int> -- editable mesh only

meshop.getSSUseEdgeDist <Mesh mesh> -- editable mesh only

meshop.setSSUseEdgeDist <Mesh mesh> <boolean> -- editable mesh only

meshop.getSubdivisionAngle <Mesh mesh> -- editable mesh only

meshop.setSubdivisionAngle <Mesh mesh> <float> -- editable mesh only

meshop.getSubdivisionDisplacement <Mesh mesh> -- editable mesh only

meshop.setSubdivisionDisplacement <Mesh mesh> <boolean> -- editable mesh only

meshop.getSubdivisionDistance <Mesh mesh> -- editable mesh only

meshop.setSubdivisionDistance <Mesh mesh> <float> -- editable mesh only

meshop.getSubdivisionEdge <Mesh mesh> -- editable mesh only

meshop.setSubdivisionEdge <Mesh mesh> <float> -- editable mesh only

meshop.getSubdivisionMaxLevels <Mesh mesh> -- editable mesh only

meshop.setSubdivisionMaxLevels <Mesh mesh> <int> -- editable mesh only

meshop.getSubdivisionMaxTriangles <Mesh mesh> -- editable mesh only

meshop.setSubdivisionMaxTriangles <Mesh mesh> <int> -- editable mesh only

meshop.getSubdivisionMethod <Mesh mesh> -- editable mesh only

meshop.setSubdivisionMethod <Mesh mesh> {#regular | #spatial | #curvature | #spatialAndCurvature} -- editable mesh only

meshop.getSubdivisionMinLevels <Mesh mesh> -- editable mesh only

meshop.setSubdivisionMinLevels <Mesh mesh> <int> -- editable mesh only

meshop.getSubdivisionSteps <Mesh mesh> -- editable mesh only

meshop.setSubdivisionSteps <Mesh mesh> <int> -- editable mesh only

meshop.getSubdivisionStyle <Mesh mesh> -- editable mesh only

meshop.setSubdivisionStyle <Mesh mesh> {#tree | #grid | #delaunay} -- editable mesh only

meshop.getSubdivisionView <Mesh mesh> -- editable mesh only

meshop.setSubdivisionView <Mesh mesh> <boolean> -- editable mesh only

meshop.getWeldPixels <Mesh mesh> -- editable mesh only

meshop.setWeldPixels <Mesh mesh> <int> -- editable mesh only

meshop.getWeldThreshold <Mesh mesh> -- editable mesh only

meshop.setWeldThreshold <Mesh mesh> <float> -- editable mesh only

Vertex Methods

getNumVerts <mesh>

Returns number of vertices as an integer, equivalent to using <mesh>.numverts

setNumVerts <mesh> <vert_index_integer> [ <boolean> ]

Set the number of vertices as specified. If the optional boolean argument is true, the existing topology remains intact. If it is false or left off, the topology is lost.

getVert <mesh> <vert_index_integer>

Returns the position (in the current working coordinate system) of the indexed vertex as a point3

setVert <mesh> <vert_index_integer> ( <point3> | <float> <float> <float> )

Sets the position coordinates of the indexed vertex as a point3 value, or 3 floats - X,Y,Z

deleteVert <mesh> <vert_index_integer>

Deletes the indexed vertex from the mesh and all faces that share the vertex. Renumbers vertices and faces to account for the deletions. Also adjusts face vertex indexes as necessary.

getNormal <mesh> <vert_index_integer>

Returns the normal at the indexed vertex's position as a point3. The normal is based on the faces that use the vertex and the smoothing groups assigned to those faces.

setNormal <mesh> <vert_index_integer> <point3>

Sets the indexed vertex's normal vector

getVertSelection <node> [ <modifier_or_index> ] [ name:<name> ]

getVertSelection <mesh>

Returns the current vertex selection set, or the specified named selection set if the optional name: parameter is specified, as a BitArray. The optional <modifier_or_index> identifies the Edit Mesh or Mesh Select modifier on the given scene object from which the selection BitArray is obtained. For example:

getVertSelection $foo $foo.modifiers[3]

If the optional <modifier_or_index> argument is not supplied, the <node> must be an Editable Mesh object and the selection is taken from the base object. If <modifier_or_index> is supplied, it must be either a modifier on the node or a number. If it is a modifier, it must be either an Edit Mesh or a Mesh Select modifier. If it is a number, it is used as an index into the Edit Mesh/Select Modifiers on the <node> starting from the top of the stack. Note that this index does not count any other types of modifier present. So, an index of 1 will always get the selection currently active at the top of the stack.

The function returns a BitArray that are the 1-based indexes of the vertices currently selected, or the vertices specified by the named selection set, in the object by the given modifier. For example:

getVertSelection $foo $foo.modifiers[3]

yields

#{2..5,9,25..27}

This is a snapshot of the selectionùthe BitArray doesn't change automatically as you make different selections. Further, it reflects the current vertex selection whether or not the modifier is in vertex sub-object selection mode (this selection is remembered and re-established whenever you go back into vertex subobject mode). So, for example, if you select some vertices then click out of vertex subobject mode, the whole object rather than the selection is passed up the stack to the next modifier, but getVertSelection() returns the selected vertices at the time the subobject mode was exited.

You might use the modifiers modifier array accessing scheme here if you've got many edit mesh modifiers with non-unique names. You can also use a constructed string as an index into the modifiers array, for example:

$foo.modifiers["edit mesh" + i as string]

assuming the variable 'i' had some indexing value and the names were set up thusly. '+' on strings concatenates.

setVertSelection <node> [ <modifier_or_index> ]          \

( <sel_bitarray> | <sel_array> ) \

[ name:<name> ] [ keep:<boolean> ]

setVertSelection <mesh> ( <sel_bitarray> | <sel_array> ) \

[ keep:<boolean> ]

Sets the vertex selections in an Editable Mesh base object, Mesh Select modifier, Edit Mesh Modifier, or TriMesh. This mirrors the selection getting method above.

The <modifier_or_index> argument is interpreted as for the get- form above, except that only the Mesh Select modifier is supported for set operations.

For example:

setVertSelection $foo #{1..4,100..102}

setFaceSelection $foo \

(getFaceSelection $baz) keep:true

If the optional name: argument is specified, the vertices in the specified named selection set in the Editable Mesh or Mesh Select modifier are selected. If the name: argument is not specified, the selection index argument gives the indexes of the sub-object items to be selected as either a BitArray or an array of integers. If the optional keep: keyword argument is false or not supplied, any current selection will be replaced by the new one. If the keep: keyword argument is true, the new selection is added to the current selection. The name: argument is not applicable to TriMeshes.

Use the mesh update() function after making a group of selection changes in order to make them visible to any modifiers on the object.

averageSelVertCenter <node> [ <modifier_or_index> ]

Returns the average position (center) of the selected vertices in the given mesh as a Point3. If the object is not a mesh this method returns undefined. If no vertices are selected in the mesh, a value of [0,0,0] is returned. This method is not applicable to TriMeshes.

The <modifier_or_index> argument is interpreted as for getVertSelection.

averageSelVertNormal <node> [ <modifier_or_index> ]

Returns the normalized average of the normals of the selected vertices in the given mesh as a Point3. If the given node is not a mesh, it returns undefined. If no vertices are selected in the mesh, or the averaged normal is [0,0,0], a value of [1,0,0] is returned. This method is not applicable to TriMeshes.

The <modifier_or_index> argument is interpreted as for getVertSelection.

The vertex normals used in this method do not consider smoothing group data of the faces that use the vertex.

Face Methods

getNumFaces <mesh>

Returns number of faces as an integer, equivalent to using <mesh>.numfaces

getFace <mesh> <face_index_integer>

Returns the face vertex indexes for the indexed face as a point3. Each component of the point3 value contains a vertex index.

setFace <mesh> <face_index_integer> <vert_indices_point3>

Sets the face vertex indexes for the indexed face from a point3.

setFace <mesh> <face_index_integer> <vert_index_integer> \

<vert_index_integer> <vert_index_integer>

Sets the face vertex indexes for the indexed face from 3 vertex indexes.

deleteFace <mesh> <face_index_integer>

Deletes indexed face from the mesh. Renumbers faces accordingly.

collapseFace <mesh> <face_index_integer>

Deletes indexed face from the mesh, welding its 3 vertices together at the center of the original face. Renumbers faces accordingly.

getFaceNormal <mesh> <face_index_integer>

Returns the normal of the indexed face as a point3.

setFaceNormal <mesh> <face_index_integer> <point3>

Sets the indexed face's normal vector. As soon as you run update() on the mesh, this value is overwritten.

getFaceMatID <mesh> <face_index_integer>

Returns the indexed face's material ID as an integer.

setFaceMatID <mesh> <face_index_integer> <integer>

Sets the indexed face's material ID.

getFaceSmoothGroup <mesh> <face_index_integer>

Returns the indexed face's smoothing groups as a 32-bit integer. There are 32 possible smoothing groups. Each bit in the returned value corresponds to a smoothing group. If a bit is turned on, the face is part of that smoothing group. You can retrieve the list of smoothing groups for a face as a BitArray using the following function:

fn getfacesmoothgroupB obj face =

(

local sgroup_val=getfacesmoothgroup obj face

local sg_bitarray=#{}

if sgroup_val < 0 do

(

sg_bitarray[32]=true

sgroup_val -= 2^31

)

for i = 1 to 31 do

(

sg_bitarray[i]= (mod sgroup_val 2 > .5)

sgroup_val /= 2

)

sg_bitarray

)

setFaceSmoothGroup <mesh> <face_index_integer> <smoothing_group_integer>

Sets the indexed face's smoothing groups. If you have a face's desired smoothing groups as a BitArray, you could set the face's smoothing group data using the following function:

fn setfacesmoothgroupB obj face sg_bitarray =

(

local sgroup_val=0

for i in sg_bitarray do sgroup_val += 2^(i-1)

setfacesmoothgroup obj face sgroup_val

update obj

)

getFaceSelection <node> [ <modifier_or_index> ] [ name:<name> ]

getFaceSelection <mesh>

Retrieves the face selection set, or the specified named selection set if the optional name: parameter is specified, as a BitArray. See the getVertSelection() method for more information.

setFaceSelection <node> [ <modifier_or_index> ]          \

( <sel_bitarray> | <sel_array> ) \

[ name:<name> ] [ keep:<boolean> ]

setFaceSelection <mesh> ( <sel_bitarray> | <sel_array> ) \

[ keep:<boolean> ]

Sets the face selections in an Editable Mesh base object, Mesh Select modifier, Edit Mesh modifier, or TriMesh. This mirrors the selection getting method above. See the setVertSelection() method for more information.

deselectHiddenFaces <mesh>

deselects the hidden faces in the mesh. This method is not applicable to TriMeshes.

extrudeFace <mesh> ( <index> | <bitarray> | <integer_array> | #selection ) \

<amount> <scale> \

[ dir:(<point3> | #common | #independent ) ]

Provides capabilities equivalent to the Extrude Face modifier. This function works only on Editable Mesh nodes. The second argument defines which faces to extrude, either a single face index, a BitArray of face indexes, an integer array of face indexes, or the name literal #selection meaning the current face selection in the Editable Mesh. The <amount> argument specifies the extrude distance and the <scale> specifies a % amount to scale each face cluster.

If the optional dir: keyword argument is not specified, face clusters are extruded by moving their vertices independently along the average normal at each vertex, as does the Extrude Face modifier. If it is specified, it can be a point3 giving a direction vector in which all vertices are moved, or it can be the value #independent which is the same as the default direction, or it can be the value #common which extrudes face clusters along the average normal of all the face normals in each cluster. #common is equivalent to the Group Normal option in EditableMesh, and #independent is equivalent to the Local Normal option. An example usage is:

s=sphere()

extrudeface s #{1..20} 10 100 dir:#independent

update s

meshop.getVertsUsingFace <Mesh mesh> <facelist>

Returns a bitarray of size=(#vertices in mesh) with bits set for all vertices that are used by the specified faces.

meshop.getEdgesUsingFace <Mesh mesh> <facelist>

Returns a bitarray of size=(#edges in mesh) with bits set for all edges that are used by the specified faces.

meshop.getPolysUsingFace <Mesh mesh> <facelist> ignoreVisEdges:<boolean=false> threshhold:<float=45.>

Returns a bitarray of size=(#faces in mesh) with bits set for all faces that are in 'polygons' containing the specified faces. The definition of a polygon is all faces sharing invisible edges with edge angles below the threshhold angle. The default threshhold angle is 45 degrees. If ignoreVisEdges is set to true, the edge visibility is ignored but the threshhold is still relevant.

meshop.autoSmooth <Mesh mesh> <facelist> <float threshold>

Smooths the specified faces based on the threshold angle.

meshop.unifyNormals <Mesh mesh> <facelist>

Unifies the normals of the specified faces.

meshop.flipNormals <Mesh mesh> <facelist>

Flips the normal of the specified faces.

<float> meshop.getFaceArea <Mesh mesh> <facelist>

Returns the area of the specified faces as a <float>.

Edge Methods

getEdgeVis <mesh> <face_index_integer> <edge_index_integer>

Returns the edge visibility for given edge (1,2,3) on indexed face as a boolean.

setEdgeVis <mesh> <face_index_integer> <edge_index_integer> <boolean>

Sets the edge visibility for given edge (1,2,3) on indexed face.

getEdgeSelection <node> [ <modifier_or_index> ] [ name:<name> ]

getEdgeSelection <mesh>

Retrieves the edge selection set, or the specified named selection set if the optional name: parameter is specified, as a BitArray. See the getVertSelection() method for more information.

setEdgeSelection <node> [ <modifier_or_index> ]          \

( <sel_bitarray> | <sel_array> ) \

[ name:<name> ] [ keep:<boolean> ]

setEdgeSelection <mesh> ( <sel_bitarray> | <sel_array> ) \

[ keep:<boolean> ]

Sets the edge selections in an Editable Mesh base object, Mesh Select modifier, Edit Mesh Modifier, or TriMesh. This mirrors the selection getting method above. See the setVertSelection() method for more information.

deselectHiddenEdges <mesh>

Deselects the hidden edges in the mesh. This method is not applicable to TriMeshes.

meshop.getVertsUsingEdge <Mesh mesh> <edgelist>

Returns a bitarray of size=(#vertices in mesh) with bits set for all vertices that are used by the specified edges.

meshop.getFacesUsingEdge <Mesh mesh> <edgelist>

Returns a bitarray of size=(#faces in mesh) with bits set for all faces that use the specified edges.

meshop.getPolysUsingEdge <Mesh mesh> <edgelist> ignoreVisEdges:<boolean=false> threshhold:<float=45.>

Returns a bitarray of size=(#faces in mesh) with bits set for all faces that are in 'polygons' containing the specified edges. The definition of a polygon is all faces sharing invisible edges with edge angles below the threshhold angle. The default threshhold angle is 45 degrees. If ignoreVisEdges is set to true, the edge visibility is ignored but the threshhold is still relevant.

meshop.getEdgesReverseEdge <Mesh mesh> <edgelist>

Returns a bitarray of size=(#edges in mesh) with bits set for all additional edges that use the same vertices as the specified edges. These are edges on the adjacent faces.

Example:

Plane length:100 width:100 isSelected:on

convertTo $ TriMeshGeometry

max modify mode

subobjectLevel = 1

select $.verts[13]

-- get edges that use vertex 13

edges = meshop.getEdgesUsingVert $ (getVertSelection $)

-- select the vertices used by those edges

$.selectedVerts = meshop.getVertsUsingEdge $ edges

update $

-- not what we wanted, really want all vertices "surrounding" vertex 13

faces = meshop.getPolysUsingVert $ 13

$.selectedVerts = meshop.getVertsUsingFace $ faces

update $

-- or ...

faces = meshop.getFacesUsingVert $ #(13)

edges = meshop.getEdgesUsingFace $ faces

-- turn off all visible edges

for e in edges do edges[e]=not (getEdgeVis $ (1+(e-1)/3)(1+mod (e-1) 3))

-- get the edges on the adjacent faces that are the "reverse" of these edges

-- "OR" that bitarray with the initial edges bitarray

edges = (meshop.getEdgesReverseEdge $ edges) + edges

-- get the faces that use the edges, and "OR" that bitarray with the initial

-- face bitarray

faces = (meshop.getFacesUsingEdge $ edges) + faces

$.selectedVerts = meshop.getVertsUsingFace $ faces

update $

meshop.autoEdge <Mesh mesh> <edgelist> <float threshold> type:<{#SetClear | #Set | #Clear}=#SetClear>

Sets/clears the edge visibility for the specified edges based on the threshold angle. Note: for an edge to be autoEdged, both it and the "reverse" edge on the face sharing the edge vertices must be specified in the edge specification.

Notes

3ds max defines an edge as the edge of a face. In any mesh object, the number of edges is 3 times the number of faces. A face has 3 vertices, and the face edges connect these vertices. Edges 1, 2, and 3 are the edges between vertices 1 and 2, 2 and 3, and 3 and 1, respectively. The first edge in a mesh is edge 1 on face 1, and the last edge is edge 3 on the last face. The following script selects all of the visible edges in the specified mesh:

EdgeSelSet=#()

for face = 1 to obj.numfaces do

for edge = 1 to 3 do

if (getedgevis obj face edge) then

append EdgeSelSet (((face-1)*3)+edge)

setedgeselection obj EdgeSelSet

update obj

The following function returns the indices of the 2 vertices that define an edge as a Point2 value. The two arguments to the function are a editable mesh node or TriMesh value and the edge index. A value of undefined is returned if the first argument isn't an editable mesh node or TriMesh value, or if the edge index is out of range.

fn edgeVerts theObj theEdge =

(

if not (classof theObj == Editable_mesh or

classof theObj == triMesh) do return undefined

if theEdge < 1 or theEdge > (theObj.numfaces*3) do return undefined

local theFace = ((theEdge-1)/3)+1

local theVerts = getFace theObj theFace

case ((mod (theEdge-1) 3) as integer) of

(

0: point2 theVerts.x theVerts.y

1: point2 theVerts.y theVerts.z

2: point2 theVerts.z theVerts.x

)

)

Texture Vertex Methods

getNumTVerts <mesh>

Returns number of texture vertices as an integer, equivalent to using <mesh>.numtverts

setNumTVerts <mesh> <number> [ <boolean> ]

Sets the number of texture vertices as specified. If the optional boolean argument is true, the existing topology remains intact. If it is false or not supplied, the topology is lost.

getTVert <mesh> <tvert_index_integer>

Returns the UVW coordinates of the indexed texture vertex

setTVert <mesh> <tvert_index_integer> ( <point3> | <x> <y> <z> )

Sets the UVW coordinates of the indexed texture vertex as a point3 value, or 3 floats - U,V,W

getTVFace <mesh> <face_index_integer>

setTVFace <mesh> <face_index_integer> <vert_indices_point3>

setTVFace <mesh> <face_index_integer> <tvert_index_integer> \

<tvert_index_integer> <tvert_index_integer>

The getTVFace() and setTVFace() functions mirror the getFace() and setFace() functions and are used to specify texture mapping topology in terms of texture vertices. You can set up and access texture vertices with the getTVert(), setTVert(), getNumTVerts(), and setNumTVerts() functions described above.

buildTVFaces <mesh> [ <boolean> ]

The buildTVFaces() function only needs to be called on meshes you are adding texture vertices to yourself to create the internal texture face array. Meshes that 3ds max applies mapping coordinates to maintain the TVFace array automatically. This is not done automatically when you add texture vertices to meshes yourself so you need to call buildTVFaces() explicitly whenever you change the texture vertex count, and before you construct the texture faces. If the optional boolean argument is true, the existing texture mapping remains intact. If it is false or not supplied, the existing texture mapping is lost (all texture faces are rebuilt, with all three vertices of the texture face using texture vertex 1).

numMapsUsed <mesh>

Returns the an upper limit on the number of texture map channels used by the given node. This is at least 1+(highest channel in use). This method is used so a script that does something to all map channels doesn't always have to do it to every channel up to 99 (the highest possible texture map channel), but rather only to this value. This method is not applicable to TriMeshes.

Notes

The mesh class contains a list of texture vertices which are completely independent of the regular vertices in the mesh. There is no correlation between the number of vertices in a mesh and the number of texture vertices. In addition to the texture vertices there are also texture faces. There needs to be one texture face for every regular face in the mesh.

Each texture face has three indices into the texture vertex array. The coordinates of a texture vertex are UVW coordinates, and are accessed as Point3 values. The 3 components are U, V, and W, and each component value is in the range of 0 to 1. An example script for creating planar texture mapping on an object is shown in Working with Editable Meshes.

The texture vertex methods do not support multiple mapping channels in 3ds max 4.

Color-Per-Vertex Methods

getNumCPVVerts <mesh>

Returns number of color-per-vertex vertices as an integer, equivalent to using <node>.numcpvverts

setNumCPVVerts <mesh> <integer> [ <boolean> ]

Sets the number of c-p-v vertices. If the optional boolean argument is true, the existing topology remains intact. If it is false or not supplied, the topology is lost.

buildVCFaces <mesh> [ <boolean> ]

Builds the c-p-v face array after you have set the c-p-v vertex count. If the optional boolean argument is true, the existing topology remains intact. If it is false or not supplied, the topology is lost.

defaultVCFaces <mesh>

Sets the number of c-p-v vertices and c-p-v faces to match exactly the current mesh's geometry and topology and calls buildVCFaces()

getVertColor <mesh> <CPVvert_index_integer>

Returns the color of the indexed c-p-v vertex as a color

getVCFace <mesh> <CPVface_index_integer>

Returns the topology for the indexed c-p-v face as a point3 containing 3 c-p-v vertex indexes

setVCFace <mesh> <CPVface_index_integer> <CPVvert_indices_point3>

Sets the indexed c-p-v face topology from a point3 containing 3 c-p-v vertex indexes

setVCFace <mesh> <CPVface_index_integer> <CPVvert_index_integer> \

<CPVvert_index_integer> <CPVvert_index_integer>

Sets the indexed c-p-v face topology from 3 c-p-v vertex index number arguments

The c-p-v vertex and face indexes are 1-based as with other mesh indexes in MAXScript. Remember that you need to call update() on the mesh after making changes to it for the changes to be reflected in the scene.

Notes

The mesh class contains a list of color vertices which are completely independent of the regular vertices in the mesh. There is no correlation between the number of vertices in a mesh and the number of color vertices. In addition to the color vertices there are also color faces. There needs to be one color face for every regular face in the mesh.

Each color face has three indices into the color vertex array. The coordinates of a color vertex are RGB coordinates, and are accessed as Color values.

The techniques for building and accessing color vertices and faces is virtually identical to the techniques for building and accessing texture vertices and faces. An example script for creating planar texture mapping on an object is shown in Working with Editable Meshes.

Subdivision Displacement Surface Properties Methods

The following methods set the Subdivision Displacement Surface Properties for a mesh object. These methods are not applicable to TriMeshes.

setSplitMesh <mesh> <boolean>

Turns on or off split mesh subdivision displacement for the mesh. Calling this function will enable subdivisionDisplacement if it is set to false.

getSplitMesh <mesh>

Returns true if split mesh subdivision displacement is turned on for the mesh, false otherwise.

setSubdivisionDisplacement <mesh> <boolean>

Turns on or off subdivision displacement for the mesh.

getSubdivisionDisplacement <mesh>

Returns true if subdivision displacement is turned on for the mesh, false if off.

displacementToPreset <mesh> ( #low | #medium | #high )

Sets the mesh subdivision parameters to the specified preset value set.

setDisplacementMapping <mesh> <boolean>

Turns on or off whether to perform displacement mapping for the mesh. There is no corresponding user interface element for this method.

getDisplacementMapping <mesh>

Returns true if displacement mapping is turned on for the mesh, false if off.

Editable Mesh Modify Panel Command Modes and Operations

A suite of methods provide the ability for a script to invoke Editable Mesh and Edit Mesh Modify panel modes and operations, corresponding to buttons available at various mesh sub-object levels. These methods reside in the meshOps global structure. These methods effectively "push the button" in the 3ds max Modify panel. In order to use these methods, the node must be selected and the Modify panel open. In the description of these methods, the first argument <editable_mesh_node_or_modifier> should be interpreted as either an Editable Mesh node where the modifier stack level is at the base object, or an Edit Mesh modifier where the modifier stack level is at the Edit Mesh. In all cases, the following methods work at the current sub-object level, but only if that level is appropriate for the invoked operation.

If you have made scripted changes to the mesh you must call the update() method on the mesh before calling these methods. You do not need to call update() after just calling one of these methods, as 3ds max will take care of updating the mesh.

The follow methods invoke one of the 'user-interaction' button operations in the Editable Mesh Modify panel, acting on the currently selected sub-objects. These methods highlight the corresponding button in the Edit Geometry rollout and start the operation, at which point the user interactively completes the operation. These methods return after starting the operation, and before the user completes the operation, so care should be taken to ensure that your script does not interfere with the operation. Invoking any of these methods is the same as clicking on the associated button in the Modify panel. Calling a method when the operation is already in effect (either due to a user action or a MAXScript command) causes the operation to be terminated and the highlight is removed from the button.

meshOps.startAttach <editable_mesh_node_or_modifier>

Enters "Attach" command mode - valid in Vertex, Face, Polygon, and Element Sub-Object levels, and when not in Sub-Object mode.

meshOps.startBevel <editable_mesh_node_or_modifier>

Enters "Bevel" command mode - valid in Edge, Face, Polygon, and Element Sub-Object levels.

meshOps.startChamfer <editable_mesh_node_or_modifier>

Enters "Chamfer" command mode - valid in Vertex and Edge Sub-Object levels.

meshOps.startCreate <editable_mesh_node_or_modifier>

Enters "Create" command mode, valid in Vertex, Face, Polygon, and Element Sub-Object levels.

meshOps.startCut <editable_mesh_node_or_modifier>

Enters "Cut" command mode - valid in Edge, Face, Polygon, and Element Sub-Object levels.

meshOps.startDivide <editable_mesh_node_or_modifier>

Divides selected edges into 2 edges, for selected face into 3 faces - valid in Edge, Face, Polygon, and Element Sub-Object levels.

meshOps.startExtrude <editable_mesh_node_or_modifier>

Enters "Extrude" command mode - valid in Face, Polygon, and Element Sub-Object levels.

meshOps.startFlipNormalMode <editable_mesh_node_or_modifier>

Enters "Flip Normal" command mode - valid in Face, Polygon, and Element Sub-Object levels.

meshOps.startSlicePlane <editable_mesh_node_or_modifier>

Enters "Slice Plane" command mode - valid in all Sub-Object levels, and when not in Sub-Object mode.

meshOps.startTurn <editable_mesh_node_or_modifier>

Enters "Turn " command mode - valid in Edge Sub-Object level.

meshOps.startWeldTarget <editable_mesh_node_or_modifier>

Enters "Weld Target " command mode - valid in Vertex Sub-Object level.

The following methods invoke one of the 'instantaneous' button operations in the Editable Mesh Modify panel, acting on the currently selected sub-objects:

meshOps.autoEdge <editable_mesh_node_or_modifier>

Automatically sets the edge visibility on the selected sub-objects - valid in Edge Sub-Object level.

meshOps.break <editable_mesh_node_or_modifier>

Creates a new vertex for each face attached to the selected sub-objects - valid in Vertex Sub-Object level.

meshOps.collapse <editable_mesh_node_or_modifier>

Collapses the selected sub-objects - valid in Vertex, Edge, Face, Polygon, and Element Sub-Object levels.

meshOps.createShapeFromEdges <editable_mesh_node_or_modifier>

Displays Create Shape dialog allowing the user to specify an object name, shape type, and whether to ignore hidden edges. Valid in Edge Sub-Object level.

meshOps.delete <editable_mesh_node_or_modifier>

Deletes the selected sub-objects - valid in Vertex, Face, Polygon, and Element Sub-Object levels.

meshOps.detach <editable_mesh_node_or_modifier>

Displays Detach dialog allowing the user to specify an object name or to detach as element, and whether to clone the selected subobjects. Valid in Vertex, Face, Polygon, and Element Sub-Object levels.

meshOps.explode <editable_mesh_node_or_modifier>

Displays Explode to Objects dialog allowing the user to specify an object name. Explodes the selected faces into multiple elements or objects based on the angles of its edges. Valid in Vertex, Face, Polygon, and Element Sub-Object levels.

meshOps.flipNormal <editable_mesh_node_or_modifier>

Flips the normal of the selected faces - valid in Face, Polygon, and Element Sub-Object levels.

meshOps.gridAlign <editable_mesh_node_or_modifier>

Aligns the selected sub-objects to the construction plane - valid in Vertex, Edge, Face, Polygon, and Element Sub-Object levels.

meshOps.hide <editable_mesh_node_or_modifier>

Hides the selected sub-objects - valid in Vertex, Face, Polygon, and Element Sub-Object levels.

meshOps.invisibleEdge <editable_mesh_node_or_modifier>

Sets selected edges invisible. Valid in Vertex Sub-Object level.

meshOps.makePlanar <editable_mesh_node_or_modifier>

Forces all selected sub-objects to become coplanar - valid in Vertex, Edge, Face, Polygon, and Element Sub-Object levels.

meshOps.removeIsolatedVerts <editable_mesh_node_or_modifier>

Deletes all isolated vertices in the object regardless of the current selection.

meshOps.selectOpenEdges <editable_mesh_node_or_modifier>

Selects all edges with only one face. Valid in Edge Sub-Object level.

meshOps.slice <editable_mesh_node_or_modifier>

Subdivides edges and faces based on Slice Plane. meshOps.startSlicePlane() must be called to enter the "Slice Plane" command mode before slice is valid. Valid in all Sub-Object levels, and when not in Sub-Object mode.

meshOps.tessellate <editable_mesh_node_or_modifier>

Tessellates the selected sub-objects - valid in Face, Polygon, and Element Sub-Object levels.

meshOps.unhideAll <editable_mesh_node_or_modifier>

Unhides the hidden sub-objects at the current Sub-Object level - valid in Vertex, Face, Polygon, and Element Sub-Object levels.

meshOps.unifyNormal <editable_mesh_node_or_modifier>

Unifies the normals of the selected faces - valid in Face, Polygon, and Element Sub-Object levels.

meshOps.viewAlign <editable_mesh_node_or_modifier>

Aligns all selected sub-objects to the 0,0,0 plane of the active viewport - valid in Vertex, Edge, Face, Polygon, and Element Sub-Object levels.

meshOps.visibleEdge <editable_mesh_node_or_modifier>

Sets selected edges visible. Valid in Edge Sub-Object level.

meshOps.weld <editable_mesh_node_or_modifier>

Welds the selected vertices - valid in Vertex Sub-Object level.

The meshOps methods depend on the Modify panel being open and the desired object, either an Editable Mesh base object or Edit Mesh modifier, being currently open in the panel. The meshOps methods do not perform any operation if these conditions aren't met. You will need to use MAXScript functions like max modify mode or setCommandPanelTaskMode mode:#modify to open the Modify panel, select <obj> to select the object, subObjectLevel = <n> to set the Sub-Object level, and modPanel.setCurrentObject <obj_or_modifier> to establish the right context for the new functions to operate. For example:

Example:

s=sphere() -- create a sphere

ConvertToMesh s             -- convert to an Editable Mesh

s.selectedfaces=#{1..112}   -- select half the faces

max modify mode             -- open the Modify panel

select s                    -- select the sphere

modPanel.setCurrentObject sùset modifier stack to the base object

-- (not really needed in this example)

subObjectLevel = 4          -- set Sub-Object level to polygon

meshOps.startExtrude s      -- start the face extrude command mode,

-- highlighting its button in the Edit

-- Geometry rollout, at which point the

-- user interactively performs the extrude.

Another example is:

meshOps.Hide (modPanel.getCurrentObject())

which would invoke the Hide button operation on the current object open in the Modify panel if it was an Edit Mesh modifier or Editable Mesh base object.