Skip to content

Instantly share code, notes, and snippets.

@MonteShaffer
Last active October 28, 2017 10:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save MonteShaffer/d142210cddf346c86aeab1ea2d1d7e9d to your computer and use it in GitHub Desktop.
Save MonteShaffer/d142210cddf346c86aeab1ea2d1d7e9d to your computer and use it in GitHub Desktop.
#' Convert String Matrix to Numeric Matrix
#'
#' @param m string matrix
#'
#' @return numeric matrix
#' @export
numericMatrix = function(m)
{
m = as.matrix(m);
mdim = dim(m);
nm <- mapply(m, FUN=as.numeric);
matrix(data=nm, nrow=mdim[1], ncol=mdim[2])
}
#' Convert String List of "f" to numeric multi-dimensional array
#'
#' @param fobj
#'
#' @return fn, multidimension array of rows, cols, and values
#' @export
#'
numericF = function(fobj)
{
rdim = dim(fobj)[1]; # rows
cdim = dim(fobj)[2]; # cols
ddim = 3;
fn = array(NA,dim=c(rdim,cdim,ddim));
for(rn in 1:rdim)
{
for(cn in 1:cdim)
{
rcdat = fobj[rn,cn];
fdat = as.numeric(unlist(strsplit(rcdat,"/",fixed=T))); # basic numeric case
fn[rn,cn,] = fdat;
}
}
#fn[1:10,1:4,1:3]
fn;
}
#' Internally equivalent to rgl 'readOBJ'
#'
#' @param rawobj Raw object read in using parseFileOBJ
#'
#' rgl::readOBJ
#' hand <- readLines("hand.OBJ")
#' poly <- grepl("^f ", hand)
#' hand[poly] <- gsub("/[^ ]+", "", hand[poly])
#' handmesh <- readOBJ(textConnection(hand))
#'
#' mymesh = buildBasicMeshFromOBJ(parseFileOBJ("hand.OBJ"));
#'
#' These appear to be equivalent in the basic form
#'
#' @return list object equivalent to readOBJ output
#' @export
#'
buildBasicMeshFromOBJ <- function(rawobj)
{
mesh = list();
vb = as.matrix(rawobj$v);
vb = cbind(vb,1);
mesh$vb = t(vb);
mesh$it = matrix(0,nrow=3,ncol=0);
mesh$primitivetype = "triangle";
mesh$ib = t(as.matrix(rawobj$fn[,,1]));
attr(mesh,"class") = c("mesh3d","shape3d");
mesh;
}
#' Parse file of type OBJ
#'
#' Specification for OBJ format can be found here:
#' http://www.martinreddy.net/gfx/3d/OBJ.spec
#'
#' Requires gdata::trim
#'
#' @param filename
#'
#' @return list 'rawobj' with all details from the file
#' @export
#'
#' @examples
#' rawobj = parseFileOBJ("hand.obj");
parseFileOBJ <- function(filename)
{
linestxt <- readLines(filename) # read all lines
linestxt = gsub("\\s+"," ",gdata::trim(linestxt)); # replace multiple spaces with single space
linesobj = strsplit(linestxt," ",fixed=T); # split on spaces
rawobj = list();
rawobj$lines = c();
rawobj$comments = c();
for(i in 1:length(linesobj))
{
hir = gdata::trim(linesobj[[i]]);
key = hir[1];
rdat = hir[-1];
rlen = length(rdat);
rstr = paste(rdat,collapse=" ");
if(!is.na(key))
{
if (key=="#") {
rawobj$lines = c(rawobj$lines,"comments");
rawobj$comments = c(rawobj$comments,rstr);
} else { rawobj$lines = c(rawobj$lines,key);
if(is.null(rawobj[[key]])) { rawobj[[key]] = rdat; } else
{ rawobj[[key]] = rbind(rawobj[[key]],rdat);}
}
}
}
if(!is.null(rawobj[["v"]])) { rawobj[["v"]] = numericMatrix(rawobj[["v"]]); }
if(!is.null(rawobj[["vn"]])) { rawobj[["vn"]] = numericMatrix(rawobj[["vn"]]); }
if(!is.null(rawobj[["vt"]])) { rawobj[["vt"]] = numericMatrix(rawobj[["vt"]]); }
# "f" could be numeric (f 1 2 3 4) or (f -4 -3 -2 -1) or references to v,vn,vt (f 1/1/1 2/2/2 3/3/3 4/4/4) or (f v/vt/vn v/vt/vn v/vt/vn v/vt/vn) or (f 1//1 2//2 3//3 4//4)
# rdat = c("1102/9904/4404","2981/9909/4404","3943/9910/4404","2854/9905/4404");
# rdat = c('1//1','2//2','3//3',4//4');
if(!is.null(rawobj[["f"]])) { rawobj[["fn"]] = numericF(rawobj[["f"]]); }
rawobj;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment