pbrt_r3/core/api/
print_context.rs

1use super::parse_context::*;
2use crate::core::base::*;
3use crate::core::param_set::*;
4
5use std::cell::{Cell, RefCell};
6use std::io::Write;
7use std::sync::Arc;
8
9fn get_param_type(s: &str) -> (&str, &str) {
10    let ss: Vec<&str> = s.split_ascii_whitespace().collect();
11    if ss.len() == 2 {
12        return (ss[0], ss[1]);
13    } else if ss.len() == 1 {
14        if let Some(t) = wellknown_params::find_type_from_key(ss[0]) {
15            return (t, ss[0]);
16        } else {
17            return ("", ss[0]);
18        }
19    } else {
20        return ("", s);
21    }
22}
23
24fn get_type(s: &str) -> &str {
25    let (t, _) = get_param_type(s);
26    match t {
27        "string" => "s",
28        "spectrum" => "s",
29        "texture" => "s",
30        "bool" => "b",
31        "integer" => "i",
32        "point" | "point2" | "point3" | "point4" => "p",
33        "normal" => "p",
34        "vector" | "vector2" | "vector3" | "vector4" => "p",
35        "color" => "p",
36        "rgb" => "p",
37        "blackbody" => "f",
38        _ => "f",
39    }
40}
41
42pub struct PrintContext {
43    pub writer: Arc<RefCell<dyn Write>>,
44    pub omit_long_values: bool,
45    pub indent: Cell<i32>,
46}
47
48impl PrintContext {
49    pub fn new(w: Arc<RefCell<dyn Write>>) -> Self {
50        PrintContext {
51            writer: w,
52            omit_long_values: false,
53            indent: Cell::<i32>::new(0),
54        }
55    }
56
57    pub fn new_with_params(w: Arc<RefCell<dyn Write>>, omit_long_values: bool) -> Self {
58        PrintContext {
59            writer: w,
60            omit_long_values,
61            indent: Cell::<i32>::new(0),
62        }
63    }
64
65    pub fn new_stdout(omit_long_values: bool) -> Self {
66        PrintContext {
67            writer: Arc::new(RefCell::new(std::io::stdout())),
68            omit_long_values,
69            indent: Cell::<i32>::new(0),
70        }
71    }
72
73    pub fn inc_indent(&mut self) {
74        self.indent.set(self.indent.get() + 1);
75    }
76    pub fn dec_indent(&mut self) {
77        self.indent.set(self.indent.get() - 1);
78    }
79
80    pub fn get_indent(&self) -> String {
81        return self.get_indent_i(self.indent.get());
82    }
83
84    pub fn get_indent_i(&self, count: i32) -> String {
85        let mut s = String::new();
86        for _ in 0..count {
87            s += "    ";
88        }
89        return s;
90    }
91
92    fn print(&self, s: &str) {
93        _ = self.writer.borrow_mut().write_all(s.as_bytes());
94    }
95
96    fn convert_transform(&self, values: &[Float]) -> String {
97        let mut s = String::from("[");
98        let len = values.len();
99        for i in 0..len {
100            let v = values[i];
101            s += &format!("{v}");
102            if i != len - 1 {
103                s += " ";
104            }
105        }
106        s += "]";
107        return s;
108    }
109
110    fn convert_values(&self, params: &ParamSet, key: &str) -> String {
111        let mut s = String::from("");
112        let t = get_type(key);
113        s += "[";
114        match t {
115            "s" => {
116                let values = params.get_strings(key);
117                let len = values.len();
118                for i in 0..len {
119                    let v = &values[i];
120                    s += &format!("\"{v}\"");
121                    if i != len - 1 {
122                        s += " ";
123                    }
124                }
125            }
126            "b" => {
127                let values = params.get_bools(key);
128                let len = values.len();
129                for i in 0..len {
130                    let v = values[i];
131                    if v {
132                        s += "\"true\"";
133                    } else {
134                        s += "\"false\"";
135                    }
136                    if i != len - 1 {
137                        s += " ";
138                    }
139                }
140            }
141            "i" => {
142                let values = params.get_ints_ref(key).unwrap();
143                if !self.omit_long_values || values.len() <= 16 {
144                    let len = values.len();
145                    for i in 0..len {
146                        let v = values[i];
147                        s += &format!("{v}");
148                        if i != len - 1 {
149                            s += " ";
150                        }
151                    }
152                } else {
153                    s += "...";
154                }
155            }
156            "p" => {
157                let values = params.get_points_ref(key).unwrap();
158                if !self.omit_long_values || values.len() <= 16 {
159                    let len = values.len();
160                    for i in 0..len {
161                        let v = values[i];
162                        s += &format!("{v}");
163                        if i != len - 1 {
164                            s += " ";
165                        }
166                    }
167                } else {
168                    s += "...";
169                }
170            }
171            _ => {
172                let values = params.get_floats_ref(key).unwrap();
173                if !self.omit_long_values || values.len() <= 16 {
174                    let len = values.len();
175                    for i in 0..len {
176                        let v = values[i];
177                        s += &format!("{v}");
178                        if i != len - 1 {
179                            s += " ";
180                        }
181                    }
182                } else {
183                    s += "...";
184                }
185            }
186        }
187        s += "]";
188        return s;
189    }
190
191    fn convert_params(&self, params: &ParamSet) -> String {
192        let mut s = String::from("");
193        let keys = &params.keys;
194        if !keys.is_empty() {
195            let indent = self.get_indent_i(self.indent.get() + 1);
196            for key in keys {
197                let values = self.convert_values(params, key);
198                s += "\n";
199                s += &format!("{indent}\"{key}\" {values}");
200            }
201        }
202        return s;
203    }
204
205    fn with_params(&self, params: &ParamSet) -> String {
206        if !params.keys.is_empty() {
207            return format!(" {}", self.convert_params(params));
208        } else {
209            return String::from("");
210        }
211    }
212}
213
214impl ParseContext for PrintContext {
215    fn pbrt_cleanup(&mut self) {
216        self.print(&format!("{}Cleanup\n", self.get_indent()));
217    }
218
219    fn pbrt_identity(&mut self) {
220        self.print(&format!("{}Identity\n", self.get_indent()));
221    }
222
223    fn pbrt_translate(&mut self, dx: Float, dy: Float, dz: Float) {
224        self.print(&format!("{}Translate {dx} {dy} {dz}\n", self.get_indent()));
225    }
226
227    fn pbrt_rotate(&mut self, angle: Float, ax: Float, ay: Float, az: Float) {
228        self.print(&format!(
229            "{}Rotate {angle} {ax} {ay} {az}\n",
230            self.get_indent()
231        ));
232    }
233
234    fn pbrt_scale(&mut self, sx: Float, sy: Float, sz: Float) {
235        self.print(&format!("{}Scale {sx} {sy} {sz}\n", self.get_indent()));
236    }
237
238    fn pbrt_look_at(
239        &mut self,
240        ex: Float,
241        ey: Float,
242        ez: Float,
243        lx: Float,
244        ly: Float,
245        lz: Float,
246        ux: Float,
247        uy: Float,
248        uz: Float,
249    ) {
250        self.print(&format!(
251            "{}LookAt {ex} {ey} {ez} {lx} {ly} {lz} {ux} {uy} {uz}\n",
252            self.get_indent()
253        ));
254    }
255
256    fn pbrt_concat_transform(&mut self, transform: &[Float]) {
257        let s_transform = self.convert_transform(transform);
258        self.print(&format!(
259            "{}ConcatTransform {s_transform}\n",
260            self.get_indent()
261        ));
262    }
263
264    fn pbrt_transform(&mut self, transform: &[Float]) {
265        let s_transform = self.convert_transform(transform);
266        self.print(&format!("{}Transform {s_transform}\n", self.get_indent()));
267    }
268
269    fn pbrt_coordinate_system(&mut self, name: &str) {
270        self.print(&format!(
271            "{}CoordinateSystem \"{name}\"\n",
272            self.get_indent()
273        ));
274    }
275
276    fn pbrt_coord_sys_transform(&mut self, name: &str) {
277        self.print(&format!(
278            "{}CoordSysTransform \"{name}\"\n",
279            self.get_indent()
280        ));
281    }
282
283    fn pbrt_active_transform_all(&mut self) {
284        self.print(&format!("{}ActiveTransfrom All\n", self.get_indent()));
285    }
286
287    fn pbrt_active_transform_end_time(&mut self) {
288        self.print(&format!("{}ActiveTransfrom EndTime\n", self.get_indent()));
289    }
290
291    fn pbrt_active_transform_start_time(&mut self) {
292        self.print(&format!("{}ActiveTransfrom StartTime\n", self.get_indent()));
293    }
294
295    fn pbrt_transform_times(&mut self, start: Float, end: Float) {
296        self.print(&format!(
297            "{}TransformTimes {start} {end}\n",
298            self.get_indent()
299        ));
300    }
301
302    fn pbrt_pixel_filter(&mut self, name: &str, params: &ParamSet) {
303        let s_params = self.with_params(params);
304        self.print(&format!(
305            "{}PixelFilter \"{name}\"{s_params}\n",
306            self.get_indent()
307        ));
308    }
309
310    fn pbrt_film(&mut self, name: &str, params: &ParamSet) {
311        let s_params = self.with_params(params);
312        self.print(&format!("{}Film \"{name}\"{s_params}\n", self.get_indent()));
313    }
314
315    fn pbrt_sampler(&mut self, name: &str, params: &ParamSet) {
316        let s_params = self.with_params(params);
317        self.print(&format!(
318            "{}Sampler \"{name}\"{s_params}\n",
319            self.get_indent()
320        ));
321    }
322
323    fn pbrt_accelerator(&mut self, name: &str, params: &ParamSet) {
324        let s_params = self.with_params(params);
325        self.print(&format!(
326            "{}Accelerator \"{name}\"{s_params}\n",
327            self.get_indent()
328        ));
329    }
330
331    fn pbrt_integrator(&mut self, name: &str, params: &ParamSet) {
332        let s_params = self.with_params(params);
333        self.print(&format!(
334            "{}Integrator \"{name}\"{s_params}\n",
335            self.get_indent()
336        ));
337    }
338
339    fn pbrt_camera(&mut self, name: &str, params: &ParamSet) {
340        let s_params = self.with_params(params);
341        self.print(&format!(
342            "{}Camera \"{name}\"{s_params}\n",
343            self.get_indent()
344        ));
345    }
346
347    fn pbrt_make_named_medium(&mut self, name: &str, params: &ParamSet) {
348        let s_params = self.with_params(params);
349        self.print(&format!(
350            "{}NamedMedium \"{name}\"{s_params}\n",
351            self.get_indent()
352        ));
353    }
354
355    fn pbrt_medium_interface(&mut self, inside_name: &str, outside_name: &str) {
356        self.print(&format!(
357            "{}MediumInterface \"{inside_name}\" \"{outside_name}\"\n",
358            self.get_indent()
359        ));
360    }
361
362    fn pbrt_world_begin(&mut self) {
363        self.print(&format!("{}WorldBegin\n", self.get_indent()));
364        self.inc_indent();
365    }
366
367    fn pbrt_attribute_begin(&mut self) {
368        self.print(&format!("{}AttributeBegin\n", self.get_indent()));
369        self.inc_indent();
370    }
371
372    fn pbrt_attribute_end(&mut self) {
373        self.dec_indent();
374        self.print(&format!("{}AttributeEnd\n", self.get_indent()));
375    }
376
377    fn pbrt_transform_begin(&mut self) {
378        self.print(&format!("{}TransformBegin\n", self.get_indent()));
379        self.inc_indent();
380    }
381
382    fn pbrt_transform_end(&mut self) {
383        self.dec_indent();
384        self.print(&format!("{}TransformEnd\n", self.get_indent()));
385    }
386
387    fn pbrt_texture(&mut self, name: &str, t: &str, tex_name: &str, params: &ParamSet) {
388        let s_params = self.with_params(params);
389        self.print(&format!(
390            "{}Texture \"{name}\" \"{t}\" \"{tex_name}\"{s_params}\n",
391            self.get_indent()
392        ));
393    }
394
395    fn pbrt_material(&mut self, name: &str, params: &ParamSet) {
396        let s_params = self.with_params(params);
397        self.print(&format!(
398            "{}Material \"{name}\"{s_params}\n",
399            self.get_indent()
400        ));
401    }
402
403    fn pbrt_make_named_material(&mut self, name: &str, params: &ParamSet) {
404        let s_params = self.with_params(params);
405        self.print(&format!(
406            "{}MakeNamedMaterial \"{name}\"{s_params}\n",
407            self.get_indent()
408        ));
409    }
410
411    fn pbrt_named_material(&mut self, name: &str) {
412        self.print(&format!("{}NamedMaterial \"{name}\"\n", self.get_indent()));
413    }
414
415    fn pbrt_light_source(&mut self, name: &str, params: &ParamSet) {
416        let s_params = self.with_params(params);
417        self.print(&format!(
418            "{}LightSource \"{name}\"{s_params}\n",
419            self.get_indent()
420        ));
421    }
422
423    fn pbrt_area_light_source(&mut self, name: &str, params: &ParamSet) {
424        let s_params = self.with_params(params);
425        self.print(&format!(
426            "{}AreaLightSource \"{name}\"{s_params}\n",
427            self.get_indent()
428        ));
429    }
430
431    fn pbrt_shape(&mut self, name: &str, params: &ParamSet) {
432        let s_params = self.with_params(params);
433        self.print(&format!(
434            "{}Shape \"{name}\"{s_params}\n",
435            self.get_indent()
436        ));
437    }
438
439    fn pbrt_reverse_orientation(&mut self) {
440        self.print(&format!("{}ReverseOrientation\n", self.get_indent()));
441    }
442
443    fn pbrt_object_begin(&mut self, name: &str) {
444        self.print(&format!("{}ObjectBegin \"{name}\"\n", self.get_indent()));
445        self.inc_indent();
446    }
447
448    fn pbrt_object_end(&mut self) {
449        self.dec_indent();
450        self.print(&format!("{}ObjectEnd\n", self.get_indent()));
451    }
452
453    fn pbrt_object_instance(&mut self, name: &str) {
454        self.print(&format!("{}ObjectInstance \"{name}\"\n", self.get_indent()));
455    }
456
457    fn pbrt_world_end(&mut self) {
458        self.dec_indent();
459        self.print(&format!("{}WorldEnd\n", self.get_indent()));
460    }
461
462    fn pbrt_parse_file(&mut self, _file_name: &str) {
463        /*
464        self.print(&format!(
465            "{}Include \"{file_name}\"\n",
466            self.get_indent()
467        ));
468        */
469    }
470    fn pbrt_parse_string(&mut self, _s: &str) {
471        /*
472        self.print(&format!(
473            "{}Include \"{file_name}\"\n",
474            self.get_indent()
475        ));
476        */
477    }
478
479    fn pbrt_work_dir_begin(&mut self, _path: &str) {
480        //Do not anything!
481    }
482
483    fn pbrt_work_dir_end(&mut self) {
484        //Do not anything!
485    }
486
487    fn pbrt_include(&mut self, filename: &str, params: &ParamSet) {
488        let s_params = self.with_params(params);
489        self.print(&format!(
490            "{}Include \"{filename}\"{s_params}\n",
491            self.get_indent()
492        ));
493    }
494}