More error handling
This commit is contained in:
parent
5b5e491cb2
commit
b56f952e9b
1 changed files with 145 additions and 35 deletions
|
|
@ -31,7 +31,7 @@ enum Statement {
|
||||||
WorldBegin,
|
WorldBegin,
|
||||||
Include(String),
|
Include(String),
|
||||||
ConcatTransform(AffineTransform),
|
ConcatTransform(AffineTransform),
|
||||||
Shape(ShapeType),
|
Shape(ShapeType, ShapeAlpha),
|
||||||
Unknown(String, Vec<String>),
|
Unknown(String, Vec<String>),
|
||||||
Transform(AffineTransform),
|
Transform(AffineTransform),
|
||||||
}
|
}
|
||||||
|
|
@ -56,24 +56,34 @@ fn parse_shape(iter: &mut Tokenizer) -> Result<Statement> {
|
||||||
let zmin = -radius;
|
let zmin = -radius;
|
||||||
let zmax = radius;
|
let zmax = radius;
|
||||||
let phimax = 360.0;
|
let phimax = 360.0;
|
||||||
|
let mut alpha = ShapeAlpha::None;
|
||||||
|
|
||||||
while let Some(p) = iter.next_if(|p| p.starts_with('"')).transpose()? {
|
while let Some(p) = iter.next_if(|p| p.starts_with('"')).transpose()? {
|
||||||
match p.as_str() {
|
match p.as_str() {
|
||||||
"\"float radius\"" => {
|
"\"float radius\"" => {
|
||||||
radius = iter.parse_parameter()?;
|
radius = iter.parse_parameter()?;
|
||||||
}
|
}
|
||||||
|
"\"float alpha\"" => {
|
||||||
|
alpha = ShapeAlpha::Value(iter.parse_parameter()?);
|
||||||
|
}
|
||||||
|
"\"texture alpha\"" => {
|
||||||
|
alpha = ShapeAlpha::Texture(iter.parse_parameter()?);
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
bail!("unknown argument {}", p)
|
bail!("unknown argument {}", p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Statement::Shape(ShapeType::Sphere {
|
Ok(Statement::Shape(
|
||||||
radius,
|
ShapeType::Sphere {
|
||||||
zmin,
|
radius,
|
||||||
zmax,
|
zmin,
|
||||||
phimax,
|
zmax,
|
||||||
}))
|
phimax,
|
||||||
|
},
|
||||||
|
alpha,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
"\"trianglemesh\"" => {
|
"\"trianglemesh\"" => {
|
||||||
let mut indices = Vec::new();
|
let mut indices = Vec::new();
|
||||||
|
|
@ -81,6 +91,7 @@ fn parse_shape(iter: &mut Tokenizer) -> Result<Statement> {
|
||||||
let mut n = Vec::new();
|
let mut n = Vec::new();
|
||||||
let mut s = Vec::new();
|
let mut s = Vec::new();
|
||||||
let mut uv = Vec::new();
|
let mut uv = Vec::new();
|
||||||
|
let mut alpha = ShapeAlpha::None;
|
||||||
|
|
||||||
while let Some(q) = iter.next_if(|p| p.starts_with('"')).transpose()? {
|
while let Some(q) = iter.next_if(|p| p.starts_with('"')).transpose()? {
|
||||||
match q.as_str() {
|
match q.as_str() {
|
||||||
|
|
@ -99,6 +110,12 @@ fn parse_shape(iter: &mut Tokenizer) -> Result<Statement> {
|
||||||
"\"point2 uv\"" => {
|
"\"point2 uv\"" => {
|
||||||
iter.parse_list_2(&mut uv, |u, v| [u, v])?;
|
iter.parse_list_2(&mut uv, |u, v| [u, v])?;
|
||||||
}
|
}
|
||||||
|
"\"float alpha\"" => {
|
||||||
|
alpha = ShapeAlpha::Value(iter.parse_parameter()?);
|
||||||
|
}
|
||||||
|
"\"texture alpha\"" => {
|
||||||
|
alpha = ShapeAlpha::Texture(iter.parse_parameter()?);
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
bail!("unknown argument {}", q)
|
bail!("unknown argument {}", q)
|
||||||
}
|
}
|
||||||
|
|
@ -128,19 +145,23 @@ fn parse_shape(iter: &mut Tokenizer) -> Result<Statement> {
|
||||||
if !uv.is_empty() && uv.len() != p.len() {
|
if !uv.is_empty() && uv.len() != p.len() {
|
||||||
bail!("Number of uvs not equal to number of positions.")
|
bail!("Number of uvs not equal to number of positions.")
|
||||||
}
|
}
|
||||||
Ok(Statement::Shape(ShapeType::TriangleMesh {
|
Ok(Statement::Shape(
|
||||||
indices,
|
ShapeType::TriangleMesh {
|
||||||
p,
|
indices,
|
||||||
n,
|
p,
|
||||||
s,
|
n,
|
||||||
uv,
|
s,
|
||||||
}))
|
uv,
|
||||||
|
},
|
||||||
|
alpha,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
"\"bilinearmesh\"" => {
|
"\"bilinearmesh\"" => {
|
||||||
let mut indices = Vec::new();
|
let mut indices = Vec::new();
|
||||||
let mut p = Vec::new();
|
let mut p = Vec::new();
|
||||||
let mut n = Vec::new();
|
let mut n = Vec::new();
|
||||||
let mut uv = Vec::new();
|
let mut uv = Vec::new();
|
||||||
|
let mut alpha = ShapeAlpha::None;
|
||||||
|
|
||||||
while let Some(q) = iter.next_if(|p| p.starts_with('"')).transpose()? {
|
while let Some(q) = iter.next_if(|p| p.starts_with('"')).transpose()? {
|
||||||
match q.as_str() {
|
match q.as_str() {
|
||||||
|
|
@ -156,6 +177,12 @@ fn parse_shape(iter: &mut Tokenizer) -> Result<Statement> {
|
||||||
"\"vector N\"" => {
|
"\"vector N\"" => {
|
||||||
iter.parse_list_3(&mut n, Dir3::new)?;
|
iter.parse_list_3(&mut n, Dir3::new)?;
|
||||||
}
|
}
|
||||||
|
"\"float alpha\"" => {
|
||||||
|
alpha = ShapeAlpha::Value(iter.parse_parameter()?);
|
||||||
|
}
|
||||||
|
"\"texture alpha\"" => {
|
||||||
|
alpha = ShapeAlpha::Texture(iter.parse_parameter()?);
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
bail!("unknown argument {}", q)
|
bail!("unknown argument {}", q)
|
||||||
}
|
}
|
||||||
|
|
@ -183,12 +210,10 @@ fn parse_shape(iter: &mut Tokenizer) -> Result<Statement> {
|
||||||
if !uv.is_empty() && uv.len() != p.len() {
|
if !uv.is_empty() && uv.len() != p.len() {
|
||||||
bail!("Number of uvs not equal to number of positions.")
|
bail!("Number of uvs not equal to number of positions.")
|
||||||
}
|
}
|
||||||
Ok(Statement::Shape(ShapeType::BilinearMesh {
|
Ok(Statement::Shape(
|
||||||
indices,
|
ShapeType::BilinearMesh { indices, p, n, uv },
|
||||||
p,
|
alpha,
|
||||||
n,
|
))
|
||||||
uv,
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
"\"loopsubdiv\"" => {
|
"\"loopsubdiv\"" => {
|
||||||
|
|
@ -196,6 +221,7 @@ fn parse_shape(iter: &mut Tokenizer) -> Result<Statement> {
|
||||||
let mut indices = Vec::new();
|
let mut indices = Vec::new();
|
||||||
|
|
||||||
let mut p = Vec::new();
|
let mut p = Vec::new();
|
||||||
|
let mut alpha = ShapeAlpha::None;
|
||||||
|
|
||||||
while let Some(q) = iter.next_if(|p| p.starts_with('"')).transpose()? {
|
while let Some(q) = iter.next_if(|p| p.starts_with('"')).transpose()? {
|
||||||
match q.as_str() {
|
match q.as_str() {
|
||||||
|
|
@ -208,6 +234,12 @@ fn parse_shape(iter: &mut Tokenizer) -> Result<Statement> {
|
||||||
"\"integer levels\"" => {
|
"\"integer levels\"" => {
|
||||||
levels = iter.parse_parameter()?;
|
levels = iter.parse_parameter()?;
|
||||||
}
|
}
|
||||||
|
"\"float alpha\"" => {
|
||||||
|
alpha = ShapeAlpha::Value(iter.parse_parameter()?);
|
||||||
|
}
|
||||||
|
"\"texture alpha\"" => {
|
||||||
|
alpha = ShapeAlpha::Texture(iter.parse_parameter()?);
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
bail!("unknown argument {}", q)
|
bail!("unknown argument {}", q)
|
||||||
}
|
}
|
||||||
|
|
@ -222,17 +254,17 @@ fn parse_shape(iter: &mut Tokenizer) -> Result<Statement> {
|
||||||
bail!("p is a required field")
|
bail!("p is a required field")
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Statement::Shape(ShapeType::LoopSubDiv {
|
Ok(Statement::Shape(
|
||||||
levels,
|
ShapeType::LoopSubDiv { levels, indices, p },
|
||||||
indices,
|
alpha,
|
||||||
p,
|
))
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
"\"disk\"" => {
|
"\"disk\"" => {
|
||||||
let mut height = 0.0;
|
let mut height = 0.0;
|
||||||
let mut radius = 1.0;
|
let mut radius = 1.0;
|
||||||
let mut innerradius = 0.0;
|
let mut innerradius = 0.0;
|
||||||
let mut phimax = 360.0;
|
let mut phimax = 360.0;
|
||||||
|
let mut alpha = ShapeAlpha::None;
|
||||||
|
|
||||||
while let Some(q) = iter.next_if(|p| p.starts_with('"')).transpose()? {
|
while let Some(q) = iter.next_if(|p| p.starts_with('"')).transpose()? {
|
||||||
match q.as_str() {
|
match q.as_str() {
|
||||||
|
|
@ -240,18 +272,57 @@ fn parse_shape(iter: &mut Tokenizer) -> Result<Statement> {
|
||||||
"\"float radius\"" => radius = iter.parse_parameter()?,
|
"\"float radius\"" => radius = iter.parse_parameter()?,
|
||||||
"\"float innerradius\"" => innerradius = iter.parse_parameter()?,
|
"\"float innerradius\"" => innerradius = iter.parse_parameter()?,
|
||||||
"\"float phimax\"" => phimax = iter.parse_parameter()?,
|
"\"float phimax\"" => phimax = iter.parse_parameter()?,
|
||||||
|
"\"float alpha\"" => {
|
||||||
|
alpha = ShapeAlpha::Value(iter.parse_parameter()?);
|
||||||
|
}
|
||||||
|
"\"texture alpha\"" => {
|
||||||
|
alpha = ShapeAlpha::Texture(iter.parse_parameter()?);
|
||||||
|
}
|
||||||
_ => {
|
_ => {
|
||||||
bail!("unknown argument {}", q)
|
bail!("unknown argument {}", q)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Statement::Shape(ShapeType::Disk {
|
Ok(Statement::Shape(
|
||||||
height,
|
ShapeType::Disk {
|
||||||
radius,
|
height,
|
||||||
innerradius,
|
radius,
|
||||||
phimax,
|
innerradius,
|
||||||
}))
|
phimax,
|
||||||
|
},
|
||||||
|
alpha,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
"\"plymesh\"" => {
|
||||||
|
let mut filename = String::new();
|
||||||
|
let mut displacement = None;
|
||||||
|
let mut edgelength = 1.0;
|
||||||
|
let mut alpha = ShapeAlpha::None;
|
||||||
|
while let Some(q) = iter.next_if(|p| p.starts_with('"')).transpose()? {
|
||||||
|
match q.as_str() {
|
||||||
|
"\"string filename\"" => filename = dbg!(iter.parse_parameter()?),
|
||||||
|
"\"texture displacement\"" => displacement = Some(iter.parse_parameter()?),
|
||||||
|
"\"float edgelength\"" => edgelength = iter.parse_parameter()?,
|
||||||
|
"\"float alpha\"" => {
|
||||||
|
alpha = ShapeAlpha::Value(iter.parse_parameter()?);
|
||||||
|
}
|
||||||
|
"\"texture alpha\"" => {
|
||||||
|
alpha = ShapeAlpha::Texture(iter.parse_parameter()?);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
bail!("unknown argument {}", q)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(Statement::Shape(
|
||||||
|
ShapeType::PlyMesh {
|
||||||
|
filename,
|
||||||
|
displacement,
|
||||||
|
edgelength,
|
||||||
|
},
|
||||||
|
alpha,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
_ => Err(miette!("Unknown shape {}", shape_type)),
|
_ => Err(miette!("Unknown shape {}", shape_type)),
|
||||||
}
|
}
|
||||||
|
|
@ -426,7 +497,6 @@ struct Parser<P> {
|
||||||
|
|
||||||
impl<P: AsRef<Path> + std::fmt::Debug> Parser<P> {
|
impl<P: AsRef<Path> + std::fmt::Debug> Parser<P> {
|
||||||
fn new(path: P) -> Result<Self> {
|
fn new(path: P) -> Result<Self> {
|
||||||
dbg!(&path);
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
iter: Lexer::new(path.as_ref())?,
|
iter: Lexer::new(path.as_ref())?,
|
||||||
path,
|
path,
|
||||||
|
|
@ -489,6 +559,18 @@ enum ShapeType {
|
||||||
innerradius: f64,
|
innerradius: f64,
|
||||||
phimax: f64,
|
phimax: f64,
|
||||||
},
|
},
|
||||||
|
PlyMesh {
|
||||||
|
filename: String,
|
||||||
|
displacement: Option<String>,
|
||||||
|
edgelength: Float,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
enum ShapeAlpha {
|
||||||
|
None,
|
||||||
|
Value(Float),
|
||||||
|
Texture(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
@ -496,6 +578,7 @@ struct Shape {
|
||||||
ctm: AffineTransform,
|
ctm: AffineTransform,
|
||||||
material: usize,
|
material: usize,
|
||||||
obj: ShapeType,
|
obj: ShapeType,
|
||||||
|
alpha: ShapeAlpha,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
@ -545,7 +628,12 @@ fn inner_parse_pbrt(
|
||||||
|
|
||||||
let mut pbrt = Pbrt::new();
|
let mut pbrt = Pbrt::new();
|
||||||
|
|
||||||
while let Some(p) = parser.next(context.last().unwrap()).transpose()? {
|
// parse global settings
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let p = parser
|
||||||
|
.next(context.last().unwrap())
|
||||||
|
.ok_or_else(|| miette!(""))??;
|
||||||
// dbg!(&p);
|
// 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()),
|
||||||
|
|
@ -559,17 +647,39 @@ fn inner_parse_pbrt(
|
||||||
Statement::Transform(affine_transform) => {
|
Statement::Transform(affine_transform) => {
|
||||||
context.last_mut().ok_or(miette!(""))?.ctm = dbg!(affine_transform)
|
context.last_mut().ok_or(miette!(""))?.ctm = dbg!(affine_transform)
|
||||||
}
|
}
|
||||||
Statement::Shape(shape_type) => {
|
Statement::Unknown(s, items) => {
|
||||||
|
eprintln!("Unknown statement: {s}")
|
||||||
|
}
|
||||||
|
Statement::WorldBegin => break,
|
||||||
|
s => bail!("unexpected statemnet in global settings: {s:?}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while let Some(p) = parser.next(context.last().unwrap()).transpose()? {
|
||||||
|
match p {
|
||||||
|
Statement::AttributeBegin => context.push(context.last().ok_or(miette!(""))?.clone()),
|
||||||
|
Statement::AttributeEnd => {
|
||||||
|
context.pop();
|
||||||
|
}
|
||||||
|
Statement::Include(_) => unreachable!(),
|
||||||
|
Statement::ConcatTransform(affine_transform) => {
|
||||||
|
context.last_mut().ok_or(miette!(""))?.ctm *= affine_transform
|
||||||
|
}
|
||||||
|
Statement::Transform(affine_transform) => {
|
||||||
|
context.last_mut().ok_or(miette!(""))?.ctm = dbg!(affine_transform)
|
||||||
|
}
|
||||||
|
Statement::Shape(shape_type, shape_alpha) => {
|
||||||
pbrt.scene.shapes.push(Shape {
|
pbrt.scene.shapes.push(Shape {
|
||||||
ctm: context.last().unwrap().ctm,
|
ctm: context.last().unwrap().ctm,
|
||||||
material: 0,
|
material: 0,
|
||||||
obj: shape_type,
|
obj: shape_type,
|
||||||
|
alpha: shape_alpha,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Statement::Unknown(s, items) => {
|
Statement::Unknown(s, items) => {
|
||||||
eprintln!("Unknown statement: {s}")
|
eprintln!("Unknown statement: {s}")
|
||||||
}
|
}
|
||||||
Statement::WorldBegin => (),
|
s => bail!("unexpected statemnet in world settings: {s:?}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue