pbrt_r3/core/api/scene_context/
scene_context.rs

1use super::graphics_state::GraphicsState;
2use super::graphics_state::MaterialInstance;
3use super::render_options::RenderOptions;
4
5use crate::accelerators::*;
6use crate::cameras::*;
7use crate::core::api::parse_context::*;
8use crate::core::base::*;
9use crate::core::camera::*;
10use crate::core::error::*;
11use crate::core::film::*;
12use crate::core::filter::*;
13use crate::core::integrator::*;
14use crate::core::light::*;
15use crate::core::material::*;
16use crate::core::medium::*;
17use crate::core::param_set::*;
18use crate::core::primitive::*;
19use crate::core::scene::*;
20use crate::core::shape::*;
21use crate::core::spectrum::*;
22use crate::core::stats::*;
23use crate::core::texture::*;
24use crate::core::transform::transform_set::*;
25use crate::core::transform::*;
26use crate::filters::*;
27use crate::integrators::*;
28use crate::lights::*;
29use crate::materials::*;
30use crate::media::*;
31use crate::samplers::*;
32use crate::shapes::*;
33use crate::textures::*;
34
35use log::*;
36use std::cell::RefCell;
37use std::collections::HashMap;
38use std::ops::Deref;
39use std::path::Path;
40use std::sync::Arc;
41use std::sync::RwLock;
42
43thread_local!(static N_SHAPES: StatCounter = StatCounter::new("Scene/Shapes")); //"Scene/Shapes created"
44thread_local!(static N_LIGHTS: StatCounter = StatCounter::new("Scene/Lights"));
45thread_local!(static N_AREA_LIGHTS: StatCounter = StatCounter::new("Scene/AreaLights"));
46thread_local!(static N_MATERIALS: StatCounter = StatCounter::new("Scene/Materials")); //"Scene/Materials created"
47thread_local!(static N_OBJECT_INSTANCES_CREATED: StatCounter = StatCounter::new("Scene/Object instances created")); //"Scene/Object instances created"
48thread_local!(static N_OBJECT_INSTANCES_USED: StatCounter = StatCounter::new("Scene/Object instances used")); //"Scene/Object instances created"
49
50#[derive(Debug, PartialEq)]
51enum APIState {
52    OptionsBlock,
53    WorldBlock,
54}
55
56fn get_param_type(s: &str) -> (&str, &str) {
57    let ss: Vec<&str> = s.split_ascii_whitespace().collect();
58    if ss.len() == 2 {
59        return (ss[0], ss[1]);
60    } else if ss.len() == 1 {
61        if let Some(t) = wellknown_params::find_type_from_key(ss[0]) {
62            return (t, ss[0]);
63        } else {
64            return ("", ss[0]);
65        }
66    } else {
67        return ("", s);
68    }
69}
70
71type FloatTextureMap = HashMap<String, Arc<dyn Texture<Float>>>;
72//type SpectrumTextureMap = HashMap<String, Arc<dyn Texture<Spectrum>>>;
73
74pub struct SceneContext {
75    current_api_state: APIState,
76    transforms: Vec<RefCell<TransformSet>>,
77    transform_bits: Vec<u32>,
78    graphics_states: Vec<RefCell<GraphicsState>>,
79    render_options: RefCell<RenderOptions>,
80    named_coordinate_systems: HashMap<String, RefCell<TransformSet>>,
81    float_textures: RefCell<HashMap<String, Arc<dyn Texture<Float>>>>,
82    spectrum_textures: RefCell<HashMap<String, Arc<dyn Texture<Spectrum>>>>,
83    work_dirs: Vec<String>,
84}
85
86impl SceneContext {
87    pub fn new() -> Self {
88        let mut ctx = SceneContext {
89            current_api_state: APIState::OptionsBlock,
90            transforms: Vec::new(),
91            transform_bits: Vec::new(),
92            graphics_states: Vec::new(),
93            render_options: RefCell::new(RenderOptions::new()),
94            named_coordinate_systems: HashMap::new(),
95            float_textures: RefCell::new(HashMap::new()),
96            spectrum_textures: RefCell::new(HashMap::new()),
97            work_dirs: Vec::new(),
98        };
99        ctx.initialize();
100        return ctx;
101    }
102
103    pub fn initialize(&mut self) {
104        self.transforms.clear();
105        self.transform_bits.clear();
106        self.graphics_states.clear();
107        self.transforms.push(RefCell::new(TransformSet::new()));
108        self.transform_bits.push(ALL_TRANSFORM_BITS);
109        self.graphics_states
110            .push(RefCell::new(GraphicsState::new()));
111    }
112
113    pub fn push_transform(&mut self) {
114        self.transforms
115            .push(self.transforms[self.transforms.len() - 1].clone());
116        self.transform_bits
117            .push(self.transform_bits[self.transform_bits.len() - 1]);
118    }
119
120    pub fn pop_transform(&mut self) {
121        self.transform_bits.pop();
122        self.transforms.pop();
123    }
124
125    pub fn push_graphics_state(&mut self) {
126        self.graphics_states
127            .push(self.graphics_states[self.transforms.len() - 1].clone());
128    }
129
130    pub fn pop_graphics_state(&mut self) {
131        self.graphics_states.pop();
132    }
133
134    pub fn print_error(&self, e: &PbrtError) {
135        match e.kind {
136            PbrtErrorKind::Error => {
137                error!("{}", e.msg);
138            }
139            PbrtErrorKind::Warning => {
140                warn!("{}", e.msg);
141            }
142        }
143    }
144
145    pub fn verify_initialized(&mut self, _fun: &str) {
146        //
147    }
148
149    pub fn verify_options(&mut self, fun: &str) {
150        if self.current_api_state != APIState::OptionsBlock {
151            error!(
152                "Options cannot be set inside world block;\n\"{}\" not allowed. Ignoring.",
153                fun
154            );
155        }
156    }
157
158    pub fn verify_world(&mut self, fun: &str) {
159        if self.current_api_state == APIState::WorldBlock {
160            error!(
161                "Scene description must be inside world block;\n\"{}\" not allowed. Ignoring.",
162                fun
163            );
164        }
165    }
166
167    pub fn replace_params_int(
168        &mut self,
169        name: &str,
170        key: &str,
171        value: i32,
172    ) -> Result<(), PbrtError> {
173        match name {
174            "Sampler" => {
175                let mut opts = self.render_options.borrow_mut();
176                let params = &mut opts.sampler_params;
177                params.replace_one_int(key, value);
178                return Ok(());
179            }
180            _ => {
181                let msg = format!("\"{}\" is unknown params name.", name);
182                return Err(PbrtError::error(&msg));
183            }
184        }
185    }
186
187    pub fn replace_params_string(
188        &mut self,
189        name: &str,
190        key: &str,
191        value: &str,
192    ) -> Result<(), PbrtError> {
193        match name {
194            "Film" => {
195                let mut opts = self.render_options.borrow_mut();
196                let params = &mut opts.film_params;
197                params.replace_one_string(key, value);
198                return Ok(());
199            }
200            _ => {
201                let msg = format!("\"{}\" is unknown params name.", name);
202                return Err(PbrtError::error(&msg));
203            }
204        }
205    }
206
207    pub fn create_medium_interface(&self) -> MediumInterface {
208        let attr = self.graphics_states[self.graphics_states.len() - 1].borrow();
209        let opts = self.render_options.borrow();
210        let inside_name = attr.current_inside_medium.clone();
211        let outside_name = attr.current_outside_medium.clone();
212        let mut m = MediumInterface::new();
213        if let Some(medium) = opts.named_media.get(&inside_name) {
214            //println!("inside_name: {}", inside_name);
215            m.set_inside(medium);
216        }
217        if let Some(medium) = opts.named_media.get(&outside_name) {
218            //println!("outside_name: {}", outside_name);
219            m.set_outside(medium);
220        }
221        return m;
222    }
223
224    pub fn shape_may_set_material_parameters(params: &ParamSet) -> bool {
225        for name in params.strings.keys() {
226            if name != "alpha" && name != "shadowalpha" {
227                return true;
228            }
229        }
230        for (name, p) in &params.floats {
231            let param = p.borrow();
232            if param.len() == 1 && name != "radius" {
233                return true;
234            }
235        }
236        for (name, p) in &params.strings {
237            let param = p.borrow();
238            if param.len() == 1 && name != "filename" && name != "type" && name != "scheme" {
239                return true;
240            }
241        }
242        for p in params.bools.values() {
243            let param = p.borrow();
244            if param.len() == 1 {
245                return true;
246            }
247        }
248        for p in params.ints.values() {
249            let param = p.borrow();
250            if param.len() == 1 {
251                return true;
252            }
253        }
254        for p in params.spectrums.values() {
255            let param = p.borrow();
256            if param.len() == 1 {
257                return true;
258            }
259        }
260        for p in params.points.values() {
261            let param = p.borrow();
262            if param.len() == 3 {
263                return true;
264            }
265        }
266        return false;
267    }
268
269    pub fn get_material_for_shape(&self, params: &ParamSet) -> Option<Arc<dyn Material>> {
270        if Self::shape_may_set_material_parameters(params) {
271            let attr = self.graphics_states[self.graphics_states.len() - 1].borrow();
272            if let Some(mat_inst) = attr.current_material.as_ref() {
273                let mat_inst = mat_inst.borrow();
274                let f_tex = attr.float_textures.as_ref().borrow();
275                let s_tex = attr.spectrum_textures.as_ref().borrow();
276                let mp = TextureParams::new(params, &mat_inst.params, &f_tex, &s_tex);
277                match self.make_material(&mat_inst.name, &mp) {
278                    Ok(material) => {
279                        return Some(material);
280                    }
281                    Err(e) => {
282                        self.print_error(&e);
283                        return None;
284                    }
285                }
286            }
287            return None;
288        } else {
289            let attr = self.graphics_states[self.graphics_states.len() - 1].borrow();
290            if let Some(mat_inst) = attr.current_material.as_ref() {
291                let mat_inst = mat_inst.borrow();
292                return Some(Arc::clone(&mat_inst.material));
293            }
294        }
295        return None;
296    }
297
298    pub fn get_named_material(&self, name: &str) -> Option<Arc<RefCell<MaterialInstance>>> {
299        let attr = self.graphics_states[self.graphics_states.len() - 1].borrow();
300        let materials = attr.named_materials.as_ref().borrow();
301        let mat = materials.get(name);
302        match mat {
303            Some(m) => {
304                return Some(Arc::clone(m));
305            }
306            None => None,
307        }
308    }
309
310    pub fn get_current_instance_name(&self) -> Option<String> {
311        let opts = self.render_options.borrow();
312        match opts.current_instance_name.as_ref() {
313            Some(name) => {
314                return Some(name.clone());
315            }
316            None => None,
317        }
318    }
319
320    pub fn get_filepath(&self, name: &str) -> Option<String> {
321        let path = Path::new(name);
322        if path.is_absolute() || self.work_dirs.is_empty() {
323            return Some(String::from(path.to_str().unwrap()));
324        } else {
325            for d in self.work_dirs.iter().rev() {
326                let dir = Path::new(d);
327                let full_path = dir.join(name);
328                if full_path.exists() {
329                    return Some(String::from(full_path.to_str().unwrap()));
330                }
331            }
332            return None;
333        }
334    }
335
336    pub fn create_shapes(
337        &self,
338        name: &str,
339        object2world: &Transform,
340        reverse_orientation: bool,
341        params: &ParamSet,
342        float_textures: &FloatTextureMap,
343    ) -> Result<Vec<Arc<dyn Shape>>, PbrtError> {
344        match name {
345            "trianglemesh" => {
346                //Do not use make_absolute_path
347                return create_shapes(
348                    name,
349                    object2world,
350                    reverse_orientation,
351                    params,
352                    float_textures,
353                );
354            }
355            "curve" => {
356                //Do not use make_absolute_path
357                return create_shapes(
358                    name,
359                    object2world,
360                    reverse_orientation,
361                    params,
362                    float_textures,
363                );
364            }
365            _ => {
366                let params = self.make_absolute_path(params);
367                return create_shapes(
368                    name,
369                    object2world,
370                    reverse_orientation,
371                    &params,
372                    float_textures,
373                );
374            }
375        }
376    }
377
378    pub fn make_shapes_core(
379        &self,
380        name: &str,
381        object2world: &Transform,
382        reverse_orientation: bool,
383        params: &ParamSet,
384    ) -> Vec<Arc<dyn Shape>> {
385        let attr = self.graphics_states[self.graphics_states.len() - 1].borrow();
386        let f_tex = attr.float_textures.borrow();
387        match self.create_shapes(
388            name,
389            object2world,
390            reverse_orientation,
391            params,
392            f_tex.deref(),
393        ) {
394            Ok(shapes) => {
395                N_SHAPES.with(|c| c.add(shapes.len() as u64));
396                return shapes;
397            }
398            Err(e) => {
399                self.print_error(&e);
400                return Vec::new();
401            }
402        }
403    }
404
405    pub fn make_shapes(
406        &self,
407        name: &str,
408        object2world: &Transform,
409        reverse_orientation: bool,
410        params: &ParamSet,
411    ) -> Vec<Arc<dyn Shape>> {
412        let attr = self.graphics_states[self.graphics_states.len() - 1].borrow();
413        if !attr.area_light_name.is_empty() {
414            let two_sided = attr.area_light_params.find_one_bool("twosided", true);
415            let two_sided = params.find_one_bool("twosided", two_sided);
416            let mut params = params.clone();
417            params.replace_one_bool("bool twosided", two_sided);
418            return self.make_shapes_core(name, object2world, reverse_orientation, &params);
419        }
420        return self.make_shapes_core(name, object2world, reverse_orientation, params);
421    }
422
423    pub fn get_named_material_matte(&self, mp: &TextureParams, key: &str) -> Arc<dyn Material> {
424        if let Some(mat) = self.get_named_material(key) {
425            return Arc::clone(&mat.borrow().material);
426        } else {
427            //
428            return self.make_material("matte", mp).unwrap();
429        }
430    }
431
432    pub fn make_material(
433        &self,
434        name: &str,
435        mp: &TextureParams,
436    ) -> Result<Arc<dyn Material>, PbrtError> {
437        if name == "subsurface" || name == "kdsubsurface" {
438            let render_options = self.render_options.borrow();
439            if render_options.integrator_name != "path"
440                && render_options.integrator_name != "volpath"
441            {
442                warn!("Subsurface scattering material \"{}\" used, but \"{}\" integrator doesn't support subsurface scattering. Use \"path\" or \"volpath\".", name, render_options.integrator_name);
443            }
444        }
445
446        let material = if name == "mix" {
447            let m1 = mp.find_string("namedmaterial1", "");
448            let m2 = mp.find_string("namedmaterial2", "");
449            let mat1 = self.get_named_material_matte(mp, &m1);
450            let mat2 = self.get_named_material_matte(mp, &m2);
451            create_mix_material(mp, &mat1, &mat2)?
452        } else {
453            create_material(name, mp)?
454        };
455        N_MATERIALS.with(|c| c.inc());
456        return Ok(material);
457    }
458
459    fn make_material_params(
460        &self,
461        name: &str,
462        geom_params: &ParamSet,
463        mat_params: &ParamSet,
464    ) -> Option<Arc<dyn Material>> {
465        let attr = self.graphics_states.last().unwrap().borrow();
466        let f_tex = attr.float_textures.clone();
467        let s_tex = attr.spectrum_textures.clone();
468        let f = f_tex.as_ref().borrow();
469        let s = s_tex.as_ref().borrow();
470        let mp = TextureParams::new(geom_params, mat_params, f.deref(), s.deref());
471        match self.make_material(name, &mp) {
472            Ok(material) => {
473                return Some(material);
474            }
475            Err(e) => {
476                self.print_error(&e);
477                return None;
478            }
479        }
480    }
481
482    pub fn make_float_texture(
483        &self,
484        name: &str,
485        tex2world: &Transform,
486        tp: &TextureParams,
487    ) -> Option<Arc<dyn Texture<Float>>> {
488        if let Some(texinfo) = create_texinfo(tp) {
489            let key = format!("{:?}", texinfo);
490            let textures = self.float_textures.borrow();
491            if let Some(texture) = textures.get(&key) {
492                return Some(Arc::clone(texture));
493            }
494        }
495
496        match create_float_texture(name, tex2world, tp) {
497            Ok(texture) => {
498                if let Some(texinfo) = create_texinfo(tp) {
499                    let key = format!("{:?}", texinfo);
500                    let mut textures = self.float_textures.borrow_mut();
501                    textures.insert(key, Arc::clone(&texture));
502                }
503
504                return Some(texture);
505            }
506            Err(e) => {
507                self.print_error(&e);
508                return None;
509            }
510        }
511    }
512
513    pub fn make_spectrum_texture(
514        &self,
515        name: &str,
516        tex2world: &Transform,
517        tp: &TextureParams,
518    ) -> Option<Arc<dyn Texture<Spectrum>>> {
519        if let Some(texinfo) = create_texinfo(tp) {
520            let key = format!("{:?}", texinfo);
521            let textures = self.spectrum_textures.borrow();
522            if let Some(texture) = textures.get(&key) {
523                return Some(Arc::clone(texture));
524            }
525        }
526
527        match create_spectrum_texture(name, tex2world, tp) {
528            Ok(texture) => {
529                if let Some(texinfo) = create_texinfo(tp) {
530                    let key = format!("{:?}", texinfo);
531                    let mut textures = self.spectrum_textures.borrow_mut();
532                    textures.insert(key, Arc::clone(&texture));
533                }
534
535                return Some(texture);
536            }
537            Err(e) => {
538                self.print_error(&e);
539                return None;
540            }
541        }
542    }
543
544    pub fn make_light(
545        &self,
546        name: &str,
547        light2world: &Transform,
548        medium_interface: &MediumInterface,
549        params: &ParamSet,
550    ) -> Option<Arc<dyn Light>> {
551        match create_light(name, light2world, medium_interface, params) {
552            Ok(light) => {
553                N_LIGHTS.with(|c| c.inc());
554                return Some(light);
555            }
556            Err(e) => {
557                self.print_error(&e);
558                return None;
559            }
560        }
561    }
562
563    pub fn make_area_light(
564        &self,
565        name: &str,
566        light2world: &Transform,
567        medium_interface: &MediumInterface,
568        params: &ParamSet,
569        shape: &Arc<dyn Shape>,
570    ) -> Option<Arc<dyn Light>> {
571        let attr = self.graphics_states[self.graphics_states.len() - 1].borrow();
572        if attr.area_light_name.is_empty() {
573            return None;
574        }
575        match create_area_light(name, light2world, medium_interface, params, shape) {
576            Ok(light) => {
577                N_LIGHTS.with(|c| c.inc());
578                N_AREA_LIGHTS.with(|c| c.inc());
579                return Some(light);
580            }
581            Err(e) => {
582                self.print_error(&e);
583                return None;
584            }
585        }
586    }
587
588    pub fn make_accelerator(
589        &self,
590        name: &str,
591        prims: &[Arc<dyn Primitive>],
592        params: &ParamSet,
593    ) -> Option<Arc<dyn Primitive>> {
594        match create_accelerator(name, prims, params) {
595            Ok(accelerator) => {
596                return Some(accelerator);
597            }
598            Err(_e) => {
599                return None;
600            }
601        }
602    }
603
604    pub fn make_medium(
605        &self,
606        name: &str,
607        params: &ParamSet,
608        medium2world: &Transform,
609    ) -> Option<Arc<dyn Medium>> {
610        return create_medium(name, params, medium2world);
611    }
612
613    pub fn make_filter(&self) -> Option<Arc<dyn Filter>> {
614        let opts = self.render_options.borrow();
615        match create_filter(&opts.filter_name, &opts.filter_params) {
616            Ok(filter) => {
617                return Some(filter);
618            }
619            Err(e) => {
620                self.print_error(&e);
621                return None;
622            }
623        }
624    }
625
626    pub fn make_film(&self, filter: &Arc<dyn Filter>) -> Option<Arc<RwLock<Film>>> {
627        let opts = self.render_options.borrow();
628        match create_film(&opts.film_name, &opts.film_params, filter) {
629            Ok(film) => {
630                return Some(film);
631            }
632            Err(e) => {
633                self.print_error(&e);
634                return None;
635            }
636        }
637    }
638
639    pub fn make_camera(&self) -> Option<Arc<dyn Camera>> {
640        if let Some(camera_transform) = self.named_coordinate_systems.get("camera") {
641            let camera_to_world = &camera_transform.borrow();
642            if let Some(filter) = self.make_filter() {
643                if let Some(film) = self.make_film(&filter) {
644                    let medium_interface = self.create_medium_interface();
645                    let opts = self.render_options.borrow();
646                    let start_time = opts.transform_start_time;
647                    let end_time = opts.transform_end_time;
648                    let animated_cam_2_world = AnimatedTransform::new(
649                        &camera_to_world[0],
650                        start_time,
651                        &camera_to_world[1],
652                        end_time,
653                    );
654                    match create_camera(
655                        &opts.camera_name,
656                        &opts.camera_params,
657                        &animated_cam_2_world,
658                        &film,
659                        &medium_interface,
660                    ) {
661                        Ok(camara) => {
662                            return Some(camara);
663                        }
664                        Err(e) => {
665                            self.print_error(&e);
666                            return None;
667                        }
668                    }
669                }
670            }
671        }
672        return None;
673    }
674
675    pub fn make_integrator(&self) -> Option<Arc<RwLock<dyn Integrator>>> {
676        let camera = self.make_camera();
677        if camera.is_none() {
678            error!("Unable to create camera");
679            return None;
680        }
681        let camera = camera.unwrap();
682        let film = camera.as_ref().get_film();
683        let opts = self.render_options.borrow();
684        let sampler = create_sampler(&opts.sampler_name, &opts.sampler_params, &film);
685        if sampler.is_err() {
686            self.print_error(&sampler.err().unwrap());
687            return None;
688        }
689        let sampler = sampler.unwrap();
690
691        if opts.have_scattering_media
692            && opts.integrator_name != "volpath"
693            && opts.integrator_name != "bdpt"
694            && opts.integrator_name != "mlt"
695        {
696            warn!("Scene has scattering media but \"{}\" integrator doesn't support volume scattering. Use \"volpath\", \"bdpt\" or \"mlt\".", opts.integrator_name);
697        }
698        // Warn if no light sources are defined
699        if opts.lights.is_empty() {
700            warn!("No light sources defined in scene; rendering a black image.");
701        }
702        match create_integrator(
703            &opts.integrator_name,
704            &opts.integrator_params,
705            &sampler,
706            &camera,
707        ) {
708            Ok(integrator) => {
709                return Some(integrator);
710            }
711            Err(e) => {
712                self.print_error(&e);
713                return None;
714            }
715        }
716    }
717
718    pub fn make_scene(&self) -> Option<Arc<Scene>> {
719        let opts = self.render_options.borrow();
720        if let Some(accelerator) = self.make_accelerator(
721            &opts.accelerator_name,
722            &opts.primitives,
723            &opts.accelerator_params,
724        ) {
725            let scene = Arc::new(Scene::new(&accelerator, &opts.lights));
726            return Some(scene);
727        }
728        return None;
729    }
730
731    //AbsolutePath
732    pub fn make_absolute_path(&self, params: &ParamSet) -> ParamSet {
733        let mut n_params = params.clone();
734        let keys = params.get_keys();
735        //Spectrum
736        {
737            let target_keys: Vec<_> = keys
738                .iter()
739                .filter(|key| -> bool {
740                    let (t, _) = get_param_type(key);
741                    return t == "spectrum";
742                })
743                .collect();
744            for key in target_keys {
745                if let Some(names) = params.get_strings_ref(key) {
746                    for name in names.iter() {
747                        if let Some(path) = self.get_filepath(name) {
748                            let ret = SampledSpectrum::load_sampled_spectrum_file(&path);
749                            match ret {
750                                Ok(spc) => {
751                                    let spc = Spectrum::from(&spc);
752                                    n_params.add_spectrum_no_key(name, &spc);
753                                }
754                                Err(e) => {
755                                    self.print_error(&e);
756                                }
757                            }
758                        }
759                    }
760                }
761            }
762        }
763        // blackbody
764        {
765            let target_keys: Vec<_> = keys
766                .iter()
767                .filter(|key| -> bool {
768                    let (t, _) = get_param_type(key);
769                    return t == "blackbody";
770                })
771                .collect();
772            for key in target_keys {
773                if let Some(values) = params.get_floats_ref(key) {
774                    let spc = SampledSpectrum::from_blackbody(&values);
775                    let spc = Spectrum::from(&spc);
776                    n_params.add_spectrum_no_key(key, &spc);
777                }
778            }
779        }
780
781        //filaname && bsdffile
782        {
783            let file_path_keys = ["filename", "mapname", "bsdffile", "lensfile"];
784
785            let target_keys: Vec<_> = keys
786                .iter()
787                .filter(|key| -> bool {
788                    let (_, key) = get_param_type(key);
789                    for file_path_key in file_path_keys {
790                        if file_path_key == key {
791                            return true;
792                        }
793                    }
794                    return false;
795                })
796                .collect();
797            let mut replaces = Vec::new();
798            for key in target_keys {
799                if let Some(names) = params.get_strings_ref(key) {
800                    for name in names.iter() {
801                        if let Some(path) = self.get_filepath(name) {
802                            replaces.push((key.clone(), path));
803                        }
804                    }
805                }
806            }
807            for (key, value) in replaces.iter() {
808                n_params.replace_one_string(key, value);
809            }
810        }
811
812        return n_params;
813    }
814}
815
816impl ParseContext for SceneContext {
817    fn pbrt_cleanup(&mut self) {
818        self.initialize();
819    }
820
821    fn pbrt_identity(&mut self) {
822        self.verify_initialized("Identity");
823
824        let t = Transform::identity();
825        let mut trns = self.transforms[self.transforms.len() - 1].borrow_mut();
826        trns.set_transform(&t, self.transform_bits[self.transform_bits.len() - 1]);
827    }
828
829    fn pbrt_translate(&mut self, dx: Float, dy: Float, dz: Float) {
830        self.verify_initialized("Translate");
831
832        let t = Transform::translate(dx, dy, dz);
833        let mut trns = self.transforms[self.transforms.len() - 1].borrow_mut();
834        trns.mul_transform(&t, self.transform_bits[self.transform_bits.len() - 1]);
835    }
836
837    fn pbrt_rotate(&mut self, angle: Float, ax: Float, ay: Float, az: Float) {
838        self.verify_initialized("Rotate");
839
840        let t = Transform::rotate(angle, ax, ay, az);
841        let mut trns = self.transforms[self.transforms.len() - 1].borrow_mut();
842        trns.mul_transform(&t, self.transform_bits[self.transform_bits.len() - 1]);
843    }
844
845    fn pbrt_scale(&mut self, sx: Float, sy: Float, sz: Float) {
846        self.verify_initialized("Scale");
847
848        let t = Transform::scale(sx, sy, sz);
849        let mut trns = self.transforms[self.transforms.len() - 1].borrow_mut();
850        trns.mul_transform(&t, self.transform_bits[self.transform_bits.len() - 1]);
851    }
852
853    fn pbrt_look_at(
854        &mut self,
855        ex: Float,
856        ey: Float,
857        ez: Float,
858        lx: Float,
859        ly: Float,
860        lz: Float,
861        ux: Float,
862        uy: Float,
863        uz: Float,
864    ) {
865        self.verify_initialized("LookAt");
866
867        let t = Transform::look_at(ex, ey, ez, lx, ly, lz, ux, uy, uz); //w2c
868        let mut trns = self.transforms[self.transforms.len() - 1].borrow_mut();
869        trns.mul_transform(&t, self.transform_bits[self.transform_bits.len() - 1]);
870    }
871
872    fn pbrt_concat_transform(&mut self, t: &[Float]) {
873        self.verify_initialized("ConcatTransform");
874
875        #[rustfmt::skip]
876        let m = Matrix4x4::from([
877            t[0], t[4], t[8], t[12],
878            t[1], t[5], t[9], t[13],
879            t[2], t[6], t[10], t[14],
880            t[3], t[7], t[11], t[15],
881        ]);
882        if let Some(im) = m.inverse() {
883            let t = Transform::from((m, im));
884            let mut trns = self.transforms[self.transforms.len() - 1].borrow_mut();
885            trns.mul_transform(&t, self.transform_bits[self.transform_bits.len() - 1]);
886        } else {
887            error!("Singular matrix in MatrixInvert");
888        }
889    }
890
891    fn pbrt_transform(&mut self, t: &[Float]) {
892        self.verify_initialized("Transform");
893
894        #[rustfmt::skip]
895        let m = Matrix4x4::from([
896            t[0], t[4], t[8], t[12],
897            t[1], t[5], t[9], t[13],
898            t[2], t[6], t[10], t[14],
899            t[3], t[7], t[11], t[15],
900        ]);
901        if let Some(im) = m.inverse() {
902            let t = Transform::from((m, im));
903            let mut trns = self.transforms[self.transforms.len() - 1].borrow_mut();
904            trns.set_transform(&t, self.transform_bits[self.transform_bits.len() - 1]);
905        } else {
906            error!("Singular matrix in MatrixInvert");
907        }
908    }
909
910    fn pbrt_coordinate_system(&mut self, name: &str) {
911        self.verify_initialized("CoordinateSystem");
912
913        let trns = self.transforms[self.transforms.len() - 1].borrow();
914        self.named_coordinate_systems
915            .insert(String::from(name), RefCell::new(trns.clone()));
916    }
917
918    fn pbrt_coord_sys_transform(&mut self, name: &str) {
919        self.verify_initialized("CoordSysTransform");
920
921        if let Some(t) = self.named_coordinate_systems.get(&String::from(name)) {
922            let t = t.borrow();
923            let mut trns = self.transforms[self.transforms.len() - 1].borrow_mut();
924            trns.set(&t, self.transform_bits[self.transform_bits.len() - 1]); //tmx
925        } else {
926            warn!("Couldn't find named coordinate system \"{}\"", name);
927        }
928    }
929
930    fn pbrt_active_transform_all(&mut self) {
931        let last = self.transform_bits.len() - 1;
932        self.transform_bits[last] = ALL_TRANSFORM_BITS;
933    }
934
935    fn pbrt_active_transform_end_time(&mut self) {
936        let last = self.transform_bits.len() - 1;
937        self.transform_bits[last] = END_TRANSFORM_BITS;
938    }
939
940    fn pbrt_active_transform_start_time(&mut self) {
941        let last = self.transform_bits.len() - 1;
942        self.transform_bits[last] = START_TRANSFORM_BITS;
943    }
944
945    fn pbrt_transform_times(&mut self, start: Float, end: Float) {
946        self.verify_options("TransformTimes");
947
948        let mut opts = self.render_options.borrow_mut();
949        opts.transform_start_time = start;
950        opts.transform_end_time = end;
951    }
952
953    fn pbrt_pixel_filter(&mut self, name: &str, params: &ParamSet) {
954        self.verify_options("PixelFilter");
955
956        let mut opts = self.render_options.borrow_mut();
957        opts.filter_name = String::from(name);
958        opts.filter_params.set(params);
959    }
960
961    fn pbrt_film(&mut self, name: &str, params: &ParamSet) {
962        self.verify_options("Film");
963        let mut opts = self.render_options.borrow_mut();
964        opts.film_name = String::from(name);
965        opts.film_params.set(params);
966    }
967
968    fn pbrt_sampler(&mut self, name: &str, params: &ParamSet) {
969        self.verify_options("Sampler");
970
971        let mut opts = self.render_options.borrow_mut();
972        opts.sampler_name = String::from(name);
973        opts.sampler_params.set(params);
974    }
975
976    fn pbrt_accelerator(&mut self, name: &str, params: &ParamSet) {
977        self.verify_options("Accelerator");
978
979        let mut opts = self.render_options.borrow_mut();
980        opts.accelerator_name = String::from(name);
981        opts.accelerator_params.set(params);
982    }
983
984    fn pbrt_integrator(&mut self, name: &str, params: &ParamSet) {
985        self.verify_options("Integrator");
986
987        let mut opts = self.render_options.borrow_mut();
988        opts.integrator_name = String::from(name);
989        opts.integrator_params.set(params);
990    }
991
992    fn pbrt_camera(&mut self, name: &str, params: &ParamSet) {
993        self.verify_options("Camera");
994
995        let params = self.make_absolute_path(params);
996
997        let trns = self.transforms[self.transforms.len() - 1].borrow();
998        let mut opts = self.render_options.borrow_mut();
999        opts.camera_name = String::from(name);
1000        opts.camera_params.set(&params);
1001        //Camera to World
1002        self.named_coordinate_systems.insert(
1003            String::from("camera"),
1004            RefCell::new(TransformSet::inverse(&trns)),
1005        );
1006    }
1007
1008    fn pbrt_make_named_medium(&mut self, name: &str, params: &ParamSet) {
1009        self.verify_initialized("MakeNamedMedium");
1010
1011        let t = params.find_one_string("type", "");
1012        if t == "" {
1013            error!("No parameter string \"type\" found in MakeNamedMedium");
1014        } else {
1015            let trns = self.transforms[self.transforms.len() - 1].borrow();
1016            if let Some(m) = self.make_medium(&t, params, &trns[0]) {
1017                let mut opts = self.render_options.borrow_mut();
1018                opts.named_media.insert(String::from(name), m);
1019            } else {
1020                error!("Unable to create medium \"{}\" \"{}\"", name, t);
1021            }
1022        }
1023    }
1024
1025    fn pbrt_medium_interface(&mut self, inside_name: &str, outside_name: &str) {
1026        self.verify_initialized("MediumInterface");
1027
1028        let mut atrs = self.graphics_states[self.graphics_states.len() - 1].borrow_mut();
1029        let mut opts = self.render_options.borrow_mut();
1030        atrs.current_inside_medium = String::from(inside_name);
1031        atrs.current_outside_medium = String::from(outside_name);
1032        opts.have_scattering_media = true;
1033    }
1034
1035    fn pbrt_world_begin(&mut self) {
1036        self.verify_options("WorldBegin");
1037
1038        self.current_api_state = APIState::OptionsBlock;
1039        let mut trns = self.transforms[self.transforms.len() - 1].borrow_mut();
1040        trns.set_transform(&Transform::identity(), ALL_TRANSFORM_BITS);
1041        let last = self.transform_bits.len() - 1;
1042        self.transform_bits[last] = ALL_TRANSFORM_BITS;
1043        self.named_coordinate_systems
1044            .insert(String::from("world"), RefCell::new(trns.clone()));
1045    }
1046
1047    fn pbrt_attribute_begin(&mut self) {
1048        self.verify_world("AttributeBegin");
1049
1050        self.push_graphics_state();
1051        self.push_transform();
1052        let mut attr = self.graphics_states[self.graphics_states.len() - 1].borrow_mut();
1053        attr.float_textures_shared = true;
1054        attr.spectrum_textures_shared = true;
1055        attr.named_materials_shared = true;
1056    }
1057
1058    fn pbrt_attribute_end(&mut self) {
1059        self.verify_world("AttributeEnd");
1060
1061        self.pop_transform();
1062        self.pop_graphics_state();
1063    }
1064
1065    fn pbrt_transform_begin(&mut self) {
1066        self.verify_world("TransformBegin");
1067
1068        self.push_transform();
1069    }
1070
1071    fn pbrt_transform_end(&mut self) {
1072        self.verify_world("Transformend");
1073
1074        self.pop_transform();
1075    }
1076
1077    fn pbrt_texture(&mut self, name: &str, t: &str, tex_name: &str, params: &ParamSet) {
1078        self.verify_world("Texture");
1079
1080        let params = self.make_absolute_path(params);
1081
1082        // Check for filename errors
1083        if let Some(maps) = params.get_strings_ref("filename") {
1084            if maps.len() == 1 {
1085                let path = Path::new(&maps[0]);
1086                if !path.exists() {
1087                    warn!("Texture file \"{}\" does not exist.", path.display());
1088                    return;
1089                }
1090            }
1091        }
1092
1093        let attr = self.graphics_states[self.graphics_states.len() - 1].borrow_mut();
1094
1095        let mut f_tex = attr.float_textures.as_ref().borrow_mut();
1096        let mut s_tex = attr.spectrum_textures.as_ref().borrow_mut();
1097        let tp = TextureParams::new(&params, &params, &f_tex, &s_tex);
1098
1099        if t == "float" {
1100            let cur_trans = self.transforms[self.transforms.len() - 1].borrow();
1101            if let Some(ft) = self.make_float_texture(tex_name, &cur_trans[0], &tp) {
1102                //warn
1103                f_tex.insert(String::from(name), ft);
1104            }
1105        } else if t == "color" || t == "rgb" || t == "spectrum" {
1106            let cur_trans = self.transforms[self.transforms.len() - 1].borrow();
1107            if let Some(st) = self.make_spectrum_texture(tex_name, &cur_trans[0], &tp) {
1108                //warn
1109                s_tex.insert(String::from(name), st);
1110            }
1111        } else {
1112            //error
1113        }
1114    }
1115
1116    fn pbrt_material(&mut self, name: &str, params: &ParamSet) {
1117        self.verify_world("Material");
1118
1119        if name == "" {
1120            let mut attr = self.graphics_states.last().unwrap().borrow_mut();
1121            attr.current_material = None;
1122        } else {
1123            let params = self.make_absolute_path(params);
1124            let empty_params = ParamSet::new();
1125            if let Some(mtl) = self.make_material_params(name, &params, &empty_params) {
1126                let mut attr = self.graphics_states.last().unwrap().borrow_mut();
1127                attr.current_material = Some(Arc::new(RefCell::new(MaterialInstance::new(
1128                    name, mtl, &params,
1129                ))));
1130            }
1131        }
1132    }
1133
1134    fn pbrt_make_named_material(&mut self, name: &str, params: &ParamSet) {
1135        //self.verify_world("MakeNamedMaterial");
1136
1137        let params = self.make_absolute_path(params);
1138        let empty_params = ParamSet::new();
1139        let mat_name = params.find_one_string("type", "");
1140        if mat_name.is_empty() {
1141            error!("No parameter string \"type\" found in MakeNamedMaterial");
1142        }
1143        if let Some(mat) = self.make_material_params(&mat_name, &params, &empty_params) {
1144            let mut attr = self.graphics_states.last().unwrap().borrow_mut();
1145            {
1146                let named_materials = attr.named_materials.as_ref().borrow();
1147                if named_materials.contains_key(name) {
1148                    warn!("Named material \"{}\" redefined.", name);
1149                }
1150            }
1151
1152            if attr.named_materials_shared {
1153                let materials = attr.clone_named_materials();
1154                attr.named_materials = materials;
1155                attr.named_materials_shared = false;
1156            }
1157            {
1158                let mut named_materials = attr.named_materials.as_ref().borrow_mut();
1159                named_materials.insert(
1160                    String::from(name),
1161                    Arc::new(RefCell::new(MaterialInstance::new(&mat_name, mat, &params))),
1162                );
1163            }
1164        }
1165    }
1166
1167    fn pbrt_named_material(&mut self, name: &str) {
1168        self.verify_world("NamedMaterial");
1169
1170        if let Some(mtl) = self.get_named_material(name) {
1171            let mut attr = self.graphics_states[self.graphics_states.len() - 1].borrow_mut();
1172            attr.current_material = Some(mtl);
1173        } else {
1174            error!("NamedMaterial \"{}\" unknown.", name);
1175        }
1176    }
1177
1178    fn pbrt_light_source(&mut self, name: &str, params: &ParamSet) {
1179        self.verify_world("LightSource");
1180
1181        let params = self.make_absolute_path(params);
1182
1183        let cur_trans = self.transforms[self.transforms.len() - 1].borrow()[0];
1184        let mi = self.create_medium_interface();
1185        if let Some(lt) = self.make_light(name, &cur_trans, &mi, &params) {
1186            let mut opts = self.render_options.borrow_mut();
1187            opts.lights.push(lt);
1188        }
1189    }
1190
1191    fn pbrt_area_light_source(&mut self, name: &str, params: &ParamSet) {
1192        self.verify_world("AreaLightSource");
1193
1194        let params = self.make_absolute_path(params);
1195
1196        let mut attr = self.graphics_states[self.graphics_states.len() - 1].borrow_mut();
1197        attr.area_light_name = String::from(name);
1198        attr.area_light_params = params;
1199    }
1200
1201    fn pbrt_shape(&mut self, name: &str, params: &ParamSet) {
1202        self.verify_world("Shape");
1203
1204        let mut prims: Vec<Arc<dyn Primitive>> = Vec::new();
1205        let mut area_lights: Vec<Arc<dyn Light>> = Vec::new();
1206
1207        let attr = self.graphics_states[self.graphics_states.len() - 1].borrow();
1208        //
1209        let cur_trans = self.transforms[self.transforms.len() - 1].borrow();
1210        if !cur_trans.is_animated() {
1211            let object2world = cur_trans[0].clone();
1212            let shapes = self.make_shapes(name, &object2world, attr.reverse_orientation, params);
1213            if !shapes.is_empty() {
1214                prims.reserve(shapes.len());
1215                let mtl = self.get_material_for_shape(params);
1216                let mi = self.create_medium_interface();
1217
1218                for s in shapes {
1219                    let area = self.make_area_light(
1220                        &attr.area_light_name,
1221                        &object2world,
1222                        &mi,
1223                        &attr.area_light_params,
1224                        &s,
1225                    );
1226                    if let Some(a) = area.as_ref() {
1227                        area_lights.push(a.clone());
1228                    }
1229                    let prim = Arc::new(GeometricPrimitive::new(&s, &mtl, &area, &mi));
1230                    prims.push(prim);
1231                }
1232            }
1233        } else {
1234            // Initialize _prims_ and _areaLights_ for animated shape
1235
1236            // Create initial shape or shapes for animated shape
1237            if attr.area_light_name != "" {
1238                warn!("Ignoring currently set area light when creating animated shape");
1239            }
1240
1241            let identity = Transform::identity();
1242            let shapes = self.make_shapes(name, &identity, attr.reverse_orientation, params);
1243            if shapes.is_empty() {
1244                return;
1245            }
1246
1247            // Create _GeometricPrimitive_(s) for animated shape
1248            let mtl = self.get_material_for_shape(params);
1249            let mi = self.create_medium_interface();
1250            prims.reserve(shapes.len());
1251            for s in shapes {
1252                let prim = Arc::new(GeometricPrimitive::new(&s, &mtl, &None, &mi));
1253                prims.push(prim);
1254            }
1255            // Create single _TransformedPrimitive_ for _prims_
1256
1257            // Get _animatedObjectToWorld_ transform for shape
1258            let cur_trans = self.transforms[self.transforms.len() - 1].borrow();
1259            if cur_trans.len() < 2 {
1260                error!("Transformation matrix has missing components");
1261                return;
1262            }
1263            let obj_to_world = [cur_trans[0].clone(), cur_trans[1].clone()];
1264            let animated_transform = {
1265                let opts = self.render_options.borrow();
1266                //println!("start_time:{}, end_time:{}", opts.transform_start_time, opts.transform_end_time);
1267                AnimatedTransform::new(
1268                    &obj_to_world[0],
1269                    opts.transform_start_time,
1270                    &obj_to_world[1],
1271                    opts.transform_end_time,
1272                )
1273            };
1274
1275            if prims.len() > 1 {
1276                let opts = self.render_options.borrow();
1277                let accelerator_name = opts.accelerator_name.clone();
1278                let accelerator_params = opts.accelerator_params.clone();
1279                if let Some(accel) =
1280                    self.make_accelerator(&accelerator_name, &prims, &accelerator_params)
1281                {
1282                    prims.clear();
1283                    prims.push(accel);
1284                }
1285            }
1286
1287            if !prims.is_empty() {
1288                assert!(prims.len() == 1);
1289                let prim = Arc::new(TransformedPrimitive::new(&prims[0], &animated_transform));
1290                prims.clear();
1291                prims.push(prim);
1292            }
1293        }
1294
1295        {
1296            if let Some(instance_name) = self.get_current_instance_name() {
1297                if !area_lights.is_empty() {
1298                    warn!("Area lights not supported with object instancing"); //ignored
1299                }
1300                let mut opts = self.render_options.borrow_mut();
1301                if let Some(out_primitives) = opts.instances.get_mut(&instance_name) {
1302                    for prim in prims {
1303                        out_primitives.push(prim);
1304                    }
1305                }
1306            } else {
1307                let mut opts = self.render_options.borrow_mut();
1308                for prim in prims {
1309                    opts.primitives.push(prim);
1310                }
1311                if !area_lights.is_empty() {
1312                    for l in area_lights {
1313                        opts.lights.push(l);
1314                    }
1315                }
1316            }
1317        }
1318    }
1319
1320    fn pbrt_reverse_orientation(&mut self) {
1321        self.verify_world("ReverseOrientation");
1322
1323        let mut atrs = self.graphics_states[self.graphics_states.len() - 1].borrow_mut();
1324        atrs.reverse_orientation = !atrs.reverse_orientation;
1325    }
1326
1327    fn pbrt_object_begin(&mut self, name: &str) {
1328        self.verify_world("ObjectBegin");
1329
1330        self.pbrt_attribute_begin();
1331        {
1332            let mut opts = self.render_options.borrow_mut();
1333            opts.instances.insert(String::from(name), Vec::new());
1334            opts.current_instance_name = Some(String::from(name));
1335        }
1336    }
1337
1338    fn pbrt_object_end(&mut self) {
1339        self.verify_world("ObjectEnd");
1340
1341        {
1342            let mut opts = self.render_options.borrow_mut();
1343            opts.current_instance_name = None;
1344        }
1345        self.pbrt_attribute_end();
1346        N_OBJECT_INSTANCES_CREATED.with(|c| c.inc());
1347    }
1348
1349    fn pbrt_object_instance(&mut self, name: &str) {
1350        self.verify_world("ObjectInstance");
1351
1352        {
1353            let opts = self.render_options.borrow();
1354            if opts.current_instance_name.as_ref().is_some() {
1355                return;
1356            }
1357        }
1358
1359        {
1360            let mut opts = self.render_options.borrow_mut();
1361            let accelerator_name = opts.accelerator_name.clone();
1362            let accelerator_params = opts.accelerator_params.clone();
1363            let start_time = opts.transform_start_time;
1364            let end_time = opts.transform_end_time;
1365            let instances = &mut opts.instances;
1366            if let Some(prims) = instances.get_mut(name) {
1367                N_OBJECT_INSTANCES_USED.with(|c| c.inc());
1368
1369                if prims.len() > 1 {
1370                    if let Some(accel) =
1371                        self.make_accelerator(&accelerator_name, prims, &accelerator_params)
1372                    {
1373                        prims.clear();
1374                        prims.push(accel);
1375                    }
1376                }
1377                if !prims.is_empty() {
1378                    assert_eq!(prims.len(), 1);
1379                    let cur_trans = self.transforms[self.transforms.len() - 1].borrow();
1380                    let animated_transform = AnimatedTransform::new(
1381                        &cur_trans.t[0],
1382                        start_time,
1383                        &cur_trans.t[1],
1384                        end_time,
1385                    );
1386                    let prim = Arc::new(TransformedPrimitive::new(&prims[0], &animated_transform));
1387                    opts.primitives.push(prim);
1388                }
1389            }
1390        }
1391    }
1392
1393    fn pbrt_world_end(&mut self) {
1394        self.verify_world("WorldEnd");
1395        //Do not anything!
1396    }
1397
1398    fn pbrt_parse_file(&mut self, _file_name: &str) {
1399        //Do not anything!
1400    }
1401    fn pbrt_parse_string(&mut self, _s: &str) {
1402        //Do not anything!
1403    }
1404
1405    fn pbrt_work_dir_begin(&mut self, path: &str) {
1406        self.work_dirs.push(String::from(path));
1407    }
1408
1409    fn pbrt_work_dir_end(&mut self) {
1410        self.work_dirs.pop();
1411    }
1412}