Merge branch 'master' into blender2.8

Conflicts:
	source/blender/blenkernel/intern/depsgraph.c
	source/blender/blenloader/intern/versioning_270.c
	source/blender/depsgraph/intern/builder/deg_builder_relations.cc
	source/blender/makesrna/intern/rna_main_api.c
	source/blender/makesrna/intern/rna_particle.c
This commit is contained in:
Bastien Montagne 2016-12-12 16:17:57 +01:00
commit 9be6d5ff18
158 changed files with 2135 additions and 1575 deletions

View File

@ -627,6 +627,12 @@ if(APPLE)
# to silence sdk not found warning, just overrides CMAKE_OSX_SYSROOT
set(CMAKE_XCODE_ATTRIBUTE_SDKROOT macosx${OSX_SYSTEM})
endif()
# QuickTime framework is no longer available in SDK 10.12+
if(WITH_CODEC_QUICKTIME AND ${OSX_SYSTEM} VERSION_GREATER 10.11)
set(WITH_CODEC_QUICKTIME OFF)
message(STATUS "QuickTime not supported by SDK ${OSX_SYSTEM}, disabling WITH_CODEC_QUICKTIME")
endif()
endif()
if(OSX_SYSTEM MATCHES 10.9)

View File

@ -284,7 +284,7 @@ NO_BUILD=false
NO_CONFIRM=false
USE_CXX11=true # Mandatory in blender2.8
PYTHON_VERSION="3.5.1"
PYTHON_VERSION="3.5.2"
PYTHON_VERSION_MIN="3.5"
PYTHON_FORCE_BUILD=false
PYTHON_FORCE_REBUILD=false
@ -317,7 +317,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
@ -332,14 +332,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
@ -367,7 +367,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
@ -2472,7 +2472,7 @@ compile_FFmpeg() {
--enable-avfilter --disable-vdpau \
--disable-bzlib --disable-libgsm --disable-libspeex \
--enable-pthreads --enable-zlib --enable-stripping --enable-runtime-cpudetect \
--disable-vaapi --disable-libfaac --disable-nonfree --enable-gpl \
--disable-vaapi --disable-nonfree --enable-gpl \
--disable-postproc --disable-librtmp --disable-libopencore-amrnb \
--disable-libopencore-amrwb --disable-libdc1394 --disable-version3 --disable-outdev=sdl \
--disable-libxcb \

View File

@ -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)

View File

@ -158,7 +158,7 @@ if(WITH_CODEC_FFMPEG)
mp3lame swscale x264 xvidcore theora theoradec theoraenc vorbis vorbisenc vorbisfile ogg
)
if(WITH_CXX11)
set(FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} schroedinger orc vpx)
set(FFMPEG_LIBRARIES ${FFMPEG_LIBRARIES} schroedinger orc vpx webp swresample)
endif()
set(FFMPEG_LIBPATH ${FFMPEG}/lib)
endif()
@ -316,6 +316,9 @@ if(WITH_OPENIMAGEIO)
${OPENEXR_LIBRARIES}
${ZLIB_LIBRARIES}
)
if(WITH_CXX11)
set(OPENIMAGEIO_LIBRARIES ${OPENIMAGEIO_LIBRARIES} ${LIBDIR}/ffmpeg/lib/libwebp.a)
endif()
set(OPENIMAGEIO_LIBPATH
${OPENIMAGEIO}/lib
${JPEG_LIBPATH}

View File

@ -238,14 +238,14 @@ if(WITH_CODEC_FFMPEG)
windows_find_package(FFMPEG)
if(NOT FFMPEG_FOUND)
warn_hardcoded_paths(ffmpeg)
set(FFMPEG_LIBRARY_VERSION 55)
set(FFMPEG_LIBRARY_VERSION_AVU 52)
set(FFMPEG_LIBRARY_VERSION 57)
set(FFMPEG_LIBRARY_VERSION_AVU 55)
set(FFMPEG_LIBRARIES
${LIBDIR}/ffmpeg/lib/avcodec-${FFMPEG_LIBRARY_VERSION}.lib
${LIBDIR}/ffmpeg/lib/avformat-${FFMPEG_LIBRARY_VERSION}.lib
${LIBDIR}/ffmpeg/lib/avdevice-${FFMPEG_LIBRARY_VERSION}.lib
${LIBDIR}/ffmpeg/lib/avutil-${FFMPEG_LIBRARY_VERSION_AVU}.lib
${LIBDIR}/ffmpeg/lib/swscale-2.lib
${LIBDIR}/ffmpeg/lib/avcodec.lib
${LIBDIR}/ffmpeg/lib/avformat.lib
${LIBDIR}/ffmpeg/lib/avdevice.lib
${LIBDIR}/ffmpeg/lib/avutil.lib
${LIBDIR}/ffmpeg/lib/swscale.lib
)
endif()
endif()
@ -380,6 +380,7 @@ if(WITH_OPENIMAGEIO)
set(OPENCOLORIO_DEFINITIONS "-DOCIO_STATIC_BUILD")
set(OPENIMAGEIO_IDIFF "${OPENIMAGEIO}/bin/idiff.exe")
add_definitions(-DOIIO_STATIC_BUILD)
add_definitions(-DOIIO_NO_SSE=1)
endif()
if(WITH_LLVM)

View File

@ -72,20 +72,17 @@ static void session_print(const string& str)
static void session_print_status()
{
int sample, tile;
double total_time, sample_time, render_time;
string status, substatus;
/* get status */
sample = options.session->progress.get_sample();
options.session->progress.get_tile(tile, total_time, sample_time, render_time);
float progress = options.session->progress.get_progress();
options.session->progress.get_status(status, substatus);
if(substatus != "")
status += ": " + substatus;
/* print status */
status = string_printf("Sample %d %s", sample, status.c_str());
status = string_printf("Progress %05.2f %s", (double) progress*100, status.c_str());
session_print(status);
}
@ -167,13 +164,12 @@ static void display_info(Progress& progress)
latency = (elapsed - last);
last = elapsed;
int sample, tile;
double total_time, sample_time, render_time;
double total_time, sample_time;
string status, substatus;
sample = progress.get_sample();
progress.get_tile(tile, total_time, sample_time, render_time);
progress.get_time(total_time, sample_time);
progress.get_status(status, substatus);
float progress_val = progress.get_progress();
if(substatus != "")
status += ": " + substatus;
@ -184,10 +180,10 @@ static void display_info(Progress& progress)
"%s"
" Time: %.2f"
" Latency: %.4f"
" Sample: %d"
" Progress: %05.2f"
" Average: %.4f"
" Interactive: %s",
status.c_str(), total_time, latency, sample, sample_time, interactive.c_str());
status.c_str(), total_time, latency, (double) progress_val*100, sample_time, interactive.c_str());
view_display_info(str.c_str());

View File

@ -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(

View File

@ -930,38 +930,13 @@ void BlenderSession::get_status(string& status, string& substatus)
void BlenderSession::get_progress(float& progress, double& total_time, double& render_time)
{
double tile_time;
int tile, sample, samples_per_tile;
int tile_total = session->tile_manager.state.num_tiles;
int samples = session->tile_manager.state.sample + 1;
int total_samples = session->tile_manager.get_num_effective_samples();
session->progress.get_tile(tile, total_time, render_time, tile_time);
sample = session->progress.get_sample();
samples_per_tile = session->tile_manager.get_num_effective_samples();
if(background && samples_per_tile && tile_total)
progress = ((float)sample / (float)(tile_total * samples_per_tile));
else if(!background && samples > 0 && total_samples != INT_MAX)
progress = ((float)samples) / total_samples;
else
progress = 0.0;
session->progress.get_time(total_time, render_time);
progress = session->progress.get_progress();
}
void BlenderSession::update_bake_progress()
{
float progress;
int sample, samples_per_task, parts_total;
sample = session->progress.get_sample();
samples_per_task = scene->bake_manager->num_samples;
parts_total = scene->bake_manager->num_parts;
if(samples_per_task)
progress = ((float)sample / (float)(parts_total * samples_per_task));
else
progress = 0.0;
float progress = session->progress.get_progress();
if(progress != last_progress) {
b_engine.update_progress(progress);

View File

@ -64,6 +64,8 @@ std::ostream& operator <<(std::ostream &os,
<< string_from_bool(requested_features.use_integrator_branched) << std::endl;
os << "Use Patch Evaluation: "
<< string_from_bool(requested_features.use_patch_evaluation) << std::endl;
os << "Use Transparent Shadows: "
<< string_from_bool(requested_features.use_transparent) << std::endl;
return os;
}

View File

@ -117,6 +117,9 @@ public:
/* Use OpenSubdiv patch evaluation */
bool use_patch_evaluation;
/* Use Transparent shadows */
bool use_transparent;
DeviceRequestedFeatures()
{
@ -133,6 +136,7 @@ public:
use_volume = false;
use_integrator_branched = false;
use_patch_evaluation = false;
use_transparent = false;
}
bool modified(const DeviceRequestedFeatures& requested_features)
@ -148,7 +152,8 @@ public:
use_subsurface == requested_features.use_subsurface &&
use_volume == requested_features.use_volume &&
use_integrator_branched == requested_features.use_integrator_branched &&
use_patch_evaluation == requested_features.use_patch_evaluation);
use_patch_evaluation == requested_features.use_patch_evaluation &&
use_transparent == requested_features.use_transparent);
}
/* Convert the requested features structure to a build options,
@ -189,6 +194,9 @@ public:
if(!use_patch_evaluation) {
build_options += " -D__NO_PATCH_EVAL__";
}
if(!use_transparent) {
build_options += " -D__NO_TRANSPARENT__";
}
return build_options;
}
};
@ -220,6 +228,7 @@ public:
DeviceInfo info;
virtual const string& error_message() { return error_msg; }
bool have_error() { return !error_message().empty(); }
virtual bool show_samples() const { return false; }
/* statistics */
Stats &stats;

View File

@ -112,6 +112,11 @@ public:
task_pool.stop();
}
virtual bool show_samples() const
{
return (TaskScheduler::num_threads() == 1);
}
void mem_alloc(device_memory& mem, MemoryType /*type*/)
{
mem.device_pointer = mem.data_pointer;
@ -275,7 +280,7 @@ public:
tile.sample = sample + 1;
task.update_progress(&tile);
task.update_progress(&tile, tile.w*tile.h);
}
task.release_tile(tile);

View File

@ -115,6 +115,12 @@ public:
return path_exists(cubins_path);
}
virtual bool show_samples() const
{
/* The CUDADevice only processes one tile at a time, so showing samples is fine. */
return true;
}
/*#ifdef NDEBUG
#define cuda_abort()
#else
@ -1267,7 +1273,7 @@ public:
tile.sample = sample + 1;
task->update_progress(&tile);
task->update_progress(&tile, tile.w*tile.h);
}
task->release_tile(tile);

View File

@ -89,6 +89,14 @@ public:
return error_msg;
}
virtual bool show_samples() const
{
if(devices.size() > 1) {
return false;
}
return devices.front().device->show_samples();
}
bool load_kernels(const DeviceRequestedFeatures& requested_features)
{
foreach(SubDevice& sub, devices)

View File

@ -51,6 +51,11 @@ public:
thread_mutex rpc_lock;
virtual bool show_samples() const
{
return false;
}
NetworkDevice(DeviceInfo& info, Stats &stats, const char *address)
: Device(info, stats, true), socket(io_service)
{

View File

@ -19,6 +19,8 @@
#include "device_task.h"
#include "buffers.h"
#include "util_algorithm.h"
#include "util_time.h"
@ -99,14 +101,18 @@ void DeviceTask::split(list<DeviceTask>& tasks, int num, int max_size)
}
}
void DeviceTask::update_progress(RenderTile *rtile)
void DeviceTask::update_progress(RenderTile *rtile, int pixel_samples)
{
if((type != PATH_TRACE) &&
(type != SHADER))
return;
if(update_progress_sample)
update_progress_sample();
if(update_progress_sample) {
if(pixel_samples == -1) {
pixel_samples = shader_w;
}
update_progress_sample(pixel_samples, rtile? rtile->sample : 0);
}
if(update_tile_sample) {
double current_time = time_dt();

View File

@ -56,10 +56,10 @@ public:
int get_subtask_count(int num, int max_size = 0);
void split(list<DeviceTask>& tasks, int num, int max_size = 0);
void update_progress(RenderTile *rtile);
void update_progress(RenderTile *rtile, int pixel_samples = -1);
function<bool(Device *device, RenderTile&)> acquire_tile;
function<void(void)> update_progress_sample;
function<void(long, int)> update_progress_sample;
function<void(RenderTile&)> update_tile_sample;
function<void(RenderTile&)> release_tile;
function<bool(void)> get_cancel;

View File

@ -39,6 +39,10 @@ public:
{
}
virtual bool show_samples() const {
return true;
}
virtual void load_kernels(const DeviceRequestedFeatures& /*requested_features*/,
vector<OpenCLProgram*> &programs)
{
@ -120,7 +124,7 @@ public:
tile.sample = sample + 1;
task->update_progress(&tile);
task->update_progress(&tile, tile.w*tile.h);
}
/* Complete kernel execution before release tile */

View File

@ -247,6 +247,10 @@ public:
}
}
virtual bool show_samples() const {
return false;
}
/* Split kernel utility functions. */
size_t get_tex_size(const char *tex_name)
{

View File

@ -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;
}

View File

@ -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;

View File

@ -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

View File

@ -323,11 +323,11 @@ ccl_device_noinline void motion_triangle_shader_setup(KernelGlobals *kg, ShaderD
* time and do a ray intersection with the resulting triangle */
ccl_device_inline bool motion_triangle_intersect(KernelGlobals *kg, Intersection *isect,
float3 P, float3 dir, float time, uint visibility, int object, int triAddr)
float3 P, float3 dir, float time, uint visibility, int object, int prim_addr)
{
/* primitive index for vertex location lookup */
int prim = kernel_tex_fetch(__prim_index, triAddr);
int fobject = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, triAddr): object;
int prim = kernel_tex_fetch(__prim_index, prim_addr);
int fobject = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, prim_addr): object;
/* get vertex locations for intersection */
float3 verts[3];
@ -340,13 +340,13 @@ ccl_device_inline bool motion_triangle_intersect(KernelGlobals *kg, Intersection
#ifdef __VISIBILITY_FLAG__
/* visibility flag test. we do it here under the assumption
* that most triangles are culled by node flags */
if(kernel_tex_fetch(__prim_visibility, triAddr) & visibility)
if(kernel_tex_fetch(__prim_visibility, prim_addr) & visibility)
#endif
{
isect->t = t;
isect->u = u;
isect->v = v;
isect->prim = triAddr;
isect->prim = prim_addr;
isect->object = object;
isect->type = PRIMITIVE_MOTION_TRIANGLE;
@ -369,14 +369,14 @@ ccl_device_inline void motion_triangle_intersect_subsurface(
float3 dir,
float time,
int object,
int triAddr,
int prim_addr,
float tmax,
uint *lcg_state,
int max_hits)
{
/* primitive index for vertex location lookup */
int prim = kernel_tex_fetch(__prim_index, triAddr);
int fobject = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, triAddr): object;
int prim = kernel_tex_fetch(__prim_index, prim_addr);
int fobject = (object == OBJECT_NONE)? kernel_tex_fetch(__prim_object, prim_addr): object;
/* get vertex locations for intersection */
float3 verts[3];
@ -413,7 +413,7 @@ ccl_device_inline void motion_triangle_intersect_subsurface(
isect->t = t;
isect->u = u;
isect->v = v;
isect->prim = triAddr;
isect->prim = prim_addr;
isect->object = object;
isect->type = PRIMITIVE_MOTION_TRIANGLE;

View File

@ -108,7 +108,7 @@ ccl_device_inline bool triangle_intersect(KernelGlobals *kg,
float3 P,
uint visibility,
int object,
int triAddr)
int prim_addr)
{
const int kx = isect_precalc->kx;
const int ky = isect_precalc->ky;
@ -118,7 +118,7 @@ ccl_device_inline bool triangle_intersect(KernelGlobals *kg,
const float Sz = isect_precalc->Sz;
/* Calculate vertices relative to ray origin. */
const uint tri_vindex = kernel_tex_fetch(__prim_tri_index, triAddr);
const uint tri_vindex = kernel_tex_fetch(__prim_tri_index, prim_addr);
#if defined(__KERNEL_AVX2__) && defined(__KERNEL_SSE__)
const avxf avxf_P(P.m128, P.m128);
@ -129,10 +129,10 @@ ccl_device_inline bool triangle_intersect(KernelGlobals *kg,
const avxf AB = tri_ab - avxf_P;
const avxf BC = tri_bc - avxf_P;
const __m256i permuteMask = _mm256_set_epi32(0x3, kz, ky, kx, 0x3, kz, ky, kx);
const __m256i permute_mask = _mm256_set_epi32(0x3, kz, ky, kx, 0x3, kz, ky, kx);
const avxf AB_k = shuffle(AB, permuteMask);
const avxf BC_k = shuffle(BC, permuteMask);
const avxf AB_k = shuffle(AB, permute_mask);
const avxf BC_k = shuffle(BC, permute_mask);
/* Akz, Akz, Bkz, Bkz, Bkz, Bkz, Ckz, Ckz */
const avxf ABBC_kz = shuffle<2>(AB_k, BC_k);
@ -155,14 +155,14 @@ ccl_device_inline bool triangle_intersect(KernelGlobals *kg,
/* By, Bx, Cy, Cx, By, Bx, Ay, Ax */
const avxf BCBA_yx = permute<3,2,7,6,3,2,1,0>(ABBC_xy);
const avxf negMask(0,0,0,0,0x80000000, 0x80000000, 0x80000000, 0x80000000);
const avxf neg_mask(0,0,0,0,0x80000000, 0x80000000, 0x80000000, 0x80000000);
/* W U V
* (AxBy-AyBx) (BxCy-ByCx) XX XX (BxBy-ByBx) (CxAy-CyAx) XX XX
*/
const avxf WUxxxxVxx_neg = _mm256_hsub_ps(ABBC_xy * BCBA_yx, negMask /* Dont care */);
const avxf WUxxxxVxx_neg = _mm256_hsub_ps(ABBC_xy * BCBA_yx, neg_mask /* Dont care */);
const avxf WUVWnegWUVW = permute<0,1,5,0,0,1,5,0>(WUxxxxVxx_neg) ^ negMask;
const avxf WUVWnegWUVW = permute<0,1,5,0,0,1,5,0>(WUxxxxVxx_neg) ^ neg_mask;
/* Calculate scaled barycentric coordinates. */
float WUVW_array[4];
@ -231,7 +231,7 @@ ccl_device_inline bool triangle_intersect(KernelGlobals *kg,
#ifdef __VISIBILITY_FLAG__
/* visibility flag test. we do it here under the assumption
* that most triangles are culled by node flags */
if(kernel_tex_fetch(__prim_visibility, triAddr) & visibility)
if(kernel_tex_fetch(__prim_visibility, prim_addr) & visibility)
#endif
{
#ifdef __KERNEL_CUDA__
@ -241,7 +241,7 @@ ccl_device_inline bool triangle_intersect(KernelGlobals *kg,
#endif
/* Normalize U, V, W, and T. */
const float inv_det = 1.0f / det;
isect->prim = triAddr;
isect->prim = prim_addr;
isect->object = object;
isect->type = PRIMITIVE_TRIANGLE;
isect->u = U * inv_det;
@ -264,7 +264,7 @@ ccl_device_inline void triangle_intersect_subsurface(
SubsurfaceIntersection *ss_isect,
float3 P,
int object,
int triAddr,
int prim_addr,
float tmax,
uint *lcg_state,
int max_hits)
@ -277,7 +277,7 @@ ccl_device_inline void triangle_intersect_subsurface(
const float Sz = isect_precalc->Sz;
/* Calculate vertices relative to ray origin. */
const uint tri_vindex = kernel_tex_fetch(__prim_tri_index, triAddr);
const uint tri_vindex = kernel_tex_fetch(__prim_tri_index, prim_addr);
const float4 tri_a = kernel_tex_fetch(__prim_tri_verts, tri_vindex+0),
tri_b = kernel_tex_fetch(__prim_tri_verts, tri_vindex+1),
tri_c = kernel_tex_fetch(__prim_tri_verts, tri_vindex+2);
@ -415,7 +415,7 @@ ccl_device_inline void triangle_intersect_subsurface(
/* record intersection */
Intersection *isect = &ss_isect->hits[hit];
isect->prim = triAddr;
isect->prim = prim_addr;
isect->object = object;
isect->type = PRIMITIVE_TRIANGLE;
isect->u = U * inv_det;

View File

@ -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);

View File

@ -141,6 +141,10 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
#endif /* __LAMP_MIS__ */
#ifdef __VOLUME__
/* Sanitize volume stack. */
if(!hit) {
kernel_volume_clean_stack(kg, state->volume_stack);
}
/* volume attenuation, emission, scatter */
if(state->volume_stack[0].shader != SHADER_NONE) {
Ray volume_ray = *ray;
@ -658,6 +662,10 @@ ccl_device_inline float4 kernel_path_integrate(KernelGlobals *kg,
#endif /* __LAMP_MIS__ */
#ifdef __VOLUME__
/* Sanitize volume stack. */
if(!hit) {
kernel_volume_clean_stack(kg, state.volume_stack);
}
/* volume attenuation, emission, scatter */
if(state.volume_stack[0].shader != SHADER_NONE) {
Ray volume_ray = ray;

View File

@ -294,6 +294,10 @@ ccl_device float4 kernel_branched_path_integrate(KernelGlobals *kg, RNG *rng, in
#endif /* __KERNEL_DEBUG__ */
#ifdef __VOLUME__
/* Sanitize volume stack. */
if(!hit) {
kernel_volume_clean_stack(kg, state.volume_stack);
}
/* volume attenuation, emission, scatter */
if(state.volume_stack[0].shader != SHADER_NONE) {
Ray volume_ray = ray;

View File

@ -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

View File

@ -192,6 +192,9 @@ CCL_NAMESPACE_BEGIN
#ifdef __NO_PATCH_EVAL__
# undef __PATCH_EVAL__
#endif
#ifdef __NO_TRANSPARENT__
# undef __TRANSPARENT_SHADOWS__
#endif
/* Random Numbers */

View File

@ -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
@ -1267,4 +1262,30 @@ ccl_device void kernel_volume_stack_update_for_subsurface(KernelGlobals *kg,
}
#endif
/* Clean stack after the last bounce.
*
* It is expected that all volumes are closed manifolds, so at the time when ray
* hits nothing (for example, it is a last bounce which goes to environment) the
* only expected volume in the stack is the world's one. All the rest volume
* entries should have been exited already.
*
* This isn't always true because of ray intersection precision issues, which
* could lead us to an infinite non-world volume in the stack, causing render
* artifacts.
*
* Use this function after the last bounce to get rid of all volumes apart from
* the world's one after the last bounce to avoid render artifacts.
*/
ccl_device_inline void kernel_volume_clean_stack(KernelGlobals *kg,
VolumeStack *volume_stack)
{
if(kernel_data.background.volume_shader != SHADER_NONE) {
/* Keep the world's volume in stack. */
volume_stack[1].shader = SHADER_NONE;
}
else {
volume_stack[0].shader = SHADER_NONE;
}
}
CCL_NAMESPACE_END

View File

@ -135,20 +135,16 @@ bool BakeManager::bake(Device *device, DeviceScene *dscene, Scene *scene, Progre
{
size_t num_pixels = bake_data->size();
progress.reset_sample();
this->num_parts = 0;
int num_samples = is_aa_pass(shader_type)? scene->integrator->aa_samples : 1;
/* calculate the total parts for the progress bar */
/* calculate the total pixel samples for the progress bar */
total_pixel_samples = 0;
for(size_t shader_offset = 0; shader_offset < num_pixels; shader_offset += m_shader_limit) {
size_t shader_size = (size_t)fminf(num_pixels - shader_offset, m_shader_limit);
DeviceTask task(DeviceTask::SHADER);
task.shader_w = shader_size;
this->num_parts += device->get_split_task_count(task);
total_pixel_samples += shader_size * num_samples;
}
this->num_samples = is_aa_pass(shader_type)? scene->integrator->aa_samples : 1;
progress.reset_sample();
progress.set_total_pixel_samples(total_pixel_samples);
for(size_t shader_offset = 0; shader_offset < num_pixels; shader_offset += m_shader_limit) {
size_t shader_size = (size_t)fminf(num_pixels - shader_offset, m_shader_limit);
@ -187,9 +183,9 @@ bool BakeManager::bake(Device *device, DeviceScene *dscene, Scene *scene, Progre
task.shader_x = 0;
task.offset = shader_offset;
task.shader_w = d_output.size();
task.num_samples = this->num_samples;
task.num_samples = num_samples;
task.get_cancel = function_bind(&Progress::get_cancel, &progress);
task.update_progress_sample = function_bind(&Progress::increment_sample_update, &progress);
task.update_progress_sample = function_bind(&Progress::add_samples_update, &progress, _1, _2);
device->task_add(task);
device->task_wait();

View File

@ -73,8 +73,7 @@ public:
bool need_update;
int num_samples;
int num_parts;
int total_pixel_samples;
private:
BakeData *m_bake_data;

View File

@ -1442,14 +1442,14 @@ void PointDensityTextureNode::compile(SVMCompiler& compiler)
else {
if(use_density) {
compiler.add_node(NODE_VALUE_F,
__float_as_int(0.0f),
compiler.stack_assign(density_out));
__float_as_int(0.0f),
compiler.stack_assign(density_out));
}
if(use_color) {
compiler.add_node(NODE_VALUE_V, compiler.stack_assign(color_out));
compiler.add_node(NODE_VALUE_V, make_float3(TEX_IMAGE_MISSING_R,
TEX_IMAGE_MISSING_G,
TEX_IMAGE_MISSING_B));
TEX_IMAGE_MISSING_G,
TEX_IMAGE_MISSING_B));
}
}
}
@ -2421,7 +2421,7 @@ void BackgroundNode::compile(SVMCompiler& compiler)
if(color_in->link || strength_in->link) {
compiler.add_node(NODE_EMISSION_WEIGHT,
compiler.stack_assign(color_in),
compiler.stack_assign(strength_in));
compiler.stack_assign(strength_in));
}
else
compiler.add_node(NODE_CLOSURE_SET_WEIGHT, color*strength);

View File

@ -67,10 +67,7 @@ Session::Session(const SessionParams& params_)
session_thread = NULL;
scene = NULL;
start_time = 0.0;
reset_time = 0.0;
preview_time = 0.0;
paused_time = 0.0;
last_update_time = 0.0;
delayed_reset.do_reset = false;
@ -201,12 +198,10 @@ void Session::run_gpu()
{
bool tiles_written = false;
start_time = time_dt();
reset_time = time_dt();
paused_time = 0.0;
last_update_time = time_dt();
progress.set_render_start_time(start_time + paused_time);
progress.set_render_start_time();
while(!progress.get_cancel()) {
/* advance to next tile */
@ -233,13 +228,9 @@ void Session::run_gpu()
update_status_time(pause, no_tiles);
while(1) {
double pause_start = time_dt();
scoped_timer pause_timer;
pause_cond.wait(pause_lock);
paused_time += time_dt() - pause_start;
if(!params.background)
progress.set_start_time(start_time + paused_time);
progress.set_render_start_time(start_time + paused_time);
progress.add_skip_time(pause_timer, params.background);
update_status_time(pause, no_tiles);
progress.set_update();
@ -255,7 +246,9 @@ void Session::run_gpu()
if(!no_tiles) {
/* update scene */
scoped_timer update_timer;
update_scene();
progress.add_skip_time(update_timer, params.background);
if(!device->error_message().empty())
progress.set_error(device->error_message());
@ -523,13 +516,9 @@ void Session::run_cpu()
update_status_time(pause, no_tiles);
while(1) {
double pause_start = time_dt();
scoped_timer pause_timer;
pause_cond.wait(pause_lock);
paused_time += time_dt() - pause_start;
if(!params.background)
progress.set_start_time(start_time + paused_time);
progress.set_render_start_time(start_time + paused_time);
progress.add_skip_time(pause_timer, params.background);
update_status_time(pause, no_tiles);
progress.set_update();
@ -550,7 +539,9 @@ void Session::run_cpu()
thread_scoped_lock buffers_lock(buffers_mutex);
/* update scene */
scoped_timer update_timer;
update_scene();
progress.add_skip_time(update_timer, params.background);
if(!device->error_message().empty())
progress.set_error(device->error_message());
@ -645,6 +636,7 @@ DeviceRequestedFeatures Session::get_requested_device_features()
BakeManager *bake_manager = scene->bake_manager;
requested_features.use_baking = bake_manager->get_baking();
requested_features.use_integrator_branched = (scene->integrator->method == Integrator::BRANCHED_PATH);
requested_features.use_transparent &= scene->integrator->transparent_shadows;
return requested_features;
}
@ -718,14 +710,14 @@ void Session::reset_(BufferParams& buffer_params, int samples)
}
tile_manager.reset(buffer_params, samples);
progress.reset_sample();
start_time = time_dt();
preview_time = 0.0;
paused_time = 0.0;
bool show_progress = params.background || tile_manager.get_num_effective_samples() != INT_MAX;
progress.set_total_pixel_samples(show_progress? tile_manager.state.total_pixel_samples : 0);
if(!params.background)
progress.set_start_time(start_time);
progress.set_render_start_time(start_time);
progress.set_start_time();
progress.set_render_start_time();
}
void Session::reset(BufferParams& buffer_params, int samples)
@ -827,61 +819,40 @@ void Session::update_scene()
void Session::update_status_time(bool show_pause, bool show_done)
{
int sample = tile_manager.state.sample;
int resolution = tile_manager.state.resolution_divider;
int num_tiles = tile_manager.state.num_tiles;
int progressive_sample = tile_manager.state.sample;
int num_samples = tile_manager.get_num_effective_samples();
int tile = tile_manager.state.num_rendered_tiles;
int num_tiles = tile_manager.state.num_tiles;
/* update status */
string status, substatus;
if(!params.progressive) {
const int progress_sample = progress.get_sample(),
num_samples = tile_manager.get_num_effective_samples();
const bool is_gpu = params.device.type == DEVICE_CUDA || params.device.type == DEVICE_OPENCL;
const bool is_multidevice = params.device.multi_devices.size() > 1;
const bool is_cpu = params.device.type == DEVICE_CPU;
const bool is_last_tile = (num_samples * num_tiles - progress_sample) < num_samples;
const bool is_last_tile = (progress.get_finished_tiles() + 1) == num_tiles;
substatus = string_printf("Path Tracing Tile %d/%d", tile, num_tiles);
if((is_gpu && !is_multidevice && !device->info.use_split_kernel) ||
(is_cpu && (num_tiles == 1 || is_last_tile)))
if(device->show_samples() || (is_cpu && is_last_tile))
{
/* When using split-kernel (OpenCL) each thread in a tile will be working on a different
* sample. Can't display sample number when device uses split-kernel
/* Some devices automatically support showing the sample number:
* - CUDADevice
* - OpenCLDevice when using the megakernel (the split kernel renders multiple samples at the same time, so the current sample isn't really defined)
* - CPUDevice when using one thread
* For these devices, the current sample is always shown.
*
* The other option is when the last tile is currently being rendered by the CPU.
*/
/* when rendering on GPU multithreading happens within single tile, as in
* tiles are handling sequentially and in this case we could display
* currently rendering sample number
* this helps a lot from feedback point of view.
* also display the info on CPU, when using 1 tile only
*/
int status_sample = progress_sample;
if(tile > 1) {
/* sample counter is global for all tiles, subtract samples
* from already finished tiles to get sample counter for
* current tile only
*/
if(is_cpu && is_last_tile && num_tiles > 1) {
status_sample = num_samples - (num_samples * num_tiles - progress_sample);
}
else {
status_sample -= (tile - 1) * num_samples;
}
}
substatus += string_printf(", Sample %d/%d", status_sample, num_samples);
substatus += string_printf(", Sample %d/%d", progress.get_current_sample(), num_samples);
}
}
else if(tile_manager.num_samples == INT_MAX)
substatus = string_printf("Path Tracing Sample %d", sample+1);
substatus = string_printf("Path Tracing Sample %d", progressive_sample+1);
else
substatus = string_printf("Path Tracing Sample %d/%d",
sample+1,
tile_manager.get_num_effective_samples());
progressive_sample+1,
num_samples);
if(show_pause) {
status = "Paused";
@ -895,22 +866,6 @@ void Session::update_status_time(bool show_pause, bool show_done)
}
progress.set_status(status, substatus);
/* update timing */
if(preview_time == 0.0 && resolution == 1)
preview_time = time_dt();
double tile_time = (tile == 0 || sample == 0)? 0.0: (time_dt() - preview_time - paused_time) / sample;
/* negative can happen when we pause a bit before rendering, can discard that */
if(preview_time < 0.0) preview_time = 0.0;
progress.set_tile(tile, tile_time);
}
void Session::update_progress_sample()
{
progress.increment_sample();
}
void Session::path_trace()
@ -922,7 +877,7 @@ void Session::path_trace()
task.release_tile = function_bind(&Session::release_tile, this, _1);
task.get_cancel = function_bind(&Progress::get_cancel, &this->progress);
task.update_tile_sample = function_bind(&Session::update_tile_sample, this, _1);
task.update_progress_sample = function_bind(&Session::update_progress_sample, this);
task.update_progress_sample = function_bind(&Progress::add_samples, &this->progress, _1, _2);
task.need_finish_queue = params.progressive_refine;
task.integrator_branched = scene->integrator->method == Integrator::BRANCHED_PATH;
task.requested_tile_size = params.tile_size;

View File

@ -145,6 +145,10 @@ public:
void device_free();
/* Returns the rendering progress or 0 if no progress can be determined
* (for example, when rendering with unlimited samples). */
float get_progress();
protected:
struct DelayedReset {
thread_mutex mutex;
@ -173,8 +177,6 @@ protected:
void update_tile_sample(RenderTile& tile);
void release_tile(RenderTile& tile);
void update_progress_sample();
bool device_use_gl;
thread *session_thread;
@ -194,10 +196,7 @@ protected:
bool kernels_loaded;
double start_time;
double reset_time;
double preview_time;
double paused_time;
/* progressive refine */
double last_update_time;

View File

@ -571,6 +571,9 @@ void ShaderManager::get_requested_graph_features(ShaderGraph *graph,
if(node->has_surface_bssrdf()) {
requested_features->use_subsurface = true;
}
if(node->has_surface_transparent()) {
requested_features->use_transparent = true;
}
}
}

View File

@ -108,36 +108,57 @@ TileManager::~TileManager()
{
}
void TileManager::reset(BufferParams& params_, int num_samples_)
static int get_divider(int w, int h, int start_resolution)
{
params = params_;
int divider = 1;
int w = params.width, h = params.height;
if(start_resolution != INT_MAX) {
while(w*h > start_resolution*start_resolution) {
w = max(1, w/2);
h = max(1, h/2);
divider *= 2;
divider <<= 1;
}
}
return divider;
}
num_samples = num_samples_;
void TileManager::reset(BufferParams& params_, int num_samples_)
{
params = params_;
set_samples(num_samples_);
state.buffer = BufferParams();
state.sample = range_start_sample - 1;
state.num_tiles = 0;
state.num_rendered_tiles = 0;
state.num_samples = 0;
state.resolution_divider = divider;
state.resolution_divider = get_divider(params.width, params.height, start_resolution);
state.tiles.clear();
}
void TileManager::set_samples(int num_samples_)
{
num_samples = num_samples_;
/* No real progress indication is possible when using unlimited samples. */
if(num_samples == INT_MAX) {
state.total_pixel_samples = 0;
}
else {
uint64_t pixel_samples = 0;
/* While rendering in the viewport, the initial preview resolution is increased to the native resolution
* before the actual rendering begins. Therefore, additional pixel samples will be rendered. */
int divider = get_divider(params.width, params.height, start_resolution) / 2;
while(divider > 1) {
int image_w = max(1, params.width/divider);
int image_h = max(1, params.height/divider);
pixel_samples += image_w * image_h;
divider >>= 1;
}
state.total_pixel_samples = pixel_samples + get_num_effective_samples() * params.width*params.height;
}
}
/* If sliced is false, splits image into tiles and assigns equal amount of tiles to every render device.

View File

@ -64,6 +64,10 @@ public:
int resolution_divider;
int num_tiles;
int num_rendered_tiles;
/* Total samples over all pixels: Generally num_samples*num_pixels,
* but can be higher due to the initial resolution division for previews. */
uint64_t total_pixel_samples;
/* This vector contains a list of tiles for every logical device in the session.
* In each list, the tiles are sorted according to the tile order setting. */
vector<list<Tile> > tiles;
@ -91,7 +95,7 @@ public:
/* Number to samples in the rendering range. */
int range_num_samples;
/* get number of actual samples to render. */
/* Get number of actual samples to render. */
int get_num_effective_samples();
protected:

View File

@ -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

View File

@ -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);

View File

@ -34,12 +34,12 @@ class Progress {
public:
Progress()
{
tile = 0;
sample = 0;
pixel_samples = 0;
total_pixel_samples = 0;
current_tile_sample = 0;
finished_tiles = 0;
start_time = time_dt();
total_time = 0.0;
render_time = 0.0;
tile_time = 0.0;
render_start_time = time_dt();
status = "Initializing";
substatus = "";
sync_status = "";
@ -62,22 +62,22 @@ public:
thread_scoped_lock lock(progress.progress_mutex);
progress.get_status(status, substatus);
progress.get_tile(tile, total_time, render_time, tile_time);
sample = progress.get_sample();
pixel_samples = progress.pixel_samples;
total_pixel_samples = progress.total_pixel_samples;
current_tile_sample = progress.get_current_sample();
return *this;
}
void reset()
{
tile = 0;
sample = 0;
pixel_samples = 0;
total_pixel_samples = 0;
current_tile_sample = 0;
finished_tiles = 0;
start_time = time_dt();
render_start_time = time_dt();
total_time = 0.0;
render_time = 0.0;
tile_time = 0.0;
status = "Initializing";
substatus = "";
sync_status = "";
@ -139,69 +139,93 @@ public:
/* tile and timing information */
void set_start_time(double start_time_)
void set_start_time()
{
thread_scoped_lock lock(progress_mutex);
start_time = start_time_;
start_time = time_dt();
}
void set_render_start_time(double render_start_time_)
void set_render_start_time()
{
thread_scoped_lock lock(progress_mutex);
render_start_time = render_start_time_;
render_start_time = time_dt();
}
void set_tile(int tile_, double tile_time_)
void add_skip_time(const scoped_timer &start_timer, bool only_render)
{
thread_scoped_lock lock(progress_mutex);
double skip_time = time_dt() - start_timer.get_start();
tile = tile_;
total_time = time_dt() - start_time;
render_time = time_dt() - render_start_time;
tile_time = tile_time_;
}
void get_tile(int& tile_, double& total_time_, double& render_time_, double& tile_time_)
{
thread_scoped_lock lock(progress_mutex);
tile_ = tile;
total_time_ = (total_time > 0.0)? total_time: 0.0;
render_time_ = (render_time > 0.0)? render_time: 0.0;
tile_time_ = tile_time;
render_start_time += skip_time;
if(!only_render) {
start_time += skip_time;
}
}
void get_time(double& total_time_, double& render_time_)
{
total_time_ = (total_time > 0.0)? total_time: 0.0;
render_time_ = (render_time > 0.0)? render_time: 0.0;
thread_scoped_lock lock(progress_mutex);
total_time_ = time_dt() - start_time;
render_time_ = time_dt() - render_start_time;
}
void reset_sample()
{
thread_scoped_lock lock(progress_mutex);
sample = 0;
pixel_samples = 0;
current_tile_sample = 0;
finished_tiles = 0;
}
void increment_sample()
void set_total_pixel_samples(uint64_t total_pixel_samples_)
{
thread_scoped_lock lock(progress_mutex);
sample++;
total_pixel_samples = total_pixel_samples_;
}
void increment_sample_update()
float get_progress()
{
increment_sample();
if(total_pixel_samples > 0) {
return ((float) pixel_samples) / total_pixel_samples;
}
return 0.0f;
}
void add_samples(uint64_t pixel_samples_, int tile_sample)
{
thread_scoped_lock lock(progress_mutex);
pixel_samples += pixel_samples_;
current_tile_sample = tile_sample;
}
void add_samples_update(uint64_t pixel_samples_, int tile_sample)
{
add_samples(pixel_samples_, tile_sample);
set_update();
}
int get_sample()
void add_finished_tile()
{
return sample;
thread_scoped_lock lock(progress_mutex);
finished_tiles++;
}
int get_current_sample()
{
/* Note that the value here always belongs to the last tile that updated,
* so it's only useful if there is only one active tile. */
return current_tile_sample;
}
int get_finished_tiles()
{
return finished_tiles;
}
/* status messages */
@ -212,8 +236,6 @@ public:
thread_scoped_lock lock(progress_mutex);
status = status_;
substatus = substatus_;
total_time = time_dt() - start_time;
render_time = time_dt() - render_start_time;
}
set_update();
@ -224,8 +246,6 @@ public:
{
thread_scoped_lock lock(progress_mutex);
substatus = substatus_;
total_time = time_dt() - start_time;
render_time = time_dt() - render_start_time;
}
set_update();
@ -237,8 +257,6 @@ public:
thread_scoped_lock lock(progress_mutex);
sync_status = status_;
sync_substatus = substatus_;
total_time = time_dt() - start_time;
render_time = time_dt() - render_start_time;
}
set_update();
@ -250,8 +268,6 @@ public:
{
thread_scoped_lock lock(progress_mutex);
sync_substatus = substatus_;
total_time = time_dt() - start_time;
render_time = time_dt() - render_start_time;
}
set_update();
@ -292,12 +308,19 @@ protected:
function<void(void)> update_cb;
function<void(void)> cancel_cb;
int tile; /* counter for rendered tiles */
int sample; /* counter of rendered samples, global for all tiles */
/* pixel_samples counts how many samples have been rendered over all pixel, not just per pixel.
* This makes the progress estimate more accurate when tiles with different sizes are used.
*
* total_pixel_samples is the total amount of pixel samples that will be rendered. */
uint64_t pixel_samples, total_pixel_samples;
/* Stores the current sample count of the last tile that called the update function.
* It's used to display the sample count if only one tile is active. */
int current_tile_sample;
/* Stores the number of tiles that's already finished.
* Used to determine whether all but the last tile are finished rendering, in which case the current_tile_sample is displayed. */
int finished_tiles;
double start_time, render_start_time;
double total_time, render_time;
double tile_time;
string status;
string substatus;

View File

@ -29,7 +29,7 @@ void time_sleep(double t);
class scoped_timer {
public:
explicit scoped_timer(double *value) : value_(value)
explicit scoped_timer(double *value = NULL) : value_(value)
{
time_start_ = time_dt();
}
@ -40,6 +40,12 @@ public:
*value_ = time_dt() - time_start_;
}
}
double get_start() const
{
return time_start_;
}
protected:
double *value_;
double time_start_;

View File

@ -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);

View File

@ -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;
@ -233,19 +380,27 @@ OCIO_ConstProcessorRcPtr *FallbackImpl::configGetProcessorWithNames(
{
OCIO_ConstColorSpaceRcPtr *cs_src = configGetColorSpace(config, srcName);
OCIO_ConstColorSpaceRcPtr *cs_dst = configGetColorSpace(config, dstName);
FallbackTransform *transform = new FallbackTransform();
if (cs_src == COLORSPACE_LINEAR && cs_dst == COLORSPACE_SRGB) {
return PROCESSOR_LINEAR_TO_SRGB;
transform->type = TRANSFORM_LINEAR_TO_SRGB;
}
else if (cs_src == COLORSPACE_SRGB && cs_dst == COLORSPACE_LINEAR) {
return PROCESSOR_SRGB_TO_LINEAR;
transform->type = TRANSFORM_SRGB_TO_LINEAR;
}
return 0;
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_ConstTransformRcPtr *transform)
{
return (OCIO_ConstProcessorRcPtr*)tfm;
FallbackProcessor *processor = new FallbackProcessor();
processor->transform = (FallbackTransform *)transform;
return (OCIO_ConstProcessorRcPtr *)processor;
}
void FallbackImpl::processorApply(OCIO_ConstProcessorRcPtr *processor,
@ -297,21 +452,13 @@ void FallbackImpl::processorApply_predivide(OCIO_ConstProcessorRcPtr *processor,
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)
{
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,
@ -338,8 +485,9 @@ 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)
@ -365,7 +513,9 @@ 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*/,
@ -383,14 +533,18 @@ void FallbackImpl::displayTransformSetView(OCIO_DisplayTransformRcPtr * /*dt*/,
{
}
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*/,
@ -432,12 +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*/)
@ -446,23 +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)

View File

@ -84,6 +84,10 @@ class QuickSmoke(Operator):
)
def execute(self, context):
if not bpy.app.build_options.mod_smoke:
self.report({'ERROR'}, "Build without Smoke modifier support")
return {'CANCELLED'}
fake_context = context.copy()
mesh_objects = [obj for obj in context.selected_objects
if obj.type == 'MESH']
@ -329,6 +333,10 @@ class QuickFluid(Operator):
)
def execute(self, context):
if not bpy.app.build_options.mod_fluid:
self.report({'ERROR'}, "Build without Fluid modifier support")
return {'CANCELLED'}
fake_context = context.copy()
mesh_objects = [obj for obj in context.selected_objects
if (obj.type == 'MESH' and 0.0 not in obj.dimensions)]

View File

@ -146,6 +146,10 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
layout.row().prop(md, "offset_type", expand=True)
def BOOLEAN(self, layout, ob, md):
if not bpy.app.build_options.mod_boolean:
layout.label("Built without Boolean modifier")
return
split = layout.split()
col = split.column()
@ -1043,6 +1047,10 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
col.prop(md, "narrowness", slider=True)
def REMESH(self, layout, ob, md):
if not bpy.app.build_options.mod_remesh:
layout.label("Built without Remesh modifier")
return
layout.prop(md, "mode")
row = layout.row()

View File

@ -44,6 +44,10 @@ class PHYSICS_PT_smoke(PhysicButtonsPanel, Panel):
def draw(self, context):
layout = self.layout
if not bpy.app.build_options.mod_smoke:
layout.label("Built without Smoke modifier")
return
md = context.smoke
ob = context.object

View File

@ -2941,11 +2941,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()
@ -2965,6 +2972,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...")
@ -2985,6 +2997,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 **********

View File

@ -129,10 +129,11 @@ enum {
G_DEBUG_GPU_MEM = (1 << 10), /* gpu memory in status bar */
G_DEBUG_DEPSGRAPH_NO_THREADS = (1 << 11), /* single threaded depsgraph */
G_DEBUG_GPU = (1 << 12), /* gpu debug */
G_DEBUG_IO = (1 << 13), /* IO Debugging (for Collada, ...)*/
};
#define G_DEBUG_ALL (G_DEBUG | G_DEBUG_FFMPEG | G_DEBUG_PYTHON | G_DEBUG_EVENTS | G_DEBUG_WM | G_DEBUG_JOBS | \
G_DEBUG_FREESTYLE | G_DEBUG_DEPSGRAPH | G_DEBUG_GPU_MEM)
G_DEBUG_FREESTYLE | G_DEBUG_DEPSGRAPH | G_DEBUG_GPU_MEM | G_DEBUG_IO)
/* G.fileflags */

View File

@ -56,7 +56,6 @@ void BKE_libblock_init_empty(struct ID *id);
void *BKE_libblock_copy(struct Main *bmain, struct ID *id) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
void *BKE_libblock_copy_nolib(struct ID *id, const bool do_action) ATTR_NONNULL();
void BKE_libblock_copy_data(struct ID *id, const struct ID *id_from, const bool do_action);
void BKE_libblock_relink(struct ID *id);
void BKE_libblock_rename(struct Main *bmain, struct ID *id, const char *name) ATTR_NONNULL();
void BLI_libblock_ensure_unique_name(struct Main *bmain, const char *name) ATTR_NONNULL();

View File

@ -64,6 +64,7 @@ void BKE_libblock_relink_ex(
struct Main *bmain, void *idv, void *old_idv, void *new_idv,
const bool us_min_never_null) ATTR_NONNULL(1, 2);
void BKE_libblock_relink_to_newid(struct ID *id) ATTR_NONNULL();
typedef void (*BKE_library_free_window_manager_cb)(struct bContext *, struct wmWindowManager *);
typedef void (*BKE_library_free_notifier_reference_cb)(const void *);

View File

@ -337,8 +337,6 @@ struct bNodeTree *ntreeAddTree(struct Main *bmain, const char *name, const char
void ntreeFreeTree(struct bNodeTree *ntree);
struct bNodeTree *ntreeCopyTree_ex(struct bNodeTree *ntree, struct Main *bmain, const bool do_id_user);
struct bNodeTree *ntreeCopyTree(struct Main *bmain, struct bNodeTree *ntree);
void ntreeSwitchID_ex(struct bNodeTree *ntree, struct ID *sce_from, struct ID *sce_to, const bool do_id_user);
void ntreeSwitchID(struct bNodeTree *ntree, struct ID *sce_from, struct ID *sce_to);
/* node->id user count */
void ntreeUserIncrefID(struct bNodeTree *ntree);
void ntreeUserDecrefID(struct bNodeTree *ntree);

View File

@ -51,7 +51,6 @@ void BKE_rigidbody_free_constraint(struct Object *ob);
struct RigidBodyOb *BKE_rigidbody_copy_object(struct Object *ob);
struct RigidBodyCon *BKE_rigidbody_copy_constraint(struct Object *ob);
void BKE_rigidbody_relink_constraint(struct RigidBodyCon *rbc);
/* Callback format for performing operations on ID-pointers for rigidbody world. */
typedef void (*RigidbodyWorldIDFunc)(struct RigidBodyWorld *rbw, struct ID **idpoin, void *userdata, int cd_flag);

View File

@ -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)

View File

@ -4404,6 +4404,7 @@ static void transformcache_free(bConstraint *con)
#ifdef WITH_ALEMBIC
CacheReader_free(data->reader);
#endif
data->reader = NULL;
}
}

View File

@ -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;
}

View File

@ -631,7 +631,7 @@ static void do_texture_effector(EffectorCache *eff, EffectorData *efd, EffectedP
force[1] = (0.5f - result->tg) * strength;
force[2] = (0.5f - result->tb) * strength;
}
else {
else if (nabla != 0) {
strength/=nabla;
tex_co[0] += nabla;
@ -671,6 +671,9 @@ static void do_texture_effector(EffectorCache *eff, EffectorData *efd, EffectedP
force[2] = (dgdx - drdy) * strength;
}
}
else {
zero_v3(force);
}
if (eff->pd->flag & PFIELD_TEX_2D) {
float fac = -dot_v3v3(force, efd->nor);

View File

@ -1157,31 +1157,6 @@ void *BKE_libblock_copy_nolib(ID *id, const bool do_action)
return idn;
}
static int id_relink_looper(void *UNUSED(user_data), ID *UNUSED(self_id), ID **id_pointer, const int cd_flag)
{
ID *id = *id_pointer;
if (id) {
/* See: NEW_ID macro */
if (id->newid) {
BKE_library_update_ID_link_user(id->newid, id, cd_flag);
*id_pointer = id->newid;
}
else if (id->tag & LIB_TAG_NEW) {
id->tag &= ~LIB_TAG_NEW;
BKE_libblock_relink(id);
}
}
return IDWALK_RET_NOP;
}
void BKE_libblock_relink(ID *id)
{
if (ID_IS_LINKED_DATABLOCK(id))
return;
BKE_library_foreach_ID_link(id, id_relink_looper, NULL, 0);
}
void BKE_library_free(Library *lib)
{
if (lib->packedfile)

View File

@ -679,6 +679,35 @@ void BKE_libblock_relink_ex(
}
}
static int id_relink_to_newid_looper(void *UNUSED(user_data), ID *UNUSED(self_id), ID **id_pointer, const int cd_flag)
{
ID *id = *id_pointer;
if (id) {
/* See: NEW_ID macro */
if (id->newid) {
BKE_library_update_ID_link_user(id->newid, id, cd_flag);
*id_pointer = id->newid;
}
else if (id->tag & LIB_TAG_NEW) {
id->tag &= ~LIB_TAG_NEW;
BKE_libblock_relink_to_newid(id);
}
}
return IDWALK_RET_NOP;
}
/** Similar to libblock_relink_ex, but is remapping IDs to their newid value if non-NULL, in given \a id.
*
* Very specific usage, not sure we'll keep it on the long run, currently only used in Object duplication code...
*/
void BKE_libblock_relink_to_newid(ID *id)
{
if (ID_IS_LINKED_DATABLOCK(id))
return;
BKE_library_foreach_ID_link(id, id_relink_to_newid_looper, NULL, 0);
}
void BKE_libblock_free_data(Main *UNUSED(bmain), ID *id)
{
if (id->properties) {

View File

@ -1307,33 +1307,6 @@ bNodeTree *ntreeCopyTree(Main *bmain, bNodeTree *ntree)
return ntreeCopyTree_ex(ntree, bmain, true);
}
/* use when duplicating scenes */
void ntreeSwitchID_ex(bNodeTree *ntree, ID *id_from, ID *id_to, const bool do_id_user)
{
bNode *node;
if (id_from == id_to) {
/* should never happen but may as well skip if it does */
return;
}
/* for scene duplication only */
for (node = ntree->nodes.first; node; node = node->next) {
if (node->id == id_from) {
if (do_id_user) {
id_us_min(id_from);
id_us_plus(id_to);
}
node->id = id_to;
}
}
}
void ntreeSwitchID(bNodeTree *ntree, ID *id_from, ID *id_to)
{
ntreeSwitchID_ex(ntree, id_from, id_to, true);
}
void ntreeUserIncrefID(bNodeTree *ntree)
{
bNode *node;

View File

@ -46,6 +46,7 @@
# include "RBI_api.h"
#endif
#include "DNA_ID.h"
#include "DNA_group_types.h"
#include "DNA_meshdata_types.h"
#include "DNA_object_types.h"
@ -217,13 +218,6 @@ RigidBodyCon *BKE_rigidbody_copy_constraint(Object *ob)
return rbcN;
}
/* preserve relationships between constraints and rigid bodies after duplication */
void BKE_rigidbody_relink_constraint(RigidBodyCon *rbc)
{
ID_NEW_REMAP(rbc->ob1);
ID_NEW_REMAP(rbc->ob2);
}
/* ************************************** */
/* Setup Utilities - Validate Sim Instances */
@ -963,12 +957,9 @@ RigidBodyWorld *BKE_rigidbody_world_copy(RigidBodyWorld *rbw)
void BKE_rigidbody_world_groups_relink(RigidBodyWorld *rbw)
{
if (rbw->group && rbw->group->id.newid)
rbw->group = (Group *)rbw->group->id.newid;
if (rbw->constraints && rbw->constraints->id.newid)
rbw->constraints = (Group *)rbw->constraints->id.newid;
if (rbw->effector_weights->group && rbw->effector_weights->group->id.newid)
rbw->effector_weights->group = (Group *)rbw->effector_weights->group->id.newid;
ID_NEW_REMAP(rbw->group);
ID_NEW_REMAP(rbw->constraints);
ID_NEW_REMAP(rbw->effector_weights->group);
}
void BKE_rigidbody_world_id_loop(RigidBodyWorld *rbw, RigidbodyWorldIDFunc func, void *userdata)

View File

@ -78,6 +78,7 @@
#include "BKE_idprop.h"
#include "BKE_image.h"
#include "BKE_library.h"
#include "BKE_library_remap.h"
#include "BKE_linestyle.h"
#include "BKE_main.h"
#include "BKE_mask.h"
@ -209,7 +210,7 @@ Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type)
if (sce->nodetree) {
/* ID's are managed on both copy and switch */
scen->nodetree = ntreeCopyTree(bmain, sce->nodetree);
ntreeSwitchID(scen->nodetree, &sce->id, &scen->id);
BKE_libblock_relink_ex(bmain, scen->nodetree, &sce->id, &scen->id, false);
}
obase = sce->base.first;

View File

@ -1074,29 +1074,31 @@ static void do_sub_effect(const SeqRenderData *context, Sequence *UNUSED(seq), f
static void do_drop_effect_byte(float facf0, float facf1, int x, int y, unsigned char *rect2i, unsigned char *rect1i, unsigned char *outi)
{
int height, width, temp, fac, fac1, fac2;
int temp, fac, fac1, fac2;
unsigned char *rt1, *rt2, *out;
int field = 1;
width = x;
height = y;
const int width = x;
const int height = y;
const int xoff = min_ii(XOFF, width);
const int yoff = min_ii(YOFF, height);
fac1 = (int) (70.0f * facf0);
fac2 = (int) (70.0f * facf1);
rt2 = (unsigned char *) (rect2i + YOFF * width);
rt1 = (unsigned char *) rect1i;
out = (unsigned char *) outi;
for (y = 0; y < height - YOFF; y++) {
rt2 = rect2i + yoff * 4 * width;
rt1 = rect1i;
out = outi;
for (y = 0; y < height - yoff; y++) {
if (field) fac = fac1;
else fac = fac2;
field = !field;
memcpy(out, rt1, sizeof(int) * XOFF);
rt1 += XOFF * 4;
out += XOFF * 4;
memcpy(out, rt1, sizeof(*out) * xoff * 4);
rt1 += xoff * 4;
out += xoff * 4;
for (x = XOFF; x < width; x++) {
for (x = xoff; x < width; x++) {
temp = ((fac * rt2[3]) >> 8);
*(out++) = MAX2(0, *rt1 - temp); rt1++;
@ -1105,37 +1107,38 @@ static void do_drop_effect_byte(float facf0, float facf1, int x, int y, unsigned
*(out++) = MAX2(0, *rt1 - temp); rt1++;
rt2 += 4;
}
rt2 += XOFF * 4;
rt2 += xoff * 4;
}
memcpy(out, rt1, sizeof(int) * YOFF * width);
memcpy(out, rt1, sizeof(*out) * yoff * 4 * width);
}
static void do_drop_effect_float(float facf0, float facf1, int x, int y, float *rect2i, float *rect1i, float *outi)
{
int height, width;
float temp, fac, fac1, fac2;
float *rt1, *rt2, *out;
int field = 1;
width = x;
height = y;
const int width = x;
const int height = y;
const int xoff = min_ii(XOFF, width);
const int yoff = min_ii(YOFF, height);
fac1 = 70.0f * facf0;
fac2 = 70.0f * facf1;
rt2 = (rect2i + YOFF * width);
rt2 = rect2i + yoff * 4 * width;
rt1 = rect1i;
out = outi;
for (y = 0; y < height - YOFF; y++) {
for (y = 0; y < height - yoff; y++) {
if (field) fac = fac1;
else fac = fac2;
field = !field;
memcpy(out, rt1, 4 * sizeof(float) * XOFF);
rt1 += XOFF * 4;
out += XOFF * 4;
memcpy(out, rt1, sizeof(*out) * xoff * 4);
rt1 += xoff * 4;
out += xoff * 4;
for (x = XOFF; x < width; x++) {
for (x = xoff; x < width; x++) {
temp = fac * rt2[3];
*(out++) = MAX2(0.0f, *rt1 - temp); rt1++;
@ -1144,9 +1147,9 @@ static void do_drop_effect_float(float facf0, float facf1, int x, int y, float *
*(out++) = MAX2(0.0f, *rt1 - temp); rt1++;
rt2 += 4;
}
rt2 += XOFF * 4;
rt2 += xoff * 4;
}
memcpy(out, rt1, 4 * sizeof(float) * YOFF * width);
memcpy(out, rt1, sizeof(*out) * yoff * 4 * width);
}
/*********************** Mul *************************/

View File

@ -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;
}

View File

@ -85,63 +85,6 @@ static const int NAN_INT = 0x7FC00000;
# define NAN_FLT (*((float *)(&NAN_INT)))
#endif
/* do not redefine functions from C99, POSIX.1-2001 or MSVC12 (partial C99) */
#if !(defined(_ISOC99_SOURCE) || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 200112L) || defined(_MSC_VER))
#ifndef sqrtf
#define sqrtf(a) ((float)sqrt(a))
#endif
#ifndef powf
#define powf(a, b) ((float)pow(a, b))
#endif
#ifndef cosf
#define cosf(a) ((float)cos(a))
#endif
#ifndef sinf
#define sinf(a) ((float)sin(a))
#endif
#ifndef acosf
#define acosf(a) ((float)acos(a))
#endif
#ifndef asinf
#define asinf(a) ((float)asin(a))
#endif
#ifndef atan2f
#define atan2f(a, b) ((float)atan2(a, b))
#endif
#ifndef tanf
#define tanf(a) ((float)tan(a))
#endif
#ifndef atanf
#define atanf(a) ((float)atan(a))
#endif
#ifndef floorf
#define floorf(a) ((float)floor(a))
#endif
#ifndef ceilf
#define ceilf(a) ((float)ceil(a))
#endif
#ifndef fabsf
#define fabsf(a) ((float)fabs(a))
#endif
#ifndef logf
#define logf(a) ((float)log(a))
#endif
#ifndef expf
#define expf(a) ((float)exp(a))
#endif
#ifndef fmodf
#define fmodf(a, b) ((float)fmod(a, b))
#endif
#ifndef hypotf
#define hypotf(a, b) ((float)hypot(a, b))
#endif
#ifndef copysignf
#define copysignf(a, b) ((float)copysign(a, b))
#endif
#endif /* C99, POSIX.1-2001 or MSVC12 (partial C99) */
#if BLI_MATH_DO_INLINE
#include "intern/math_base_inline.c"
#endif

View File

@ -46,6 +46,8 @@
/**
* Plot a line from \a p1 to \a p2 (inclusive).
*
* \note For clipped line drawing, see: http://stackoverflow.com/a/40902741/432509
*/
void BLI_bitmap_draw_2d_line_v2v2i(
const int p1[2], const int p2[2],
@ -57,33 +59,36 @@ void BLI_bitmap_draw_2d_line_v2v2i(
int x2 = p2[0];
int y2 = p2[1];
int ix;
int iy;
/* if x1 == x2 or y1 == y2, then it does not matter what we set here */
int delta_x = (x2 > x1 ? ((void)(ix = 1), x2 - x1) : ((void)(ix = -1), x1 - x2)) << 1;
int delta_y = (y2 > y1 ? ((void)(iy = 1), y2 - y1) : ((void)(iy = -1), y1 - y2)) << 1;
if (callback(x1, y1, userData) == 0) {
return;
}
/* if x1 == x2 or y1 == y2, then it does not matter what we set here */
const int sign_x = (x2 > x1) ? 1 : -1;
const int sign_y = (y2 > y1) ? 1 : -1;
const int delta_x = (sign_x == 1) ? (x2 - x1) : (x1 - x2);
const int delta_y = (sign_y == 1) ? (y2 - y1) : (y1 - y2);
const int delta_x_step = delta_x * 2;
const int delta_y_step = delta_y * 2;
if (delta_x >= delta_y) {
/* error may go below zero */
int error = delta_y - (delta_x >> 1);
int error = delta_y_step - delta_x;
while (x1 != x2) {
if (error >= 0) {
if (error || (ix > 0)) {
y1 += iy;
error -= delta_x;
if (error || (sign_x == 1)) {
y1 += sign_y;
error -= delta_x_step;
}
/* else do nothing */
}
/* else do nothing */
x1 += ix;
error += delta_y;
x1 += sign_x;
error += delta_y_step;
if (callback(x1, y1, userData) == 0) {
return;
@ -92,20 +97,20 @@ void BLI_bitmap_draw_2d_line_v2v2i(
}
else {
/* error may go below zero */
int error = delta_x - (delta_y >> 1);
int error = delta_x_step - delta_y;
while (y1 != y2) {
if (error >= 0) {
if (error || (iy > 0)) {
x1 += ix;
error -= delta_y;
if (error || (sign_y == 1)) {
x1 += sign_x;
error -= delta_y_step;
}
/* else do nothing */
}
/* else do nothing */
y1 += iy;
error += delta_x;
y1 += sign_y;
error += delta_x_step;
if (callback(x1, y1, userData) == 0) {
return;

View File

@ -4922,6 +4922,10 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
csmd->delta_cache = NULL;
csmd->delta_cache_num = 0;
}
else if (md->type == eModifierType_MeshSequenceCache) {
MeshSeqCacheModifierData *msmcd = (MeshSeqCacheModifierData *)md;
msmcd->reader = NULL;
}
}
}

View File

@ -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_linestyle_types.h"
@ -59,6 +60,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"
@ -1374,6 +1376,23 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
/* 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);
}
}
}
}
}
}
{
if (!DNA_struct_elem_find(fd->filesdna, "View3DDebug", "char", "background")) {
bScreen *screen;

View File

@ -3557,7 +3557,7 @@ static void find_bevel_edge_order(BMesh *bm, BevVert *bv, BMEdge *first_bme)
{
BMEdge *bme, *bme2;
BMIter iter;
BMFace *f;
BMFace *f, *bestf;
EdgeHalf *e;
EdgeHalf *e2;
BMLoop *l;
@ -3595,10 +3595,21 @@ static void find_bevel_edge_order(BMesh *bm, BevVert *bv, BMEdge *first_bme)
bme = e->e;
bme2 = e2->e;
BLI_assert(bme != NULL);
if (e->fnext != NULL || e2->fprev != NULL)
continue;
/* Which faces have successive loops that are for bme and bme2?
* There could be more than one. E.g., in manifold ntot==2 case.
* Prefer one that has loop in same direction as e. */
bestf = NULL;
BM_ITER_ELEM(l, &iter, bme, BM_LOOPS_OF_EDGE) {
f = l->f;
if ((l->prev->e == bme2 || l->next->e == bme2) && !e->fnext && !e2->fprev)
e->fnext = e2->fprev = f;
if ((l->prev->e == bme2 || l->next->e == bme2)) {
if (!bestf || l->v == bv->v)
bestf = f;
}
if (bestf) {
e->fnext = e2->fprev = bestf;
}
}
}
}

View File

@ -27,7 +27,6 @@
#include "COM_MixOperation.h"
#include "COM_SetColorOperation.h"
#include "COM_SetValueOperation.h"
#include "COM_ChangeHSVOperation.h"
#include "DNA_node_types.h"
#include "COM_HueSaturationValueCorrectOperation.h"

View File

@ -62,4 +62,9 @@ if(NOT WITH_HEADLESS)
add_executable(datatoc_icon ${SRC})
target_link_libraries(datatoc_icon ${PNG_LIBRARIES} ${ZLIB_LIBRARIES})
# PNG library uses pow() and floow(), so seems -lm is required for proper
# workign binary.
if(UNIX AND NOT APPLE)
target_link_libraries(datatoc_icon m)
endif()
endif()

View File

@ -154,19 +154,21 @@ void deg_graph_build_finalize(Depsgraph *graph)
}
GHASH_FOREACH_END();
ID *id = id_node->id;
if ((id->tag & LIB_TAG_ID_RECALC_ALL) &&
(id->tag & LIB_TAG_DOIT))
{
id_node->tag_update(graph);
id->tag &= ~LIB_TAG_DOIT;
}
else if (GS(id->name) == ID_OB) {
Object *object = (Object *)id;
if (object->recalc & OB_RECALC_ALL) {
if ((id_node->layers & graph->layers) != 0) {
ID *id = id_node->id;
if ((id->tag & LIB_TAG_ID_RECALC_ALL) &&
(id->tag & LIB_TAG_DOIT))
{
id_node->tag_update(graph);
id->tag &= ~LIB_TAG_DOIT;
}
else if (GS(id->name) == ID_OB) {
Object *object = (Object *)id;
if (object->recalc & OB_RECALC_ALL) {
id_node->tag_update(graph);
id->tag &= ~LIB_TAG_DOIT;
}
}
}
id_node->finalize_build();
}

View File

@ -389,12 +389,23 @@ void DepsgraphRelationBuilder::build_object(Main *bmain, Scene *scene, Object *o
add_relation(ob_ubereval_key, final_transform_key, DEPSREL_TYPE_COMPONENT_ORDER, "Temp Ubereval");
}
else {
/* operation order */
add_relation(base_op_key, final_transform_key, DEPSREL_TYPE_COMPONENT_ORDER, "Object Transform");
// XXX
add_relation(base_op_key, ob_ubereval_key, DEPSREL_TYPE_COMPONENT_ORDER, "Temp Ubereval");
add_relation(ob_ubereval_key, final_transform_key, DEPSREL_TYPE_COMPONENT_ORDER, "Temp Ubereval");
/* NOTE: Keep an eye here, we skip some relations here to "streamline"
* dependencies and avoid transitive relations which causes overhead.
* But once we get rid of uber eval node this will need reconsideration.
*/
if (ob->rigidbody_object == NULL) {
/* Rigid body will hook up another node inbetween, so skip
* relation here to avoid transitive relation.
*/
add_relation(base_op_key,
ob_ubereval_key,
DEPSREL_TYPE_COMPONENT_ORDER,
"Temp Ubereval");
}
add_relation(ob_ubereval_key,
final_transform_key,
DEPSREL_TYPE_COMPONENT_ORDER,
"Temp Ubereval");
}
@ -495,8 +506,20 @@ void DepsgraphRelationBuilder::build_object_parent(Object *ob)
case PARBONE: /* Bone Parent */
{
ComponentKey parent_key(&ob->parent->id, DEPSNODE_TYPE_BONE, ob->parsubstr);
add_relation(parent_key, ob_key, DEPSREL_TYPE_TRANSFORM, "Bone Parent");
ComponentKey parent_bone_key(&ob->parent->id,
DEPSNODE_TYPE_BONE,
ob->parsubstr);
OperationKey parent_transform_key(&ob->parent->id,
DEPSNODE_TYPE_TRANSFORM,
DEG_OPCODE_TRANSFORM_FINAL);
add_relation(parent_bone_key,
ob_key,
DEPSREL_TYPE_TRANSFORM,
"Bone Parent");
add_relation(parent_transform_key,
ob_key,
DEPSREL_TYPE_TRANSFORM,
"Armature Parent");
break;
}
@ -1037,8 +1060,10 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene)
/* time dependency */
TimeSourceKey time_src_key;
add_relation(time_src_key, init_key, DEPSREL_TYPE_TIME, "TimeSrc -> Rigidbody Reset/Rebuild (Optional)");
add_relation(time_src_key, sim_key, DEPSREL_TYPE_TIME, "TimeSrc -> Rigidbody Sim Step");
add_relation(time_src_key,
init_key,
DEPSREL_TYPE_TIME,
"TimeSrc -> Rigidbody Reset/Rebuild (Optional)");
/* objects - simulation participants */
if (rbw->group) {
@ -1061,7 +1086,6 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene)
eDepsOperation_Code trans_opcode = ob->parent ? DEG_OPCODE_TRANSFORM_PARENT : DEG_OPCODE_TRANSFORM_LOCAL;
OperationKey trans_op(&ob->id, DEPSNODE_TYPE_TRANSFORM, trans_opcode);
add_relation(trans_op, rbo_key, DEPSREL_TYPE_OPERATION, "Base Ob Transform -> RBO Sync");
add_relation(sim_key, rbo_key, DEPSREL_TYPE_COMPONENT_ORDER, "Rigidbody Sim Eval -> RBO Sync");
/* if constraints exist, those depend on the result of the rigidbody sim
@ -1073,22 +1097,34 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene)
* to control whether rigidbody eval gets interleaved into the constraint stack
*/
if (ob->constraints.first) {
OperationKey constraint_key(&ob->id, DEPSNODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_CONSTRAINTS);
add_relation(rbo_key, constraint_key, DEPSREL_TYPE_COMPONENT_ORDER, "RBO Sync -> Ob Constraints");
OperationKey constraint_key(&ob->id,
DEPSNODE_TYPE_TRANSFORM,
DEG_OPCODE_TRANSFORM_CONSTRAINTS);
add_relation(rbo_key,
constraint_key,
DEPSREL_TYPE_COMPONENT_ORDER,
"RBO Sync -> Ob Constraints");
}
else {
/* final object transform depends on rigidbody */
OperationKey done_key(&ob->id, DEPSNODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_FINAL);
add_relation(rbo_key, done_key, DEPSREL_TYPE_COMPONENT_ORDER, "RBO Sync -> Done");
// XXX: ubereval will be removed eventually, but we still need it in the meantime
OperationKey uber_key(&ob->id, DEPSNODE_TYPE_TRANSFORM, DEG_OPCODE_OBJECT_UBEREVAL);
add_relation(rbo_key, uber_key, DEPSREL_TYPE_COMPONENT_ORDER, "RBO Sync -> Uber (Temp)");
/* Final object transform depends on rigidbody.
*
* NOTE: Currently we consider final here an ubereval node.
* If it is gone we'll need to reconsider relation here.
*/
OperationKey uber_key(&ob->id,
DEPSNODE_TYPE_TRANSFORM,
DEG_OPCODE_OBJECT_UBEREVAL);
add_relation(rbo_key,
uber_key,
DEPSREL_TYPE_COMPONENT_ORDER,
"RBO Sync -> Uber (Temp)");
}
/* needed to get correct base values */
add_relation(trans_op, sim_key, DEPSREL_TYPE_OPERATION, "Base Ob Transform -> Rigidbody Sim Eval");
/* Needed to get correct base values. */
add_relation(trans_op,
sim_key,
DEPSREL_TYPE_OPERATION,
"Base Ob Transform -> Rigidbody Sim Eval");
}
}

View File

@ -304,7 +304,7 @@ static void schedule_node(TaskPool *pool, Depsgraph *graph, unsigned int layers,
deg_task_run_func,
node,
false,
TASK_PRIORITY_LOW,
TASK_PRIORITY_HIGH,
thread_id);
}
}

View File

@ -231,7 +231,7 @@ static int armature_click_extrude_invoke(bContext *C, wmOperator *op, const wmEv
copy_v3_v3(oldcurs, fp);
VECCOPY2D(mval_f, event->mval);
ED_view3d_win_to_3d(ar, fp, mval_f, tvec);
ED_view3d_win_to_3d(v3d, ar, fp, mval_f, tvec);
copy_v3_v3(fp, tvec);
/* extrude to the where new cursor is and store the operation result */

View File

@ -4993,7 +4993,7 @@ static int add_vertex_invoke(bContext *C, wmOperator *op, const wmEvent *event)
copy_v3_v3(location, ED_view3d_cursor3d_get(vc.scene, vc.v3d));
}
ED_view3d_win_to_3d_int(vc.ar, location, event->mval, location);
ED_view3d_win_to_3d_int(vc.v3d, vc.ar, location, event->mval, location);
if (use_proj) {
const float mval[2] = {UNPACK2(event->mval)};

View File

@ -353,7 +353,7 @@ static bool stroke_elem_project_fallback(
surface_offset, radius,
r_location_world, r_normal_world);
if (is_depth_found == false) {
ED_view3d_win_to_3d(cdd->vc.ar, location_fallback_depth, mval_fl, r_location_world);
ED_view3d_win_to_3d(cdd->vc.v3d, cdd->vc.ar, location_fallback_depth, mval_fl, r_location_world);
zero_v3(r_normal_local);
}
mul_v3_m4v3(r_location_local, cdd->vc.obedit->imat, r_location_world);
@ -1135,7 +1135,7 @@ static int curve_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event)
const float mval_fl[2] = {UNPACK2(event->mval)};
float center[3];
negate_v3_v3(center, cdd->vc.rv3d->ofs);
ED_view3d_win_to_3d(cdd->vc.ar, center, mval_fl, cdd->prev.location_world);
ED_view3d_win_to_3d(cdd->vc.v3d, cdd->vc.ar, center, mval_fl, cdd->prev.location_world);
copy_v3_v3(cdd->prev.location_world_valid, cdd->prev.location_world);
}

View File

@ -1799,6 +1799,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:

View File

@ -191,7 +191,7 @@ static void gp_strokepoint_convertcoords(
}
}
ED_view3d_win_to_3d(ar, fp, mvalf, p3d);
ED_view3d_win_to_3d(v3d, ar, fp, mvalf, p3d);
}
}

View File

@ -216,8 +216,14 @@ bool ED_view3d_win_to_ray_ex(
const struct ARegion *ar, const struct View3D *v3d, const float mval[2],
float r_ray_co[3], float r_ray_normal[3], float r_ray_start[3], bool do_clip);
void ED_view3d_global_to_vector(const struct RegionView3D *rv3d, const float coord[3], float vec[3]);
void ED_view3d_win_to_3d(const struct ARegion *ar, const float depth_pt[3], const float mval[2], float out[3]);
void ED_view3d_win_to_3d_int(const struct ARegion *ar, const float depth_pt[3], const int mval[2], float out[3]);
void ED_view3d_win_to_3d(
const struct View3D *v3d, const struct ARegion *ar,
const float depth_pt[3], const float mval[2],
float r_out[3]);
void ED_view3d_win_to_3d_int(
const struct View3D *v3d, const struct ARegion *ar,
const float depth_pt[3], const int mval[2],
float r_out[3]);
void ED_view3d_win_to_delta(const struct ARegion *ar, const float mval[2], float out[3], const float zfac);
void ED_view3d_win_to_origin(const struct ARegion *ar, const float mval[2], float out[3]);
void ED_view3d_win_to_vector(const struct ARegion *ar, const float mval[2], float out[3]);

View File

@ -882,7 +882,6 @@ static void depthdropper_exit(bContext *C, wmOperator *op)
*/
static void depthdropper_depth_sample_pt(bContext *C, DepthDropper *ddr, int mx, int my, float *r_depth)
{
/* we could use some clever */
wmWindow *win = CTX_wm_window(C);
ScrArea *sa = BKE_screen_find_area_xy(win->screen, SPACE_TYPE_ANY, mx, my);
@ -923,7 +922,7 @@ static void depthdropper_depth_sample_pt(bContext *C, DepthDropper *ddr, int mx,
float co_align[3];
/* quick way to get view-center aligned point */
ED_view3d_win_to_3d(ar, co, mval_center_fl, co_align);
ED_view3d_win_to_3d(v3d, ar, co, mval_center_fl, co_align);
*r_depth = len_v3v3(view_co, co_align);

View File

@ -570,8 +570,13 @@ static void ui_item_enum_expand(
/* we dont want nested rows, cols in menus */
if (radial) {
layout_radial = uiLayoutRadial(layout);
UI_block_layout_set_current(block, layout_radial);
if (layout->root->layout == layout) {
layout_radial = uiLayoutRadial(layout);
UI_block_layout_set_current(block, layout_radial);
}
else {
UI_block_layout_set_current(block, layout);
}
}
else if (layout->root->type != UI_LAYOUT_MENU) {
UI_block_layout_set_current(block, ui_item_local_sublayout(layout, layout, 1));

View File

@ -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);

View File

@ -73,6 +73,7 @@ static bool mesh_bisect_interactive_calc(
wmGesture *gesture = op->customdata;
BisectData *opdata;
View3D *v3d = CTX_wm_view3d(C);
ARegion *ar = CTX_wm_region(C);
RegionView3D *rv3d = ar->regiondata;
@ -101,7 +102,7 @@ static bool mesh_bisect_interactive_calc(
normalize_v3(plane_no); /* not needed but nicer for user */
/* point on plane, can use either start or endpoint */
ED_view3d_win_to_3d(ar, co_ref, co_a_ss, plane_co);
ED_view3d_win_to_3d(v3d, ar, co_ref, co_a_ss, plane_co);
if (opdata->is_first == false)
EDBM_redo_state_restore(opdata->mesh_backup, em, false);

View File

@ -584,7 +584,7 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, const w
copy_v3_v3(min, cent);
mul_m4_v3(vc.obedit->obmat, min); /* view space */
ED_view3d_win_to_3d_int(vc.ar, min, event->mval, min);
ED_view3d_win_to_3d_int(vc.v3d, vc.ar, min, event->mval, min);
mul_m4_v3(vc.obedit->imat, min); // back in object space
sub_v3_v3(min, cent);
@ -633,7 +633,7 @@ static int edbm_dupli_extrude_cursor_invoke(bContext *C, wmOperator *op, const w
BMOIter oiter;
copy_v3_v3(min, curs);
ED_view3d_win_to_3d_int(vc.ar, min, event->mval, min);
ED_view3d_win_to_3d_int(vc.v3d, vc.ar, min, event->mval, min);
invert_m4_m4(vc.obedit->imat, vc.obedit->obmat);
mul_m4_v3(vc.obedit->imat, min); // back in object space

View File

@ -971,7 +971,7 @@ static void knifetool_draw_angle_snapping(const KnifeTool_OpData *kcd)
copy_v3_v3(co_depth, kcd->prev.cage);
mul_m4_v3(kcd->ob->obmat, co_depth);
ED_view3d_win_to_3d(kcd->ar, co_depth, kcd->curr.mval, curr_cage_adjust);
ED_view3d_win_to_3d(kcd->vc.v3d, kcd->ar, co_depth, kcd->curr.mval, curr_cage_adjust);
mul_m4_v3(kcd->ob->imat, curr_cage_adjust);
sub_v3_v3v3(ray_dir, curr_cage_adjust, kcd->prev.cage);

View File

@ -75,6 +75,7 @@
#include "BKE_lattice.h"
#include "BKE_library.h"
#include "BKE_library_query.h"
#include "BKE_library_remap.h"
#include "BKE_key.h"
#include "BKE_main.h"
#include "BKE_material.h"
@ -1240,7 +1241,7 @@ static void copy_object_set_idnew(bContext *C)
CTX_DATA_BEGIN (C, Object *, ob, selected_editable_objects)
{
BKE_libblock_relink(&ob->id);
BKE_libblock_relink_to_newid(&ob->id);
}
CTX_DATA_END;
@ -1394,7 +1395,7 @@ 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);
BKE_libblock_relink_to_newid(&ob->id);
set_sca_new_poins_ob(ob);
BKE_id_clear_newpoin(&dob->ob->id);
@ -2200,7 +2201,7 @@ Base *ED_object_add_duplicate(Main *bmain, Scene *scene, Base *base, int dupflag
ob = basen->object;
/* link own references to the newly duplicated data [#26816] */
BKE_libblock_relink(&ob->id);
BKE_libblock_relink_to_newid(&ob->id);
set_sca_new_poins_ob(ob);
/* DAG_relations_tag_update(bmain); */ /* caller must do */

View File

@ -75,6 +75,7 @@
#include "BKE_lattice.h"
#include "BKE_library.h"
#include "BKE_library_query.h"
#include "BKE_library_remap.h"
#include "BKE_main.h"
#include "BKE_material.h"
#include "BKE_mball.h"
@ -1805,7 +1806,7 @@ static void single_object_users(Main *bmain, Scene *scene, View3D *v3d, const in
/* object and group pointers */
for (base = FIRSTBASE; base; base = base->next) {
BKE_libblock_relink(&base->object->id);
BKE_libblock_relink_to_newid(&base->object->id);
}
set_sca_new_poins();

View File

@ -4187,7 +4187,7 @@ static void sculpt_update_brush_delta(UnifiedPaintSettings *ups, Object *ob, Bru
/* compute 3d coordinate at same z from original location + mouse */
mul_v3_m4v3(loc, ob->obmat, cache->orig_grab_location);
ED_view3d_win_to_3d(cache->vc->ar, loc, mouse, grab_location);
ED_view3d_win_to_3d(cache->vc->v3d, cache->vc->ar, loc, mouse, grab_location);
/* compute delta to move verts by */
if (!cache->first_time) {

View File

@ -52,6 +52,7 @@
#include "DNA_node_types.h"
#include "DNA_packedFile_types.h"
#include "DNA_scene_types.h"
#include "DNA_screen_types.h"
#include "BKE_colortools.h"
#include "BKE_context.h"
@ -1218,7 +1219,7 @@ static Image *image_open_single(
static int image_open_exec(bContext *C, wmOperator *op)
{
Main *bmain = CTX_data_main(C);
SpaceImage *sima = CTX_wm_space_image(C); /* XXX other space types can call */
ScrArea *sa = CTX_wm_area(C);
Scene *scene = CTX_data_scene(C);
Object *obedit = CTX_data_edit_object(C);
ImageUser *iuser = NULL;
@ -1297,10 +1298,21 @@ static int image_open_exec(bContext *C, wmOperator *op)
if (iod->iuser) {
iuser = iod->iuser;
}
else if (sima) {
else if (sa->spacetype == SPACE_IMAGE) {
SpaceImage *sima = sa->spacedata.first;
ED_space_image_set(sima, scene, obedit, ima);
iuser = &sima->iuser;
}
else if (sa->spacetype == SPACE_VIEW3D) {
View3D *v3d = sa->spacedata.first;
for (BGpic *bgpic = v3d->bgpicbase.first; bgpic; bgpic = bgpic->next) {
if (bgpic->ima == ima) {
iuser = &bgpic->iuser;
break;
}
}
}
else {
Tex *tex = CTX_data_pointer_get_type(C, "texture", &RNA_Texture).data;
if (tex && tex->type == TEX_IMAGE) {

View File

@ -788,7 +788,7 @@ static void viewops_data_create_ex(bContext *C, wmOperator *op, const wmEvent *e
(float)vod->ar->winx / 2.0f,
(float)vod->ar->winy / 2.0f};
ED_view3d_win_to_3d(vod->ar, vod->dyn_ofs, mval_ar_mid, rv3d->ofs);
ED_view3d_win_to_3d(vod->v3d, vod->ar, vod->dyn_ofs, mval_ar_mid, rv3d->ofs);
negate_v3(rv3d->ofs);
}
negate_v3(vod->dyn_ofs);
@ -3285,7 +3285,7 @@ static int viewcenter_pick_invoke(bContext *C, wmOperator *op, const wmEvent *ev
else {
/* fallback to simple pan */
negate_v3_v3(new_ofs, rv3d->ofs);
ED_view3d_win_to_3d_int(ar, new_ofs, event->mval, new_ofs);
ED_view3d_win_to_3d_int(v3d, ar, new_ofs, event->mval, new_ofs);
}
negate_v3(new_ofs);
ED_view3d_smooth_view(
@ -4704,7 +4704,7 @@ void ED_view3d_cursor3d_position(bContext *C, float fp[3], const int mval[2])
if (depth_used == false) {
float depth_pt[3];
copy_v3_v3(depth_pt, fp);
ED_view3d_win_to_3d_int(ar, depth_pt, mval, fp);
ED_view3d_win_to_3d_int(v3d, ar, depth_pt, mval, fp);
}
}
@ -4953,7 +4953,7 @@ bool ED_view3d_autodist(
}
if (fallback_depth_pt) {
ED_view3d_win_to_3d_int(ar, fallback_depth_pt, mval, mouse_worldloc);
ED_view3d_win_to_3d_int(v3d, ar, fallback_depth_pt, mval, mouse_worldloc);
return true;
}
else {

View File

@ -28,6 +28,7 @@
* \ingroup spview3d
*/
#include "DNA_camera_types.h"
#include "DNA_object_types.h"
#include "DNA_screen_types.h"
#include "DNA_scene_types.h"
@ -40,6 +41,7 @@
#include "BLI_math_vector.h"
#include "BKE_camera.h"
#include "BKE_screen.h"
#include "ED_view3d.h" /* own include */
@ -462,9 +464,12 @@ bool view3d_get_view_aligned_coordinate(ARegion *ar, float fp[3], const int mval
* \param ar The region (used for the window width and height).
* \param depth_pt The reference location used to calculate the Z depth.
* \param mval The area relative location (such as event->mval converted to floats).
* \param out The resulting world-space location.
* \param r_out The resulting world-space location.
*/
void ED_view3d_win_to_3d(const ARegion *ar, const float depth_pt[3], const float mval[2], float out[3])
void ED_view3d_win_to_3d(
const View3D *v3d, const ARegion *ar,
const float depth_pt[3], const float mval[2],
float r_out[3])
{
RegionView3D *rv3d = ar->regiondata;
@ -488,11 +493,19 @@ void ED_view3d_win_to_3d(const ARegion *ar, const float depth_pt[3], const float
else {
float dx = (2.0f * mval[0] / (float)ar->winx) - 1.0f;
float dy = (2.0f * mval[1] / (float)ar->winy) - 1.0f;
if (rv3d->persp == RV3D_CAMOB) {
/* ortho camera needs offset applied */
const Camera *cam = v3d->camera->data;
const int sensor_fit = BKE_camera_sensor_fit(cam->sensor_fit, ar->winx, ar->winy);
const float zoomfac = BKE_screen_view3d_zoom_to_fac(rv3d->camzoom) * 4.0f;
dx += rv3d->camdx * zoomfac;
dy += rv3d->camdy * zoomfac;
const float aspx = ar->winx / (float)ar->winy;
const float aspy = ar->winy / (float)ar->winx;
const float shiftx = cam->shiftx * 0.5f * (sensor_fit == CAMERA_SENSOR_FIT_HOR ? 1.0f : aspy);
const float shifty = cam->shifty * 0.5f * (sensor_fit == CAMERA_SENSOR_FIT_HOR ? aspx : 1.0f);
dx += (rv3d->camdx + shiftx) * zoomfac;
dy += (rv3d->camdy + shifty) * zoomfac;
}
ray_origin[0] = (rv3d->persinv[0][0] * dx) + (rv3d->persinv[1][0] * dy) + rv3d->viewinv[3][0];
ray_origin[1] = (rv3d->persinv[0][1] * dx) + (rv3d->persinv[1][1] * dy) + rv3d->viewinv[3][1];
@ -502,13 +515,16 @@ void ED_view3d_win_to_3d(const ARegion *ar, const float depth_pt[3], const float
lambda = ray_point_factor_v3(depth_pt, ray_origin, ray_direction);
}
madd_v3_v3v3fl(out, ray_origin, ray_direction, lambda);
madd_v3_v3v3fl(r_out, ray_origin, ray_direction, lambda);
}
void ED_view3d_win_to_3d_int(const ARegion *ar, const float depth_pt[3], const int mval[2], float out[3])
void ED_view3d_win_to_3d_int(
const View3D *v3d, const ARegion *ar,
const float depth_pt[3], const int mval[2],
float r_out[3])
{
const float mval_fl[2] = {mval[0], mval[1]};
ED_view3d_win_to_3d(ar, depth_pt, mval_fl, out);
ED_view3d_win_to_3d(v3d, ar, depth_pt, mval_fl, r_out);
}
/**

View File

@ -698,7 +698,7 @@ static void view3d_ruler_free(RulerInfo *ruler_info)
static void view3d_ruler_item_project(RulerInfo *ruler_info, float r_co[3],
const int xy[2])
{
ED_view3d_win_to_3d_int(ruler_info->ar, r_co, xy, r_co);
ED_view3d_win_to_3d_int(ruler_info->sa->spacedata.first, ruler_info->ar, r_co, xy, r_co);
}
/* use for mousemove events */

View File

@ -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]);
@ -2880,7 +2880,7 @@ static void initBend(TransInfo *t)
curs = ED_view3d_cursor3d_get(t->scene, t->view);
copy_v3_v3(data->warp_sta, curs);
ED_view3d_win_to_3d(t->ar, curs, mval_fl, data->warp_end);
ED_view3d_win_to_3d(t->sa->spacedata.first, t->ar, curs, mval_fl, data->warp_end);
copy_v3_v3(data->warp_nor, t->viewinv[2]);
if (t->flag & T_EDIT) {

View File

@ -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;

View File

@ -1227,7 +1227,12 @@ const char *IMB_colormanagement_get_float_colorspace(ImBuf *ibuf)
const char *IMB_colormanagement_get_rect_colorspace(ImBuf *ibuf)
{
return ibuf->rect_colorspace->name;
if (ibuf->rect_colorspace) {
return ibuf->rect_colorspace->name;
}
else {
return IMB_colormanagement_role_colorspace_name_get(COLOR_ROLE_DEFAULT_BYTE);
}
}
/*********************** Threaded display buffer transform routines *************************/

View File

@ -769,6 +769,7 @@ PropertyType RNA_property_type(PropertyRNA *prop);
PropertySubType RNA_property_subtype(PropertyRNA *prop);
PropertyUnit RNA_property_unit(PropertyRNA *prop);
int RNA_property_flag(PropertyRNA *prop);
bool RNA_property_builtin(PropertyRNA *prop);
void *RNA_property_py_data_get(PropertyRNA *prop);
int RNA_property_array_length(PointerRNA *ptr, PropertyRNA *prop);
@ -1118,6 +1119,8 @@ const struct ListBase *RNA_function_defined_parameters(FunctionRNA *func);
/* Utility */
int RNA_parameter_flag(PropertyRNA *prop);
ParameterList *RNA_parameter_list_create(ParameterList *parms, PointerRNA *ptr, FunctionRNA *func);
void RNA_parameter_list_free(ParameterList *parms);
int RNA_parameter_list_size(ParameterList *parms);

View File

@ -137,8 +137,8 @@ void RNA_def_property_enum_bitflag_sdna(PropertyRNA *prop, const char *structnam
void RNA_def_property_pointer_sdna(PropertyRNA *prop, const char *structname, const char *propname);
void RNA_def_property_collection_sdna(PropertyRNA *prop, const char *structname, const char *propname, const char *lengthpropname);
void RNA_def_property_flag(PropertyRNA *prop, int flag);
void RNA_def_property_clear_flag(PropertyRNA *prop, int flag);
void RNA_def_property_flag(PropertyRNA *prop, PropertyFlag flag);
void RNA_def_property_clear_flag(PropertyRNA *prop, PropertyFlag flag);
void RNA_def_property_subtype(PropertyRNA *prop, PropertySubType subtype);
void RNA_def_property_array(PropertyRNA *prop, int length);
void RNA_def_property_multi_array(PropertyRNA *prop, int dimension, const int length[]);
@ -201,6 +201,9 @@ void RNA_def_function_output(FunctionRNA *func, PropertyRNA *ret);
void RNA_def_function_flag(FunctionRNA *func, int flag);
void RNA_def_function_ui_description(FunctionRNA *func, const char *description);
void RNA_def_parameter_flags(PropertyRNA *prop, PropertyFlag flag_property, ParameterFlag flag_parameter);
void RNA_def_parameter_clear_flags(PropertyRNA *prop, PropertyFlag flag_property, ParameterFlag flag_parameter);
/* Dynamic Enums
* strings are not freed, assumed pointing to static location. */

View File

@ -155,7 +155,8 @@ typedef enum PropertySubType {
} PropertySubType;
/* Make sure enums are updated with these */
/* HIGHEST FLAG IN USE: 1 << 31 */
/* HIGHEST FLAG IN USE: 1 << 31
* FREE FLAGS: 2, 3, 7, 9, 11, 13, 14, 15, 30 */
typedef enum PropertyFlag {
/* editable means the property is editable in the user
* interface, properties are editable by default except
@ -185,20 +186,6 @@ typedef enum PropertyFlag {
/* do not write in presets */
PROP_SKIP_SAVE = (1 << 28),
/* function parameter flags */
PROP_REQUIRED = (1 << 2),
PROP_OUTPUT = (1 << 3),
PROP_RNAPTR = (1 << 11),
/* This allows for non-breaking API updates, when adding non-critical new parameter to a callback function.
* This way, old py code defining funcs without that parameter would still work.
* WARNING: any parameter after the first PYFUNC_OPTIONAL one will be considered as optional!
* NOTE: only for input parameters!
*/
PROP_PYFUNC_OPTIONAL = (1 << 30),
/* registering */
PROP_REGISTER = (1 << 4),
PROP_REGISTER_OPTIONAL = PROP_REGISTER | (1 << 5),
/* numbers */
/* each value is related proportionally (object scale, image size) */
@ -229,25 +216,37 @@ typedef enum PropertyFlag {
/* need context for update function */
PROP_CONTEXT_UPDATE = (1 << 22),
PROP_CONTEXT_PROPERTY_UPDATE = (1 << 22) | (1 << 27),
PROP_CONTEXT_PROPERTY_UPDATE = PROP_CONTEXT_UPDATE | (1 << 27),
/* registering */
PROP_REGISTER = (1 << 4),
PROP_REGISTER_OPTIONAL = PROP_REGISTER | (1 << 5),
/* Use for arrays or for any data that should not have a reference kept
* most common case is functions that return arrays where the array */
PROP_THICK_WRAP = (1 << 23),
/* internal flags */
PROP_BUILTIN = (1 << 7),
PROP_EXPORT = (1 << 8),
PROP_RUNTIME = (1 << 9),
PROP_IDPROPERTY = (1 << 10),
PROP_RAW_ACCESS = (1 << 13),
PROP_RAW_ARRAY = (1 << 14),
PROP_FREE_POINTERS = (1 << 15),
PROP_EXPORT = (1 << 8), /* XXX Is this still used? makesrna.c seems to ignore it currently... */
PROP_IDPROPERTY = (1 << 10), /* This is an IDProperty, not a DNA one. */
PROP_DYNAMIC = (1 << 17), /* for dynamic arrays, and retvals of type string */
PROP_ENUM_NO_CONTEXT = (1 << 24), /* for enum that shouldn't be contextual */
PROP_ENUM_NO_TRANSLATE = (1 << 29), /* for enums not to be translated (e.g. renderlayers' names in nodes) */
} PropertyFlag;
/* Function parameters flags.
* WARNING: 16bits only. */
typedef enum ParameterFlag {
PARM_REQUIRED = (1 << 0),
PARM_OUTPUT = (1 << 1),
PARM_RNAPTR = (1 << 2),
/* This allows for non-breaking API updates, when adding non-critical new parameter to a callback function.
* This way, old py code defining funcs without that parameter would still work.
* WARNING: any parameter after the first PYFUNC_OPTIONAL one will be considered as optional!
* NOTE: only for input parameters!
*/
PARM_PYFUNC_OPTIONAL = (1 << 3),
} ParameterFlag;
struct CollectionPropertyIterator;
struct Link;
typedef int (*IteratorSkipFunc)(struct CollectionPropertyIterator *iter, void *data);

View File

@ -463,7 +463,7 @@ static const char *rna_parameter_type_name(PropertyRNA *parm)
{
PointerPropertyRNA *pparm = (PointerPropertyRNA *)parm;
if (parm->flag & PROP_RNAPTR)
if (parm->flag_parameter & PARM_RNAPTR)
return "PointerRNA";
else
return rna_find_dna_type((const char *)pparm->type);
@ -1409,23 +1409,23 @@ static void rna_set_raw_property(PropertyDefRNA *dp, PropertyRNA *prop)
if (STREQ(dp->dnatype, "char")) {
prop->rawtype = PROP_RAW_CHAR;
prop->flag |= PROP_RAW_ACCESS;
prop->flag_internal |= PROP_INTERN_RAW_ACCESS;
}
else if (STREQ(dp->dnatype, "short")) {
prop->rawtype = PROP_RAW_SHORT;
prop->flag |= PROP_RAW_ACCESS;
prop->flag_internal |= PROP_INTERN_RAW_ACCESS;
}
else if (STREQ(dp->dnatype, "int")) {
prop->rawtype = PROP_RAW_INT;
prop->flag |= PROP_RAW_ACCESS;
prop->flag_internal |= PROP_INTERN_RAW_ACCESS;
}
else if (STREQ(dp->dnatype, "float")) {
prop->rawtype = PROP_RAW_FLOAT;
prop->flag |= PROP_RAW_ACCESS;
prop->flag_internal |= PROP_INTERN_RAW_ACCESS;
}
else if (STREQ(dp->dnatype, "double")) {
prop->rawtype = PROP_RAW_DOUBLE;
prop->flag |= PROP_RAW_ACCESS;
prop->flag_internal |= PROP_INTERN_RAW_ACCESS;
}
}
@ -1553,7 +1553,7 @@ static void rna_def_property_funcs(FILE *f, StructRNA *srna, PropertyDefRNA *dp)
if (STREQ((const char *)cprop->next, "rna_iterator_array_next") &&
STREQ((const char *)cprop->get, "rna_iterator_array_get"))
{
prop->flag |= PROP_RAW_ARRAY;
prop->flag_internal |= PROP_INTERN_RAW_ARRAY;
}
cprop->get = (void *)rna_def_property_get_func(f, srna, prop, dp, (const char *)cprop->get);
@ -1599,8 +1599,9 @@ static void rna_def_property_funcs_header(FILE *f, StructRNA *srna, PropertyDefR
prop = dp->prop;
if (prop->flag & (PROP_IDPROPERTY | PROP_BUILTIN))
if (prop->flag & PROP_IDPROPERTY || prop->flag_internal & PROP_INTERN_BUILTIN) {
return;
}
func = rna_alloc_function_name(srna->identifier, rna_safe_id(prop->identifier), "");
@ -1719,8 +1720,9 @@ static void rna_def_property_funcs_header_cpp(FILE *f, StructRNA *srna, Property
prop = dp->prop;
if (prop->flag & (PROP_IDPROPERTY | PROP_BUILTIN))
if (prop->flag & PROP_IDPROPERTY || prop->flag_internal & PROP_INTERN_BUILTIN) {
return;
}
/* disabled for now to avoid msvc compiler error due to large file size */
#if 0
@ -1822,8 +1824,9 @@ static void rna_def_property_funcs_header_cpp(FILE *f, StructRNA *srna, Property
CollectionPropertyRNA *cprop = (CollectionPropertyRNA *)dp->prop;
const char *collection_funcs = "DefaultCollectionFunctions";
if (!(dp->prop->flag & (PROP_IDPROPERTY | PROP_BUILTIN)) && cprop->property.srna)
if (!(dp->prop->flag & PROP_IDPROPERTY || dp->prop->flag_internal & PROP_INTERN_BUILTIN) && cprop->property.srna) {
collection_funcs = (char *)cprop->property.srna;
}
if (cprop->item_type)
fprintf(f, "\tCOLLECTION_PROPERTY(%s, %s, %s, %s, %s, %s, %s)", collection_funcs, (const char *)cprop->item_type, srna->identifier,
@ -1879,7 +1882,7 @@ static void rna_def_struct_function_prototype_cpp(FILE *f, StructRNA *UNUSED(srn
WRITE_PARAM("Context C");
for (dp = dfunc->cont.properties.first; dp; dp = dp->next) {
int type, flag, pout;
int type, flag, flag_parameter, pout;
const char *ptrstr;
if (dp->prop == func->c_ret)
@ -1887,7 +1890,8 @@ static void rna_def_struct_function_prototype_cpp(FILE *f, StructRNA *UNUSED(srn
type = dp->prop->type;
flag = dp->prop->flag;
pout = (flag & PROP_OUTPUT);
flag_parameter = dp->prop->flag_parameter;
pout = (flag_parameter & PARM_OUTPUT);
if (flag & PROP_DYNAMIC)
ptrstr = pout ? "**" : "*";
@ -1903,7 +1907,7 @@ static void rna_def_struct_function_prototype_cpp(FILE *f, StructRNA *UNUSED(srn
WRITE_COMMA;
if (flag & PROP_DYNAMIC)
fprintf(f, "int %s%s_len, ", (flag & PROP_OUTPUT) ? "*" : "", dp->prop->identifier);
fprintf(f, "int %s%s_len, ", (flag_parameter & PARM_OUTPUT) ? "*" : "", dp->prop->identifier);
if (!(flag & PROP_DYNAMIC) && dp->prop->arraydimension)
fprintf(f, "%s %s[%u]", rna_parameter_type_cpp_name(dp->prop),
@ -1941,8 +1945,9 @@ static void rna_def_property_funcs_impl_cpp(FILE *f, StructRNA *srna, PropertyDe
prop = dp->prop;
if (prop->flag & (PROP_IDPROPERTY | PROP_BUILTIN))
if (prop->flag & PROP_IDPROPERTY || prop->flag_internal & PROP_INTERN_BUILTIN) {
return;
}
switch (prop->type) {
case PROP_BOOLEAN:
@ -2075,9 +2080,9 @@ static void rna_def_struct_function_call_impl_cpp(FILE *f, StructRNA *srna, Func
fprintf(f, "%s_len, ", dp->prop->identifier);
if (dp->prop->type == PROP_POINTER)
if ((dp->prop->flag & PROP_RNAPTR) && !(dp->prop->flag & PROP_THICK_WRAP))
if ((dp->prop->flag_parameter & PARM_RNAPTR) && !(dp->prop->flag & PROP_THICK_WRAP))
fprintf(f, "(::%s *) &%s.ptr", rna_parameter_type_name(dp->prop), rna_safe_id(dp->prop->identifier));
else if (dp->prop->flag & PROP_OUTPUT)
else if (dp->prop->flag_parameter & PARM_OUTPUT)
fprintf(f, "(::%s **) &%s->ptr.data", rna_parameter_type_name(dp->prop), rna_safe_id(dp->prop->identifier));
else
fprintf(f, "(::%s *) %s.ptr.data", rna_parameter_type_name(dp->prop), rna_safe_id(dp->prop->identifier));
@ -2110,7 +2115,7 @@ static void rna_def_struct_function_impl_cpp(FILE *f, StructRNA *srna, FunctionD
fprintf(f, "\t\tPointerRNA result;\n");
if ((dp->prop->flag & PROP_RNAPTR) == 0) {
if ((dp->prop->flag_parameter & PARM_RNAPTR) == 0) {
StructRNA *ret_srna = rna_find_struct((const char *) pprop->type);
fprintf(f, "\t\t::%s *retdata = ", rna_parameter_type_name(dp->prop));
rna_def_struct_function_call_impl_cpp(f, srna, dfunc);
@ -2221,7 +2226,7 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA
const char *funcname, *valstr;
const char *ptrstr;
const bool has_data = (dfunc->cont.properties.first != NULL);
int flag, pout, cptr, first;
int flag, flag_parameter, pout, cptr, first;
srna = dsrna->srna;
func = dfunc->func;
@ -2254,8 +2259,9 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA
for (; dparm; dparm = dparm->next) {
type = dparm->prop->type;
flag = dparm->prop->flag;
pout = (flag & PROP_OUTPUT);
cptr = ((type == PROP_POINTER) && !(flag & PROP_RNAPTR));
flag_parameter = dparm->prop->flag_parameter;
pout = (flag_parameter & PARM_OUTPUT);
cptr = ((type == PROP_POINTER) && !(flag_parameter & PARM_RNAPTR));
if (dparm->prop == func->c_ret)
ptrstr = cptr || dparm->prop->arraydimension ? "*" : "";
@ -2265,7 +2271,7 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA
/* fixed size arrays and RNA pointers are pre-allocated on the ParameterList stack, pass a pointer to it */
else if (type == PROP_POINTER || dparm->prop->arraydimension)
ptrstr = "*";
else if ((type == PROP_POINTER) && (flag & PROP_RNAPTR) && !(flag & PROP_THICK_WRAP))
else if ((type == PROP_POINTER) && (flag_parameter & PARM_RNAPTR) && !(flag & PROP_THICK_WRAP))
ptrstr = "*";
/* PROP_THICK_WRAP strings are pre-allocated on the ParameterList stack,
* but type name for string props is already (char *), so leave empty */
@ -2311,8 +2317,9 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA
for (; dparm; dparm = dparm->next) {
type = dparm->prop->type;
flag = dparm->prop->flag;
pout = (flag & PROP_OUTPUT);
cptr = ((type == PROP_POINTER) && !(flag & PROP_RNAPTR));
flag_parameter = dparm->prop->flag_parameter;
pout = (flag_parameter & PARM_OUTPUT);
cptr = ((type == PROP_POINTER) && !(flag_parameter & PARM_RNAPTR));
if (dparm->prop == func->c_ret)
fprintf(f, "\t_retdata = _data;\n");
@ -2422,7 +2429,7 @@ static void rna_def_function_funcs(FILE *f, StructDefRNA *dsrna, FunctionDefRNA
if (func->c_ret) {
dparm = rna_find_parameter_def(func->c_ret);
ptrstr = (((dparm->prop->type == PROP_POINTER) && !(dparm->prop->flag & PROP_RNAPTR)) ||
ptrstr = (((dparm->prop->type == PROP_POINTER) && !(dparm->prop->flag_parameter & PARM_RNAPTR)) ||
(dparm->prop->arraydimension)) ? "*" : "";
fprintf(f, "\t*((%s%s %s*)_retdata) = %s;\n", rna_type_struct(dparm->prop),
rna_parameter_type_name(dparm->prop), ptrstr, func->c_ret->identifier);
@ -2657,7 +2664,7 @@ static void rna_generate_static_parameter_prototypes(FILE *f, StructRNA *srna, F
PropertyDefRNA *dparm;
StructDefRNA *dsrna;
PropertyType type;
int flag, pout, cptr, first;
int flag, flag_parameter, pout, cptr, first;
const char *ptrstr;
dsrna = rna_find_struct_def(srna);
@ -2668,7 +2675,7 @@ static void rna_generate_static_parameter_prototypes(FILE *f, StructRNA *srna, F
if (dparm->prop == func->c_ret) {
if (dparm->prop->arraydimension)
fprintf(f, "XXX no array return types yet"); /* XXX not supported */
else if (dparm->prop->type == PROP_POINTER && !(dparm->prop->flag & PROP_RNAPTR))
else if (dparm->prop->type == PROP_POINTER && !(dparm->prop->flag_parameter & PARM_RNAPTR))
fprintf(f, "%s%s *", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop));
else
fprintf(f, "%s%s ", rna_type_struct(dparm->prop), rna_parameter_type_name(dparm->prop));
@ -2730,8 +2737,9 @@ static void rna_generate_static_parameter_prototypes(FILE *f, StructRNA *srna, F
for (dparm = dfunc->cont.properties.first; dparm; dparm = dparm->next) {
type = dparm->prop->type;
flag = dparm->prop->flag;
pout = (flag & PROP_OUTPUT);
cptr = ((type == PROP_POINTER) && !(flag & PROP_RNAPTR));
flag_parameter = dparm->prop->flag_parameter;
pout = (flag_parameter & PARM_OUTPUT);
cptr = ((type == PROP_POINTER) && !(flag_parameter & PARM_RNAPTR));
if (dparm->prop == func->c_ret)
continue;
@ -2986,7 +2994,7 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
else fprintf(f, "NULL,\n");
fprintf(f, "\t%d, ", prop->magic);
rna_print_c_string(f, prop->identifier);
fprintf(f, ", %d, ", prop->flag);
fprintf(f, ", %d, %d, %d, ", prop->flag, prop->flag_parameter, prop->flag_internal);
rna_print_c_string(f, prop->name); fprintf(f, ",\n\t");
rna_print_c_string(f, prop->description); fprintf(f, ",\n\t");
fprintf(f, "%d, ", prop->icon);
@ -3008,7 +3016,7 @@ static void rna_generate_property(FILE *f, StructRNA *srna, const char *nest, Pr
rna_function_string(prop->editable),
rna_function_string(prop->itemeditable));
if (prop->flag & PROP_RAW_ACCESS) rna_set_raw_offset(f, srna, prop);
if (prop->flag_internal & PROP_INTERN_RAW_ACCESS) rna_set_raw_offset(f, srna, prop);
else fprintf(f, "\t0, -1");
/* our own type - collections/arrays only */
@ -3794,9 +3802,11 @@ static const char *cpp_classes = ""
static int rna_is_collection_prop(PropertyRNA *prop)
{
if (!(prop->flag & (PROP_IDPROPERTY | PROP_BUILTIN)))
if (prop->type == PROP_COLLECTION)
if (!(prop->flag & PROP_IDPROPERTY || prop->flag_internal & PROP_INTERN_BUILTIN)) {
if (prop->type == PROP_COLLECTION) {
return 1;
}
}
return 0;
}

View File

@ -828,7 +828,7 @@ static void rna_def_ID_materials(BlenderRNA *brna)
RNA_def_function_flag(func, FUNC_USE_MAIN);
RNA_def_function_ui_description(func, "Add a new material to the data-block");
parm = RNA_def_pointer(func, "material", "Material", "", "Material to add");
RNA_def_property_flag(parm, PROP_REQUIRED);
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
func = RNA_def_function(srna, "pop", "rna_IDMaterials_pop_id");
RNA_def_function_flag(func, FUNC_USE_REPORTS | FUNC_USE_MAIN);
@ -1002,7 +1002,7 @@ static void rna_def_ID(BlenderRNA *brna)
RNA_def_function_ui_description(func, "Replace all usage in the .blend file of this ID by new given one");
RNA_def_function_flag(func, FUNC_USE_MAIN);
parm = RNA_def_pointer(func, "new_id", "ID", "", "New ID to use");
RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
func = RNA_def_function(srna, "make_local", "rna_ID_make_local");
RNA_def_function_ui_description(func, "Make this datablock local, return local one "
@ -1011,14 +1011,13 @@ static void rna_def_ID(BlenderRNA *brna)
parm = RNA_def_boolean(func, "clear_proxy", true, "",
"Whether to clear proxies (the default behavior, "
"note that if object has to be duplicated to be made local, proxies are always cleared)");
RNA_def_property_flag(parm, PROP_PYFUNC_OPTIONAL);
parm = RNA_def_pointer(func, "id", "ID", "", "This ID, or the new ID if it was copied");
RNA_def_function_return(func, parm);
func = RNA_def_function(srna, "user_of_id", "BKE_library_ID_use_ID");
RNA_def_function_ui_description(func, "Count the number of times that ID uses/references given one");
parm = RNA_def_pointer(func, "id", "ID", "", "ID to count usages");
RNA_def_property_flag(parm, PROP_REQUIRED | PROP_NEVER_NULL);
RNA_def_parameter_flags(parm, PROP_NEVER_NULL, PARM_REQUIRED);
parm = RNA_def_int(func, "count", 0, 0, INT_MAX,
"", "Number of usages/references of given id by current data-block", 0, INT_MAX);
RNA_def_function_return(func, parm);

Some files were not shown because too many files have changed in this diff Show More