Blender V5.0
bvh/node.cpp
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2009-2010 NVIDIA Corporation
2 * SPDX-FileCopyrightText: 2011-2022 Blender Foundation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Adapted code from NVIDIA Corporation. */
7
8#include "bvh/node.h"
9
10#include "bvh/build.h"
11#include "bvh/bvh.h"
12
14
15/* BVH Node */
16
18{
19 int cnt = 0;
20
21 switch (stat) {
23 cnt = 1;
24 break;
26 cnt = is_leaf() ? 1 : 0;
27 break;
29 cnt = is_leaf() ? 0 : 1;
30 break;
32 cnt = is_leaf() ? reinterpret_cast<const LeafNode *>(this)->num_triangles() : 0;
33 break;
35 cnt = num_children();
36 break;
38 if (!is_unaligned) {
39 cnt = 1;
40 }
41 break;
43 if (is_unaligned) {
44 cnt = 1;
45 }
46 break;
48 if (!is_leaf()) {
49 bool has_unaligned = false;
50 for (int j = 0; j < num_children(); j++) {
52 }
53 cnt += has_unaligned ? 0 : 1;
54 }
55 break;
57 if (!is_leaf()) {
58 bool has_unaligned = false;
59 for (int j = 0; j < num_children(); j++) {
61 }
62 cnt += has_unaligned ? 1 : 0;
63 }
64 break;
66 cnt = (is_leaf() && !is_unaligned) ? 1 : 0;
67 break;
69 cnt = (is_leaf() && is_unaligned) ? 1 : 0;
70 break;
71 case BVH_STAT_DEPTH:
72 if (is_leaf()) {
73 cnt = 1;
74 }
75 else {
76 for (int i = 0; i < num_children(); i++) {
77 cnt = max(cnt, get_child(i)->getSubtreeSize(stat));
78 }
79 cnt += 1;
80 }
81 return cnt;
82 default:
83 assert(0); /* unknown mode */
84 }
85
86 if (!is_leaf()) {
87 for (int i = 0; i < num_children(); i++) {
88 cnt += get_child(i)->getSubtreeSize(stat);
89 }
90 }
91
92 return cnt;
93}
94
95float BVHNode::computeSubtreeSAHCost(const BVHParams &p, const float probability) const
96{
97 float SAH = probability * p.cost(num_children(), num_triangles());
98
99 for (int i = 0; i < num_children(); i++) {
100 BVHNode *child = get_child(i);
101 SAH += child->computeSubtreeSAHCost(
102 p, probability * child->bounds.safe_area() / bounds.safe_area());
103 }
104
105 return SAH;
106}
107
109{
110 if (!is_leaf() && visibility == 0) {
111 InnerNode *inner = (InnerNode *)this;
112 BVHNode *child0 = inner->children[0].get();
113 BVHNode *child1 = inner->children[1].get();
114
115 visibility = child0->update_visibility() | child1->update_visibility();
116 }
117
118 return visibility;
119}
120
122{
123 if (!is_leaf()) {
124 InnerNode *inner = (InnerNode *)this;
125 BVHNode *child0 = inner->children[0].get();
126 BVHNode *child1 = inner->children[1].get();
127 child0->update_time();
128 child1->update_time();
129 time_from = min(child0->time_from, child1->time_from);
130 time_to = max(child0->time_to, child1->time_to);
131 }
132}
133
134namespace {
135
136struct DumpTraversalContext {
137 /* Descriptor of while where writing is happening. */
138 FILE *stream;
139 /* Unique identifier of the node current. */
140 int id;
141};
142
143void dump_subtree(DumpTraversalContext *context,
144 const BVHNode *node,
145 const BVHNode *parent = nullptr)
146{
147 if (node->is_leaf()) {
148 fprintf(context->stream,
149 " node_%p [label=\"%d\",fillcolor=\"#ccccee\",style=filled]\n",
150 node,
151 context->id);
152 }
153 else {
154 fprintf(context->stream,
155 " node_%p [label=\"%d\",fillcolor=\"#cceecc\",style=filled]\n",
156 node,
157 context->id);
158 }
159 if (parent != nullptr) {
160 fprintf(context->stream, " node_%p -> node_%p;\n", parent, node);
161 }
162 context->id += 1;
163 for (int i = 0; i < node->num_children(); ++i) {
164 dump_subtree(context, node->get_child(i), node);
165 }
166}
167
168} // namespace
169
170void BVHNode::dump_graph(const char *filename)
171{
172 DumpTraversalContext context;
173 context.stream = fopen(filename, "w");
174 if (context.stream == nullptr) {
175 return;
176 }
177 context.id = 0;
178 fprintf(context.stream, "digraph BVH {\n");
179 dump_subtree(&context, this);
180 fprintf(context.stream, "}\n");
181 fclose(context.stream);
182}
183
184/* Inner Node */
185
186void InnerNode::print(const int depth) const
187{
188 for (int i = 0; i < depth; i++) {
189 printf(" ");
190 }
191
192 printf("inner node %p\n", (void *)this);
193
194 if (children[0]) {
195 children[0]->print(depth + 1);
196 }
197 if (children[1]) {
198 children[1]->print(depth + 1);
199 }
200}
201
202void LeafNode::print(const int depth) const
203{
204 for (int i = 0; i < depth; i++) {
205 printf(" ");
206 }
207
208 printf("leaf node %d to %d\n", lo, hi);
209}
210
unsigned int uint
BVH_STAT
Definition bvh/node.h:16
@ BVH_STAT_TRIANGLE_COUNT
Definition bvh/node.h:20
@ BVH_STAT_NODE_COUNT
Definition bvh/node.h:17
@ BVH_STAT_CHILDNODE_COUNT
Definition bvh/node.h:21
@ BVH_STAT_ALIGNED_COUNT
Definition bvh/node.h:22
@ BVH_STAT_ALIGNED_INNER_COUNT
Definition bvh/node.h:24
@ BVH_STAT_ALIGNED_LEAF_COUNT
Definition bvh/node.h:26
@ BVH_STAT_DEPTH
Definition bvh/node.h:28
@ BVH_STAT_UNALIGNED_COUNT
Definition bvh/node.h:23
@ BVH_STAT_UNALIGNED_LEAF_COUNT
Definition bvh/node.h:27
@ BVH_STAT_UNALIGNED_INNER_COUNT
Definition bvh/node.h:25
@ BVH_STAT_INNER_COUNT
Definition bvh/node.h:18
@ BVH_STAT_LEAF_COUNT
Definition bvh/node.h:19
__forceinline float cost(const int num_nodes, const int num_primitives) const
Definition params.h:148
void print(const int depth) const override
Definition bvh/node.cpp:186
unique_ptr< BVHNode > children[kNumMaxChildren]
Definition bvh/node.h:166
void print(const int depth) const override
Definition bvh/node.cpp:202
#define CCL_NAMESPACE_END
#define assert(assertion)
#define printf(...)
int context(const bContext *C, const char *member, bContextDataResult *result)
#define min(a, b)
Definition sort.cc:36
float computeSubtreeSAHCost(const BVHParams &p, const float probability=1.0f) const
Definition bvh/node.cpp:95
int getSubtreeSize(BVH_STAT stat=BVH_STAT_NODE_COUNT) const
Definition bvh/node.cpp:17
void update_time()
Definition bvh/node.cpp:121
uint visibility
Definition bvh/node.h:90
uint update_visibility()
Definition bvh/node.cpp:108
virtual int num_children() const =0
float time_to
Definition bvh/node.h:99
BVHNode(const BoundBox &bounds)
Definition bvh/node.h:102
bool is_unaligned
Definition bvh/node.h:92
virtual bool is_leaf() const =0
float time_from
Definition bvh/node.h:99
bool has_unaligned() const
Definition bvh/node.h:65
virtual int num_triangles() const
Definition bvh/node.h:40
virtual BVHNode * get_child(const int i) const =0
BoundBox bounds
Definition bvh/node.h:89
void dump_graph(const char *filename)
Definition bvh/node.cpp:170
__forceinline float safe_area() const
Definition boundbox.h:92
i
Definition text_draw.cc:230
max
Definition text_draw.cc:251