[SCM] blender/upstream: New upstream version 2.78.c+dfsg0
mfv at users.alioth.debian.org
mfv at users.alioth.debian.org
Sat Jun 3 20:28:12 UTC 2017
The following commit has been merged in the upstream branch:
commit aabbbecb847abea264b2783443e4a86d2bee2077
Author: Matteo F. Vescovi <mfv at debian.org>
Date: Sat Jun 3 22:12:14 2017 +0200
New upstream version 2.78.c+dfsg0
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 578f913..8a48e6e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -445,6 +445,7 @@ option(WITH_BOOST "Enable features depending on boost" ON)
# Unit testsing
option(WITH_GTESTS "Enable GTest unit testing" OFF)
+option(WITH_OPENGL_TESTS "Enable OpenGL related unit testing (Experimental)" OFF)
# Documentation
diff --git a/build_files/cmake/Modules/GTestTesting.cmake b/build_files/cmake/Modules/GTestTesting.cmake
index 96c06ef..0732e10 100644
--- a/build_files/cmake/Modules/GTestTesting.cmake
+++ b/build_files/cmake/Modules/GTestTesting.cmake
@@ -45,7 +45,7 @@ macro(BLENDER_SRC_GTEST_EX NAME SRC EXTRA_LIBS DO_ADD_TEST)
RUNTIME_OUTPUT_DIRECTORY_DEBUG "${TESTS_OUTPUT_DIR}"
INCLUDE_DIRECTORIES "${TEST_INC}")
if(${DO_ADD_TEST})
- add_test(${NAME}_test ${TESTS_OUTPUT_DIR}/${NAME}_test)
+ add_test(NAME ${NAME}_test COMMAND ${TESTS_OUTPUT_DIR}/${NAME}_test WORKING_DIRECTORY $<TARGET_FILE_DIR:blender>)
endif()
endif()
endmacro()
diff --git a/build_files/cmake/macros.cmake b/build_files/cmake/macros.cmake
index 5a67ac9..ead4fd4 100644
--- a/build_files/cmake/macros.cmake
+++ b/build_files/cmake/macros.cmake
@@ -416,14 +416,7 @@ function(setup_liblinks
target_link_libraries(${target} ${OPENCOLORIO_LIBRARIES})
endif()
if(WITH_OPENSUBDIV OR WITH_CYCLES_OPENSUBDIV)
- if(WIN32 AND NOT UNIX)
- file_list_suffix(OPENSUBDIV_LIBRARIES_DEBUG "${OPENSUBDIV_LIBRARIES}" "_d")
- target_link_libraries_debug(${target} "${OPENSUBDIV_LIBRARIES_DEBUG}")
- target_link_libraries_optimized(${target} "${OPENSUBDIV_LIBRARIES}")
- unset(OPENSUBDIV_LIBRARIES_DEBUG)
- else()
target_link_libraries(${target} ${OPENSUBDIV_LIBRARIES})
- endif()
endif()
if(WITH_OPENVDB)
target_link_libraries(${target} ${OPENVDB_LIBRARIES} ${TBB_LIBRARIES})
@@ -1205,7 +1198,7 @@ function(get_blender_version)
string(LENGTH "${_out_version_char}" _out_version_char_len)
if(NOT _out_version_char_len EQUAL 1)
set(_out_version_char "")
- elseif(NOT ${_out_version_char} MATCHES "[a-z]+")
+ elseif(NOT ${_out_version_char} MATCHES "[a-z]?")
message(FATAL_ERROR "Version parsing failed for BLENDER_VERSION_CHAR")
endif()
diff --git a/build_files/cmake/platform/platform_win32_msvc.cmake b/build_files/cmake/platform/platform_win32_msvc.cmake
index ecdba59..8968581 100644
--- a/build_files/cmake/platform/platform_win32_msvc.cmake
+++ b/build_files/cmake/platform/platform_win32_msvc.cmake
@@ -444,10 +444,20 @@ if(WITH_MOD_CLOTH_ELTOPO)
endif()
if(WITH_OPENSUBDIV OR WITH_CYCLES_OPENSUBDIV)
- set(OPENSUBDIV_INCLUDE_DIR ${LIBDIR}/opensubdiv/include)
- set(OPENSUBDIV_LIBPATH ${LIBDIR}/opensubdiv/lib)
- set(OPENSUBDIV_LIBRARIES ${OPENSUBDIV_LIBPATH}/osdCPU.lib ${OPENSUBDIV_LIBPATH}/osdGPU.lib)
- find_package(OpenSubdiv)
+ set(OPENSUBDIV_INCLUDE_DIR ${LIBDIR}/opensubdiv/include)
+ set(OPENSUBDIV_LIBPATH ${LIBDIR}/opensubdiv/lib)
+ set(OPENSUBDIV_LIBRARIES optimized ${OPENSUBDIV_LIBPATH}/osdCPU.lib
+ optimized ${OPENSUBDIV_LIBPATH}/osdGPU.lib
+ debug ${OPENSUBDIV_LIBPATH}/osdCPU_d.lib
+ debug ${OPENSUBDIV_LIBPATH}/osdGPU_d.lib
+ )
+ set(OPENSUBDIV_HAS_OPENMP TRUE)
+ set(OPENSUBDIV_HAS_TBB FALSE)
+ set(OPENSUBDIV_HAS_OPENCL TRUE)
+ set(OPENSUBDIV_HAS_CUDA FALSE)
+ set(OPENSUBDIV_HAS_GLSL_TRANSFORM_FEEDBACK TRUE)
+ set(OPENSUBDIV_HAS_GLSL_COMPUTE TRUE)
+ windows_find_package(OpenSubdiv)
endif()
if(WITH_SDL)
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index 85117cf..79db072 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -525,69 +525,177 @@ static void attr_create_uv_map(Scene *scene,
}
/* Create vertex pointiness attributes. */
+
+/* Compare vertices by sum of their coordinates. */
+class VertexAverageComparator {
+public:
+ VertexAverageComparator(const array<float3>& verts)
+ : verts_(verts) {
+ }
+
+ bool operator()(const int& vert_idx_a, const int& vert_idx_b)
+ {
+ const float3 &vert_a = verts_[vert_idx_a];
+ const float3 &vert_b = verts_[vert_idx_b];
+ if(vert_a == vert_b) {
+ /* Special case for doubles, so we ensure ordering. */
+ return vert_idx_a > vert_idx_b;
+ }
+ const float x1 = vert_a.x + vert_a.y + vert_a.z;
+ const float x2 = vert_b.x + vert_b.y + vert_b.z;
+ return x1 < x2;
+ }
+
+protected:
+ const array<float3>& verts_;
+};
+
static void attr_create_pointiness(Scene *scene,
Mesh *mesh,
BL::Mesh& b_mesh,
bool subdivision)
{
- if(mesh->need_attribute(scene, ATTR_STD_POINTINESS)) {
- const int numverts = b_mesh.vertices.length();
- AttributeSet& attributes = (subdivision)? mesh->subd_attributes: mesh->attributes;
- Attribute *attr = attributes.add(ATTR_STD_POINTINESS);
- float *data = attr->data_float();
- int *counter = new int[numverts];
- float *raw_data = new float[numverts];
- float3 *edge_accum = new float3[numverts];
-
- /* Calculate pointiness using single ring neighborhood. */
- memset(counter, 0, sizeof(int) * numverts);
- memset(raw_data, 0, sizeof(float) * numverts);
- memset(edge_accum, 0, sizeof(float3) * numverts);
- BL::Mesh::edges_iterator e;
- int i = 0;
- for(b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e, ++i) {
- int v0 = b_mesh.edges[i].vertices()[0],
- v1 = b_mesh.edges[i].vertices()[1];
- float3 co0 = get_float3(b_mesh.vertices[v0].co()),
- co1 = get_float3(b_mesh.vertices[v1].co());
- float3 edge = normalize(co1 - co0);
- edge_accum[v0] += edge;
- edge_accum[v1] += -edge;
- ++counter[v0];
- ++counter[v1];
- }
- i = 0;
- BL::Mesh::vertices_iterator v;
- for(b_mesh.vertices.begin(v); v != b_mesh.vertices.end(); ++v, ++i) {
- if(counter[i] > 0) {
- float3 normal = get_float3(b_mesh.vertices[i].normal());
- float angle = safe_acosf(dot(normal, edge_accum[i] / counter[i]));
- raw_data[i] = angle * M_1_PI_F;
+ if(!mesh->need_attribute(scene, ATTR_STD_POINTINESS)) {
+ return;
+ }
+ const int num_verts = b_mesh.vertices.length();
+ /* STEP 1: Find out duplicated vertices and point duplicates to a single
+ * original vertex.
+ */
+ vector<int> sorted_vert_indeices(num_verts);
+ for(int vert_index = 0; vert_index < num_verts; ++vert_index) {
+ sorted_vert_indeices[vert_index] = vert_index;
+ }
+ VertexAverageComparator compare(mesh->verts);
+ sort(sorted_vert_indeices.begin(), sorted_vert_indeices.end(), compare);
+ /* This array stores index of the original vertex for the given vertex
+ * index.
+ */
+ vector<int> vert_orig_index(num_verts);
+ for(int sorted_vert_index = 0;
+ sorted_vert_index < num_verts;
+ ++sorted_vert_index)
+ {
+ const int vert_index = sorted_vert_indeices[sorted_vert_index];
+ const float3 &vert_co = mesh->verts[vert_index];
+ bool found = false;
+ for(int other_sorted_vert_index = sorted_vert_index + 1;
+ other_sorted_vert_index < num_verts;
+ ++other_sorted_vert_index)
+ {
+ const int other_vert_index =
+ sorted_vert_indeices[other_sorted_vert_index];
+ const float3 &other_vert_co = mesh->verts[other_vert_index];
+ /* We are too far away now, we wouldn't have duplicate. */
+ if ((other_vert_co.x + other_vert_co.y + other_vert_co.z) -
+ (vert_co.x + vert_co.y + vert_co.z) > 3 * FLT_EPSILON)
+ {
+ break;
}
- else {
- raw_data[i] = 0.0f;
+ /* Found duplicate. */
+ if(len_squared(other_vert_co - vert_co) < FLT_EPSILON) {
+ found = true;
+ vert_orig_index[vert_index] = other_vert_index;
+ break;
}
}
-
- /* Blur vertices to approximate 2 ring neighborhood. */
- memset(counter, 0, sizeof(int) * numverts);
- memcpy(data, raw_data, sizeof(float) * numverts);
- i = 0;
- for(b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e, ++i) {
- int v0 = b_mesh.edges[i].vertices()[0],
- v1 = b_mesh.edges[i].vertices()[1];
- data[v0] += raw_data[v1];
- data[v1] += raw_data[v0];
- ++counter[v0];
- ++counter[v1];
+ if(!found) {
+ vert_orig_index[vert_index] = vert_index;
}
- for(i = 0; i < numverts; ++i) {
- data[i] /= counter[i] + 1;
+ }
+ /* Make sure we always points to the very first orig vertex. */
+ for(int vert_index = 0; vert_index < num_verts; ++vert_index) {
+ int orig_index = vert_orig_index[vert_index];
+ while(orig_index != vert_orig_index[orig_index]) {
+ orig_index = vert_orig_index[orig_index];
}
-
- delete [] counter;
- delete [] raw_data;
- delete [] edge_accum;
+ vert_orig_index[vert_index] = orig_index;
+ }
+ sorted_vert_indeices.free_memory();
+ /* STEP 2: Calculate vertex normals taking into account their possible
+ * duplicates which gets "welded" together.
+ */
+ vector<float3> vert_normal(num_verts, make_float3(0.0f, 0.0f, 0.0f));
+ /* First we accumulate all vertex normals in the original index. */
+ for(int vert_index = 0; vert_index < num_verts; ++vert_index) {
+ const float3 normal = get_float3(b_mesh.vertices[vert_index].normal());
+ const int orig_index = vert_orig_index[vert_index];
+ vert_normal[orig_index] += normal;
+ }
+ /* Then we normalize the accumulated result and flush it to all duplicates
+ * as well.
+ */
+ for(int vert_index = 0; vert_index < num_verts; ++vert_index) {
+ const int orig_index = vert_orig_index[vert_index];
+ vert_normal[vert_index] = normalize(vert_normal[orig_index]);
+ }
+ /* STEP 3: Calculate pointiness using single ring neighborhood. */
+ vector<int> counter(num_verts, 0);
+ vector<float> raw_data(num_verts, 0.0f);
+ vector<float3> edge_accum(num_verts, make_float3(0.0f, 0.0f, 0.0f));
+ BL::Mesh::edges_iterator e;
+ EdgeMap visited_edges;
+ int edge_index = 0;
+ memset(&counter[0], 0, sizeof(int) * counter.size());
+ for(b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e, ++edge_index) {
+ const int v0 = vert_orig_index[b_mesh.edges[edge_index].vertices()[0]],
+ v1 = vert_orig_index[b_mesh.edges[edge_index].vertices()[1]];
+ if(visited_edges.exists(v0, v1)) {
+ continue;
+ }
+ visited_edges.insert(v0, v1);
+ float3 co0 = get_float3(b_mesh.vertices[v0].co()),
+ co1 = get_float3(b_mesh.vertices[v1].co());
+ float3 edge = normalize(co1 - co0);
+ edge_accum[v0] += edge;
+ edge_accum[v1] += -edge;
+ ++counter[v0];
+ ++counter[v1];
+ }
+ for(int vert_index = 0; vert_index < num_verts; ++vert_index) {
+ const int orig_index = vert_orig_index[vert_index];
+ if(orig_index != vert_index) {
+ /* Skip duplicates, they'll be overwritten later on. */
+ continue;
+ }
+ if(counter[vert_index] > 0) {
+ const float3 normal = vert_normal[vert_index];
+ const float angle =
+ safe_acosf(dot(normal,
+ edge_accum[vert_index] / counter[vert_index]));
+ raw_data[vert_index] = angle * M_1_PI_F;
+ }
+ else {
+ raw_data[vert_index] = 0.0f;
+ }
+ }
+ /* STEP 3: Blur vertices to approximate 2 ring neighborhood. */
+ AttributeSet& attributes = (subdivision)? mesh->subd_attributes: mesh->attributes;
+ Attribute *attr = attributes.add(ATTR_STD_POINTINESS);
+ float *data = attr->data_float();
+ memcpy(data, &raw_data[0], sizeof(float) * raw_data.size());
+ memset(&counter[0], 0, sizeof(int) * counter.size());
+ edge_index = 0;
+ visited_edges.clear();
+ for(b_mesh.edges.begin(e); e != b_mesh.edges.end(); ++e, ++edge_index) {
+ const int v0 = vert_orig_index[b_mesh.edges[edge_index].vertices()[0]],
+ v1 = vert_orig_index[b_mesh.edges[edge_index].vertices()[1]];
+ if(visited_edges.exists(v0, v1)) {
+ continue;
+ }
+ visited_edges.insert(v0, v1);
+ data[v0] += raw_data[v1];
+ data[v1] += raw_data[v0];
+ ++counter[v0];
+ ++counter[v1];
+ }
+ for(int vert_index = 0; vert_index < num_verts; ++vert_index) {
+ data[vert_index] /= counter[vert_index] + 1;
+ }
+ /* STEP 4: Copy attribute to the duplicated vertices. */
+ for(int vert_index = 0; vert_index < num_verts; ++vert_index) {
+ const int orig_index = vert_orig_index[vert_index];
+ data[vert_index] = data[orig_index];
}
}
diff --git a/intern/cycles/blender/blender_shader.cpp b/intern/cycles/blender/blender_shader.cpp
index f63f94a..78f0cc1 100644
--- a/intern/cycles/blender/blender_shader.cpp
+++ b/intern/cycles/blender/blender_shader.cpp
@@ -609,7 +609,8 @@ static ShaderNode *add_node(Scene *scene,
bool is_builtin = b_image.packed_file() ||
b_image.source() == BL::Image::source_GENERATED ||
b_image.source() == BL::Image::source_MOVIE ||
- b_engine.is_preview();
+ (b_engine.is_preview() &&
+ b_image.source() != BL::Image::source_SEQUENCE);
if(is_builtin) {
/* for builtin images we're using image datablock name to find an image to
@@ -661,7 +662,8 @@ static ShaderNode *add_node(Scene *scene,
bool is_builtin = b_image.packed_file() ||
b_image.source() == BL::Image::source_GENERATED ||
b_image.source() == BL::Image::source_MOVIE ||
- b_engine.is_preview();
+ (b_engine.is_preview() &&
+ b_image.source() != BL::Image::source_SEQUENCE);
if(is_builtin) {
int scene_frame = b_scene.frame_current();
diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h
index b67834c..8120de9 100644
--- a/intern/cycles/blender/blender_util.h
+++ b/intern/cycles/blender/blender_util.h
@@ -19,6 +19,7 @@
#include "mesh.h"
+#include "util_algorithm.h"
#include "util_map.h"
#include "util_path.h"
#include "util_set.h"
@@ -786,6 +787,35 @@ struct ParticleSystemKey {
}
};
+class EdgeMap {
+public:
+ EdgeMap() {
+ }
+
+ void clear() {
+ edges_.clear();
+ }
+
+ void insert(int v0, int v1) {
+ get_sorted_verts(v0, v1);
+ edges_.insert(std::pair<int, int>(v0, v1));
+ }
+
+ bool exists(int v0, int v1) {
+ get_sorted_verts(v0, v1);
+ return edges_.find(std::pair<int, int>(v0, v1)) != edges_.end();
+ }
+
+protected:
+ void get_sorted_verts(int& v0, int& v1) {
+ if(v0 > v1) {
+ swap(v0, v1);
+ }
+ }
+
+ set< std::pair<int, int> > edges_;
+};
+
CCL_NAMESPACE_END
#endif /* __BLENDER_UTIL_H__ */
diff --git a/intern/cycles/bvh/bvh.cpp b/intern/cycles/bvh/bvh.cpp
index 874a424..1fb2f37 100644
--- a/intern/cycles/bvh/bvh.cpp
+++ b/intern/cycles/bvh/bvh.cpp
@@ -81,6 +81,7 @@ void BVH::build(Progress& progress)
pack.prim_type,
pack.prim_index,
pack.prim_object,
+ pack.prim_time,
params,
progress);
BVHNode *root = bvh_build.run();
@@ -256,6 +257,10 @@ void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
pack.leaf_nodes.resize(leaf_nodes_size);
pack.object_node.resize(objects.size());
+ if(params.num_motion_curve_steps > 0 || params.num_motion_triangle_steps > 0) {
+ pack.prim_time.resize(prim_index_size);
+ }
+
int *pack_prim_index = (pack.prim_index.size())? &pack.prim_index[0]: NULL;
int *pack_prim_type = (pack.prim_type.size())? &pack.prim_type[0]: NULL;
int *pack_prim_object = (pack.prim_object.size())? &pack.prim_object[0]: NULL;
@@ -264,6 +269,7 @@ void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
uint *pack_prim_tri_index = (pack.prim_tri_index.size())? &pack.prim_tri_index[0]: NULL;
int4 *pack_nodes = (pack.nodes.size())? &pack.nodes[0]: NULL;
int4 *pack_leaf_nodes = (pack.leaf_nodes.size())? &pack.leaf_nodes[0]: NULL;
+ float2 *pack_prim_time = (pack.prim_time.size())? &pack.prim_time[0]: NULL;
/* merge */
foreach(Object *ob, objects) {
@@ -309,6 +315,7 @@ void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
int *bvh_prim_type = &bvh->pack.prim_type[0];
uint *bvh_prim_visibility = &bvh->pack.prim_visibility[0];
uint *bvh_prim_tri_index = &bvh->pack.prim_tri_index[0];
+ float2 *bvh_prim_time = bvh->pack.prim_time.size()? &bvh->pack.prim_time[0]: NULL;
for(size_t i = 0; i < bvh_prim_index_size; i++) {
if(bvh->pack.prim_type[i] & PRIMITIVE_ALL_CURVE) {
@@ -324,6 +331,9 @@ void BVH::pack_instances(size_t nodes_size, size_t leaf_nodes_size)
pack_prim_type[pack_prim_index_offset] = bvh_prim_type[i];
pack_prim_visibility[pack_prim_index_offset] = bvh_prim_visibility[i];
pack_prim_object[pack_prim_index_offset] = 0; // unused for instances
+ if(bvh_prim_time != NULL) {
+ pack_prim_time[pack_prim_index_offset] = bvh_prim_time[i];
+ }
pack_prim_index_offset++;
}
}
diff --git a/intern/cycles/bvh/bvh.h b/intern/cycles/bvh/bvh.h
index 35f4d30..08f41fc 100644
--- a/intern/cycles/bvh/bvh.h
+++ b/intern/cycles/bvh/bvh.h
@@ -68,6 +68,8 @@ struct PackedBVH {
array<int> prim_index;
/* mapping from BVH primitive index, to the object id of that primitive. */
array<int> prim_object;
+ /* Time range of BVH primitive. */
+ array<float2> prim_time;
/* index of the root node. */
int root_index;
diff --git a/intern/cycles/bvh/bvh_build.cpp b/intern/cycles/bvh/bvh_build.cpp
index a2f8b33..fcbc50f 100644
--- a/intern/cycles/bvh/bvh_build.cpp
+++ b/intern/cycles/bvh/bvh_build.cpp
@@ -93,12 +93,14 @@ BVHBuild::BVHBuild(const vector<Object*>& objects_,
array<int>& prim_type_,
array<int>& prim_index_,
array<int>& prim_object_,
+ array<float2>& prim_time_,
const BVHParams& params_,
Progress& progress_)
: objects(objects_),
prim_type(prim_type_),
prim_index(prim_index_),
prim_object(prim_object_),
+ prim_time(prim_time_),
params(params_),
progress(progress_),
progress_start_time(0.0),
@@ -465,6 +467,9 @@ BVHNode* BVHBuild::run()
}
spatial_free_index = 0;
+ need_prim_time = params.num_motion_curve_steps > 0 ||
+ params.num_motion_triangle_steps > 0;
+
/* init progress updates */
double build_start_time;
build_start_time = progress_start_time = time_dt();
@@ -475,6 +480,12 @@ BVHNode* BVHBuild::run()
prim_type.resize(references.size());
prim_index.resize(references.size());
prim_object.resize(references.size());
+ if(need_prim_time) {
+ prim_time.resize(references.size());
+ }
+ else {
+ prim_time.resize(0);
+ }
/* build recursively */
BVHNode *rootnode;
@@ -849,6 +860,9 @@ BVHNode *BVHBuild::create_object_leaf_nodes(const BVHReference *ref, int start,
prim_type[start] = ref->prim_type();
prim_index[start] = ref->prim_index();
prim_object[start] = ref->prim_object();
+ if(need_prim_time) {
+ prim_time[start] = make_float2(ref->time_from(), ref->time_to());
+ }
uint visibility = objects[ref->prim_object()]->visibility;
BVHNode *leaf_node = new LeafNode(ref->bounds(), visibility, start, start+1);
@@ -896,6 +910,7 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range,
vector<int, LeafStackAllocator> p_type[PRIMITIVE_NUM_TOTAL];
vector<int, LeafStackAllocator> p_index[PRIMITIVE_NUM_TOTAL];
vector<int, LeafStackAllocator> p_object[PRIMITIVE_NUM_TOTAL];
+ vector<float2, LeafStackAllocator> p_time[PRIMITIVE_NUM_TOTAL];
vector<BVHReference, LeafReferenceStackAllocator> p_ref[PRIMITIVE_NUM_TOTAL];
/* TODO(sergey): In theory we should be able to store references. */
@@ -918,6 +933,8 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range,
p_type[type_index].push_back(ref.prim_type());
p_index[type_index].push_back(ref.prim_index());
p_object[type_index].push_back(ref.prim_object());
+ p_time[type_index].push_back(make_float2(ref.time_from(),
+ ref.time_to()));
bounds[type_index].grow(ref.bounds());
visibility[type_index] |= objects[ref.prim_object()]->visibility;
@@ -947,9 +964,13 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range,
vector<int, LeafStackAllocator> local_prim_type,
local_prim_index,
local_prim_object;
+ vector<float2, LeafStackAllocator> local_prim_time;
local_prim_type.resize(num_new_prims);
local_prim_index.resize(num_new_prims);
local_prim_object.resize(num_new_prims);
+ if(need_prim_time) {
+ local_prim_time.resize(num_new_prims);
+ }
for(int i = 0; i < PRIMITIVE_NUM_TOTAL; ++i) {
int num = (int)p_type[i].size();
if(num != 0) {
@@ -962,6 +983,9 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range,
local_prim_type[index] = p_type[i][j];
local_prim_index[index] = p_index[i][j];
local_prim_object[index] = p_object[i][j];
+ if(need_prim_time) {
+ local_prim_time[index] = p_time[i][j];
+ }
if(params.use_unaligned_nodes && !alignment_found) {
alignment_found =
unaligned_heuristic.compute_aligned_space(p_ref[i][j],
@@ -1028,11 +1052,17 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range,
prim_type.reserve(reserve);
prim_index.reserve(reserve);
prim_object.reserve(reserve);
+ if(need_prim_time) {
+ prim_time.reserve(reserve);
+ }
}
prim_type.resize(range_end);
prim_index.resize(range_end);
prim_object.resize(range_end);
+ if(need_prim_time) {
+ prim_time.resize(range_end);
+ }
}
spatial_spin_lock.unlock();
@@ -1041,6 +1071,9 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range,
memcpy(&prim_type[start_index], &local_prim_type[0], new_leaf_data_size);
memcpy(&prim_index[start_index], &local_prim_index[0], new_leaf_data_size);
memcpy(&prim_object[start_index], &local_prim_object[0], new_leaf_data_size);
+ if(need_prim_time) {
+ memcpy(&prim_time[start_index], &local_prim_time[0], sizeof(float2)*num_new_leaf_data);
+ }
}
}
else {
@@ -1053,6 +1086,9 @@ BVHNode* BVHBuild::create_leaf_node(const BVHRange& range,
memcpy(&prim_type[start_index], &local_prim_type[0], new_leaf_data_size);
memcpy(&prim_index[start_index], &local_prim_index[0], new_leaf_data_size);
memcpy(&prim_object[start_index], &local_prim_object[0], new_leaf_data_size);
+ if(need_prim_time) {
+ memcpy(&prim_time[start_index], &local_prim_time[0], sizeof(float2)*num_new_leaf_data);
+ }
}
}
diff --git a/intern/cycles/bvh/bvh_build.h b/intern/cycles/bvh/bvh_build.h
index ee3cde6..430efc3 100644
--- a/intern/cycles/bvh/bvh_build.h
+++ b/intern/cycles/bvh/bvh_build.h
@@ -48,6 +48,7 @@ public:
array<int>& prim_type,
array<int>& prim_index,
array<int>& prim_object,
+ array<float2>& prim_time,
const BVHParams& params,
Progress& progress);
~BVHBuild();
@@ -112,6 +113,9 @@ protected:
array<int>& prim_type;
array<int>& prim_index;
array<int>& prim_object;
+ array<float2>& prim_time;
+
+ bool need_prim_time;
/* Build parameters. */
BVHParams params;
diff --git a/intern/cycles/bvh/bvh_params.h b/intern/cycles/bvh/bvh_params.h
index 65f9da1..7b30950 100644
--- a/intern/cycles/bvh/bvh_params.h
+++ b/intern/cycles/bvh/bvh_params.h
@@ -104,6 +104,7 @@ public:
primitive_mask = PRIMITIVE_ALL;
num_motion_curve_steps = 0;
+ num_motion_triangle_steps = 0;
}
/* SAH costs */
diff --git a/intern/cycles/kernel/geom/geom_curve.h b/intern/cycles/kernel/geom/geom_curve.h
index 9de3354..712b67a 100644
--- a/intern/cycles/kernel/geom/geom_curve.h
+++ b/intern/cycles/kernel/geom/geom_curve.h
@@ -229,6 +229,15 @@ ccl_device_forceinline bool bvh_cardinal_curve_intersect(KernelGlobals *kg, Inte
float3 P, float3 dir, uint visibility, int object, int curveAddr, float time,int type, uint *lcg_state, float difl, float extmax)
#endif
{
+ const bool is_curve_primitive = (type & PRIMITIVE_CURVE);
+
+ if(!is_curve_primitive && kernel_data.bvh.use_bvh_steps) {
+ const float2 prim_time = kernel_tex_fetch(__prim_time, curveAddr);
+ if(time < prim_time.x || time > prim_time.y) {
+ return false;
+ }
+ }
+
int segment = PRIMITIVE_UNPACK_SEGMENT(type);
float epsilon = 0.0f;
float r_st, r_en;
@@ -257,7 +266,7 @@ ccl_device_forceinline bool bvh_cardinal_curve_intersect(KernelGlobals *kg, Inte
#ifdef __KERNEL_AVX2__
avxf P_curve_0_1, P_curve_2_3;
- if(type & PRIMITIVE_CURVE) {
+ if(is_curve_primitive) {
P_curve_0_1 = _mm256_loadu2_m128(&kg->__curve_keys.data[k0].x, &kg->__curve_keys.data[ka].x);
P_curve_2_3 = _mm256_loadu2_m128(&kg->__curve_keys.data[kb].x, &kg->__curve_keys.data[k1].x);
}
@@ -268,7 +277,7 @@ ccl_device_forceinline bool bvh_cardinal_curve_intersect(KernelGlobals *kg, Inte
#else /* __KERNEL_AVX2__ */
ssef P_curve[4];
- if(type & PRIMITIVE_CURVE) {
+ if(is_curve_primitive) {
P_curve[0] = load4f(&kg->__curve_keys.data[ka].x);
P_curve[1] = load4f(&kg->__curve_keys.data[k0].x);
P_curve[2] = load4f(&kg->__curve_keys.data[k1].x);
@@ -363,7 +372,7 @@ ccl_device_forceinline bool bvh_cardinal_curve_intersect(KernelGlobals *kg, Inte
float4 P_curve[4];
- if(type & PRIMITIVE_CURVE) {
+ if(is_curve_primitive) {
P_curve[0] = kernel_tex_fetch(__curve_keys, ka);
P_curve[1] = kernel_tex_fetch(__curve_keys, k0);
P_curve[2] = kernel_tex_fetch(__curve_keys, k1);
@@ -689,6 +698,15 @@ ccl_device_forceinline bool bvh_curve_intersect(KernelGlobals *kg, Intersection
# define dot3(x, y) dot(x, y)
#endif
+ const bool is_curve_primitive = (type & PRIMITIVE_CURVE);
+
+ if(!is_curve_primitive && kernel_data.bvh.use_bvh_steps) {
+ const float2 prim_time = kernel_tex_fetch(__prim_time, curveAddr);
+ if(time < prim_time.x || time > prim_time.y) {
+ return false;
+ }
+ }
+
int segment = PRIMITIVE_UNPACK_SEGMENT(type);
/* curve Intersection check */
int flags = kernel_data.curve.curveflags;
@@ -703,7 +721,7 @@ ccl_device_forceinline bool bvh_curve_intersect(KernelGlobals *kg, Intersection
#ifndef __KERNEL_SSE2__
float4 P_curve[2];
- if(type & PRIMITIVE_CURVE) {
+ if(is_curve_primitive) {
P_curve[0] = kernel_tex_fetch(__curve_keys, k0);
P_curve[1] = kernel_tex_fetch(__curve_keys, k1);
}
@@ -738,7 +756,7 @@ ccl_device_forceinline bool bvh_curve_intersect(KernelGlobals *kg, Intersection
#else
ssef P_curve[2];
- if(type & PRIMITIVE_CURVE) {
+ if(is_curve_primitive) {
P_curve[0] = load4f(&kg->__curve_keys.data[k0].x);
P_curve[1] = load4f(&kg->__curve_keys.data[k1].x);
}
diff --git a/intern/cycles/kernel/kernel_textures.h b/intern/cycles/kernel/kernel_textures.h
index 8d5bb75..cb1a3f4 100644
--- a/intern/cycles/kernel/kernel_textures.h
+++ b/intern/cycles/kernel/kernel_textures.h
@@ -32,6 +32,7 @@ KERNEL_TEX(uint, texture_uint, __prim_visibility)
KERNEL_TEX(uint, texture_uint, __prim_index)
KERNEL_TEX(uint, texture_uint, __prim_object)
KERNEL_TEX(uint, texture_uint, __object_node)
+KERNEL_TEX(float2, texture_float2, __prim_time)
/* objects */
KERNEL_TEX(float4, texture_float4, __objects)
@@ -177,7 +178,6 @@ KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_byte4_085)
KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_byte4_086)
KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_byte4_087)
KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_byte4_088)
-KERNEL_IMAGE_TEX(uchar4, texture_image_uchar4, __tex_image_byte4_089)
# else
/* bindless textures */
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index 358db9e..c2f63f3 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -1144,7 +1144,8 @@ typedef struct KernelBVH {
int have_curves;
int have_instancing;
int use_qbvh;
- int pad1, pad2;
+ int use_bvh_steps;
+ int pad1;
} KernelBVH;
static_assert_align(KernelBVH, 16);
diff --git a/intern/cycles/kernel/svm/svm_image.h b/intern/cycles/kernel/svm/svm_image.h
index 2afdf61..0d6efb4 100644
--- a/intern/cycles/kernel/svm/svm_image.h
+++ b/intern/cycles/kernel/svm/svm_image.h
@@ -144,7 +144,6 @@ ccl_device float4 svm_image_texture(KernelGlobals *kg, int id, float x, float y,
case 86: r = kernel_tex_image_interp(__tex_image_byte4_086, x, y); break;
case 87: r = kernel_tex_image_interp(__tex_image_byte4_087, x, y); break;
case 88: r = kernel_tex_image_interp(__tex_image_byte4_088, x, y); break;
- case 89: r = kernel_tex_image_interp(__tex_image_byte4_089, x, y); break;
default:
kernel_assert(0);
return make_float4(0.0f, 0.0f, 0.0f, 0.0f);
diff --git a/intern/cycles/render/bake.h b/intern/cycles/render/bake.h
index 25f5eb3..aed9c5a 100644
--- a/intern/cycles/render/bake.h
+++ b/intern/cycles/render/bake.h
@@ -73,7 +73,7 @@ public:
bool need_update;
- int total_pixel_samples;
+ size_t total_pixel_samples;
private:
BakeData *m_bake_data;
diff --git a/intern/cycles/render/mesh.cpp b/intern/cycles/render/mesh.cpp
index c42b329..b766029 100644
--- a/intern/cycles/render/mesh.cpp
+++ b/intern/cycles/render/mesh.cpp
@@ -1873,9 +1873,14 @@ void MeshManager::device_update_bvh(Device *device, DeviceScene *dscene, Scene *
dscene->prim_object.reference((uint*)&pack.prim_object[0], pack.prim_object.size());
device->tex_alloc("__prim_object", dscene->prim_object);
}
+ if(pack.prim_time.size()) {
+ dscene->prim_time.reference((float2*)&pack.prim_time[0], pack.prim_time.size());
+ device->tex_alloc("__prim_time", dscene->prim_time);
+ }
dscene->data.bvh.root = pack.root_index;
dscene->data.bvh.use_qbvh = scene->params.use_qbvh;
+ dscene->data.bvh.use_bvh_steps = (scene->params.num_bvh_time_steps != 0);
}
void MeshManager::device_update_flags(Device * /*device*/,
@@ -2152,6 +2157,7 @@ void MeshManager::device_free(Device *device, DeviceScene *dscene)
device->tex_free(dscene->prim_visibility);
device->tex_free(dscene->prim_index);
device->tex_free(dscene->prim_object);
+ device->tex_free(dscene->prim_time);
device->tex_free(dscene->tri_shader);
device->tex_free(dscene->tri_vnormal);
device->tex_free(dscene->tri_vindex);
@@ -2173,6 +2179,7 @@ void MeshManager::device_free(Device *device, DeviceScene *dscene)
dscene->prim_visibility.clear();
dscene->prim_index.clear();
dscene->prim_object.clear();
+ dscene->prim_time.clear();
dscene->tri_shader.clear();
dscene->tri_vnormal.clear();
dscene->tri_vindex.clear();
diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h
index 8768682..9f398c4 100644
--- a/intern/cycles/render/scene.h
+++ b/intern/cycles/render/scene.h
@@ -69,6 +69,7 @@ public:
device_vector<uint> prim_visibility;
device_vector<uint> prim_index;
device_vector<uint> prim_object;
+ device_vector<float2> prim_time;
/* mesh */
device_vector<uint> tri_shader;
diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp
index 7c01934..420866c 100644
--- a/intern/cycles/render/session.cpp
+++ b/intern/cycles/render/session.cpp
@@ -230,7 +230,9 @@ void Session::run_gpu()
while(1) {
scoped_timer pause_timer;
pause_cond.wait(pause_lock);
- progress.add_skip_time(pause_timer, params.background);
+ if(pause) {
+ progress.add_skip_time(pause_timer, params.background);
+ }
update_status_time(pause, no_tiles);
progress.set_update();
@@ -520,7 +522,9 @@ void Session::run_cpu()
while(1) {
scoped_timer pause_timer;
pause_cond.wait(pause_lock);
- progress.add_skip_time(pause_timer, params.background);
+ if(pause) {
+ progress.add_skip_time(pause_timer, params.background);
+ }
update_status_time(pause, no_tiles);
progress.set_update();
diff --git a/intern/cycles/test/CMakeLists.txt b/intern/cycles/test/CMakeLists.txt
index 9af777f..80564c3 100644
--- a/intern/cycles/test/CMakeLists.txt
+++ b/intern/cycles/test/CMakeLists.txt
@@ -54,12 +54,23 @@ if(WITH_CYCLES_OPENSUBDIV)
endif()
list(APPEND ALL_CYCLES_LIBRARIES
${BOOST_LIBRARIES}
+ ${PNG_LIBRARIES}
+ ${JPEG_LIBRARIES}
+ ${ZLIB_LIBRARIES}
+ ${TIFF_LIBRARY}
+ ${OPENIMAGEIO_LIBRARIES}
+ ${OPENEXR_LIBRARIES}
)
include_directories(${INC})
-link_directories(${BOOST_LIBPATH})
-link_directories(${OPENIMAGEIO_LIBPATH})
+link_directories(${OPENIMAGEIO_LIBPATH}
+ ${BOOST_LIBPATH}
+ ${PNG_LIBPATH}
+ ${JPEG_LIBPATH}
+ ${ZLIB_LIBPATH}
+ ${TIFF_LIBPATH}
+ ${OPENEXR_LIBPATH})
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${PLATFORM_LINKFLAGS}")
set(CMAKE_EXE_LINKER_FLAGS_DEBUG "${CMAKE_EXE_LINKER_FLAGS_DEBUG} ${PLATFORM_LINKFLAGS_DEBUG}")
diff --git a/intern/cycles/util/util_half.h b/intern/cycles/util/util_half.h
index 5db3384..c1a47d5 100644
--- a/intern/cycles/util/util_half.h
+++ b/intern/cycles/util/util_half.h
@@ -18,6 +18,7 @@
#define __UTIL_HALF_H__
#include "util_types.h"
+#include "util_math.h"
#ifdef __KERNEL_SSE2__
#include "util_simd.h"
@@ -110,6 +111,28 @@ ccl_device_inline float4 half4_to_float4(half4 h)
return f;
}
+ccl_device_inline half float_to_half(float f)
+{
+ const uint u = __float_as_uint(f);
+ /* Sign bit, shifted to it's position. */
+ uint sign_bit = u & 0x80000000;
+ sign_bit >>= 16;
+ /* Exponent. */
+ uint exponent_bits = u & 0x7f800000;
+ /* Non-sign bits. */
+ uint value_bits = u & 0x7fffffff;
+ value_bits >>= 13; /* Align mantissa on MSB. */
+ value_bits -= 0x1c000; /* Adjust bias. */
+ /* Flush-to-zero. */
+ value_bits = (exponent_bits < 0x38800000) ? 0 : value_bits;
+ /* Clamp-to-max. */
+ value_bits = (exponent_bits > 0x47000000) ? 0x7bff : value_bits;
+ /* Denormals-as-zero. */
+ value_bits = (exponent_bits == 0 ? 0 : value_bits);
+ /* Re-insert sign bit and return. */
+ return (value_bits | sign_bit);
+}
+
#endif
#endif
diff --git a/intern/cycles/util/util_image_impl.h b/intern/cycles/util/util_image_impl.h
index 73ecfda..4daf1ea 100644
--- a/intern/cycles/util/util_image_impl.h
+++ b/intern/cycles/util/util_image_impl.h
@@ -19,6 +19,7 @@
#include "util_algorithm.h"
#include "util_debug.h"
+#include "util_half.h"
#include "util_image.h"
CCL_NAMESPACE_BEGIN
@@ -38,6 +39,52 @@ const T *util_image_read(const vector<T>& pixels,
return &pixels[index];
}
+/* Cast input pixel from unknown storage to float. */
+template<typename T>
+inline float cast_to_float(T value);
+
+template<>
+inline float cast_to_float(float value)
+{
+ return value;
+}
+template<>
+inline float cast_to_float(uchar value)
+{
+ return (float)value / 255.0f;
+}
+template<>
+inline float cast_to_float(half value)
+{
+ return half_to_float(value);
+}
+
+/* Cast float value to output pixel type. */
+template<typename T>
+inline T cast_from_float(float value);
+
+template<>
+inline float cast_from_float(float value)
+{
+ return value;
+}
+template<>
+inline uchar cast_from_float(float value)
+{
+ if(value < 0.0f) {
+ return 0;
+ }
+ else if(value > (1.0f - 0.5f / 255.0f)) {
+ return 255;
+ }
+ return (uchar)((255.0f * value) + 0.5f);
+}
+template<>
+inline half cast_from_float(float value)
+{
+ return float_to_half(value);
+}
+
template<typename T>
void util_image_downscale_sample(const vector<T>& pixels,
const size_t width,
@@ -71,15 +118,22 @@ void util_image_downscale_sample(const vector<T>& pixels,
components,
nx, ny, nz);
for(size_t k = 0; k < components; ++k) {
- accum[k] += pixel[k];
+ accum[k] += cast_to_float(pixel[k]);
}
++count;
}
}
}
- const float inv_count = 1.0f / (float)count;
- for(size_t k = 0; k < components; ++k) {
- result[k] = T(accum[k] * inv_count);
+ if(count != 0) {
+ const float inv_count = 1.0f / (float)count;
+ for(size_t k = 0; k < components; ++k) {
+ result[k] = cast_from_float<T>(accum[k] * inv_count);
+ }
+ }
+ else {
+ for(size_t k = 0; k < components; ++k) {
+ result[k] = T(0.0f);
+ }
}
}
diff --git a/intern/cycles/util/util_static_assert.h b/intern/cycles/util/util_static_assert.h
index 033d85e..e900492 100644
--- a/intern/cycles/util/util_static_assert.h
+++ b/intern/cycles/util/util_static_assert.h
@@ -43,7 +43,9 @@ template <> class StaticAssertFailure<true> {};
# endif /* __COUNTER__ */
# endif /* C++11 or MSVC2015 */
#else /* __KERNEL_GPU__ */
-# define static_assert(statement, message)
+# ifndef static_assert
+# define static_assert(statement, message)
+# endif
#endif /* __KERNEL_GPU__ */
/* TODO(sergey): For until C++11 is a bare minimum for us,
diff --git a/intern/libmv/libmv/multiview/panography_test.cc b/intern/libmv/libmv/multiview/panography_test.cc
index f6faf0f..96d52ac 100644
--- a/intern/libmv/libmv/multiview/panography_test.cc
+++ b/intern/libmv/libmv/multiview/panography_test.cc
@@ -48,7 +48,7 @@ TEST(Panography, PrintSomeSharedFocalEstimationValues) {
// Assert we found a valid solution.
EXPECT_EQ(1, fs.size());
- EXPECT_NEAR(1.01667, fs[1], 1e-3);
+ EXPECT_NEAR(3.47194, fs[0], 1e-3);
}
TEST(Panography, GetR_FixedCameraCenterWithIdentity) {
diff --git a/make.bat b/make.bat
index 11c1ff0..8d72ec0 100644
--- a/make.bat
+++ b/make.bat
@@ -17,7 +17,7 @@ set MUST_CLEAN=
set NOBUILD=
set TARGET=
set WINDOWS_ARCH=
-
+set TESTS_CMAKE_ARGS=
:argv_loop
if NOT "%1" == "" (
@@ -30,6 +30,8 @@ if NOT "%1" == "" (
if "%1" == "debug" (
set BUILD_TYPE=Debug
REM Build Configurations
+ ) else if "%1" == "with_tests" (
+ set TESTS_CMAKE_ARGS=-DWITH_GTESTS=On
) else if "%1" == "full" (
set TARGET=Full
set BUILD_CMAKE_ARGS=%BUILD_CMAKE_ARGS% ^
@@ -183,7 +185,7 @@ if "%TARGET%"=="" (
goto HELP
)
-set BUILD_CMAKE_ARGS=%BUILD_CMAKE_ARGS% -G "Visual Studio %BUILD_VS_VER% %BUILD_VS_YEAR%%WINDOWS_ARCH%"
+set BUILD_CMAKE_ARGS=%BUILD_CMAKE_ARGS% -G "Visual Studio %BUILD_VS_VER% %BUILD_VS_YEAR%%WINDOWS_ARCH%" %TESTS_CMAKE_ARGS%
if NOT EXIST %BUILD_DIR%\nul (
mkdir %BUILD_DIR%
)
@@ -262,6 +264,7 @@ goto EOF
echo - showhash ^(Show git hashes of source tree^)
echo.
echo Configuration options
+ echo - with_tests ^(enable building unit tests^)
echo - debug ^(Build an unoptimized debuggable build^)
echo - packagename [newname] ^(override default cpack package name^)
echo - x86 ^(override host autodetect and build 32 bit code^)
diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h
index 6dad0d7..63ac07a 100644
--- a/source/blender/blenkernel/BKE_blender_version.h
+++ b/source/blender/blenkernel/BKE_blender_version.h
@@ -35,7 +35,7 @@
/* used by packaging tools */
/* can be left blank, otherwise a,b,c... etc with no quotes */
-#define BLENDER_VERSION_CHAR b
+#define BLENDER_VERSION_CHAR c
/* alpha/beta/rc/release, docs use this */
#define BLENDER_VERSION_CYCLE release
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 8a9cb73..0ffcaff 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -3178,7 +3178,7 @@ static ImBuf *load_sequence_single(Image *ima, ImageUser *iuser, int frame, cons
struct ImBuf *ibuf;
char name[FILE_MAX];
int flag;
- ImageUser iuser_t;
+ ImageUser iuser_t = {0};
/* XXX temp stuff? */
if (ima->lastframe != frame)
@@ -3186,8 +3186,12 @@ static ImBuf *load_sequence_single(Image *ima, ImageUser *iuser, int frame, cons
ima->lastframe = frame;
- if (iuser)
+ if (iuser) {
iuser_t = *iuser;
+ }
+ else {
+ /* TODO(sergey): Do we need to initialize something here? */
+ }
iuser_t.view = view_id;
BKE_image_user_file_path(&iuser_t, ima, name);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc
index 6b51a95..a0e9e47 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc
@@ -82,7 +82,7 @@ void DepsgraphRelationBuilder::build_scene(Main *bmain, Scene *scene)
} FOREACH_NODETREE_END
if (scene->set) {
- // TODO: link set to scene, especially our timesource...
+ build_scene(bmain, scene->set);
}
/* scene objects */
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index 549c979..0f3ffa8 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -2822,7 +2822,7 @@ void node_tex_checker(vec3 co, vec4 color1, vec4 color2, float scale, out vec4 c
}
#ifdef BIT_OPERATIONS
-vec2 calc_brick_texture(vec3 p, float mortar_size, float bias,
+vec2 calc_brick_texture(vec3 p, float mortar_size, float mortar_smooth, float bias,
float brick_width, float row_height,
float offset_amount, int offset_frequency,
float squash_amount, int squash_frequency)
@@ -2843,17 +2843,26 @@ vec2 calc_brick_texture(vec3 p, float mortar_size, float bias,
x = (p.x + offset) - brick_width * bricknum;
y = p.y - row_height * rownum;
- return vec2(clamp((integer_noise((rownum << 16) + (bricknum & 0xFFFF)) + bias), 0.0, 1.0),
- (x < mortar_size || y < mortar_size ||
- x > (brick_width - mortar_size) ||
- y > (row_height - mortar_size)) ? 1.0 : 0.0);
+ float tint = clamp((integer_noise((rownum << 16) + (bricknum & 0xFFFF)) + bias), 0.0, 1.0);
+
+ float min_dist = min(min(x, y), min(brick_width - x, row_height - y));
+ if(min_dist >= mortar_size) {
+ return vec2(tint, 0.0);
+ }
+ else if(mortar_smooth == 0.0) {
+ return vec2(tint, 1.0);
+ }
+ else {
+ min_dist = 1.0 - min_dist/mortar_size;
+ return vec2(tint, smoothstep(0.0, mortar_smooth, min_dist));
+ }
}
#endif
void node_tex_brick(vec3 co,
vec4 color1, vec4 color2,
vec4 mortar, float scale,
- float mortar_size, float bias,
+ float mortar_size, float mortar_smooth, float bias,
float brick_width, float row_height,
float offset_amount, float offset_frequency,
float squash_amount, float squash_frequency,
@@ -2861,7 +2870,7 @@ void node_tex_brick(vec3 co,
{
#ifdef BIT_OPERATIONS
vec2 f2 = calc_brick_texture(co * scale,
- mortar_size, bias,
+ mortar_size, mortar_smooth, bias,
brick_width, row_height,
offset_amount, int(offset_frequency),
squash_amount, int(squash_frequency));
@@ -2871,7 +2880,7 @@ void node_tex_brick(vec3 co,
float facm = 1.0 - tint;
color1 = facm * color1 + tint * color2;
}
- color = (f == 1.0) ? mortar : color1;
+ color = mix(color1, mortar, f);
fac = f;
#else
color = vec4(1.0);
@@ -3527,6 +3536,8 @@ void node_light_path(
out float is_transmission_ray,
out float ray_length,
out float ray_depth,
+ out float diffuse_depth,
+ out float glossy_depth,
out float transparent_depth,
out float transmission_depth)
{
@@ -3539,6 +3550,8 @@ void node_light_path(
is_transmission_ray = 0.0;
ray_length = 1.0;
ray_depth = 1.0;
+ diffuse_depth = 1.0;
+ glossy_depth = 1.0;
transparent_depth = 1.0;
transmission_depth = 1.0;
}
diff --git a/source/creator/creator_args.c b/source/creator/creator_args.c
index c3c76a0..4707931 100644
--- a/source/creator/creator_args.c
+++ b/source/creator/creator_args.c
@@ -1355,7 +1355,7 @@ static int arg_handle_render_frame(int argc, const char **argv, void *data)
re = RE_NewRender(scene->id.name);
BLI_begin_threaded_malloc();
- BKE_reports_init(&reports, RPT_PRINT);
+ BKE_reports_init(&reports, RPT_STORE);
RE_SetReports(re, &reports);
for (int i = 0; i < frames_range_len; i++) {
@@ -1370,6 +1370,7 @@ static int arg_handle_render_frame(int argc, const char **argv, void *data)
}
}
RE_SetReports(re, NULL);
+ BKE_reports_clear(&reports);
BLI_end_threaded_malloc();
MEM_freeN(frame_range_arr);
return 1;
@@ -1397,10 +1398,11 @@ static int arg_handle_render_animation(int UNUSED(argc), const char **UNUSED(arg
Render *re = RE_NewRender(scene->id.name);
ReportList reports;
BLI_begin_threaded_malloc();
- BKE_reports_init(&reports, RPT_PRINT);
+ BKE_reports_init(&reports, RPT_STORE);
RE_SetReports(re, &reports);
RE_BlenderAnim(re, bmain, scene, NULL, scene->lay, scene->r.sfra, scene->r.efra, scene->r.frame_step);
RE_SetReports(re, NULL);
+ BKE_reports_clear(&reports);
BLI_end_threaded_malloc();
}
else {
diff --git a/tests/gtests/CMakeLists.txt b/tests/gtests/CMakeLists.txt
index a3860ce..1d363f3 100644
--- a/tests/gtests/CMakeLists.txt
+++ b/tests/gtests/CMakeLists.txt
@@ -4,6 +4,9 @@ if(WITH_GTESTS)
Include(GTestTesting)
+ add_definitions(${GFLAGS_DEFINES})
+ add_definitions(${GLOG_DEFINES})
+
# Otherwise we get warnings here that we cant fix in external projects
remove_strict_flags()
diff --git a/tests/gtests/blenlib/BLI_string_test.cc b/tests/gtests/blenlib/BLI_string_test.cc
index 17a4b5e..08f2a74 100644
--- a/tests/gtests/blenlib/BLI_string_test.cc
+++ b/tests/gtests/blenlib/BLI_string_test.cc
@@ -374,7 +374,7 @@ TEST(string, StrFormatIntGrouped)
const int word_num = BLI_string_find_split_words( \
word_str_src, word_str_src_len, ' ', word_info, word_cmp_size_input); \
EXPECT_EQ(word_num, word_cmp_size - 1); \
- EXPECT_EQ_ARRAY_ND(word_cmp, word_info, word_cmp_size, 2); \
+ EXPECT_EQ_ARRAY_ND<const int[2]>(word_cmp, word_info, word_cmp_size, 2); \
} ((void)0)
#define STRING_FIND_SPLIT_WORDS(word_str_src, ...) \
diff --git a/tests/gtests/testing/CMakeLists.txt b/tests/gtests/testing/CMakeLists.txt
index 1eb60e7..796f975 100644
--- a/tests/gtests/testing/CMakeLists.txt
+++ b/tests/gtests/testing/CMakeLists.txt
@@ -47,7 +47,4 @@ set(SRC
testing.h
)
-add_definitions(${GFLAGS_DEFINES})
-add_definitions(${GLOG_DEFINES})
-
blender_add_lib(bf_testing_main "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/tests/python/CMakeLists.txt b/tests/python/CMakeLists.txt
index 8487c6a..d9731a5 100644
--- a/tests/python/CMakeLists.txt
+++ b/tests/python/CMakeLists.txt
@@ -95,6 +95,11 @@ add_test(bevel ${TEST_BLENDER_EXE}
--python-text run_tests
)
+add_test(split_faces ${TEST_BLENDER_EXE}
+ ${TEST_SRC_DIR}/modeling/split_faces_test.blend
+ --python-text run_tests
+)
+
# ------------------------------------------------------------------------------
# IO TESTS
@@ -399,24 +404,33 @@ endif()
if(WITH_CYCLES)
if(OPENIMAGEIO_IDIFF AND EXISTS "${TEST_SRC_DIR}/cycles/ctests/shader")
- add_test(cycles_reports_test
- ${CMAKE_CURRENT_LIST_DIR}/cycles_render_tests.py
- -blender "${TEST_BLENDER_EXE_BARE}"
- -testdir "${TEST_SRC_DIR}/cycles/ctests/reports"
- -idiff "${OPENIMAGEIO_IDIFF}"
- )
- add_test(cycles_render_test
- ${CMAKE_CURRENT_LIST_DIR}/cycles_render_tests.py
- -blender "${TEST_BLENDER_EXE_BARE}"
- -testdir "${TEST_SRC_DIR}/cycles/ctests/render"
- -idiff "${OPENIMAGEIO_IDIFF}"
- )
- add_test(cycles_shaders_test
- ${CMAKE_CURRENT_LIST_DIR}/cycles_render_tests.py
- -blender "${TEST_BLENDER_EXE_BARE}"
- -testdir "${TEST_SRC_DIR}/cycles/ctests/shader"
- -idiff "${OPENIMAGEIO_IDIFF}"
- )
+ macro(add_cycles_render_test subject)
+ if(MSVC)
+ add_test(NAME cycles_${subject}_test
+ COMMAND
+ "$<TARGET_FILE_DIR:blender>/${BLENDER_VERSION_MAJOR}.${BLENDER_VERSION_MINOR}/python/bin/python$<$<CONFIG:Debug>:_d>"
+ ${CMAKE_CURRENT_LIST_DIR}/cycles_render_tests.py
+ -blender "$<TARGET_FILE:blender>"
+ -testdir "${TEST_SRC_DIR}/cycles/ctests/${subject}"
+ -idiff "${OPENIMAGEIO_IDIFF}"
+ )
+ else()
+ add_test(cycles_${subject}_test
+ ${CMAKE_CURRENT_LIST_DIR}/cycles_render_tests.py
+ -blender "${TEST_BLENDER_EXE_BARE}"
+ -testdir "${TEST_SRC_DIR}/cycles/ctests/${subject}"
+ -idiff "${OPENIMAGEIO_IDIFF}"
+ )
+ endif()
+ endmacro()
+ if(WITH_OPENGL_TESTS)
+ add_cycles_render_test(opengl)
+ endif()
+ add_cycles_render_test(image)
+ add_cycles_render_test(mblur)
+ add_cycles_render_test(reports)
+ add_cycles_render_test(render)
+ add_cycles_render_test(shader)
else()
MESSAGE(STATUS "Disabling Cycles tests because tests folder does not exist")
endif()
diff --git a/tests/python/cycles_render_tests.py b/tests/python/cycles_render_tests.py
index fa4b3f2..a030cc5 100755
--- a/tests/python/cycles_render_tests.py
+++ b/tests/python/cycles_render_tests.py
@@ -6,24 +6,82 @@ import os
import shutil
import subprocess
import sys
+import time
import tempfile
+class COLORS_ANSI:
+ RED = '\033[00;31m'
+ GREEN = '\033[00;32m'
+ ENDC = '\033[0m'
+
+
+class COLORS_DUMMY:
+ RED = ''
+ GREEN = ''
+ ENDC = ''
+
+COLORS = COLORS_DUMMY
+
+
+def printMessage(type, status, message):
+ if type == 'SUCCESS':
+ print(COLORS.GREEN, end="")
+ elif type == 'FAILURE':
+ print(COLORS.RED, end="")
+ status_text = ...
+ if status == 'RUN':
+ status_text = " RUN "
+ elif status == 'OK':
+ status_text = " OK "
+ elif status == 'PASSED':
+ status_text = " PASSED "
+ elif status == 'FAILED':
+ status_text = " FAILED "
+ else:
+ status_text = status
+ print("[{}]" . format(status_text), end="")
+ print(COLORS.ENDC, end="")
+ print(" {}" . format(message))
+ sys.stdout.flush()
+
+
def render_file(filepath):
- command = (
- BLENDER,
- "--background",
- "-noaudio",
- "--factory-startup",
- "--enable-autoexec",
- filepath,
- "-E", "CYCLES",
- # Run with OSL enabled
- # "--python-expr", "import bpy; bpy.context.scene.cycles.shading_system = True",
- "-o", TEMP_FILE_MASK,
- "-F", "PNG",
- "-f", "1",
+ dirname = os.path.dirname(filepath)
+ basedir = os.path.dirname(dirname)
+ subject = os.path.basename(dirname)
+ if subject == 'opengl':
+ command = (
+ BLENDER,
+ "--window-geometry", "0", "0", "1", "1",
+ "-noaudio",
+ "--factory-startup",
+ "--enable-autoexec",
+ filepath,
+ "-E", "CYCLES",
+ # Run with OSL enabled
+ # "--python-expr", "import bpy; bpy.context.scene.cycles.shading_system = True",
+ "-o", TEMP_FILE_MASK,
+ "-F", "PNG",
+ '--python', os.path.join(basedir,
+ "util",
+ "render_opengl.py")
)
+ else:
+ command = (
+ BLENDER,
+ "--background",
+ "-noaudio",
+ "--factory-startup",
+ "--enable-autoexec",
+ filepath,
+ "-E", "CYCLES",
+ # Run with OSL enabled
+ # "--python-expr", "import bpy; bpy.context.scene.cycles.shading_system = True",
+ "-o", TEMP_FILE_MASK,
+ "-F", "PNG",
+ "-f", "1",
+ )
try:
output = subprocess.check_output(command)
if VERBOSE:
@@ -84,16 +142,32 @@ def verify_output(filepath):
def run_test(filepath):
testname = test_get_name(filepath)
spacer = "." * (32 - len(testname))
- print(testname, spacer, end="")
- sys.stdout.flush()
+ printMessage('SUCCESS', 'RUN', testname)
+ time_start = time.time()
error = render_file(filepath)
+ status = "FAIL"
if not error:
- if verify_output(filepath):
- print("PASS")
- else:
+ if not verify_output(filepath):
error = "VERIFY"
- if error:
- print("FAIL", error)
+ time_end = time.time()
+ elapsed_ms = int((time_end - time_start) * 1000)
+ if not error:
+ printMessage('SUCCESS', 'OK', "{} ({} ms)" .
+ format(testname, elapsed_ms))
+ else:
+ if error == "NO_CYCLES":
+ print("Can't perform tests because Cycles failed to load!")
+ return False
+ elif error == "NO_START":
+ print('Can not perform tests because blender fails to start.',
+ 'Make sure INSTALL target was run.')
+ return False
+ elif error == 'VERIFY':
+ print("Rendered result is different from reference image")
+ else:
+ print("Unknown error %r" % error)
+ printMessage('FAILURE', 'FAILED', "{} ({} ms)" .
+ format(testname, elapsed_ms))
return error
@@ -106,30 +180,38 @@ def blend_list(path):
def run_all_tests(dirpath):
+ passed_tests = []
failed_tests = []
all_files = list(blend_list(dirpath))
all_files.sort()
+ printMessage('SUCCESS', "==========",
+ "Running {} tests from 1 test case." . format(len(all_files)))
+ time_start = time.time()
for filepath in all_files:
error = run_test(filepath)
+ testname = test_get_name(filepath)
if error:
if error == "NO_CYCLES":
- print("Can't perform tests because Cycles failed to load!")
return False
elif error == "NO_START":
- print('Can not perform tests because blender fails to start.',
- 'Make sure INSTALL target was run.')
return False
- elif error == 'VERIFY':
- pass
- else:
- print("Unknown error %r" % error)
- testname = test_get_name(filepath)
failed_tests.append(testname)
+ else:
+ passed_tests.append(testname)
+ time_end = time.time()
+ elapsed_ms = int((time_end - time_start) * 1000)
+ print("")
+ printMessage('SUCCESS', "==========",
+ "{} tests from 1 test case ran. ({} ms total)" .
+ format(len(all_files), elapsed_ms))
+ printMessage('SUCCESS', 'PASSED', "{} tests." .
+ format(len(passed_tests)))
if failed_tests:
+ printMessage('FAILURE', 'FAILED', "{} tests, listed below:" .
+ format(len(failed_tests)))
failed_tests.sort()
- print("\n\nFAILED tests:")
for test in failed_tests:
- print(" ", test)
+ printMessage('FAILURE', "FAILED", "{}" . format(test))
return False
return True
@@ -146,10 +228,14 @@ def main():
parser = create_argparse()
args = parser.parse_args()
+ global COLORS
global BLENDER, ROOT, IDIFF
global TEMP_FILE, TEMP_FILE_MASK, TEST_SCRIPT
global VERBOSE
+ if os.environ.get("CYCLESTEST_COLOR") is not None:
+ COLORS = COLORS_ANSI
+
BLENDER = args.blender[0]
ROOT = args.testdir[0]
IDIFF = args.idiff[0]
--
blender packaging
More information about the pkg-multimedia-commits
mailing list