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

# Meshop Face Methods

| Editable Mesh - Quick Navigation

The following methods exposed by the meshOp Struct provide advanced access to the mesh faces.

Topic Navigation: |
--- | ---
Face Number Get Face Info Delete Faces Hidden Faces Bevel Extrude Clone Collapse and Detach Faces Divide Faces | Explode Faces Get A Using B Flip and Unify Normals Make Planar AutoSmooth Faces

Methods:

## Face Number

| Back To Topic Navigation |  | Editable Mesh - Quick Navigation

    <integer>meshop.getNumFaces <Mesh mesh>

Returns the number of faces in the mesh.

    meshop.setNumFaces <Mesh mesh> <int>

Sets the number of faces in the mesh.

## Get Face Info

| Back To Topic Navigation |  | Editable Mesh - Quick Navigation

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

Returns the area of the specified faces as a float.

FOR EXAMPLE
    --Select all faces with area smaller than 20.0
    obj = sphere radius:20 --create a Sphere
    convertToMesh obj --collapse to EditableMesh
    faceSel= #() --init. an array
    --Loop through all faces in the mesh,
    --compare the face area to the threshold and
    --append the face to the array to be selected
    for f = 1 to obj.numfaces do
    if meshop.getFaceArea obj #{f} < 20.0 then
    append faceSel f
    setFaceSelection obj faceSel --select all collected faces
    update obj --update the mesh
    max modify mode --switch to modify mode
    select obj --select the mesh
    subObjectLevel = 3 --switch to face sub-object level

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

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

Returns the center of the specified face. The face center is the average of the face's three vertex coordinates.

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.

## Delete Faces

| Back To Topic Navigation |  | Editable Mesh - Quick Navigation

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

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

EXAMPLE
    obj = geosphere() --create a GeoSphere
    convertToMesh obj --collapse to EditableMesh
    --Delete all faces in the mesh but leave the vertices:
    meshop.deleteFaces obj #{1..obj.numfaces} delIsoVerts:false
    update obj --update the mesh
    max modify mode --switch to modify mode
    select obj --select the mesh
    SubObjectLevel = 1 --switch to vertex level to see the vertices

    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.

## Hidden Faces

| Back To Topic Navigation |  | Editable Mesh - Quick Navigation

    meshop.setHiddenFaces <Mesh mesh> <facelist>

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

    meshop.getHiddenFaces <Mesh mesh>

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

## Bevel, Extrude, Clone, Collapse and Detach Faces

| Back To Topic Navigation |  | Editable Mesh - Quick Navigation

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

NoteThis method does not correspond to the Bevel functionality in the EditableMesh UI. It moves and outlines faces without creating new faces. See meshop.ExtrudeFaces further on this page for the corresponding method that creates new beveled faces.

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

EXAMPLE
    obj = geosphere() --create a GeoSphere
    convertToMesh obj --collapse to Editable_Mesh
    --Loop from half the face count back to 1.
    --Since ExtrudeFaces creates new faces, counting backwards
    --ensures the loop will go only through the original faces:
    for f = obj.numfaces/2 to 1 by -1 do
    meshop.extrudeFaces obj #{f} 5.0 -1.0 --extrude the single face
    update obj --update the mesh

    meshop.cloneFaces <Mesh mesh> <facelist>

Clones the specified faces.

EXAMPLE
    obj = geosphere() --create a GeoSphere
    convertToMesh obj --collapse to EditableMesh
    --Clone half of the faces - they get selected automatically:
    meshop.cloneFaces obj #{1..obj.numfaces/2}
    --Offset the selected Faces at 20 units along their local normals
    meshop.bevelFaces obj (getFaceSelection obj) 20 0 dir:#independent
    update obj--update the mesh

    meshop.collapseFaces <Mesh mesh> <facelist>

Collapses the specified faces.

EXAMPLE
    obj = geosphere() --create a GeoSphere
    convertToMesh obj --collapse to EditableMesh
    --Collapse half the faces:
    meshop.collapseFaces obj #{1..obj.numfaces/2}
    update obj --update the mesh

    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.

EXAMPLE
    --Let's detach faces as element inside the original mesh:
    obj = geosphere pos:[100,0,0] --create a GeoSphere
    convertToMesh obj --collapse to EditableMesh
    --Detach half of the faces as element, delete the originalfaces
    meshop.detachFaces obj #{1..obj.numfaces/2} delete:true
    update obj --update the mesh
    --In this example, the same mesh will be detached as a separate object
    obj = geosphere pos:[0,0,0] --create another GeoSphere
    convertToMesh obj --collapse to EditableMesh
    -- Detach the faces as Mesh and
    --get the resulting TriMesh in a variable:
    newMesh = meshop.detachFaces obj #{1..obj.numfaces/2} delete:true asMesh:true
    update obj --update the mesh
    emesh = Editable_mesh() --create an empty Editable_mesh
    emesh.mesh = newMesh --assign the detached faces to the new mesh
    update emesh --update the mesh

## Divide Faces

| Back To Topic Navigation |  | Editable Mesh - Quick Navigation

    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.

See also BarycentricCoordinates

EXAMPLE
    obj = plane() --create a plane
    convertToMesh obj --collapse to Editable_Mesh
    --Loop backwards through all original faces.
    --This will ignore any new faces added to the face array
    for f = obj.numfaces to 1 by -1 do
    meshop.divideFace obj f barycoord:[0.1,0.1,0.5] --divide the face
    update obj --update the mesh
    --Note that if the sum of the barycentric coordinates' components is not
    --equal to 1.0, the values will be scaled proportionally. Thus the above
    --coordinates are equivalent to [0.142857,0.142857,0.714285].

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

EXAMPLE
    obj = plane lengthsegs:1 widthsegs:1 --create a simple plane of 2 faces
    convertToMesh obj --collapse to Editable_mesh
    obj.allEdges = true --show all edges
    --Divide face 1 connecting edges 2 and 3 at 0.25 resp. 0.75 along
    --their length. This gives a new edge parallel to edge 1
    meshop.divideFaceByEdges obj 1 2 0.25 3 0.75
    update obj --update the mesh

    meshop.divideFaces <Mesh mesh> <facelist>

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

EXAMPLE
    --The following code does the same as Tessellate in Face-Center mode
    obj = plane() --create a plane
    convertToMesh obj --collapse to Editable_Mesh
    --Divide all faces by placing a new vertex at the face center:
    meshop.divideFaces obj #{1..obj.numfaces}
    update obj --update the mesh

## Explode Faces

| Back To Topic Navigation |  | Editable Mesh - Quick Navigation

    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.

WARNING!
The float threshold parameter is currently expected in radians!

EXAMPLE
    obj = geosphere() --create a GeoSphere
    convertToMesh obj --collapse to EditableMesh
    --Explode all faces in the mesh to elements, disregarding the angle:
    meshop.explodeAllFaces obj 0
    update obj --update the mesh

    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.

EXAMPLE
    obj = geosphere() --create a GeoSphere
    convertToMesh obj --collapse to EditableMesh
    --Explode half of the faces regardless the angle
    meshop.explodeFaces obj #{1..obj.numfaces/2} 0
    --Move the exploded faces (selected by the explodeFaces method)
    --along their normals at 10 units without outline:
    meshop.bevelFaces obj (getFaceSelection obj) 10 0 dir:#independent
    update obj --update the mesh

## Get A Using B

| Back To Topic Navigation |  | Editable Mesh - Quick Navigation

    meshop.getVertsUsingFace <Mesh mesh> <facelist>

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

SCRIPT
    macroScript Face2VertSel category:"MXS Help"
    (
    --make sure a single EMesh object is selected
    on isEnabled return
    selection.count == 1 and classof selection[1] == Editable_Mesh
    on execute do
    (
    obj = selection[1]--get selected object
    faceSel = getFaceSelection obj--get selected Faces
    --get Verts of selected Faces:
    vertsSel = meshop.getVertsUsedFace obj faceSel
    setVertSelection obj vertsSel --select the Verts
    update obj --update the mesh
    max modify mode--switch to Modify panel
    subObjectLevel = 1--set Vertex SO level
    )
    ) --end macro

Note

A common mistake would be to pass an array with a single face to meshop.getVertsUsingFace() and to assume that the result converted to an array is the definition of the face (all its vertices).

This would be the case only in the special case where the face definition happens to have the vertex indices in ascending order. This is because the return value is a bitarray where the indices are always sorted in ascending order.

For example, it a face definition is [4,6,9], the assumption would be correct. But if the face definition was [6,9,4], the result of meshop.getVertsUsingFace() converted to array would be #(4,6,9) and would not match. Any operations requiring the correct vertex order, for example those involving calculations with barycentric coordinates would turn out incorrect.

The correct approach for getting the three vertices of a face in the correct order is by calling getFace() and accessing the .x, .y and .z components of the returned Point3 value.

    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.

SCRIPT
    macroScript Face2EdgeSel category:"MXS Help"
    (
    --make sure a single EMesh object is selected
    on isEnabled return
    selection.count == 1 and classof selection[1] == Editable_Mesh
    on execute do
    (
    obj = selection[1] --get selected object
    faceSel = getFaceSelection obj --get selected Faces
    --get Edges of selected Faces:
    edgeSel = meshop.getEdgesUsingFace obj faceSel
    setEdgeSelection obj edgeSel --select the edges
    update obj --update the mesh
    max modify mode --switch to Modify panel
    subObjectLevel = 2 --set Edge SO level
    )
    ) --end macro

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

Returns a bitarray of size=(#faces inmesh) 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.getFacesUsingVert <Mesh mesh> <vertlist>

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

EXAMPLE
    obj =Sphere() --create a Sphere
    convertToMesh obj --collapse to EditableMesh
    --Get the faces used by the first vertex (north pole)
    verts= meshop.getFacesUsingVert obj #{1}
    --Add the faces used by the last vertex (south pole)
    verts+= meshop.getFacesUsingVert obj #{obj.numverts}
    --Select the faces used by both pole vertices
    setFaceSelectionobjverts
    update obj --update the mesh
    max modify mode --switch to modify mode
    select obj --select the mesh
    subObjectLevel = 3 --switch to face sub-object level

SCRIPT
    macroScript Vert2FaceSel category:"MXS Help"
    (
    --make sure a single EMesh object is selected
    on isEnabled return
    selection.count == 1 and classof selection[1] == Editable_Mesh
    on execute do
    (
    obj = selection[1] --get selected object
    vertSel = getVertSelection obj --get selected Vertices
    --get Faces of selected Verts:
    faceSel = meshop.getFacesUsingVert obj vertSel
    setFaceSelection obj vertsSel --select the Faces
    update obj --update the mesh
    max modify mode --switch to Modify panel
    subObjectLevel =3 --set Face SO level
    )
    ) --end macro

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

Returns a bitarray of size=(#faces inmesh) 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.getVertsUsedOnlyByFaces <Mesh mesh> <facelist>

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

## Flip and Unify Normals

| Back To Topic Navigation |  | Editable Mesh - Quick Navigation

    meshop.unifyNormals <Mesh mesh> <facelist>

Unifies the normals of the specified faces.

    meshop.flipNormals <Mesh mesh> <facelist>

Flips the normal of the specified faces.

FOR EXAMPLE
    obj =sphere() --create a Sphere
    convertToMesh obj --collapse to EditableMesh
    --Flip the normals of the top half of the faces:
    meshop.flipNormals obj #{1..obj.numfaces/2}
    update obj --update the mesh

## Make Planar

| Back To Topic Navigation |  | Editable Mesh - Quick Navigation

    meshop.makeFacesPlanar <Mesh mesh> <facelist>

Moves the specified faces so that they are planar.

EXAMPLE
    obj = sphere()
    convertToMesh obj
    --make the faces of the top half of the sphere planar:
    meshop.makeFacesPlanar obj #{1..obj.numfaces/2.0}
    update obj

## AutoSmooth Faces

| Back To Topic Navigation |  | Editable Mesh - Quick Navigation

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

Smooths the specified faces based on the threshold angle.

FOR EXAMPLE
    obj =geosphere() --create a GeoSphere
    convertToMesh obj --collapse to EditableMesh
    --Smooth half of the faces:
    meshop.autoSmooth obj #{obj.numfaces/2..obj.numfaces} 0.0
    update obj --update the mesh

For more mesh-related methods, see

Editable Mesh - Topics Index

Editable_Mesh : GeometryClass and TriMesh : Value

| Back To Topic Navigation |  | Editable Mesh - Quick Navigation

#### See Also

- Face Methods

- Mesh Methods (meshop struct)

- Face Methods

- Mesh Methods (meshop struct)