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

<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

<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

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

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

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

NOTE:This 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

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

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

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

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

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

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

See Also