# clipMesh3d

##### Clip mesh to general region

Modifies a mesh3d object so that values of a function are bounded.

##### Usage

```
clipMesh3d(mesh, fn, bound = 0, greater = TRUE,
attribute = "vertices")
```

##### Arguments

- mesh
A

`mesh3d`

object.- fn
A function used to determine clipping, or a vector of values from such a function, with one value per vertex in the mesh.

- bound
The value(s) of

`fn`

on the clipping boundary.- greater
Logical; whether to keep

`fn >= bound`

or not.- attribute
Which attribute(s) to pass to

`fn`

? Possible values are`c("vertices", "normals", "texcoords", "index")`

.

##### Details

This function transforms a mesh3d object.

First, all quads are converted to triangles.

Next, each vertex is checked against the condition. If `fn`

is a numeric vector, with one value per vertex, those values will be
used in the test.
If it is a function, it will be passed a matrix, whose columns are
the specified attribute(s), with one row per vertex. It should return
a vector of values, one per vertex, to check against the bound.
The `"vertices"`

and `"normals"`

values will be converted to
Euclidean coordinates. `"index"`

will be an integer from 1
to the number of vertices.

Modifications to the triangles depend
on how many of the vertices satisfy the condition
(`fn >= bound`

or `fn <= bound`

, depending on `greater`

)
for inclusion.

If no vertices in a triangle satisfy the condition, the triangle is omitted.

If one vertex satisfies the condition, the other two vertices in that triangle are shrunk towards it by assuming

`fn`

is locally linear.If two vertices satisfy the condition, the third vertex is shrunk along each edge towards each other vertex, forming a quadrilateral made of two new triangles.

If all vertices satisfy the condition, they are included with no modifications.

##### Value

A new mesh3d object in which all vertices (approximately) satisfy the clipping condition. Note that the order of vertices will likely differ from the original order, and new vertices will be added near the boundary.

##### References

See https://stackoverflow.com/q/56242470/2554330 for the motivating example.

##### Examples

```
# NOT RUN {
if (requireNamespace("misc3d")) {
# Togliatti surface equation: f(x,y,z) = 0
# Due to Stephane Laurent
f <- function(x,y,z){
w <- 1
64*(x-w)*
(x^4-4*x^3*w-10*x^2*y^2-4*x^2*w^2+16*x*w^3-20*x*y^2*w+5*y^4+16*w^4-20*y^2*w^2) -
5*sqrt(5-sqrt(5))*(2*z-sqrt(5-sqrt(5))*w)*(4*(x^2+y^2-z^2)+(1+3*sqrt(5))*w^2)^2
}
# make grid
# The original had 220 instead of 20, this is coarse to be quicker
nx <- 20; ny <- 20; nz <- 20
x <- seq(-5, 5, length=nx)
y <- seq(-5, 5, length=ny)
z <- seq(-4, 4, length=nz)
g <- expand.grid(x=x, y=y, z=z)
# calculate voxel
voxel <- array(with(g, f(x,y,z)), dim = c(nx,ny,nz))
# compute isosurface
open3d(useNULL = TRUE)
surf <- as.mesh3d(misc3d::contour3d(voxel, maxvol=max(voxel), level=0, x=x, y=y, z=z))
rgl.close()
surf$normals <- NULL
surf <- mergeVertices(surf)
surf <- addNormals(surf)
fn <- function(x) {
rowSums(x^2)
}
open3d()
shade3d(clipMesh3d(surf, fn, bound = 4.8^2,
greater = FALSE), col="red")
}
# }
```

*Documentation reproduced from package rgl, version 0.100.50, License: GPL*