MAXScript Language Reference > 3ds Max Objects > Editable Meshes, Splines, Patches, and Polys > Editable_Mesh and TriMesh >

# Editable_Mesh : GeometryClass and TriMesh : Value

| Editable Mesh - Quick Navigation

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.

Note

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.

Coordinates are given in the MAXScript working coordinate system.

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.

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)

    editable_mesh...

Creates an empty 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 [ mesh:<TriMesh>]

Creates a mesh using the specified TriMesh value as the mesh source.

    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:

EXAMPLE
    mesh vertices:#([0,0,0],[10,0,0],[0,10,0],[10,10,0]) \
    faces:#([1,2,3],[2,4,3]) materialIDS:#(1,2)

NoteThe optional tverts array feature is currently broken. The texture vertices are set correctly, but no texture faces are built internally. Until this gets fixed, you can work around by building the texture faces yourself:

WORKAROUND EXAMPLE:
    mnode = mesh vertices:#([0,0,0],[10,0,0],[0,10,0],[10,10,0]) tverts:#([0,0,0],[10,0,0],[0,10,0],[10,10,0]) faces:#([1,2,3],[2,4,3])
    mmesh = mnode.mesh
    buildTVFaces mmesh
    for i = 1 to mmesh.numfacesdo(setTVFace mmesh i (getFace mmesh i))

    collapseStack <node> -- mapped

Collapses the object space modifiers out of a stack, leaving a resultant base object corresponding to the evaluation result on top of the node(s)' stack. This means that the result will be Editable_Meshonly if the result on top of the stack is Editable_Mesh. Some modifiers convert the object class implicitly, for example a Box with MeshSmooth on top will collapse to Editable_Poly because MeshSmooth implicitly converts the incoming geometry topolygons. Adding a MeshSelector a TurnToMesh modifier on top of the MeshSmooth modifier and then calling collapseStack() will results in an Editable_Mesh base object.

EXAMPLE
    b = box() --create a box
    $Box:Box01 @ [0.000000,0.000000,0.000000]
    addModifier b (MeshSmooth()) --add meshSmooth modifier
    OK
    classof b --check the class - it was turned into Polygons!
    PolyMeshObject
    collapseStack b --collapse the stack of the box
    OK
    classof b --the result is Editable_Poly
    Editable_Poly
    addModifier b (Turn_To_Mesh()) --now add Turn To Mesh modifier
    OK
    classof b --the class is now Editable_Mesh and not Editable_Poly!
    Editable_mesh
    collapseStack b --collapse the stack
    OK
    classof b --as expected, the result is an Editable_Mesh!
    Editable_mesh

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:

EXAMPLE
    b = box() --create a box
    $Box:Box03 @ [0.000000,0.000000,0.000000]
    collapseStack b --try to collapse the stack
    OK
    classof b --it is still a box - nothing to collapse!
    Box
    addModifier b (meshSelect()) --add a MeshSelect modifier
    OK
    collapseStack b --try to collapse the stack again
    OK
    classof b --this time it worked!
    Editable_mesh

collapseStack() does not collapse the effect of any world space modifiers (including bindings to SpaceWarps). The world space modifiers remain on the object's stack. To collapse an object with world space modifiers 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.

Note 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. When setting the number of vertices using the numVerts property or the setNumVerts method, the new vertices are initialized to [0.,0.,0.]

    <mesh>.numfaces Integer

Get or set the number of faces

In versions prior 3ds Max 7, the user was responsible for re-initializing the mesh to make it valid before calling update. In 3ds Max 7 and higher, the re-initializing is performed automatically when setting the .numfaces value or calling the setNumFaces function.

Note

    $.numfaces=300
    --is equivalent to
    setNumFaces $ 300 false
    --The falseargumentmeans tonot keep the existing topology

For all new faces, the following occurs:

- Smoothing group set to 1

- Vertices are set to [1,1,1] (1-based, if # verts is 0 at update, you will crash. It is expected at this point)

- Material ID is set to 1 (1-based)

- For each map channel in use:

- - the map face verts are set to [1,1,1]

  - if keep is false, the number of map verts is set to 1 its verts are set to [1,1,1] (1-based)

    <mesh>.numtverts Integer

Get or set the number of texture vertices. When setting the number of texture vertices using the numTVerts property or setNumTVerts method, the new verts are initialized to [0.,0.,0.]

    <mesh>.numcpvverts Integer

Get or set the number of color-per-vertex vertices. When setting the number of CPV vertices using the numCPTVerts property or setNumCPVVerts method, the new verts are initialized to [0.,0.,0.]

    <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.

NoteThe 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.

EXAMPLE
    meshop.attach $.baseobject $sphere02 targetNode:$
    meshop.attach $box01 $box02 attachMat:#IDToMat \
    condenseMat:true deleteSourceNode:false

    meshopgetUIParam. <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)

Further Mesh-Related Topics:

Vertex Methods

Vertex Methods (meshop struct)

Vertex Data Methods (meshop struct)

Edge Methods

Edge Methods (meshop struct)

Face Methods

Face Methods (meshop struct)

Mesh Methods (meshop struct)

Mapping Methods - General (meshop struct)

Texture Vertex Methods

Color-Per-Vertex Methods

Subdivision Displacement Surface Properties Methods

Editable Mesh UI Property Methods (meshop struct)

Editable Mesh Modify Panel Command Modes and Operations (meshOps struct)

#### See Also

- Node Common Properties, Operators, and Methods

- MAXWrapper Common Properties, Operators, and Methods

- Value Common Properties, Operators, and Methods

- Class and Object Inspector Functions

- Scripting Vertex and Control Point Animation