# PyTrace [![](https://img.shields.io/badge/github-Vanille--N/ray__tracer-8da0cb?logo=github)](https://github.com/Vanille-N/ray_tracer) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) `pytrace` [![crates.io](http://meritbadge.herokuapp.com/pytrace)](https://crates.io/crates/pytrace) [![API](https://docs.rs/pytrace/badge.svg)](https://docs.rs/pytrace) --- ### Direct dependencies `pytrace_core` [![crates.io](http://meritbadge.herokuapp.com/pytrace_core)](https://crates.io/crates/pytrace_core) [![API](https://docs.rs/pytrace_core/badge.svg)](https://docs.rs/pytrace_core) `glob` [![crates.io](http://meritbadge.herokuapp.com/glob)](https://crates.io/crates/glob) [![API](https://docs.rs/glob/badge.svg)](https://docs.rs/glob) `ctrlc` [![crates.io](http://meritbadge.herokuapp.com/ctrlc)](https://crates.io/crates/ctrlc) [![API](https://docs.rs/ctrlc/badge.svg)](https://docs.rs/ctrlc) --- ```diff - WARNING PyTrace uses PyO3. If you wish to compile this crate, you should use Rust nightly. ``` ### How to build ```shell cargo build --release cp target/release/libpytrace.so pytrace.so ``` That last step will only allow you to import the resulting library from your current directory. You may want to replace it with any of the following : ```shell cp target/release/libpytrace.so usr/bin/pytrace.so mv target/release/libpytrace.so target/release/pytrace.so; export PATH=$(pwd)/target/release:$PATH ... ``` You can now `import pytrace as tr` from any Python script, as long as `pytrace.so` is in your working directory or in your `PATH`. See `LIB.md` to view the autogenerated docs. A few `.py` files provide working examples. ### Interrupting execution Interrupting the rendering process is a non-trivial task because the chain of function calls is as follows: ``` Cfg.render Zone 1 ↓ ↓ (PyO3 interface) -------------------------- ↓ pytrace::external::cfg::Cfg::render Zone 2 ↓ ↓ (external dependency) --------------------- ↓ pytrace_core::render::render Zone 3 ↓ ↓ (external dependency) ↓ [for each core] threadpool::Threadpool::execute ↓ ↓ (closure) ↓ [multiple times for each pixel] pytrace_core::internal::world::calc_color ``` Any solution for how to interrupt the process has to be managed in `Zone 2`, which leaves us few options. Indeed, Addressing the problem in `Zone 1` would require the user to type more boilerplate code, and `Zone 3` is out of the question because external dependencies should not be modified for this purpose (even though as the creator of `pytrace_core` I *could*). When we want to interrupt the process, there is no way of telling what the state of the calculations is, and if anything can be recovered. The most sensible way of dealing with `KeyboardInterrupt` was decided to be to immediately `exit(2)`, which is easy thanks to the `ctrlc` crate. As such, interrupting the creation of an image will **INTERRUPT THE WHOLE PROCESS**. This makes little difference if you run a script, but it does if you run a REPL. Be warned that if you abort the `render` function, your REPL session will be terminated.