|
| 1 | + |
| 2 | +import os |
| 3 | +import time |
| 4 | +import numpy as np |
| 5 | +from matplotlib import pyplot as plt |
| 6 | +from Py3DViewer import Tetmesh |
| 7 | + |
| 8 | +from raysect.optical import World, translate, Point3D, Vector3D, rotate_basis |
| 9 | +from raysect.core.math.function.float.function3d.interpolate import Discrete3DMesh |
| 10 | +from raysect.optical.library import RoughTitanium |
| 11 | +from raysect.optical.material import InhomogeneousVolumeEmitter |
| 12 | +from raysect.optical.observer import PinholeCamera, RGBPipeline2D, RGBAdaptiveSampler2D |
| 13 | +from raysect.primitive import Box |
| 14 | + |
| 15 | +BASE_PATH = os.path.split(os.path.realpath(__file__))[0] |
| 16 | + |
| 17 | + |
| 18 | +class UnityEmitter(InhomogeneousVolumeEmitter): |
| 19 | + |
| 20 | + def __init__(self, radiation_function): |
| 21 | + super().__init__() |
| 22 | + self.radiation_function = radiation_function |
| 23 | + |
| 24 | + def emission_function(self, point, direction, spectrum, world, ray, primitive, to_local, to_world): |
| 25 | + spectrum = ray.new_spectrum() |
| 26 | + spectrum.samples[:] = self.radiation_function(point.x, point.y, point.z) |
| 27 | + return spectrum |
| 28 | + |
| 29 | + |
| 30 | +# Rabbit tetrahedra mesh emitter |
| 31 | +mesh = Tetmesh(os.path.join(BASE_PATH, "../resources/stanford_bunny.mesh")) |
| 32 | + |
| 33 | +try: |
| 34 | + tetra = Discrete3DMesh(mesh.vertices, mesh.polys, np.ones((mesh.num_polys)), False, 0) |
| 35 | +except AttributeError: # for backward compatibility with older versions of Py3DViewer |
| 36 | + tetra = Discrete3DMesh(mesh.vertices, mesh.tets, np.ones((mesh.num_tets)), False, 0) |
| 37 | + |
| 38 | +# scene |
| 39 | +world = World() |
| 40 | +lower = Point3D(mesh.bbox[0, 0], mesh.bbox[0, 1], mesh.bbox[0, 2]) |
| 41 | +upper = Point3D(mesh.bbox[1, 0], mesh.bbox[1, 1], mesh.bbox[1, 2]) |
| 42 | +emitter = Box(lower, upper, material=UnityEmitter(tetra), parent=world) |
| 43 | +floor = Box(Point3D(-100, -0.1, -100), Point3D(100, -0.01, 100), world, material=RoughTitanium(0.1)) |
| 44 | + |
| 45 | +# camera |
| 46 | +camera_pos = Point3D(-0.015, 0.204, 0.25) |
| 47 | +rgb_pipeline = RGBPipeline2D(display_update_time=5) |
| 48 | +sampler = RGBAdaptiveSampler2D(rgb_pipeline, min_samples=100, fraction=0.2) |
| 49 | +camera = PinholeCamera((512, 512), parent=world, transform=translate(camera_pos.x, camera_pos.y, camera_pos.z) * rotate_basis(camera_pos.vector_to(Point3D(0, 0.06, 0)), Vector3D(0, 1, 0)), |
| 50 | + pipelines=[rgb_pipeline], frame_sampler=sampler) |
| 51 | +camera.fov = 50 |
| 52 | +camera.spectral_bins = 1 |
| 53 | +camera.spectral_rays = 1 |
| 54 | +camera.pixel_samples = 200 |
| 55 | + |
| 56 | +# integration resolution |
| 57 | +emitter.material.integrator.step = 0.0001 |
| 58 | + |
| 59 | +# start ray tracing |
| 60 | +os.nice(15) |
| 61 | +plt.ion() |
| 62 | +timestamp = time.strftime("%Y-%m-%d_%H-%M-%S") |
| 63 | +for p in range(1, 1000): |
| 64 | + print("Rendering pass {}...".format(p)) |
| 65 | + camera.observe() |
| 66 | + rgb_pipeline.save("demo_volume_{}_pass_{}.png".format(timestamp, p)) |
| 67 | + print() |
| 68 | + |
| 69 | +# display final result |
| 70 | +plt.ioff() |
| 71 | +rgb_pipeline.display() |
| 72 | +plt.show() |
0 commit comments