The as.mesh3d generic function converts various objects to mesh3d objects.

The default method takes takes a matrix of vertices as input and (optionally) merges repeated vertices, producing a mesh3d object as output. It will contain either triangles or quads or segments or points according to the type argument.

If the generic is called without any argument, it will pass all RGL ids from the current scene to the as.mesh3d.rglId method.

as.mesh3d(x, ...)
# S3 method for default
as.mesh3d(x, y = NULL, z = NULL, 
             type = c("triangles", "quads", "segments", "points"),
             smooth = FALSE, 
             tolerance = sqrt(.Machine$double.eps), 
             notEqual = NULL, 
             merge = TRUE,
             ...,
             triangles)

Arguments

x, y, z

For the generic, x is the object to convert. For the default method, x, y and z are coordinates. Any reasonable way of defining the coordinates is acceptable. See the function xyz.coords for details.

type

What type of things should be in the mesh? Tries this list in order until it finds one that works.

smooth

If TRUE, addNormals will be called on the mesh object to make it render smoothly.

tolerance

The numerical tolerance to be used in all.equal to determine whether two vertices should be merged.

notEqual

If not NULL, an n by n matrix of logical values, where n is the number of vertices as input. TRUE entries indicate that the corresponding pair of vertices should not be merged even if they appear equal.

merge

Should apparently equal vertices be merged?

...

Material properties to pass to tmesh3d or qmesh3d.

triangles

Deprecated. If present, TRUE indicates type = "triangles" and FALSE indicates type = "quads".

Details

The motivation for this function is the following problem: I was asked whether RGL could render a surface made up of triangles or quadrilaterals to look smooth. It can do that, but needs normals at each vertex; they should be the average of the normals for each polygon sharing that vertex. Then OpenGL will interpolate the normals across the polygons and give the illusion of smoothness.

To do this, it needs to know which polygons share each vertex. If the surface is described as a list of triangles or quadrilaterals, that means identifying vertices that are in multiple polygons, and converting the representation to a "mesh3d" object (which is a matrix of vertices and a matrix of vertex numbers making up triangles or quads). Then the addNormals function will add the normals.

Sometimes two polygons will share vertices (within numerical tolerance) without the user wanting them to be considered internal to the surface, or might want one sharp edge in an otherwise smooth surface. This means I needed a way to declare that two vertices from the original list of vertices in the triangles or quads are "not equal", even when they test numerically equal. That's what the notEqual matrix specifies.

Value

A "mesh3d" object with the same faces as in the input, but (if merge=TRUE) with vertices that test equal to within tolerance merged.

Author

Duncan Murdoch

Examples

xyz <- matrix(c(-1, -1, -1,
                -1,  1, -1,
                 1,  1, -1,
                 1, -1, -1,
                -1,  1, -1,
                -1,  1,  1,
                 1,  1,  1,
                 1,  1, -1,
                 1, -1, -1,
                 1,  1, -1,
                 1,  1,  1,
                 1, -1,  1), byrow = TRUE, ncol = 3)
mesh <- as.mesh3d(xyz, type = "quads", col = "red")
mesh$vb
#>      [,1] [,2] [,3] [,4] [,5] [,6] [,7]
#> [1,]   -1   -1    1    1   -1    1    1
#> [2,]   -1    1    1   -1    1    1   -1
#> [3,]   -1   -1   -1   -1    1    1    1
#> [4,]    1    1    1    1    1    1    1
mesh$ib
#>      [,1] [,2] [,3]
#> [1,]    1    2    4
#> [2,]    2    5    3
#> [3,]    3    6    6
#> [4,]    4    3    7
open3d()
shade3d(mesh)



# Stop vertices 2 and 5 from being merged
notEQ <- matrix(FALSE, 12, 12)
notEQ[2, 5] <- TRUE
mesh <- as.mesh3d(xyz, type = "quads", notEqual = notEQ)
mesh$vb
#>      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8]
#> [1,]   -1   -1    1    1   -1   -1    1    1
#> [2,]   -1    1    1   -1    1    1    1   -1
#> [3,]   -1   -1   -1   -1   -1    1    1    1
#> [4,]    1    1    1    1    1    1    1    1
mesh$ib
#>      [,1] [,2] [,3]
#> [1,]    1    5    4
#> [2,]    2    6    3
#> [3,]    3    7    7
#> [4,]    4    3    8