### Configuring and observing with a MeshCamera Source: http://www.raysect.org/api_reference/optical/observers.html Example demonstrating the setup of a MeshCamera using a mesh primitive, a power pipeline, and an adaptive sampler. ```python >>> from raysect.primitive import Mesh >>> from raysect.optical import World >>> from raysect.optical.material import AbsorbingSurface >>> from raysect.optical.observer import MeshCamera, PowerPipeline1D, MonoAdaptiveSampler1D >>> >>> world = World() >>> >>> mesh = Mesh.from_file("my_mesh.rsm", material=AbsorbingSurface(), parent=world) >>> >>> power = PowerPipeline1D() >>> sampler = MonoAdaptiveSampler1D(power, fraction=0.2, ratio=25.0, min_samples=1000, cutoff=0.1) >>> camera = MeshCamera(mesh, surface_offset=1e-6, # launch rays 1mm off surface to avoid intersection with absorbing mesh pipelines=[power], frame_sampler=sampler, parent=world, spectral_bins=1, min_wavelength=400, max_wavelength=740, pixel_samples=250) >>> camera.observe() ``` -------------------------------- ### Install Raysect from source Source: http://www.raysect.org/_sources/installation.rst.txt Use this method if pip is unavailable or if you are working with a local copy of the source code. ```bash python setup.py install ``` -------------------------------- ### RenderEngine.run Source: http://www.raysect.org/_modules/raysect/core/workflow.html Starts the render engine to execute a list of tasks using provided render and update functions. ```APIDOC ## RenderEngine.run ### Description Starts the render engine executing the requested tasks. The engine distributes tasks to workers, which execute the render function and return results to be processed by the update function. ### Parameters - **tasks** (list) - Required - List of user defined tuples that describe the task to execute. - **render** (object) - Required - Callable python object that executes the tasks. Signature: def render(task, *render_args, **render_kwargs) - **update** (object) - Required - Callable python object that is called following a render task to update internal state. Signature: def update(results, *update_args, **update_kwargs) - **render_args** (tuple) - Optional - Additional arguments to pass to user defined render function. - **render_kwargs** (dict) - Optional - Additional keyword arguments to pass to user defined render function. - **update_args** (tuple) - Optional - Additional arguments to pass to user defined update function. - **update_kwargs** (dict) - Optional - Additional keyword arguments to pass to user defined update function. ``` -------------------------------- ### Cornell Box Scene Setup Source: http://www.raysect.org/demonstrations/observers/cornell_box.html This script initializes the scene graph, defines material properties using interpolated spectral functions, and constructs the box geometry. ```python from matplotlib.pyplot import * from raysect.primitive import Sphere, Box from raysect.optical import World, Node, translate, rotate, Point3D from raysect.optical.material import Lambert, UniformSurfaceEmitter from raysect.optical.library import * from raysect.optical.observer import PinholeCamera from raysect.optical.observer import RGBPipeline2D, BayerPipeline2D, PowerPipeline2D from raysect.optical.observer import RGBAdaptiveSampler2D """ Cornell Box Demo ================ This demo renders a variant of the classic Cornell Box scene. To the original Cornell Box see: http://www.graphics.cornell.edu/online/box/data.html The wall colours and light spectrum used in this demo are the values measured for the physical Cornell Box. """ # define reflectivity for box surfaces wavelengths = array( [400, 404, 408, 412, 416, 420, 424, 428, 432, 436, 440, 444, 448, 452, 456, 460, 464, 468, 472, 476, 480, 484, 488, 492, 496, 500, 504, 508, 512, 516, 520, 524, 528, 532, 536, 540, 544, 548, 552, 556, 560, 564, 568, 572, 576, 580, 584, 588, 592, 596, 600, 604, 608, 612, 616, 620, 624, 628, 632, 636, 640, 644, 648, 652, 656, 660, 664, 668, 672, 676, 680, 684, 688, 692, 696, 700]) white = array( [0.343, 0.445, 0.551, 0.624, 0.665, 0.687, 0.708, 0.723, 0.715, 0.71, 0.745, 0.758, 0.739, 0.767, 0.777, 0.765, 0.751, 0.745, 0.748, 0.729, 0.745, 0.757, 0.753, 0.75, 0.746, 0.747, 0.735, 0.732, 0.739, 0.734, 0.725, 0.721, 0.733, 0.725, 0.732, 0.743, 0.744, 0.748, 0.728, 0.716, 0.733, 0.726, 0.713, 0.74, 0.754, 0.764, 0.752, 0.736, 0.734, 0.741, 0.74, 0.732, 0.745, 0.755, 0.751, 0.744, 0.731, 0.733, 0.744, 0.731, 0.712, 0.708, 0.729, 0.73, 0.727, 0.707, 0.703, 0.729, 0.75, 0.76, 0.751, 0.739, 0.724, 0.73, 0.74, 0.737]) green = array( [0.092, 0.096, 0.098, 0.097, 0.098, 0.095, 0.095, 0.097, 0.095, 0.094, 0.097, 0.098, 0.096, 0.101, 0.103, 0.104, 0.107, 0.109, 0.112, 0.115, 0.125, 0.14, 0.16, 0.187, 0.229, 0.285, 0.343, 0.39, 0.435, 0.464, 0.472, 0.476, 0.481, 0.462, 0.447, 0.441, 0.426, 0.406, 0.373, 0.347, 0.337, 0.314, 0.285, 0.277, 0.266, 0.25, 0.23, 0.207, 0.186, 0.171, 0.16, 0.148, 0.141, 0.136, 0.13, 0.126, 0.123, 0.121, 0.122, 0.119, 0.114, 0.115, 0.117, 0.117, 0.118, 0.12, 0.122, 0.128, 0.132, 0.139, 0.144, 0.146, 0.15, 0.152, 0.157, 0.159]) red = array( [0.04, 0.046, 0.048, 0.053, 0.049, 0.05, 0.053, 0.055, 0.057, 0.056, 0.059, 0.057, 0.061, 0.061, 0.06, 0.062, 0.062, 0.062, 0.061, 0.062, 0.06, 0.059, 0.057, 0.058, 0.058, 0.058, 0.056, 0.055, 0.056, 0.059, 0.057, 0.055, 0.059, 0.059, 0.058, 0.059, 0.061, 0.061, 0.063, 0.063, 0.067, 0.068, 0.072, 0.08, 0.09, 0.099, 0.124, 0.154, 0.192, 0.255, 0.287, 0.349, 0.402, 0.443, 0.487, 0.513, 0.558, 0.584, 0.62, 0.606, 0.609, 0.651, 0.612, 0.61, 0.65, 0.638, 0.627, 0.62, 0.63, 0.628, 0.642, 0.639, 0.657, 0.639, 0.635, 0.642]) white_reflectivity = InterpolatedSF(wavelengths, white) red_reflectivity = InterpolatedSF(wavelengths, red) green_reflectivity = InterpolatedSF(wavelengths, green) # define light spectrum light_spectrum = InterpolatedSF(array([400, 500, 600, 700]), array([0.0, 8.0, 15.6, 18.4])) # set-up scenegraph world = World() # enclosing box enclosure = Node(world) e_back = Box(Point3D(-1, -1, 0), Point3D(1, 1, 0), parent=enclosure, transform=translate(0, 0, 1) * rotate(0, 0, 0), material=Lambert(white_reflectivity)) e_bottom = Box(Point3D(-1, -1, 0), Point3D(1, 1, 0), parent=enclosure, transform=translate(0, -1, 0) * rotate(0, -90, 0), # material=m) material=Lambert(white_reflectivity)) e_top = Box(Point3D(-1, -1, 0), Point3D(1, 1, 0), parent=enclosure, transform=translate(0, 1, 0) * rotate(0, 90, 0), material=Lambert(white_reflectivity)) e_left = Box(Point3D(-1, -1, 0), Point3D(1, 1, 0), parent=enclosure, transform=translate(1, 0, 0) * rotate(-90, 0, 0), material=Lambert(red_reflectivity)) e_right = Box(Point3D(-1, -1, 0), Point3D(1, 1, 0), parent=enclosure, transform=translate(-1, 0, 0) * rotate(90, 0, 0), material=Lambert(green_reflectivity)) # ceiling light light = Box(Point3D(-0.4, -0.4, -0.01), Point3D(0.4, 0.4, 0.0), parent=enclosure, transform=translate(0, 1, 0) * rotate(0, 90, 0), material=UniformSurfaceEmitter(light_spectrum, 2)) ``` -------------------------------- ### Install Raysect via pip Source: http://www.raysect.org/_sources/index.rst.txt Use this command to install the Raysect package and its dependencies. ```bash pip install raysect ``` -------------------------------- ### Run Raysect tests Source: http://www.raysect.org/_sources/installation.rst.txt Execute the test suite using the nose framework within the source directory to verify the installation. ```bash nosetests ``` -------------------------------- ### RenderEngine run method Source: http://www.raysect.org/_modules/raysect/core/workflow.html The method used to start the render engine with tasks and processing functions. ```python def run(self, tasks, render, update, render_args=(), render_kwargs={}, update_args=(), update_kwargs={}): """ Starts the render engine executing the requested tasks. :param list tasks: List of user defined tuples that describe the task to execute. :param object render: Callable python object that executes the tasks. :param object update: Callable python object that is called following a render task and must be used to update the internal state of the object requesting work. :param tuple render_args: Additional arguments to pass to user defined render function. :param tuple render_kwargs: Additional keyword arguments to pass to user defined render function. :param tuple update_args: Additional arguments to pass to user defined update function. :param tuple update_kwargs: Additional keyword arguments to pass to user defined update function. """ raise NotImplementedError("Virtual method must be implemented in sub-class.") ``` -------------------------------- ### Execute Multicore and Serial Engines Source: http://www.raysect.org/_modules/raysect/core/workflow.html Example usage of the Job class to compare performance between SerialEngine and MulticoreEngine. ```python if __name__ == '__main__': class Job: def __init__(self, engine=None): self.total = 0 self.engine = engine if engine else MulticoreEngine() def run(self, v): self.total = 0 self.engine.run(list(range(v)), self.render, self.update, render_args=(10000,)) return self.total def render(self, task, count): sum = 0 for i in range(count): sum += 1 / count return sum def update(self, result): self.total += result n = 20000 t = time.time() j = Job(SerialEngine()) print(j.run(n), time.time() - t) t = time.time() j = Job(MulticoreEngine()) print(j.run(n), time.time() - t) ``` -------------------------------- ### Initialize and observe with a FibreOptic Source: http://www.raysect.org/api_reference/optical/observers.html Demonstrates configuring a FibreOptic observer with multiple pipelines and specific physical parameters. ```python >>> from raysect.optical.observer import FibreOptic, RadiancePipeline0D, PowerPipeline0D >>> >>> power = PowerPipeline0D() >>> radiance = RadiancePipeline0D() >>> fibre = FibreOptic([power, radiance], acceptance_angle=10, radius=0.0005, spectral_bins=500, pixel_samples=1000, transform=translate(0, 0, -5), parent=world) >>> fibre.observe() ``` -------------------------------- ### Initialize and observe with a Pixel observer Source: http://www.raysect.org/api_reference/optical/observers.html Demonstrates setting up a Pixel observer with a PowerPipeline0D and performing an observation. ```python >>> from raysect.optical import World >>> from raysect.optical.observer import Pixel, PowerPipeline0D >>> >>> world = World() >>> power = PowerPipeline0D(accumulate=False) >>> observing_plane = Pixel([power], x_width=2.0, y_width=2.0, min_wavelength=400, max_wavelength=720, spectral_bins=1, pixel_samples=250, parent=world, transform=rotate(0, 0, 0)*translate(0, 0, -1)) >>> observing_plane.observe() ``` -------------------------------- ### Get Vector3D Length Source: http://www.raysect.org/api_reference/core/points_and_vectors.html Retrieves the length of the vector. ```python >>> a = Vector3D(1, 1, 1) >>> a.length 1.7320508075688772 ``` -------------------------------- ### Initialize camera and film settings Source: http://www.raysect.org/demonstrations/observers/cornell_box_with_camera.html Sets up the camera node, pinhole, and CCD array with specific ray-tracing parameters. ```python camera = Node(parent=world, transform=translate(0, 0, -3.3)) pinhole = Sphere(0.0005, camera, transform=translate(0, 0, 0), material=NullMaterial()) film = TargetedCCDArray(targeted_path_prob=1.0, targets=[pinhole], width=0.1, pixels=(512, 512), parent=camera, transform=translate(0, 0, -0.1207), pipelines=pipelines) film.frame_sampler = sampler film.pixel_samples = 250 film.spectral_bins = 15 film.spectral_rays = 1 film.ray_importance_sampling = True film.ray_important_path_weight = 0.25 film.ray_max_depth = 500 film.ray_extinction_min_depth = 3 film.ray_extinction_prob = 0.01 ``` -------------------------------- ### Get Vector2D Length Source: http://www.raysect.org/api_reference/core/points_and_vectors.html Retrieve the magnitude of the vector. ```python >>> a = Vector2D(1, 1) >>> a.length 1.4142135623730951 ``` -------------------------------- ### important_direction_sample(origin) Source: http://www.raysect.org/api_reference/optical/main_optical_classes.html Gets a sample direction of an important primitive. ```APIDOC ## important_direction_sample(origin) ### Description Get a sample direction of an important primitive. ### Parameters - **origin** (Point3D) - Required - The point from which to sample. ### Returns - **Vector3D** - The vector along which to sample. ``` -------------------------------- ### Access Point3D Coordinates Source: http://www.raysect.org/api_reference/core/points_and_vectors.html Get or set coordinates using index notation. ```python >>> a = Point3D(1, 0, 0) >>> a[0] 1 ``` ```python >>> a = Point3D(1, 0, 0) >>> a[1] = 2 >>> a Point3D(1.0, 2.0, 0.0) ``` -------------------------------- ### Initialize UnityVolumeEmitter Source: http://www.raysect.org/api_reference/optical/optical_volumes.html Demonstrates setting up a scene with a sphere using the UnityVolumeEmitter material. ```python >>> from raysect.primitive import Sphere >>> from raysect.optical import World >>> from raysect.optical.material import UnityVolumeEmitter >>> >>> # set-up scenegraph >>> world = World() >>> emitter = Sphere(radius=0.01, parent=world, material=UnityVolumeEmitter()) ``` -------------------------------- ### Configure and Run a PinholeCamera Source: http://www.raysect.org/api_reference/optical/observers.html Demonstrates initializing a PinholeCamera with a PowerPipeline2D, setting camera transforms, and triggering the observation process. ```python >>> from raysect.core import translate >>> from raysect.optical import World >>> from raysect.optical.observer import PinholeCamera, PowerPipeline2D >>> >>> power = PowerPipeline2D(display_unsaturated_fraction=0.96, name="Unfiltered") >>> >>> camera = PinholeCamera((512, 512), parent=world, pipelines=[power]) >>> camera.transform = translate(0, 0, -3.3) >>> camera.pixel_samples = 250 >>> camera.spectral_bins = 15 >>> >>> camera.observe() ``` -------------------------------- ### Get Orthogonal Vector3D Source: http://www.raysect.org/api_reference/core/points_and_vectors.html Returns a unit vector guaranteed to be orthogonal to the current vector. ```python >>> a = Vector3D(1, 0, 0) >>> a.orthogonal() Vector3D(0.0, 1.0, 0.0) ``` -------------------------------- ### Configure camera pipelines and sampler Source: http://www.raysect.org/demonstrations/observers/cornell_box_with_camera.html Initializes various imaging pipelines and an adaptive sampler for the camera. ```python # create and setup the camera power_unfiltered = PowerPipeline2D(display_unsaturated_fraction=0.96, name="Unfiltered") power_unfiltered.display_update_time = 15 power_green = PowerPipeline2D(filter=filter_green, display_unsaturated_fraction=0.96, name="Green Filter") power_green.display_update_time = 15 power_red = PowerPipeline2D(filter=filter_red, display_unsaturated_fraction=0.96, name="Red Filter") power_red.display_update_time = 15 rgb = RGBPipeline2D(display_unsaturated_fraction=0.96, name="sRGB") bayer = BayerPipeline2D(filter_red, filter_green, filter_blue, display_unsaturated_fraction=0.96, name="Bayer Filter") bayer.display_update_time = 15 pipelines = [rgb, power_unfiltered, power_green, power_red, bayer] sampler = RGBAdaptiveSampler2D(rgb, ratio=10, fraction=0.2, min_samples=500, cutoff=0.05) ``` -------------------------------- ### Initialize a UnitySurfaceEmitter Source: http://www.raysect.org/api_reference/optical/optical_surfaces.html Demonstrates setting up a sphere with a uniform and isotropic UnitySurfaceEmitter. ```python >>> from raysect.primitive import Sphere >>> from raysect.optical import World >>> from raysect.optical.material import UnitySurfaceEmitter >>> >>> # set-up scenegraph >>> world = World() >>> emitter = Sphere(radius=0.01, parent=world, material=UnitySurfaceEmitter()) ``` -------------------------------- ### Initialize and observe with a SightLine Source: http://www.raysect.org/api_reference/optical/observers.html Demonstrates setting up a SightLine observer within a world and triggering an observation. ```python >>> from raysect.optical import World >>> from raysect.optical.observer import SightLine, PowerPipeline0D >>> >>> world = World() >>> power = PowerPipeline0D(accumulate=False) >>> los = SightLine([power], min_wavelength=400, max_wavelength=720, parent=world, transform=rotate(0, 0, 0)*translate(0, 0, -1)) >>> los.observe() ``` -------------------------------- ### Configure and run a FibreOptic observer Source: http://www.raysect.org/demonstrations/observers/optical_fibre.html Sets up a scene with a ground plane, emitter, and sphere, then initializes a FibreOptic observer with multiple data pipelines to perform an observation. ```python # External imports import matplotlib.pyplot as plt # Raysect imports from raysect.primitive import Sphere, Box from raysect.optical import World, translate, rotate, Point3D, d65_white from raysect.optical.material import Lambert, Checkerboard from raysect.optical.library import schott from raysect.optical.observer import FibreOptic, PowerPipeline0D, RadiancePipeline0D, SpectralPowerPipeline0D, SpectralRadiancePipeline0D # Box defining the ground plane ground = Box(lower=Point3D(-50, -1.51, -50), upper=Point3D(50, -1.5, 50), material=Lambert()) # checker board wall that acts as emitter emitter = Box(lower=Point3D(-10, -10, 10), upper=Point3D(10, 10, 10.1), material=Checkerboard(4, d65_white, d65_white, 0.1, 2.0), transform=rotate(45, 0, 0)) # Sphere sphere = Sphere(radius=1.5, transform=translate(0, 0.0001, 0), material=schott("N-BK7")) # 3. Build Scenegraph # ------------------- world = World() sphere.parent = world ground.parent = world emitter.parent = world # 4. Observe() # ------------ plt.ion() spectral_power = SpectralPowerPipeline0D() spectral_radiance = SpectralRadiancePipeline0D() power = PowerPipeline0D() radiance = RadiancePipeline0D() fibre = FibreOptic([spectral_power, spectral_radiance, power, radiance], acceptance_angle=10, radius=0.0005, spectral_bins=500, spectral_rays=1, pixel_samples=1000, transform=translate(0, 0, -5), parent=world) fibre.observe() plt.ioff() plt.show() ``` -------------------------------- ### Initialize a Point3D Source: http://www.raysect.org/api_reference/core/points_and_vectors.html Create a new 3D point instance. ```python >>> from raysect.core import Point3D >>> a = Point3D(0, 1, 2) ``` -------------------------------- ### Configure Camera and Sampler Source: http://www.raysect.org/demonstrations/observers/cornell_box.html Initializes the PinholeCamera with specific sampling and ray tracing parameters. ```python sampler = RGBAdaptiveSampler2D(rgb, ratio=10, fraction=0.2, min_samples=500, cutoff=0.01) camera = PinholeCamera((1024, 1024), parent=world, transform=translate(0, 0, -3.3) * rotate(0, 0, 0), pipelines=pipelines) camera.frame_sampler = sampler camera.spectral_rays = 1 camera.spectral_bins = 15 camera.pixel_samples = 250 camera.ray_importance_sampling = True camera.ray_important_path_weight = 0.25 camera.ray_max_depth = 500 camera.ray_extinction_min_depth = 3 camera.ray_extinction_prob = 0.01 ``` -------------------------------- ### Initialize UniformVolumeEmitter Source: http://www.raysect.org/api_reference/optical/optical_volumes.html Demonstrates configuring a sphere with a UniformVolumeEmitter using a constant spectral function. ```python >>> from raysect.primitive import Sphere >>> from raysect.optical import World, ConstantSF >>> from raysect.optical.material import UniformVolumeEmitter >>> >>> # set-up scenegraph >>> world = World() >>> emitter = Sphere(radius=0.01, parent=world) >>> emitter.material=UniformVolumeEmitter(ConstantSF(1.0)) ``` -------------------------------- ### Initialize Point2D Source: http://www.raysect.org/api_reference/core/points_and_vectors.html Create a new 2D point instance. ```python >>> from raysect.core import Point2D >>> >>> a = Point2D(1, 1) ``` -------------------------------- ### Initialize an AbsorbingSurface Source: http://www.raysect.org/api_reference/optical/optical_surfaces.html Demonstrates how to instantiate an AbsorbingSurface and assign it to a primitive within a Raysect world. ```python >>> from raysect.primitive import Sphere >>> from raysect.optical import World >>> from raysect.optical.material import AbsorbingSurface >>> >>> # set-up scenegraph >>> world = World() >>> absorber = Sphere(radius=0.01, parent=world, material=AbsorbingSurface()) ``` -------------------------------- ### Initialize a Vector3D Source: http://www.raysect.org/api_reference/core/points_and_vectors.html Create a new 3D vector instance. ```python >>> from raysect.core import Vector3D >>> a = Vector3D(1, 0, 0) ``` -------------------------------- ### Initialize a Checkerboard Emitter Source: http://www.raysect.org/api_reference/optical/optical_surfaces.html Demonstrates creating a box with a Checkerboard material emitter. ```python >>> from raysect.primitive import Box >>> from raysect.optical import World, rotate, Point3D, d65_white >>> from raysect.optical.material import Checkerboard >>> >>> world = World() >>> >>> # checker board wall that acts as emitter >>> emitter = Box(lower=Point3D(-10, -10, 10), upper=Point3D(10, 10, 10.1), parent=world, transform=rotate(45, 0, 0)) >>> emitter.material=Checkerboard(4, d65_white, d65_white, 0.1, 2.0) ``` -------------------------------- ### Initialize and observe with a MeshPixel observer Source: http://www.raysect.org/api_reference/optical/observers.html Demonstrates using a triangular mesh as a pixel observer, including setting a surface offset to avoid collision. ```python >>> from raysect.primitive import Mesh >>> from raysect.optical import World >>> from raysect.optical.material import AbsorbingSurface >>> from raysect.optical.observer import MeshPixel, PowerPipeline0D >>> >>> world = World() >>> >>> mesh = Mesh.from_file("my_mesh.rsm", material=AbsorbingSurface(), parent=world) >>> >>> power = PowerPipeline0D(accumulate=False) >>> observer = MeshPixel(mesh, pipelines=[power], parent=world, >>> min_wavelength=400, max_wavelength=750, >>> spectral_bins=1, pixel_samples=10000, surface_offset=1E-6) >>> observer.observe() ``` -------------------------------- ### Configure Spectral Filters and Pipelines Source: http://www.raysect.org/demonstrations/observers/cornell_box.html Sets up color filters and various imaging pipelines for the camera. ```python filter_red = InterpolatedSF([100, 650, 660, 670, 680, 800], [0, 0, 1, 1, 0, 0]) filter_green = InterpolatedSF([100, 530, 540, 550, 560, 800], [0, 0, 1, 1, 0, 0]) filter_blue = InterpolatedSF([100, 480, 490, 500, 510, 800], [0, 0, 1, 1, 0, 0]) # create and setup the camera power_unfiltered = PowerPipeline2D(display_unsaturated_fraction=0.96, name="Unfiltered") power_unfiltered.display_update_time = 15 power_green = PowerPipeline2D(filter=filter_green, display_unsaturated_fraction=0.96, name="Green Filter") power_green.display_update_time = 15 power_red = PowerPipeline2D(filter=filter_red, display_unsaturated_fraction=0.96, name="Red Filter") power_red.display_update_time = 15 rgb = RGBPipeline2D(display_unsaturated_fraction=0.96, name="sRGB") bayer = BayerPipeline2D(filter_red, filter_green, filter_blue, display_unsaturated_fraction=0.96, name="Bayer Filter") bayer.display_update_time = 15 pipelines = [rgb, power_unfiltered, power_green, power_red, bayer] ``` -------------------------------- ### Using 1D Interpolator Source: http://www.raysect.org/api_reference/core/functions.html Demonstrates initializing a 1D interpolator with cubic interpolation and nearest-neighbor extrapolation. ```python >>> from raysect.core.math.function.float.function1d.interpolate import Interpolator1DArray >>> >>> x = np.linspace(-1., 1., 20) >>> f = np.exp(-x**2) >>> interpolator1D = Interpolate1DArray(x, f, 'cubic', 'nearest', 1.0) >>> # Interpolation >>> interpolator1D(0.2) 0.9607850606581484 >>> # Extrapolation >>> interpolator1D(1.1) 0.36787944117144233 >>> # Extrapolation out of bounds >>> interpolator1D(2.1) ValueError: The specified value (x=2.1) is outside of extrapolation range. ``` -------------------------------- ### Initializing scene constants and sphere Source: http://www.raysect.org/_sources/demonstrations/core/energy_conservation.rst.txt Define simulation parameters and place the emitting sphere into the world. ```python samples = 100000 sphere_radius = 0.5 cube_size = 2 min_wl = 400 max_wl = 401 # set-up scenegraph world = World() emitter = Sphere(radius=sphere_radius, parent=world) ``` -------------------------------- ### Initialize Vector2D Source: http://www.raysect.org/api_reference/core/points_and_vectors.html Create a new 2D vector instance. ```python >>> from raysect.core import Vector2D >>> a = Vector2D(1, 0) ``` -------------------------------- ### Add Observer Source: http://www.raysect.org/_sources/quickstart_guide.rst.txt Configure a camera and its sampling parameters for the rendering pipeline. ```python # processing pipeline (human vision like camera response) rgb = RGBPipeline2D() # camera camera = PinholeCamera(pixels=(512, 512), fov=45, pipeline=[rgb], transform=translate(0, 10, -10) * rotate(0, -45, 0)) # camera - pixel sampling settings camera.pixel_samples = 250 camera.min_wavelength = 375.0 camera.max_wavelength = 740.0 camera.spectral_bins = 15 camera.spectral_rays = 1 ``` -------------------------------- ### Load a Mesh from an RSM file Source: http://www.raysect.org/api_reference/primitives/meshes.html Demonstrates instantiating a Mesh from an RSM file using the from_file class method, including setting parent, material, and transform properties. ```python >>> from raysect.optical import World, translate, rotate, ConstantSF, Sellmeier, Dielectric >>> from raysect.primitive import Mesh >>> >>> world = World() >>> >>> diamond = Dielectric(Sellmeier(0.3306, 4.3356, 0.0, 0.1750**2, 0.1060**2, 0.0), ConstantSF(1.0)) >>> >>> mesh = Mesh.from_file("my_mesh.rsm", parent=world, material=diamond, >>> transform=translate(0, 0, 0)*rotate(165, 0, 0)) ``` -------------------------------- ### Using Arg2D for Coordinate Selection and Arithmetic Source: http://www.raysect.org/api_reference/core/functions.html Demonstrates how to use Arg2D to select function arguments and perform basic arithmetic operations on the resulting function objects. ```python >>> argx = Arg2D("x") >>> argx(2, 3) 2.0 >>> argy = Arg2D("y") >>> argy(2, 3) 3.0 >>> squarerx = argx**2 >>> squarerx(2, 3) 4.0 >>> squarery = argy**2 >>> squarery(2, 3) 9.0 ``` -------------------------------- ### Observe Scene Source: http://www.raysect.org/_sources/quickstart_guide.rst.txt Execute the rendering process and display or save the output. ```python plt.ion() camera.observe() plt.ioff() rgb.save("render.png") rgb.display() ``` -------------------------------- ### Using Arg1D for Identity and Squaring Source: http://www.raysect.org/api_reference/core/functions.html Demonstrates using Arg1D to return the input argument and applying mathematical operations to create new function objects. ```python >>> arg = Arg1D() >>> arg(2) 2.0 >>> arg(-3.14) -3.14 >>> squarer = Arg1D()**2 >>> squarer(2) 4.0 >>> squarer(-3.14) 9.8596 ``` -------------------------------- ### Initialize Spectrum Object Source: http://www.raysect.org/api_reference/optical/main_optical_classes.html Creates a new Spectrum instance with specified wavelength bounds and bin count. ```python >>> from raysect.optical import Spectrum >>> >>> spectrum = Spectrum(400, 720, 250) ``` -------------------------------- ### Initialize a UniformSurfaceEmitter Source: http://www.raysect.org/api_reference/optical/optical_surfaces.html Demonstrates assigning a UniformSurfaceEmitter with a constant spectral function to a sphere. ```python >>> from raysect.primitive import Sphere >>> from raysect.optical import World, ConstantSF >>> from raysect.optical.material import UniformSurfaceEmitter >>> >>> # set-up scenegraph >>> world = World() >>> emitter = Sphere(radius=0.01, parent=world) >>> emitter.material=UniformSurfaceEmitter(ConstantSF(1.0)) ``` -------------------------------- ### Import a Mesh from an OBJ file Source: http://www.raysect.org/api_reference/primitives/meshes.html Demonstrates importing a Wavefront OBJ file into a Raysect Mesh, including applying a scaling factor to convert units. ```python >>> from raysect.optical import World, translate, rotate, ConstantSF, Sellmeier, Dielectric >>> from raysect.primitive import import_obj >>> >>> world = World() >>> >>> diamond = Dielectric(Sellmeier(0.3306, 4.3356, 0.0, 0.1750**2, 0.1060**2, 0.0), >>> ConstantSF(1.0)) >>> >>> bunny_mesh = import_obj("resources/stanford_bunny.obj", scaling=1, parent=world, >>> transform=translate(0, 0, 0)*rotate(165, 0, 0), material=diamond) ``` -------------------------------- ### Constructing a custom camera with lens and aperture Source: http://www.raysect.org/demonstrations/observers/metal_balls_with_lens.html Sets up a scene with metallic spheres and a camera assembly using a BiConvex lens, aperture, and CCD array. ```python from matplotlib.pyplot import * from raysect.optical import World, translate, rotate, Point3D, d65_white, ConstantSF, Node from raysect.primitive import Sphere, Box, Cylinder, Subtract from raysect.primitive.lens.spherical import BiConvex from raysect.optical.library.metal import Gold, Silver, Copper, Titanium, Aluminium, Beryllium from raysect.optical.material import Lambert, UniformSurfaceEmitter, AbsorbingSurface, NullMaterial from raysect.optical.library import schott from raysect.optical.observer import RGBPipeline2D, BayerPipeline2D, TargetedCCDArray, CCDArray, RGBAdaptiveSampler2D from raysect.optical.colour import ciexyz_x, ciexyz_y, ciexyz_z world = World() Sphere(0.5, world, transform=translate(1.2, 0.5001, 0.6), material=Gold()) Sphere(0.5, world, transform=translate(0.6, 0.5001, -0.6), material=Silver()) Sphere(0.5, world, transform=translate(0, 0.5001, 0.6), material=Copper()) Sphere(0.5, world, transform=translate(-0.6, 0.5001, -0.6), material=Titanium()) Sphere(0.5, world, transform=translate(-1.2, 0.5001, 0.6), material=Aluminium()) Sphere(0.5, world, transform=translate(0, 0.5001, -1.8), material=Beryllium()) Box(Point3D(-100, -0.1, -100), Point3D(100, 0, 100), world, material=Lambert(ConstantSF(1.0))) Cylinder(3.0, 8.0, world, transform=translate(4, 8, 0) * rotate(90, 0, 0), material=UniformSurfaceEmitter(d65_white, 1.0)) camera = Node(parent=world, transform=translate(0, 4, -3.5) * rotate(0, -48, 180)) # b = BiConvex(0.0508, 0.0036, 1.0295, 1.0295, parent=camera, transform=translate(0, 0, 0.1), material=schott("N-BK7")) # b = BiConvex(0.0508, 0.0062, 0.205, 0.205, parent=camera, transform=translate(0, 0, 0.05), material=schott("N-BK7")) lens = BiConvex(0.0508, 0.0144, 0.0593, 0.0593, parent=camera, transform=translate(0, 0, 0.0536), material=schott("N-BK7")) body = Subtract( Subtract( Cylinder(0.0260, 0.07, transform=translate(0, 0, 0)), Cylinder(0.0255, 0.06, transform=translate(0, 0, 0.005)) ), Cylinder(0.015, 0.007, transform=translate(0, 0, 0.064)), parent=camera, transform=translate(0, 0, -0.01), material=AbsorbingSurface() ) aperture = Cylinder(0.016, 0.0009, parent=camera, transform=translate(0, 0, 0.064), material=NullMaterial()) rgb = RGBPipeline2D(display_unsaturated_fraction=0.98, name="sRGB") bayer = BayerPipeline2D(ciexyz_x, ciexyz_y, ciexyz_z, display_unsaturated_fraction=0.98, name="Bayer Filter") sampler = RGBAdaptiveSampler2D(rgb, ratio=10, fraction=0.2, min_samples=500, cutoff=0.05) pipelines = [rgb, bayer] # ccd = CCDArray(parent=camera, pipelines=pipelines) ccd = TargetedCCDArray(targets=[aperture], parent=camera, pipelines=pipelines) ccd.frame_sampler = sampler ccd.pixels = (180*2, 120*2) # (360, 240) ccd.pixel_samples = 250 ccd.spectral_rays = 1 ccd.spectral_bins = 15 # start ray tracing ion() p = 1 while not ccd.render_complete: print("Rendering pass {}...".format(p)) ccd.observe() # ccd.pipelines[0].save("demo_metal_lens_{}.png".format(p)) print() p += 1 ioff() show() ``` -------------------------------- ### MulticoreEngine Constructor Source: http://www.raysect.org/api_reference/core/render_engines.html Initializes a new MulticoreEngine instance to manage parallel rendering processes. ```APIDOC ## MulticoreEngine(processes=None, tasks_per_job=None, start_method='fork') ### Description A render engine for distributing work across multiple CPU cores. It manages worker processes and task grouping to optimize rendering performance. ### Parameters - **processes** (int/None) - Optional - The number of worker processes. Defaults to None, which uses all available CPU cores. - **tasks_per_job** (int/None) - Optional - The number of tasks to group into a single job to reduce IPC overhead. Defaults to None for automatic adjustment. - **start_method** (str) - Optional - The method used to start child processes: 'fork', 'spawn', or 'forkserver'. Defaults to 'fork'. ### Usage Example ```python from raysect.core import MulticoreEngine from raysect.optical.observer import PinholeCamera camera = PinholeCamera((512, 512)) # Use all available CPU cores camera.render_engine = MulticoreEngine() # Force use of 8 CPU processes camera.render_engine = MulticoreEngine(processes=8) ``` ``` -------------------------------- ### instance(parent=None, transform=None, material=None, name=None) Source: http://www.raysect.org/api_reference/core/raysect_core_scenegraph.html Creates a new instance of the primitive with the same geometry. ```APIDOC ## instance(parent=None, transform=None, material=None, name=None) ### Description Returns a new instance of the primitive with the same geometry. ### Parameters - **parent** (Node) - Optional - Assigns the Node’s parent to the specified scene-graph object. - **transform** (AffineMatrix3D) - Optional - Sets the affine transform associated with the Node. - **material** (Material) - Optional - An object representing the material properties of the primitive. - **name** (str) - Optional - A string defining the node name. ``` -------------------------------- ### Execute ray tracing render loop Source: http://www.raysect.org/demonstrations/observers/cornell_box_with_camera.html Runs the rendering process and saves output images periodically. ```python # start ray tracing ion() p = 1 while not film.render_complete: print("Rendering pass {}...".format(p)) film.observe() rgb.save('cornell_box_real_rgb_pass_{:04d}.png'.format(p)) power_unfiltered.save('cornell_box_real_unfiltered_pass_{:04d}.png'.format(p)) print() p += 1 ioff() rgb.display() ``` -------------------------------- ### Execute Rendering Loop Source: http://www.raysect.org/demonstrations/observers/cornell_box.html Runs the iterative rendering process and saves output images. ```python # start ray tracing ion() name = 'cornell_box' timestamp = time.strftime("%Y-%m-%d_%H-%M-%S") render_pass = 1 while not camera.render_complete: print("Rendering pass {}...".format(render_pass)) camera.observe() rgb.save("{}_{}_pass_{}.png".format(name, timestamp, render_pass)) # power_unfiltered.save('cornell_box_unfiltered_pass_{:04d}.png'.format(p)) # power_red.save('cornell_box_red_filter_pass_{:04d}.png'.format(p)) # power_green.save('cornell_box_green_filter_pass_{:04d}.png'.format(p)) # bayer.save('cornell_box_bayer_pass_{:04d}.png'.format(p)) print() render_pass += 1 ioff() rgb.display() ```