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:
authorLukas Stockner <lukas.stockner@freenet.de>2016-12-03 00:14:52 +0300
committerLukas Stockner <lukas.stockner@freenet.de>2016-12-03 00:14:52 +0300
commit8c8b81dfdb3c0529be4cf4a16a3310e6ec26db0a (patch)
tree6f2572b1c4bc9cd521d4919415d7a7fd4d467f75
parentbe47582c46f831e5c5f34899185a70c3d8ff78ab (diff)
parent35d490b3f13c75e9a62cb30f3842ed38a27f6dbc (diff)
Merge remote-tracking branch 'origin/master' into soc-2016-cycles_denoising
-rwxr-xr-xbuild_files/build_environment/install_deps.sh10
-rw-r--r--build_files/buildbot/master.cfg4
-rw-r--r--build_files/cmake/platform/platform_win32_msvc.cmake2
-rw-r--r--extern/Eigen3/Eigen/src/StlSupport/StdVector.h4
-rw-r--r--intern/audaspace/FX/AUD_LimiterReader.cpp4
-rw-r--r--intern/cycles/blender/addon/properties.py2
-rw-r--r--intern/cycles/blender/blender_session.cpp86
-rw-r--r--intern/cycles/blender/blender_session.h18
-rw-r--r--intern/cycles/kernel/closure/bsdf_hair.h5
-rw-r--r--intern/cycles/kernel/geom/geom_curve.h66
-rw-r--r--intern/cycles/kernel/geom/geom_motion_curve.h66
-rw-r--r--intern/cycles/kernel/kernel_jitter.h9
-rw-r--r--intern/cycles/kernel/kernel_random.h12
-rw-r--r--intern/cycles/kernel/kernel_volume.h9
-rw-r--r--intern/cycles/render/image.cpp8
-rw-r--r--intern/cycles/render/image.h22
-rw-r--r--intern/cycles/util/util_avxf.h8
-rw-r--r--intern/cycles/util/util_math.h9
-rw-r--r--intern/cycles/util/util_transform.h5
-rw-r--r--intern/ghost/intern/GHOST_WindowWin32.cpp2
-rw-r--r--intern/opencolorio/fallback_impl.cc368
-rw-r--r--release/scripts/startup/bl_ui/space_view3d.py26
-rw-r--r--source/blender/alembic/intern/abc_camera.cc18
-rw-r--r--source/blender/alembic/intern/abc_curves.cc2
-rw-r--r--source/blender/alembic/intern/abc_curves.h2
-rw-r--r--source/blender/alembic/intern/abc_customdata.h5
-rw-r--r--source/blender/alembic/intern/abc_exporter.cc14
-rw-r--r--source/blender/alembic/intern/abc_mesh.cc286
-rw-r--r--source/blender/alembic/intern/abc_mesh.h15
-rw-r--r--source/blender/alembic/intern/abc_object.cc4
-rw-r--r--source/blender/alembic/intern/abc_object.h5
-rw-r--r--source/blender/alembic/intern/abc_points.cc7
-rw-r--r--source/blender/alembic/intern/abc_points.h4
-rw-r--r--source/blender/alembic/intern/abc_util.cc2
-rw-r--r--source/blender/alembic/intern/abc_util.h2
-rw-r--r--source/blender/alembic/intern/alembic_capi.cc12
-rw-r--r--source/blender/blenkernel/BKE_animsys.h2
-rw-r--r--source/blender/blenkernel/BKE_library.h1
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c4
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c8
-rw-r--r--source/blender/blenkernel/intern/brush.c3
-rw-r--r--source/blender/blenkernel/intern/camera.c4
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c6
-rw-r--r--source/blender/blenkernel/intern/editderivedmesh.c56
-rw-r--r--source/blender/blenkernel/intern/gpencil.c15
-rw-r--r--source/blender/blenkernel/intern/image.c1
-rw-r--r--source/blender/blenkernel/intern/library.c33
-rw-r--r--source/blender/blenkernel/intern/object.c3
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c4
-rw-r--r--source/blender/blenkernel/intern/sca.c22
-rw-r--r--source/blender/blenkernel/intern/scene.c8
-rw-r--r--source/blender/blenkernel/intern/sequencer.c3
-rw-r--r--source/blender/blenkernel/intern/subsurf_ccg.c60
-rw-r--r--source/blender/blenlib/intern/math_geom.c2
-rw-r--r--source/blender/blenloader/intern/readfile.c1
-rw-r--r--source/blender/blenloader/intern/versioning_270.c19
-rw-r--r--source/blender/collada/ArmatureImporter.cpp1
-rw-r--r--source/blender/editors/gpencil/gpencil_brush.c6
-rw-r--r--source/blender/editors/gpencil/gpencil_utils.c2
-rw-r--r--source/blender/editors/include/UI_interface.h2
-rw-r--r--source/blender/editors/interface/interface.c41
-rw-r--r--source/blender/editors/interface/interface_eyedropper.c2
-rw-r--r--source/blender/editors/interface/interface_handlers.c90
-rw-r--r--source/blender/editors/interface/interface_intern.h2
-rw-r--r--source/blender/editors/interface/interface_layout.c2
-rw-r--r--source/blender/editors/interface/interface_regions.c6
-rw-r--r--source/blender/editors/interface/interface_templates.c5
-rw-r--r--source/blender/editors/interface/interface_utils.c4
-rw-r--r--source/blender/editors/interface/interface_widgets.c10
-rw-r--r--source/blender/editors/mask/mask_add.c1
-rw-r--r--source/blender/editors/object/object_add.c107
-rw-r--r--source/blender/editors/object/object_relations.c98
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.c3
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.c7
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c17
-rw-r--r--source/blender/editors/transform/transform.c2
-rw-r--r--source/blender/imbuf/intern/allocimbuf.c13
-rw-r--r--source/blender/imbuf/intern/oiio/CMakeLists.txt5
-rw-r--r--source/blender/makesdna/DNA_ID.h6
-rw-r--r--source/blender/makesdna/DNA_node_types.h3
-rw-r--r--source/blender/makesrna/intern/rna_ID.c4
-rw-r--r--source/blender/makesrna/intern/rna_gpencil.c10
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c12
-rw-r--r--source/blender/python/mathutils/mathutils_bvhtree.c5
-rw-r--r--source/creator/CMakeLists.txt2
85 files changed, 1214 insertions, 632 deletions
diff --git a/build_files/build_environment/install_deps.sh b/build_files/build_environment/install_deps.sh
index 573ea4577e2..44334612a3a 100755
--- a/build_files/build_environment/install_deps.sh
+++ b/build_files/build_environment/install_deps.sh
@@ -289,7 +289,7 @@ NO_BUILD=false
NO_CONFIRM=false
USE_CXX11=false
-PYTHON_VERSION="3.5.1"
+PYTHON_VERSION="3.5.2"
PYTHON_VERSION_MIN="3.5"
PYTHON_FORCE_BUILD=false
PYTHON_FORCE_REBUILD=false
@@ -322,7 +322,7 @@ OPENEXR_FORCE_REBUILD=false
OPENEXR_SKIP=false
_with_built_openexr=false
-OIIO_VERSION="1.6.9"
+OIIO_VERSION="1.7.8"
OIIO_VERSION_MIN="1.6.0"
OIIO_VERSION_MAX="1.9.0" # UNKNOWN currently # Not supported by current OSL...
OIIO_FORCE_BUILD=false
@@ -337,14 +337,14 @@ LLVM_FORCE_REBUILD=false
LLVM_SKIP=false
# OSL needs to be compiled for now!
-OSL_VERSION="1.7.3"
+OSL_VERSION="1.7.5"
OSL_VERSION_MIN=$OSL_VERSION
OSL_FORCE_BUILD=false
OSL_FORCE_REBUILD=false
OSL_SKIP=false
# OpenSubdiv needs to be compiled for now
-OSD_VERSION="3.0.5"
+OSD_VERSION="3.1.0"
OSD_VERSION_MIN=$OSD_VERSION
OSD_FORCE_BUILD=false
OSD_FORCE_REBUILD=false
@@ -372,7 +372,7 @@ OPENCOLLADA_FORCE_BUILD=false
OPENCOLLADA_FORCE_REBUILD=false
OPENCOLLADA_SKIP=false
-FFMPEG_VERSION="2.8.4"
+FFMPEG_VERSION="3.2.1"
FFMPEG_VERSION_MIN="2.8.4"
FFMPEG_FORCE_BUILD=false
FFMPEG_FORCE_REBUILD=false
diff --git a/build_files/buildbot/master.cfg b/build_files/buildbot/master.cfg
index 6b7191cd57b..387e53593b3 100644
--- a/build_files/buildbot/master.cfg
+++ b/build_files/buildbot/master.cfg
@@ -297,8 +297,8 @@ def generic_builder(id, libdir='', branch='', rsync=False):
# Builders
add_builder(c, 'mac_x86_64_10_6_cmake', 'darwin-9.x.universal', generic_builder, hour=5)
-add_builder(c, 'linux_glibc211_i686_cmake', '', generic_builder, hour=1)
-add_builder(c, 'linux_glibc211_x86_64_cmake', '', generic_builder, hour=2)
+# add_builder(c, 'linux_glibc211_i686_cmake', '', generic_builder, hour=1)
+# add_builder(c, 'linux_glibc211_x86_64_cmake', '', generic_builder, hour=2)
add_builder(c, 'linux_glibc219_i686_cmake', '', generic_builder, hour=3)
add_builder(c, 'linux_glibc219_x86_64_cmake', '', generic_builder, hour=4)
add_builder(c, 'win32_cmake_vc2013', 'windows_vc12', generic_builder, hour=3)
diff --git a/build_files/cmake/platform/platform_win32_msvc.cmake b/build_files/cmake/platform/platform_win32_msvc.cmake
index 6ca0568b5fd..96c9ec91d11 100644
--- a/build_files/cmake/platform/platform_win32_msvc.cmake
+++ b/build_files/cmake/platform/platform_win32_msvc.cmake
@@ -112,7 +112,7 @@ set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} /ignore:4221")
# MSVC only, Mingw doesnt need
if(CMAKE_CL_64)
- set(PLATFORM_LINKFLAGS "/MACHINE:X64 /OPT:NOREF ${PLATFORM_LINKFLAGS}")
+ set(PLATFORM_LINKFLAGS "/MACHINE:X64 ${PLATFORM_LINKFLAGS}")
else()
set(PLATFORM_LINKFLAGS "/MACHINE:IX86 /LARGEADDRESSAWARE ${PLATFORM_LINKFLAGS}")
endif()
diff --git a/extern/Eigen3/Eigen/src/StlSupport/StdVector.h b/extern/Eigen3/Eigen/src/StlSupport/StdVector.h
index 611664a2e8a..1894af6b779 100644
--- a/extern/Eigen3/Eigen/src/StlSupport/StdVector.h
+++ b/extern/Eigen3/Eigen/src/StlSupport/StdVector.h
@@ -77,7 +77,7 @@ namespace std {
void resize(size_type new_size)
{ resize(new_size, T()); }
-#if defined(_VECTOR_)
+#if defined(_VECTOR_) && (_MSC_VER<1910)
// workaround MSVC std::vector implementation
void resize(size_type new_size, const value_type& x)
{
@@ -110,7 +110,7 @@ namespace std {
vector_base::insert(vector_base::end(), new_size - vector_base::size(), x);
}
#else
- // either GCC 4.1 or non-GCC
+ // either GCC 4.1, MSVC2017 or non-GCC
// default implementation which should always work.
void resize(size_type new_size, const value_type& x)
{
diff --git a/intern/audaspace/FX/AUD_LimiterReader.cpp b/intern/audaspace/FX/AUD_LimiterReader.cpp
index 9c1d4443b06..7d850ac7b5f 100644
--- a/intern/audaspace/FX/AUD_LimiterReader.cpp
+++ b/intern/audaspace/FX/AUD_LimiterReader.cpp
@@ -110,10 +110,10 @@ void AUD_LimiterReader::read(int& length, bool& eos, sample_t* buffer)
eos = true;
}
- if(position < m_start * rate)
+ if(position < int(m_start * rate))
{
int len2 = length;
- for(int len = m_start * rate - position;
+ for(int len = int(m_start * rate) - position;
len2 == length && !eos;
len -= length)
{
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py
index 607aafbfa1d..3616b13e751 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -288,7 +288,7 @@ class CyclesRenderSettings(bpy.types.PropertyGroup):
description="Probabilistically terminate light samples when the light contribution is below this threshold (more noise but faster rendering). "
"Zero disables the test and never ignores lights",
min=0.0, max=1.0,
- default=0.05,
+ default=0.01,
)
cls.caustics_reflective = BoolProperty(
diff --git a/intern/cycles/blender/blender_session.cpp b/intern/cycles/blender/blender_session.cpp
index f0ef61bdcad..5c99d4d6915 100644
--- a/intern/cycles/blender/blender_session.cpp
+++ b/intern/cycles/blender/blender_session.cpp
@@ -150,8 +150,8 @@ void BlenderSession::create_session()
/* setup callbacks for builtin image support */
scene->image_manager->builtin_image_info_cb = function_bind(&BlenderSession::builtin_image_info, this, _1, _2, _3, _4, _5, _6, _7);
- scene->image_manager->builtin_image_pixels_cb = function_bind(&BlenderSession::builtin_image_pixels, this, _1, _2, _3);
- scene->image_manager->builtin_image_float_pixels_cb = function_bind(&BlenderSession::builtin_image_float_pixels, this, _1, _2, _3);
+ scene->image_manager->builtin_image_pixels_cb = function_bind(&BlenderSession::builtin_image_pixels, this, _1, _2, _3, _4);
+ scene->image_manager->builtin_image_float_pixels_cb = function_bind(&BlenderSession::builtin_image_float_pixels, this, _1, _2, _3, _4);
/* create session */
session = new Session(session_params);
@@ -1090,7 +1090,13 @@ int BlenderSession::builtin_image_frame(const string &builtin_name)
return atoi(builtin_name.substr(last + 1, builtin_name.size() - last - 1).c_str());
}
-void BlenderSession::builtin_image_info(const string &builtin_name, void *builtin_data, bool &is_float, int &width, int &height, int &depth, int &channels)
+void BlenderSession::builtin_image_info(const string &builtin_name,
+ void *builtin_data,
+ bool &is_float,
+ int &width,
+ int &height,
+ int &depth,
+ int &channels)
{
/* empty image */
is_float = false;
@@ -1168,60 +1174,67 @@ void BlenderSession::builtin_image_info(const string &builtin_name, void *builti
}
}
-bool BlenderSession::builtin_image_pixels(const string &builtin_name, void *builtin_data, unsigned char *pixels)
+bool BlenderSession::builtin_image_pixels(const string &builtin_name,
+ void *builtin_data,
+ unsigned char *pixels,
+ const size_t pixels_size)
{
- if(!builtin_data)
+ if(!builtin_data) {
return false;
+ }
- int frame = builtin_image_frame(builtin_name);
+ const int frame = builtin_image_frame(builtin_name);
PointerRNA ptr;
RNA_id_pointer_create((ID*)builtin_data, &ptr);
BL::Image b_image(ptr);
- int width = b_image.size()[0];
- int height = b_image.size()[1];
- int channels = b_image.channels();
+ const int width = b_image.size()[0];
+ const int height = b_image.size()[1];
+ const int channels = b_image.channels();
- unsigned char *image_pixels;
- image_pixels = image_get_pixels_for_frame(b_image, frame);
- size_t num_pixels = ((size_t)width) * height;
+ unsigned char *image_pixels = image_get_pixels_for_frame(b_image, frame);
+ const size_t num_pixels = ((size_t)width) * height;
- if(image_pixels) {
- memcpy(pixels, image_pixels, num_pixels * channels * sizeof(unsigned char));
+ if(image_pixels && num_pixels * channels == pixels_size) {
+ memcpy(pixels, image_pixels, pixels_size * sizeof(unsigned char));
MEM_freeN(image_pixels);
}
else {
if(channels == 1) {
- memset(pixels, 0, num_pixels * sizeof(unsigned char));
+ memset(pixels, 0, pixels_size * sizeof(unsigned char));
}
else {
+ const size_t num_pixels_safe = pixels_size / channels;
unsigned char *cp = pixels;
- for(size_t i = 0; i < num_pixels; i++, cp += channels) {
+ for(size_t i = 0; i < num_pixels_safe; i++, cp += channels) {
cp[0] = 255;
cp[1] = 0;
cp[2] = 255;
- if(channels == 4)
+ if(channels == 4) {
cp[3] = 255;
+ }
}
}
}
-
- /* premultiply, byte images are always straight for blender */
+ /* Premultiply, byte images are always straight for Blender. */
unsigned char *cp = pixels;
for(size_t i = 0; i < num_pixels; i++, cp += channels) {
cp[0] = (cp[0] * cp[3]) >> 8;
cp[1] = (cp[1] * cp[3]) >> 8;
cp[2] = (cp[2] * cp[3]) >> 8;
}
-
return true;
}
-bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, void *builtin_data, float *pixels)
+bool BlenderSession::builtin_image_float_pixels(const string &builtin_name,
+ void *builtin_data,
+ float *pixels,
+ const size_t pixels_size)
{
- if(!builtin_data)
+ if(!builtin_data) {
return false;
+ }
PointerRNA ptr;
RNA_id_pointer_create((ID*)builtin_data, &ptr);
@@ -1232,16 +1245,16 @@ bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, void
BL::Image b_image(b_id);
int frame = builtin_image_frame(builtin_name);
- int width = b_image.size()[0];
- int height = b_image.size()[1];
- int channels = b_image.channels();
+ const int width = b_image.size()[0];
+ const int height = b_image.size()[1];
+ const int channels = b_image.channels();
float *image_pixels;
image_pixels = image_get_float_pixels_for_frame(b_image, frame);
- size_t num_pixels = ((size_t)width) * height;
+ const size_t num_pixels = ((size_t)width) * height;
- if(image_pixels) {
- memcpy(pixels, image_pixels, num_pixels * channels * sizeof(float));
+ if(image_pixels && num_pixels * channels == pixels_size) {
+ memcpy(pixels, image_pixels, pixels_size * sizeof(float));
MEM_freeN(image_pixels);
}
else {
@@ -1249,13 +1262,15 @@ bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, void
memset(pixels, 0, num_pixels * sizeof(float));
}
else {
+ const size_t num_pixels_safe = pixels_size / channels;
float *fp = pixels;
- for(int i = 0; i < num_pixels; i++, fp += channels) {
+ for(int i = 0; i < num_pixels_safe; i++, fp += channels) {
fp[0] = 1.0f;
fp[1] = 0.0f;
fp[2] = 1.0f;
- if(channels == 4)
+ if(channels == 4) {
fp[3] = 1.0f;
+ }
}
}
}
@@ -1267,8 +1282,9 @@ bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, void
BL::Object b_ob(b_id);
BL::SmokeDomainSettings b_domain = object_smoke_domain_find(b_ob);
- if(!b_domain)
+ if(!b_domain) {
return false;
+ }
int3 resolution = get_int3(b_domain.domain_resolution());
int length, amplify = (b_domain.use_high_resolution())? b_domain.amplify() + 1: 1;
@@ -1280,10 +1296,10 @@ bool BlenderSession::builtin_image_float_pixels(const string &builtin_name, void
amplify = 1;
}
- int width = resolution.x * amplify;
- int height = resolution.y * amplify;
- int depth = resolution.z * amplify;
- size_t num_pixels = ((size_t)width) * height * depth;
+ const int width = resolution.x * amplify;
+ const int height = resolution.y * amplify;
+ const int depth = resolution.z * amplify;
+ const size_t num_pixels = ((size_t)width) * height * depth;
if(builtin_name == Attribute::standard_name(ATTR_STD_VOLUME_DENSITY)) {
SmokeDomainSettings_density_grid_get_length(&b_domain.ptr, &length);
diff --git a/intern/cycles/blender/blender_session.h b/intern/cycles/blender/blender_session.h
index e579f556836..cf8def676b8 100644
--- a/intern/cycles/blender/blender_session.h
+++ b/intern/cycles/blender/blender_session.h
@@ -152,9 +152,21 @@ protected:
void do_write_update_render_tile(RenderTile& rtile, bool do_update_only, bool highlight);
int builtin_image_frame(const string &builtin_name);
- void builtin_image_info(const string &builtin_name, void *builtin_data, bool &is_float, int &width, int &height, int &depth, int &channels);
- bool builtin_image_pixels(const string &builtin_name, void *builtin_data, unsigned char *pixels);
- bool builtin_image_float_pixels(const string &builtin_name, void *builtin_data, float *pixels);
+ void builtin_image_info(const string &builtin_name,
+ void *builtin_data,
+ bool &is_float,
+ int &width,
+ int &height,
+ int &depth,
+ int &channels);
+ bool builtin_image_pixels(const string &builtin_name,
+ void *builtin_data,
+ unsigned char *pixels,
+ const size_t pixels_size);
+ bool builtin_image_float_pixels(const string &builtin_name,
+ void *builtin_data,
+ float *pixels,
+ const size_t pixels_size);
/* Update tile manager to reflect resumable render settings. */
void update_resumable_tile_manager(int num_samples);
diff --git a/intern/cycles/kernel/closure/bsdf_hair.h b/intern/cycles/kernel/closure/bsdf_hair.h
index bede5f45e7e..daaa26dc6ad 100644
--- a/intern/cycles/kernel/closure/bsdf_hair.h
+++ b/intern/cycles/kernel/closure/bsdf_hair.h
@@ -267,7 +267,10 @@ ccl_device int bsdf_hair_transmission_sample(const ShaderClosure *sc, float3 Ng,
*eval = make_float3(*pdf, *pdf, *pdf);
- kernel_assert(dot(locy, *omega_in) < 0.0f);
+ /* TODO(sergey): Should always be negative, but seems some precision issue
+ * is involved here.
+ */
+ kernel_assert(dot(locy, *omega_in) < 1e-4f);
return LABEL_TRANSMIT|LABEL_GLOSSY;
}
diff --git a/intern/cycles/kernel/geom/geom_curve.h b/intern/cycles/kernel/geom/geom_curve.h
index 84aaaab7453..636dbcc71e0 100644
--- a/intern/cycles/kernel/geom/geom_curve.h
+++ b/intern/cycles/kernel/geom/geom_curve.h
@@ -255,6 +255,17 @@ ccl_device_forceinline bool bvh_cardinal_curve_intersect(KernelGlobals *kg, Inte
int ka = max(k0 - 1, v00.x);
int kb = min(k1 + 1, v00.x + v00.y - 1);
+#ifdef __KERNEL_AVX2__
+ avxf P_curve_0_1, P_curve_2_3;
+ if(type & PRIMITIVE_CURVE) {
+ 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);
+ }
+ else {
+ int fobject = (object == OBJECT_NONE) ? kernel_tex_fetch(__prim_object, curveAddr) : object;
+ motion_cardinal_curve_keys_avx(kg, fobject, prim, time, ka, k0, k1, kb, &P_curve_0_1,&P_curve_2_3);
+ }
+#else /* __KERNEL_AVX2__ */
ssef P_curve[4];
if(type & PRIMITIVE_CURVE) {
@@ -267,6 +278,7 @@ ccl_device_forceinline bool bvh_cardinal_curve_intersect(KernelGlobals *kg, Inte
int fobject = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, curveAddr): object;
motion_cardinal_curve_keys(kg, fobject, prim, time, ka, k0, k1, kb, (float4*)&P_curve);
}
+#endif /* __KERNEL_AVX2__ */
ssef rd_sgn = set_sign_bit<0, 1, 1, 1>(shuffle<0>(rd_ss));
ssef mul_zxxy = shuffle<2, 0, 0, 1>(vdir) * rd_sgn;
@@ -278,6 +290,33 @@ ccl_device_forceinline bool bvh_cardinal_curve_intersect(KernelGlobals *kg, Inte
ssef htfm1 = shuffle<1, 0, 1, 3>(load1f_first(extract<0>(d_ss)), vdir0);
ssef htfm2 = shuffle<1, 3, 2, 3>(mul_shuf, vdir0);
+#ifdef __KERNEL_AVX2__
+ const avxf vPP = _mm256_broadcast_ps(&P.m128);
+ const avxf htfm00 = avxf(htfm0.m128, htfm0.m128);
+ const avxf htfm11 = avxf(htfm1.m128, htfm1.m128);
+ const avxf htfm22 = avxf(htfm2.m128, htfm2.m128);
+
+ const avxf p01 = madd(shuffle<0>(P_curve_0_1 - vPP),
+ htfm00,
+ madd(shuffle<1>(P_curve_0_1 - vPP),
+ htfm11,
+ shuffle<2>(P_curve_0_1 - vPP) * htfm22));
+ const avxf p23 = madd(shuffle<0>(P_curve_2_3 - vPP),
+ htfm00,
+ madd(shuffle<1>(P_curve_2_3 - vPP),
+ htfm11,
+ shuffle<2>(P_curve_2_3 - vPP)*htfm22));
+
+ const ssef p0 = _mm256_castps256_ps128(p01);
+ const ssef p1 = _mm256_extractf128_ps(p01, 1);
+ const ssef p2 = _mm256_castps256_ps128(p23);
+ const ssef p3 = _mm256_extractf128_ps(p23, 1);
+
+ const ssef P_curve_1 = _mm256_extractf128_ps(P_curve_0_1, 1);
+ r_st = ((float4 &)P_curve_1).w;
+ const ssef P_curve_2 = _mm256_castps256_ps128(P_curve_2_3);
+ r_en = ((float4 &)P_curve_2).w;
+#else /* __KERNEL_AVX2__ */
ssef htfm[] = { htfm0, htfm1, htfm2 };
ssef vP = load4f(P);
ssef p0 = transform_point_T3(htfm, P_curve[0] - vP);
@@ -285,6 +324,10 @@ ccl_device_forceinline bool bvh_cardinal_curve_intersect(KernelGlobals *kg, Inte
ssef p2 = transform_point_T3(htfm, P_curve[2] - vP);
ssef p3 = transform_point_T3(htfm, P_curve[3] - vP);
+ r_st = ((float4 &)P_curve[1]).w;
+ r_en = ((float4 &)P_curve[2]).w;
+#endif /* __KERNEL_AVX2__ */
+
float fc = 0.71f;
ssef vfc = ssef(fc);
ssef vfcxp3 = vfc * p3;
@@ -294,8 +337,6 @@ ccl_device_forceinline bool bvh_cardinal_curve_intersect(KernelGlobals *kg, Inte
vcurve_coef[2] = madd(ssef(fc * 2.0f), p0, madd(ssef(fc - 3.0f), p1, msub(ssef(3.0f - 2.0f * fc), p2, vfcxp3)));
vcurve_coef[3] = msub(ssef(fc - 2.0f), p2 - p1, msub(vfc, p0, vfcxp3));
- r_st = ((float4 &)P_curve[1]).w;
- r_en = ((float4 &)P_curve[2]).w;
}
#else
float3 curve_coef[4];
@@ -383,8 +424,9 @@ ccl_device_forceinline bool bvh_cardinal_curve_intersect(KernelGlobals *kg, Inte
/* begin loop */
while(!(tree >> (depth))) {
- float i_st = tree * resol;
- float i_en = i_st + (level * resol);
+ const float i_st = tree * resol;
+ const float i_en = i_st + (level * resol);
+
#ifdef __KERNEL_SSE2__
ssef vi_st = ssef(i_st), vi_en = ssef(i_en);
ssef vp_st = madd(madd(madd(vcurve_coef[3], vi_st, vcurve_coef[2]), vi_st, vcurve_coef[1]), vi_st, vcurve_coef[0]);
@@ -458,13 +500,23 @@ ccl_device_forceinline bool bvh_cardinal_curve_intersect(KernelGlobals *kg, Inte
if(flags & CURVE_KN_RIBBONS) {
float3 tg = (p_en - p_st);
+#ifdef __KERNEL_SSE__
+ const float3 tg_sq = tg * tg;
+ float w = tg_sq.x + tg_sq.y;
+#else
float w = tg.x * tg.x + tg.y * tg.y;
+#endif
if(w == 0) {
tree++;
level = tree & -tree;
continue;
}
+#ifdef __KERNEL_SSE__
+ const float3 p_sttg = p_st * tg;
+ w = -(p_sttg.x + p_sttg.y) / w;
+#else
w = -(p_st.x * tg.x + p_st.y * tg.y) / w;
+#endif
w = saturate(w);
/* compute u on the curve segment */
@@ -496,7 +548,13 @@ ccl_device_forceinline bool bvh_cardinal_curve_intersect(KernelGlobals *kg, Inte
if(difl != 0.0f) {
mw_extension = min(difl * fabsf(bmaxz), extmax);
r_ext = mw_extension + r_curr;
+#ifdef __KERNEL_SSE__
+ const float3 p_curr_sq = p_curr * p_curr;
+ const float3 dxxx = _mm_sqrt_ss(_mm_hadd_ps(p_curr_sq.m128, p_curr_sq.m128));
+ float d = dxxx.x;
+#else
float d = sqrtf(p_curr.x * p_curr.x + p_curr.y * p_curr.y);
+#endif
float d0 = d - r_curr;
float d1 = d + r_curr;
float inv_mw_extension = 1.0f/mw_extension;
diff --git a/intern/cycles/kernel/geom/geom_motion_curve.h b/intern/cycles/kernel/geom/geom_motion_curve.h
index 6de5aa7ea99..80b33fad68b 100644
--- a/intern/cycles/kernel/geom/geom_motion_curve.h
+++ b/intern/cycles/kernel/geom/geom_motion_curve.h
@@ -118,7 +118,12 @@ ccl_device_inline void motion_cardinal_curve_keys_for_step(KernelGlobals *kg, in
}
/* return 2 curve key locations */
-ccl_device_inline void motion_cardinal_curve_keys(KernelGlobals *kg, int object, int prim, float time, int k0, int k1, int k2, int k3, float4 keys[4])
+ccl_device_inline void motion_cardinal_curve_keys(KernelGlobals *kg,
+ int object,
+ int prim,
+ float time,
+ int k0, int k1, int k2, int k3,
+ float4 keys[4])
{
/* get motion info */
int numsteps, numkeys;
@@ -147,6 +152,65 @@ ccl_device_inline void motion_cardinal_curve_keys(KernelGlobals *kg, int object,
keys[3] = (1.0f - t)*keys[3] + t*next_keys[3];
}
+#ifdef __KERNEL_AVX2__
+/* Similar to above, but returns keys as pair of two AVX registers with each
+ * holding two float4.
+ */
+ccl_device_inline void motion_cardinal_curve_keys_avx(KernelGlobals *kg,
+ int object,
+ int prim,
+ float time,
+ int k0, int k1,
+ int k2, int k3,
+ avxf *out_keys_0_1,
+ avxf *out_keys_2_3)
+{
+ /* Get motion info. */
+ int numsteps, numkeys;
+ object_motion_info(kg, object, &numsteps, NULL, &numkeys);
+
+ /* Figure out which steps we need to fetch and their interpolation factor. */
+ int maxstep = numsteps * 2;
+ int step = min((int)(time*maxstep), maxstep - 1);
+ float t = time*maxstep - step;
+
+ /* Find attribute. */
+ AttributeElement elem;
+ int offset = find_attribute_curve_motion(kg,
+ object,
+ ATTR_STD_MOTION_VERTEX_POSITION,
+ &elem);
+ kernel_assert(offset != ATTR_STD_NOT_FOUND);
+
+ /* Fetch key coordinates. */
+ float4 next_keys[4];
+ float4 keys[4];
+ motion_cardinal_curve_keys_for_step(kg,
+ offset,
+ numkeys,
+ numsteps,
+ step,
+ k0, k1, k2, k3,
+ keys);
+ motion_cardinal_curve_keys_for_step(kg,
+ offset,
+ numkeys,
+ numsteps,
+ step + 1,
+ k0, k1, k2, k3,
+ next_keys);
+
+ const avxf keys_0_1 = avxf(keys[0].m128, keys[1].m128);
+ const avxf keys_2_3 = avxf(keys[2].m128, keys[3].m128);
+ const avxf next_keys_0_1 = avxf(next_keys[0].m128, next_keys[1].m128);
+ const avxf next_keys_2_3 = avxf(next_keys[2].m128, next_keys[3].m128);
+
+ /* Interpolate between steps. */
+ *out_keys_0_1 = (1.0f - t) * keys_0_1 + t*next_keys_0_1;
+ *out_keys_2_3 = (1.0f - t) * keys_2_3 + t*next_keys_2_3;
+}
+#endif
+
#endif
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_jitter.h b/intern/cycles/kernel/kernel_jitter.h
index aec7bc33acd..67546131746 100644
--- a/intern/cycles/kernel/kernel_jitter.h
+++ b/intern/cycles/kernel/kernel_jitter.h
@@ -149,6 +149,15 @@ ccl_device_inline uint cmj_hash(uint i, uint p)
return i;
}
+ccl_device_inline uint cmj_hash_simple(uint i, uint p)
+{
+ i = (i ^ 61) ^ p;
+ i += i << 3;
+ i ^= i >> 4;
+ i *= 0x27d4eb2d;
+ return i;
+}
+
ccl_device_inline float cmj_randfloat(uint i, uint p)
{
return cmj_hash(i, p) * (1.0f / 4294967808.0f);
diff --git a/intern/cycles/kernel/kernel_random.h b/intern/cycles/kernel/kernel_random.h
index 2b767da5041..e773753396f 100644
--- a/intern/cycles/kernel/kernel_random.h
+++ b/intern/cycles/kernel/kernel_random.h
@@ -120,13 +120,11 @@ ccl_device_forceinline float path_rng_1D(KernelGlobals *kg, ccl_addr_space RNG *
/* Cranly-Patterson rotation using rng seed */
float shift;
- /* using the same *rng value to offset seems to give correlation issues,
- * we could hash it with the dimension but this has a performance impact,
- * we need to find a solution for this */
- if(dimension & 1)
- shift = (*rng >> 16) * (1.0f/(float)0xFFFF);
- else
- shift = (*rng & 0xFFFF) * (1.0f/(float)0xFFFF);
+ /* Hash rng with dimension to solve correlation issues.
+ * See T38710, T50116.
+ */
+ RNG tmp_rng = cmj_hash_simple(dimension, *rng);
+ shift = tmp_rng * (1.0f/(float)0xFFFFFFFF);
return r + shift - floorf(r + shift);
#endif
diff --git a/intern/cycles/kernel/kernel_volume.h b/intern/cycles/kernel/kernel_volume.h
index dd7b0d9812d..a07ce6be077 100644
--- a/intern/cycles/kernel/kernel_volume.h
+++ b/intern/cycles/kernel/kernel_volume.h
@@ -582,17 +582,12 @@ ccl_device VolumeIntegrateResult kernel_volume_integrate_heterogeneous_distance(
ccl_device_noinline VolumeIntegrateResult kernel_volume_integrate(KernelGlobals *kg,
PathState *state, ShaderData *sd, Ray *ray, PathRadiance *L, float3 *throughput, RNG *rng, bool heterogeneous)
{
- /* workaround to fix correlation bug in T38710, can find better solution
- * in random number generator later, for now this is done here to not impact
- * performance of rendering without volumes */
- RNG tmp_rng = cmj_hash(*rng, state->rng_offset);
-
shader_setup_from_volume(kg, sd, ray);
if(heterogeneous)
- return kernel_volume_integrate_heterogeneous_distance(kg, state, ray, sd, L, throughput, &tmp_rng);
+ return kernel_volume_integrate_heterogeneous_distance(kg, state, ray, sd, L, throughput, rng);
else
- return kernel_volume_integrate_homogeneous(kg, state, ray, sd, L, throughput, &tmp_rng, true);
+ return kernel_volume_integrate_homogeneous(kg, state, ray, sd, L, throughput, rng, true);
}
/* Decoupled Volume Sampling
diff --git a/intern/cycles/render/image.cpp b/intern/cycles/render/image.cpp
index 11193bf4974..ab830b19c57 100644
--- a/intern/cycles/render/image.cpp
+++ b/intern/cycles/render/image.cpp
@@ -498,6 +498,7 @@ bool ImageManager::file_load_image(Image *img,
pixels = (StorageType*)tex_img.resize(width, height, depth);
}
bool cmyk = false;
+ const size_t num_pixels = ((size_t)width) * height * depth;
if(in) {
StorageType *readpixels = pixels;
vector<StorageType> tmppixels;
@@ -534,12 +535,14 @@ bool ImageManager::file_load_image(Image *img,
if(FileFormat == TypeDesc::FLOAT) {
builtin_image_float_pixels_cb(img->filename,
img->builtin_data,
- (float*)&pixels[0]);
+ (float*)&pixels[0],
+ num_pixels * components);
}
else if(FileFormat == TypeDesc::UINT8) {
builtin_image_pixels_cb(img->filename,
img->builtin_data,
- (uchar*)&pixels[0]);
+ (uchar*)&pixels[0],
+ num_pixels * components);
}
else {
/* TODO(dingto): Support half for ImBuf. */
@@ -552,7 +555,6 @@ bool ImageManager::file_load_image(Image *img,
type == IMAGE_DATA_TYPE_HALF4 ||
type == IMAGE_DATA_TYPE_BYTE4);
if(is_rgba) {
- size_t num_pixels = ((size_t)width) * height * depth;
if(cmyk) {
/* CMYK */
for(size_t i = num_pixels-1, pixel = 0; pixel < num_pixels; pixel++, i--) {
diff --git a/intern/cycles/render/image.h b/intern/cycles/render/image.h
index 3da7338985c..47bbd92347c 100644
--- a/intern/cycles/render/image.h
+++ b/intern/cycles/render/image.h
@@ -86,9 +86,25 @@ public:
bool need_update;
- function<void(const string &filename, void *data, bool &is_float, int &width, int &height, int &depth, int &channels)> builtin_image_info_cb;
- function<bool(const string &filename, void *data, unsigned char *pixels)> builtin_image_pixels_cb;
- function<bool(const string &filename, void *data, float *pixels)> builtin_image_float_pixels_cb;
+ /* NOTE: Here pixels_size is a size of storage, which equals to
+ * width * height * depth.
+ * Use this to avoid some nasty memory corruptions.
+ */
+ function<void(const string &filename,
+ void *data,
+ bool &is_float,
+ int &width,
+ int &height,
+ int &depth,
+ int &channels)> builtin_image_info_cb;
+ function<bool(const string &filename,
+ void *data,
+ unsigned char *pixels,
+ const size_t pixels_size)> builtin_image_pixels_cb;
+ function<bool(const string &filename,
+ void *data,
+ float *pixels,
+ const size_t pixels_size)> builtin_image_float_pixels_cb;
struct Image {
string filename;
diff --git a/intern/cycles/util/util_avxf.h b/intern/cycles/util/util_avxf.h
index 2db2c4dad1a..2451213963a 100644
--- a/intern/cycles/util/util_avxf.h
+++ b/intern/cycles/util/util_avxf.h
@@ -180,6 +180,14 @@ __forceinline const avxf nmadd(const avxf& a, const avxf& b, const avxf& c) {
}
#endif
+#ifndef _mm256_set_m128
+# define _mm256_set_m128(/* __m128 */ hi, /* __m128 */ lo) \
+ _mm256_insertf128_ps(_mm256_castps128_ps256(lo), (hi), 0x1)
+#endif
+
+#define _mm256_loadu2_m128(/* float const* */ hiaddr, /* float const* */ loaddr) \
+ _mm256_set_m128(_mm_loadu_ps(hiaddr), _mm_loadu_ps(loaddr))
+
CCL_NAMESPACE_END
#endif
diff --git a/intern/cycles/util/util_math.h b/intern/cycles/util/util_math.h
index 9c7cc583be9..e5512e2e65f 100644
--- a/intern/cycles/util/util_math.h
+++ b/intern/cycles/util/util_math.h
@@ -596,8 +596,7 @@ ccl_device_inline float len_squared(const float4& a)
ccl_device_inline float3 normalize(const float3& a)
{
- /* TODO(sergey): Disabled for now, causes crashes in certain cases. */
-#if defined(__KERNEL_SSE41__) && defined(__KERNEL_SSE__) && 0
+#if defined(__KERNEL_SSE41__) && defined(__KERNEL_SSE__)
__m128 norm = _mm_sqrt_ps(_mm_dp_ps(a.m128, a.m128, 0x7F));
return _mm_div_ps(a.m128, norm);
#else
@@ -798,8 +797,7 @@ ccl_device_inline float4 operator-(const float4& a)
ccl_device_inline float4 operator*(const float4& a, const float4& b)
{
- /* TODO(sergey): Disabled for now, causes crashes in certain cases. */
-#if defined(__KERNEL_SSE__) && 0
+#ifdef __KERNEL_SSE__
return _mm_mul_ps(a.m128, b.m128);
#else
return make_float4(a.x*b.x, a.y*b.y, a.z*b.z, a.w*b.w);
@@ -847,8 +845,7 @@ ccl_device_inline float4 operator/(const float4& a, const float4& b)
ccl_device_inline float4 operator+(const float4& a, const float4& b)
{
- /* TODO(sergey): Disabled for now, causes crashes in certain cases. */
-#if defined(__KERNEL_SSE__) && 0
+#ifdef __KERNEL_SSE__
return _mm_add_ps(a.m128, b.m128);
#else
return make_float4(a.x+b.x, a.y+b.y, a.z+b.z, a.w+b.w);
diff --git a/intern/cycles/util/util_transform.h b/intern/cycles/util/util_transform.h
index ea5eb3b25b0..a0695f20488 100644
--- a/intern/cycles/util/util_transform.h
+++ b/intern/cycles/util/util_transform.h
@@ -74,7 +74,7 @@ ccl_device_inline float3 transform_perspective(const Transform *t, const float3
ccl_device_inline float3 transform_point(const Transform *t, const float3 a)
{
/* TODO(sergey): Disabled for now, causes crashes in certain cases. */
-#if defined(__KERNEL_SSE__) && defined(__KERNEL_SSE2__) && 0
+#if defined(__KERNEL_SSE__) && defined(__KERNEL_SSE2__)
ssef x, y, z, w, aa;
aa = a.m128;
@@ -103,8 +103,7 @@ ccl_device_inline float3 transform_point(const Transform *t, const float3 a)
ccl_device_inline float3 transform_direction(const Transform *t, const float3 a)
{
- /* TODO(sergey): Disabled for now, causes crashes in certain cases. */
-#if defined(__KERNEL_SSE__) && defined(__KERNEL_SSE2__) && 0
+#if defined(__KERNEL_SSE__) && defined(__KERNEL_SSE2__)
ssef x, y, z, w, aa;
aa = a.m128;
x = _mm_loadu_ps(&t->x.x);
diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp
index 2aa950f8278..7d80aa43a40 100644
--- a/intern/ghost/intern/GHOST_WindowWin32.cpp
+++ b/intern/ghost/intern/GHOST_WindowWin32.cpp
@@ -353,7 +353,7 @@ GHOST_WindowWin32::~GHOST_WindowWin32()
// Release our reference of the DropTarget and it will delete itself eventually.
m_dropTarget->Release();
}
-
+ ::SetWindowLongPtr(m_hWnd, GWLP_USERDATA, NULL);
::DestroyWindow(m_hWnd);
m_hWnd = 0;
}
diff --git a/intern/opencolorio/fallback_impl.cc b/intern/opencolorio/fallback_impl.cc
index 1124e7fd8ab..87629422013 100644
--- a/intern/opencolorio/fallback_impl.cc
+++ b/intern/opencolorio/fallback_impl.cc
@@ -23,18 +23,26 @@
* ***** END GPL LICENSE BLOCK *****
*/
-#include <string.h>
+#include <algorithm>
+#include <cstring>
#include "MEM_guardedalloc.h"
#include "BLI_math_color.h"
+#include "BLI_math_vector.h"
#include "ocio_impl.h"
+using std::max;
+
#define CONFIG_DEFAULT ((OCIO_ConstConfigRcPtr*)1)
-#define PROCESSOR_LINEAR_TO_SRGB ((OCIO_ConstProcessorRcPtr*)1)
-#define PROCESSOR_SRGB_TO_LINEAR ((OCIO_ConstProcessorRcPtr*)2)
-#define PROCESSOR_UNKNOWN ((OCIO_ConstProcessorRcPtr*)3)
+enum TransformType {
+ TRANSFORM_LINEAR_TO_SRGB,
+ TRANSFORM_SRGB_TO_LINEAR,
+ TRANSFORM_MATRIX,
+ TRANSFORM_EXPONENT,
+ TRANSFORM_UNKNOWN,
+};
#define COLORSPACE_LINEAR ((OCIO_ConstColorSpaceRcPtr*)1)
#define COLORSPACE_SRGB ((OCIO_ConstColorSpaceRcPtr*)2)
@@ -49,6 +57,145 @@ typedef struct OCIO_PackedImageDescription {
long yStrideBytes;
} OCIO_PackedImageDescription;
+struct FallbackTransform {
+ FallbackTransform()
+ : type(TRANSFORM_UNKNOWN),
+ linear_transform(NULL),
+ display_transform(NULL)
+ {
+ }
+
+ ~FallbackTransform()
+ {
+ delete linear_transform;
+ delete display_transform;
+ }
+
+ void applyRGB(float *pixel)
+ {
+ if (type == TRANSFORM_LINEAR_TO_SRGB) {
+ applyLinearRGB(pixel);
+ linearrgb_to_srgb_v3_v3(pixel, pixel);
+ applyDisplayRGB(pixel);
+ }
+ else if (type == TRANSFORM_SRGB_TO_LINEAR) {
+ srgb_to_linearrgb_v3_v3(pixel, pixel);
+ }
+ else if (type == TRANSFORM_EXPONENT) {
+ pixel[0] = powf(max(0.0f, pixel[0]), exponent[0]);
+ pixel[1] = powf(max(0.0f, pixel[1]), exponent[1]);
+ pixel[2] = powf(max(0.0f, pixel[2]), exponent[2]);
+ }
+ else if (type == TRANSFORM_MATRIX) {
+ float r = pixel[0];
+ float g = pixel[1];
+ float b = pixel[2];
+ pixel[0] = r*matrix[0] + g*matrix[1] + b*matrix[2];
+ pixel[1] = r*matrix[4] + g*matrix[5] + b*matrix[6];
+ pixel[2] = r*matrix[8] + g*matrix[9] + b*matrix[10];
+ pixel[0] += offset[0];
+ pixel[1] += offset[1];
+ pixel[2] += offset[2];
+ }
+ }
+
+ void applyRGBA(float *pixel)
+ {
+ if (type == TRANSFORM_LINEAR_TO_SRGB) {
+ applyLinearRGBA(pixel);
+ linearrgb_to_srgb_v4(pixel, pixel);
+ applyDisplayRGBA(pixel);
+ }
+ else if (type == TRANSFORM_SRGB_TO_LINEAR) {
+ srgb_to_linearrgb_v4(pixel, pixel);
+ }
+ else if (type == TRANSFORM_EXPONENT) {
+ pixel[0] = powf(max(0.0f, pixel[0]), exponent[0]);
+ pixel[1] = powf(max(0.0f, pixel[1]), exponent[1]);
+ pixel[2] = powf(max(0.0f, pixel[2]), exponent[2]);
+ pixel[3] = powf(max(0.0f, pixel[3]), exponent[3]);
+ }
+ else if (type == TRANSFORM_MATRIX) {
+ float r = pixel[0];
+ float g = pixel[1];
+ float b = pixel[2];
+ float a = pixel[3];
+ pixel[0] = r*matrix[0] + g*matrix[1] + b*matrix[2] + a*matrix[3];
+ pixel[1] = r*matrix[4] + g*matrix[5] + b*matrix[6] + a*matrix[7];
+ pixel[2] = r*matrix[8] + g*matrix[9] + b*matrix[10] + a*matrix[11];
+ pixel[3] = r*matrix[12] + g*matrix[13] + b*matrix[14] + a*matrix[15];
+ pixel[0] += offset[0];
+ pixel[1] += offset[1];
+ pixel[2] += offset[2];
+ pixel[3] += offset[3];
+ }
+ }
+
+ void applyLinearRGB(float *pixel)
+ {
+ if (linear_transform != NULL) {
+ linear_transform->applyRGB(pixel);
+ }
+ }
+
+ void applyLinearRGBA(float *pixel)
+ {
+ if (linear_transform != NULL) {
+ linear_transform->applyRGBA(pixel);
+ }
+ }
+
+ void applyDisplayRGB(float *pixel)
+ {
+ if (display_transform != NULL) {
+ display_transform->applyRGB(pixel);
+ }
+ }
+
+ void applyDisplayRGBA(float *pixel)
+ {
+ if (display_transform != NULL) {
+ display_transform->applyRGBA(pixel);
+ }
+ }
+
+ TransformType type;
+ FallbackTransform *linear_transform;
+ FallbackTransform *display_transform;
+ /* Exponent transform. */
+ float exponent[4];
+ /* Matrix transform. */
+ float matrix[16];
+ float offset[4];
+
+ MEM_CXX_CLASS_ALLOC_FUNCS("FallbackProcessor");
+};
+
+struct FallbackProcessor {
+ FallbackProcessor()
+ : transform(NULL)
+ {
+ }
+
+ ~FallbackProcessor() {
+ delete transform;
+ }
+
+ void applyRGB(float *pixel)
+ {
+ transform->applyRGB(pixel);
+ }
+
+ void applyRGBA(float *pixel)
+ {
+ transform->applyRGBA(pixel);
+ }
+
+ FallbackTransform *transform;
+
+ MEM_CXX_CLASS_ALLOC_FUNCS("FallbackProcessor");
+};
+
OCIO_ConstConfigRcPtr *FallbackImpl::getCurrentConfig(void)
{
return CONFIG_DEFAULT;
@@ -77,7 +224,8 @@ int FallbackImpl::configGetNumColorSpaces(OCIO_ConstConfigRcPtr * /*config*/)
return 2;
}
-const char *FallbackImpl::configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr * /*config*/, int index)
+const char *FallbackImpl::configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr * /*config*/,
+ int index)
{
if (index == 0)
return "Linear";
@@ -87,7 +235,8 @@ const char *FallbackImpl::configGetColorSpaceNameByIndex(OCIO_ConstConfigRcPtr *
return NULL;
}
-OCIO_ConstColorSpaceRcPtr *FallbackImpl::configGetColorSpace(OCIO_ConstConfigRcPtr * /*config*/, const char *name)
+OCIO_ConstColorSpaceRcPtr *FallbackImpl::configGetColorSpace(OCIO_ConstConfigRcPtr * /*config*/,
+ const char *name)
{
if (strcmp(name, "scene_linear") == 0)
return COLORSPACE_LINEAR;
@@ -109,15 +258,17 @@ OCIO_ConstColorSpaceRcPtr *FallbackImpl::configGetColorSpace(OCIO_ConstConfigRcP
return NULL;
}
-int FallbackImpl::configGetIndexForColorSpace(OCIO_ConstConfigRcPtr *config, const char *name)
+int FallbackImpl::configGetIndexForColorSpace(OCIO_ConstConfigRcPtr *config,
+ const char *name)
{
OCIO_ConstColorSpaceRcPtr *cs = configGetColorSpace(config, name);
- if (cs == COLORSPACE_LINEAR)
+ if (cs == COLORSPACE_LINEAR) {
return 0;
- else if (cs == COLORSPACE_SRGB)
+ }
+ else if (cs == COLORSPACE_SRGB) {
return 1;
-
+ }
return -1;
}
@@ -131,44 +282,51 @@ int FallbackImpl::configGetNumDisplays(OCIO_ConstConfigRcPtr * /*config*/)
return 1;
}
-const char *FallbackImpl::configGetDisplay(OCIO_ConstConfigRcPtr * /*config*/, int index)
+const char *FallbackImpl::configGetDisplay(OCIO_ConstConfigRcPtr * /*config*/,
+ int index)
{
- if (index == 0)
+ if (index == 0) {
return "sRGB";
-
+ }
return NULL;
}
-const char *FallbackImpl::configGetDefaultView(OCIO_ConstConfigRcPtr * /*config*/, const char * /*display*/)
+const char *FallbackImpl::configGetDefaultView(OCIO_ConstConfigRcPtr * /*config*/,
+ const char * /*display*/)
{
return "Default";
}
-int FallbackImpl::configGetNumViews(OCIO_ConstConfigRcPtr * /*config*/, const char * /*display*/)
+int FallbackImpl::configGetNumViews(OCIO_ConstConfigRcPtr * /*config*/,
+ const char * /*display*/)
{
return 1;
}
-const char *FallbackImpl::configGetView(OCIO_ConstConfigRcPtr * /*config*/, const char * /*display*/, int index)
+const char *FallbackImpl::configGetView(OCIO_ConstConfigRcPtr * /*config*/,
+ const char * /*display*/, int index)
{
- if (index == 0)
+ if (index == 0) {
return "Default";
-
+ }
return NULL;
}
-const char *FallbackImpl::configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr * /*config*/, const char * /*display*/, const char * /*view*/)
+const char *FallbackImpl::configGetDisplayColorSpaceName(OCIO_ConstConfigRcPtr * /*config*/,
+ const char * /*display*/,
+ const char * /*view*/)
{
return "sRGB";
}
-void FallbackImpl::configGetDefaultLumaCoefs(OCIO_ConstConfigRcPtr * /*config*/, float *rgb)
+void FallbackImpl::configGetDefaultLumaCoefs(OCIO_ConstConfigRcPtr * /*config*/,
+ float *rgb)
{
- /* Here we simply use the older Blender assumed primaries of
- * ITU-BT.709 / sRGB, or 0.2126729 0.7151522 0.0721750. Brute
- * force stupid, but only plausible option given no color management
- * system in place.
- */
+ /* Here we simply use the older Blender assumed primaries of
+ * ITU-BT.709 / sRGB, or 0.2126729 0.7151522 0.0721750. Brute
+ * force stupid, but only plausible option given no color management
+ * system in place.
+ */
rgb[0] = 0.2126f;
rgb[1] = 0.7152f;
@@ -180,12 +338,14 @@ int FallbackImpl::configGetNumLooks(OCIO_ConstConfigRcPtr * /*config*/)
return 0;
}
-const char *FallbackImpl::configGetLookNameByIndex(OCIO_ConstConfigRcPtr * /*config*/, int /*index*/)
+const char *FallbackImpl::configGetLookNameByIndex(OCIO_ConstConfigRcPtr * /*config*/,
+ int /*index*/)
{
return "";
}
-OCIO_ConstLookRcPtr *FallbackImpl::configGetLook(OCIO_ConstConfigRcPtr * /*config*/, const char * /*name*/)
+OCIO_ConstLookRcPtr *FallbackImpl::configGetLook(OCIO_ConstConfigRcPtr * /*config*/,
+ const char * /*name*/)
{
return NULL;
}
@@ -213,25 +373,38 @@ void FallbackImpl::colorSpaceRelease(OCIO_ConstColorSpaceRcPtr * /*cs*/)
{
}
-OCIO_ConstProcessorRcPtr *FallbackImpl::configGetProcessorWithNames(OCIO_ConstConfigRcPtr *config, const char *srcName, const char *dstName)
+OCIO_ConstProcessorRcPtr *FallbackImpl::configGetProcessorWithNames(
+ OCIO_ConstConfigRcPtr *config,
+ const char *srcName,
+ const char *dstName)
{
OCIO_ConstColorSpaceRcPtr *cs_src = configGetColorSpace(config, srcName);
OCIO_ConstColorSpaceRcPtr *cs_dst = configGetColorSpace(config, dstName);
-
- if (cs_src == COLORSPACE_LINEAR && cs_dst == COLORSPACE_SRGB)
- return PROCESSOR_LINEAR_TO_SRGB;
- else if (cs_src == COLORSPACE_SRGB && cs_dst == COLORSPACE_LINEAR)
- return PROCESSOR_SRGB_TO_LINEAR;
-
- return 0;
+ FallbackTransform *transform = new FallbackTransform();
+ if (cs_src == COLORSPACE_LINEAR && cs_dst == COLORSPACE_SRGB) {
+ transform->type = TRANSFORM_LINEAR_TO_SRGB;
+ }
+ else if (cs_src == COLORSPACE_SRGB && cs_dst == COLORSPACE_LINEAR) {
+ transform->type = TRANSFORM_SRGB_TO_LINEAR;
+ }
+ else {
+ transform->type = TRANSFORM_UNKNOWN;
+ }
+ FallbackProcessor *processor = new FallbackProcessor();
+ processor->transform = transform;
+ return (OCIO_ConstProcessorRcPtr *)processor;
}
-OCIO_ConstProcessorRcPtr *FallbackImpl::configGetProcessor(OCIO_ConstConfigRcPtr * /*config*/, OCIO_ConstTransformRcPtr *tfm)
+OCIO_ConstProcessorRcPtr *FallbackImpl::configGetProcessor(OCIO_ConstConfigRcPtr * /*config*/,
+ OCIO_ConstTransformRcPtr *transform)
{
- return (OCIO_ConstProcessorRcPtr*)tfm;
+ FallbackProcessor *processor = new FallbackProcessor();
+ processor->transform = (FallbackTransform *)transform;
+ return (OCIO_ConstProcessorRcPtr *)processor;
}
-void FallbackImpl::processorApply(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img)
+void FallbackImpl::processorApply(OCIO_ConstProcessorRcPtr *processor,
+ OCIO_PackedImageDesc *img)
{
/* OCIO_TODO stride not respected, channels must be 3 or 4 */
OCIO_PackedImageDescription *desc = (OCIO_PackedImageDescription*)img;
@@ -253,7 +426,8 @@ void FallbackImpl::processorApply(OCIO_ConstProcessorRcPtr *processor, OCIO_Pack
}
}
-void FallbackImpl::processorApply_predivide(OCIO_ConstProcessorRcPtr *processor, OCIO_PackedImageDesc *img)
+void FallbackImpl::processorApply_predivide(OCIO_ConstProcessorRcPtr *processor,
+ OCIO_PackedImageDesc *img)
{
/* OCIO_TODO stride not respected, channels must be 3 or 4 */
OCIO_PackedImageDescription *desc = (OCIO_PackedImageDescription*)img;
@@ -275,23 +449,20 @@ void FallbackImpl::processorApply_predivide(OCIO_ConstProcessorRcPtr *processor,
}
}
-void FallbackImpl::processorApplyRGB(OCIO_ConstProcessorRcPtr *processor, float *pixel)
+void FallbackImpl::processorApplyRGB(OCIO_ConstProcessorRcPtr *processor,
+ float *pixel)
{
- if (processor == PROCESSOR_LINEAR_TO_SRGB)
- linearrgb_to_srgb_v3_v3(pixel, pixel);
- else if (processor == PROCESSOR_SRGB_TO_LINEAR)
- srgb_to_linearrgb_v3_v3(pixel, pixel);
+ ((FallbackProcessor *)processor)->applyRGB(pixel);
}
-void FallbackImpl::processorApplyRGBA(OCIO_ConstProcessorRcPtr *processor, float *pixel)
+void FallbackImpl::processorApplyRGBA(OCIO_ConstProcessorRcPtr *processor,
+ float *pixel)
{
- if (processor == PROCESSOR_LINEAR_TO_SRGB)
- linearrgb_to_srgb_v4(pixel, pixel);
- else if (processor == PROCESSOR_SRGB_TO_LINEAR)
- srgb_to_linearrgb_v4(pixel, pixel);
+ ((FallbackProcessor *)processor)->applyRGBA(pixel);
}
-void FallbackImpl::processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *processor, float *pixel)
+void FallbackImpl::processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *processor,
+ float *pixel)
{
if (pixel[3] == 1.0f || pixel[3] == 0.0f) {
processorApplyRGBA(processor, pixel);
@@ -314,17 +485,19 @@ void FallbackImpl::processorApplyRGBA_predivide(OCIO_ConstProcessorRcPtr *proces
}
}
-void FallbackImpl::processorRelease(OCIO_ConstProcessorRcPtr * /*p*/)
+void FallbackImpl::processorRelease(OCIO_ConstProcessorRcPtr *processor)
{
+ delete (FallbackProcessor*)(processor);
}
const char *FallbackImpl::colorSpaceGetName(OCIO_ConstColorSpaceRcPtr *cs)
{
- if (cs == COLORSPACE_LINEAR)
+ if (cs == COLORSPACE_LINEAR) {
return "Linear";
- else if (cs == COLORSPACE_SRGB)
+ }
+ else if (cs == COLORSPACE_SRGB) {
return "sRGB";
-
+ }
return NULL;
}
@@ -340,34 +513,47 @@ const char *FallbackImpl::colorSpaceGetFamily(OCIO_ConstColorSpaceRcPtr * /*cs*/
OCIO_DisplayTransformRcPtr *FallbackImpl::createDisplayTransform(void)
{
- return (OCIO_DisplayTransformRcPtr*)PROCESSOR_LINEAR_TO_SRGB;
+ FallbackTransform *transform = new FallbackTransform();
+ transform->type = TRANSFORM_LINEAR_TO_SRGB;
+ return (OCIO_DisplayTransformRcPtr*)transform;
}
-void FallbackImpl::displayTransformSetInputColorSpaceName(OCIO_DisplayTransformRcPtr * /*dt*/, const char * /*name*/)
+void FallbackImpl::displayTransformSetInputColorSpaceName(OCIO_DisplayTransformRcPtr * /*dt*/,
+ const char * /*name*/)
{
}
-void FallbackImpl::displayTransformSetDisplay(OCIO_DisplayTransformRcPtr * /*dt*/, const char * /*name*/)
+void FallbackImpl::displayTransformSetDisplay(OCIO_DisplayTransformRcPtr * /*dt*/,
+ const char * /*name*/)
{
}
-void FallbackImpl::displayTransformSetView(OCIO_DisplayTransformRcPtr * /*dt*/, const char * /*name*/)
+void FallbackImpl::displayTransformSetView(OCIO_DisplayTransformRcPtr * /*dt*/,
+ const char * /*name*/)
{
}
-void FallbackImpl::displayTransformSetDisplayCC(OCIO_DisplayTransformRcPtr * /*dt*/, OCIO_ConstTransformRcPtr * /*et*/)
+void FallbackImpl::displayTransformSetDisplayCC(OCIO_DisplayTransformRcPtr *dt,
+ OCIO_ConstTransformRcPtr *et)
{
+ FallbackTransform *transform = (FallbackTransform *)dt;
+ transform->display_transform = (FallbackTransform *)et;
}
-void FallbackImpl::displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr * /*dt*/, OCIO_ConstTransformRcPtr * /*et*/)
+void FallbackImpl::displayTransformSetLinearCC(OCIO_DisplayTransformRcPtr *dt,
+ OCIO_ConstTransformRcPtr *et)
{
+ FallbackTransform *transform = (FallbackTransform *)dt;
+ transform->linear_transform = (FallbackTransform *)et;
}
-void FallbackImpl::displayTransformSetLooksOverride(OCIO_DisplayTransformRcPtr * /*dt*/, const char * /*looks*/)
+void FallbackImpl::displayTransformSetLooksOverride(OCIO_DisplayTransformRcPtr * /*dt*/,
+ const char * /*looks*/)
{
}
-void FallbackImpl::displayTransformSetLooksOverrideEnabled(OCIO_DisplayTransformRcPtr * /*dt*/, bool /*enabled*/)
+void FallbackImpl::displayTransformSetLooksOverrideEnabled(OCIO_DisplayTransformRcPtr * /*dt*/,
+ bool /*enabled*/)
{
}
@@ -375,11 +561,14 @@ void FallbackImpl::displayTransformRelease(OCIO_DisplayTransformRcPtr * /*dt*/)
{
}
-OCIO_PackedImageDesc *FallbackImpl::createOCIO_PackedImageDesc(float *data, long width, long height, long numChannels,
- long chanStrideBytes, long xStrideBytes, long yStrideBytes)
+OCIO_PackedImageDesc *FallbackImpl::createOCIO_PackedImageDesc(
+ float *data,
+ long width, long height, long numChannels,
+ long chanStrideBytes, long xStrideBytes, long yStrideBytes)
{
- OCIO_PackedImageDescription *desc = (OCIO_PackedImageDescription*)MEM_callocN(sizeof(OCIO_PackedImageDescription), "OCIO_PackedImageDescription");
-
+ OCIO_PackedImageDescription *desc =
+ (OCIO_PackedImageDescription*)MEM_callocN(sizeof(OCIO_PackedImageDescription),
+ "OCIO_PackedImageDescription");
desc->data = data;
desc->width = width;
desc->height = height;
@@ -387,7 +576,6 @@ OCIO_PackedImageDesc *FallbackImpl::createOCIO_PackedImageDesc(float *data, long
desc->chanStrideBytes = chanStrideBytes;
desc->xStrideBytes = xStrideBytes;
desc->yStrideBytes = yStrideBytes;
-
return (OCIO_PackedImageDesc*)desc;
}
@@ -398,11 +586,16 @@ void FallbackImpl::OCIO_PackedImageDescRelease(OCIO_PackedImageDesc* id)
OCIO_ExponentTransformRcPtr *FallbackImpl::createExponentTransform(void)
{
- return (OCIO_ExponentTransformRcPtr*)PROCESSOR_UNKNOWN;
+ FallbackTransform *transform = new FallbackTransform();
+ transform->type = TRANSFORM_EXPONENT;
+ return (OCIO_ExponentTransformRcPtr *)transform;
}
-void FallbackImpl::exponentTransformSetValue(OCIO_ExponentTransformRcPtr * /*et*/, const float * /*exponent*/)
+void FallbackImpl::exponentTransformSetValue(OCIO_ExponentTransformRcPtr *et,
+ const float *exponent)
{
+ FallbackTransform *transform = (FallbackTransform *)et;
+ copy_v4_v4(transform->exponent, exponent);
}
void FallbackImpl::exponentTransformRelease(OCIO_ExponentTransformRcPtr * /*et*/)
@@ -411,19 +604,44 @@ void FallbackImpl::exponentTransformRelease(OCIO_ExponentTransformRcPtr * /*et*/
OCIO_MatrixTransformRcPtr *FallbackImpl::createMatrixTransform(void)
{
- return (OCIO_MatrixTransformRcPtr*)PROCESSOR_UNKNOWN;
+ FallbackTransform *transform = new FallbackTransform();
+ transform->type = TRANSFORM_MATRIX;
+ return (OCIO_MatrixTransformRcPtr *)transform;
}
-void FallbackImpl::matrixTransformSetValue(OCIO_MatrixTransformRcPtr * /*mt*/, const float * /*m44*/, const float * /*offset4*/)
+void FallbackImpl::matrixTransformSetValue(OCIO_MatrixTransformRcPtr *mt,
+ const float *m44,
+ const float *offset4)
{
+ FallbackTransform *transform = (FallbackTransform *)mt;
+ copy_m4_m4((float (*)[4])transform->matrix, (float (*)[4])m44);
+ copy_v4_v4(transform->offset, offset4);
}
void FallbackImpl::matrixTransformRelease(OCIO_MatrixTransformRcPtr * /*mt*/)
{
}
-void FallbackImpl::matrixTransformScale(float * /*m44*/, float * /*offset44*/, const float * /*scale4*/)
+void FallbackImpl::matrixTransformScale(float *m44,
+ float *offset4,
+ const float *scale4)
{
+ if (scale4 == NULL) {
+ return;
+ }
+ if (m44 != NULL) {
+ memset(m44, 0, 16*sizeof(float));
+ m44[0] = scale4[0];
+ m44[5] = scale4[1];
+ m44[10] = scale4[2];
+ m44[15] = scale4[3];
+ }
+ if (offset4 != NULL) {
+ offset4[0] = 0.0f;
+ offset4[1] = 0.0f;
+ offset4[2] = 0.0f;
+ offset4[3] = 0.0f;
+ }
}
bool FallbackImpl::supportGLSLDraw(void)
@@ -431,9 +649,11 @@ bool FallbackImpl::supportGLSLDraw(void)
return false;
}
-bool FallbackImpl::setupGLSLDraw(struct OCIO_GLSLDrawState ** /*state_r*/, OCIO_ConstProcessorRcPtr * /*processor*/,
+bool FallbackImpl::setupGLSLDraw(struct OCIO_GLSLDrawState ** /*state_r*/,
+ OCIO_ConstProcessorRcPtr * /*processor*/,
OCIO_CurveMappingSettings * /*curve_mapping_settings*/,
- float /*dither*/, bool /*predivide*/)
+ float /*dither*/,
+ bool /*predivide*/)
{
return false;
}
diff --git a/release/scripts/startup/bl_ui/space_view3d.py b/release/scripts/startup/bl_ui/space_view3d.py
index 9de9376312c..5e936076d0e 100644
--- a/release/scripts/startup/bl_ui/space_view3d.py
+++ b/release/scripts/startup/bl_ui/space_view3d.py
@@ -3053,11 +3053,18 @@ class VIEW3D_MT_edit_gpencil(Menu):
layout.separator()
layout.menu("VIEW3D_MT_object_animation") # NOTE: provides keyingset access...
+ layout.menu("VIEW3D_MT_edit_gpencil_interpolate")
layout.separator()
layout.menu("VIEW3D_MT_edit_gpencil_delete")
layout.operator("gpencil.duplicate_move", text="Duplicate")
+ layout.operator("gpencil.stroke_subdivide", text="Subdivide")
+
+ layout.separator()
+
+ layout.operator_menu_enum("gpencil.stroke_join", "type", text="Join...")
+ layout.operator("gpencil.stroke_flip", text="Flip Direction")
layout.separator()
@@ -3077,6 +3084,11 @@ class VIEW3D_MT_edit_gpencil(Menu):
layout.separator()
layout.operator_menu_enum("gpencil.move_to_layer", "layer", text="Move to Layer")
+ layout.operator("gpencil.stroke_change_color", text="Move to Color")
+ layout.operator_menu_enum("gpencil.stroke_arrange", "direction", text="Arrange Strokes...")
+
+ layout.separator()
+
layout.operator_menu_enum("gpencil.convert", "type", text="Convert to Geometry...")
@@ -3097,6 +3109,20 @@ class VIEW3D_MT_edit_gpencil_transform(Menu):
layout.operator("transform.tosphere", text="To Sphere")
layout.operator("transform.transform", text="Shrink Fatten").mode = 'GPENCIL_SHRINKFATTEN'
+ layout.separator()
+
+ layout.operator("gpencil.reproject")
+
+
+class VIEW3D_MT_edit_gpencil_interpolate(Menu):
+ bl_label = "Interpolate"
+
+ def draw(self, context):
+ layout = self.layout
+
+ layout.operator("gpencil.interpolate", text="Interpolate")
+ layout.operator("gpencil.interpolate_sequence", text="Sequence")
+
# ********** Panel **********
diff --git a/source/blender/alembic/intern/abc_camera.cc b/source/blender/alembic/intern/abc_camera.cc
index d5271e3ca31..4f70b2a972c 100644
--- a/source/blender/alembic/intern/abc_camera.cc
+++ b/source/blender/alembic/intern/abc_camera.cc
@@ -138,11 +138,11 @@ void AbcCameraReader::readObjectData(Main *bmain, float time)
bcam->stereo.convergence_distance = convergence_plane.getValue(sample_sel);
}
- const float lens = cam_sample.getFocalLength();
- const float apperture_x = cam_sample.getHorizontalAperture();
- const float apperture_y = cam_sample.getVerticalAperture();
- const float h_film_offset = cam_sample.getHorizontalFilmOffset();
- const float v_film_offset = cam_sample.getVerticalFilmOffset();
+ const float lens = static_cast<float>(cam_sample.getFocalLength());
+ const float apperture_x = static_cast<float>(cam_sample.getHorizontalAperture());
+ const float apperture_y = static_cast<float>(cam_sample.getVerticalAperture());
+ const float h_film_offset = static_cast<float>(cam_sample.getHorizontalFilmOffset());
+ const float v_film_offset = static_cast<float>(cam_sample.getVerticalFilmOffset());
const float film_aspect = apperture_x / apperture_y;
bcam->lens = lens;
@@ -150,10 +150,10 @@ void AbcCameraReader::readObjectData(Main *bmain, float time)
bcam->sensor_y = apperture_y * 10;
bcam->shiftx = h_film_offset / apperture_x;
bcam->shifty = v_film_offset / apperture_y / film_aspect;
- bcam->clipsta = max_ff(0.1f, cam_sample.getNearClippingPlane());
- bcam->clipend = cam_sample.getFarClippingPlane();
- bcam->gpu_dof.focus_distance = cam_sample.getFocusDistance();
- bcam->gpu_dof.fstop = cam_sample.getFStop();
+ bcam->clipsta = max_ff(0.1f, static_cast<float>(cam_sample.getNearClippingPlane()));
+ bcam->clipend = static_cast<float>(cam_sample.getFarClippingPlane());
+ bcam->gpu_dof.focus_distance = static_cast<float>(cam_sample.getFocusDistance());
+ bcam->gpu_dof.fstop = static_cast<float>(cam_sample.getFStop());
m_object = BKE_object_add_only_object(bmain, OB_CAMERA, m_object_name.c_str());
m_object->data = bcam;
diff --git a/source/blender/alembic/intern/abc_curves.cc b/source/blender/alembic/intern/abc_curves.cc
index 7e5ea3b1853..4ecb9d944f2 100644
--- a/source/blender/alembic/intern/abc_curves.cc
+++ b/source/blender/alembic/intern/abc_curves.cc
@@ -361,7 +361,7 @@ void read_curve_sample(Curve *cu, const ICurvesSchema &schema, const float time)
* object directly and create a new DerivedMesh from that. Also we might need to
* create new or delete existing NURBS in the curve.
*/
-DerivedMesh *AbcCurveReader::read_derivedmesh(DerivedMesh */*dm*/, const float time, int /*read_flag*/)
+DerivedMesh *AbcCurveReader::read_derivedmesh(DerivedMesh */*dm*/, const float time, int /*read_flag*/, const char **/*err_str*/)
{
ISampleSelector sample_sel(time);
const ICurvesSchema::Sample sample = m_curves_schema.getValue(sample_sel);
diff --git a/source/blender/alembic/intern/abc_curves.h b/source/blender/alembic/intern/abc_curves.h
index 979ee8af639..2757d179a47 100644
--- a/source/blender/alembic/intern/abc_curves.h
+++ b/source/blender/alembic/intern/abc_curves.h
@@ -56,7 +56,7 @@ public:
bool valid() const;
void readObjectData(Main *bmain, float time);
- DerivedMesh *read_derivedmesh(DerivedMesh *, const float time, int);
+ DerivedMesh *read_derivedmesh(DerivedMesh *, const float time, int read_flag, const char **err_str);
};
/* ************************************************************************** */
diff --git a/source/blender/alembic/intern/abc_customdata.h b/source/blender/alembic/intern/abc_customdata.h
index bc42e24eba1..9e671fde386 100644
--- a/source/blender/alembic/intern/abc_customdata.h
+++ b/source/blender/alembic/intern/abc_customdata.h
@@ -26,6 +26,7 @@
#define __ABC_CUSTOMDATA_H__
#include <Alembic/Abc/All.h>
+#include <Alembic/AbcGeom/All.h>
struct CustomData;
struct MLoop;
@@ -65,8 +66,8 @@ struct CDStreamConfig {
float weight;
float time;
- int index;
- int ceil_index;
+ Alembic::AbcGeom::index_t index;
+ Alembic::AbcGeom::index_t ceil_index;
CDStreamConfig()
: mloop(NULL)
diff --git a/source/blender/alembic/intern/abc_exporter.cc b/source/blender/alembic/intern/abc_exporter.cc
index d259721e192..ff8b0442ab6 100644
--- a/source/blender/alembic/intern/abc_exporter.cc
+++ b/source/blender/alembic/intern/abc_exporter.cc
@@ -176,13 +176,13 @@ void AbcExporter::getShutterSamples(double step, bool time_relative,
/* sample all frame */
if (shutter_open == 0.0 && shutter_close == 1.0) {
- for (double t = 0; t < 1.0; t += step) {
+ for (double t = 0.0; t < 1.0; t += step) {
samples.push_back((t + m_settings.frame_start) / time_factor);
}
}
else {
/* sample between shutter open & close */
- const int nsamples = std::max((1.0 / step) - 1.0, 1.0);
+ const int nsamples = static_cast<int>(std::max((1.0 / step) - 1.0, 1.0));
const double time_inc = (shutter_close - shutter_open) / nsamples;
for (double t = shutter_open; t <= shutter_close; t += time_inc) {
@@ -217,7 +217,7 @@ void AbcExporter::getFrameSet(double step, std::set<double> &frames)
getShutterSamples(step, false, shutter_samples);
- for (int frame = m_settings.frame_start; frame <= m_settings.frame_end; ++frame) {
+ for (double frame = m_settings.frame_start; frame <= m_settings.frame_end; frame += 1.0) {
for (int j = 0, e = shutter_samples.size(); j < e; ++j) {
frames.insert(frame + shutter_samples[j]);
}
@@ -238,9 +238,9 @@ void AbcExporter::operator()(Main *bmain, float &progress, bool &was_canceled)
}
Scene *scene = m_scene;
- const int fps = FPS;
+ const double fps = FPS;
char buf[16];
- snprintf(buf, 15, "%d", fps);
+ snprintf(buf, 15, "%f", fps);
const std::string str_fps = buf;
Alembic::AbcCoreAbstract::MetaData md;
@@ -578,7 +578,7 @@ AbcTransformWriter *AbcExporter::getXForm(const std::string &name)
void AbcExporter::setCurrentFrame(Main *bmain, double t)
{
- m_scene->r.cfra = std::floor(t);
- m_scene->r.subframe = t - m_scene->r.cfra;
+ m_scene->r.cfra = static_cast<int>(t);
+ m_scene->r.subframe = static_cast<float>(t) - m_scene->r.cfra;
BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, m_scene, m_scene->lay);
}
diff --git a/source/blender/alembic/intern/abc_mesh.cc b/source/blender/alembic/intern/abc_mesh.cc
index 5b282e3c5bb..bdd75f93189 100644
--- a/source/blender/alembic/intern/abc_mesh.cc
+++ b/source/blender/alembic/intern/abc_mesh.cc
@@ -868,53 +868,6 @@ ABC_INLINE void read_normals_params(AbcMeshData &abc_data,
}
}
-/* ************************************************************************** */
-
-AbcMeshReader::AbcMeshReader(const IObject &object, ImportSettings &settings)
- : AbcObjectReader(object, settings)
-{
- m_settings->read_flag |= MOD_MESHSEQ_READ_ALL;
-
- IPolyMesh ipoly_mesh(m_iobject, kWrapExisting);
- m_schema = ipoly_mesh.getSchema();
-
- get_min_max_time(m_iobject, m_schema, m_min_time, m_max_time);
-}
-
-bool AbcMeshReader::valid() const
-{
- return m_schema.valid();
-}
-
-void AbcMeshReader::readObjectData(Main *bmain, float time)
-{
- Mesh *mesh = BKE_mesh_add(bmain, m_data_name.c_str());
-
- m_object = BKE_object_add_only_object(bmain, OB_MESH, m_object_name.c_str());
- m_object->data = mesh;
-
- const ISampleSelector sample_sel(time);
-
- DerivedMesh *dm = CDDM_from_mesh(mesh);
- DerivedMesh *ndm = this->read_derivedmesh(dm, time, MOD_MESHSEQ_READ_ALL);
-
- if (ndm != dm) {
- dm->release(dm);
- }
-
- DM_to_mesh(ndm, mesh, m_object, CD_MASK_MESH, true);
-
- if (m_settings->validate_meshes) {
- BKE_mesh_validate(mesh, false, false);
- }
-
- readFaceSetsSample(bmain, mesh, 0, sample_sel);
-
- if (has_animations(m_schema, m_settings)) {
- addCacheModifier();
- }
-}
-
static bool check_smooth_poly_flag(DerivedMesh *dm)
{
MPoly *mpolys = dm->getPolyArray(dm);
@@ -962,6 +915,66 @@ static void *add_customdata_cb(void *user_data, const char *name, int data_type)
return cd_ptr;
}
+static void get_weight_and_index(CDStreamConfig &config,
+ Alembic::AbcCoreAbstract::TimeSamplingPtr time_sampling,
+ size_t samples_number)
+{
+ Alembic::AbcGeom::index_t i0, i1;
+
+ config.weight = get_weight_and_index(config.time,
+ time_sampling,
+ samples_number,
+ i0,
+ i1);
+
+ config.index = i0;
+ config.ceil_index = i1;
+}
+
+static void read_mesh_sample(ImportSettings *settings,
+ const IPolyMeshSchema &schema,
+ const ISampleSelector &selector,
+ CDStreamConfig &config,
+ bool &do_normals)
+{
+ const IPolyMeshSchema::Sample sample = schema.getValue(selector);
+
+ AbcMeshData abc_mesh_data;
+ abc_mesh_data.face_counts = sample.getFaceCounts();
+ abc_mesh_data.face_indices = sample.getFaceIndices();
+ abc_mesh_data.positions = sample.getPositions();
+
+ read_normals_params(abc_mesh_data, schema.getNormalsParam(), selector);
+
+ do_normals = (abc_mesh_data.face_normals != NULL);
+
+ get_weight_and_index(config, schema.getTimeSampling(), schema.getNumSamples());
+
+ if (config.weight != 0.0f) {
+ Alembic::AbcGeom::IPolyMeshSchema::Sample ceil_sample;
+ schema.get(ceil_sample, Alembic::Abc::ISampleSelector(config.ceil_index));
+ abc_mesh_data.ceil_positions = ceil_sample.getPositions();
+ }
+
+ if ((settings->read_flag & MOD_MESHSEQ_READ_UV) != 0) {
+ read_uvs_params(config, abc_mesh_data, schema.getUVsParam(), selector);
+ }
+
+ if ((settings->read_flag & MOD_MESHSEQ_READ_VERT) != 0) {
+ read_mverts(config, abc_mesh_data);
+ }
+
+ if ((settings->read_flag & MOD_MESHSEQ_READ_POLY) != 0) {
+ read_mpolys(config, abc_mesh_data);
+ }
+
+ if ((settings->read_flag & (MOD_MESHSEQ_READ_UV | MOD_MESHSEQ_READ_COLOR)) != 0) {
+ read_custom_data(schema.getArbGeomParams(), config, selector);
+ }
+
+ /* TODO: face sets */
+}
+
CDStreamConfig get_config(DerivedMesh *dm)
{
CDStreamConfig config;
@@ -978,7 +991,54 @@ CDStreamConfig get_config(DerivedMesh *dm)
return config;
}
-DerivedMesh *AbcMeshReader::read_derivedmesh(DerivedMesh *dm, const float time, int read_flag)
+/* ************************************************************************** */
+
+AbcMeshReader::AbcMeshReader(const IObject &object, ImportSettings &settings)
+ : AbcObjectReader(object, settings)
+{
+ m_settings->read_flag |= MOD_MESHSEQ_READ_ALL;
+
+ IPolyMesh ipoly_mesh(m_iobject, kWrapExisting);
+ m_schema = ipoly_mesh.getSchema();
+
+ get_min_max_time(m_iobject, m_schema, m_min_time, m_max_time);
+}
+
+bool AbcMeshReader::valid() const
+{
+ return m_schema.valid();
+}
+
+void AbcMeshReader::readObjectData(Main *bmain, float time)
+{
+ Mesh *mesh = BKE_mesh_add(bmain, m_data_name.c_str());
+
+ m_object = BKE_object_add_only_object(bmain, OB_MESH, m_object_name.c_str());
+ m_object->data = mesh;
+
+ const ISampleSelector sample_sel(time);
+
+ DerivedMesh *dm = CDDM_from_mesh(mesh);
+ DerivedMesh *ndm = this->read_derivedmesh(dm, time, MOD_MESHSEQ_READ_ALL, NULL);
+
+ if (ndm != dm) {
+ dm->release(dm);
+ }
+
+ DM_to_mesh(ndm, mesh, m_object, CD_MASK_MESH, true);
+
+ if (m_settings->validate_meshes) {
+ BKE_mesh_validate(mesh, false, false);
+ }
+
+ readFaceSetsSample(bmain, mesh, 0, sample_sel);
+
+ if (has_animations(m_schema, m_settings)) {
+ addCacheModifier();
+ }
+}
+
+DerivedMesh *AbcMeshReader::read_derivedmesh(DerivedMesh *dm, const float time, int read_flag, const char **err_str)
{
ISampleSelector sample_sel(time);
const IPolyMeshSchema::Sample sample = m_schema.getValue(sample_sel);
@@ -1003,6 +1063,21 @@ DerivedMesh *AbcMeshReader::read_derivedmesh(DerivedMesh *dm, const float time,
settings.read_flag |= MOD_MESHSEQ_READ_ALL;
}
+ else {
+ /* If the face count changed (e.g. by triangulation), only read points.
+ * This prevents crash from T49813.
+ * TODO(kevin): perhaps find a better way to do this? */
+ if (face_counts->size() != dm->getNumPolys(dm) ||
+ face_indices->size() != dm->getNumLoops(dm))
+ {
+ settings.read_flag = MOD_MESHSEQ_READ_VERT;
+
+ if (err_str) {
+ *err_str = "Topology has changed, perhaps by triangulating the"
+ " mesh. Only vertices will be read!";
+ }
+ }
+ }
CDStreamConfig config = get_config(new_dm ? new_dm : dm);
config.time = time;
@@ -1078,44 +1153,40 @@ void AbcMeshReader::readFaceSetsSample(Main *bmain, Mesh *mesh, size_t poly_star
utils::assign_materials(bmain, m_object, mat_map);
}
-static void get_weight_and_index(CDStreamConfig &config,
- Alembic::AbcCoreAbstract::TimeSamplingPtr time_sampling,
- size_t samples_number)
+/* ************************************************************************** */
+
+ABC_INLINE MEdge *find_edge(MEdge *edges, int totedge, int v1, int v2)
{
- Alembic::AbcGeom::index_t i0, i1;
+ for (int i = 0, e = totedge; i < e; ++i) {
+ MEdge &edge = edges[i];
- config.weight = get_weight_and_index(config.time,
- time_sampling,
- samples_number,
- i0,
- i1);
+ if (edge.v1 == v1 && edge.v2 == v2) {
+ return &edge;
+ }
+ }
- config.index = i0;
- config.ceil_index = i1;
+ return NULL;
}
-void read_mesh_sample(ImportSettings *settings,
- const IPolyMeshSchema &schema,
- const ISampleSelector &selector,
- CDStreamConfig &config,
- bool &do_normals)
+static void read_subd_sample(ImportSettings *settings,
+ const ISubDSchema &schema,
+ const ISampleSelector &selector,
+ CDStreamConfig &config)
{
- const IPolyMeshSchema::Sample sample = schema.getValue(selector);
+ const ISubDSchema::Sample sample = schema.getValue(selector);
AbcMeshData abc_mesh_data;
abc_mesh_data.face_counts = sample.getFaceCounts();
abc_mesh_data.face_indices = sample.getFaceIndices();
+ abc_mesh_data.vertex_normals = N3fArraySamplePtr();
+ abc_mesh_data.face_normals = N3fArraySamplePtr();
abc_mesh_data.positions = sample.getPositions();
- read_normals_params(abc_mesh_data, schema.getNormalsParam(), selector);
-
- do_normals = (abc_mesh_data.face_normals != NULL);
-
get_weight_and_index(config, schema.getTimeSampling(), schema.getNumSamples());
if (config.weight != 0.0f) {
- Alembic::AbcGeom::IPolyMeshSchema::Sample ceil_sample;
- schema.get(ceil_sample, Alembic::Abc::ISampleSelector(static_cast<Alembic::AbcCoreAbstract::index_t>(config.ceil_index)));
+ Alembic::AbcGeom::ISubDSchema::Sample ceil_sample;
+ schema.get(ceil_sample, Alembic::Abc::ISampleSelector(config.ceil_index));
abc_mesh_data.ceil_positions = ceil_sample.getPositions();
}
@@ -1140,19 +1211,6 @@ void read_mesh_sample(ImportSettings *settings,
/* ************************************************************************** */
-ABC_INLINE MEdge *find_edge(MEdge *edges, int totedge, int v1, int v2)
-{
- for (int i = 0, e = totedge; i < e; ++i) {
- MEdge &edge = edges[i];
-
- if (edge.v1 == v1 && edge.v2 == v2) {
- return &edge;
- }
- }
-
- return NULL;
-}
-
AbcSubDReader::AbcSubDReader(const IObject &object, ImportSettings &settings)
: AbcObjectReader(object, settings)
{
@@ -1177,7 +1235,7 @@ void AbcSubDReader::readObjectData(Main *bmain, float time)
m_object->data = mesh;
DerivedMesh *dm = CDDM_from_mesh(mesh);
- DerivedMesh *ndm = this->read_derivedmesh(dm, time, MOD_MESHSEQ_READ_ALL);
+ DerivedMesh *ndm = this->read_derivedmesh(dm, time, MOD_MESHSEQ_READ_ALL, NULL);
if (ndm != dm) {
dm->release(dm);
@@ -1216,48 +1274,7 @@ void AbcSubDReader::readObjectData(Main *bmain, float time)
}
}
-void read_subd_sample(ImportSettings *settings,
- const ISubDSchema &schema,
- const ISampleSelector &selector,
- CDStreamConfig &config)
-{
- const ISubDSchema::Sample sample = schema.getValue(selector);
-
- AbcMeshData abc_mesh_data;
- abc_mesh_data.face_counts = sample.getFaceCounts();
- abc_mesh_data.face_indices = sample.getFaceIndices();
- abc_mesh_data.vertex_normals = N3fArraySamplePtr();
- abc_mesh_data.face_normals = N3fArraySamplePtr();
- abc_mesh_data.positions = sample.getPositions();
-
- get_weight_and_index(config, schema.getTimeSampling(), schema.getNumSamples());
-
- if (config.weight != 0.0f) {
- Alembic::AbcGeom::ISubDSchema::Sample ceil_sample;
- schema.get(ceil_sample, Alembic::Abc::ISampleSelector(static_cast<Alembic::AbcCoreAbstract::index_t>(config.ceil_index)));
- abc_mesh_data.ceil_positions = ceil_sample.getPositions();
- }
-
- if ((settings->read_flag & MOD_MESHSEQ_READ_UV) != 0) {
- read_uvs_params(config, abc_mesh_data, schema.getUVsParam(), selector);
- }
-
- if ((settings->read_flag & MOD_MESHSEQ_READ_VERT) != 0) {
- read_mverts(config, abc_mesh_data);
- }
-
- if ((settings->read_flag & MOD_MESHSEQ_READ_POLY) != 0) {
- read_mpolys(config, abc_mesh_data);
- }
-
- if ((settings->read_flag & (MOD_MESHSEQ_READ_UV | MOD_MESHSEQ_READ_COLOR)) != 0) {
- read_custom_data(schema.getArbGeomParams(), config, selector);
- }
-
- /* TODO: face sets */
-}
-
-DerivedMesh *AbcSubDReader::read_derivedmesh(DerivedMesh *dm, const float time, int read_flag)
+DerivedMesh *AbcSubDReader::read_derivedmesh(DerivedMesh *dm, const float time, int read_flag, const char **err_str)
{
ISampleSelector sample_sel(time);
const ISubDSchema::Sample sample = m_schema.getValue(sample_sel);
@@ -1281,6 +1298,21 @@ DerivedMesh *AbcSubDReader::read_derivedmesh(DerivedMesh *dm, const float time,
settings.read_flag |= MOD_MESHSEQ_READ_ALL;
}
+ else {
+ /* If the face count changed (e.g. by triangulation), only read points.
+ * This prevents crash from T49813.
+ * TODO(kevin): perhaps find a better way to do this? */
+ if (face_counts->size() != dm->getNumPolys(dm) ||
+ face_indices->size() != dm->getNumLoops(dm))
+ {
+ settings.read_flag = MOD_MESHSEQ_READ_VERT;
+
+ if (err_str) {
+ *err_str = "Topology has changed, perhaps by triangulating the"
+ " mesh. Only vertices will be read!";
+ }
+ }
+ }
/* Only read point data when streaming meshes, unless we need to create new ones. */
CDStreamConfig config = get_config(new_dm ? new_dm : dm);
diff --git a/source/blender/alembic/intern/abc_mesh.h b/source/blender/alembic/intern/abc_mesh.h
index 66e6585a3d3..64a3109232c 100644
--- a/source/blender/alembic/intern/abc_mesh.h
+++ b/source/blender/alembic/intern/abc_mesh.h
@@ -102,19 +102,13 @@ public:
void readObjectData(Main *bmain, float time);
- DerivedMesh *read_derivedmesh(DerivedMesh *dm, const float time, int read_flag);
+ DerivedMesh *read_derivedmesh(DerivedMesh *dm, const float time, int read_flag, const char **err_str);
private:
void readFaceSetsSample(Main *bmain, Mesh *mesh, size_t poly_start,
const Alembic::AbcGeom::ISampleSelector &sample_sel);
};
-void read_mesh_sample(ImportSettings *settings,
- const Alembic::AbcGeom::IPolyMeshSchema &schema,
- const Alembic::AbcGeom::ISampleSelector &selector,
- CDStreamConfig &config,
- bool &do_normals);
-
/* ************************************************************************** */
class AbcSubDReader : public AbcObjectReader {
@@ -128,14 +122,9 @@ public:
bool valid() const;
void readObjectData(Main *bmain, float time);
- DerivedMesh *read_derivedmesh(DerivedMesh *dm, const float time, int read_flag);
+ DerivedMesh *read_derivedmesh(DerivedMesh *dm, const float time, int read_flag, const char **err_str);
};
-void read_subd_sample(ImportSettings *settings,
- const Alembic::AbcGeom::ISubDSchema &schema,
- const Alembic::AbcGeom::ISampleSelector &selector,
- CDStreamConfig &config);
-
/* ************************************************************************** */
void read_mverts(MVert *mverts,
diff --git a/source/blender/alembic/intern/abc_object.cc b/source/blender/alembic/intern/abc_object.cc
index 314b2568bed..9dfccdb8c7f 100644
--- a/source/blender/alembic/intern/abc_object.cc
+++ b/source/blender/alembic/intern/abc_object.cc
@@ -170,13 +170,13 @@ static Imath::M44d blend_matrices(const Imath::M44d &m0, const Imath::M44d &m1,
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
- mat0[i][j] = m0[i][j];
+ mat0[i][j] = static_cast<float>(m0[i][j]);
}
}
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
- mat1[i][j] = m1[i][j];
+ mat1[i][j] = static_cast<float>(m1[i][j]);
}
}
diff --git a/source/blender/alembic/intern/abc_object.h b/source/blender/alembic/intern/abc_object.h
index 7ff927b4d33..0f733e67d3f 100644
--- a/source/blender/alembic/intern/abc_object.h
+++ b/source/blender/alembic/intern/abc_object.h
@@ -76,7 +76,7 @@ private:
/* ************************************************************************** */
-class CacheFile;
+struct CacheFile;
struct ImportSettings {
bool do_convert_mat;
@@ -165,10 +165,11 @@ public:
virtual void readObjectData(Main *bmain, float time) = 0;
- virtual DerivedMesh *read_derivedmesh(DerivedMesh *dm, const float time, int read_flag)
+ virtual DerivedMesh *read_derivedmesh(DerivedMesh *dm, const float time, int read_flag, const char **err_str)
{
(void)time;
(void)read_flag;
+ (void)err_str;
return dm;
}
diff --git a/source/blender/alembic/intern/abc_points.cc b/source/blender/alembic/intern/abc_points.cc
index c16da621c77..4c78f3e83c7 100644
--- a/source/blender/alembic/intern/abc_points.cc
+++ b/source/blender/alembic/intern/abc_points.cc
@@ -156,7 +156,7 @@ void AbcPointsReader::readObjectData(Main *bmain, float time)
Mesh *mesh = BKE_mesh_add(bmain, m_data_name.c_str());
DerivedMesh *dm = CDDM_from_mesh(mesh);
- DerivedMesh *ndm = this->read_derivedmesh(dm, time, 0);
+ DerivedMesh *ndm = this->read_derivedmesh(dm, time, 0, NULL);
if (ndm != dm) {
dm->release(dm);
@@ -189,7 +189,8 @@ void read_points_sample(const IPointsSchema &schema,
N3fArraySamplePtr vnormals;
if (has_property(prop, "N")) {
- const IN3fArrayProperty &normals_prop = IN3fArrayProperty(prop, "N", time);
+ const Alembic::Util::uint32_t itime = static_cast<Alembic::Util::uint32_t>(time);
+ const IN3fArrayProperty &normals_prop = IN3fArrayProperty(prop, "N", itime);
if (normals_prop) {
vnormals = normals_prop.getValue(selector);
@@ -199,7 +200,7 @@ void read_points_sample(const IPointsSchema &schema,
read_mverts(config.mvert, positions, vnormals);
}
-DerivedMesh *AbcPointsReader::read_derivedmesh(DerivedMesh *dm, const float time, int /*read_flag*/)
+DerivedMesh *AbcPointsReader::read_derivedmesh(DerivedMesh *dm, const float time, int /*read_flag*/, const char **/*err_str*/)
{
ISampleSelector sample_sel(time);
const IPointsSchema::Sample sample = m_schema.getValue(sample_sel);
diff --git a/source/blender/alembic/intern/abc_points.h b/source/blender/alembic/intern/abc_points.h
index 54873eed346..cb68dbca4d5 100644
--- a/source/blender/alembic/intern/abc_points.h
+++ b/source/blender/alembic/intern/abc_points.h
@@ -28,7 +28,7 @@
#include "abc_object.h"
#include "abc_customdata.h"
-class ParticleSystem;
+struct ParticleSystem;
/* ************************************************************************** */
@@ -61,7 +61,7 @@ public:
void readObjectData(Main *bmain, float time);
- DerivedMesh *read_derivedmesh(DerivedMesh *dm, const float time, int read_flag);
+ DerivedMesh *read_derivedmesh(DerivedMesh *dm, const float time, int read_flag, const char **err_str);
};
void read_points_sample(const Alembic::AbcGeom::IPointsSchema &schema,
diff --git a/source/blender/alembic/intern/abc_util.cc b/source/blender/alembic/intern/abc_util.cc
index 979a72fcf4e..f8ce72d845d 100644
--- a/source/blender/alembic/intern/abc_util.cc
+++ b/source/blender/alembic/intern/abc_util.cc
@@ -215,7 +215,7 @@ void convert_matrix(const Imath::M44d &xform, Object *ob,
{
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
- r_mat[i][j] = xform[i][j];
+ r_mat[i][j] = static_cast<float>(xform[i][j]);
}
}
diff --git a/source/blender/alembic/intern/abc_util.h b/source/blender/alembic/intern/abc_util.h
index 2f423a9f8c5..60a96855d14 100644
--- a/source/blender/alembic/intern/abc_util.h
+++ b/source/blender/alembic/intern/abc_util.h
@@ -39,7 +39,7 @@ struct CacheReader {
using Alembic::Abc::chrono_t;
class AbcObjectReader;
-class ImportSettings;
+struct ImportSettings;
struct ID;
struct Object;
diff --git a/source/blender/alembic/intern/alembic_capi.cc b/source/blender/alembic/intern/alembic_capi.cc
index e690a255505..d8d017119b1 100644
--- a/source/blender/alembic/intern/alembic_capi.cc
+++ b/source/blender/alembic/intern/alembic_capi.cc
@@ -625,8 +625,8 @@ static void import_startjob(void *user_data, short *stop, short *do_update, floa
CFRA = SFRA;
}
else if (min_time < max_time) {
- SFRA = min_time * FPS;
- EFRA = max_time * FPS;
+ SFRA = static_cast<int>(min_time * FPS);
+ EFRA = static_cast<int>(max_time * FPS);
CFRA = SFRA;
}
}
@@ -816,7 +816,7 @@ DerivedMesh *ABC_read_mesh(CacheReader *reader,
return NULL;
}
- return abc_reader->read_derivedmesh(dm, time, read_flag);
+ return abc_reader->read_derivedmesh(dm, time, read_flag, err_str);
}
else if (ISubD::matches(header)) {
if (ob->type != OB_MESH) {
@@ -824,7 +824,7 @@ DerivedMesh *ABC_read_mesh(CacheReader *reader,
return NULL;
}
- return abc_reader->read_derivedmesh(dm, time, read_flag);
+ return abc_reader->read_derivedmesh(dm, time, read_flag, err_str);
}
else if (IPoints::matches(header)) {
if (ob->type != OB_MESH) {
@@ -832,7 +832,7 @@ DerivedMesh *ABC_read_mesh(CacheReader *reader,
return NULL;
}
- return abc_reader->read_derivedmesh(dm, time, read_flag);
+ return abc_reader->read_derivedmesh(dm, time, read_flag, err_str);
}
else if (ICurves::matches(header)) {
if (ob->type != OB_CURVE) {
@@ -840,7 +840,7 @@ DerivedMesh *ABC_read_mesh(CacheReader *reader,
return NULL;
}
- return abc_reader->read_derivedmesh(dm, time, read_flag);
+ return abc_reader->read_derivedmesh(dm, time, read_flag, err_str);
}
*err_str = "Unsupported object type: verify object path"; // or poke developer
diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h
index 00ea323f934..a67e903877a 100644
--- a/source/blender/blenkernel/BKE_animsys.h
+++ b/source/blender/blenkernel/BKE_animsys.h
@@ -73,7 +73,7 @@ struct AnimData *BKE_animdata_copy(struct AnimData *adt, const bool do_action);
bool BKE_animdata_copy_id(struct ID *id_to, struct ID *id_from, const bool do_action);
/* Copy AnimData Actions */
-void BKE_animdata_copy_id_action(struct ID *id);
+void BKE_animdata_copy_id_action(struct ID *id, const bool set_newid);
/* Merge copies of data from source AnimData block */
typedef enum eAnimData_MergeCopy_Modes {
diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h
index 855eb10976c..77ea7ecbefb 100644
--- a/source/blender/blenkernel/BKE_library.h
+++ b/source/blender/blenkernel/BKE_library.h
@@ -80,6 +80,7 @@ void id_us_plus(struct ID *id);
void id_us_min(struct ID *id);
void id_fake_user_set(struct ID *id);
void id_fake_user_clear(struct ID *id);
+void BKE_id_clear_newpoin(struct ID *id);
void BKE_id_make_local_generic(struct Main *bmain, struct ID *id, const bool id_in_mainlist, const bool lib_local);
bool id_make_local(struct Main *bmain, struct ID *id, const bool test, const bool force_local);
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index ae18f5289d4..1f937d837b4 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -230,7 +230,9 @@ static MPoly *dm_dupPolyArray(DerivedMesh *dm)
static int dm_getNumLoopTri(DerivedMesh *dm)
{
- return dm->looptris.num;
+ const int numlooptris = poly_to_tri_count(dm->getNumPolys(dm), dm->getNumLoops(dm));
+ BLI_assert(ELEM(dm->looptris.num, 0, numlooptris));
+ return numlooptris;
}
static CustomData *dm_getVertCData(DerivedMesh *dm)
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index a5abc6beff8..21279392392 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -308,17 +308,19 @@ bool BKE_animdata_copy_id(ID *id_to, ID *id_from, const bool do_action)
return true;
}
-void BKE_animdata_copy_id_action(ID *id)
+void BKE_animdata_copy_id_action(ID *id, const bool set_newid)
{
AnimData *adt = BKE_animdata_from_id(id);
if (adt) {
if (adt->action) {
id_us_min((ID *)adt->action);
- adt->action = BKE_action_copy(G.main, adt->action);
+ adt->action = set_newid ? ID_NEW_SET(adt->action, BKE_action_copy(G.main, adt->action)) :
+ BKE_action_copy(G.main, adt->action);
}
if (adt->tmpact) {
id_us_min((ID *)adt->tmpact);
- adt->tmpact = BKE_action_copy(G.main, adt->tmpact);
+ adt->tmpact = set_newid ? ID_NEW_SET(adt->tmpact, BKE_action_copy(G.main, adt->tmpact)) :
+ BKE_action_copy(G.main, adt->tmpact);
}
}
}
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index 8ef1fae1155..0d509ecea06 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -249,6 +249,9 @@ void BKE_brush_make_local(Main *bmain, Brush *brush, const bool lib_local)
brush_new->id.us = 0;
+ /* setting newid is mandatory for complex make_lib_local logic... */
+ ID_NEW_SET(brush, brush_new);
+
if (!lib_local) {
BKE_libblock_remap(bmain, brush, brush_new, ID_REMAP_SKIP_INDIRECT_USAGE);
}
diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c
index 85ce399b770..9cb553aa27b 100644
--- a/source/blender/blenkernel/intern/camera.c
+++ b/source/blender/blenkernel/intern/camera.c
@@ -252,7 +252,7 @@ void BKE_camera_params_from_view3d(CameraParams *params, const View3D *v3d, cons
}
else if (rv3d->persp == RV3D_ORTHO) {
/* orthographic view */
- int sensor_size = BKE_camera_sensor_size(params->sensor_fit, params->sensor_x, params->sensor_y);
+ float sensor_size = BKE_camera_sensor_size(params->sensor_fit, params->sensor_x, params->sensor_y);
params->clipend *= 0.5f; // otherwise too extreme low zbuffer quality
params->clipsta = -params->clipend;
@@ -337,6 +337,8 @@ void BKE_camera_params_compute_viewplane(CameraParams *params, int winx, int win
viewplane.ymin *= pixsize;
viewplane.ymax *= pixsize;
+ /* Used for rendering (offset by near-clip with perspective views), passed to RE_SetPixelSize.
+ * For viewport drawing 'RegionView3D.pixsize'. */
params->viewdx = pixsize;
params->viewdy = params->ycor * pixsize;
params->viewplane = viewplane;
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 50f8423bbff..7361645ba2c 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -1428,7 +1428,6 @@ static void scene_sort_groups(Main *bmain, Scene *sce)
/* test; are group objects all in this scene? */
for (ob = bmain->object.first; ob; ob = ob->id.next) {
ob->id.tag &= ~LIB_TAG_DOIT;
- ob->id.newid = NULL; /* newid abuse for GroupObject */
}
for (base = sce->base.first; base; base = base->next)
base->object->id.tag |= LIB_TAG_DOIT;
@@ -1459,6 +1458,11 @@ static void scene_sort_groups(Main *bmain, Scene *sce)
group->gobject = listb;
}
}
+
+ /* newid abused for GroupObject, cleanup. */
+ for (ob = bmain->object.first; ob; ob = ob->id.next) {
+ ob->id.newid = NULL;
+ }
}
static void dag_scene_tag_rebuild(Scene *sce)
diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c
index 05cf5f6d7bd..e7c0e69b1cb 100644
--- a/source/blender/blenkernel/intern/editderivedmesh.c
+++ b/source/blender/blenkernel/intern/editderivedmesh.c
@@ -621,10 +621,33 @@ static void emDM_recalcTessellation(DerivedMesh *UNUSED(dm))
/* do nothing */
}
-static void emDM_recalcLoopTri(DerivedMesh *UNUSED(dm))
+static void emDM_recalcLoopTri(DerivedMesh *dm)
{
- /* Nothing to do: emDM tessellation is known,
- * allocate and fill in with emDM_getLoopTriArray */
+ EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
+ BMLoop *(*looptris)[3] = bmdm->em->looptris;
+ MLoopTri *mlooptri;
+ const int tottri = bmdm->em->tottri;
+ int i;
+
+ DM_ensure_looptri_data(dm);
+ mlooptri = dm->looptris.array;
+
+ BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num);
+ BLI_assert(tottri == dm->looptris.num);
+
+ BM_mesh_elem_index_ensure(bmdm->em->bm, BM_FACE | BM_LOOP);
+
+ for (i = 0; i < tottri; i++) {
+ BMLoop **ltri = looptris[i];
+ MLoopTri *lt = &mlooptri[i];
+
+ ARRAY_SET_ITEMS(
+ lt->tri,
+ BM_elem_index_get(ltri[0]),
+ BM_elem_index_get(ltri[1]),
+ BM_elem_index_get(ltri[2]));
+ lt->poly = BM_elem_index_get(ltri[0]->f);
+ }
}
static const MLoopTri *emDM_getLoopTriArray(DerivedMesh *dm)
@@ -633,32 +656,9 @@ static const MLoopTri *emDM_getLoopTriArray(DerivedMesh *dm)
BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num);
}
else {
- EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
- BMLoop *(*looptris)[3] = bmdm->em->looptris;
- MLoopTri *mlooptri;
- const int tottri = bmdm->em->tottri;
- int i;
-
- DM_ensure_looptri_data(dm);
- mlooptri = dm->looptris.array;
-
- BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num);
- BLI_assert(tottri == dm->looptris.num);
-
- BM_mesh_elem_index_ensure(bmdm->em->bm, BM_FACE | BM_LOOP);
-
- for (i = 0; i < tottri; i++) {
- BMLoop **ltri = looptris[i];
- MLoopTri *lt = &mlooptri[i];
-
- ARRAY_SET_ITEMS(
- lt->tri,
- BM_elem_index_get(ltri[0]),
- BM_elem_index_get(ltri[1]),
- BM_elem_index_get(ltri[2]));
- lt->poly = BM_elem_index_get(ltri[0]->f);
- }
+ dm->recalcLoopTri(dm);
}
+
return dm->looptris.array;
}
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index 2242113b79b..cd2eac078cf 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -382,7 +382,8 @@ bGPDpalette *BKE_gpencil_palette_addnew(bGPdata *gpd, const char *name, bool set
sizeof(palette->info));
/* make this one the active one */
- if (setactive) {
+ /* NOTE: Always make this active if there's nothing else yet (T50123) */
+ if ((setactive) || (gpd->palettes.first == gpd->palettes.last)) {
BKE_gpencil_palette_setactive(gpd, palette);
}
@@ -1263,7 +1264,11 @@ void BKE_gpencil_palettecolor_changename(bGPdata *gpd, char *oldname, const char
bGPDlayer *gpl;
bGPDframe *gpf;
bGPDstroke *gps;
-
+
+ /* Sanity checks (gpd may not be set in the RNA pointers sometimes) */
+ if (ELEM(NULL, gpd, oldname, newname))
+ return;
+
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
for (gps = gpf->strokes.first; gps; gps = gps->next) {
@@ -1282,7 +1287,11 @@ void BKE_gpencil_palettecolor_delete_strokes(struct bGPdata *gpd, char *name)
bGPDlayer *gpl;
bGPDframe *gpf;
bGPDstroke *gps, *gpsn;
-
+
+ /* Sanity checks (gpd may not be set in the RNA pointers sometimes) */
+ if (ELEM(NULL, gpd, name))
+ return;
+
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
for (gps = gpf->strokes.first; gps; gps = gpsn) {
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index c9bad2160ff..a2d94ccc478 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -436,7 +436,6 @@ static void copy_image_packedfiles(ListBase *lb_dst, const ListBase *lb_src)
Image *BKE_image_copy(Main *bmain, Image *ima)
{
Image *nima = image_alloc(bmain, ima->id.name + 2, ima->source, ima->type);
- ima->id.newid = &nima->id;
BLI_strncpy(nima->name, ima->name, sizeof(ima->name));
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index 3411eae22e1..31c10c843da 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -263,6 +263,14 @@ void id_fake_user_clear(ID *id)
}
}
+void BKE_id_clear_newpoin(ID *id)
+{
+ if (id->newid) {
+ id->newid->tag &= ~LIB_TAG_NEW;
+ }
+ id->newid = NULL;
+}
+
static int id_expand_local_callback(
void *UNUSED(user_data), struct ID *id_self, struct ID **id_pointer, int UNUSED(cd_flag))
{
@@ -326,6 +334,17 @@ void BKE_id_make_local_generic(Main *bmain, ID *id, const bool id_in_mainlist, c
if (id_copy(bmain, id, &id_new, false)) {
id_new->us = 0;
+ /* setting newid is mandatory for complex make_lib_local logic... */
+ ID_NEW_SET(id, id_new);
+ Key *key = BKE_key_from_id(id), *key_new = BKE_key_from_id(id);
+ if (key && key_new) {
+ ID_NEW_SET(key, key_new);
+ }
+ bNodeTree *ntree = ntreeFromID(id), *ntree_new = ntreeFromID(id_new);
+ if (ntree && ntree_new) {
+ ID_NEW_SET(ntree, ntree_new);
+ }
+
if (!lib_local) {
BKE_libblock_remap(bmain, id, id_new, ID_REMAP_SKIP_INDIRECT_USAGE);
}
@@ -337,6 +356,8 @@ void BKE_id_make_local_generic(Main *bmain, ID *id, const bool id_in_mainlist, c
/**
* Calls the appropriate make_local method for the block, unless test is set.
*
+ * \note Always set ID->newid pointer in case it gets duplicated...
+ *
* \param lib_local Special flag used when making a whole library's content local, it needs specific handling.
*
* \return true if the block can be made local.
@@ -561,6 +582,7 @@ bool id_copy(Main *bmain, ID *id, ID **newid, bool test)
return false;
}
+/** Does *not* set ID->newid pointer. */
bool id_single_user(bContext *C, ID *id, PointerRNA *ptr, PropertyRNA *prop)
{
ID *newid = NULL;
@@ -571,11 +593,11 @@ bool id_single_user(bContext *C, ID *id, PointerRNA *ptr, PropertyRNA *prop)
if (RNA_property_editable(ptr, prop)) {
if (id_copy(CTX_data_main(C), id, &newid, false) && newid) {
/* copy animation actions too */
- BKE_animdata_copy_id_action(id);
+ BKE_animdata_copy_id_action(id, false);
/* us is 1 by convention, but RNA_property_pointer_set
* will also increment it, so set it to zero */
newid->us = 0;
-
+
/* assign copy */
RNA_id_pointer_create(newid, &idptr);
RNA_property_pointer_set(ptr, prop, idptr);
@@ -1120,9 +1142,6 @@ void *BKE_libblock_copy(Main *bmain, ID *id)
memcpy(cpn + sizeof(ID), cp + sizeof(ID), idn_len - sizeof(ID));
}
-
- id->newid = idn;
- idn->tag |= LIB_TAG_NEW;
BKE_libblock_copy_data(idn, id, false);
@@ -1147,8 +1166,6 @@ void *BKE_libblock_copy_nolib(ID *id, const bool do_action)
memcpy(cpn + sizeof(ID), cp + sizeof(ID), idn_len - sizeof(ID));
}
- id->newid = idn;
- idn->tag |= LIB_TAG_NEW;
idn->us = 1;
BKE_libblock_copy_data(idn, id, do_action);
@@ -1662,7 +1679,6 @@ void BKE_library_make_local(
const bool do_skip = (id && !BKE_idcode_is_linkable(GS(id->name)));
for (; id; id = id->next) {
- id->newid = NULL;
id->tag &= ~LIB_TAG_DOIT;
if (id->lib == NULL) {
@@ -1862,6 +1878,7 @@ void BKE_library_make_local(
}
}
+ BKE_main_id_clear_newpoins(bmain);
BLI_memarena_free(linklist_mem);
}
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 4489ca907f6..c6666ec5ced 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -1215,6 +1215,9 @@ void BKE_object_make_local_ex(Main *bmain, Object *ob, const bool lib_local, con
ob_new->id.us = 0;
ob_new->proxy = ob_new->proxy_from = ob_new->proxy_group = NULL;
+ /* setting newid is mandatory for complex make_lib_local logic... */
+ ID_NEW_SET(ob, ob_new);
+
if (!lib_local) {
BKE_libblock_remap(bmain, ob, ob_new, ID_REMAP_SKIP_INDIRECT_USAGE);
}
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index ebf9f017731..628222ed306 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -225,8 +225,8 @@ RigidBodyCon *BKE_rigidbody_copy_constraint(Object *ob)
/* preserve relationships between constraints and rigid bodies after duplication */
void BKE_rigidbody_relink_constraint(RigidBodyCon *rbc)
{
- ID_NEW(rbc->ob1);
- ID_NEW(rbc->ob2);
+ ID_NEW_REMAP(rbc->ob1);
+ ID_NEW_REMAP(rbc->ob2);
}
/* ************************************** */
diff --git a/source/blender/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c
index c7f406089d9..fa221348932 100644
--- a/source/blender/blenkernel/intern/sca.c
+++ b/source/blender/blenkernel/intern/sca.c
@@ -602,41 +602,41 @@ void set_sca_new_poins_ob(Object *ob)
if (act->flag & ACT_NEW) {
if (act->type==ACT_EDIT_OBJECT) {
bEditObjectActuator *eoa= act->data;
- ID_NEW(eoa->ob);
+ ID_NEW_REMAP(eoa->ob);
}
else if (act->type==ACT_SCENE) {
bSceneActuator *sca= act->data;
- ID_NEW(sca->camera);
+ ID_NEW_REMAP(sca->camera);
}
else if (act->type==ACT_CAMERA) {
bCameraActuator *ca= act->data;
- ID_NEW(ca->ob);
+ ID_NEW_REMAP(ca->ob);
}
else if (act->type==ACT_OBJECT) {
bObjectActuator *oa= act->data;
- ID_NEW(oa->reference);
+ ID_NEW_REMAP(oa->reference);
}
else if (act->type==ACT_MESSAGE) {
bMessageActuator *ma= act->data;
- ID_NEW(ma->toObject);
+ ID_NEW_REMAP(ma->toObject);
}
else if (act->type==ACT_PARENT) {
bParentActuator *para = act->data;
- ID_NEW(para->ob);
+ ID_NEW_REMAP(para->ob);
}
else if (act->type==ACT_ARMATURE) {
bArmatureActuator *aa = act->data;
- ID_NEW(aa->target);
- ID_NEW(aa->subtarget);
+ ID_NEW_REMAP(aa->target);
+ ID_NEW_REMAP(aa->subtarget);
}
else if (act->type==ACT_PROPERTY) {
bPropertyActuator *pa= act->data;
- ID_NEW(pa->ob);
+ ID_NEW_REMAP(pa->ob);
}
else if (act->type==ACT_STEERING) {
bSteeringActuator *sta = act->data;
- ID_NEW(sta->navmesh);
- ID_NEW(sta->target);
+ ID_NEW_REMAP(sta->navmesh);
+ ID_NEW_REMAP(sta->target);
}
}
act= act->next;
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index a440168c24b..ae1217ddf69 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -186,8 +186,6 @@ Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type)
scen = BKE_libblock_copy(bmain, &sce->id);
BLI_duplicatelist(&(scen->base), &(sce->base));
- BKE_main_id_clear_newpoins(bmain);
-
id_us_plus((ID *)scen->world);
id_us_plus((ID *)scen->set);
/* id_us_plus((ID *)scen->gm.dome.warptext); */ /* XXX Not refcounted? see readfile.c */
@@ -225,7 +223,7 @@ Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type)
}
/* copy action and remove animation used by sequencer */
- BKE_animdata_copy_id_action(&scen->id);
+ BKE_animdata_copy_id_action(&scen->id, false);
if (type != SCE_COPY_FULL)
remove_sequencer_fcurves(scen);
@@ -318,7 +316,7 @@ Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type)
/* camera */
if (type == SCE_COPY_LINK_DATA || type == SCE_COPY_FULL) {
- ID_NEW(scen->camera);
+ ID_NEW_REMAP(scen->camera);
}
/* before scene copy */
@@ -329,7 +327,7 @@ Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type)
if (scen->world) {
id_us_plus((ID *)scen->world);
scen->world = BKE_world_copy(bmain, scen->world);
- BKE_animdata_copy_id_action((ID *)scen->world);
+ BKE_animdata_copy_id_action((ID *)scen->world, false);
}
if (sce->ed) {
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index 65d751a8a72..1d2f5aee440 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -320,7 +320,8 @@ void BKE_sequencer_free_clipboard(void)
/* Manage pointers in the clipboard.
* note that these pointers should _never_ be access in the sequencer,
* they are only for storage while in the clipboard
- * notice 'newid' is used for temp pointer storage here, validate on access.
+ * notice 'newid' is used for temp pointer storage here, validate on access (this is safe usage,
+ * since those datablocks are fully out of Main lists).
*/
#define ID_PT (*id_pt)
static void seqclipboard_ptr_free(ID **id_pt)
diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c
index 6d57c5f09e8..c4665c40ec4 100644
--- a/source/blender/blenkernel/intern/subsurf_ccg.c
+++ b/source/blender/blenkernel/intern/subsurf_ccg.c
@@ -4474,46 +4474,46 @@ static void ccgDM_recalcTessellation(DerivedMesh *UNUSED(dm))
/* Nothing to do: CCG handles creating its own tessfaces */
}
-static void ccgDM_recalcLoopTri(DerivedMesh *UNUSED(dm))
+static void ccgDM_recalcLoopTri(DerivedMesh *dm)
{
- /* Nothing to do: CCG tessellation is known,
- * allocate and fill in with ccgDM_getLoopTriArray */
+ BLI_rw_mutex_lock(&loops_cache_rwlock, THREAD_LOCK_WRITE);
+ MLoopTri *mlooptri;
+ const int tottri = dm->numPolyData * 2;
+ int i, poly_index;
+
+ DM_ensure_looptri_data(dm);
+ mlooptri = dm->looptris.array;
+
+ BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num);
+ BLI_assert(tottri == dm->looptris.num);
+
+ for (i = 0, poly_index = 0; i < tottri; i += 2, poly_index += 1) {
+ MLoopTri *lt;
+ lt = &mlooptri[i];
+ /* quad is (0, 3, 2, 1) */
+ lt->tri[0] = (poly_index * 4) + 0;
+ lt->tri[1] = (poly_index * 4) + 2;
+ lt->tri[2] = (poly_index * 4) + 3;
+ lt->poly = poly_index;
+
+ lt = &mlooptri[i + 1];
+ lt->tri[0] = (poly_index * 4) + 0;
+ lt->tri[1] = (poly_index * 4) + 1;
+ lt->tri[2] = (poly_index * 4) + 2;
+ lt->poly = poly_index;
+ }
+ BLI_rw_mutex_unlock(&loops_cache_rwlock);
}
static const MLoopTri *ccgDM_getLoopTriArray(DerivedMesh *dm)
{
- BLI_rw_mutex_lock(&loops_cache_rwlock, THREAD_LOCK_WRITE);
if (dm->looptris.array) {
BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num);
}
else {
- MLoopTri *mlooptri;
- const int tottri = dm->numPolyData * 2;
- int i, poly_index;
-
- DM_ensure_looptri_data(dm);
- mlooptri = dm->looptris.array;
-
- BLI_assert(poly_to_tri_count(dm->numPolyData, dm->numLoopData) == dm->looptris.num);
- BLI_assert(tottri == dm->looptris.num);
-
- for (i = 0, poly_index = 0; i < tottri; i += 2, poly_index += 1) {
- MLoopTri *lt;
- lt = &mlooptri[i];
- /* quad is (0, 3, 2, 1) */
- lt->tri[0] = (poly_index * 4) + 0;
- lt->tri[1] = (poly_index * 4) + 2;
- lt->tri[2] = (poly_index * 4) + 3;
- lt->poly = poly_index;
-
- lt = &mlooptri[i + 1];
- lt->tri[0] = (poly_index * 4) + 0;
- lt->tri[1] = (poly_index * 4) + 1;
- lt->tri[2] = (poly_index * 4) + 2;
- lt->poly = poly_index;
- }
+ dm->recalcLoopTri(dm);
}
- BLI_rw_mutex_unlock(&loops_cache_rwlock);
+
return dm->looptris.array;
}
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c
index 0790d65345d..38947e139ff 100644
--- a/source/blender/blenlib/intern/math_geom.c
+++ b/source/blender/blenlib/intern/math_geom.c
@@ -3919,7 +3919,7 @@ void lookat_m4(float mat[4][4], float vx, float vy, float vz, float px, float py
unit_m4(mat1);
- axis_angle_to_mat3_single(mat, 'Z', -twist);
+ axis_angle_to_mat4_single(mat, 'Z', -twist);
dx = px - vx;
dy = py - vy;
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 98c8a260993..af73410728b 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -8102,6 +8102,7 @@ static BHead *read_libblock(FileData *fd, Main *main, BHead *bhead, const short
id->lib = main->curlib;
id->us = ID_FAKE_USERS(id);
id->icon_id = 0;
+ id->newid = NULL; /* Needed because .blend may have been saved with crap value here... */
/* this case cannot be direct_linked: it's just the ID part */
if (bhead->code == ID_ID) {
diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c
index 2c60de0f732..8bb6ebf6115 100644
--- a/source/blender/blenloader/intern/versioning_270.c
+++ b/source/blender/blenloader/intern/versioning_270.c
@@ -46,6 +46,7 @@
#include "DNA_screen_types.h"
#include "DNA_object_force.h"
#include "DNA_object_types.h"
+#include "DNA_mask_types.h"
#include "DNA_mesh_types.h"
#include "DNA_modifier_types.h"
#include "DNA_particle_types.h"
@@ -60,6 +61,7 @@
#include "BKE_colortools.h"
#include "BKE_library.h"
#include "BKE_main.h"
+#include "BKE_mask.h"
#include "BKE_modifier.h"
#include "BKE_node.h"
#include "BKE_scene.h"
@@ -1490,4 +1492,21 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
br->fill_threshold /= sqrt_3;
}
}
+
+ /* To be added to next subversion bump! */
+ {
+ /* Mask primitive adding code was not initializing correctly id_type of its points' parent. */
+ for (Mask *mask = main->mask.first; mask; mask = mask->id.next) {
+ for (MaskLayer *mlayer = mask->masklayers.first; mlayer; mlayer = mlayer->next) {
+ for (MaskSpline *mspline = mlayer->splines.first; mspline; mspline = mspline->next) {
+ int i = 0;
+ for (MaskSplinePoint *mspoint = mspline->points; i < mspline->tot_point; mspoint++, i++) {
+ if (mspoint->parent.id_type == 0) {
+ BKE_mask_parent_init(&mspoint->parent);
+ }
+ }
+ }
+ }
+ }
+ }
}
diff --git a/source/blender/collada/ArmatureImporter.cpp b/source/blender/collada/ArmatureImporter.cpp
index ae43c0a69d2..17334ca326c 100644
--- a/source/blender/collada/ArmatureImporter.cpp
+++ b/source/blender/collada/ArmatureImporter.cpp
@@ -169,6 +169,7 @@ int ArmatureImporter::create_bone(SkinInfo *skin, COLLADAFW::Node *node, EditBon
float angle;
mat4_to_loc_rot_size(loc, rot, size, mat);
mat3_to_vec_roll(rot, NULL, &angle);
+ bone->roll = angle;
}
copy_v3_v3(bone->head, mat[3]);
add_v3_v3v3(bone->tail, bone->head, tail); //tail must be non zero
diff --git a/source/blender/editors/gpencil/gpencil_brush.c b/source/blender/editors/gpencil/gpencil_brush.c
index 8576cbca239..ec5a42c23a5 100644
--- a/source/blender/editors/gpencil/gpencil_brush.c
+++ b/source/blender/editors/gpencil/gpencil_brush.c
@@ -1798,6 +1798,12 @@ static int gpsculpt_brush_modal(bContext *C, wmOperator *op, const wmEvent *even
case UPARROWKEY:
case DOWNARROWKEY:
return OPERATOR_PASS_THROUGH;
+
+ /* Camera/View Manipulations - Allowed */
+ /* (See rationale in gpencil_paint.c -> gpencil_draw_modal()) */
+ case PAD0: case PAD1: case PAD2: case PAD3: case PAD4:
+ case PAD5: case PAD6: case PAD7: case PAD8: case PAD9:
+ return OPERATOR_PASS_THROUGH;
/* Unhandled event */
default:
diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c
index 8073b13ba10..76e85f20c36 100644
--- a/source/blender/editors/gpencil/gpencil_utils.c
+++ b/source/blender/editors/gpencil/gpencil_utils.c
@@ -915,7 +915,7 @@ void gp_subdivide_stroke(bGPDstroke *gps, const int new_totpoints)
/**
* Add randomness to stroke
* \param gps Stroke data
- * \param brsuh Brush data
+ * \param brush Brush data
*/
void gp_randomize_stroke(bGPDstroke *gps, bGPDbrush *brush)
{
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index fd5351394c3..9fbce7dd203 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -181,7 +181,7 @@ enum {
UI_BUT_HAS_SEP_CHAR = (1 << 27), /* but->str contains UI_SEP_CHAR, used for key shortcuts */
UI_BUT_UPDATE_DELAY = (1 << 28), /* don't run updates while dragging (needed in rare cases). */
UI_BUT_TEXTEDIT_UPDATE = (1 << 29), /* when widget is in textedit mode, update value on each char stroke */
- UI_BUT_SEARCH_UNLINK = (1 << 30), /* show unlink for search button */
+ UI_BUT_VALUE_CLEAR = (1 << 30), /* show 'x' icon to clear/unlink value of text or search button */
};
#define UI_PANEL_WIDTH 340
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 6bba35e821f..a913421d12c 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -1987,22 +1987,29 @@ uiBut *ui_but_drag_multi_edit_get(uiBut *but)
/** \name Check to show extra icons
*
* Extra icons are shown on the right hand side of buttons.
+ * This could (should!) definitely become more generic, but for now this is good enough.
* \{ */
+static bool ui_but_icon_extra_is_visible_text_clear(const uiBut *but)
+{
+ BLI_assert(but->type == UI_BTYPE_TEXT);
+ return ((but->flag & UI_BUT_VALUE_CLEAR) && but->drawstr && but->drawstr[0]);
+}
+
static bool ui_but_icon_extra_is_visible_search_unlink(const uiBut *but)
{
BLI_assert(but->type == UI_BTYPE_SEARCH_MENU);
return ((but->editstr == NULL) &&
(but->drawstr[0] != '\0') &&
- (but->flag & UI_BUT_SEARCH_UNLINK));
+ (but->flag & UI_BUT_VALUE_CLEAR));
}
-static bool ui_but_icon_extra_is_visible_eyedropper(uiBut *but)
+static bool ui_but_icon_extra_is_visible_search_eyedropper(uiBut *but)
{
StructRNA *type;
short idcode;
- BLI_assert(but->type == UI_BTYPE_SEARCH_MENU && (but->flag & UI_BUT_SEARCH_UNLINK));
+ BLI_assert(but->type == UI_BTYPE_SEARCH_MENU && (but->flag & UI_BUT_VALUE_CLEAR));
if (but->rnaprop == NULL) {
return false;
@@ -2011,21 +2018,31 @@ static bool ui_but_icon_extra_is_visible_eyedropper(uiBut *but)
type = RNA_property_pointer_type(&but->rnapoin, but->rnaprop);
idcode = RNA_type_to_ID_code(type);
-
return ((but->editstr == NULL) &&
(idcode == ID_OB || OB_DATA_SUPPORT_ID(idcode)));
}
uiButExtraIconType ui_but_icon_extra_get(uiBut *but)
{
- if ((but->flag & UI_BUT_SEARCH_UNLINK) == 0) {
- /* pass */
- }
- else if (ui_but_icon_extra_is_visible_search_unlink(but)) {
- return UI_BUT_ICONEXTRA_UNLINK;
- }
- else if (ui_but_icon_extra_is_visible_eyedropper(but)) {
- return UI_BUT_ICONEXTRA_EYEDROPPER;
+ switch (but->type) {
+ case UI_BTYPE_TEXT:
+ if (ui_but_icon_extra_is_visible_text_clear(but)) {
+ return UI_BUT_ICONEXTRA_CLEAR;
+ }
+ break;
+ case UI_BTYPE_SEARCH_MENU:
+ if ((but->flag & UI_BUT_VALUE_CLEAR) == 0) {
+ /* pass */
+ }
+ else if (ui_but_icon_extra_is_visible_search_unlink(but)) {
+ return UI_BUT_ICONEXTRA_CLEAR;
+ }
+ else if (ui_but_icon_extra_is_visible_search_eyedropper(but)) {
+ return UI_BUT_ICONEXTRA_EYEDROPPER;
+ }
+ break;
+ default:
+ break;
}
return UI_BUT_ICONEXTRA_NONE;
diff --git a/source/blender/editors/interface/interface_eyedropper.c b/source/blender/editors/interface/interface_eyedropper.c
index d7f06b7db13..5f7a018e4c2 100644
--- a/source/blender/editors/interface/interface_eyedropper.c
+++ b/source/blender/editors/interface/interface_eyedropper.c
@@ -748,7 +748,7 @@ static int datadropper_poll(bContext *C)
if ((CTX_wm_window(C) != NULL) &&
(but = UI_context_active_but_prop_get(C, &ptr, &prop, &index_dummy)) &&
(but->type == UI_BTYPE_SEARCH_MENU) &&
- (but->flag & UI_BUT_SEARCH_UNLINK))
+ (but->flag & UI_BUT_VALUE_CLEAR))
{
if (prop && RNA_property_type(prop) == PROP_POINTER) {
StructRNA *type = RNA_property_pointer_type(&ptr, prop);
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index fc511d61e2b..33f1d5e93cb 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -2563,6 +2563,18 @@ void ui_but_text_password_hide(char password_str[UI_MAX_PASSWORD_STR], uiBut *bu
}
}
+static void ui_but_text_clear(bContext *C, uiBut *but, uiHandleButtonData *data)
+{
+ /* most likely NULL, but let's check, and give it temp zero string */
+ if (!data->str) {
+ data->str = MEM_callocN(1, "temp str");
+ }
+ data->str[0] = 0;
+
+ ui_apply_but_TEX(C, but, data);
+ button_activate_state(C, but, BUTTON_STATE_EXIT);
+}
+
/* ************* in-button text selection/editing ************* */
@@ -3842,6 +3854,21 @@ static int ui_do_but_KEYEVT(
return WM_UI_HANDLER_CONTINUE;
}
+static bool ui_but_is_mouse_over_icon_extra(const ARegion *region, uiBut *but, const int mouse_xy[2])
+{
+ int x = mouse_xy[0], y = mouse_xy[1];
+ rcti icon_rect;
+
+ BLI_assert(ui_but_icon_extra_get(but) != UI_BUT_ICONEXTRA_NONE);
+
+ ui_window_to_block(region, but->block, &x, &y);
+
+ BLI_rcti_rctf_copy(&icon_rect, &but->rect);
+ icon_rect.xmin = icon_rect.xmax - (BLI_rcti_size_y(&icon_rect));
+
+ return BLI_rcti_isect_pt(&icon_rect, x, y);
+}
+
static int ui_do_but_TEX(
bContext *C, uiBlock *block, uiBut *but,
uiHandleButtonData *data, const wmEvent *event)
@@ -3855,7 +3882,14 @@ static int ui_do_but_TEX(
/* pass */
}
else {
- button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
+ const bool has_icon_extra = ui_but_icon_extra_get(but) == UI_BUT_ICONEXTRA_CLEAR;
+
+ if (has_icon_extra && ui_but_is_mouse_over_icon_extra(data->region, but, &event->x)) {
+ ui_but_text_clear(C, but, data);
+ }
+ else {
+ button_activate_state(C, but, BUTTON_STATE_TEXT_EDITING);
+ }
return WM_UI_HANDLER_BREAK;
}
}
@@ -3876,47 +3910,29 @@ static int ui_do_but_SEARCH_UNLINK(
bContext *C, uiBlock *block, uiBut *but,
uiHandleButtonData *data, const wmEvent *event)
{
- uiButExtraIconType extra_icon_type;
+ const uiButExtraIconType extra_icon_type = ui_but_icon_extra_get(but);
+ const bool has_icon_extra = (extra_icon_type != UI_BUT_ICONEXTRA_NONE);
/* unlink icon is on right */
if ((ELEM(event->type, LEFTMOUSE, EVT_BUT_OPEN, PADENTER, RETKEY)) &&
- ((extra_icon_type = ui_but_icon_extra_get(but)) != UI_BUT_ICONEXTRA_NONE))
+ (has_icon_extra == true) &&
+ (ui_but_is_mouse_over_icon_extra(data->region, but, &event->x) == true))
{
- ARegion *ar = data->region;
- rcti rect;
- int x = event->x, y = event->y;
-
- ui_window_to_block(ar, but->block, &x, &y);
-
- BLI_rcti_rctf_copy(&rect, &but->rect);
-
- rect.xmin = rect.xmax - (BLI_rcti_size_y(&rect));
- /* handle click on unlink/eyedropper icon */
- if (BLI_rcti_isect_pt(&rect, x, y)) {
- /* doing this on KM_PRESS calls eyedropper after clicking unlink icon */
- if (event->val == KM_RELEASE) {
- /* unlink */
- if (extra_icon_type == UI_BUT_ICONEXTRA_UNLINK) {
- /* most likely NULL, but let's check, and give it temp zero string */
- if (data->str == NULL) {
- data->str = MEM_callocN(1, "temp str");
- }
- data->str[0] = 0;
-
- ui_apply_but_TEX(C, but, data);
- button_activate_state(C, but, BUTTON_STATE_EXIT);
- }
- /* eyedropper */
- else if (extra_icon_type == UI_BUT_ICONEXTRA_EYEDROPPER) {
- WM_operator_name_call(C, "UI_OT_eyedropper_id", WM_OP_INVOKE_DEFAULT, NULL);
- }
- else {
- BLI_assert(0);
- }
+ /* doing this on KM_PRESS calls eyedropper after clicking unlink icon */
+ if (event->val == KM_RELEASE) {
+ /* unlink */
+ if (extra_icon_type == UI_BUT_ICONEXTRA_CLEAR) {
+ ui_but_text_clear(C, but, data);
+ }
+ /* eyedropper */
+ else if (extra_icon_type == UI_BUT_ICONEXTRA_EYEDROPPER) {
+ WM_operator_name_call(C, "UI_OT_eyedropper_id", WM_OP_INVOKE_DEFAULT, NULL);
+ }
+ else {
+ BLI_assert(0);
}
-
- return WM_UI_HANDLER_BREAK;
}
+ return WM_UI_HANDLER_BREAK;
}
return ui_do_but_TEX(C, block, but, data, event);
}
@@ -7091,7 +7107,7 @@ static int ui_do_button(bContext *C, uiBlock *block, uiBut *but, const wmEvent *
case UI_BTYPE_TEXT:
case UI_BTYPE_SEARCH_MENU:
if ((but->type == UI_BTYPE_SEARCH_MENU) &&
- (but->flag & UI_BUT_SEARCH_UNLINK))
+ (but->flag & UI_BUT_VALUE_CLEAR))
{
retval = ui_do_but_SEARCH_UNLINK(C, block, but, data, event);
if (retval & WM_UI_HANDLER_BREAK) {
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index fcf827bdbe6..d8f9fdcbaae 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -127,7 +127,7 @@ enum {
* (e.g. 'x' icon in search menu) - used with ui_but_icon_extra_get */
typedef enum uiButExtraIconType {
UI_BUT_ICONEXTRA_NONE = 1,
- UI_BUT_ICONEXTRA_UNLINK,
+ UI_BUT_ICONEXTRA_CLEAR,
UI_BUT_ICONEXTRA_EYEDROPPER,
} uiButExtraIconType;
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 875522e01c6..b128bf47b5f 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -1659,7 +1659,7 @@ void ui_but_add_search(uiBut *but, PointerRNA *ptr, PropertyRNA *prop, PointerRN
but->rnasearchprop = searchprop;
but->drawflag |= UI_BUT_ICON_LEFT | UI_BUT_TEXT_LEFT;
if (RNA_property_is_unlink(prop)) {
- but->flag |= UI_BUT_SEARCH_UNLINK;
+ but->flag |= UI_BUT_VALUE_CLEAR;
}
if (RNA_property_type(prop) == PROP_ENUM) {
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index cdf34642a8d..466978272bc 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -851,7 +851,7 @@ static void ui_searchbox_select(bContext *C, ARegion *ar, uiBut *but, int step)
}
else {
/* only let users step into an 'unset' state for unlink buttons */
- data->active = (but->flag & UI_BUT_SEARCH_UNLINK) ? -1 : 0;
+ data->active = (but->flag & UI_BUT_VALUE_CLEAR) ? -1 : 0;
}
}
@@ -922,8 +922,8 @@ bool ui_searchbox_apply(uiBut *but, ARegion *ar)
return true;
}
- else if (but->flag & UI_BUT_SEARCH_UNLINK) {
- /* It is valid for _UNLINK flavor to have no active element (it's a valid way to unlink). */
+ else if (but->flag & UI_BUT_VALUE_CLEAR) {
+ /* It is valid for _VALUE_CLEAR flavor to have no active element (it's a valid way to unlink). */
but->editstr[0] = '\0';
return true;
diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c
index b8b46d0e4c9..550a7b52921 100644
--- a/source/blender/editors/interface/interface_templates.c
+++ b/source/blender/editors/interface/interface_templates.c
@@ -303,7 +303,10 @@ static void template_id_cb(bContext *C, void *arg_litem, void *arg_event)
break;
case UI_ID_LOCAL:
if (id) {
- if (id_make_local(CTX_data_main(C), id, false, false)) {
+ Main *bmain = CTX_data_main(C);
+ if (id_make_local(bmain, id, false, false)) {
+ BKE_main_id_clear_newpoins(bmain);
+
/* reassign to get get proper updates/notifiers */
idptr = RNA_property_pointer_get(&template->ptr, template->prop);
RNA_property_pointer_set(&template->ptr, template->prop, idptr);
diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c
index 1d51c0588b6..8dfbbdd02eb 100644
--- a/source/blender/editors/interface/interface_utils.c
+++ b/source/blender/editors/interface/interface_utils.c
@@ -119,6 +119,10 @@ uiBut *uiDefAutoButR(uiBlock *block, PointerRNA *ptr, PropertyRNA *prop, int ind
else
but = uiDefButR_prop(block, UI_BTYPE_TEXT, 0, name, x1, y1, x2, y2, ptr, prop, index, 0, 0, -1, -1, NULL);
+ PropertySubType subtype = RNA_property_subtype(prop);
+ if (!(ELEM(subtype, PROP_FILEPATH, PROP_DIRPATH, PROP_FILENAME) || (block->flag & UI_BLOCK_LIST_ITEM))) {
+ UI_but_flag_enable(but, UI_BUT_VALUE_CLEAR);
+ }
if (RNA_property_flag(prop) & PROP_TEXTEDIT_UPDATE) {
UI_but_flag_enable(but, UI_BUT_TEXTEDIT_UPDATE);
}
diff --git a/source/blender/editors/interface/interface_widgets.c b/source/blender/editors/interface/interface_widgets.c
index c285d753b96..d43a94c5514 100644
--- a/source/blender/editors/interface/interface_widgets.c
+++ b/source/blender/editors/interface/interface_widgets.c
@@ -1508,10 +1508,10 @@ static void widget_draw_text(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *b
/* draws text and icons for buttons */
static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiBut *but, rcti *rect)
{
+ const uiButExtraIconType extra_icon_type = ui_but_icon_extra_get(but);
const bool show_menu_icon = ui_but_draw_menu_icon(but);
float alpha = (float)wcol->text[3] / 255.0f;
char password_str[UI_MAX_DRAW_STR];
- uiButExtraIconType extra_icon_type;
ui_but_text_password_hide(password_str, but, false);
@@ -1577,15 +1577,13 @@ static void widget_draw_text_icon(uiFontStyle *fstyle, uiWidgetColors *wcol, uiB
rect->xmax -= (UI_TEXT_MARGIN_X * U.widget_unit) / but->block->aspect;
}
- /* unlink icon for this button type */
- if ((but->type == UI_BTYPE_SEARCH_MENU) &&
- ((extra_icon_type = ui_but_icon_extra_get(but)) != UI_BUT_ICONEXTRA_NONE))
- {
+ /* extra icons, e.g. 'x' icon to clear text or icon for eyedropper */
+ if (extra_icon_type != UI_BUT_ICONEXTRA_NONE) {
rcti temp = *rect;
temp.xmin = temp.xmax - (BLI_rcti_size_y(rect) * 1.08f);
- if (extra_icon_type == UI_BUT_ICONEXTRA_UNLINK) {
+ if (extra_icon_type == UI_BUT_ICONEXTRA_CLEAR) {
widget_draw_icon(but, ICON_X, alpha, &temp, false);
}
else if (extra_icon_type == UI_BUT_ICONEXTRA_EYEDROPPER) {
diff --git a/source/blender/editors/mask/mask_add.c b/source/blender/editors/mask/mask_add.c
index e3e8f35e7d8..f01af22cec9 100644
--- a/source/blender/editors/mask/mask_add.c
+++ b/source/blender/editors/mask/mask_add.c
@@ -779,6 +779,7 @@ static int create_primitive_from_points(bContext *C, wmOperator *op, const float
for (i = 0; i < num_points; i++) {
MaskSplinePoint *new_point = &new_spline->points[i];
+ BKE_mask_parent_init(&new_point->parent);
copy_v2_v2(new_point->bezt.vec[1], points[i]);
mul_v2_fl(new_point->bezt.vec[1], scale);
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 6647102acad..02dd3ed2df5 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -1350,7 +1350,7 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
for (dob = lb->first; dob; dob = dob->next) {
Base *basen;
- Object *ob = BKE_object_copy(bmain, dob->ob);
+ Object *ob = ID_NEW_SET(dob->ob, BKE_object_copy(bmain, dob->ob));
/* font duplis can have a totcol without material, we get them from parent
* should be implemented better...
@@ -1394,6 +1394,11 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
}
}
+ /* Remap new object to itself, and clear again newid pointer of orig object. */
+ BKE_libblock_relink(&ob->id);
+ set_sca_new_poins_ob(ob);
+ BKE_id_clear_newpoin(&dob->ob->id);
+
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
}
@@ -1484,8 +1489,6 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
if (parent_gh)
BLI_ghash_free(parent_gh, NULL, NULL);
- copy_object_set_idnew(C);
-
free_object_duplilist(lb);
base->object->transflag &= ~OB_DUPLI;
@@ -1960,8 +1963,12 @@ void OBJECT_OT_convert(wmOperatorType *ot)
/* used below, assumes id.new is correct */
/* leaves selection of base/object unaltered */
+/* Does set ID->newid pointers. */
static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base, int dupflag)
{
+#define ID_NEW_REMAP_US(a) if ( (a)->id.newid) { (a) = (void *)(a)->id.newid; (a)->id.us++; }
+#define ID_NEW_REMAP_US2(a) if (((ID *)a)->newid) { (a) = ((ID *)a)->newid; ((ID *)a)->us++; }
+
Base *basen = NULL;
Material ***matarar;
Object *ob, *obn;
@@ -1973,7 +1980,7 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
; /* nothing? */
}
else {
- obn = BKE_object_copy(bmain, ob);
+ obn = ID_NEW_SET(ob, BKE_object_copy(bmain, ob));
DAG_id_tag_update(&obn->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
basen = MEM_mallocN(sizeof(Base), "duplibase");
@@ -1995,20 +2002,21 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
/* duplicates using userflags */
if (dupflag & USER_DUP_ACT) {
- BKE_animdata_copy_id_action(&obn->id);
+ BKE_animdata_copy_id_action(&obn->id, true);
}
if (dupflag & USER_DUP_MAT) {
for (a = 0; a < obn->totcol; a++) {
id = (ID *)obn->mat[a];
if (id) {
- ID_NEW_US(obn->mat[a])
- else
- obn->mat[a] = BKE_material_copy(bmain, obn->mat[a]);
+ ID_NEW_REMAP_US(obn->mat[a])
+ else {
+ obn->mat[a] = ID_NEW_SET(obn->mat[a], BKE_material_copy(bmain, obn->mat[a]));
+ }
id_us_min(id);
if (dupflag & USER_DUP_ACT) {
- BKE_animdata_copy_id_action(&obn->mat[a]->id);
+ BKE_animdata_copy_id_action(&obn->mat[a]->id, true);
}
}
}
@@ -2018,12 +2026,13 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
for (psys = obn->particlesystem.first; psys; psys = psys->next) {
id = (ID *) psys->part;
if (id) {
- ID_NEW_US(psys->part)
- else
- psys->part = BKE_particlesettings_copy(bmain, psys->part);
+ ID_NEW_REMAP_US(psys->part)
+ else {
+ psys->part = ID_NEW_SET(psys->part, BKE_particlesettings_copy(bmain, psys->part));
+ }
if (dupflag & USER_DUP_ACT) {
- BKE_animdata_copy_id_action(&psys->part->id);
+ BKE_animdata_copy_id_action(&psys->part->id, true);
}
id_us_min(id);
@@ -2037,9 +2046,9 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
switch (obn->type) {
case OB_MESH:
if (dupflag & USER_DUP_MESH) {
- ID_NEW_US2(obn->data)
+ ID_NEW_REMAP_US2(obn->data)
else {
- obn->data = BKE_mesh_copy(bmain, obn->data);
+ obn->data = ID_NEW_SET(obn->data, BKE_mesh_copy(bmain, obn->data));
didit = 1;
}
id_us_min(id);
@@ -2047,9 +2056,9 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
break;
case OB_CURVE:
if (dupflag & USER_DUP_CURVE) {
- ID_NEW_US2(obn->data)
+ ID_NEW_REMAP_US2(obn->data)
else {
- obn->data = BKE_curve_copy(bmain, obn->data);
+ obn->data = ID_NEW_SET(obn->data, BKE_curve_copy(bmain, obn->data));
didit = 1;
}
id_us_min(id);
@@ -2057,9 +2066,9 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
break;
case OB_SURF:
if (dupflag & USER_DUP_SURF) {
- ID_NEW_US2(obn->data)
+ ID_NEW_REMAP_US2(obn->data)
else {
- obn->data = BKE_curve_copy(bmain, obn->data);
+ obn->data = ID_NEW_SET(obn->data, BKE_curve_copy(bmain, obn->data));
didit = 1;
}
id_us_min(id);
@@ -2067,9 +2076,9 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
break;
case OB_FONT:
if (dupflag & USER_DUP_FONT) {
- ID_NEW_US2(obn->data)
+ ID_NEW_REMAP_US2(obn->data)
else {
- obn->data = BKE_curve_copy(bmain, obn->data);
+ obn->data = ID_NEW_SET(obn->data, BKE_curve_copy(bmain, obn->data));
didit = 1;
}
id_us_min(id);
@@ -2077,9 +2086,9 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
break;
case OB_MBALL:
if (dupflag & USER_DUP_MBALL) {
- ID_NEW_US2(obn->data)
+ ID_NEW_REMAP_US2(obn->data)
else {
- obn->data = BKE_mball_copy(bmain, obn->data);
+ obn->data = ID_NEW_SET(obn->data, BKE_mball_copy(bmain, obn->data));
didit = 1;
}
id_us_min(id);
@@ -2087,9 +2096,9 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
break;
case OB_LAMP:
if (dupflag & USER_DUP_LAMP) {
- ID_NEW_US2(obn->data)
+ ID_NEW_REMAP_US2(obn->data)
else {
- obn->data = BKE_lamp_copy(bmain, obn->data);
+ obn->data = ID_NEW_SET(obn->data, BKE_lamp_copy(bmain, obn->data));
didit = 1;
}
id_us_min(id);
@@ -2100,9 +2109,9 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
if (obn->pose)
BKE_pose_tag_recalc(bmain, obn->pose);
if (dupflag & USER_DUP_ARM) {
- ID_NEW_US2(obn->data)
+ ID_NEW_REMAP_US2(obn->data)
else {
- obn->data = BKE_armature_copy(bmain, obn->data);
+ obn->data = ID_NEW_SET(obn->data, BKE_armature_copy(bmain, obn->data));
BKE_pose_rebuild(obn, obn->data);
didit = 1;
}
@@ -2111,9 +2120,9 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
break;
case OB_LATTICE:
if (dupflag != 0) {
- ID_NEW_US2(obn->data)
+ ID_NEW_REMAP_US2(obn->data)
else {
- obn->data = BKE_lattice_copy(bmain, obn->data);
+ obn->data = ID_NEW_SET(obn->data, BKE_lattice_copy(bmain, obn->data));
didit = 1;
}
id_us_min(id);
@@ -2121,9 +2130,9 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
break;
case OB_CAMERA:
if (dupflag != 0) {
- ID_NEW_US2(obn->data)
+ ID_NEW_REMAP_US2(obn->data)
else {
- obn->data = BKE_camera_copy(bmain, obn->data);
+ obn->data = ID_NEW_SET(obn->data, BKE_camera_copy(bmain, obn->data));
didit = 1;
}
id_us_min(id);
@@ -2131,9 +2140,9 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
break;
case OB_SPEAKER:
if (dupflag != 0) {
- ID_NEW_US2(obn->data)
+ ID_NEW_REMAP_US2(obn->data)
else {
- obn->data = BKE_speaker_copy(bmain, obn->data);
+ obn->data = ID_NEW_SET(obn->data, BKE_speaker_copy(bmain, obn->data));
didit = 1;
}
id_us_min(id);
@@ -2148,12 +2157,15 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
if (dupflag & USER_DUP_ACT) {
bActuator *act;
- BKE_animdata_copy_id_action((ID *)obn->data);
+ BKE_animdata_copy_id_action((ID *)obn->data, true);
if (key) {
- BKE_animdata_copy_id_action((ID *)key);
+ BKE_animdata_copy_id_action((ID *)key, true);
}
/* Update the duplicated action in the action actuators */
+ /* XXX TODO this code is all wrong! actact->act is user-refcounted (see readfile.c),
+ * and what about other ID pointers of other BGE logic bricks,
+ * and since this is object-level, why is it only ran if obdata was duplicated??? -mont29 */
for (act = obn->actuators.first; act; act = act->next) {
if (act->type == ACT_ACTION) {
bActionActuator *actact = (bActionActuator *) act->data;
@@ -2170,9 +2182,10 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
for (a = 0; a < obn->totcol; a++) {
id = (ID *)(*matarar)[a];
if (id) {
- ID_NEW_US((*matarar)[a])
- else
- (*matarar)[a] = BKE_material_copy(bmain, (*matarar)[a]);
+ ID_NEW_REMAP_US((*matarar)[a])
+ else {
+ (*matarar)[a] = ID_NEW_SET((*matarar)[a], BKE_material_copy(bmain, (*matarar)[a]));
+ }
id_us_min(id);
}
}
@@ -2181,6 +2194,9 @@ static Base *object_add_duplicate_internal(Main *bmain, Scene *scene, Base *base
}
}
return basen;
+
+#undef ID_NEW_REMAP_US
+#undef ID_NEW_REMAP_US2
}
/* single object duplicate, if dupflag==0, fully linked, else it uses the flags given */
@@ -2193,8 +2209,7 @@ Base *ED_object_add_duplicate(Main *bmain, Scene *scene, Base *base, int dupflag
Base *basen;
Object *ob;
- BKE_main_id_clear_newpoins(bmain);
- clear_sca_new_poins(); /* sensor/contr/act */
+ clear_sca_new_poins(); /* BGE logic */
basen = object_add_duplicate_internal(bmain, scene, base, dupflag);
if (basen == NULL) {
@@ -2213,6 +2228,8 @@ Base *ED_object_add_duplicate(Main *bmain, Scene *scene, Base *base, int dupflag
ED_render_id_flush_update(bmain, ob->data);
}
+ BKE_main_id_clear_newpoins(bmain);
+
return basen;
}
@@ -2224,8 +2241,7 @@ static int duplicate_exec(bContext *C, wmOperator *op)
const bool linked = RNA_boolean_get(op->ptr, "linked");
int dupflag = (linked) ? 0 : U.dupflag;
- BKE_main_id_clear_newpoins(bmain);
- clear_sca_new_poins(); /* sensor/contr/act */
+ clear_sca_new_poins(); /* BGE logic */
CTX_DATA_BEGIN (C, Base *, base, selected_bases)
{
@@ -2251,6 +2267,8 @@ static int duplicate_exec(bContext *C, wmOperator *op)
copy_object_set_idnew(C);
+ BKE_main_id_clear_newpoins(bmain);
+
DAG_relations_tag_update(bmain);
WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
@@ -2309,8 +2327,7 @@ static int add_named_exec(bContext *C, wmOperator *op)
base->flag = ob->flag;
/* prepare dupli */
- BKE_main_id_clear_newpoins(bmain);
- clear_sca_new_poins(); /* sensor/contr/act */
+ clear_sca_new_poins(); /* BGE logic */
basen = object_add_duplicate_internal(bmain, scene, base, dupflag);
@@ -2336,6 +2353,8 @@ static int add_named_exec(bContext *C, wmOperator *op)
copy_object_set_idnew(C);
+ BKE_main_id_clear_newpoins(bmain);
+
DAG_relations_tag_update(bmain);
MEM_freeN(base);
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index f448e925dd9..d670f4b8425 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -1731,6 +1731,7 @@ void OBJECT_OT_make_links_data(wmOperatorType *ot)
/**************************** Make Single User ********************************/
+/* Warning, sets ID->newid pointers of objects and groups, but does not clear them. */
static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const int flag, const bool copy_groups)
{
Base *base;
@@ -1738,18 +1739,7 @@ static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const in
Group *group, *groupn;
GroupObject *go;
- clear_sca_new_poins(); /* sensor/contr/act */
-
- /* newid may still have some trash from Outliner tree building, so clear that first to avoid errors, see T26002.
- * We have to clear whole datablocks, not only Object one may be accessed here, see T49905. */
- ListBase *lbarray[MAX_LIBARRAY];
- int a = set_listbasepointers(bmain, lbarray);
- while (a--) {
- ListBase *lb = lbarray[a];
- for (ID *id = lb->first; id; id = id->next) {
- id->newid = NULL;
- }
- }
+ clear_sca_new_poins(); /* BGE logic */
/* duplicate (must set newid) */
for (base = FIRSTBASE; base; base = base->next) {
@@ -1758,8 +1748,7 @@ static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const in
if ((base->flag & flag) == flag) {
if (!ID_IS_LINKED_DATABLOCK(ob) && ob->id.us > 1) {
/* base gets copy of object */
- obn = BKE_object_copy(bmain, ob);
- base->object = obn;
+ base->object = obn = ID_NEW_SET(ob, BKE_object_copy(bmain, ob));
if (copy_groups) {
if (ob->flag & OB_FROMGROUP) {
@@ -1789,8 +1778,6 @@ static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const in
/* duplicate groups that consist entirely of duplicated objects */
for (group = bmain->group.first; group; group = group->id.next) {
- group->id.newid = NULL;
-
if (copy_groups && group->gobject.first) {
bool all_duplicated = true;
@@ -1802,10 +1789,11 @@ static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const in
}
if (all_duplicated) {
- groupn = BKE_group_copy(bmain, group);
+ groupn = ID_NEW_SET(group, BKE_group_copy(bmain, group));
- for (go = groupn->gobject.first; go; go = go->next)
+ for (go = groupn->gobject.first; go; go = go->next) {
go->ob = (Object *)go->ob->id.newid;
+ }
}
}
}
@@ -1813,8 +1801,8 @@ static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const in
/* group pointers in scene */
BKE_scene_groups_relink(scene);
- ID_NEW(scene->camera);
- if (v3d) ID_NEW(v3d->camera);
+ ID_NEW_REMAP(scene->camera);
+ if (v3d) ID_NEW_REMAP(v3d->camera);
/* object and group pointers */
for (base = FIRSTBASE; base; base = base->next) {
@@ -1837,6 +1825,8 @@ void ED_object_single_user(Main *bmain, Scene *scene, Object *ob)
}
single_object_users(bmain, scene, NULL, OB_DONE, copy_groups);
+
+ BKE_main_id_clear_newpoins(bmain);
}
static void new_id_matar(Main *bmain, Material **matar, const int totcol)
@@ -1853,9 +1843,8 @@ static void new_id_matar(Main *bmain, Material **matar, const int totcol)
id_us_min(id);
}
else if (id->us > 1) {
- matar[a] = BKE_material_copy(bmain, matar[a]);
+ matar[a] = ID_NEW_SET(id, BKE_material_copy(bmain, matar[a]));
id_us_min(id);
- id->newid = (ID *)matar[a];
}
}
}
@@ -1883,45 +1872,46 @@ static void single_obdata_users(Main *bmain, Scene *scene, const int flag)
switch (ob->type) {
case OB_LAMP:
- ob->data = la = BKE_lamp_copy(bmain, ob->data);
+ ob->data = la = ID_NEW_SET(ob->data, BKE_lamp_copy(bmain, ob->data));
for (a = 0; a < MAX_MTEX; a++) {
if (la->mtex[a]) {
- ID_NEW(la->mtex[a]->object);
+ ID_NEW_REMAP(la->mtex[a]->object);
}
}
break;
case OB_CAMERA:
- ob->data = BKE_camera_copy(bmain, ob->data);
+ ob->data = ID_NEW_SET(ob->data, BKE_camera_copy(bmain, ob->data));
break;
case OB_MESH:
- ob->data = me = BKE_mesh_copy(bmain, ob->data);
- if (me->key)
- BKE_animdata_copy_id_action((ID *)me->key);
+ /* Needed to remap texcomesh below. */
+ me = ob->data = ID_NEW_SET(ob->data, BKE_mesh_copy(bmain, ob->data));
+ if (me->key) /* We do not need to set me->key->id.newid here... */
+ BKE_animdata_copy_id_action((ID *)me->key, false);
break;
case OB_MBALL:
- ob->data = BKE_mball_copy(bmain, ob->data);
+ ob->data = ID_NEW_SET(ob->data, BKE_mball_copy(bmain, ob->data));
break;
case OB_CURVE:
case OB_SURF:
case OB_FONT:
- ob->data = cu = BKE_curve_copy(bmain, ob->data);
- ID_NEW(cu->bevobj);
- ID_NEW(cu->taperobj);
- if (cu->key)
- BKE_animdata_copy_id_action((ID *)cu->key);
+ ob->data = cu = ID_NEW_SET(ob->data, BKE_curve_copy(bmain, ob->data));
+ ID_NEW_REMAP(cu->bevobj);
+ ID_NEW_REMAP(cu->taperobj);
+ if (cu->key) /* We do not need to set cu->key->id.newid here... */
+ BKE_animdata_copy_id_action((ID *)cu->key, false);
break;
case OB_LATTICE:
- ob->data = lat = BKE_lattice_copy(bmain, ob->data);
- if (lat->key)
- BKE_animdata_copy_id_action((ID *)lat->key);
+ ob->data = lat = ID_NEW_SET(ob->data, BKE_lattice_copy(bmain, ob->data));
+ if (lat->key) /* We do not need to set lat->key->id.newid here... */
+ BKE_animdata_copy_id_action((ID *)lat->key, false);
break;
case OB_ARMATURE:
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
- ob->data = BKE_armature_copy(bmain, ob->data);
+ ob->data = ID_NEW_SET(ob->data, BKE_armature_copy(bmain, ob->data));
BKE_pose_rebuild(ob, ob->data);
break;
case OB_SPEAKER:
- ob->data = BKE_speaker_copy(bmain, ob->data);
+ ob->data = ID_NEW_SET(ob->data, BKE_speaker_copy(bmain, ob->data));
break;
default:
if (G.debug & G_DEBUG)
@@ -1934,17 +1924,16 @@ static void single_obdata_users(Main *bmain, Scene *scene, const int flag)
* AnimData structure, which is not what we want.
* (sergey)
*/
- BKE_animdata_copy_id_action((ID *)ob->data);
+ BKE_animdata_copy_id_action((ID *)ob->data, false);
id_us_min(id);
- id->newid = ob->data;
}
}
}
me = bmain->mesh.first;
while (me) {
- ID_NEW(me->texcomesh);
+ ID_NEW_REMAP(me->texcomesh);
me = me->id.next;
}
}
@@ -1958,7 +1947,7 @@ static void single_object_action_users(Scene *scene, const int flag)
ob = base->object;
if (!ID_IS_LINKED_DATABLOCK(ob) && (flag == 0 || (base->flag & SELECT)) ) {
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
- BKE_animdata_copy_id_action(&ob->id);
+ BKE_animdata_copy_id_action(&ob->id, false);
}
}
}
@@ -1977,11 +1966,11 @@ static void single_mat_users(Main *bmain, Scene *scene, const int flag, const bo
for (a = 1; a <= ob->totcol; a++) {
ma = give_current_material(ob, a);
if (ma) {
- /* do not test for LIB_TAG_NEW: this functions guaranteed delivers single_users! */
+ /* do not test for LIB_TAG_NEW or use newid: this functions guaranteed delivers single_users! */
if (ma->id.us > 1) {
man = BKE_material_copy(bmain, ma);
- BKE_animdata_copy_id_action(&man->id);
+ BKE_animdata_copy_id_action(&man->id, false);
man->id.us = 0;
assign_material(ob, man, a, BKE_MAT_ASSIGN_USERPREF);
@@ -1992,7 +1981,7 @@ static void single_mat_users(Main *bmain, Scene *scene, const int flag, const bo
if (tex->id.us > 1) {
id_us_min(&tex->id);
tex = BKE_texture_copy(bmain, tex);
- BKE_animdata_copy_id_action(&tex->id);
+ BKE_animdata_copy_id_action(&tex->id, false);
man->mtex[b]->tex = tex;
}
}
@@ -2018,8 +2007,8 @@ static void do_single_tex_user(Main *bmain, Tex **from)
id_us_min(&tex->id);
}
else if (tex->id.us > 1) {
- texn = BKE_texture_copy(bmain, tex);
- BKE_animdata_copy_id_action(&texn->id);
+ texn = ID_NEW_SET(tex, BKE_texture_copy(bmain, tex));
+ BKE_animdata_copy_id_action(&texn->id, false);
tex->id.newid = (ID *)texn;
id_us_min(&tex->id);
*from = texn;
@@ -2096,7 +2085,7 @@ static void single_mat_users_expand(Main *bmain)
if (ma->id.tag & LIB_TAG_NEW)
for (a = 0; a < MAX_MTEX; a++)
if (ma->mtex[a])
- ID_NEW(ma->mtex[a]->object);
+ ID_NEW_REMAP(ma->mtex[a]->object);
}
/* used for copying scenes */
@@ -2247,7 +2236,6 @@ static int make_local_exec(bContext *C, wmOperator *op)
}
tag_localizable_objects(C, mode);
- BKE_main_id_clear_newpoins(bmain);
CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
{
@@ -2264,7 +2252,7 @@ static int make_local_exec(bContext *C, wmOperator *op)
CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
{
if (ob->id.lib == NULL) {
- ID_NEW(ob->parent);
+ ID_NEW_REMAP(ob->parent);
}
}
CTX_DATA_END;
@@ -2335,6 +2323,7 @@ static int make_local_exec(bContext *C, wmOperator *op)
CTX_DATA_END;
}
+ BKE_main_id_clear_newpoins(bmain);
WM_event_add_notifier(C, NC_WINDOW, NULL);
return OPERATOR_FINISHED;
@@ -2381,8 +2370,6 @@ static int make_single_user_exec(bContext *C, wmOperator *op)
const bool copy_groups = false;
bool update_deps = false;
- BKE_main_id_clear_newpoins(bmain);
-
if (RNA_boolean_get(op->ptr, "object")) {
single_object_users(bmain, scene, v3d, flag, copy_groups);
@@ -2406,11 +2393,6 @@ static int make_single_user_exec(bContext *C, wmOperator *op)
single_object_action_users(scene, flag);
}
- /* TODO(sergey): This should not be needed, however some tool still could rely
- * on the fact, that id->newid is kept NULL by default.
- * Need to make sure all the guys are learing newid before they're
- * using it, not after.
- */
BKE_main_id_clear_newpoins(bmain);
WM_event_add_notifier(C, NC_WINDOW, NULL);
diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index 13200e92e7e..7739d241bd3 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -442,6 +442,9 @@ static void id_local_cb(
if (id_make_local(bmain, tselem->id, false, false) == false) {
id_clear_lib_data(bmain, tselem->id);
}
+ else {
+ BKE_main_id_clear_newpoins(bmain);
+ }
}
}
diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c
index 20f7ca4db16..ec46c5df9a0 100644
--- a/source/blender/editors/space_outliner/outliner_tree.c
+++ b/source/blender/editors/space_outliner/outliner_tree.c
@@ -1645,11 +1645,6 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops)
outliner_free_tree(&soops->tree);
outliner_storage_cleanup(soops);
- /* clear ob id.new flags */
- for (Object *ob = mainvar->object.first; ob; ob = ob->id.next) {
- ob->id.newid = NULL;
- }
-
/* options */
if (soops->outlinevis == SO_LIBRARIES) {
Library *lib;
@@ -1835,6 +1830,8 @@ void outliner_build_tree(Main *mainvar, Scene *scene, SpaceOops *soops)
outliner_sort(&soops->tree);
}
outliner_filter_tree(soops, &soops->tree);
+
+ BKE_main_id_clear_newpoins(mainvar);
}
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 000d1fe4810..f23e587e55d 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -2658,7 +2658,6 @@ CustomDataMask ED_view3d_screen_datamask(const bScreen *screen)
void ED_view3d_update_viewmat(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4])
{
RegionView3D *rv3d = ar->regiondata;
- rctf cameraborder;
/* setup window matrices */
if (winmat)
@@ -2672,7 +2671,7 @@ void ED_view3d_update_viewmat(Scene *scene, View3D *v3d, ARegion *ar, float view
else
view3d_viewmatrix_set(scene, v3d, rv3d); /* note: calls BKE_object_where_is_calc for camera... */
- /* update utilitity matrices */
+ /* update utility matrices */
mul_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat);
invert_m4_m4(rv3d->persinv, rv3d->persmat);
invert_m4_m4(rv3d->viewinv, rv3d->viewmat);
@@ -2681,6 +2680,7 @@ void ED_view3d_update_viewmat(Scene *scene, View3D *v3d, ARegion *ar, float view
/* store window coordinates scaling/offset */
if (rv3d->persp == RV3D_CAMOB && v3d->camera) {
+ rctf cameraborder;
ED_view3d_calc_camera_border(scene, ar, v3d, rv3d, &cameraborder, false);
rv3d->viewcamtexcofac[0] = (float)ar->winx / BLI_rctf_size_x(&cameraborder);
rv3d->viewcamtexcofac[1] = (float)ar->winy / BLI_rctf_size_y(&cameraborder);
@@ -2692,8 +2692,17 @@ void ED_view3d_update_viewmat(Scene *scene, View3D *v3d, ARegion *ar, float view
rv3d->viewcamtexcofac[0] = rv3d->viewcamtexcofac[1] = 1.0f;
rv3d->viewcamtexcofac[2] = rv3d->viewcamtexcofac[3] = 0.0f;
}
-
- /* calculate pixelsize factor once, is used for lamps and obcenters */
+
+ /**
+ * Calculate pixel-size factor once, is used for lamps and object centers.
+ * Used by #ED_view3d_pixel_size and typically not accessed directly.
+ *
+ * \note #BKE_camera_params_compute_viewplane' also calculates a pixel-size value,
+ * passed to #RE_SetPixelSize, in ortho mode this is compatible with this value,
+ * but in perspective mode its offset by the near-clip.
+ *
+ * 'RegionView3D.pixsize' is used for viewport drawing, not rendering.
+ */
{
/* note: '1.0f / len_v3(v1)' replaced 'len_v3(rv3d->viewmat[0])'
* because of float point precision problems at large values [#23908] */
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index daf0aed59e7..d4cd2351f46 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -103,7 +103,7 @@ static void drawEdgeSlide(TransInfo *t);
static void drawVertSlide(TransInfo *t);
static void postInputRotation(TransInfo *t, float values[3]);
-static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], short around);
+static void ElementRotation(TransInfo *t, TransData *td, float mat[3][3], const short around);
static void initSnapSpatial(TransInfo *t, float r_snap[3]);
diff --git a/source/blender/imbuf/intern/allocimbuf.c b/source/blender/imbuf/intern/allocimbuf.c
index ef3743d9c8a..33750478bb4 100644
--- a/source/blender/imbuf/intern/allocimbuf.c
+++ b/source/blender/imbuf/intern/allocimbuf.c
@@ -89,11 +89,14 @@ void imb_mmap_unlock(void)
void imb_freemipmapImBuf(ImBuf *ibuf)
{
int a;
-
- for (a = 1; a < ibuf->miptot; a++) {
- if (ibuf->mipmap[a - 1])
- IMB_freeImBuf(ibuf->mipmap[a - 1]);
- ibuf->mipmap[a - 1] = NULL;
+
+ /* Do not trust ibuf->miptot, in some cases IMB_remakemipmap can leave unfreed unused levels,
+ * leading to memory leaks... */
+ for (a = 0; a < IMB_MIPMAP_LEVELS; a++) {
+ if (ibuf->mipmap[a] != NULL) {
+ IMB_freeImBuf(ibuf->mipmap[a]);
+ ibuf->mipmap[a] = NULL;
+ }
}
ibuf->miptot = 0;
diff --git a/source/blender/imbuf/intern/oiio/CMakeLists.txt b/source/blender/imbuf/intern/oiio/CMakeLists.txt
index c873fa3f32d..a4fb9c5aee1 100644
--- a/source/blender/imbuf/intern/oiio/CMakeLists.txt
+++ b/source/blender/imbuf/intern/oiio/CMakeLists.txt
@@ -49,6 +49,11 @@ if(WITH_OPENIMAGEIO)
${OPENIMAGEIO_INCLUDE_DIRS}
${BOOST_INCLUDE_DIR}
)
+ if(WITH_IMAGE_OPENEXR)
+ list(APPEND INC_SYS
+ ${OPENEXR_INCLUDE_DIRS}
+ )
+ endif()
add_definitions(-DWITH_OPENIMAGEIO)
endif()
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index feeb2d5e4d7..59fd0c7832c 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -290,9 +290,9 @@ typedef enum ID_Type {
#endif
#define GS(a) (CHECK_TYPE_ANY(a, char *, const char *, char [66], const char[66]), (*((const short *)(a))))
-#define ID_NEW(a) if ( (a) && (a)->id.newid ) (a) = (void *)(a)->id.newid
-#define ID_NEW_US(a) if ( (a)->id.newid) { (a) = (void *)(a)->id.newid; (a)->id.us++; }
-#define ID_NEW_US2(a) if (((ID *)a)->newid) { (a) = ((ID *)a)->newid; ((ID *)a)->us++; }
+#define ID_NEW_SET(_id, _idn) \
+ (((ID *)(_id))->newid = (ID *)(_idn), ((ID *)(_id))->newid->tag |= LIB_TAG_NEW, (void *)((ID *)(_id))->newid)
+#define ID_NEW_REMAP(a) if ((a) && (a)->id.newid) (a) = (void *)(a)->id.newid
/* id->flag (persitent). */
enum {
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 46b30f41f5b..3a7e2b6f7f8 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -811,7 +811,10 @@ typedef struct NodeShaderTexPointDensity {
short color_source;
short ob_color_source;
char vertex_attribute_name[64]; /* vertex attribute layer for color source, MAX_CUSTOMDATA_LAYER_NAME */
+ /* Used at runtime only by sampling RNA API. */
PointDensity pd;
+ int cached_resolution;
+ int pad2;
} NodeShaderTexPointDensity;
/* TEX_output */
diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c
index 87fb45a4419..896d4979089 100644
--- a/source/blender/makesrna/intern/rna_ID.c
+++ b/source/blender/makesrna/intern/rna_ID.c
@@ -358,7 +358,9 @@ static struct ID *rna_ID_make_local(struct ID *self, Main *bmain, int clear_prox
id_make_local(bmain, self, false, false);
}
- return self->newid ? self->newid : self;
+ ID *ret_id = self->newid ? self->newid : self;
+ BKE_id_clear_newpoin(self);
+ return ret_id;
}
diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c
index 7ba89538b18..16aa60e1b91 100644
--- a/source/blender/makesrna/intern/rna_gpencil.c
+++ b/source/blender/makesrna/intern/rna_gpencil.c
@@ -585,11 +585,11 @@ static bGPDframe *rna_GPencil_frame_copy(bGPDlayer *layer, bGPDframe *src)
static bGPDlayer *rna_GPencil_layer_new(bGPdata *gpd, const char *name, int setactive)
{
- bGPDlayer *gl = BKE_gpencil_layer_addnew(gpd, name, setactive != 0);
+ bGPDlayer *gpl = BKE_gpencil_layer_addnew(gpd, name, setactive != 0);
WM_main_add_notifier(NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
- return gl;
+ return gpl;
}
static void rna_GPencil_layer_remove(bGPdata *gpd, ReportList *reports, PointerRNA *layer_ptr)
@@ -1354,7 +1354,7 @@ static void rna_def_gpencil_layers_api(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_function_ui_description(func, "Add a new grease pencil layer");
parm = RNA_def_string(func, "name", "GPencilLayer", MAX_NAME, "Name", "Name of the layer");
RNA_def_property_flag(parm, PROP_REQUIRED);
- RNA_def_boolean(func, "set_active", 0, "Set Active", "Set the newly created layer to the active layer");
+ RNA_def_boolean(func, "set_active", true, "Set Active", "Set the newly created layer to the active layer");
parm = RNA_def_pointer(func, "layer", "GPencilLayer", "", "The newly created layer");
RNA_def_function_return(func, parm);
@@ -1443,7 +1443,7 @@ static void rna_def_gpencil_palettecolor(BlenderRNA *brna)
prop = RNA_def_property(srna, "ghost", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", PC_COLOR_ONIONSKIN);
RNA_def_property_ui_icon(prop, ICON_GHOST_ENABLED, 0);
- RNA_def_property_ui_text(prop, "Ghost", "Display the color in onion skinning");
+ RNA_def_property_ui_text(prop, "Show in Ghosts", "Display strokes using this color when showing onion skins");
RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update");
/* Draw Style */
@@ -1557,7 +1557,7 @@ static void rna_def_gpencil_palettes_api(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_function_ui_description(func, "Add a new grease pencil palette");
parm = RNA_def_string(func, "name", "GPencilPalette", MAX_NAME, "Name", "Name of the palette");
RNA_def_property_flag(parm, PROP_REQUIRED);
- RNA_def_boolean(func, "set_active", 0, "Set Active", "Activate the newly created palette");
+ RNA_def_boolean(func, "set_active", true, "Set Active", "Activate the newly created palette");
parm = RNA_def_pointer(func, "palette", "GPencilPalette", "", "The newly created palette");
RNA_def_function_return(func, parm);
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 47e9d989dbf..34002f8d550 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -3107,6 +3107,9 @@ void rna_ShaderNodePointDensity_density_cache(bNode *self,
sizeof(pd->vertex_attribute_name));
}
+ /* Store resolution, so it can be changed in the UI. */
+ shader_point_density->cached_resolution = shader_point_density->resolution;
+
/* Single-threaded sampling of the voxel domain. */
RE_point_density_cache(scene,
pd,
@@ -3121,15 +3124,15 @@ void rna_ShaderNodePointDensity_density_calc(bNode *self,
{
NodeShaderTexPointDensity *shader_point_density = self->storage;
PointDensity *pd = &shader_point_density->pd;
+ const int resolution = shader_point_density->cached_resolution;
if (scene == NULL) {
*length = 0;
return;
}
- *length = 4 * shader_point_density->resolution *
- shader_point_density->resolution *
- shader_point_density->resolution;
+ /* TODO(sergey): Will likely overflow, but how to pass size_t via RNA? */
+ *length = 4 * resolution * resolution * resolution;
if (*values == NULL) {
*values = MEM_mallocN(sizeof(float) * (*length), "point density dynamic array");
@@ -3137,13 +3140,14 @@ void rna_ShaderNodePointDensity_density_calc(bNode *self,
/* Single-threaded sampling of the voxel domain. */
RE_point_density_sample(scene, pd,
- shader_point_density->resolution,
+ resolution,
settings == 1,
*values);
/* We're done, time to clean up. */
BKE_texture_pointdensity_free_data(pd);
memset(pd, 0, sizeof(*pd));
+ shader_point_density->cached_resolution = 0.0f;
}
void rna_ShaderNodePointDensity_density_minmax(bNode *self,
diff --git a/source/blender/python/mathutils/mathutils_bvhtree.c b/source/blender/python/mathutils/mathutils_bvhtree.c
index ff1761eb6d7..1eb8644a9a6 100644
--- a/source/blender/python/mathutils/mathutils_bvhtree.c
+++ b/source/blender/python/mathutils/mathutils_bvhtree.c
@@ -817,13 +817,14 @@ static PyObject *C_BVHTree_FromPolygons(PyObject *UNUSED(cls), PyObject *args, P
PyErr_Format(PyExc_ValueError,
"%s: index %d must be less than %d",
error_prefix, plink->poly[j], coords_len);
-
- Py_DECREF(py_tricoords_fast);
+ /* decref below */
valid = false;
break;
}
}
+ Py_DECREF(py_tricoords_fast);
+
if (py_tricoords_len >= 3) {
tris_len += (py_tricoords_len - 2);
}
diff --git a/source/creator/CMakeLists.txt b/source/creator/CMakeLists.txt
index aa0a213cf64..04a79f6498f 100644
--- a/source/creator/CMakeLists.txt
+++ b/source/creator/CMakeLists.txt
@@ -1185,7 +1185,7 @@ if(WIN32 AND NOT WITH_PYTHON_MODULE)
message(FATAL_ERROR "Windows 10 SDK directory not found")
endif()
endif()
-
+ FILE(TO_CMAKE_PATH ${KITSPATH} KITSPATH)
install(
FILES
${KITSPATH}/api-ms-win-core-file-l1-2-0.dll