Parsing some stuff.
This commit is contained in:
parent
16b9c32632
commit
96a24fcc28
2 changed files with 371 additions and 37 deletions
|
|
@ -10,5 +10,7 @@ struct Args {
|
||||||
fn main() -> Result<(), miette::Error> {
|
fn main() -> Result<(), miette::Error> {
|
||||||
let args = Args::parse();
|
let args = Args::parse();
|
||||||
|
|
||||||
parse_pbrt_v4(args.filename)
|
dbg!(parse_pbrt_v4(args.filename)?);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -117,6 +117,7 @@ enum Statement {
|
||||||
AttributeEnd,
|
AttributeEnd,
|
||||||
Include(String),
|
Include(String),
|
||||||
ConcatTransform(AffineTransform),
|
ConcatTransform(AffineTransform),
|
||||||
|
Shape(ShapeType),
|
||||||
Unknown(String, Vec<String>),
|
Unknown(String, Vec<String>),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -169,14 +170,331 @@ fn parse_look_at(iter: &mut impl Iterator<Item = Result<String>>) -> Result<Stat
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn parse_parameter<I, T>(iter: &mut Peekable<Tokenizer<I>>) -> Result<T>
|
||||||
|
where
|
||||||
|
I: Iterator<Item = Result<char>>,
|
||||||
|
T: std::str::FromStr,
|
||||||
|
<T as std::str::FromStr>::Err:
|
||||||
|
std::marker::Send + std::marker::Sync + std::error::Error + 'static,
|
||||||
|
{
|
||||||
|
let p = iter.next().ok_or(miette!("value expected"))??;
|
||||||
|
|
||||||
|
match p.as_str() {
|
||||||
|
"[" => {
|
||||||
|
let s = iter.next().ok_or(miette!("value expected"))??;
|
||||||
|
|
||||||
|
let d = s.parse::<T>().into_diagnostic()?;
|
||||||
|
|
||||||
|
if !iter
|
||||||
|
.next()
|
||||||
|
.is_none_or(|p| p.is_ok_and(|p| p.as_str() == "]"))
|
||||||
|
{
|
||||||
|
bail!("expected closing bracket.")
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(d)
|
||||||
|
}
|
||||||
|
s => Ok(s.parse::<T>().into_diagnostic()?),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_list<I, T>(iter: &mut Peekable<Tokenizer<I>>, data: &mut Vec<T>) -> Result<()>
|
||||||
|
where
|
||||||
|
I: Iterator<Item = Result<char>>,
|
||||||
|
T: std::str::FromStr,
|
||||||
|
<T as std::str::FromStr>::Err:
|
||||||
|
std::marker::Send + std::marker::Sync + std::error::Error + 'static,
|
||||||
|
{
|
||||||
|
if !iter
|
||||||
|
.next()
|
||||||
|
.is_none_or(|p| p.is_ok_and(|p| p.as_str() == "["))
|
||||||
|
{
|
||||||
|
bail!("expected list.")
|
||||||
|
}
|
||||||
|
|
||||||
|
while let Some(p) = iter
|
||||||
|
.next_if(|p| p.as_ref().is_ok_and(|p| p != "]"))
|
||||||
|
.transpose()?
|
||||||
|
{
|
||||||
|
data.push(p.parse().into_diagnostic()?);
|
||||||
|
}
|
||||||
|
|
||||||
|
if !iter
|
||||||
|
.next()
|
||||||
|
.is_none_or(|p| p.is_ok_and(|p| p.as_str() == "]"))
|
||||||
|
{
|
||||||
|
bail!("expected list end.")
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_list_2<I, T, P, F>(
|
||||||
|
iter: &mut Peekable<Tokenizer<I>>,
|
||||||
|
data: &mut Vec<P>,
|
||||||
|
f: F,
|
||||||
|
) -> Result<()>
|
||||||
|
where
|
||||||
|
I: Iterator<Item = Result<char>>,
|
||||||
|
T: std::str::FromStr,
|
||||||
|
<T as std::str::FromStr>::Err:
|
||||||
|
std::marker::Send + std::marker::Sync + std::error::Error + 'static,
|
||||||
|
F: Fn(T, T) -> P,
|
||||||
|
{
|
||||||
|
if !iter
|
||||||
|
.next()
|
||||||
|
.is_none_or(|p| p.is_ok_and(|p| p.as_str() == "["))
|
||||||
|
{
|
||||||
|
bail!("expected list.")
|
||||||
|
}
|
||||||
|
|
||||||
|
while let Some(pa) = iter
|
||||||
|
.next_if(|p| p.as_ref().is_ok_and(|p| p != "]"))
|
||||||
|
.transpose()?
|
||||||
|
{
|
||||||
|
if let Some(pb) = iter
|
||||||
|
.next_if(|p| p.as_ref().is_ok_and(|p| p != "]"))
|
||||||
|
.transpose()?
|
||||||
|
{
|
||||||
|
data.push(f(
|
||||||
|
pa.parse().into_diagnostic()?,
|
||||||
|
pb.parse().into_diagnostic()?,
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
bail!("Unfinished group")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !iter
|
||||||
|
.next()
|
||||||
|
.is_none_or(|p| p.is_ok_and(|p| p.as_str() == "]"))
|
||||||
|
{
|
||||||
|
bail!("expected list end.")
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_list_3<I, T, P, F>(
|
||||||
|
iter: &mut Peekable<Tokenizer<I>>,
|
||||||
|
data: &mut Vec<P>,
|
||||||
|
f: F,
|
||||||
|
) -> Result<()>
|
||||||
|
where
|
||||||
|
I: Iterator<Item = Result<char>>,
|
||||||
|
T: std::str::FromStr,
|
||||||
|
<T as std::str::FromStr>::Err:
|
||||||
|
std::marker::Send + std::marker::Sync + std::error::Error + 'static,
|
||||||
|
F: Fn(T, T, T) -> P,
|
||||||
|
{
|
||||||
|
if !iter
|
||||||
|
.next()
|
||||||
|
.is_none_or(|p| p.is_ok_and(|p| p.as_str() == "["))
|
||||||
|
{
|
||||||
|
bail!("expected list.")
|
||||||
|
}
|
||||||
|
|
||||||
|
while let Some(pa) = iter
|
||||||
|
.next_if(|p| p.as_ref().is_ok_and(|p| p != "]"))
|
||||||
|
.transpose()?
|
||||||
|
{
|
||||||
|
if let Some(pb) = iter
|
||||||
|
.next_if(|p| p.as_ref().is_ok_and(|p| p != "]"))
|
||||||
|
.transpose()?
|
||||||
|
{
|
||||||
|
if let Some(pc) = iter
|
||||||
|
.next_if(|p| p.as_ref().is_ok_and(|p| p != "]"))
|
||||||
|
.transpose()?
|
||||||
|
{
|
||||||
|
data.push(f(
|
||||||
|
pa.parse().into_diagnostic()?,
|
||||||
|
pb.parse().into_diagnostic()?,
|
||||||
|
pc.parse().into_diagnostic()?,
|
||||||
|
));
|
||||||
|
} else {
|
||||||
|
bail!("Unfinished group")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
bail!("Unfinished group")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if !iter
|
||||||
|
.next()
|
||||||
|
.is_none_or(|p| p.is_ok_and(|p| p.as_str() == "]"))
|
||||||
|
{
|
||||||
|
bail!("expected list end.")
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn parse_shape<I: Iterator<Item = Result<char>>>(
|
fn parse_shape<I: Iterator<Item = Result<char>>>(
|
||||||
iter: &mut Peekable<Tokenizer<I>>,
|
iter: &mut Peekable<Tokenizer<I>>,
|
||||||
) -> std::result::Result<Statement, Error> {
|
) -> std::result::Result<Statement, Error> {
|
||||||
let shape_type = iter.next().ok_or(miette!(""))??;
|
let shape_type = iter.next().ok_or(miette!("unable to get shape type"))??;
|
||||||
|
|
||||||
match shape_type.as_str() {
|
match shape_type.as_str() {
|
||||||
"sphere" => {}
|
"\"sphere\"" => {
|
||||||
_ => Err(miette!("")),
|
let mut radius = 1.0;
|
||||||
|
let zmin = -radius;
|
||||||
|
let zmax = radius;
|
||||||
|
let phimax = 360.0;
|
||||||
|
|
||||||
|
while let Some(p) = iter
|
||||||
|
.next_if(|p| p.as_ref().is_ok_and(|p| p.starts_with('"')))
|
||||||
|
.transpose()?
|
||||||
|
{
|
||||||
|
match p.as_str() {
|
||||||
|
"\"float radius\"" => {
|
||||||
|
radius = parse_parameter(iter)?;
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
bail!("unknown argument {}", p)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Statement::Shape(ShapeType::Sphere {
|
||||||
|
radius,
|
||||||
|
zmin,
|
||||||
|
zmax,
|
||||||
|
phimax,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
"\"trianglemesh\"" => {
|
||||||
|
let mut indices = Vec::new();
|
||||||
|
let mut p = Vec::new();
|
||||||
|
let mut n = Vec::new();
|
||||||
|
let mut s = Vec::new();
|
||||||
|
let mut uv = Vec::new();
|
||||||
|
|
||||||
|
while let Some(q) = iter
|
||||||
|
.next_if(|p| p.as_ref().is_ok_and(|p| p.starts_with('"')))
|
||||||
|
.transpose()?
|
||||||
|
{
|
||||||
|
match q.as_str() {
|
||||||
|
"\"integer indices\"" => {
|
||||||
|
parse_list(iter, &mut indices)?;
|
||||||
|
}
|
||||||
|
"\"point3 P\"" => {
|
||||||
|
parse_list_3(iter, &mut p, Pos3::new)?;
|
||||||
|
}
|
||||||
|
"\"normal N\"" => {
|
||||||
|
parse_list_3(iter, &mut n, Dir3::new)?;
|
||||||
|
}
|
||||||
|
"\"vector N\"" => {
|
||||||
|
parse_list_3(iter, &mut s, Dir3::new)?;
|
||||||
|
}
|
||||||
|
"\"point2 uv\"" => {
|
||||||
|
parse_list_2(iter, &mut uv, |u, v| [u, v])?;
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
bail!("unknown argument {}", q)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if p.len() < 3 {
|
||||||
|
bail!("At least 3 points required.")
|
||||||
|
}
|
||||||
|
if indices.is_empty() && p.len() != 3 {
|
||||||
|
bail!("Indices required for trianglemesh with more than 3 points.")
|
||||||
|
}
|
||||||
|
|
||||||
|
if indices.len() % 3 != 0 {
|
||||||
|
bail!(
|
||||||
|
"number of indices must be divisible by 3. num indices: {}",
|
||||||
|
indices.len()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if !n.is_empty() && n.len() != p.len() {
|
||||||
|
bail!("Number of normals not equal to number of positions.")
|
||||||
|
}
|
||||||
|
|
||||||
|
if !s.is_empty() && s.len() != p.len() {
|
||||||
|
bail!("Number of tangents not equal to number of positions.")
|
||||||
|
}
|
||||||
|
if !uv.is_empty() && uv.len() != p.len() {
|
||||||
|
bail!("Number of uvs not equal to number of positions.")
|
||||||
|
}
|
||||||
|
Ok(Statement::Shape(ShapeType::TriangleMesh {
|
||||||
|
indices,
|
||||||
|
p,
|
||||||
|
n,
|
||||||
|
s,
|
||||||
|
uv,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
"\"bilinearmesh\"" => {
|
||||||
|
let mut p = Vec::new();
|
||||||
|
|
||||||
|
let mut uv = Vec::new();
|
||||||
|
|
||||||
|
while let Some(q) = iter
|
||||||
|
.next_if(|p| p.as_ref().is_ok_and(|p| p.starts_with('"')))
|
||||||
|
.transpose()?
|
||||||
|
{
|
||||||
|
match q.as_str() {
|
||||||
|
"\"point3 P\"" => {
|
||||||
|
parse_list_3(iter, &mut p, Pos3::new)?;
|
||||||
|
}
|
||||||
|
"\"point2 uv\"" => {
|
||||||
|
parse_list_2(iter, &mut uv, |u, v| [u, v])?;
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
bail!("unknown argument {}", q)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Statement::Shape(ShapeType::BilinearMesh {
|
||||||
|
p: [p[0], p[1], p[2], p[3]],
|
||||||
|
uv: [uv[0], uv[1], uv[2], uv[3]],
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
"\"loopsubdiv\"" => {
|
||||||
|
let mut levels = 3;
|
||||||
|
let mut indices = Vec::new();
|
||||||
|
|
||||||
|
let mut p = Vec::new();
|
||||||
|
|
||||||
|
while let Some(q) = iter
|
||||||
|
.next_if(|p| p.as_ref().is_ok_and(|p| p.starts_with('"')))
|
||||||
|
.transpose()?
|
||||||
|
{
|
||||||
|
match q.as_str() {
|
||||||
|
"\"point3 P\"" => {
|
||||||
|
parse_list_3(iter, &mut p, Pos3::new)?;
|
||||||
|
}
|
||||||
|
"\"integer indices\"" => {
|
||||||
|
parse_list(iter, &mut indices)?;
|
||||||
|
}
|
||||||
|
"\"integer levels\"" => {
|
||||||
|
levels = parse_parameter(iter)?;
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
bail!("unknown argument {}", q)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if indices.is_empty() {
|
||||||
|
bail!("indices are a required field")
|
||||||
|
}
|
||||||
|
|
||||||
|
if p.is_empty() {
|
||||||
|
bail!("p is a required field")
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Statement::Shape(ShapeType::LoopSubDiv {
|
||||||
|
levels,
|
||||||
|
indices,
|
||||||
|
p,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
_ => Err(miette!("Unknown shape {}", shape_type)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -199,6 +517,7 @@ impl<I: Iterator<Item = Result<char>>> Lexer<I> {
|
||||||
}
|
}
|
||||||
"LookAt" => Some(parse_look_at(&mut self.input)),
|
"LookAt" => Some(parse_look_at(&mut self.input)),
|
||||||
"Identity" => Some(Ok(Statement::ConcatTransform(AffineTransform::identity()))),
|
"Identity" => Some(Ok(Statement::ConcatTransform(AffineTransform::identity()))),
|
||||||
|
"Shape" => Some(parse_shape(&mut self.input)),
|
||||||
_ => {
|
_ => {
|
||||||
if s.chars().any(|c| !c.is_ascii_alphabetic()) {
|
if s.chars().any(|c| !c.is_ascii_alphabetic()) {
|
||||||
Some(Err(miette!("malformed identifier")))
|
Some(Err(miette!("malformed identifier")))
|
||||||
|
|
@ -218,7 +537,6 @@ impl<I: Iterator<Item = Result<char>>> Lexer<I> {
|
||||||
Some(Ok(Statement::Unknown(s, v)))
|
Some(Ok(Statement::Unknown(s, v)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"Shape" => Some(parse_shape(&mut self.input)),
|
|
||||||
},
|
},
|
||||||
Some(Err(e)) => Some(Err(e)),
|
Some(Err(e)) => Some(Err(e)),
|
||||||
None => None,
|
None => None,
|
||||||
|
|
@ -251,7 +569,6 @@ struct Parser<P> {
|
||||||
path: P,
|
path: P,
|
||||||
inner: Option<Box<Parser<PathBuf>>>,
|
inner: Option<Box<Parser<PathBuf>>>,
|
||||||
iter: Lexer<BytesToChar<Bytes<BufReader<File>>>>,
|
iter: Lexer<BytesToChar<Bytes<BufReader<File>>>>,
|
||||||
ctm: AffineTransform,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P: AsRef<Path> + std::fmt::Debug> Parser<P> {
|
impl<P: AsRef<Path> + std::fmt::Debug> Parser<P> {
|
||||||
|
|
@ -260,40 +577,29 @@ impl<P: AsRef<Path> + std::fmt::Debug> Parser<P> {
|
||||||
let bufreader = BufReader::new(std::fs::File::open(&path).into_diagnostic()?);
|
let bufreader = BufReader::new(std::fs::File::open(&path).into_diagnostic()?);
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
path,
|
path,
|
||||||
ctm: AffineTransform::identity(),
|
|
||||||
inner: None,
|
inner: None,
|
||||||
iter: Lexer::new(BytesToChar {
|
iter: Lexer::new(BytesToChar {
|
||||||
iter: bufreader.bytes(),
|
iter: bufreader.bytes(),
|
||||||
}),
|
}),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_transform(&mut self, transform: AffineTransform) {
|
|
||||||
self.ctm *= transform;
|
|
||||||
}
|
|
||||||
|
|
||||||
fn set_transform(&mut self, transform: AffineTransform) {
|
|
||||||
self.ctm = transform;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P: AsRef<Path>> Iterator for Parser<P> {
|
impl<P: AsRef<Path>> Parser<P> {
|
||||||
type Item = Result<Statement>;
|
fn next(&mut self, context: &PbrtContext) -> Option<Result<Statement>> {
|
||||||
|
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
|
||||||
if let Some(iter) = &mut self.inner {
|
if let Some(iter) = &mut self.inner {
|
||||||
if let Some(statement) = iter.next() {
|
if let Some(statement) = iter.next(context) {
|
||||||
return Some(statement);
|
return Some(statement);
|
||||||
}
|
}
|
||||||
self.inner = None;
|
self.inner = None;
|
||||||
}
|
}
|
||||||
|
|
||||||
match self.iter.next(self.ctm) {
|
match self.iter.next(context.ctm) {
|
||||||
Some(Ok(Statement::Include(s))) => {
|
Some(Ok(Statement::Include(s))) => {
|
||||||
let path = self.path.as_ref().parent().unwrap().join(s);
|
let path = self.path.as_ref().parent().unwrap().join(s);
|
||||||
self.inner = Some(Box::new(Parser::new(path).unwrap()));
|
self.inner = Some(Box::new(Parser::new(path).unwrap()));
|
||||||
|
|
||||||
self.next()
|
self.next(context)
|
||||||
}
|
}
|
||||||
Some(s) => Some(s),
|
Some(s) => Some(s),
|
||||||
None => None,
|
None => None,
|
||||||
|
|
@ -301,6 +607,7 @@ impl<P: AsRef<Path>> Iterator for Parser<P> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
enum ShapeType {
|
enum ShapeType {
|
||||||
Sphere {
|
Sphere {
|
||||||
radius: Float,
|
radius: Float,
|
||||||
|
|
@ -308,29 +615,50 @@ enum ShapeType {
|
||||||
zmax: Float,
|
zmax: Float,
|
||||||
phimax: Float,
|
phimax: Float,
|
||||||
},
|
},
|
||||||
|
TriangleMesh {
|
||||||
|
indices: Vec<usize>,
|
||||||
|
p: Vec<Pos3>,
|
||||||
|
n: Vec<Dir3>,
|
||||||
|
s: Vec<Dir3>,
|
||||||
|
uv: Vec<[Float; 2]>,
|
||||||
|
},
|
||||||
|
BilinearMesh {
|
||||||
|
p: [Pos3; 4],
|
||||||
|
uv: [[Float; 2]; 4],
|
||||||
|
},
|
||||||
|
LoopSubDiv {
|
||||||
|
levels: u32,
|
||||||
|
indices: Vec<usize>,
|
||||||
|
p: Vec<Pos3>,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
struct Shape {
|
struct Shape {
|
||||||
ctm: AffineTransform,
|
ctm: AffineTransform,
|
||||||
material: usize,
|
material: usize,
|
||||||
obj: ShapeType,
|
obj: ShapeType,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Pbrt {
|
#[derive(Debug)]
|
||||||
|
pub struct Pbrt {
|
||||||
settings: PbrtWorldSettings,
|
settings: PbrtWorldSettings,
|
||||||
scene: PbrtScene,
|
scene: PbrtScene,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Pbrt {
|
impl Pbrt {
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
settings: todo!(),
|
settings: PbrtWorldSettings {},
|
||||||
scene: todo!(),
|
scene: PbrtScene { shapes: Vec::new() },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
struct PbrtWorldSettings {}
|
struct PbrtWorldSettings {}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
struct PbrtScene {
|
struct PbrtScene {
|
||||||
shapes: Vec<Shape>,
|
shapes: Vec<Shape>,
|
||||||
}
|
}
|
||||||
|
|
@ -352,13 +680,15 @@ fn inner_parse_pbrt(
|
||||||
path: impl AsRef<Path> + std::fmt::Debug,
|
path: impl AsRef<Path> + std::fmt::Debug,
|
||||||
context: Option<PbrtContext>,
|
context: Option<PbrtContext>,
|
||||||
) -> Result<Pbrt> {
|
) -> Result<Pbrt> {
|
||||||
|
// unwrap on context.last() ok because context is never empty
|
||||||
let mut context = vec![context.unwrap_or(PbrtContext::new())];
|
let mut context = vec![context.unwrap_or(PbrtContext::new())];
|
||||||
|
|
||||||
let mut parser = Parser::new(path)?;
|
let mut parser = Parser::new(path)?;
|
||||||
|
|
||||||
let mut pbrt = Pbrt::new();
|
let mut pbrt = Pbrt::new();
|
||||||
|
|
||||||
while let Some(p) = parser.next().transpose()? {
|
while let Some(p) = parser.next(context.last().unwrap()).transpose()? {
|
||||||
|
// dbg!(&p);
|
||||||
match p {
|
match p {
|
||||||
Statement::AttributeBegin => context.push(context.last().ok_or(miette!(""))?.clone()),
|
Statement::AttributeBegin => context.push(context.last().ok_or(miette!(""))?.clone()),
|
||||||
Statement::AttributeEnd => {
|
Statement::AttributeEnd => {
|
||||||
|
|
@ -368,20 +698,22 @@ fn inner_parse_pbrt(
|
||||||
Statement::ConcatTransform(affine_transform) => {
|
Statement::ConcatTransform(affine_transform) => {
|
||||||
context.last_mut().ok_or(miette!(""))?.ctm *= affine_transform
|
context.last_mut().ok_or(miette!(""))?.ctm *= affine_transform
|
||||||
}
|
}
|
||||||
Statement::Unknown(_, items) => todo!(),
|
Statement::Shape(shape_type) => {
|
||||||
|
pbrt.scene.shapes.push(Shape {
|
||||||
|
ctm: context.last().unwrap().ctm,
|
||||||
|
material: 0,
|
||||||
|
obj: shape_type,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
Statement::Unknown(s, items) => {
|
||||||
|
eprintln!("Unknown statement: {s}")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
todo!()
|
Ok(pbrt)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parse_pbrt_v4(path: impl AsRef<Path> + std::fmt::Debug) -> Result<()> {
|
pub fn parse_pbrt_v4(path: impl AsRef<Path> + std::fmt::Debug) -> Result<Pbrt> {
|
||||||
let mut tokens = 0;
|
inner_parse_pbrt(path, None)
|
||||||
for token in Parser::new(path).unwrap() {
|
|
||||||
dbg!(token);
|
|
||||||
tokens += 1;
|
|
||||||
}
|
|
||||||
dbg!(tokens);
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue