Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/cycles/bvh/node.cpp')
-rw-r--r--intern/cycles/bvh/node.cpp224
1 files changed, 224 insertions, 0 deletions
diff --git a/intern/cycles/bvh/node.cpp b/intern/cycles/bvh/node.cpp
new file mode 100644
index 00000000000..d3a665adfe7
--- /dev/null
+++ b/intern/cycles/bvh/node.cpp
@@ -0,0 +1,224 @@
+/*
+ * Adapted from code copyright 2009-2010 NVIDIA Corporation
+ * Modifications Copyright 2011, Blender Foundation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "bvh/node.h"
+
+#include "bvh/build.h"
+#include "bvh/bvh.h"
+
+#include "util/vector.h"
+
+CCL_NAMESPACE_BEGIN
+
+/* BVH Node */
+
+int BVHNode::getSubtreeSize(BVH_STAT stat) const
+{
+ int cnt = 0;
+
+ switch (stat) {
+ case BVH_STAT_NODE_COUNT:
+ cnt = 1;
+ break;
+ case BVH_STAT_LEAF_COUNT:
+ cnt = is_leaf() ? 1 : 0;
+ break;
+ case BVH_STAT_INNER_COUNT:
+ cnt = is_leaf() ? 0 : 1;
+ break;
+ case BVH_STAT_TRIANGLE_COUNT:
+ cnt = is_leaf() ? reinterpret_cast<const LeafNode *>(this)->num_triangles() : 0;
+ break;
+ case BVH_STAT_CHILDNODE_COUNT:
+ cnt = num_children();
+ break;
+ case BVH_STAT_ALIGNED_COUNT:
+ if (!is_unaligned) {
+ cnt = 1;
+ }
+ break;
+ case BVH_STAT_UNALIGNED_COUNT:
+ if (is_unaligned) {
+ cnt = 1;
+ }
+ break;
+ case BVH_STAT_ALIGNED_INNER_COUNT:
+ if (!is_leaf()) {
+ bool has_unaligned = false;
+ for (int j = 0; j < num_children(); j++) {
+ has_unaligned |= get_child(j)->is_unaligned;
+ }
+ cnt += has_unaligned ? 0 : 1;
+ }
+ break;
+ case BVH_STAT_UNALIGNED_INNER_COUNT:
+ if (!is_leaf()) {
+ bool has_unaligned = false;
+ for (int j = 0; j < num_children(); j++) {
+ has_unaligned |= get_child(j)->is_unaligned;
+ }
+ cnt += has_unaligned ? 1 : 0;
+ }
+ break;
+ case BVH_STAT_ALIGNED_LEAF_COUNT:
+ cnt = (is_leaf() && !is_unaligned) ? 1 : 0;
+ break;
+ case BVH_STAT_UNALIGNED_LEAF_COUNT:
+ cnt = (is_leaf() && is_unaligned) ? 1 : 0;
+ break;
+ case BVH_STAT_DEPTH:
+ if (is_leaf()) {
+ cnt = 1;
+ }
+ else {
+ for (int i = 0; i < num_children(); i++) {
+ cnt = max(cnt, get_child(i)->getSubtreeSize(stat));
+ }
+ cnt += 1;
+ }
+ return cnt;
+ default:
+ assert(0); /* unknown mode */
+ }
+
+ if (!is_leaf())
+ for (int i = 0; i < num_children(); i++)
+ cnt += get_child(i)->getSubtreeSize(stat);
+
+ return cnt;
+}
+
+void BVHNode::deleteSubtree()
+{
+ for (int i = 0; i < num_children(); i++)
+ if (get_child(i))
+ get_child(i)->deleteSubtree();
+
+ delete this;
+}
+
+float BVHNode::computeSubtreeSAHCost(const BVHParams &p, float probability) const
+{
+ float SAH = probability * p.cost(num_children(), num_triangles());
+
+ for (int i = 0; i < num_children(); i++) {
+ BVHNode *child = get_child(i);
+ SAH += child->computeSubtreeSAHCost(
+ p, probability * child->bounds.safe_area() / bounds.safe_area());
+ }
+
+ return SAH;
+}
+
+uint BVHNode::update_visibility()
+{
+ if (!is_leaf() && visibility == 0) {
+ InnerNode *inner = (InnerNode *)this;
+ BVHNode *child0 = inner->children[0];
+ BVHNode *child1 = inner->children[1];
+
+ visibility = child0->update_visibility() | child1->update_visibility();
+ }
+
+ return visibility;
+}
+
+void BVHNode::update_time()
+{
+ if (!is_leaf()) {
+ InnerNode *inner = (InnerNode *)this;
+ BVHNode *child0 = inner->children[0];
+ BVHNode *child1 = inner->children[1];
+ child0->update_time();
+ child1->update_time();
+ time_from = min(child0->time_from, child1->time_from);
+ time_to = max(child0->time_to, child1->time_to);
+ }
+}
+
+namespace {
+
+struct DumpTraversalContext {
+ /* Descriptor of wile where writing is happening. */
+ FILE *stream;
+ /* Unique identifier of the node current. */
+ int id;
+};
+
+void dump_subtree(DumpTraversalContext *context, const BVHNode *node, const BVHNode *parent = NULL)
+{
+ if (node->is_leaf()) {
+ fprintf(context->stream,
+ " node_%p [label=\"%d\",fillcolor=\"#ccccee\",style=filled]\n",
+ node,
+ context->id);
+ }
+ else {
+ fprintf(context->stream,
+ " node_%p [label=\"%d\",fillcolor=\"#cceecc\",style=filled]\n",
+ node,
+ context->id);
+ }
+ if (parent != NULL) {
+ fprintf(context->stream, " node_%p -> node_%p;\n", parent, node);
+ }
+ context->id += 1;
+ for (int i = 0; i < node->num_children(); ++i) {
+ dump_subtree(context, node->get_child(i), node);
+ }
+}
+
+} // namespace
+
+void BVHNode::dump_graph(const char *filename)
+{
+ DumpTraversalContext context;
+ context.stream = fopen(filename, "w");
+ if (context.stream == NULL) {
+ return;
+ }
+ context.id = 0;
+ fprintf(context.stream, "digraph BVH {\n");
+ dump_subtree(&context, this);
+ fprintf(context.stream, "}\n");
+ fclose(context.stream);
+}
+
+/* Inner Node */
+
+void InnerNode::print(int depth) const
+{
+ for (int i = 0; i < depth; i++)
+ printf(" ");
+
+ printf("inner node %p\n", (void *)this);
+
+ if (children[0])
+ children[0]->print(depth + 1);
+ if (children[1])
+ children[1]->print(depth + 1);
+}
+
+void LeafNode::print(int depth) const
+{
+ for (int i = 0; i < depth; i++)
+ printf(" ");
+
+ printf("leaf node %d to %d\n", lo, hi);
+}
+
+CCL_NAMESPACE_END