Read a Wavefront OBJ 3D scene file into an R list
read.obj(f, materialspath = NULL, convert.rgl = FALSE, triangulate = TRUE)
f | Path to an OBJ file |
---|---|
materialspath | Path to a folder containing materials files. This is
optional and only required if materials files are in a different folder
from the OBJ file defined by |
convert.rgl | Whether to convert the returned list to a
|
triangulate | (default |
When convert.rgl=FALSE
, the default, a named list with items
shapes
and materials
, each containing sublists with one entry
per object (shapes) or material (materials). Objects in the shapes
list have the following structure
positions
3 x N matrix of 3D vertices
indices
3/4 x M matrix of indices into vertex array
(trimesh/quadmesh) 0-indexed
normals
3 x N matrix of normal directions for each vertex
(missing when there are no normals)
normindices
3/4 x M matrix of indices into normals array
(trimesh/quadmesh) 0-indexed (missing when there are no normals)
texcoords
2 x N matrix of texture coordinates (missing when
there are no texture coordinates)
texindices
3/4 x M matrix of indices into texcoords
array (trimesh/quadmesh) 0-indexed (missing when there are no texture
coordinates)
nvfaces
Raw vector specifying the number of vertices per face
(missing unless triangulate=FALSE
and there are a mixture of
different numbers of vertices per face.)
material_ids
0-indexed, -1 when not set (missing when no
materials)
When convert.rgl=TRUE
a list of class shapelist3d
containing a mesh3d
for each object or group element in
the original OBJ file. See tinyobj2shapelist3d
for details of
rgl conversion.
tinyobjloader
made some substantial changes to its data
structures after the first code snapshot was taken for the this package in
2015. In order to benefit from bug fixes, we updated the code in 2020 but
we note that tinyobjloader
now de-duplicates vertices more
aggressively e.g. in the situation where there are normals or texture coordinates.
We were forced when converting to rgl::shapelist3d
objects
to revert these de-duplications on the R side
in order for display in rgl; note that this only happens
when there are texture coordinates and/or normals in the obj file.
Note that some fields in the tinyobjloader
return structure will be
omitted when they are not relevant for a given obj file. In this case, as
with any R list, the list element will have the value NULL
when
tested. See examples.
Note that at the request of the CRAN maintainers the
sample files have the file extension .wavefront
instead of the
standard .obj
because this triggers a false positive R CMD check
NOTE.
tinyobj2shapelist3d
, rgl::readOBJ
for simpler, pure R implementation.
#> List of 2 #> $ shapes :List of 6 #> ..$ front cube :List of 3 #> .. ..$ positions : num [1:3, 1:8] 0 2 2 0 0 2 2 0 2 2 ... #> .. ..$ indices : int [1:3, 1:2] 0 1 2 0 2 3 #> .. ..$ material_ids: int [1:2] 0 0 #> ..$ back cube :List of 3 #> .. ..$ positions : num [1:3, 1:8] 0 2 2 0 0 2 2 0 2 2 ... #> .. ..$ indices : int [1:3, 1:2] 7 6 5 7 5 4 #> .. ..$ material_ids: int [1:2] 0 0 #> ..$ right cube :List of 3 #> .. ..$ positions : num [1:3, 1:8] 0 2 2 0 0 2 2 0 2 2 ... #> .. ..$ indices : int [1:3, 1:2] 3 2 6 3 6 7 #> .. ..$ material_ids: int [1:2] 1 1 #> ..$ top cube :List of 3 #> .. ..$ positions : num [1:3, 1:8] 0 2 2 0 0 2 2 0 2 2 ... #> .. ..$ indices : int [1:3, 1:2] 4 0 3 4 3 7 #> .. ..$ material_ids: int [1:2] 0 0 #> ..$ left cube :List of 3 #> .. ..$ positions : num [1:3, 1:8] 0 2 2 0 0 2 2 0 2 2 ... #> .. ..$ indices : int [1:3, 1:2] 4 5 1 4 1 0 #> .. ..$ material_ids: int [1:2] 2 2 #> ..$ bottom cube:List of 3 #> .. ..$ positions : num [1:3, 1:8] 0 2 2 0 0 2 2 0 2 2 ... #> .. ..$ indices : int [1:3, 1:2] 1 5 6 1 6 2 #> .. ..$ material_ids: int [1:2] 0 0 #> $ materials:List of 5 #> ..$ white:List of 13 #> .. ..$ ambient : num [1:3] 0 0 0 #> .. ..$ diffuse : num [1:3] 1 1 1 #> .. ..$ specular : num [1:3] 0 0 0 #> .. ..$ transmittance : num [1:3] 0 0 0 #> .. ..$ emission : num [1:3] 0 0 0 #> .. ..$ shininess : num 1 #> .. ..$ ior : num 1 #> .. ..$ dissolve : num 1 #> .. ..$ illum : int 0 #> .. ..$ ambient_texname : chr "" #> .. ..$ diffuse_texname : chr "" #> .. ..$ specular_texname: chr "" #> .. ..$ normal_texname : chr "" #> ..$ red :List of 13 #> .. ..$ ambient : num [1:3] 0 0 0 #> .. ..$ diffuse : num [1:3] 1 0 0 #> .. ..$ specular : num [1:3] 0 0 0 #> .. ..$ transmittance : num [1:3] 0 0 0 #> .. ..$ emission : num [1:3] 0 0 0 #> .. ..$ shininess : num 1 #> .. ..$ ior : num 1 #> .. ..$ dissolve : num 1 #> .. ..$ illum : int 0 #> .. ..$ ambient_texname : chr "" #> .. ..$ diffuse_texname : chr "" #> .. ..$ specular_texname: chr "" #> .. ..$ normal_texname : chr "" #> ..$ green:List of 13 #> .. ..$ ambient : num [1:3] 0 0 0 #> .. ..$ diffuse : num [1:3] 0 1 0 #> .. ..$ specular : num [1:3] 0 0 0 #> .. ..$ transmittance : num [1:3] 0 0 0 #> .. ..$ emission : num [1:3] 0 0 0 #> .. ..$ shininess : num 1 #> .. ..$ ior : num 1 #> .. ..$ dissolve : num 1 #> .. ..$ illum : int 0 #> .. ..$ ambient_texname : chr "" #> .. ..$ diffuse_texname : chr "" #> .. ..$ specular_texname: chr "" #> .. ..$ normal_texname : chr "" #> ..$ blue :List of 13 #> .. ..$ ambient : num [1:3] 0 0 0 #> .. ..$ diffuse : num [1:3] 0 0 1 #> .. ..$ specular : num [1:3] 0 0 0 #> .. ..$ transmittance : num [1:3] 0 0 0 #> .. ..$ emission : num [1:3] 0 0 0 #> .. ..$ shininess : num 1 #> .. ..$ ior : num 1 #> .. ..$ dissolve : num 1 #> .. ..$ illum : int 0 #> .. ..$ ambient_texname : chr "" #> .. ..$ diffuse_texname : chr "" #> .. ..$ specular_texname: chr "" #> .. ..$ normal_texname : chr "" #> ..$ light:List of 13 #> .. ..$ ambient : num [1:3] 1 1 1 #> .. ..$ diffuse : num [1:3] 1 1 1 #> .. ..$ specular : num [1:3] 0 0 0 #> .. ..$ transmittance : num [1:3] 0 0 0 #> .. ..$ emission : num [1:3] 0 0 0 #> .. ..$ shininess : num 1 #> .. ..$ ior : num 1 #> .. ..$ dissolve : num 1 #> .. ..$ illum : int 0 #> .. ..$ ambient_texname : chr "" #> .. ..$ diffuse_texname : chr "" #> .. ..$ specular_texname: chr "" #> .. ..$ normal_texname : chr ""# elements will be NULL when not present in the obj file e.g. normals is.null(cube$shapes[[1]]$texcoords)#> [1] TRUE# demonstrate direct conversion of result to rgl format if(require('rgl')) { cuber=read.obj(system.file("obj/cube.wavefront", package = "readobj"), convert.rgl=TRUE) shade3d(cuber) }#>