More error handling

This commit is contained in:
hal8174 2025-08-09 23:23:36 +02:00
parent 5b5e491cb2
commit b56f952e9b
Signed by: hal8174
SSH key fingerprint: SHA256:NN98ZYwnrreQLSOV/g+amY7C3yL/mS1heD7bi5t6PPw

View file

@ -31,7 +31,7 @@ enum Statement {
WorldBegin,
Include(String),
ConcatTransform(AffineTransform),
Shape(ShapeType),
Shape(ShapeType, ShapeAlpha),
Unknown(String, Vec<String>),
Transform(AffineTransform),
}
@ -56,24 +56,34 @@ fn parse_shape(iter: &mut Tokenizer) -> Result<Statement> {
let zmin = -radius;
let zmax = radius;
let phimax = 360.0;
let mut alpha = ShapeAlpha::None;
while let Some(p) = iter.next_if(|p| p.starts_with('"')).transpose()? {
match p.as_str() {
"\"float radius\"" => {
radius = iter.parse_parameter()?;
}
"\"float alpha\"" => {
alpha = ShapeAlpha::Value(iter.parse_parameter()?);
}
"\"texture alpha\"" => {
alpha = ShapeAlpha::Texture(iter.parse_parameter()?);
}
_ => {
bail!("unknown argument {}", p)
}
}
}
Ok(Statement::Shape(ShapeType::Sphere {
Ok(Statement::Shape(
ShapeType::Sphere {
radius,
zmin,
zmax,
phimax,
}))
},
alpha,
))
}
"\"trianglemesh\"" => {
let mut indices = Vec::new();
@ -81,6 +91,7 @@ fn parse_shape(iter: &mut Tokenizer) -> Result<Statement> {
let mut n = Vec::new();
let mut s = Vec::new();
let mut uv = Vec::new();
let mut alpha = ShapeAlpha::None;
while let Some(q) = iter.next_if(|p| p.starts_with('"')).transpose()? {
match q.as_str() {
@ -99,6 +110,12 @@ fn parse_shape(iter: &mut Tokenizer) -> Result<Statement> {
"\"point2 uv\"" => {
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)
}
@ -128,19 +145,23 @@ fn parse_shape(iter: &mut Tokenizer) -> Result<Statement> {
if !uv.is_empty() && uv.len() != p.len() {
bail!("Number of uvs not equal to number of positions.")
}
Ok(Statement::Shape(ShapeType::TriangleMesh {
Ok(Statement::Shape(
ShapeType::TriangleMesh {
indices,
p,
n,
s,
uv,
}))
},
alpha,
))
}
"\"bilinearmesh\"" => {
let mut indices = Vec::new();
let mut p = Vec::new();
let mut n = Vec::new();
let mut uv = Vec::new();
let mut alpha = ShapeAlpha::None;
while let Some(q) = iter.next_if(|p| p.starts_with('"')).transpose()? {
match q.as_str() {
@ -156,6 +177,12 @@ fn parse_shape(iter: &mut Tokenizer) -> Result<Statement> {
"\"vector N\"" => {
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)
}
@ -183,12 +210,10 @@ fn parse_shape(iter: &mut Tokenizer) -> Result<Statement> {
if !uv.is_empty() && uv.len() != p.len() {
bail!("Number of uvs not equal to number of positions.")
}
Ok(Statement::Shape(ShapeType::BilinearMesh {
indices,
p,
n,
uv,
}))
Ok(Statement::Shape(
ShapeType::BilinearMesh { indices, p, n, uv },
alpha,
))
}
"\"loopsubdiv\"" => {
@ -196,6 +221,7 @@ fn parse_shape(iter: &mut Tokenizer) -> Result<Statement> {
let mut indices = Vec::new();
let mut p = Vec::new();
let mut alpha = ShapeAlpha::None;
while let Some(q) = iter.next_if(|p| p.starts_with('"')).transpose()? {
match q.as_str() {
@ -208,6 +234,12 @@ fn parse_shape(iter: &mut Tokenizer) -> Result<Statement> {
"\"integer levels\"" => {
levels = iter.parse_parameter()?;
}
"\"float alpha\"" => {
alpha = ShapeAlpha::Value(iter.parse_parameter()?);
}
"\"texture alpha\"" => {
alpha = ShapeAlpha::Texture(iter.parse_parameter()?);
}
_ => {
bail!("unknown argument {}", q)
}
@ -222,17 +254,17 @@ fn parse_shape(iter: &mut Tokenizer) -> Result<Statement> {
bail!("p is a required field")
}
Ok(Statement::Shape(ShapeType::LoopSubDiv {
levels,
indices,
p,
}))
Ok(Statement::Shape(
ShapeType::LoopSubDiv { levels, indices, p },
alpha,
))
}
"\"disk\"" => {
let mut height = 0.0;
let mut radius = 1.0;
let mut innerradius = 0.0;
let mut phimax = 360.0;
let mut alpha = ShapeAlpha::None;
while let Some(q) = iter.next_if(|p| p.starts_with('"')).transpose()? {
match q.as_str() {
@ -240,18 +272,57 @@ fn parse_shape(iter: &mut Tokenizer) -> Result<Statement> {
"\"float radius\"" => radius = iter.parse_parameter()?,
"\"float innerradius\"" => innerradius = 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)
}
}
}
Ok(Statement::Shape(ShapeType::Disk {
Ok(Statement::Shape(
ShapeType::Disk {
height,
radius,
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)),
}
@ -426,7 +497,6 @@ struct Parser<P> {
impl<P: AsRef<Path> + std::fmt::Debug> Parser<P> {
fn new(path: P) -> Result<Self> {
dbg!(&path);
Ok(Self {
iter: Lexer::new(path.as_ref())?,
path,
@ -489,6 +559,18 @@ enum ShapeType {
innerradius: f64,
phimax: f64,
},
PlyMesh {
filename: String,
displacement: Option<String>,
edgelength: Float,
},
}
#[derive(Debug)]
enum ShapeAlpha {
None,
Value(Float),
Texture(String),
}
#[derive(Debug)]
@ -496,6 +578,7 @@ struct Shape {
ctm: AffineTransform,
material: usize,
obj: ShapeType,
alpha: ShapeAlpha,
}
#[derive(Debug)]
@ -545,7 +628,12 @@ fn inner_parse_pbrt(
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);
match p {
Statement::AttributeBegin => context.push(context.last().ok_or(miette!(""))?.clone()),
@ -559,17 +647,39 @@ fn inner_parse_pbrt(
Statement::Transform(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 {
ctm: context.last().unwrap().ctm,
material: 0,
obj: shape_type,
alpha: shape_alpha,
});
}
Statement::Unknown(s, items) => {
eprintln!("Unknown statement: {s}")
}
Statement::WorldBegin => (),
s => bail!("unexpected statemnet in world settings: {s:?}"),
}
}