|
| 1 | +# External imports |
| 2 | +from time import strftime |
| 3 | + |
| 4 | +from matplotlib import pyplot as plt |
| 5 | + |
| 6 | +# Raysect imports |
| 7 | +from raysect.optical import Point3D, World, d65_white, rotate, translate |
| 8 | +from raysect.optical.library import schott |
| 9 | +from raysect.optical.material import Checkerboard, Lambert |
| 10 | +from raysect.optical.observer import PinholeCamera, RGBAdaptiveSampler2D, RGBPipeline2D |
| 11 | +from raysect.primitive import Box, Cone, Cylinder, Parabola, Sphere, Torus |
| 12 | + |
| 13 | +# 1. Create Primitives |
| 14 | +# -------------------- |
| 15 | + |
| 16 | +# Box defining the ground plane |
| 17 | +ground = Box( |
| 18 | + lower=Point3D(-50, -0.01, -50), upper=Point3D(50, 0.0, 50), material=Lambert() |
| 19 | +) |
| 20 | + |
| 21 | +# checker board wall that acts as emitter |
| 22 | +emitter = Box( |
| 23 | + lower=Point3D(-100, -100, 10), |
| 24 | + upper=Point3D(100, 100, 10.1), |
| 25 | + material=Checkerboard(4, d65_white, d65_white, 0.1, 2.0), |
| 26 | +) |
| 27 | + |
| 28 | +# Primitive showcasing all geometric features |
| 29 | +# Note that the primitives must be displaced slightly above the ground plane to prevent numerically issues that could |
| 30 | +# cause a light leak at the intersection between the objects and the ground. |
| 31 | +cylinder = Cylinder( |
| 32 | + radius=1.5, |
| 33 | + height=3.0, |
| 34 | + transform=translate(1.5 * 3 + 1.0, 0.0001, 0) * rotate(0, 90, 0), |
| 35 | + material=schott("N-BK7"), |
| 36 | +) |
| 37 | +cone = Cone( |
| 38 | + radius=1.5, |
| 39 | + height=3.0, |
| 40 | + transform=translate(1.5 + 0.2, 0.0001, 0) * rotate(0, 90, 0), |
| 41 | + material=schott("N-BK7"), |
| 42 | +) |
| 43 | +sphere = Sphere( |
| 44 | + radius=1.5, |
| 45 | + transform=translate(-1.5 - 0.2, 1.5 + 0.0001, 0), |
| 46 | + material=schott("N-BK7"), |
| 47 | +) |
| 48 | +box = Box( |
| 49 | + lower=Point3D(-1.5, 0.0, -1.5), |
| 50 | + upper=Point3D(1.5, 3.0, 1.5), |
| 51 | + transform=translate(-1.5 * 3 - 1.0, 0.0001, 0), |
| 52 | + material=schott("N-BK7"), |
| 53 | +) |
| 54 | +parabola = Parabola( |
| 55 | + radius=2.0, |
| 56 | + height=1.0, |
| 57 | + transform=translate(2.5, 1.0 + 0.0001, -5.0) * rotate(0, -90, 0), |
| 58 | + material=schott("N-BK7"), |
| 59 | +) |
| 60 | +torus = Torus( |
| 61 | + major_radius=1.0, |
| 62 | + minor_radius=0.5, |
| 63 | + transform=translate(-2.5, 0.5 + 0.0001, -5.0) * rotate(0, 90, 0), |
| 64 | + material=schott("N-BK7"), |
| 65 | +) |
| 66 | + |
| 67 | + |
| 68 | +# 2. Add Observer |
| 69 | +# --------------- |
| 70 | + |
| 71 | +# Process the ray-traced spectra with the RGB pipeline. |
| 72 | +rgb = RGBPipeline2D(display_unsaturated_fraction=0.96) |
| 73 | +sampler = RGBAdaptiveSampler2D( |
| 74 | + rgb, ratio=10, fraction=0.2, min_samples=2000, cutoff=0.01 |
| 75 | +) |
| 76 | + |
| 77 | +# camera |
| 78 | +camera = PinholeCamera( |
| 79 | + (512, 512), pipelines=[rgb], transform=translate(-7, 12, -15) * rotate(-25, -40, 0) |
| 80 | +) |
| 81 | + |
| 82 | +# camera - pixel sampling settings |
| 83 | +camera.fov = 45 |
| 84 | +camera.pixel_samples = 250 |
| 85 | + |
| 86 | +# camera - ray sampling settings |
| 87 | +camera.spectral_rays = 15 |
| 88 | +camera.spectral_bins = 15 |
| 89 | +camera.ray_max_depth = 100 |
| 90 | +camera.ray_extinction_prob = 0.1 |
| 91 | +camera.min_wavelength = 375.0 |
| 92 | +camera.max_wavelength = 740.0 |
| 93 | + |
| 94 | + |
| 95 | +# 3. Build Scenegraph |
| 96 | +# ------------------- |
| 97 | + |
| 98 | +world = World() |
| 99 | + |
| 100 | +ground.parent = world |
| 101 | +emitter.parent = world |
| 102 | +camera.parent = world |
| 103 | +cylinder.parent = world |
| 104 | +cone.parent = world |
| 105 | +sphere.parent = world |
| 106 | +box.parent = world |
| 107 | +parabola.parent = world |
| 108 | +torus.parent = world |
| 109 | + |
| 110 | +# 4. Observe() |
| 111 | +# ------------ |
| 112 | +name = "raysect_primitives" |
| 113 | +timestamp = strftime("%Y-%m-%d_%H-%M-%S") |
| 114 | +render_pass = 1 |
| 115 | +plt.ion() |
| 116 | +while not camera.render_complete: |
| 117 | + print(f"Rendering pass {render_pass}...") |
| 118 | + camera.observe() |
| 119 | + rgb.save(f"{name}_{timestamp}_pass_{render_pass}.png") |
| 120 | + render_pass += 1 |
| 121 | + print() |
| 122 | + |
| 123 | +# display final result |
| 124 | +plt.ioff() |
| 125 | +rgb.display() |
| 126 | +plt.show() |
0 commit comments