0

I have vertices and indices data for human face here. I have a post one year ago on plotting 3D facial surface mesh based on these data. Now, I want to plot only the right half and mid-facial vertices while ignoring the left side vertices. Based on my earlier plot, I tried the following code:

library(tidyverse)
library(readxl)
library(rgl)

vb <- read_excel("...\\vb.xlsx", sheet = "Sheet1", col_names = F)
it <- read_excel("...\\it.xlsx", sheet = "Sheet1", col_names = F)

# Extract vertices for the right side
lm_right_ind <- which(vb[,1] < 0)
vb_mat_right <- t(vb[lm_right_ind, ])
vb_mat_right <- rbind(vb_mat_right, 1)
rownames(vb_mat_right) <- c("xpts", "ypts", "zpts", "")
vertices1_right <- c(vb_mat_right)

# Extract `it` whose rows do not contain vertices on the left side
# Left-side vertices have vb[,1] greater than 0
lm_left_ind <- which(vb[,1] > 0)

leftContain <- NULL

for (i in 1: dim(it)[1]) {
   if (T %in% (it[i,] %in% lm_left_ind)) {
          leftContain[i] <- i
    } else {leftContain[i] <- NA}
}

leftContain <- leftContain[!is.na(leftContain)]
# Remove indices that involve left-side vertices
it_rightMid <- it[-leftContain,]

it_mat_right <- t(as.matrix(it_rightMid))
rownames(it_mat_right) <- NULL

indices_right <- c(it_mat_right)

# Plot
try1_right <- tmesh3d(vertices = vertices1_right, indices = indices_right, homogeneous = TRUE, 
             material = NULL, normals = NULL, texcoords = NULL)

# Use addNormals to smooth the plot. See my Stackoverflow question:
# https://stackoverflow.com/questions/53918849/smooth-3d-trangular-mesh-in-r
try12_right <- addNormals(try1_right)

shade3d(try12_right, col="#add9ec", specular = "#202020", alpha = 0.8)

I got an error whing trying to obtain try12_right: Error in v[, it[3, i]] : subscript out of bounds.

I did exactly as what I did in my earlier plot but why something went wrong here? Thank you.

Patrick
  • 1,057
  • 9
  • 23
  • 1
    I can't run your code, but I assume the problem is that you are modifying the `vb` matrix and not consistently modifying the `it` matrix. I'd suggest making no changes at all to `vb`, and just leaving out the columns of `it` that correspond to vertices on the left. Or even simpler, use a clipping plane to just ignore the left half. Both solutions are a little inefficient, but they'll save you a lot of time. – user2554330 May 02 '20 at 17:47
  • Thank you for the reply. You are right that there was a mismatch between `vb` and `it` because midfacial vertices were included in `it` but not in `vb`. Correcting for this solved my issue. Thank you as well for introducing clipping plane to me. It is useful as well. – Patrick May 03 '20 at 01:43

1 Answers1

1

Here's an example of using a clipping plane to leave off the left hand side of a mesh object:

library(rgl)
open3d()
root <- currentSubscene3d()
newSubscene3d("inherit", "inherit", "inherit", parent = root) # Clipping limited to this subscene
shade3d(addNormals(subdivision3d(icosahedron3d(), 2)), col = "pink")
clipplanes3d(a = 1, b = 0, c = 0, d = 0)
useSubscene3d(root)
decorate3d()

The fiddling with subscenes limits the clipping to just the shaded sphere, not everything else in the picture.

This produces this output:

screenshot

If there's nothing else there, it's simpler:

library(rgl)
open3d()
shade3d(addNormals(subdivision3d(icosahedron3d(), 2)), col = "pink")
clipplanes3d(a = 1, b = 0, c = 0, d = 0)

which produces

screenshot

user2554330
  • 37,248
  • 4
  • 43
  • 90