Skip to content

Commit 995f5d2

Browse files
committed
feat(pyraydeon): expose render settings through python
1 parent a27899f commit 995f5d2

File tree

11 files changed

+119
-196
lines changed

11 files changed

+119
-196
lines changed

pyraydeon/examples/py_sphere.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
PointLight,
1414
Plane,
1515
LineSegment3D,
16+
CameraOptions,
1617
)
1718

1819

@@ -107,7 +108,16 @@ def paths(self, cam):
107108
znear = 0.1
108109
zfar = 100.0
109110

110-
cam = Camera().look_at(eye, focus, up).perspective(fovy, width, height, znear, zfar)
111+
render_opts = CameraOptions(pen_px_size=4.0)
112+
113+
assert render_opts.hatch_slice_forgiveness == 1
114+
115+
cam = (
116+
Camera()
117+
.look_at(eye, focus, up)
118+
.perspective(fovy, width, height, znear, zfar)
119+
.render_options(render_opts)
120+
)
111121

112122
paths = scene.render_with_lighting(cam, seed=5)
113123

pyraydeon/src/lib.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use pyo3::prelude::*;
22

33
macro_rules! pywrap {
44
($name:ident, $wraps:ty) => {
5-
#[derive(Debug, Clone, Copy)]
5+
#[derive(Debug, Clone)]
66
#[pyclass(frozen)]
77
pub(crate) struct $name(pub(crate) $wraps);
88

@@ -22,6 +22,7 @@ macro_rules! pywrap {
2222
};
2323
}
2424

25+
mod camera;
2526
mod light;
2627
mod linear;
2728
mod material;
@@ -33,10 +34,15 @@ mod shapes;
3334
#[pymodule]
3435
fn pyraydeon(m: &Bound<'_, PyModule>) -> PyResult<()> {
3536
crate::linear::register(m)?;
36-
crate::shapes::register(m)?;
37+
38+
crate::camera::register(m)?;
3739
crate::scene::register(m)?;
40+
3841
crate::ray::register(m)?;
42+
43+
crate::shapes::register(m)?;
3944
crate::material::register(m)?;
4045
crate::light::register(m)?;
46+
4147
Ok(())
4248
}

pyraydeon/src/scene.rs

Lines changed: 8 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -4,108 +4,12 @@ use numpy::{Ix1, PyArray, PyReadonlyArray1};
44
use pyo3::prelude::*;
55
use raydeon::SceneLighting;
66

7+
use crate::camera::Camera;
78
use crate::light::PointLight;
8-
use crate::linear::{ArbitrarySpace, Point2, Point3, Vec3};
9+
use crate::linear::{ArbitrarySpace, Point2, Point3};
910
use crate::material::Material;
1011
use crate::shapes::Geometry;
1112

12-
#[derive(Debug, Clone)]
13-
#[pyclass(frozen)]
14-
pub(crate) struct Camera(pub(crate) raydeon::Camera);
15-
16-
impl ::std::ops::Deref for Camera {
17-
type Target = raydeon::Camera;
18-
19-
fn deref(&self) -> &Self::Target {
20-
&self.0
21-
}
22-
}
23-
24-
impl From<raydeon::Camera> for Camera {
25-
fn from(value: raydeon::Camera) -> Self {
26-
Self(value)
27-
}
28-
}
29-
30-
#[pymethods]
31-
impl Camera {
32-
#[new]
33-
fn new() -> Self {
34-
raydeon::Camera::default().into()
35-
}
36-
37-
fn look_at(
38-
&self,
39-
eye: &Bound<'_, PyAny>,
40-
center: &Bound<'_, PyAny>,
41-
up: &Bound<'_, PyAny>,
42-
) -> PyResult<Camera> {
43-
let eye = Point3::try_from(eye)?;
44-
let center = Vec3::try_from(center)?;
45-
let up = Vec3::try_from(up)?;
46-
let mut ncam = self.0.clone();
47-
ncam.observation =
48-
raydeon::Camera::look_at(eye.cast_unit(), center.cast_unit(), up.cast_unit());
49-
Ok(ncam.into())
50-
}
51-
52-
fn perspective(&self, fovy: f64, width: usize, height: usize, znear: f64, zfar: f64) -> Camera {
53-
let mut ncam = self.0.clone();
54-
ncam.perspective = raydeon::Camera::perspective(fovy, width, height, znear, zfar);
55-
ncam.into()
56-
}
57-
58-
#[getter]
59-
fn eye<'py>(&self, py: Python<'py>) -> Bound<'py, PyArray<f64, Ix1>> {
60-
PyArray::from_slice_bound(py, &self.0.observation.eye.to_array())
61-
}
62-
63-
#[getter]
64-
fn focus<'py>(&self, py: Python<'py>) -> Bound<'py, PyArray<f64, Ix1>> {
65-
PyArray::from_slice_bound(py, &self.0.observation.center.to_array())
66-
}
67-
68-
#[getter]
69-
fn up<'py>(&self, py: Python<'py>) -> Bound<'py, PyArray<f64, Ix1>> {
70-
PyArray::from_slice_bound(py, &self.0.observation.up.to_array())
71-
}
72-
73-
#[getter]
74-
fn fovy(&self) -> f64 {
75-
self.0.perspective.fovy
76-
}
77-
78-
#[getter]
79-
fn width(&self) -> usize {
80-
self.0.perspective.width
81-
}
82-
83-
#[getter]
84-
fn height(&self) -> usize {
85-
self.0.perspective.height
86-
}
87-
88-
#[getter]
89-
fn aspect(&self) -> f64 {
90-
self.0.perspective.aspect
91-
}
92-
93-
#[getter]
94-
fn znear(&self) -> f64 {
95-
self.0.perspective.znear
96-
}
97-
98-
#[getter]
99-
fn zfar(&self) -> f64 {
100-
self.0.perspective.zfar
101-
}
102-
103-
fn __repr__(slf: &Bound<'_, Self>) -> PyResult<String> {
104-
let class_name = slf.get_type().qualname()?;
105-
Ok(format!("{}<{:?}>", class_name, slf.borrow().0))
106-
}
107-
}
108-
10913
#[pyclass(frozen)]
11014
pub(crate) struct Scene {
11115
scene: Arc<raydeon::Scene>,
@@ -228,14 +132,12 @@ impl LineSegment3D {
228132
) -> PyResult<Self> {
229133
let p1 = Point3::try_from(p1)?;
230134
let p2 = Point3::try_from(p2)?;
231-
Ok(
232-
raydeon::path::LineSegment3D::new(
233-
p1.cast_unit(),
234-
p2.cast_unit(),
235-
material.map(|i| i.0),
236-
)
237-
.into(),
238-
)
135+
Ok(raydeon::path::LineSegment3D::new()
136+
.p1(p1.cast_unit())
137+
.p2(p2.cast_unit())
138+
.maybe_material(material.map(|i| i.0))
139+
.build()
140+
.into())
239141
}
240142

241143
#[getter]
@@ -255,7 +157,6 @@ impl LineSegment3D {
255157
}
256158

257159
pub(crate) fn register(m: &Bound<'_, PyModule>) -> PyResult<()> {
258-
m.add_class::<Camera>()?;
259160
m.add_class::<Scene>()?;
260161
m.add_class::<LineSegment2D>()?;
261162
m.add_class::<LineSegment3D>()?;

pyraydeon/src/shapes/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@ mod primitive;
88

99
pub(crate) use primitive::{AxisAlignedCuboid, Tri};
1010

11+
use crate::camera::Camera;
1112
use crate::material::Material;
1213
use crate::ray::{HitData, Ray, AABB3};
13-
use crate::scene::{Camera, LineSegment3D};
14+
use crate::scene::LineSegment3D;
1415

1516
#[derive(Debug)]
1617
enum InnerGeometry {

raydeon/examples/cube.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ fn main() {
2929
let camera = Camera::configure()
3030
.observation(Camera::look_at(eye, focus, up))
3131
.perspective(Camera::perspective(fovy, width, height, znear, zfar))
32-
.render_options(CameraOptions::defaults_for_pen_px_size(4.0))
32+
.render_options(CameraOptions::configure().pen_px_size(4.0).build())
3333
.build();
3434

3535
let paths = scene.attach_camera(camera).render();

raydeon/src/camera.rs

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ use path::SlicedSegment3D;
55
use self::view_matrix_settings::*;
66
use crate::*;
77

8+
pub const DEFAULT_PEN_PX_SIZE: f64 = 4.0;
9+
pub const DEFAULT_HATCH_PIXEL_SPACING_FACTOR: f64 = 2.0;
10+
pub const DEFAULT_HATCH_PIXEL_CHOP_QUOTIENT: f64 = 3.0;
11+
pub const DEFAULT_HATCH_SLICE_FORGIVENESS: usize = 1;
12+
pub const DEFAULT_VERT_HATCH_BRIGHTNESS_SCALING: f64 = 0.8;
13+
pub const DEFAULT_DIAG_HATCH_BRIGHTNESS_SCALING: f64 = 0.46;
14+
815
#[derive(Debug, Clone, Builder, Default)]
916
#[builder(start_fn(name = configure))]
1017
pub struct Camera {
@@ -15,31 +22,25 @@ pub struct Camera {
1522
}
1623

1724
#[derive(Debug, Clone, Builder)]
25+
#[builder(start_fn(name = configure))]
1826
pub struct CameraOptions {
27+
#[builder(default = DEFAULT_PEN_PX_SIZE)]
1928
pub pen_px_size: f64,
29+
#[builder(default = pen_px_size * DEFAULT_HATCH_PIXEL_SPACING_FACTOR)]
2030
pub hatch_pixel_spacing: f64,
31+
#[builder(default = pen_px_size / DEFAULT_HATCH_PIXEL_CHOP_QUOTIENT)]
2132
pub hatch_pixel_chop_factor: f64,
33+
#[builder(default = DEFAULT_HATCH_SLICE_FORGIVENESS)]
2234
pub hatch_slice_forgiveness: usize,
35+
#[builder(default = DEFAULT_VERT_HATCH_BRIGHTNESS_SCALING)]
2336
pub vert_hatch_brightness_scaling: f64,
37+
#[builder(default = DEFAULT_DIAG_HATCH_BRIGHTNESS_SCALING)]
2438
pub diag_hatch_brightness_scaling: f64,
2539
}
2640

2741
impl Default for CameraOptions {
2842
fn default() -> Self {
29-
Self::defaults_for_pen_px_size(4.0)
30-
}
31-
}
32-
33-
impl CameraOptions {
34-
pub fn defaults_for_pen_px_size(px_size: f64) -> Self {
35-
Self {
36-
pen_px_size: px_size,
37-
hatch_pixel_spacing: px_size * 2.0,
38-
hatch_pixel_chop_factor: px_size / 3.0,
39-
hatch_slice_forgiveness: 1,
40-
vert_hatch_brightness_scaling: 0.8,
41-
diag_hatch_brightness_scaling: 0.46,
42-
}
43+
Self::configure().build()
4344
}
4445
}
4546

0 commit comments

Comments
 (0)