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 = ¶ms.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 }
470 fn pbrt_parse_string(&mut self, _s: &str) {
471 }
478
479 fn pbrt_work_dir_begin(&mut self, _path: &str) {
480 }
482
483 fn pbrt_work_dir_end(&mut self) {
484 }
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}