A scene graph of nodes.
| 15 | |
| 16 | |
| 17 | class Scene(object): |
| 18 | """ A scene graph of nodes. |
| 19 | """ |
| 20 | |
| 21 | def __init__(self, root=None): |
| 22 | super(Scene, self).__init__() |
| 23 | self.root = root |
| 24 | |
| 25 | def finalise_nodes(self): |
| 26 | """ Update bounding boxes of node hierarchy in prepration for tracing. |
| 27 | """ |
| 28 | root = self.root |
| 29 | if root is not None: |
| 30 | |
| 31 | # Clear any existing bounding boxes |
| 32 | for node in PostOrderIter(root): |
| 33 | node.bounding_box = None |
| 34 | |
| 35 | # More efficiency to calcualte from leaves to root because because |
| 36 | # the parent's bounding box calculation requires the size of the |
| 37 | # child's bounding box. |
| 38 | leaves = self.root.leaves |
| 39 | for leaf_node in leaves: |
| 40 | node = leaf_node |
| 41 | while True: |
| 42 | _ = node.bounding_box # will force recalculation |
| 43 | node = node.parent |
| 44 | if node is None: |
| 45 | break |
| 46 | |
| 47 | @property |
| 48 | def light_nodes(self) -> Sequence[Light]: |
| 49 | """ Returns all lights in the scene. |
| 50 | """ |
| 51 | root = self.root |
| 52 | found_nodes = [] |
| 53 | for node in LevelOrderIter(root): |
| 54 | if isinstance(node.light, Light): |
| 55 | found_nodes.append(node) |
| 56 | return found_nodes |
| 57 | |
| 58 | @property |
| 59 | def component_nodes(self) -> Sequence[Component]: |
| 60 | """ Returns all lights in the scene. |
| 61 | """ |
| 62 | root = self.root |
| 63 | found_nodes = [] |
| 64 | for node in LevelOrderIter(root): |
| 65 | if node.geometry: |
| 66 | if node.geometry.material: |
| 67 | found_nodes.extend(node.geometry.material.components) |
| 68 | return found_nodes |
| 69 | |
| 70 | def emit(self, num_rays): |
| 71 | """ Rays are emitted in the coordinate system of the world node. |
| 72 | |
| 73 | Internally the scene cycles through Light nodes, askes them to emit |
| 74 | a ray and the converts the ray to the world coordinate system. |
no outgoing calls