## ------------------------------------------------
## Method `cgalMesh$new`
## ------------------------------------------------
library(cgalMeshes)
meshFile <- system.file(
"extdata", "bigPolyhedron.off", package = "cgalMeshes"
)
mesh <- cgalMesh$new(meshFile)
rglmesh <- mesh$getMesh()
library(rgl)
open3d(windowRect = 50 + c(0, 0, 512, 512), zoom = 0.9)
shade3d(rglmesh, color = "tomato")
plotEdges(
mesh$getVertices(), mesh$getEdges(), color = "darkred"
)
# this one has colors: ####
meshFile <- system.file(
"extdata", "pentagrammicDipyramid.ply", package = "cgalMeshes"
)
mesh <- cgalMesh$new(meshFile)
rmesh <- mesh$getMesh()
library(rgl)
open3d(windowRect = 50 + c(0, 0, 512, 512), zoom = 0.85)
shade3d(rmesh, meshColor = "faces")
## ------------------------------------------------
## Method `cgalMesh$area`
## ------------------------------------------------
library(rgl)
mesh <- cgalMesh$new(cube3d())$triangulate()
mesh$area()
## ------------------------------------------------
## Method `cgalMesh$boundingBox`
## ------------------------------------------------
library(cgalMeshes)
library(rgl)
rmesh <- cyclideMesh(a = 97, c = 32, mu = 57)
mesh <- cgalMesh$new(rmesh)
bbox <- mesh$boundingBox()
bxmesh <- isoCuboidMesh(bbox[["lcorner"]], bbox[["ucorner"]])
open3d(windowRect = 50 + c(0, 0, 512, 512))
view3d(0, -60)
shade3d(rmesh, color = "gold")
wire3d(bxmesh, color = "black")
## ------------------------------------------------
## Method `cgalMesh$boundsVolume`
## ------------------------------------------------
library(rgl)
mesh <- cgalMesh$new(tetrahedron3d())
mesh$boundsVolume() # TRUE
mesh$reverseOrientation()
mesh$boundsVolume() # TRUE
## ------------------------------------------------
## Method `cgalMesh$CatmullClark`
## ------------------------------------------------
library(cgalMeshes)
library(rgl)
hopfMesh <- HopfTorusMesh(nu = 80, nv = 40)
mesh <- cgalMesh$new(hopfMesh)
mesh$CatmullClark(iterations = 2)
mesh$computeNormals()
rmesh <- mesh$getMesh()
# plot
open3d(windowRect = 50 + c(0, 0, 800, 400))
mfrow3d(1, 2)
view3d(0, 0, zoom = 0.9)
shade3d(hopfMesh, color = "red")
wire3d(hopfMesh, color = "black")
next3d()
view3d(0, 0, zoom = 0.9)
shade3d(rmesh, color = "red")
wire3d(rmesh, color = "black")
## ------------------------------------------------
## Method `cgalMesh$centroid`
## ------------------------------------------------
library(cgalMeshes)
library(rgl)
mesh <- cgalMesh$new(icosahedron3d())
mesh$centroid()
## ------------------------------------------------
## Method `cgalMesh$clip`
## ------------------------------------------------
# cube clipped to sphere ####
library(cgalMeshes)
library(rgl)
mesh <- cgalMesh$new(cube3d())$triangulate()
clipper <- cgalMesh$new(sphereMesh(r= sqrt(2)))
mesh$assignFaceColors("blue")
clipper$assignFaceColors("red")
meshes <- mesh$clip(clipper, clipVolume = TRUE)
mesh1 <- meshes[[1]]
mesh2 <- meshes[[2]]
mesh2$computeNormals()
rglmesh1 <- mesh1$getMesh()
rglmesh2 <- mesh2$getMesh()
open3d(windowRect = 50 + c(0, 0, 512, 512))
view3d(45, 45, zoom = 0.9)
shade3d(rglmesh1, meshColor = "faces")
shade3d(rglmesh2, meshColor = "faces")
# Togliatti surface clipped to a ball ####
library(rmarchingcubes)
library(rgl)
library(cgalMeshes)
# Togliatti surface equation: f(x,y,z) = 0
f <- function(x, y, z) {
64*(x-1) *
(x^4 - 4*x^3 - 10*x^2*y^2 - 4*x^2 + 16*x - 20*x*y^2 + 5*y^4 + 16 - 20*y^2) -
5*sqrt(5-sqrt(5))*(2*z - sqrt(5-sqrt(5))) *
(4*(x^2 + y^2 - z^2) + (1 + 3*sqrt(5)))^2
}
# grid
n <- 200L
x <- y <- seq(-5, 5, length.out = n)
z <- seq(-4, 4, length.out = n)
Grid <- expand.grid(X = x, Y = y, Z = z)
# calculate voxel
voxel <- array(with(Grid, f(X, Y, Z)), dim = c(n, n, n))
# calculate isosurface
contour_shape <- contour3d(
griddata = voxel, level = 0, x = x, y = y, z = z
)
# make rgl mesh (plotted later)
rglMesh <- tmesh3d(
vertices = t(contour_shape[["vertices"]]),
indices = t(contour_shape[["triangles"]]),
normals = contour_shape[["normals"]],
homogeneous = FALSE
)
# make CGAL mesh
mesh <- cgalMesh$new(rglMesh)
# clip to sphere of radius 4.8
sphere <- sphereMesh(r = 4.8)
clipper <- cgalMesh$new(sphere)
mesh$clip(clipper, clipVolume = FALSE)
rglClippedMesh <- mesh$getMesh()
# plot
open3d(windowRect = 50 + c(0, 0, 900, 450))
mfrow3d(1L, 2L)
view3d(0, -70, zoom = 0.8)
shade3d(rglMesh, color = "firebrick")
next3d()
view3d(0, -70, zoom = 0.8)
shade3d(rglClippedMesh, color = "firebrick")
shade3d(sphere, color = "yellow", alpha = 0.15)
## ------------------------------------------------
## Method `cgalMesh$clipToPlane`
## ------------------------------------------------
library(cgalMeshes)
library(rgl)
rmesh <- sphereMesh()
mesh <- cgalMesh$new(rmesh)
nfaces <- nrow(mesh$getFaces())
if(require("randomcoloR")) {
colors <-
randomColor(nfaces, hue = "random", luminosity = "dark")
} else {
colors <- rainbow(nfaces)
}
mesh$assignFaceColors(colors)
meshes <- mesh$clipToPlane(
planePoint = c(0, 0, 0),
planeNormal = c(0, 0, 1),
clipVolume = TRUE
)
mesh1 <- meshes[[1]]
mesh2 <- meshes[[2]]
mesh1$computeNormals()
rClippedMesh1 <- mesh1$getMesh()
rClippedMesh2 <- mesh2$getMesh()
open3d(windowRect = 50 + c(0, 0, 512, 512))
view3d(70, 0)
shade3d(rClippedMesh1, meshColor = "faces")
shade3d(rClippedMesh2, color = "orange")
## ------------------------------------------------
## Method `cgalMesh$clipToIsoCuboid`
## ------------------------------------------------
library(cgalMeshes)
library(rgl)
rmesh <- HopfTorusMesh(nu = 200, nv = 200)
mesh <- cgalMesh$new(rmesh)
mesh$assignFaceColors("orangered")
lcorner <- c(-7, -7, -5)
ucorner <- c(7, 6, 5)
bxmesh <- isoCuboidMesh(lcorner, ucorner)
mesh$clipToIsoCuboid(
lcorner, ucorner, clipVolume = FALSE
)
mesh$computeNormals()
rClippedMesh <- mesh$getMesh()
open3d(windowRect = 50 + c(0, 0, 512, 512))
view3d(-40, 0)
shade3d(rClippedMesh, meshColor = "faces")
shade3d(bxmesh, color = "cyan", alpha = 0.3)
## ------------------------------------------------
## Method `cgalMesh$connectedComponents`
## ------------------------------------------------
library(cgalMeshes)
library(rmarchingcubes)
# isosurface function (slice of a seven-dimensional toratope)
f <- function(x, y, z, a) {
(sqrt(
(sqrt((sqrt((x*sin(a))^2 + (z*cos(a))^2) - 5)^2 + (y*sin(a))^2) - 2.5)^2 +
(x*cos(a))^2) - 1.25
)^2 + (sqrt((sqrt((z*sin(a))^2 + (y*cos(a))^2) - 2.5)^2) - 1.25)^2
}
# make grid
n <- 200L
x <- seq(-10, 10, len = n)
y <- seq(-10, 10, len = n)
z <- seq(-10, 10, len = n)
Grid <- expand.grid(X = x, Y = y, Z = z)
# compute isosurface
voxel <- array(with(Grid, f(X, Y, Z, a = pi/2)), dim = c(n, n, n))
isosurface <- contour3d(voxel, level = 0.25, x = x, y = y, z = z)
# make CGAL mesh
mesh <- cgalMesh$new(
vertices = isosurface[["vertices"]],
faces = isosurface[["triangles"]],
normals = isosurface[["normals"]]
)
# connected components
components <- mesh$connectedComponents()
ncc <- length(components)
# plot
library(rgl)
colors <- rainbow(ncc)
open3d(windowRect = 50 + c(0, 0, 512, 512))
view3d(30, 50)
for(i in 1L:ncc) {
rglMesh <- components[[i]]$getMesh()
shade3d(rglMesh, color = colors[i])
}
## ------------------------------------------------
## Method `cgalMesh$convexParts`
## ------------------------------------------------
library(cgalMeshes)
library(rgl)
mesh <- cgalMesh$new(pentagrammicPrism)$triangulate()
cxparts <- mesh$convexParts()
ncxparts <- length(cxparts)
colors <- hcl.colors(ncxparts, palette = "plasma")
open3d(windowRect = 50 + c(0, 0, 512, 512))
view3d(20, -20, zoom = 0.8)
for(i in 1L:ncxparts) {
cxmesh <- cxparts[[i]]$getMesh()
shade3d(cxmesh, color = colors[i])
}
## ------------------------------------------------
## Method `cgalMesh$copy`
## ------------------------------------------------
library(rgl)
mesh <- cgalMesh$new(cube3d())
tmesh <- mesh$copy()$triangulate()
tmesh$isTriangle() # TRUE
mesh$isTriangle() # FALSE
## ------------------------------------------------
## Method `cgalMesh$distance`
## ------------------------------------------------
# cube example ####
library(cgalMeshes)
mesh <- cgalMesh$new(rgl::cube3d())$triangulate()
points <- rbind(
c(0, 0, 0),
c(1, 1, 1)
)
mesh$distance(points) # should be 1 and 0
# cyclide example ####
library(cgalMeshes)
a <- 100; c <- 30; mu <- 80
mesh <- cgalMesh$new(cyclideMesh(a, c, mu, nu = 100L, nv = 100L))
O2 <- c(c, 0, 0)
# should be a - mu = 20 (see ?cyclideMesh):
mesh$distance(O2)
## ------------------------------------------------
## Method `cgalMesh$DooSabin`
## ------------------------------------------------
library(cgalMeshes)
library(rgl)
hopfMesh <- HopfTorusMesh(nu = 80, nv = 40)
mesh <- cgalMesh$new(hopfMesh)
mesh$DooSabin(iterations = 2)
mesh$triangulate()
mesh$computeNormals()
rmesh <- mesh$getMesh()
# plot
open3d(windowRect = 50 + c(0, 0, 800, 400))
mfrow3d(1, 2)
view3d(0, 0, zoom = 0.9)
shade3d(hopfMesh, color = "brown")
wire3d(hopfMesh, color = "black")
next3d()
view3d(0, 0, zoom = 0.9)
shade3d(rmesh, color = "brown")
wire3d(rmesh, color = "black")
## ------------------------------------------------
## Method `cgalMesh$fair`
## ------------------------------------------------
library(cgalMeshes)
rglHopf <- HopfTorusMesh(nu = 100, nv = 100)
hopf <- cgalMesh$new(rglHopf)
# squared norms of the vertices
normsq <- apply(hopf$getVertices(), 1L, crossprod)
# fair the region where the squared norm is > 19
indices <- which(normsq > 19)
hopf$fair(indices)
rglHopf_faired <- hopf$getMesh()
# plot
library(rgl)
open3d(windowRect = 50 + c(0, 0, 900, 450))
mfrow3d(1L, 2L)
view3d(0, 0, zoom = 0.8)
shade3d(rglHopf, color = "orangered")
next3d()
view3d(0, 0, zoom = 0.8)
shade3d(rglHopf_faired, color = "orangered")
## ------------------------------------------------
## Method `cgalMesh$fillBoundaryHole`
## ------------------------------------------------
library(cgalMeshes)
library(rgl)
# make a sphere
sphere <- sphereMesh()
mesh <- cgalMesh$new(sphere)
# make a hole in this sphere
mesh$clipToPlane(
planePoint = c(0.5, 0, 0),
planeNormal = c(1, 0, 0),
clipVolume = FALSE
)
mesh$computeNormals()
rmesh <- mesh$getMesh()
# fill the hole
hole <- mesh$fillBoundaryHole(1, fair = TRUE)
hole$computeNormals()
rhole <- hole$getMesh()
# plot
open3d(windowRect = 50 + c(0, 0, 512, 512))
view3d(30, 30)
shade3d(rmesh, color = "red")
shade3d(rhole, color = "blue")
## ------------------------------------------------
## Method `cgalMesh$filterMesh`
## ------------------------------------------------
library(rgl)
library(cgalMeshes)
rmesh <- HopfTorusMesh(nu = 80, nv = 60)
mesh <- cgalMesh$new(rmesh)
areas <- mesh$getFacesInfo()[, "area"]
bigFaces <- which(areas > 1)
meshes <- mesh$filterMesh(bigFaces)
rmesh1 <- meshes[[1]]$getMesh()
rmesh2 <- meshes[[2]]$getMesh()
open3d(windowRect = 50 + c(0, 0, 512, 512))
view3d(0, 0)
shade3d(rmesh1, color = "red")
shade3d(rmesh2, color = "blue")
wire3d(rmesh)
## ------------------------------------------------
## Method `cgalMesh$geoDists`
## ------------------------------------------------
# torus ####
library(cgalMeshes)
library(rgl)
rglmesh <- torusMesh(R = 3, r = 2, nu = 90, nv = 60)
mesh <- cgalMesh$new(rglmesh)
# estimated geodesic distances
geodists <- mesh$geoDists(1L)
# normalization to (0, 1)
geodists <- geodists / max(geodists)
# color each vertex according to its geodesic distance from the source
fcolor <- colorRamp(viridisLite::turbo(200L))
colors <- fcolor(geodists)
colors <- rgb(colors[, 1L], colors[, 2L], colors[, 3L], maxColorValue = 255)
rglmesh[["material"]] <- list("color" = colors)
# plot
open3d(windowRect = 50 + c(0, 0, 512, 512), zoom = 0.8)
shade3d(rglmesh)
wire3d(rglmesh, color = "black")
if(!rgl.useNULL()) {
play3d(spin3d(axis = c(1, 1, 1), rpm = 5), duration = 20)
}
# a trefoil knot (taken from `?rgl::cylinder3d`) ####
library(cgalMeshes)
library(rgl)
theta <- seq(0, 2*pi, length.out = 50L)
knot <- cylinder3d(
center = cbind(
sin(theta) + 2*sin(2*theta),
2*sin(3*theta),
cos(theta) - 2*cos(2*theta)),
e1 = cbind(
cos(theta) + 4*cos(2*theta),
6*cos(3*theta),
sin(theta) + 4*sin(2*theta)),
radius = 0.8,
closed = TRUE)
knot <- subdivision3d(knot, depth = 2)
mesh <- cgalMesh$new(knot)$triangulate()
rglmesh <- mesh$getMesh()
# estimated geodesic distances
geodists <- mesh$geoDists(1L)
# normalization to (0, 1)
geodists <- geodists / max(geodists)
# color each vertex according to its geodesic distance from the source
fcolor <- colorRamp(viridisLite::inferno(200L))
colors <- fcolor(geodists)
colors <- rgb(colors[, 1L], colors[, 2L], colors[, 3L], maxColorValue = 255)
rglmesh[["material"]] <- list("color" = colors)
# plot
open3d(windowRect = 50 + c(0, 0, 512, 512), zoom = 0.8)
shade3d(rglmesh)
if(!rgl.useNULL()) {
play3d(spin3d(axis = c(1, 1, 0), rpm = 5), duration = 20)
}
## ------------------------------------------------
## Method `cgalMesh$getBorders`
## ------------------------------------------------
library(cgalMeshes)
library(rgl)
# isosurface f=0
f <- function(x, y, z) {
sin_x <- sin(x)
sin_y <- sin(y)
sin_z <- sin(z)
cos_x <- cos(x)
cos_y <- cos(y)
cos_z <- cos(z)
d <- sqrt(
(-sin_x * sin_y + cos_x * cos_z) ** 2
+ (-sin_y * sin_z + cos_y * cos_x) ** 2
+ (-sin_z * sin_x + cos_z * cos_y) ** 2
)
(
cos(
x - (-sin_x * sin_y + cos_x * cos_z) / d
)
* sin(
y - (-sin_y * sin_z + cos_y * cos_x) / d
)
+ cos(
y - (-sin_y * sin_z + cos_y * cos_x) / d
)
* sin(
z - (-sin_z * sin_x + cos_z * cos_y)/ d
)
+ cos(
z - (-sin_z * sin_x + cos_z * cos_y) / d
)
* sin(
x - (-sin_x * sin_y + cos_x * cos_z) / d
)
) * (
(
cos(
x + (-sin_x * sin_y + cos_x * cos_z) / d
)
* sin(
y + (-sin_y * sin_z + cos_y * cos_x) / d
)
+ cos(
y + (-sin_y * sin_z + cos_y * cos_x) / d
)
* sin(
z + (-sin_z * sin_x + cos_z * cos_y) / d
)
+ cos(
z + (-sin_z * sin_x + cos_z * cos_y) / d
)
* sin(
x + (-sin_x * sin_y + cos_x * cos_z) / d
)
)
)
}
# construct the isosurface f=0
ngrid <- 200L
x <- y <- z <- seq(-8.1, 8.1, length.out = ngrid)
Grid <- expand.grid(X = x, Y = y, Z = z)
voxel <- array(
with(Grid, f(X, Y, Z)), dim = c(ngrid, ngrid, ngrid)
)
library(rmarchingcubes)
contour_shape <- contour3d(
griddata = voxel, level = 0,
x = x, y = y, z = z
)
# make mesh
mesh <- cgalMesh$new(
list(
"vertices" = contour_shape[["vertices"]],
"faces" = contour_shape[["triangles"]]
)
)
# clip the mesh to the ball of radius 8
spheremesh <- cgalMesh$new(sphereMesh(r = 8))
mesh$clip(spheremesh, clipVolume = FALSE)
# compute normals
mesh$computeNormals()
# we will plot the borders
borders <- mesh$getBorders()
# plot
rmesh <- mesh$getMesh()
open3d(windowRect = c(50, 50, 562, 562), zoom = 0.7)
shade3d(rmesh, color = "darkred")
vertices <- mesh$getVertices()
for(border in borders){
plotEdges(
vertices, border[, c("v1", "v2")], color = "gold",
lwd = 3, edgesAsTubes = FALSE, verticesAsSpheres = FALSE
)
}
## ------------------------------------------------
## Method `cgalMesh$getEdges`
## ------------------------------------------------
library(rgl)
mesh <- cgalMesh$new(dodecahedron3d())
head(mesh$getEdges())
## ------------------------------------------------
## Method `cgalMesh$getMesh`
## ------------------------------------------------
library(rgl)
mesh <- cgalMesh$new(cube3d())$triangulate()
mesh$getMesh()
## ------------------------------------------------
## Method `cgalMesh$intersection`
## ------------------------------------------------
library(cgalMeshes)
library(rgl)
# take two cubes
rglmesh1 <- cube3d()
rglmesh2 <- translate3d(cube3d(), 1, 1, 1)
mesh1 <- cgalMesh$new(rglmesh1)
mesh2 <- cgalMesh$new(rglmesh2)
# the two meshes must be triangle
mesh1$triangulate()
mesh2$triangulate()
# intersection
imesh <- mesh1$intersection(mesh2)
rglimesh <- imesh$getMesh()
# extract edges for plotting
extEdges <- exteriorEdges(imesh$getEdges())
# plot
open3d(windowRect = 50 + c(0, 0, 512, 512), zoom = 0.9)
shade3d(rglimesh, color = "red")
plotEdges(imesh$getVertices(), extEdges)
shade3d(rglmesh1, color = "yellow", alpha = 0.2)
shade3d(rglmesh2, color = "cyan", alpha = 0.2)
## ------------------------------------------------
## Method `cgalMesh$isotropicRemeshing`
## ------------------------------------------------
library(cgalMeshes)
library(rgl)
mesh <- cgalMesh$new(HopfTorusMesh(nu = 80, nv = 50))
mesh$isotropicRemeshing(targetEdgeLength = 0.7)
# squared norms of the vertices
normsq <- apply(mesh$getVertices(), 1L, crossprod)
# fair the region where the squared norm is > 19
mesh$fair(which(normsq > 19))
# plot
mesh$computeNormals()
rmesh <- mesh$getMesh()
open3d(windowRect = 50 + c(0, 0, 512, 512))
view3d(0, 0)
shade3d(rmesh, color = "maroon")
wire3d(rmesh)
## ------------------------------------------------
## Method `cgalMesh$isOutwardOriented`
## ------------------------------------------------
library(rgl)
mesh <- cgalMesh$new(tetrahedron3d())
mesh$isOutwardOriented() # TRUE
mesh$reverseOrientation()
mesh$isOutwardOriented() # FALSE
## ------------------------------------------------
## Method `cgalMesh$isTriangle`
## ------------------------------------------------
library(rgl)
mesh <- cgalMesh$new(cube3d())
mesh$isTriangle()
## ------------------------------------------------
## Method `cgalMesh$LoopSubdivision`
## ------------------------------------------------
library(cgalMeshes)
library(rgl)
hopfMesh <- HopfTorusMesh(nu = 80, nv = 40)
mesh <- cgalMesh$new(hopfMesh)
mesh$LoopSubdivision(iterations = 2)
mesh$computeNormals()
rmesh <- mesh$getMesh()
# plot
open3d(windowRect = 50 + c(0, 0, 800, 400))
mfrow3d(1, 2)
view3d(0, 0, zoom = 0.9)
shade3d(hopfMesh, color = "gold")
wire3d(hopfMesh, color = "black")
next3d()
view3d(0, 0, zoom = 0.9)
shade3d(rmesh, color = "gold")
wire3d(rmesh, color = "black")
## ------------------------------------------------
## Method `cgalMesh$merge`
## ------------------------------------------------
library(cgalMeshes)
library(rgl)
mesh1 <- cgalMesh$new(sphereMesh())
mesh1$assignFaceColors("red")
mesh2 <- cgalMesh$new(sphereMesh(x = 3))
mesh2$assignFaceColors("blue")
mesh1$merge(mesh2)
rmesh <- mesh1$getMesh()
open3d(windowRect = c(50, 50, 562, 562))
shade3d(rmesh, meshColor = "faces")
## ------------------------------------------------
## Method `cgalMesh$orientToBoundVolume`
## ------------------------------------------------
# two disjoint tetrahedra ####
vertices <- rbind(
c(0, 0, 0),
c(2, 2, 0),
c(2, 0, 2),
c(0, 2, 2),
c(3, 3, 3),
c(5, 5, 3),
c(5, 3, 5),
c(3, 5, 5)
)
faces <- rbind(
c(3, 2, 1),
c(3, 4, 2),
c(1, 2, 4),
c(4, 3, 1),
c(5, 6, 7),
c(6, 8, 7),
c(8, 6, 5),
c(5, 7, 8)
)
mesh <- cgalMesh$new(vertices = vertices, faces = faces)
mesh$boundsVolume() # FALSE
mesh$orientToBoundVolume()
mesh$boundsVolume() # TRUE
## ------------------------------------------------
## Method `cgalMesh$reverseOrientation`
## ------------------------------------------------
library(rgl)
mesh <- cgalMesh$new(tetrahedron3d())
mesh$isOutwardOriented() # TRUE
mesh$reverseOrientation()
mesh$isOutwardOriented() # FALSE
## ------------------------------------------------
## Method `cgalMesh$selfIntersects`
## ------------------------------------------------
library(rgl)
mesh <- cgalMesh$new(dodecahedron3d())
mesh$selfIntersects()
## ------------------------------------------------
## Method `cgalMesh$sharpEdges`
## ------------------------------------------------
library(cgalMeshes)
library(rgl)
# astroidal ellipsoid
f <- function(u, v) {
rbind(
cos(u)^3 * cos(v)^3,
sin(u)^3 * cos(v)^3,
sin(v)^3
)
}
rmesh <- parametricMesh(
f, urange = c(0, 2*pi), vrange = c(0, 2*pi),
periodic = c(TRUE, TRUE), nu = 120, nv = 110
)
mesh <- cgalMesh$new(rmesh)
sharpEdges <- mesh$sharpEdges(30)
# plot
open3d(windowRect = 50 + c(0, 0, 512, 512), zoom = 0.8)
shade3d(addNormals(rmesh), color = "chartreuse")
plotEdges(
mesh$getVertices(), sharpEdges[, c("v1", "v2")],
edgesAsTubes = FALSE, lwd = 5, verticesAsSpheres = FALSE
)
## ------------------------------------------------
## Method `cgalMesh$Sqrt3Subdivision`
## ------------------------------------------------
library(cgalMeshes)
library(rgl)
hopfMesh <- HopfTorusMesh(nu = 80, nv = 40)
mesh <- cgalMesh$new(hopfMesh)
mesh$Sqrt3Subdivision(iterations = 2)
mesh$computeNormals()
rmesh <- mesh$getMesh()
# plot
open3d(windowRect = 50 + c(0, 0, 800, 400))
mfrow3d(1, 2)
view3d(0, 0, zoom = 0.9)
shade3d(hopfMesh, color = "cyan")
wire3d(hopfMesh, color = "black")
next3d()
view3d(0, 0, zoom = 0.9)
shade3d(rmesh, color = "cyan")
wire3d(rmesh, color = "black")
## ------------------------------------------------
## Method `cgalMesh$subtract`
## ------------------------------------------------
library(cgalMeshes)
library(rgl)
# take two cubes
rglmesh1 <- cube3d()
rglmesh2 <- translate3d(cube3d(), 1, 1, 1)
mesh1 <- cgalMesh$new(rglmesh1)
mesh2 <- cgalMesh$new(rglmesh2)
# the two meshes must be triangle
mesh1$triangulate()
mesh2$triangulate()
# assign colors
mesh1$assignFaceColors("red")
mesh2$assignFaceColors("navy")
# difference
mesh <- mesh1$subtract(mesh2)
rglmesh <- mesh$getMesh()
# extract edges for plotting
extEdges <- exteriorEdges(mesh$getEdges())
# plot
open3d(windowRect = 50 + c(0, 0, 512, 512), zoom = 0.9)
shade3d(rglmesh, meshColor = "faces")
plotEdges(mesh$getVertices(), extEdges)
shade3d(rglmesh2, color = "cyan", alpha = 0.2)
## ------------------------------------------------
## Method `cgalMesh$triangulate`
## ------------------------------------------------
library(rgl)
mesh <- cgalMesh$new(cube3d())
mesh$isTriangle() # FALSE
# warning: triangulating the mesh modifies it
mesh$triangulate()
mesh$isTriangle() # TRUE
## ------------------------------------------------
## Method `cgalMesh$union`
## ------------------------------------------------
library(cgalMeshes)
library(rgl)
# take two cubes
rglmesh1 <- cube3d()
rglmesh2 <- translate3d(cube3d(), 1, 1, 1)
mesh1 <- cgalMesh$new(rglmesh1)
mesh2 <- cgalMesh$new(rglmesh2)
# the two meshes must be triangle
mesh1$triangulate()
mesh2$triangulate()
# assign a color to the faces; they will be retrieved in the union
mesh1$assignFaceColors("yellow")
mesh2$assignFaceColors("navy")
# union
umesh <- mesh1$union(mesh2)
rglumesh <- umesh$getMesh()
# extract edges for plotting
extEdges <- exteriorEdges(umesh$getEdges())
# plot
open3d(windowRect = 50 + c(0, 0, 512, 512), zoom = 0.9)
shade3d(rglumesh, meshColor = "faces")
plotEdges(umesh$getVertices(), extEdges)
## ------------------------------------------------
## Method `cgalMesh$volume`
## ------------------------------------------------
library(rgl)
mesh <- cgalMesh$new(cube3d())$triangulate()
mesh$volume()
## ------------------------------------------------
## Method `cgalMesh$whereIs`
## ------------------------------------------------
library(cgalMeshes)
mesh <- cgalMesh$new(sphereMesh())
pt1 <- c(0, 0, 0) # inside
pt2 <- c(2, 0, 0) # outside
mesh$whereIs(rbind(pt1, pt2))
Run the code above in your browser using DataLab