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:
authorJulian Eisel <eiseljulian@gmail.com>2015-10-21 18:30:35 +0300
committerJulian Eisel <eiseljulian@gmail.com>2015-10-21 18:30:35 +0300
commit0775680e4d05eda3c495a56dc0b6eafbe96dc586 (patch)
tree4f3286eef96dec6ababe43467ed2a4f50388b988 /intern/cycles/bvh
parent4ade467fc6adfc13ce9e21d7e50b366fce70ea5f (diff)
parent6bc007610263c879f6bb30b844ba9d9a0fb9433c (diff)
Merge branch 'master' into UI-graphical-redesignUI-graphical-redesign
Conflicts: source/blender/blenkernel/BKE_blender.h source/blender/blenloader/intern/versioning_270.c source/blender/editors/interface/interface.c source/blender/editors/interface/interface_handlers.c source/blender/editors/interface/interface_intern.h source/blender/editors/interface/resources.c
Diffstat (limited to 'intern/cycles/bvh')
-rw-r--r--intern/cycles/bvh/bvh.cpp126
-rw-r--r--intern/cycles/bvh/bvh.h9
-rw-r--r--intern/cycles/bvh/bvh_binning.cpp6
-rw-r--r--intern/cycles/bvh/bvh_build.cpp18
-rw-r--r--intern/cycles/bvh/bvh_params.h4
-rw-r--r--intern/cycles/bvh/bvh_split.cpp237
-rw-r--r--intern/cycles/bvh/bvh_split.h53
7 files changed, 249 insertions, 204 deletions
diff --git a/intern/cycles/bvh/bvh.cpp b/intern/cycles/bvh/bvh.cpp
index 350ca16f6e2..4a5f8b1bda6 100644
--- a/intern/cycles/bvh/bvh.cpp
+++ b/intern/cycles/bvh/bvh.cpp
@@ -25,7 +25,6 @@
#include "bvh_node.h"
#include "bvh_params.h"
-#include "util_cache.h"
#include "util_debug.h"
#include "util_foreach.h"
#include "util_logging.h"
@@ -70,125 +69,12 @@ BVH *BVH::create(const BVHParams& params, const vector<Object*>& objects)
return new RegularBVH(params, objects);
}
-/* Cache */
-
-bool BVH::cache_read(CacheData& key)
-{
- key.add(system_cpu_bits());
- key.add(&params, sizeof(params));
-
- foreach(Object *ob, objects) {
- Mesh *mesh = ob->mesh;
-
- key.add(mesh->verts);
- key.add(mesh->triangles);
- key.add(mesh->curve_keys);
- key.add(mesh->curves);
- key.add(&ob->bounds, sizeof(ob->bounds));
- key.add(&ob->visibility, sizeof(ob->visibility));
- key.add(&mesh->transform_applied, sizeof(bool));
-
- if(mesh->use_motion_blur) {
- Attribute *attr = mesh->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
- if(attr)
- key.add(attr->buffer);
-
- attr = mesh->curve_attributes.find(ATTR_STD_MOTION_VERTEX_POSITION);
- if(attr)
- key.add(attr->buffer);
- }
- }
-
- CacheData value;
-
- if(Cache::global.lookup(key, value)) {
- cache_filename = key.get_filename();
-
- if(!(value.read(pack.root_index) &&
- value.read(pack.SAH) &&
- value.read(pack.nodes) &&
- value.read(pack.leaf_nodes) &&
- value.read(pack.object_node) &&
- value.read(pack.tri_woop) &&
- value.read(pack.prim_type) &&
- value.read(pack.prim_visibility) &&
- value.read(pack.prim_index) &&
- value.read(pack.prim_object)))
- {
- /* Clear the pack if load failed. */
- pack.root_index = 0;
- pack.SAH = 0.0f;
- pack.nodes.clear();
- pack.leaf_nodes.clear();
- pack.object_node.clear();
- pack.tri_woop.clear();
- pack.prim_type.clear();
- pack.prim_visibility.clear();
- pack.prim_index.clear();
- pack.prim_object.clear();
- return false;
- }
- return true;
- }
-
- return false;
-}
-
-void BVH::cache_write(CacheData& key)
-{
- CacheData value;
-
- value.add(pack.root_index);
- value.add(pack.SAH);
-
- value.add(pack.nodes);
- value.add(pack.leaf_nodes);
- value.add(pack.object_node);
- value.add(pack.tri_woop);
- value.add(pack.prim_type);
- value.add(pack.prim_visibility);
- value.add(pack.prim_index);
- value.add(pack.prim_object);
-
- Cache::global.insert(key, value);
-
- cache_filename = key.get_filename();
-}
-
-void BVH::clear_cache_except()
-{
- set<string> except;
-
- if(!cache_filename.empty())
- except.insert(cache_filename);
-
- foreach(Object *ob, objects) {
- Mesh *mesh = ob->mesh;
- BVH *bvh = mesh->bvh;
-
- if(bvh && !bvh->cache_filename.empty())
- except.insert(bvh->cache_filename);
- }
-
- Cache::global.clear_except("bvh", except);
-}
-
/* Building */
void BVH::build(Progress& progress)
{
progress.set_substatus("Building BVH");
- /* cache read */
- CacheData key("bvh");
-
- if(params.use_cache) {
- progress.set_substatus("Looking in BVH cache");
-
- if(cache_read(key))
- return;
- }
-
/* build nodes */
BVHBuild bvh_build(objects,
pack.prim_type,
@@ -227,18 +113,6 @@ void BVH::build(Progress& progress)
/* free build nodes */
root->deleteSubtree();
-
- if(progress.get_cancel()) return;
-
- /* cache write */
- if(params.use_cache) {
- progress.set_substatus("Writing BVH cache");
- cache_write(key);
-
- /* clear other bvh files from cache */
- if(params.top_level)
- clear_cache_except();
- }
}
/* Refitting */
diff --git a/intern/cycles/bvh/bvh.h b/intern/cycles/bvh/bvh.h
index 669d2ccdcd5..272a3fa1514 100644
--- a/intern/cycles/bvh/bvh.h
+++ b/intern/cycles/bvh/bvh.h
@@ -20,7 +20,6 @@
#include "bvh_params.h"
-#include "util_string.h"
#include "util_types.h"
#include "util_vector.h"
@@ -30,7 +29,6 @@ class BVHNode;
struct BVHStackEntry;
class BVHParams;
class BoundBox;
-class CacheData;
class LeafNode;
class Object;
class Progress;
@@ -87,7 +85,6 @@ public:
PackedBVH pack;
BVHParams params;
vector<Object*> objects;
- string cache_filename;
static BVH *create(const BVHParams& params, const vector<Object*>& objects);
virtual ~BVH() {}
@@ -95,15 +92,9 @@ public:
void build(Progress& progress);
void refit(Progress& progress);
- void clear_cache_except();
-
protected:
BVH(const BVHParams& params, const vector<Object*>& objects);
- /* cache */
- bool cache_read(CacheData& key);
- void cache_write(CacheData& key);
-
/* triangles and strands*/
void pack_primitives();
void pack_triangle(int idx, float4 woop[3]);
diff --git a/intern/cycles/bvh/bvh_binning.cpp b/intern/cycles/bvh/bvh_binning.cpp
index db96490a36f..8745e39c21e 100644
--- a/intern/cycles/bvh/bvh_binning.cpp
+++ b/intern/cycles/bvh/bvh_binning.cpp
@@ -76,8 +76,8 @@ BVHObjectBinning::BVHObjectBinning(const BVHRange& job, BVHReference *prims)
prefetch_L2(&prims[start() + i + 8]);
/* map even and odd primitive to bin */
- BVHReference prim0 = prims[start() + i + 0];
- BVHReference prim1 = prims[start() + i + 1];
+ const BVHReference& prim0 = prims[start() + i + 0];
+ const BVHReference& prim1 = prims[start() + i + 1];
int4 bin0 = get_bin(prim0.bounds());
int4 bin1 = get_bin(prim1.bounds());
@@ -96,7 +96,7 @@ BVHObjectBinning::BVHObjectBinning(const BVHRange& job, BVHReference *prims)
/* for uneven number of primitives */
if(i < ssize_t(size())) {
/* map primitive to bin */
- BVHReference prim0 = prims[start() + i];
+ const BVHReference& prim0 = prims[start() + i];
int4 bin0 = get_bin(prim0.bounds());
/* increase bounds of bins */
diff --git a/intern/cycles/bvh/bvh_build.cpp b/intern/cycles/bvh/bvh_build.cpp
index a44ad656316..45b0aaa2d63 100644
--- a/intern/cycles/bvh/bvh_build.cpp
+++ b/intern/cycles/bvh/bvh_build.cpp
@@ -234,8 +234,14 @@ BVHNode* BVHBuild::run()
return NULL;
/* init spatial splits */
- if(params.top_level) /* todo: get rid of this */
+ if(params.top_level) {
+ /* NOTE: Technically it is supported by the builder but it's not really
+ * optimized for speed yet and not really clear yet if it has measurable
+ * improvement on render time. Needs some extra investigation before
+ * enabling spatial split for top level BVH.
+ */
params.use_spatial_split = false;
+ }
spatial_min_overlap = root.bounds().safe_area() * params.spatial_split_alpha;
spatial_right_bounds.clear();
@@ -276,6 +282,8 @@ BVHNode* BVHBuild::run()
else if(!params.use_spatial_split) {
/*rotate(rootnode, 4, 5);*/
rootnode->update_visibility();
+ }
+ if(rootnode != NULL) {
VLOG(1) << "BVH build statistics:\n"
<< " Build time: " << time_dt() - build_start_time << "\n"
<< " Total number of nodes: "
@@ -525,11 +533,9 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range)
/* Extend an array when needed. */
if(prim_type.size() < range.end()) {
assert(params.use_spatial_split);
- /* TODO(sergey): We might want to look into different policies of
- * re-allocation here, so on the one hand we would not do as much
- * re-allocations and on the other hand will have small memory
- * overhead.
- */
+ prim_type.reserve(references.size());
+ prim_index.reserve(references.size());
+ prim_object.reserve(references.size());
prim_type.resize(range.end());
prim_index.resize(range.end());
prim_object.resize(range.end());
diff --git a/intern/cycles/bvh/bvh_params.h b/intern/cycles/bvh/bvh_params.h
index af8d8eeb3ee..faa995c3f29 100644
--- a/intern/cycles/bvh/bvh_params.h
+++ b/intern/cycles/bvh/bvh_params.h
@@ -43,9 +43,6 @@ public:
/* object or mesh level bvh */
bool top_level;
- /* disk cache */
- bool use_cache;
-
/* QBVH */
bool use_qbvh;
@@ -71,7 +68,6 @@ public:
max_curve_leaf_size = 2;
top_level = false;
- use_cache = false;
use_qbvh = false;
}
diff --git a/intern/cycles/bvh/bvh_split.cpp b/intern/cycles/bvh/bvh_split.cpp
index 2290c4143ad..534c1aa73b5 100644
--- a/intern/cycles/bvh/bvh_split.cpp
+++ b/intern/cycles/bvh/bvh_split.cpp
@@ -191,11 +191,16 @@ void BVHSpatialSplit::split(BVHBuild *builder, BVHRange& left, BVHRange& right,
}
}
- /* duplicate or unsplit references intersecting both sides. */
+ /* Duplicate or unsplit references intersecting both sides.
+ *
+ * Duplication happens into a temporary pre-allocated vector in order to
+ * reduce number of memmove() calls happening in vector.insert().
+ */
+ vector<BVHReference> new_refs;
+ new_refs.reserve(right_start - left_end);
while(left_end < right_start) {
/* split reference. */
BVHReference lref, rref;
-
split_reference(builder, lref, rref, refs[left_end], this->dim, this->pos);
/* compute SAH for duplicate/unsplit candidates. */
@@ -234,61 +239,36 @@ void BVHSpatialSplit::split(BVHBuild *builder, BVHRange& left, BVHRange& right,
left_bounds = ldb;
right_bounds = rdb;
refs[left_end++] = lref;
- refs.insert(refs.begin() + right_end, rref);
+ new_refs.push_back(rref);
right_end++;
}
}
-
+ /* Insert duplicated references into actual array in one go. */
+ if(new_refs.size() != 0) {
+ refs.insert(refs.begin() + right_end - new_refs.size(),
+ new_refs.begin(),
+ new_refs.end());
+ }
left = BVHRange(left_bounds, left_start, left_end - left_start);
right = BVHRange(right_bounds, right_start, right_end - right_start);
}
-void BVHSpatialSplit::split_reference(BVHBuild *builder, BVHReference& left, BVHReference& right, const BVHReference& ref, int dim, float pos)
+void BVHSpatialSplit::split_triangle_primitive(const Mesh *mesh,
+ const Transform *tfm,
+ int prim_index,
+ int dim,
+ float pos,
+ BoundBox& left_bounds,
+ BoundBox& right_bounds)
{
- /* initialize boundboxes */
- BoundBox left_bounds = BoundBox::empty;
- BoundBox right_bounds = BoundBox::empty;
-
- /* loop over vertices/edges. */
- Object *ob = builder->objects[ref.prim_object()];
- const Mesh *mesh = ob->mesh;
-
- if(ref.prim_type() & PRIMITIVE_ALL_TRIANGLE) {
- const int *inds = mesh->triangles[ref.prim_index()].v;
- const float3 *verts = &mesh->verts[0];
- const float3* v1 = &verts[inds[2]];
-
- for(int i = 0; i < 3; i++) {
- const float3* v0 = v1;
- int vindex = inds[i];
- v1 = &verts[vindex];
- float v0p = (*v0)[dim];
- float v1p = (*v1)[dim];
-
- /* insert vertex to the boxes it belongs to. */
- if(v0p <= pos)
- left_bounds.grow(*v0);
-
- if(v0p >= pos)
- right_bounds.grow(*v0);
-
- /* edge intersects the plane => insert intersection to both boxes. */
- if((v0p < pos && v1p > pos) || (v0p > pos && v1p < pos)) {
- float3 t = lerp(*v0, *v1, clamp((pos - v0p) / (v1p - v0p), 0.0f, 1.0f));
- left_bounds.grow(t);
- right_bounds.grow(t);
- }
- }
- }
- else {
- /* curve split: NOTE - Currently ignores curve width and needs to be fixed.*/
- const int k0 = mesh->curves[ref.prim_index()].first_key + PRIMITIVE_UNPACK_SEGMENT(ref.prim_type());
- const int k1 = k0 + 1;
- const float4 key0 = mesh->curve_keys[k0];
- const float4 key1 = mesh->curve_keys[k1];
- const float3 v0 = float4_to_float3(key0);
- const float3 v1 = float4_to_float3(key1);
-
+ const int *inds = mesh->triangles[prim_index].v;
+ const float3 *verts = &mesh->verts[0];
+ float3 v1 = tfm ? transform_point(tfm, verts[inds[2]]) : verts[inds[2]];
+
+ for(int i = 0; i < 3; i++) {
+ float3 v0 = v1;
+ int vindex = inds[i];
+ v1 = tfm ? transform_point(tfm, verts[vindex]) : verts[vindex];
float v0p = v0[dim];
float v1p = v1[dim];
@@ -299,12 +279,6 @@ void BVHSpatialSplit::split_reference(BVHBuild *builder, BVHReference& left, BVH
if(v0p >= pos)
right_bounds.grow(v0);
- if(v1p <= pos)
- left_bounds.grow(v1);
-
- if(v1p >= pos)
- right_bounds.grow(v1);
-
/* edge intersects the plane => insert intersection to both boxes. */
if((v0p < pos && v1p > pos) || (v0p > pos && v1p < pos)) {
float3 t = lerp(v0, v1, clamp((pos - v0p) / (v1p - v0p), 0.0f, 1.0f));
@@ -312,6 +286,159 @@ void BVHSpatialSplit::split_reference(BVHBuild *builder, BVHReference& left, BVH
right_bounds.grow(t);
}
}
+}
+
+void BVHSpatialSplit::split_curve_primitive(const Mesh *mesh,
+ const Transform *tfm,
+ int prim_index,
+ int segment_index,
+ int dim,
+ float pos,
+ BoundBox& left_bounds,
+ BoundBox& right_bounds)
+{
+ /* curve split: NOTE - Currently ignores curve width and needs to be fixed.*/
+ const int k0 = mesh->curves[prim_index].first_key + segment_index;
+ const int k1 = k0 + 1;
+ const float4& key0 = mesh->curve_keys[k0];
+ const float4& key1 = mesh->curve_keys[k1];
+ float3 v0 = float4_to_float3(key0);
+ float3 v1 = float4_to_float3(key1);
+
+ if(tfm != NULL) {
+ v0 = transform_point(tfm, v0);
+ v1 = transform_point(tfm, v1);
+ }
+
+ float v0p = v0[dim];
+ float v1p = v1[dim];
+
+ /* insert vertex to the boxes it belongs to. */
+ if(v0p <= pos)
+ left_bounds.grow(v0);
+
+ if(v0p >= pos)
+ right_bounds.grow(v0);
+
+ if(v1p <= pos)
+ left_bounds.grow(v1);
+
+ if(v1p >= pos)
+ right_bounds.grow(v1);
+
+ /* edge intersects the plane => insert intersection to both boxes. */
+ if((v0p < pos && v1p > pos) || (v0p > pos && v1p < pos)) {
+ float3 t = lerp(v0, v1, clamp((pos - v0p) / (v1p - v0p), 0.0f, 1.0f));
+ left_bounds.grow(t);
+ right_bounds.grow(t);
+ }
+}
+
+void BVHSpatialSplit::split_triangle_reference(const BVHReference& ref,
+ const Mesh *mesh,
+ int dim,
+ float pos,
+ BoundBox& left_bounds,
+ BoundBox& right_bounds)
+{
+ split_triangle_primitive(mesh,
+ NULL,
+ ref.prim_index(),
+ dim,
+ pos,
+ left_bounds,
+ right_bounds);
+}
+
+void BVHSpatialSplit::split_curve_reference(const BVHReference& ref,
+ const Mesh *mesh,
+ int dim,
+ float pos,
+ BoundBox& left_bounds,
+ BoundBox& right_bounds)
+{
+ split_curve_primitive(mesh,
+ NULL,
+ ref.prim_index(),
+ PRIMITIVE_UNPACK_SEGMENT(ref.prim_type()),
+ dim,
+ pos,
+ left_bounds,
+ right_bounds);
+}
+
+void BVHSpatialSplit::split_object_reference(const Object *object,
+ int dim,
+ float pos,
+ BoundBox& left_bounds,
+ BoundBox& right_bounds)
+{
+ Mesh *mesh = object->mesh;
+ for(int tri_idx = 0; tri_idx < mesh->triangles.size(); ++tri_idx) {
+ split_triangle_primitive(mesh,
+ &object->tfm,
+ tri_idx,
+ dim,
+ pos,
+ left_bounds,
+ right_bounds);
+ }
+ for(int curve_idx = 0; curve_idx < mesh->curves.size(); ++curve_idx) {
+ Mesh::Curve &curve = mesh->curves[curve_idx];
+ for(int segment_idx = 0;
+ segment_idx < curve.num_keys - 1;
+ ++segment_idx)
+ {
+ split_curve_primitive(mesh,
+ &object->tfm,
+ curve_idx,
+ segment_idx,
+ dim,
+ pos,
+ left_bounds,
+ right_bounds);
+ }
+ }
+}
+
+void BVHSpatialSplit::split_reference(BVHBuild *builder,
+ BVHReference& left,
+ BVHReference& right,
+ const BVHReference& ref,
+ int dim,
+ float pos)
+{
+ /* initialize boundboxes */
+ BoundBox left_bounds = BoundBox::empty;
+ BoundBox right_bounds = BoundBox::empty;
+
+ /* loop over vertices/edges. */
+ Object *ob = builder->objects[ref.prim_object()];
+ const Mesh *mesh = ob->mesh;
+
+ if(ref.prim_type() & PRIMITIVE_ALL_TRIANGLE) {
+ split_triangle_reference(ref,
+ mesh,
+ dim,
+ pos,
+ left_bounds,
+ right_bounds);
+ }
+ else if(ref.prim_type() & PRIMITIVE_ALL_CURVE) {
+ split_curve_reference(ref,
+ mesh,
+ dim,
+ pos,
+ left_bounds,
+ right_bounds);
+ }
+ else {
+ split_object_reference(ob,
+ dim,
+ pos,
+ left_bounds,
+ right_bounds);
+ }
/* intersect with original bounds. */
left_bounds.max[dim] = pos;
diff --git a/intern/cycles/bvh/bvh_split.h b/intern/cycles/bvh/bvh_split.h
index 5b739311e5f..1e46bb66203 100644
--- a/intern/cycles/bvh/bvh_split.h
+++ b/intern/cycles/bvh/bvh_split.h
@@ -55,7 +55,58 @@ public:
BVHSpatialSplit(BVHBuild *builder, const BVHRange& range, float nodeSAH);
void split(BVHBuild *builder, BVHRange& left, BVHRange& right, const BVHRange& range);
- void split_reference(BVHBuild *builder, BVHReference& left, BVHReference& right, const BVHReference& ref, int dim, float pos);
+ void split_reference(BVHBuild *builder,
+ BVHReference& left,
+ BVHReference& right,
+ const BVHReference& ref,
+ int dim,
+ float pos);
+
+protected:
+ /* Lower-level functions which calculates boundaries of left and right nodes
+ * needed for spatial split.
+ *
+ * Operates directly with primitive specified by it's index, reused by higher
+ * level splitting functions.
+ */
+ void split_triangle_primitive(const Mesh *mesh,
+ const Transform *tfm,
+ int prim_index,
+ int dim,
+ float pos,
+ BoundBox& left_bounds,
+ BoundBox& right_bounds);
+ void split_curve_primitive(const Mesh *mesh,
+ const Transform *tfm,
+ int prim_index,
+ int segment_index,
+ int dim,
+ float pos,
+ BoundBox& left_bounds,
+ BoundBox& right_bounds);
+
+ /* Lower-level functions which calculates boundaries of left and right nodes
+ * needed for spatial split.
+ *
+ * Operates with BVHReference, internally uses lower level API functions.
+ */
+ void split_triangle_reference(const BVHReference& ref,
+ const Mesh *mesh,
+ int dim,
+ float pos,
+ BoundBox& left_bounds,
+ BoundBox& right_bounds);
+ void split_curve_reference(const BVHReference& ref,
+ const Mesh *mesh,
+ int dim,
+ float pos,
+ BoundBox& left_bounds,
+ BoundBox& right_bounds);
+ void split_object_reference(const Object *object,
+ int dim,
+ float pos,
+ BoundBox& left_bounds,
+ BoundBox& right_bounds);
};
/* Mixed Object-Spatial Split */