Sculpt: Add Transform, Trim, and Mesh Filter operators to Sculpt menu #104718
|
@ -236,6 +236,8 @@ ForEachMacros:
|
|||
- LOOP_UNSELECTED_POINTS
|
||||
- LOOP_VISIBLE_KEYS
|
||||
- LOOP_VISIBLE_POINTS
|
||||
- LIGHT_FOREACH_BEGIN_DIRECTIONAL
|
||||
- LIGHT_FOREACH_BEGIN_LOCAL
|
||||
- LISTBASE_CIRCULAR_BACKWARD_BEGIN
|
||||
- LISTBASE_CIRCULAR_FORWARD_BEGIN
|
||||
- LISTBASE_FOREACH
|
||||
|
|
|
@ -2,15 +2,19 @@
|
|||
path = release/scripts/addons
|
||||
url = ../blender-addons.git
|
||||
branch = main
|
||||
ignore = all
|
||||
[submodule "release/scripts/addons_contrib"]
|
||||
path = release/scripts/addons_contrib
|
||||
url = ../blender-addons-contrib.git
|
||||
branch = main
|
||||
ignore = all
|
||||
[submodule "release/datafiles/locale"]
|
||||
path = release/datafiles/locale
|
||||
url = ../blender-translations.git
|
||||
branch = main
|
||||
ignore = all
|
||||
[submodule "source/tools"]
|
||||
path = source/tools
|
||||
url = ../blender-dev-tools.git
|
||||
branch = main
|
||||
ignore = all
|
||||
|
|
|
@ -524,7 +524,7 @@ endif()
|
|||
if(NOT APPLE)
|
||||
option(WITH_CYCLES_DEVICE_HIP "Enable Cycles AMD HIP support" ON)
|
||||
option(WITH_CYCLES_HIP_BINARIES "Build Cycles AMD HIP binaries" OFF)
|
||||
set(CYCLES_HIP_BINARIES_ARCH gfx1010 gfx1011 gfx1012 gfx1030 gfx1031 gfx1032 gfx1034 gfx1035 gfx1100 gfx1101 gfx1102 CACHE STRING "AMD HIP architectures to build binaries for")
|
||||
set(CYCLES_HIP_BINARIES_ARCH gfx900 gfx906 gfx90c gfx902 gfx1010 gfx1011 gfx1012 gfx1030 gfx1031 gfx1032 gfx1034 gfx1035 gfx1100 gfx1101 gfx1102 CACHE STRING "AMD HIP architectures to build binaries for")
|
||||
mark_as_advanced(WITH_CYCLES_DEVICE_HIP)
|
||||
mark_as_advanced(CYCLES_HIP_BINARIES_ARCH)
|
||||
endif()
|
||||
|
@ -625,8 +625,10 @@ mark_as_advanced(
|
|||
|
||||
# Vulkan
|
||||
option(WITH_VULKAN_BACKEND "Enable Vulkan as graphics backend (only for development)" OFF)
|
||||
option(WITH_VULKAN_GUARDEDALLOC "Use guardedalloc for host allocations done inside Vulkan (development option)" OFF)
|
||||
mark_as_advanced(
|
||||
WITH_VULKAN_BACKEND
|
||||
WITH_VULKAN_GUARDEDALLOC
|
||||
)
|
||||
|
||||
# Metal
|
||||
|
|
|
@ -22,7 +22,7 @@ elseif(UNIX AND NOT APPLE)
|
|||
)
|
||||
endif()
|
||||
|
||||
# Boolean crashes with Arm assembly, see T103423.
|
||||
# Boolean crashes with Arm assembly, see #103423.
|
||||
if(BLENDER_PLATFORM_ARM)
|
||||
set(GMP_OPTIONS
|
||||
${GMP_OPTIONS}
|
||||
|
|
|
@ -544,7 +544,7 @@ endfunction()
|
|||
function(setup_platform_linker_libs
|
||||
target
|
||||
)
|
||||
# jemalloc must be early in the list, to be before pthread (see T57998)
|
||||
# jemalloc must be early in the list, to be before pthread (see #57998).
|
||||
if(WITH_MEM_JEMALLOC)
|
||||
target_link_libraries(${target} ${JEMALLOC_LIBRARIES})
|
||||
endif()
|
||||
|
|
|
@ -440,7 +440,7 @@ string(APPEND PLATFORM_LINKFLAGS " -stdlib=libc++")
|
|||
# Make stack size more similar to Embree, required for Embree.
|
||||
string(APPEND PLATFORM_LINKFLAGS_EXECUTABLE " -Wl,-stack_size,0x100000")
|
||||
|
||||
# Suppress ranlib "has no symbols" warnings (workaround for T48250)
|
||||
# Suppress ranlib "has no symbols" warnings (workaround for #48250).
|
||||
set(CMAKE_C_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||
set(CMAKE_CXX_ARCHIVE_CREATE "<CMAKE_AR> Scr <TARGET> <LINK_FLAGS> <OBJECTS>")
|
||||
# llvm-ranlib doesn't support this flag. Xcode's libtool does.
|
||||
|
|
|
@ -121,7 +121,7 @@ if(WITH_WINDOWS_BUNDLE_CRT)
|
|||
include(InstallRequiredSystemLibraries)
|
||||
|
||||
# ucrtbase(d).dll cannot be in the manifest, due to the way windows 10 handles
|
||||
# redirects for this dll, for details see T88813.
|
||||
# redirects for this dll, for details see #88813.
|
||||
foreach(lib ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS})
|
||||
string(FIND ${lib} "ucrtbase" pos)
|
||||
if(NOT pos EQUAL -1)
|
||||
|
|
|
@ -476,7 +476,7 @@ MODULE_GROUPING = {
|
|||
|
||||
# -------------------------------BLENDER----------------------------------------
|
||||
|
||||
# converting bytes to strings, due to T30154
|
||||
# Converting bytes to strings, due to #30154.
|
||||
BLENDER_REVISION = str(bpy.app.build_hash, 'utf_8')
|
||||
BLENDER_REVISION_TIMESTAMP = bpy.app.build_commit_timestamp
|
||||
|
||||
|
@ -2200,7 +2200,7 @@ def write_rst_enum_items(basepath, key, key_no_prefix, enum_items):
|
|||
Write a single page for a static enum in RST.
|
||||
|
||||
This helps avoiding very large lists being in-lined in many places which is an issue
|
||||
especially with icons in ``bpy.types.UILayout``. See T87008.
|
||||
especially with icons in ``bpy.types.UILayout``. See #87008.
|
||||
"""
|
||||
filepath = os.path.join(basepath, "%s.rst" % key_no_prefix)
|
||||
with open(filepath, "w", encoding="utf-8") as fh:
|
||||
|
|
|
@ -1679,12 +1679,12 @@ class CyclesPreferences(bpy.types.AddonPreferences):
|
|||
import sys
|
||||
if sys.platform[:3] == "win":
|
||||
driver_version = "21.Q4"
|
||||
col.label(text="Requires AMD GPU with RDNA architecture", icon='BLANK1')
|
||||
col.label(text="Requires AMD GPU with Vega or RDNA architecture", icon='BLANK1')
|
||||
col.label(text=iface_("and AMD Radeon Pro %s driver or newer") % driver_version,
|
||||
icon='BLANK1', translate=False)
|
||||
elif sys.platform.startswith("linux"):
|
||||
driver_version = "22.10"
|
||||
col.label(text="Requires AMD GPU with RDNA architecture", icon='BLANK1')
|
||||
col.label(text="Requires AMD GPU with Vega or RDNA architecture", icon='BLANK1')
|
||||
col.label(text=iface_("and AMD driver version %s or newer") % driver_version, icon='BLANK1',
|
||||
translate=False)
|
||||
elif device_type == 'ONEAPI':
|
||||
|
|
|
@ -20,7 +20,7 @@ class CyclesPresetPanel(PresetPanel, Panel):
|
|||
@staticmethod
|
||||
def post_cb(context):
|
||||
# Modify an arbitrary built-in scene property to force a depsgraph
|
||||
# update, because add-on properties don't. (see T62325)
|
||||
# update, because add-on properties don't. (see #62325)
|
||||
render = context.scene.render
|
||||
render.filter_size = render.filter_size
|
||||
|
||||
|
|
|
@ -105,11 +105,12 @@ GPUShader *BlenderFallbackDisplayShader::bind(int width, int height)
|
|||
|
||||
/* Bind shader now to enable uniform assignment. */
|
||||
GPU_shader_bind(shader_program_);
|
||||
GPU_shader_uniform_int(shader_program_, image_texture_location_, 0);
|
||||
int slot = 0;
|
||||
GPU_shader_uniform_int_ex(shader_program_, image_texture_location_, 1, 1, &slot);
|
||||
float size[2];
|
||||
size[0] = width;
|
||||
size[1] = height;
|
||||
GPU_shader_uniform_vector(shader_program_, fullscreen_location_, 2, 1, size);
|
||||
GPU_shader_uniform_float_ex(shader_program_, fullscreen_location_, 2, 1, size);
|
||||
return shader_program_;
|
||||
}
|
||||
|
||||
|
|
|
@ -20,7 +20,7 @@ BlenderImageLoader::BlenderImageLoader(BL::Image b_image,
|
|||
: b_image(b_image),
|
||||
frame(frame),
|
||||
tile_number(tile_number),
|
||||
/* Don't free cache for preview render to avoid race condition from T93560, to be fixed
|
||||
/* Don't free cache for preview render to avoid race condition from #93560, to be fixed
|
||||
* properly later as we are close to release. */
|
||||
free_cache(!is_preview_render && !b_image.has_data())
|
||||
{
|
||||
|
@ -72,7 +72,7 @@ bool BlenderImageLoader::load_metadata(const ImageDeviceFeatures &, ImageMetaDat
|
|||
metadata.colorspace = u_colorspace_raw;
|
||||
}
|
||||
else {
|
||||
/* In some cases (e.g. T94135), the colorspace setting in Blender gets updated as part of the
|
||||
/* In some cases (e.g. #94135), the colorspace setting in Blender gets updated as part of the
|
||||
* metadata queries in this function, so update the colorspace setting here. */
|
||||
PointerRNA colorspace_ptr = b_image.colorspace_settings().ptr;
|
||||
metadata.colorspace = get_enum_identifier(colorspace_ptr, "name");
|
||||
|
|
|
@ -24,7 +24,7 @@ void BlenderSync::sync_light(BL::Object &b_parent,
|
|||
Light *light = light_map.find(key);
|
||||
|
||||
/* Check if the transform was modified, in case a linked collection is moved we do not get a
|
||||
* specific depsgraph update (T88515). This also mimics the behavior for Objects. */
|
||||
* specific depsgraph update (#88515). This also mimics the behavior for Objects. */
|
||||
const bool tfm_updated = (light && light->get_tfm() != tfm);
|
||||
|
||||
/* Update if either object or light data changed. */
|
||||
|
|
|
@ -404,7 +404,7 @@ void BlenderSession::render(BL::Depsgraph &b_depsgraph_)
|
|||
* point we know that we've got everything to render current view layer.
|
||||
*/
|
||||
/* At the moment we only free if we are not doing multi-view
|
||||
* (or if we are rendering the last view). See T58142/D4239 for discussion.
|
||||
* (or if we are rendering the last view). See #58142/D4239 for discussion.
|
||||
*/
|
||||
if (view_index == num_views - 1) {
|
||||
free_blender_memory_if_possible();
|
||||
|
|
|
@ -766,7 +766,7 @@ void BlenderSync::free_data_after_sync(BL::Depsgraph &b_depsgraph)
|
|||
(BlenderSession::headless || is_interface_locked) &&
|
||||
/* Baking re-uses the depsgraph multiple times, clearing crashes
|
||||
* reading un-evaluated mesh data which isn't aligned with the
|
||||
* geometry we're baking, see T71012. */
|
||||
* geometry we're baking, see #71012. */
|
||||
!scene->bake_manager->get_baking() &&
|
||||
/* Persistent data must main caches for performance and correctness. */
|
||||
!is_persistent_data;
|
||||
|
|
|
@ -906,7 +906,7 @@ bool HIPDevice::should_use_graphics_interop()
|
|||
* possible, but from the empiric measurements it can be considerably slower than using naive
|
||||
* pixels copy. */
|
||||
|
||||
/* Disable graphics interop for now, because of driver bug in 21.40. See T92972 */
|
||||
/* Disable graphics interop for now, because of driver bug in 21.40. See #92972 */
|
||||
# if 0
|
||||
HIPContextScope scope(this);
|
||||
|
||||
|
|
|
@ -51,7 +51,7 @@ static inline bool hipSupportsDevice(const int hipDevId)
|
|||
hipDeviceGetAttribute(&major, hipDeviceAttributeComputeCapabilityMajor, hipDevId);
|
||||
hipDeviceGetAttribute(&minor, hipDeviceAttributeComputeCapabilityMinor, hipDevId);
|
||||
|
||||
return (major >= 10);
|
||||
return (major >= 9);
|
||||
}
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -105,6 +105,7 @@ MetalDevice::MetalDevice(const DeviceInfo &info, Stats &stats, Profiler &profile
|
|||
}
|
||||
case METAL_GPU_AMD: {
|
||||
max_threads_per_threadgroup = 128;
|
||||
use_metalrt = info.use_metalrt;
|
||||
break;
|
||||
}
|
||||
case METAL_GPU_APPLE: {
|
||||
|
@ -585,7 +586,7 @@ void MetalDevice::erase_allocation(device_memory &mem)
|
|||
if (it != metal_mem_map.end()) {
|
||||
MetalMem *mmem = it->second.get();
|
||||
|
||||
/* blank out reference to MetalMem* in the launch params (fixes crash T94736) */
|
||||
/* blank out reference to MetalMem* in the launch params (fixes crash #94736) */
|
||||
if (mmem->pointer_index >= 0) {
|
||||
device_ptr *pointers = (device_ptr *)&launch_params;
|
||||
pointers[mmem->pointer_index] = 0;
|
||||
|
|
|
@ -886,7 +886,7 @@ int RenderScheduler::get_num_samples_during_navigation(int resolution_divider) c
|
|||
{
|
||||
/* Special trick for fast navigation: schedule multiple samples during fast navigation
|
||||
* (which will prefer to use lower resolution to keep up with refresh rate). This gives more
|
||||
* usable visual feedback for artists. There are a couple of tricks though. */
|
||||
* usable visual feedback for artists. */
|
||||
|
||||
if (is_denoise_active_during_update()) {
|
||||
/* When denoising is used during navigation prefer using a higher resolution with less samples
|
||||
|
@ -896,25 +896,12 @@ int RenderScheduler::get_num_samples_during_navigation(int resolution_divider) c
|
|||
return 1;
|
||||
}
|
||||
|
||||
if (resolution_divider <= pixel_size_) {
|
||||
/* When resolution divider is at or below pixel size, schedule one sample. This doesn't effect
|
||||
* the sample count at this resolution division, but instead assists in the calculation of
|
||||
* the resolution divider. */
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (resolution_divider == pixel_size_ * 2) {
|
||||
/* When resolution divider is the previous step to the final resolution, schedule two samples.
|
||||
* This is so that rendering on lower resolution does not exceed time that it takes to render
|
||||
* first sample at the full resolution. */
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* Always render 4 samples, even if scene is configured for less.
|
||||
* The idea here is to have enough information on the screen. Resolution divider of 2 allows us
|
||||
* to have 4 time extra samples, so overall worst case timing is the same as the final resolution
|
||||
* at one sample. */
|
||||
return 4;
|
||||
/* Schedule samples equal to the resolution divider up to a maximum of 4.
|
||||
* The idea is to have enough information on the screen by increasing the sample count as the
|
||||
* resolution is decreased. */
|
||||
/* NOTE: Changeing this formula will change the formula in
|
||||
* "RenderScheduler::calculate_resolution_divider_for_time()"*/
|
||||
return min(max(1, resolution_divider / pixel_size_), 4);
|
||||
}
|
||||
|
||||
bool RenderScheduler::work_need_adaptive_filter() const
|
||||
|
@ -1100,9 +1087,10 @@ void RenderScheduler::update_start_resolution_divider()
|
|||
/* TODO(sergey): Need to add hysteresis to avoid resolution divider bouncing around when actual
|
||||
* render time is somewhere on a boundary between two resolutions. */
|
||||
|
||||
/* Never increase resolution to higher than the pixel size (which is possible if the scene is
|
||||
* simple and compute device is fast). */
|
||||
start_resolution_divider_ = max(resolution_divider_for_update, pixel_size_);
|
||||
/* Don't let resolution drop below the desired one. It's better to be slow than provide an
|
||||
* unreadable viewport render. */
|
||||
start_resolution_divider_ = min(resolution_divider_for_update,
|
||||
default_start_resolution_divider_);
|
||||
|
||||
VLOG_WORK << "Calculated resolution divider is " << start_resolution_divider_;
|
||||
}
|
||||
|
@ -1187,24 +1175,24 @@ void RenderScheduler::check_time_limit_reached()
|
|||
|
||||
int RenderScheduler::calculate_resolution_divider_for_time(double desired_time, double actual_time)
|
||||
{
|
||||
/* TODO(sergey): There should a non-iterative analytical formula here. */
|
||||
const double ratio_between_times = actual_time / desired_time;
|
||||
|
||||
int resolution_divider = 1;
|
||||
/* We can pass "ratio_between_times" to "get_num_samples_during_navigation()" to get our
|
||||
* navigation samples because the equation for calculating the resolution divider is as follows:
|
||||
* "actual_time / desired_time = sqr(resolution_divider) / sample_count".
|
||||
* While "resolution_divider" is less than or equal to 4, "resolution_divider = sample_count"
|
||||
* (This relationship is determined in "get_num_samples_during_navigation()"). With some
|
||||
* substitution we end up with "actual_time / desired_time = resolution_divider" while the
|
||||
* resolution divider is less than or equal to 4. Once the resolution divider increases above 4,
|
||||
* the relationsip of "actual_time / desired_time = resolution_divider" is no longer true,
|
||||
* however the sample count retrieved from "get_num_samples_during_navigation()" is still
|
||||
* accurate if we continue using this assumption. It should be noted that the interaction between
|
||||
* pixel_size, sample count, and resolution divider are automatically accounted for and that's
|
||||
* why pixel_size isn't included in any of the equations. */
|
||||
const int navigation_samples = get_num_samples_during_navigation(
|
||||
ceil_to_int(ratio_between_times));
|
||||
|
||||
/* This algorithm iterates through resolution dividers until a divider is found that achieves
|
||||
* the desired render time. A limit of default_start_resolution_divider_ is put in place as the
|
||||
* maximum resolution divider to avoid an unreadable viewport due to a low resolution.
|
||||
* pre_resolution_division_samples and post_resolution_division_samples are used in this
|
||||
* calculation to better predict the performance impact of changing resolution divisions as
|
||||
* the sample count can also change between resolution divisions. */
|
||||
while (actual_time > desired_time && resolution_divider < default_start_resolution_divider_) {
|
||||
int pre_resolution_division_samples = get_num_samples_during_navigation(resolution_divider);
|
||||
resolution_divider = resolution_divider * 2;
|
||||
int post_resolution_division_samples = get_num_samples_during_navigation(resolution_divider);
|
||||
actual_time /= 4.0 * pre_resolution_division_samples / post_resolution_division_samples;
|
||||
}
|
||||
|
||||
return resolution_divider;
|
||||
return ceil_to_int(sqrt(navigation_samples * ratio_between_times));
|
||||
}
|
||||
|
||||
int calculate_resolution_divider_for_resolution(int width, int height, int resolution)
|
||||
|
|
|
@ -412,11 +412,12 @@ if(WITH_CYCLES_CUDA_BINARIES)
|
|||
# warn for other versions
|
||||
if((CUDA_VERSION STREQUAL "101") OR
|
||||
(CUDA_VERSION STREQUAL "102") OR
|
||||
(CUDA_VERSION_MAJOR STREQUAL "11"))
|
||||
(CUDA_VERSION_MAJOR STREQUAL "11") OR
|
||||
(CUDA_VERSION_MAJOR STREQUAL "12"))
|
||||
else()
|
||||
message(WARNING
|
||||
"CUDA version ${CUDA_VERSION_MAJOR}.${CUDA_VERSION_MINOR} detected, "
|
||||
"build may succeed but only CUDA 11, 10.2 and 10.1 have been tested")
|
||||
"build may succeed but only CUDA 12, 11, 10.2 and 10.1 have been tested")
|
||||
endif()
|
||||
|
||||
# build for each arch
|
||||
|
@ -514,6 +515,16 @@ if(WITH_CYCLES_CUDA_BINARIES)
|
|||
else()
|
||||
message(STATUS "CUDA binaries for ${arch} require CUDA 10 or earlier, skipped.")
|
||||
endif()
|
||||
elseif(${arch} MATCHES ".*_3.")
|
||||
if(DEFINED CUDA11_NVCC_EXECUTABLE)
|
||||
set(cuda_nvcc_executable ${CUDA11_NVCC_EXECUTABLE})
|
||||
set(cuda_toolkit_root_dir ${CUDA11_TOOLKIT_ROOT_DIR})
|
||||
elseif("${CUDA_VERSION}" LESS 120) # Support for sm_35, sm_37 was removed in CUDA 12
|
||||
set(cuda_nvcc_executable ${CUDA_NVCC_EXECUTABLE})
|
||||
set(cuda_toolkit_root_dir ${CUDA_TOOLKIT_ROOT_DIR})
|
||||
else()
|
||||
message(STATUS "CUDA binaries for ${arch} require CUDA 11 or earlier, skipped.")
|
||||
endif()
|
||||
elseif(${arch} MATCHES ".*_7." AND "${CUDA_VERSION}" LESS 100)
|
||||
message(STATUS "CUDA binaries for ${arch} require CUDA 10.0+, skipped.")
|
||||
elseif(${arch} MATCHES ".*_8.")
|
||||
|
|
|
@ -276,10 +276,6 @@ ccl_device_inline void bsdf_roughness_eta(const KernelGlobals kg,
|
|||
ccl_private float2 *roughness,
|
||||
ccl_private float *eta)
|
||||
{
|
||||
#ifdef __SVM__
|
||||
bool refractive = false;
|
||||
float alpha = 1.0f;
|
||||
#endif
|
||||
switch (sc->type) {
|
||||
case CLOSURE_BSDF_DIFFUSE_ID:
|
||||
*roughness = one_float2();
|
||||
|
@ -291,11 +287,13 @@ ccl_device_inline void bsdf_roughness_eta(const KernelGlobals kg,
|
|||
*eta = 1.0f;
|
||||
break;
|
||||
# ifdef __OSL__
|
||||
case CLOSURE_BSDF_PHONG_RAMP_ID:
|
||||
alpha = phong_ramp_exponent_to_roughness(((ccl_private const PhongRampBsdf *)sc)->exponent);
|
||||
case CLOSURE_BSDF_PHONG_RAMP_ID: {
|
||||
ccl_private const PhongRampBsdf *bsdf = (ccl_private const PhongRampBsdf *)sc;
|
||||
float alpha = phong_ramp_exponent_to_roughness(bsdf->exponent);
|
||||
*roughness = make_float2(alpha, alpha);
|
||||
*eta = 1.0f;
|
||||
break;
|
||||
}
|
||||
case CLOSURE_BSDF_DIFFUSE_RAMP_ID:
|
||||
*roughness = one_float2();
|
||||
*eta = 1.0f;
|
||||
|
@ -328,7 +326,7 @@ ccl_device_inline void bsdf_roughness_eta(const KernelGlobals kg,
|
|||
case CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID: {
|
||||
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
|
||||
*roughness = make_float2(bsdf->alpha_x, bsdf->alpha_y);
|
||||
refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
|
||||
const bool refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
|
||||
*eta = refractive ? 1.0f / bsdf->ior : bsdf->ior;
|
||||
break;
|
||||
}
|
||||
|
@ -350,7 +348,7 @@ ccl_device_inline void bsdf_roughness_eta(const KernelGlobals kg,
|
|||
case CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID: {
|
||||
ccl_private const MicrofacetBsdf *bsdf = (ccl_private const MicrofacetBsdf *)sc;
|
||||
*roughness = make_float2(bsdf->alpha_x, bsdf->alpha_y);
|
||||
refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
|
||||
const bool refractive = bsdf->type == CLOSURE_BSDF_MICROFACET_BECKMANN_REFRACTION_ID;
|
||||
*eta = refractive ? 1.0f / bsdf->ior : bsdf->ior;
|
||||
} break;
|
||||
case CLOSURE_BSDF_ASHIKHMIN_SHIRLEY_ID: {
|
||||
|
@ -382,11 +380,12 @@ ccl_device_inline void bsdf_roughness_eta(const KernelGlobals kg,
|
|||
((ccl_private HairBsdf *)sc)->roughness2);
|
||||
*eta = 1.0f;
|
||||
break;
|
||||
case CLOSURE_BSDF_HAIR_PRINCIPLED_ID:
|
||||
alpha = ((ccl_private PrincipledHairBSDF *)sc)->m0_roughness;
|
||||
*roughness = make_float2(alpha, alpha);
|
||||
*eta = ((ccl_private PrincipledHairBSDF *)sc)->eta;
|
||||
case CLOSURE_BSDF_HAIR_PRINCIPLED_ID: {
|
||||
ccl_private const PrincipledHairBSDF *bsdf = (ccl_private const PrincipledHairBSDF *)sc;
|
||||
*roughness = make_float2(bsdf->v_R, bsdf->v_R);
|
||||
*eta = bsdf->eta;
|
||||
break;
|
||||
}
|
||||
case CLOSURE_BSDF_PRINCIPLED_DIFFUSE_ID:
|
||||
*roughness = one_float2();
|
||||
*eta = 1.0f;
|
||||
|
|
|
@ -13,7 +13,11 @@ CCL_NAMESPACE_BEGIN
|
|||
|
||||
typedef struct PrincipledHairExtra {
|
||||
/* Geometry data. */
|
||||
float4 geom;
|
||||
float3 Y, Z;
|
||||
float gamma_o, gamma_t;
|
||||
/* Precomputed Transmission and Fresnel term */
|
||||
Spectrum T;
|
||||
float f;
|
||||
} PrincipledHairExtra;
|
||||
|
||||
typedef struct PrincipledHairBSDF {
|
||||
|
@ -21,16 +25,16 @@ typedef struct PrincipledHairBSDF {
|
|||
|
||||
/* Absorption coefficient. */
|
||||
Spectrum sigma;
|
||||
/* Variance of the underlying logistic distribution. */
|
||||
/* Variance of the underlying logistic distribution, based on longitudinal roughness. */
|
||||
float v;
|
||||
/* Scale factor of the underlying logistic distribution. */
|
||||
/* Scale factor of the underlying logistic distribution, based on azimuthal roughness. */
|
||||
float s;
|
||||
/* Alternative value for v, used for the R lobe. */
|
||||
float v_R;
|
||||
/* Cuticle tilt angle. */
|
||||
float alpha;
|
||||
/* IOR. */
|
||||
float eta;
|
||||
/* Effective variance for the diffuse bounce only. */
|
||||
float m0_roughness;
|
||||
|
||||
/* Extra closure. */
|
||||
ccl_private PrincipledHairExtra *extra;
|
||||
|
@ -131,6 +135,9 @@ ccl_device_inline float sample_trimmed_logistic(float u, float s)
|
|||
ccl_device_inline float azimuthal_scattering(
|
||||
float phi, int p, float s, float gamma_o, float gamma_t)
|
||||
{
|
||||
if (p == 3) {
|
||||
return M_1_2PI_F;
|
||||
}
|
||||
float phi_o = wrap_angle(phi - delta_phi(p, gamma_o, gamma_t));
|
||||
float val = trimmed_logistic(phi_o, s);
|
||||
return val;
|
||||
|
@ -155,27 +162,45 @@ ccl_device_inline float longitudinal_scattering(
|
|||
}
|
||||
}
|
||||
|
||||
ccl_device_forceinline float hair_get_lobe_v(const ccl_private PrincipledHairBSDF *bsdf,
|
||||
const int lobe)
|
||||
{
|
||||
if (lobe == 0) {
|
||||
return bsdf->v_R;
|
||||
}
|
||||
else if (lobe == 1) {
|
||||
return 0.25f * bsdf->v;
|
||||
}
|
||||
else {
|
||||
return 4.0f * bsdf->v;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __HAIR__
|
||||
/* Set up the hair closure. */
|
||||
ccl_device int bsdf_principled_hair_setup(ccl_private ShaderData *sd,
|
||||
ccl_private PrincipledHairBSDF *bsdf)
|
||||
ccl_private PrincipledHairBSDF *bsdf,
|
||||
float u_rough,
|
||||
float u_coat_rough,
|
||||
float v_rough)
|
||||
{
|
||||
bsdf->type = CLOSURE_BSDF_HAIR_PRINCIPLED_ID;
|
||||
bsdf->v = clamp(bsdf->v, 0.001f, 1.0f);
|
||||
bsdf->s = clamp(bsdf->s, 0.001f, 1.0f);
|
||||
/* Apply Primary Reflection Roughness modifier. */
|
||||
bsdf->m0_roughness = clamp(bsdf->m0_roughness * bsdf->v, 0.001f, 1.0f);
|
||||
u_rough = clamp(u_rough, 0.001f, 1.0f);
|
||||
v_rough = clamp(v_rough, 0.001f, 1.0f);
|
||||
/* u_coat_rough is a multiplier that modifies u_rough for the R lobe. */
|
||||
float u_R_roughness = clamp(u_coat_rough * u_rough, 0.001f, 1.0f);
|
||||
|
||||
/* Map from roughness_u and roughness_v to variance and scale factor. */
|
||||
bsdf->v = sqr(0.726f * bsdf->v + 0.812f * sqr(bsdf->v) + 3.700f * pow20(bsdf->v));
|
||||
bsdf->s = (0.265f * bsdf->s + 1.194f * sqr(bsdf->s) + 5.372f * pow22(bsdf->s)) * M_SQRT_PI_8_F;
|
||||
bsdf->m0_roughness = sqr(0.726f * bsdf->m0_roughness + 0.812f * sqr(bsdf->m0_roughness) +
|
||||
3.700f * pow20(bsdf->m0_roughness));
|
||||
bsdf->type = CLOSURE_BSDF_HAIR_PRINCIPLED_ID;
|
||||
|
||||
/* Map from the azimuthal and the two longitudinal roughnesses to variance and scale factor. */
|
||||
bsdf->v = sqr(0.726f * u_rough + 0.812f * sqr(u_rough) + 3.700f * pow20(u_rough));
|
||||
bsdf->v_R = sqr(0.726f * u_R_roughness + 0.812f * sqr(u_R_roughness) +
|
||||
3.700f * pow20(u_R_roughness));
|
||||
bsdf->s = (0.265f * v_rough + 1.194f * sqr(v_rough) + 5.372f * pow22(v_rough)) * M_SQRT_PI_8_F;
|
||||
|
||||
/* Compute local frame, aligned to curve tangent and ray direction. */
|
||||
float3 X = safe_normalize(sd->dPdu);
|
||||
float3 Y = safe_normalize(cross(X, sd->wi));
|
||||
float3 Z = safe_normalize(cross(X, Y));
|
||||
bsdf->extra->Y = safe_normalize(cross(X, sd->wi));
|
||||
bsdf->extra->Z = safe_normalize(cross(X, bsdf->extra->Y));
|
||||
|
||||
/* h -1..0..1 means the rays goes from grazing the hair, to hitting it at
|
||||
* the center, to grazing the other edge. This is the sine of the angle
|
||||
|
@ -183,13 +208,28 @@ ccl_device int bsdf_principled_hair_setup(ccl_private ShaderData *sd,
|
|||
|
||||
/* TODO: we convert this value to a cosine later and discard the sign, so
|
||||
* we could probably save some operations. */
|
||||
float h = (sd->type & PRIMITIVE_CURVE_RIBBON) ? -sd->v : dot(cross(sd->Ng, X), Z);
|
||||
float h = (sd->type & PRIMITIVE_CURVE_RIBBON) ? -sd->v : dot(cross(sd->Ng, X), bsdf->extra->Z);
|
||||
|
||||
kernel_assert(fabsf(h) < 1.0f + 1e-4f);
|
||||
kernel_assert(isfinite_safe(Y));
|
||||
kernel_assert(isfinite_safe(h));
|
||||
|
||||
bsdf->extra->geom = make_float4(Y.x, Y.y, Y.z, h);
|
||||
const float sin_theta_o = dot(sd->wi, X);
|
||||
const float cos_theta_o = cos_from_sin(sin_theta_o);
|
||||
|
||||
const float sin_theta_t = sin_theta_o / bsdf->eta;
|
||||
const float cos_theta_t = cos_from_sin(sin_theta_t);
|
||||
|
||||
const float sin_gamma_o = h;
|
||||
const float cos_gamma_o = cos_from_sin(sin_gamma_o);
|
||||
bsdf->extra->gamma_o = safe_asinf(sin_gamma_o);
|
||||
|
||||
const float sin_gamma_t = sin_gamma_o * cos_theta_o / sqrtf(sqr(bsdf->eta) - sqr(sin_theta_o));
|
||||
const float cos_gamma_t = cos_from_sin(sin_gamma_t);
|
||||
bsdf->extra->gamma_t = safe_asinf(sin_gamma_t);
|
||||
|
||||
bsdf->extra->T = exp(-bsdf->sigma * (2.0f * cos_gamma_t / cos_theta_t));
|
||||
bsdf->extra->f = fresnel_dielectric_cos(cos_theta_o * cos_gamma_o, bsdf->eta);
|
||||
|
||||
return SD_BSDF | SD_BSDF_HAS_EVAL | SD_BSDF_NEEDS_LCG | SD_BSDF_HAS_TRANSMISSION;
|
||||
}
|
||||
|
@ -198,35 +238,35 @@ ccl_device int bsdf_principled_hair_setup(ccl_private ShaderData *sd,
|
|||
|
||||
/* Given the Fresnel term and transmittance, generate the attenuation terms for each bounce. */
|
||||
ccl_device_inline void hair_attenuation(
|
||||
KernelGlobals kg, float f, Spectrum T, ccl_private Spectrum *Ap, ccl_private float *Ap_energy)
|
||||
KernelGlobals kg, float f, Spectrum T, ccl_private Spectrum *Ap, ccl_private float *lobe_pdf)
|
||||
{
|
||||
/* Primary specular (R). */
|
||||
Ap[0] = make_spectrum(f);
|
||||
Ap_energy[0] = f;
|
||||
lobe_pdf[0] = f;
|
||||
|
||||
/* Transmission (TT). */
|
||||
Spectrum col = sqr(1.0f - f) * T;
|
||||
Ap[1] = col;
|
||||
Ap_energy[1] = spectrum_to_gray(kg, col);
|
||||
lobe_pdf[1] = spectrum_to_gray(kg, col);
|
||||
|
||||
/* Secondary specular (TRT). */
|
||||
col *= T * f;
|
||||
Ap[2] = col;
|
||||
Ap_energy[2] = spectrum_to_gray(kg, col);
|
||||
lobe_pdf[2] = spectrum_to_gray(kg, col);
|
||||
|
||||
/* Residual component (TRRT+). */
|
||||
col *= safe_divide(T * f, one_spectrum() - T * f);
|
||||
Ap[3] = col;
|
||||
Ap_energy[3] = spectrum_to_gray(kg, col);
|
||||
lobe_pdf[3] = spectrum_to_gray(kg, col);
|
||||
|
||||
/* Normalize sampling weights. */
|
||||
float totweight = Ap_energy[0] + Ap_energy[1] + Ap_energy[2] + Ap_energy[3];
|
||||
float totweight = lobe_pdf[0] + lobe_pdf[1] + lobe_pdf[2] + lobe_pdf[3];
|
||||
float fac = safe_divide(1.0f, totweight);
|
||||
|
||||
Ap_energy[0] *= fac;
|
||||
Ap_energy[1] *= fac;
|
||||
Ap_energy[2] *= fac;
|
||||
Ap_energy[3] *= fac;
|
||||
lobe_pdf[0] *= fac;
|
||||
lobe_pdf[1] *= fac;
|
||||
lobe_pdf[2] *= fac;
|
||||
lobe_pdf[3] *= fac;
|
||||
}
|
||||
|
||||
/* Given the tilt angle, generate the rotated theta_i for the different bounces. */
|
||||
|
@ -248,91 +288,120 @@ ccl_device_inline void hair_alpha_angles(float sin_theta_i,
|
|||
angles[3] = fabsf(cos_theta_i * cos_1alpha + sin_theta_i * sin_1alpha);
|
||||
angles[4] = sin_theta_i * cos_4alpha - cos_theta_i * sin_4alpha;
|
||||
angles[5] = fabsf(cos_theta_i * cos_4alpha + sin_theta_i * sin_4alpha);
|
||||
angles[6] = sin_theta_i;
|
||||
angles[7] = cos_theta_i;
|
||||
}
|
||||
|
||||
/* Since most of the implementation is the same between sampling and evaluation,
|
||||
* this shared function implements both.
|
||||
* For evaluation, wo is an input, and randu/randv are ignored.
|
||||
* For sampling, wo is an output, and randu/randv are used to pick it.
|
||||
*/
|
||||
template<bool do_sample>
|
||||
ccl_device int bsdf_principled_hair_impl(KernelGlobals kg,
|
||||
ccl_private const PrincipledHairBSDF *bsdf,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private float3 *wo,
|
||||
ccl_private Spectrum *F,
|
||||
ccl_private float *pdf,
|
||||
float randu,
|
||||
float randv)
|
||||
{
|
||||
const float3 X = safe_normalize(sd->dPdu);
|
||||
const float3 Y = bsdf->extra->Y;
|
||||
const float3 Z = bsdf->extra->Z;
|
||||
kernel_assert(fabsf(dot(X, Y)) < 1e-3f);
|
||||
|
||||
const float gamma_o = bsdf->extra->gamma_o;
|
||||
const float gamma_t = bsdf->extra->gamma_t;
|
||||
|
||||
const float3 local_O = make_float3(dot(sd->wi, X), dot(sd->wi, Y), dot(sd->wi, Z));
|
||||
const float sin_theta_o = local_O.x;
|
||||
const float cos_theta_o = cos_from_sin(sin_theta_o);
|
||||
const float phi_o = atan2f(local_O.z, local_O.y);
|
||||
|
||||
Spectrum Ap[4];
|
||||
float lobe_pdf[4];
|
||||
hair_attenuation(kg, bsdf->extra->f, bsdf->extra->T, Ap, lobe_pdf);
|
||||
|
||||
float sin_theta_i, cos_theta_i, phi;
|
||||
int sampled_p = 0;
|
||||
if (do_sample) {
|
||||
/* Pick lobe for sampline */
|
||||
for (; sampled_p < 3; sampled_p++) {
|
||||
if (randu < lobe_pdf[sampled_p]) {
|
||||
break;
|
||||
}
|
||||
randu -= lobe_pdf[sampled_p];
|
||||
}
|
||||
|
||||
/* Sample incoming direction */
|
||||
float v = hair_get_lobe_v(bsdf, sampled_p);
|
||||
float randw = lcg_step_float(&sd->lcg_state), randx = lcg_step_float(&sd->lcg_state);
|
||||
randw = max(randw, 1e-5f);
|
||||
const float fac = 1.0f + v * logf(randw + (1.0f - randw) * expf(-2.0f / v));
|
||||
sin_theta_i = -fac * sin_theta_o + cos_from_sin(fac) * cosf(M_2PI_F * randx) * cos_theta_o;
|
||||
cos_theta_i = cos_from_sin(sin_theta_i);
|
||||
|
||||
if (sampled_p < 3) {
|
||||
float angles[8];
|
||||
hair_alpha_angles(sin_theta_i, cos_theta_i, -bsdf->alpha, angles);
|
||||
sin_theta_i = angles[2 * sampled_p];
|
||||
cos_theta_i = angles[2 * sampled_p + 1];
|
||||
|
||||
phi = delta_phi(sampled_p, gamma_o, gamma_t) + sample_trimmed_logistic(randv, bsdf->s);
|
||||
}
|
||||
else {
|
||||
phi = M_2PI_F * randv;
|
||||
}
|
||||
|
||||
const float phi_i = phi_o + phi;
|
||||
*wo = X * sin_theta_i + Y * cos_theta_i * cosf(phi_i) + Z * cos_theta_i * sinf(phi_i);
|
||||
}
|
||||
else {
|
||||
const float3 local_I = make_float3(dot(*wo, X), dot(*wo, Y), dot(*wo, Z));
|
||||
|
||||
sin_theta_i = local_I.x;
|
||||
cos_theta_i = cos_from_sin(sin_theta_i);
|
||||
|
||||
const float phi_i = atan2f(local_I.z, local_I.y);
|
||||
phi = phi_i - phi_o;
|
||||
}
|
||||
|
||||
/* Evaluate throughput. */
|
||||
float angles[8];
|
||||
hair_alpha_angles(sin_theta_i, cos_theta_i, bsdf->alpha, angles);
|
||||
|
||||
*F = zero_spectrum();
|
||||
*pdf = 0.0f;
|
||||
|
||||
for (int p = 0; p < 4; p++) {
|
||||
const float Mp = longitudinal_scattering(
|
||||
angles[2 * p], angles[2 * p + 1], sin_theta_o, cos_theta_o, hair_get_lobe_v(bsdf, p));
|
||||
const float Np = azimuthal_scattering(phi, p, bsdf->s, gamma_o, gamma_t);
|
||||
*F += Ap[p] * Mp * Np;
|
||||
*pdf += lobe_pdf[p] * Mp * Np;
|
||||
kernel_assert(isfinite_safe(*F) && isfinite_safe(*pdf));
|
||||
}
|
||||
|
||||
return sampled_p;
|
||||
}
|
||||
|
||||
/* Evaluation function for our shader. */
|
||||
ccl_device Spectrum bsdf_principled_hair_eval(KernelGlobals kg,
|
||||
ccl_private const ShaderData *sd,
|
||||
ccl_private ShaderData *sd,
|
||||
ccl_private const ShaderClosure *sc,
|
||||
const float3 wo,
|
||||
float3 wo,
|
||||
ccl_private float *pdf)
|
||||
{
|
||||
kernel_assert(isfinite_safe(sd->P) && isfinite_safe(sd->ray_length));
|
||||
|
||||
ccl_private const PrincipledHairBSDF *bsdf = (ccl_private const PrincipledHairBSDF *)sc;
|
||||
const float3 Y = float4_to_float3(bsdf->extra->geom);
|
||||
|
||||
const float3 X = safe_normalize(sd->dPdu);
|
||||
kernel_assert(fabsf(dot(X, Y)) < 1e-3f);
|
||||
const float3 Z = safe_normalize(cross(X, Y));
|
||||
|
||||
/* local_I is the illumination direction. */
|
||||
const float3 local_O = make_float3(dot(sd->wi, X), dot(sd->wi, Y), dot(sd->wi, Z));
|
||||
const float3 local_I = make_float3(dot(wo, X), dot(wo, Y), dot(wo, Z));
|
||||
|
||||
const float sin_theta_o = local_O.x;
|
||||
const float cos_theta_o = cos_from_sin(sin_theta_o);
|
||||
const float phi_o = atan2f(local_O.z, local_O.y);
|
||||
|
||||
const float sin_theta_t = sin_theta_o / bsdf->eta;
|
||||
const float cos_theta_t = cos_from_sin(sin_theta_t);
|
||||
|
||||
const float sin_gamma_o = bsdf->extra->geom.w;
|
||||
const float cos_gamma_o = cos_from_sin(sin_gamma_o);
|
||||
const float gamma_o = safe_asinf(sin_gamma_o);
|
||||
|
||||
const float sin_gamma_t = sin_gamma_o * cos_theta_o / sqrtf(sqr(bsdf->eta) - sqr(sin_theta_o));
|
||||
const float cos_gamma_t = cos_from_sin(sin_gamma_t);
|
||||
const float gamma_t = safe_asinf(sin_gamma_t);
|
||||
|
||||
const Spectrum T = exp(-bsdf->sigma * (2.0f * cos_gamma_t / cos_theta_t));
|
||||
Spectrum Ap[4];
|
||||
float Ap_energy[4];
|
||||
hair_attenuation(
|
||||
kg, fresnel_dielectric_cos(cos_theta_o * cos_gamma_o, bsdf->eta), T, Ap, Ap_energy);
|
||||
|
||||
const float sin_theta_i = local_I.x;
|
||||
const float cos_theta_i = cos_from_sin(sin_theta_i);
|
||||
const float phi_i = atan2f(local_I.z, local_I.y);
|
||||
|
||||
const float phi = phi_i - phi_o;
|
||||
|
||||
float angles[6];
|
||||
hair_alpha_angles(sin_theta_i, cos_theta_i, bsdf->alpha, angles);
|
||||
|
||||
Spectrum F = zero_spectrum();
|
||||
float F_energy = 0.0f;
|
||||
|
||||
/* Primary specular (R), Transmission (TT) and Secondary Specular (TRT). */
|
||||
for (int i = 0; i < 3; i++) {
|
||||
const float Mp = longitudinal_scattering(angles[2 * i],
|
||||
angles[2 * i + 1],
|
||||
sin_theta_o,
|
||||
cos_theta_o,
|
||||
(i == 0) ? bsdf->m0_roughness :
|
||||
(i == 1) ? 0.25f * bsdf->v :
|
||||
4.0f * bsdf->v);
|
||||
const float Np = azimuthal_scattering(phi, i, bsdf->s, gamma_o, gamma_t);
|
||||
F += Ap[i] * Mp * Np;
|
||||
F_energy += Ap_energy[i] * Mp * Np;
|
||||
kernel_assert(isfinite_safe(F) && isfinite_safe(F_energy));
|
||||
}
|
||||
|
||||
/* Residual component (TRRT+). */
|
||||
{
|
||||
const float Mp = longitudinal_scattering(
|
||||
sin_theta_i, cos_theta_i, sin_theta_o, cos_theta_o, 4.0f * bsdf->v);
|
||||
const float Np = M_1_2PI_F;
|
||||
F += Ap[3] * Mp * Np;
|
||||
F_energy += Ap_energy[3] * Mp * Np;
|
||||
kernel_assert(isfinite_safe(F) && isfinite_safe(F_energy));
|
||||
}
|
||||
|
||||
*pdf = F_energy;
|
||||
return F;
|
||||
Spectrum eval;
|
||||
bsdf_principled_hair_impl<false>(kg, bsdf, sd, &wo, &eval, pdf, 0.0f, 0.0f);
|
||||
return eval;
|
||||
}
|
||||
|
||||
/* Sampling function for the hair shader. */
|
||||
ccl_device int bsdf_principled_hair_sample(KernelGlobals kg,
|
||||
ccl_private const ShaderClosure *sc,
|
||||
ccl_private ShaderData *sd,
|
||||
|
@ -344,118 +413,13 @@ ccl_device int bsdf_principled_hair_sample(KernelGlobals kg,
|
|||
ccl_private float2 *sampled_roughness,
|
||||
ccl_private float *eta)
|
||||
{
|
||||
ccl_private PrincipledHairBSDF *bsdf = (ccl_private PrincipledHairBSDF *)sc;
|
||||
ccl_private const PrincipledHairBSDF *bsdf = (ccl_private const PrincipledHairBSDF *)sc;
|
||||
|
||||
*sampled_roughness = make_float2(bsdf->m0_roughness, bsdf->m0_roughness);
|
||||
int p = bsdf_principled_hair_impl<true>(kg, bsdf, sd, wo, eval, pdf, randu, randv);
|
||||
|
||||
*sampled_roughness = make_float2(bsdf->v_R, bsdf->v_R);
|
||||
*eta = bsdf->eta;
|
||||
|
||||
const float3 Y = float4_to_float3(bsdf->extra->geom);
|
||||
|
||||
const float3 X = safe_normalize(sd->dPdu);
|
||||
kernel_assert(fabsf(dot(X, Y)) < 1e-3f);
|
||||
const float3 Z = safe_normalize(cross(X, Y));
|
||||
|
||||
const float3 local_O = make_float3(dot(sd->wi, X), dot(sd->wi, Y), dot(sd->wi, Z));
|
||||
|
||||
float2 u[2];
|
||||
u[0] = make_float2(randu, randv);
|
||||
u[1].x = lcg_step_float(&sd->lcg_state);
|
||||
u[1].y = lcg_step_float(&sd->lcg_state);
|
||||
|
||||
const float sin_theta_o = local_O.x;
|
||||
const float cos_theta_o = cos_from_sin(sin_theta_o);
|
||||
const float phi_o = atan2f(local_O.z, local_O.y);
|
||||
|
||||
const float sin_theta_t = sin_theta_o / bsdf->eta;
|
||||
const float cos_theta_t = cos_from_sin(sin_theta_t);
|
||||
|
||||
const float sin_gamma_o = bsdf->extra->geom.w;
|
||||
const float cos_gamma_o = cos_from_sin(sin_gamma_o);
|
||||
const float gamma_o = safe_asinf(sin_gamma_o);
|
||||
|
||||
const float sin_gamma_t = sin_gamma_o * cos_theta_o / sqrtf(sqr(bsdf->eta) - sqr(sin_theta_o));
|
||||
const float cos_gamma_t = cos_from_sin(sin_gamma_t);
|
||||
const float gamma_t = safe_asinf(sin_gamma_t);
|
||||
|
||||
const Spectrum T = exp(-bsdf->sigma * (2.0f * cos_gamma_t / cos_theta_t));
|
||||
Spectrum Ap[4];
|
||||
float Ap_energy[4];
|
||||
hair_attenuation(
|
||||
kg, fresnel_dielectric_cos(cos_theta_o * cos_gamma_o, bsdf->eta), T, Ap, Ap_energy);
|
||||
|
||||
int p = 0;
|
||||
for (; p < 3; p++) {
|
||||
if (u[0].x < Ap_energy[p]) {
|
||||
break;
|
||||
}
|
||||
u[0].x -= Ap_energy[p];
|
||||
}
|
||||
|
||||
float v = bsdf->v;
|
||||
if (p == 1) {
|
||||
v *= 0.25f;
|
||||
}
|
||||
if (p >= 2) {
|
||||
v *= 4.0f;
|
||||
}
|
||||
|
||||
u[1].x = max(u[1].x, 1e-5f);
|
||||
const float fac = 1.0f + v * logf(u[1].x + (1.0f - u[1].x) * expf(-2.0f / v));
|
||||
float sin_theta_i = -fac * sin_theta_o +
|
||||
cos_from_sin(fac) * cosf(M_2PI_F * u[1].y) * cos_theta_o;
|
||||
float cos_theta_i = cos_from_sin(sin_theta_i);
|
||||
|
||||
float angles[6];
|
||||
if (p < 3) {
|
||||
hair_alpha_angles(sin_theta_i, cos_theta_i, -bsdf->alpha, angles);
|
||||
sin_theta_i = angles[2 * p];
|
||||
cos_theta_i = angles[2 * p + 1];
|
||||
}
|
||||
|
||||
float phi;
|
||||
if (p < 3) {
|
||||
phi = delta_phi(p, gamma_o, gamma_t) + sample_trimmed_logistic(u[0].y, bsdf->s);
|
||||
}
|
||||
else {
|
||||
phi = M_2PI_F * u[0].y;
|
||||
}
|
||||
const float phi_i = phi_o + phi;
|
||||
|
||||
hair_alpha_angles(sin_theta_i, cos_theta_i, bsdf->alpha, angles);
|
||||
|
||||
Spectrum F = zero_spectrum();
|
||||
float F_energy = 0.0f;
|
||||
|
||||
/* Primary specular (R), Transmission (TT) and Secondary Specular (TRT). */
|
||||
for (int i = 0; i < 3; i++) {
|
||||
const float Mp = longitudinal_scattering(angles[2 * i],
|
||||
angles[2 * i + 1],
|
||||
sin_theta_o,
|
||||
cos_theta_o,
|
||||
(i == 0) ? bsdf->m0_roughness :
|
||||
(i == 1) ? 0.25f * bsdf->v :
|
||||
4.0f * bsdf->v);
|
||||
const float Np = azimuthal_scattering(phi, i, bsdf->s, gamma_o, gamma_t);
|
||||
F += Ap[i] * Mp * Np;
|
||||
F_energy += Ap_energy[i] * Mp * Np;
|
||||
kernel_assert(isfinite_safe(F) && isfinite_safe(F_energy));
|
||||
}
|
||||
|
||||
/* Residual component (TRRT+). */
|
||||
{
|
||||
const float Mp = longitudinal_scattering(
|
||||
sin_theta_i, cos_theta_i, sin_theta_o, cos_theta_o, 4.0f * bsdf->v);
|
||||
const float Np = M_1_2PI_F;
|
||||
F += Ap[3] * Mp * Np;
|
||||
F_energy += Ap_energy[3] * Mp * Np;
|
||||
kernel_assert(isfinite_safe(F) && isfinite_safe(F_energy));
|
||||
}
|
||||
|
||||
*eval = F;
|
||||
*pdf = F_energy;
|
||||
|
||||
*wo = X * sin_theta_i + Y * cos_theta_i * cosf(phi_i) + Z * cos_theta_i * sinf(phi_i);
|
||||
|
||||
return LABEL_GLOSSY | ((p == 0) ? LABEL_REFLECT : LABEL_TRANSMIT);
|
||||
}
|
||||
|
||||
|
@ -466,29 +430,30 @@ ccl_device void bsdf_principled_hair_blur(ccl_private ShaderClosure *sc, float r
|
|||
|
||||
bsdf->v = fmaxf(roughness, bsdf->v);
|
||||
bsdf->s = fmaxf(roughness, bsdf->s);
|
||||
bsdf->m0_roughness = fmaxf(roughness, bsdf->m0_roughness);
|
||||
bsdf->v_R = fmaxf(roughness, bsdf->v_R);
|
||||
}
|
||||
|
||||
/* Hair Albedo */
|
||||
|
||||
ccl_device_inline float bsdf_principled_hair_albedo_roughness_scale(
|
||||
const float azimuthal_roughness)
|
||||
ccl_device_inline float bsdf_principled_hair_albedo_roughness_scale(const float u_rough)
|
||||
{
|
||||
const float x = azimuthal_roughness;
|
||||
const float x = u_rough;
|
||||
return (((((0.245f * x) + 5.574f) * x - 10.73f) * x + 2.532f) * x - 0.215f) * x + 5.969f;
|
||||
}
|
||||
|
||||
ccl_device Spectrum bsdf_principled_hair_albedo(ccl_private const ShaderClosure *sc)
|
||||
{
|
||||
ccl_private PrincipledHairBSDF *bsdf = (ccl_private PrincipledHairBSDF *)sc;
|
||||
return exp(-sqrt(bsdf->sigma) * bsdf_principled_hair_albedo_roughness_scale(bsdf->v));
|
||||
/* This is simply the sum of the four Ap terms in hair_attenuation. */
|
||||
const float3 T = bsdf->extra->T;
|
||||
const float f = bsdf->extra->f;
|
||||
return safe_divide(T * (1.0f - 2.0f * f) + make_spectrum(f), one_spectrum() - f * T);
|
||||
}
|
||||
|
||||
ccl_device_inline Spectrum
|
||||
bsdf_principled_hair_sigma_from_reflectance(const Spectrum color, const float azimuthal_roughness)
|
||||
ccl_device_inline Spectrum bsdf_principled_hair_sigma_from_reflectance(const Spectrum color,
|
||||
const float u_rough)
|
||||
{
|
||||
const Spectrum sigma = log(color) /
|
||||
bsdf_principled_hair_albedo_roughness_scale(azimuthal_roughness);
|
||||
const Spectrum sigma = log(color) / bsdf_principled_hair_albedo_roughness_scale(u_rough);
|
||||
return sigma * sigma;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#ifndef WITH_CYCLES_OPTIMIZED_KERNEL_AVX2
|
||||
# define KERNEL_STUB
|
||||
#else
|
||||
/* SSE optimization disabled for now on 32 bit, see bug T36316. */
|
||||
/* SSE optimization disabled for now on 32 bit, see bug #36316. */
|
||||
# if !(defined(__GNUC__) && (defined(i386) || defined(_M_IX86)))
|
||||
# define __KERNEL_SSE__
|
||||
# define __KERNEL_SSE2__
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#ifndef WITH_CYCLES_OPTIMIZED_KERNEL_SSE2
|
||||
# define KERNEL_STUB
|
||||
#else
|
||||
/* SSE optimization disabled for now on 32 bit, see bug T36316. */
|
||||
/* SSE optimization disabled for now on 32 bit, see bug #36316. */
|
||||
# if !(defined(__GNUC__) && (defined(i386) || defined(_M_IX86)))
|
||||
# define __KERNEL_SSE2__
|
||||
# endif
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
#ifndef WITH_CYCLES_OPTIMIZED_KERNEL_SSE41
|
||||
# define KERNEL_STUB
|
||||
#else
|
||||
/* SSE optimization disabled for now on 32 bit, see bug T36316. */
|
||||
/* SSE optimization disabled for now on 32 bit, see bug #36316. */
|
||||
# if !(defined(__GNUC__) && (defined(i386) || defined(_M_IX86)))
|
||||
# define __KERNEL_SSE2__
|
||||
# define __KERNEL_SSE3__
|
||||
|
|
|
@ -645,7 +645,7 @@ ccl_device_inline void kernel_gpu_film_convert_half_write(ccl_global uchar4 *rgb
|
|||
const int y,
|
||||
const half4 half_pixel)
|
||||
{
|
||||
/* Work around HIP issue with half float display, see T92972. */
|
||||
/* Work around HIP issue with half float display, see #92972. */
|
||||
#ifdef __KERNEL_HIP__
|
||||
ccl_global half *out = ((ccl_global half *)rgba) + (rgba_offset + y * rgba_stride + x) * 4;
|
||||
out[0] = half_pixel.x;
|
||||
|
|
|
@ -1078,15 +1078,13 @@ ccl_device void osl_closure_principled_hair_setup(KernelGlobals kg,
|
|||
|
||||
bsdf->N = ensure_valid_reflection(sd->Ng, sd->wi, closure->N);
|
||||
bsdf->sigma = closure->sigma;
|
||||
bsdf->v = closure->v;
|
||||
bsdf->s = closure->s;
|
||||
bsdf->alpha = closure->alpha;
|
||||
bsdf->eta = closure->eta;
|
||||
bsdf->m0_roughness = closure->m0_roughness;
|
||||
|
||||
bsdf->extra = extra;
|
||||
|
||||
sd->flag |= bsdf_principled_hair_setup(sd, bsdf);
|
||||
sd->flag |= bsdf_principled_hair_setup(
|
||||
sd, bsdf, closure->u_roughness, closure->coat_roughness, closure->v_roughness);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -238,9 +238,9 @@ OSL_CLOSURE_STRUCT_END(HairTransmission, hair_transmission)
|
|||
OSL_CLOSURE_STRUCT_BEGIN(PrincipledHair, principled_hair)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(PrincipledHair, VECTOR, packed_float3, N, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(PrincipledHair, VECTOR, packed_float3, sigma, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(PrincipledHair, FLOAT, float, v, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(PrincipledHair, FLOAT, float, s, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(PrincipledHair, FLOAT, float, m0_roughness, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(PrincipledHair, FLOAT, float, u_roughness, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(PrincipledHair, FLOAT, float, v_roughness, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(PrincipledHair, FLOAT, float, coat_roughness, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(PrincipledHair, FLOAT, float, alpha, NULL)
|
||||
OSL_CLOSURE_STRUCT_MEMBER(PrincipledHair, FLOAT, float, eta, NULL)
|
||||
OSL_CLOSURE_STRUCT_END(PrincipledHair, principled_hair)
|
||||
|
|
|
@ -53,7 +53,7 @@ shader node_principled_hair_bsdf(color Color = color(0.017513, 0.005763, 0.00205
|
|||
|
||||
/* Compute roughness. */
|
||||
float factor_random_roughness = 1.0 + 2.0 * (random_value - 0.5) * RandomRoughness;
|
||||
float m0_roughness = 1.0 - clamp(Coat, 0.0, 1.0);
|
||||
float coat_roughness = 1.0 - clamp(Coat, 0.0, 1.0);
|
||||
float roughness = Roughness * factor_random_roughness;
|
||||
float radial_roughness = RadialRoughness * factor_random_roughness;
|
||||
|
||||
|
@ -88,5 +88,5 @@ shader node_principled_hair_bsdf(color Color = color(0.017513, 0.005763, 0.00205
|
|||
sigma = sigma_from_concentration(0.0, 0.8054375);
|
||||
}
|
||||
|
||||
BSDF = principled_hair(Normal, sigma, roughness, radial_roughness, m0_roughness, Offset, IOR);
|
||||
BSDF = principled_hair(Normal, sigma, roughness, radial_roughness, coat_roughness, Offset, IOR);
|
||||
}
|
||||
|
|
|
@ -802,12 +802,9 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
|
||||
/* Remap Coat value to [0, 100]% of Roughness. */
|
||||
float coat = stack_load_float_default(stack, coat_ofs, data_node2.y);
|
||||
float m0_roughness = 1.0f - clamp(coat, 0.0f, 1.0f);
|
||||
float coat_roughness = 1.0f - clamp(coat, 0.0f, 1.0f);
|
||||
|
||||
bsdf->N = N;
|
||||
bsdf->v = roughness;
|
||||
bsdf->s = radial_roughness;
|
||||
bsdf->m0_roughness = m0_roughness;
|
||||
bsdf->alpha = alpha;
|
||||
bsdf->eta = ior;
|
||||
bsdf->extra = extra;
|
||||
|
@ -860,7 +857,8 @@ ccl_device_noinline int svm_node_closure_bsdf(KernelGlobals kg,
|
|||
}
|
||||
}
|
||||
|
||||
sd->flag |= bsdf_principled_hair_setup(sd, bsdf);
|
||||
sd->flag |= bsdf_principled_hair_setup(
|
||||
sd, bsdf, roughness, coat_roughness, radial_roughness);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -394,7 +394,7 @@ bool OSLShaderManager::osl_compile(const string &inputfile, const string &output
|
|||
|
||||
/* Compile.
|
||||
*
|
||||
* Mutex protected because the OSL compiler does not appear to be thread safe, see T92503. */
|
||||
* Mutex protected because the OSL compiler does not appear to be thread safe, see #92503. */
|
||||
static thread_mutex osl_compiler_mutex;
|
||||
thread_scoped_lock lock(osl_compiler_mutex);
|
||||
|
||||
|
|
|
@ -573,7 +573,7 @@ void ShaderManager::device_update_common(Device * /*device*/,
|
|||
kfilm->is_rec709 = is_rec709;
|
||||
}
|
||||
|
||||
void ShaderManager::device_free_common(Device *, DeviceScene *dscene, Scene *scene)
|
||||
void ShaderManager::device_free_common(Device * /*device*/, DeviceScene *dscene, Scene * /*scene*/)
|
||||
{
|
||||
dscene->shaders.free();
|
||||
}
|
||||
|
|
|
@ -520,7 +520,7 @@ bool TileManager::write_tile(const RenderBuffers &tile_buffers)
|
|||
/* If there is an overscan used for the tile copy pixels into single continuous block of memory
|
||||
* without any "gaps".
|
||||
* This is a workaround for bug in OIIO (https://github.com/OpenImageIO/oiio/pull/3176).
|
||||
* Our task reference: T93008. */
|
||||
* Our task reference: #93008. */
|
||||
if (tile_params.window_x || tile_params.window_y ||
|
||||
tile_params.window_width != tile_params.width ||
|
||||
tile_params.window_height != tile_params.height) {
|
||||
|
|
|
@ -421,7 +421,7 @@ ccl_device_inline float fast_expf(float x)
|
|||
|
||||
#if !defined(__KERNEL_GPU__) && !defined(_MSC_VER)
|
||||
/* MSVC seems to have a code-gen bug here in at least SSE41/AVX, see
|
||||
* T78047 and T78869 for details. Just disable for now, it only makes
|
||||
* #78047 and #78869 for details. Just disable for now, it only makes
|
||||
* a small difference in denoising performance. */
|
||||
ccl_device float4 fast_exp2f4(float4 x)
|
||||
{
|
||||
|
|
|
@ -516,7 +516,7 @@ GHOST_TSuccess GHOST_ContextCGL::releaseNativeHandles()
|
|||
|
||||
/* OpenGL on Metal
|
||||
*
|
||||
* Use Metal layer to avoid Viewport lagging on macOS, see T60043. */
|
||||
* Use Metal layer to avoid Viewport lagging on macOS, see #60043. */
|
||||
|
||||
static const MTLPixelFormat METAL_FRAMEBUFFERPIXEL_FORMAT = MTLPixelFormatBGRA8Unorm;
|
||||
static const OSType METAL_CORE_VIDEO_PIXEL_FORMAT = kCVPixelFormatType_32BGRA;
|
||||
|
|
|
@ -141,7 +141,7 @@ GHOST_TSuccess GHOST_ContextGLX::initializeDrawingContext()
|
|||
/* -------------------------------------------------------------------- */
|
||||
#else
|
||||
/* Important to initialize only GLXEW (_not_ GLEW),
|
||||
* since this breaks w/ Mesa's `swrast`, see: T46431. */
|
||||
* since this breaks w/ Mesa's `swrast`, see: #46431. */
|
||||
glxewInit();
|
||||
#endif /* USE_GLXEW_INIT_WORKAROUND */
|
||||
|
||||
|
|
|
@ -302,7 +302,7 @@ bool GHOST_NDOFManager::setDevice(ushort vendor_id, ushort product_id)
|
|||
switch (product_id) {
|
||||
case 0xC62E: /* Plugged in. */
|
||||
case 0xC62F: /* Wireless. */
|
||||
case 0xC658: /* Wireless (3DConnexion Universal Wireless Receiver in WIN32), see T82412. */
|
||||
case 0xC658: /* Wireless (3DConnexion Universal Wireless Receiver in WIN32), see #82412. */
|
||||
{
|
||||
device_type_ = NDOF_SpaceMouseWireless;
|
||||
hid_map_button_num_ = 2;
|
||||
|
@ -341,7 +341,7 @@ bool GHOST_NDOFManager::setDevice(ushort vendor_id, ushort product_id)
|
|||
hid_map_button_mask_ = int(~(UINT_MAX << hid_map_button_num_));
|
||||
}
|
||||
|
||||
CLOG_INFO(LOG, 2, "%d buttons -> hex:%X", hid_map_button_num_, (uint)hid_map_button_mask_);
|
||||
CLOG_INFO(LOG, 2, "%d buttons -> hex:%X", hid_map_button_num_, uint(hid_map_button_mask_));
|
||||
|
||||
return device_type_ != NDOF_UnknownDevice;
|
||||
}
|
||||
|
@ -445,14 +445,14 @@ void GHOST_NDOFManager::updateButton(int button_number, bool press, uint64_t tim
|
|||
2,
|
||||
"button=%d, press=%d (out of range %d, ignoring!)",
|
||||
button_number,
|
||||
(int)press,
|
||||
int(press),
|
||||
hid_map_button_num_);
|
||||
return;
|
||||
}
|
||||
const NDOF_ButtonT button = hid_map_[button_number];
|
||||
if (button == NDOF_BUTTON_NONE) {
|
||||
CLOG_INFO(
|
||||
LOG, 2, "button=%d, press=%d (mapped to none, ignoring!)", button_number, (int)press);
|
||||
LOG, 2, "button=%d, press=%d (mapped to none, ignoring!)", button_number, int(press));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -460,7 +460,7 @@ void GHOST_NDOFManager::updateButton(int button_number, bool press, uint64_t tim
|
|||
2,
|
||||
"button=%d, press=%d, name=%s",
|
||||
button_number,
|
||||
(int)press,
|
||||
int(press),
|
||||
ndof_button_names[button]);
|
||||
|
||||
GHOST_IWindow *window = system_.getWindowManager()->getActiveWindow();
|
||||
|
|
|
@ -141,7 +141,7 @@ constexpr size_t events_pending_default_size = 4096 / sizeof(void *);
|
|||
* \{ */
|
||||
|
||||
/**
|
||||
* GNOME (mutter 42.2 had a bug with confine not respecting scale - Hi-DPI), See: T98793.
|
||||
* GNOME (mutter 42.2 had a bug with confine not respecting scale - Hi-DPI), See: #98793.
|
||||
* Even though this has been fixed, at time of writing it's not yet in a release.
|
||||
* Workaround the problem by implementing confine with a software cursor.
|
||||
* While this isn't ideal, it's not adding a lot of overhead as software
|
||||
|
@ -176,7 +176,7 @@ static bool use_gnome_confine_hack = false;
|
|||
|
||||
/**
|
||||
* KDE (plasma 5.26.1) has a bug where the cursor surface needs to be committed
|
||||
* (via `wl_surface_commit`) when it was hidden and is being set to visible again, see: T102048.
|
||||
* (via `wl_surface_commit`) when it was hidden and is being set to visible again, see: #102048.
|
||||
* See: https://bugs.kde.org/show_bug.cgi?id=461001
|
||||
*/
|
||||
#define USE_KDE_TABLET_HIDDEN_CURSOR_HACK
|
||||
|
@ -197,8 +197,8 @@ static bool use_gnome_confine_hack = false;
|
|||
* \{ */
|
||||
|
||||
/**
|
||||
* Fix short-cut part of keyboard reading code not properly handling some keys, see: T102194.
|
||||
* \note This is similar to X11 workaround by the same name, see: T47228.
|
||||
* Fix short-cut part of keyboard reading code not properly handling some keys, see: #102194.
|
||||
* \note This is similar to X11 workaround by the same name, see: #47228.
|
||||
*/
|
||||
#define USE_NON_LATIN_KB_WORKAROUND
|
||||
|
||||
|
@ -1328,7 +1328,7 @@ static void ghost_wl_display_report_error(struct wl_display *display)
|
|||
* So in practice re-connecting to the display server isn't an option.
|
||||
*
|
||||
* Exit since leaving the process open will simply flood the output and do nothing.
|
||||
* Although as the process is in a valid state, auto-save for e.g. is possible, see: T100855. */
|
||||
* Although as the process is in a valid state, auto-save for e.g. is possible, see: #100855. */
|
||||
::exit(-1);
|
||||
}
|
||||
|
||||
|
@ -1442,7 +1442,7 @@ static GHOST_TKey xkb_map_gkey(const xkb_keysym_t sym)
|
|||
|
||||
/* Additional keys for non US layouts. */
|
||||
|
||||
/* Uses the same physical key as #XKB_KEY_KP_Decimal for QWERTZ layout, see: T102287. */
|
||||
/* Uses the same physical key as #XKB_KEY_KP_Decimal for QWERTZ layout, see: #102287. */
|
||||
GXMAP(gkey, XKB_KEY_KP_Separator, GHOST_kKeyNumpadPeriod);
|
||||
|
||||
default:
|
||||
|
@ -3810,7 +3810,7 @@ static xkb_keysym_t xkb_state_key_get_one_sym_without_modifiers(
|
|||
|
||||
/* NOTE(@ideasman42): Only perform the number-locked lookup as a fallback
|
||||
* when a number-pad key has been pressed. This is important as some key-maps use number lock
|
||||
* for switching other layers (in particular `de(neo_qwertz)` turns on layer-4), see: T96170.
|
||||
* for switching other layers (in particular `de(neo_qwertz)` turns on layer-4), see: #96170.
|
||||
* Alternative solutions could be to inspect the layout however this could get involved
|
||||
* and turning on the number-lock is only needed for a limited set of keys. */
|
||||
|
||||
|
@ -4467,7 +4467,7 @@ static void xdg_output_handle_logical_size(void *data,
|
|||
|
||||
#ifdef USE_GNOME_CONFINE_HACK
|
||||
/* Use a bug in GNOME to check GNOME is in use. If the bug is fixed this won't cause an issue
|
||||
* as T98793 has been fixed up-stream too, but not in a release at time of writing. */
|
||||
* as #98793 has been fixed up-stream too, but not in a release at time of writing. */
|
||||
use_gnome_confine_hack = true;
|
||||
#endif
|
||||
|
||||
|
|
|
@ -208,7 +208,7 @@ class GHOST_SystemWayland : public GHOST_System {
|
|||
* Clear all references to this output.
|
||||
*
|
||||
* \note The compositor should have already called the `wl_surface_listener.leave` callback,
|
||||
* however some compositors may not (see T103586).
|
||||
* however some compositors may not (see #103586).
|
||||
* So remove references to the output before it's destroyed to avoid crashing.
|
||||
*
|
||||
* \return true when any references were removed.
|
||||
|
|
|
@ -565,8 +565,8 @@ GHOST_TKey GHOST_SystemWin32::hardKey(RAWINPUT const &raw, bool *r_key_down)
|
|||
/**
|
||||
* \note this function can be extended to include other exotic cases as they arise.
|
||||
*
|
||||
* This function was added in response to bug T25715.
|
||||
* This is going to be a long list T42426.
|
||||
* This function was added in response to bug #25715.
|
||||
* This is going to be a long list #42426.
|
||||
*/
|
||||
GHOST_TKey GHOST_SystemWin32::processSpecialKey(short vKey, short scanCode) const
|
||||
{
|
||||
|
@ -1083,7 +1083,7 @@ GHOST_EventCursor *GHOST_SystemWin32::processCursorEvent(GHOST_WindowWin32 *wind
|
|||
* so the box needs to small enough not to let the cursor escape the window but large
|
||||
* enough that the cursor isn't being warped every time.
|
||||
* If this was not the case it would be less trouble to simply warp the cursor to the
|
||||
* center of the screen on every motion, see: D16558 (alternative fix for T102346). */
|
||||
* center of the screen on every motion, see: D16558 (alternative fix for #102346). */
|
||||
const int32_t subregion_div = 4; /* One quarter of the region. */
|
||||
const int32_t size[2] = {bounds.getWidth(), bounds.getHeight()};
|
||||
const int32_t center[2] = {(bounds.m_l + bounds.m_r) / 2, (bounds.m_t + bounds.m_b) / 2};
|
||||
|
@ -1209,7 +1209,7 @@ GHOST_EventKey *GHOST_SystemWin32::processKeyEvent(GHOST_WindowWin32 *window, RA
|
|||
const bool ctrl_pressed = has_state && state[VK_CONTROL] & 0x80;
|
||||
const bool alt_pressed = has_state && state[VK_MENU] & 0x80;
|
||||
|
||||
/* We can be here with !key_down if processing dead keys (diacritics). See T103119. */
|
||||
/* We can be here with !key_down if processing dead keys (diacritics). See #103119. */
|
||||
|
||||
/* No text with control key pressed (Alt can be used to insert special characters though!). */
|
||||
if (ctrl_pressed && !alt_pressed) {
|
||||
|
|
|
@ -46,7 +46,7 @@
|
|||
|
||||
#ifdef WITH_X11_XFIXES
|
||||
# include <X11/extensions/Xfixes.h>
|
||||
/* Workaround for XWayland grab glitch: T53004. */
|
||||
/* Workaround for XWayland grab glitch: #53004. */
|
||||
# define WITH_XWAYLAND_HACK
|
||||
#endif
|
||||
|
||||
|
@ -71,11 +71,11 @@
|
|||
# define USE_XINPUT_HOTPLUG
|
||||
#endif
|
||||
|
||||
/* see T34039 Fix Alt key glitch on Unity desktop */
|
||||
/* see #34039 Fix Alt key glitch on Unity desktop */
|
||||
#define USE_UNITY_WORKAROUND
|
||||
|
||||
/* Fix 'shortcut' part of keyboard reading code only ever using first defined key-map
|
||||
* instead of active one. See T47228 and D1746 */
|
||||
* instead of active one. See #47228 and D1746 */
|
||||
#define USE_NON_LATIN_KB_WORKAROUND
|
||||
|
||||
static uchar bit_is_on(const uchar *ptr, int bit)
|
||||
|
@ -928,7 +928,7 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
|
|||
window->getClientBounds(bounds);
|
||||
|
||||
/* TODO(@ideasman42): warp the cursor to `window->getCursorGrabInitPos`,
|
||||
* on every motion event, see: D16557 (alternative fix for T102346). */
|
||||
* on every motion event, see: D16557 (alternative fix for #102346). */
|
||||
const int32_t subregion_div = 4; /* One quarter of the region. */
|
||||
const int32_t size[2] = {bounds.getWidth(), bounds.getHeight()};
|
||||
const int32_t center[2] = {
|
||||
|
@ -964,7 +964,7 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
|
|||
if (x_new != xme.x_root || y_new != xme.y_root) {
|
||||
/* Use time of last event to avoid wrapping several times on the 'same' actual wrap.
|
||||
* Note that we need to deal with X and Y separately as those might wrap at the same time
|
||||
* but still in two different events (corner case, see T74918).
|
||||
* but still in two different events (corner case, see #74918).
|
||||
* We also have to add a few extra milliseconds of 'padding', as sometimes we get two
|
||||
* close events that will generate extra wrap on the same axis within those few
|
||||
* milliseconds. */
|
||||
|
@ -1028,7 +1028,7 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
|
|||
/* XXX: Code below is kinda awfully convoluted... Issues are:
|
||||
* - In keyboards like Latin ones, numbers need a 'Shift' to be accessed but key_sym
|
||||
* is unmodified (or anyone swapping the keys with `xmodmap`).
|
||||
* - #XLookupKeysym seems to always use first defined key-map (see T47228), which generates
|
||||
* - #XLookupKeysym seems to always use first defined key-map (see #47228), which generates
|
||||
* key-codes unusable by ghost_key_from_keysym for non-Latin-compatible key-maps.
|
||||
*
|
||||
* To address this, we:
|
||||
|
@ -1715,7 +1715,7 @@ GHOST_TSuccess GHOST_SystemX11::setCursorPosition(int32_t x, int32_t y)
|
|||
|
||||
#if defined(WITH_X11_XINPUT) && defined(USE_X11_XINPUT_WARP)
|
||||
if ((m_xinput_version.present) && (m_xinput_version.major_version >= 2)) {
|
||||
/* Needed to account for XInput "Coordinate Transformation Matrix", see T48901 */
|
||||
/* Needed to account for XInput "Coordinate Transformation Matrix", see #48901 */
|
||||
int device_id;
|
||||
if (XIGetClientPointer(m_display, None, &device_id) != False) {
|
||||
XIWarpPointer(m_display, device_id, None, None, 0, 0, 0, 0, relx, rely);
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
|
||||
/* Disable XINPUT warp, currently not implemented by Xorg for multi-head display.
|
||||
* (see comment in XSERVER `Xi/xiwarppointer.c` -> `FIXME: panoramix stuff is missing` ~ v1.13.4)
|
||||
* If this is supported we can add back XINPUT for warping (fixing T48901).
|
||||
* For now disable (see T50383). */
|
||||
* If this is supported we can add back XINPUT for warping (fixing #48901).
|
||||
* For now disable (see #50383). */
|
||||
// # define USE_X11_XINPUT_WARP
|
||||
#endif
|
||||
|
||||
|
|
|
@ -812,12 +812,12 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system,
|
|||
* when the `window_->scale` changed. */
|
||||
const int32_t size_min[2] = {320, 240};
|
||||
|
||||
/* This value is expected to match the base name of the `.desktop` file. see T101805.
|
||||
/* This value is expected to match the base name of the `.desktop` file. see #101805.
|
||||
*
|
||||
* NOTE: the XDG desktop-entry-spec defines that this should follow the "reverse DNS" convention.
|
||||
* For e.g. `org.blender.Blender` - however the `.desktop` file distributed with Blender is
|
||||
* simply called `blender.desktop`, so the it's important to follow that name.
|
||||
* Other distributions such as SNAP & FLATPAK may need to change this value T101779.
|
||||
* Other distributions such as SNAP & FLATPAK may need to change this value #101779.
|
||||
* Currently there isn't a way to configure this, we may want to support that. */
|
||||
const char *xdg_app_id = (
|
||||
#ifdef WITH_GHOST_WAYLAND_APP_ID
|
||||
|
@ -1080,7 +1080,7 @@ GHOST_WindowWayland::~GHOST_WindowWayland()
|
|||
|
||||
/* NOTE(@ideasman42): Flushing will often run the appropriate handlers event
|
||||
* (#wl_surface_listener.leave in particular) to avoid attempted access to the freed surfaces.
|
||||
* This is not fool-proof though, hence the call to #window_surface_unref, see: T99078. */
|
||||
* This is not fool-proof though, hence the call to #window_surface_unref, see: #99078. */
|
||||
wl_display_flush(system_->wl_display());
|
||||
|
||||
delete window_;
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#include <wayland-util.h> /* For #wl_fixed_t */
|
||||
|
||||
/**
|
||||
* Define to workaround for a bug/limitation in WAYLAND, see: T100855 & upstream report:
|
||||
* Define to workaround for a bug/limitation in WAYLAND, see: #100855 & upstream report:
|
||||
* https://gitlab.freedesktop.org/wayland/wayland/-/issues/159
|
||||
*
|
||||
* Consume events from WAYLAND in a thread, this is needed because overflowing the event queue
|
||||
|
|
|
@ -154,7 +154,7 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system,
|
|||
}
|
||||
|
||||
if (parentwindow) {
|
||||
/* Release any parent capture to allow immediate interaction (T90110). */
|
||||
/* Release any parent capture to allow immediate interaction (#90110). */
|
||||
::ReleaseCapture();
|
||||
parentwindow->lostMouseCapture();
|
||||
}
|
||||
|
|
|
@ -418,7 +418,7 @@ void GHOST_WindowX11::refreshXInputDevices()
|
|||
for (GHOST_SystemX11::GHOST_TabletX11 &xtablet : m_system->GetXTablets()) {
|
||||
/* With modern XInput (XLIB 1.6.2 at least and/or EVDEV 2.9.0) and some 'no-name' tablets
|
||||
* like 'UC-LOGIC Tablet WP5540U', we also need to 'select' ButtonPress for motion event,
|
||||
* otherwise we do not get any tablet motion event once pen is pressed... See T43367.
|
||||
* otherwise we do not get any tablet motion event once pen is pressed... See #43367.
|
||||
*/
|
||||
XEventClass ev;
|
||||
|
||||
|
@ -1467,7 +1467,7 @@ GHOST_TSuccess GHOST_WindowX11::setWindowCursorGrab(GHOST_TGrabCursorMode mode)
|
|||
}
|
||||
}
|
||||
|
||||
/* Perform this last so to workaround XWayland bug, see: T53004. */
|
||||
/* Perform this last so to workaround XWayland bug, see: #53004. */
|
||||
if (m_cursorGrab == GHOST_kGrabHide) {
|
||||
setWindowCursorVisibility(true);
|
||||
}
|
||||
|
|
|
@ -108,7 +108,7 @@ void bl_locale_set(const char *locale)
|
|||
}
|
||||
/* Extra catch on `std::runtime_error` is needed for macOS/Clang as it seems that exceptions
|
||||
* like `boost::locale::conv::conversion_error` (which inherit from `std::runtime_error`) are
|
||||
* not caught by their ancestor `std::exception`. See T88877#1177108 */
|
||||
* not caught by their ancestor `std::exception`. See #88877#1177108 */
|
||||
catch (std::runtime_error const &e) {
|
||||
std::cout << "bl_locale_set(" << locale << "): " << e.what() << " \n";
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ const char *osx_user_locale()
|
|||
[myNSLocale autorelease];
|
||||
|
||||
// This produces gettext-invalid locale in recent macOS versions (11.4),
|
||||
// like `ko-Kore_KR` instead of `ko_KR`. See T88877.
|
||||
// like `ko-Kore_KR` instead of `ko_KR`. See #88877.
|
||||
// NSString *nsIdentifier = [myNSLocale localeIdentifier];
|
||||
|
||||
const NSString *nsIdentifier = [myNSLocale languageCode];
|
||||
|
|
|
@ -193,7 +193,7 @@ static bool createGPUShader(OCIO_GPUShader &shader,
|
|||
info.fragment_source("gpu_shader_display_transform_frag.glsl");
|
||||
info.fragment_source_generated = source;
|
||||
|
||||
/* T96502: Work around for incorrect OCIO GLSL code generation when using
|
||||
/* #96502: Work around for incorrect OCIO GLSL code generation when using
|
||||
* GradingPrimaryTransform. Should be reevaluated when changing to a next version of OCIO.
|
||||
* (currently v2.1.1). */
|
||||
info.define("inf 1e32");
|
||||
|
|
|
@ -145,7 +145,7 @@ const UserDef U_default = {
|
|||
.ndof_flag = (NDOF_MODE_ORBIT | NDOF_LOCK_HORIZON | NDOF_SHOULD_PAN | NDOF_SHOULD_ZOOM |
|
||||
NDOF_SHOULD_ROTATE |
|
||||
/* Software from the driver authors follows this convention
|
||||
* so invert this by default, see: T67579. */
|
||||
* so invert this by default, see: #67579. */
|
||||
NDOF_ROTX_INVERT_AXIS | NDOF_ROTY_INVERT_AXIS | NDOF_ROTZ_INVERT_AXIS |
|
||||
NDOF_PANX_INVERT_AXIS | NDOF_PANY_INVERT_AXIS | NDOF_PANZ_INVERT_AXIS |
|
||||
NDOF_ZOOM_INVERT | NDOF_CAMERA_PAN_ZOOM),
|
||||
|
|
|
@ -370,6 +370,7 @@ const bTheme U_theme_default = {
|
|||
.clipping_border_3d = RGBA(0x3f3f3fff),
|
||||
.bundle_solid = RGBA(0xc8c8c8ff),
|
||||
.camera_path = RGBA(0x000000ff),
|
||||
.camera_passepartout = RGBA(0x000000),
|
||||
.gp_vertex_size = 3,
|
||||
.gp_vertex = RGBA(0x000000ff),
|
||||
.gp_vertex_select = RGBA(0xff8500ff),
|
||||
|
|
|
@ -286,7 +286,7 @@ class pySketchyChainingIterator(ChainingIterator):
|
|||
|
||||
if not found:
|
||||
# This is a fatal error condition: self.current_edge must be found
|
||||
# among the edges seen by the AdjacencyIterator [bug T35695].
|
||||
# among the edges seen by the AdjacencyIterator [bug #35695].
|
||||
if bpy.app.debug_freestyle:
|
||||
print('pySketchyChainingIterator: current edge not found')
|
||||
return None
|
||||
|
|
|
@ -113,7 +113,7 @@ def expand(line, cursor, namespace, *, private=True):
|
|||
if len(matches) == 1:
|
||||
scrollback = ''
|
||||
else:
|
||||
# causes blender bug T27495 since string keys may contain '.'
|
||||
# causes blender bug #27495 since string keys may contain '.'
|
||||
# scrollback = ' '.join([m.split('.')[-1] for m in matches])
|
||||
|
||||
# add white space to align with the cursor
|
||||
|
|
|
@ -30,7 +30,7 @@ def url_prefill_from_blender(*, addon_info=None):
|
|||
"**Blender Version**\n"
|
||||
)
|
||||
fh.write(
|
||||
"Broken: version: %s, branch: %s, commit date: %s %s, hash: `rB%s`\n" % (
|
||||
"Broken: version: %s, branch: %s, commit date: %s %s, hash: `%s`\n" % (
|
||||
bpy.app.version_string,
|
||||
bpy.app.build_branch.decode('utf-8', 'replace'),
|
||||
bpy.app.build_commit_date.decode('utf-8', 'replace'),
|
||||
|
|
|
@ -32,7 +32,7 @@ class _BPyOpsSubModOp:
|
|||
# XXX You never quite know what you get from bpy.types,
|
||||
# with operators... Operator and OperatorProperties
|
||||
# are shadowing each other, and not in the same way for
|
||||
# native ops and py ones! See T39158.
|
||||
# native ops and py ones! See #39158.
|
||||
# op_class = getattr(bpy.types, idname)
|
||||
op_class = _op_get_rna_type(idname)
|
||||
descr = op_class.description
|
||||
|
|
|
@ -259,15 +259,15 @@ def bake_action_iter(
|
|||
if is_new_action:
|
||||
action = bpy.data.actions.new("Action")
|
||||
|
||||
# Only leave tweak mode if we actually need to modify the action (T57159)
|
||||
# Only leave tweak mode if we actually need to modify the action (#57159)
|
||||
if action != atd.action:
|
||||
# Leave tweak mode before trying to modify the action (T48397)
|
||||
# Leave tweak mode before trying to modify the action (#48397)
|
||||
if atd.use_tweak_mode:
|
||||
atd.use_tweak_mode = False
|
||||
|
||||
atd.action = action
|
||||
|
||||
# Baking the action only makes sense in Replace mode, so force it (T69105)
|
||||
# Baking the action only makes sense in Replace mode, so force it (#69105)
|
||||
if not atd.use_tweak_mode:
|
||||
atd.action_blend_type = 'REPLACE'
|
||||
|
||||
|
|
|
@ -111,7 +111,7 @@ def orientation_helper(axis_forward='Y', axis_up='Z'):
|
|||
"""
|
||||
def wrapper(cls):
|
||||
# Without that, we may end up adding those fields to some **parent** class' __annotations__ property
|
||||
# (like the ImportHelper or ExportHelper ones)! See T58772.
|
||||
# (like the ImportHelper or ExportHelper ones)! See #58772.
|
||||
if "__annotations__" not in cls.__dict__:
|
||||
setattr(cls, "__annotations__", {})
|
||||
|
||||
|
|
|
@ -564,7 +564,7 @@ class Mesh(bpy_types.ID):
|
|||
|
||||
face_lengths = tuple(map(len, faces))
|
||||
|
||||
# NOTE: check non-empty lists by length because of how `numpy` handles truth tests, see: T90268.
|
||||
# NOTE: check non-empty lists by length because of how `numpy` handles truth tests, see: #90268.
|
||||
vertices_len = len(vertices)
|
||||
edges_len = len(edges)
|
||||
faces_len = len(faces)
|
||||
|
|
|
@ -613,7 +613,6 @@ url_manual_mapping = (
|
|||
("bpy.types.volumedisplay.interpolation_method*", "modeling/volumes/properties.html#bpy-types-volumedisplay-interpolation-method"),
|
||||
("bpy.ops.geometry.color_attribute_render_set*", "modeling/meshes/properties/object_data.html#bpy-ops-geometry-color-attribute-render-set"),
|
||||
("bpy.ops.mesh.customdata_crease_vertex_clear*", "modeling/meshes/properties/custom_data.html#bpy-ops-mesh-customdata-crease-vertex-clear"),
|
||||
("bpy.types.brush.html#bpy.types.brush.jitter*", "sculpt_paint/brush/stroke.html#bpy-types-brush-html-bpy-types-brush-jitter"),
|
||||
("bpy.types.brushgpencilsettings.angle_factor*", "grease_pencil/modes/draw/tools/draw.html#bpy-types-brushgpencilsettings-angle-factor"),
|
||||
("bpy.types.brushgpencilsettings.pen_strength*", "grease_pencil/modes/draw/tools/erase.html#bpy-types-brushgpencilsettings-pen-strength"),
|
||||
("bpy.types.clothcollisionsettings.collection*", "physics/cloth/settings/collisions.html#bpy-types-clothcollisionsettings-collection"),
|
||||
|
@ -644,7 +643,7 @@ url_manual_mapping = (
|
|||
("bpy.types.geometrynodeinputmeshedgevertices*", "modeling/geometry_nodes/mesh/read/edge_vertices.html#bpy-types-geometrynodeinputmeshedgevertices"),
|
||||
("bpy.types.geometrynodeinputmeshfaceisplanar*", "modeling/geometry_nodes/mesh/read/face_is_planar.html#bpy-types-geometrynodeinputmeshfaceisplanar"),
|
||||
("bpy.types.geometrynodeinputsplineresolution*", "modeling/geometry_nodes/curve/read/spline_resolution.html#bpy-types-geometrynodeinputsplineresolution"),
|
||||
("bpy.types.geometrynodemeshfacesetboundaries*", "modeling/geometry_nodes/mesh/read/face_set_boundaries.html#bpy-types-geometrynodemeshfacesetboundaries"),
|
||||
("bpy.types.geometrynodemeshfacesetboundaries*", "modeling/geometry_nodes/mesh/read/face_group_boundaries.html#bpy-types-geometrynodemeshfacesetboundaries"),
|
||||
("bpy.types.greasepencil.curve_edit_threshold*", "grease_pencil/modes/edit/curve_editing.html#bpy-types-greasepencil-curve-edit-threshold"),
|
||||
("bpy.types.lineartgpencilmodifier.use_crease*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-crease"),
|
||||
("bpy.types.lineartgpencilmodifier.use_shadow*", "grease_pencil/modifiers/generate/line_art.html#bpy-types-lineartgpencilmodifier-use-shadow"),
|
||||
|
@ -1389,6 +1388,7 @@ url_manual_mapping = (
|
|||
("bpy.types.functionnodereplacestring*", "modeling/geometry_nodes/utilities/text/replace_string.html#bpy-types-functionnodereplacestring"),
|
||||
("bpy.types.functionnodeseparatecolor*", "modeling/geometry_nodes/utilities/color/separate_color.html#bpy-types-functionnodeseparatecolor"),
|
||||
("bpy.types.functionnodevaluetostring*", "modeling/geometry_nodes/utilities/text/value_to_string.html#bpy-types-functionnodevaluetostring"),
|
||||
("bpy.types.geometrynodeblurattribute*", "modeling/geometry_nodes/attribute/blur_attribute.html#bpy-types-geometrynodeblurattribute"),
|
||||
("bpy.types.geometrynodecurvetopoints*", "modeling/geometry_nodes/curve/operations/curve_to_points.html#bpy-types-geometrynodecurvetopoints"),
|
||||
("bpy.types.geometrynodeedgesofcorner*", "modeling/geometry_nodes/mesh/topology/edges_of_corner.html#bpy-types-geometrynodeedgesofcorner"),
|
||||
("bpy.types.geometrynodeedgesofvertex*", "modeling/geometry_nodes/mesh/topology/edges_of_vertex.html#bpy-types-geometrynodeedgesofvertex"),
|
||||
|
@ -2027,7 +2027,6 @@ url_manual_mapping = (
|
|||
("bpy.ops.graph.equalize_handles*", "editors/graph_editor/fcurves/editing.html#bpy-ops-graph-equalize-handles"),
|
||||
("bpy.ops.mball.delete_metaelems*", "modeling/metas/editing.html#bpy-ops-mball-delete-metaelems"),
|
||||
("bpy.ops.mball.reveal_metaelems*", "modeling/metas/properties.html#bpy-ops-mball-reveal-metaelems"),
|
||||
("bpy.ops.mesh.bridge-edge-loops*", "modeling/meshes/editing/edge/bridge_edge_loops.html#bpy-ops-mesh-bridge-edge-loops"),
|
||||
("bpy.ops.mesh.intersect_boolean*", "modeling/meshes/editing/face/intersect_boolean.html#bpy-ops-mesh-intersect-boolean"),
|
||||
("bpy.ops.mesh.loop_multi_select*", "modeling/meshes/selecting/loops.html#bpy-ops-mesh-loop-multi-select"),
|
||||
("bpy.ops.mesh.vert_connect_path*", "modeling/meshes/editing/vertex/connect_vertex_path.html#bpy-ops-mesh-vert-connect-path"),
|
||||
|
@ -2083,7 +2082,6 @@ url_manual_mapping = (
|
|||
("bpy.types.geometrynodeboundbox*", "modeling/geometry_nodes/geometry/operations/bounding_box.html#bpy-types-geometrynodeboundbox"),
|
||||
("bpy.types.geometrynodecurvearc*", "modeling/geometry_nodes/curve/primitives/arc.html#bpy-types-geometrynodecurvearc"),
|
||||
("bpy.types.geometrynodedualmesh*", "modeling/geometry_nodes/mesh/operations/dual_mesh.html#bpy-types-geometrynodedualmesh"),
|
||||
("bpy.types.geometrynodematerial*", "-1"),
|
||||
("bpy.types.geometrynodemeshcone*", "modeling/geometry_nodes/mesh/primitives/cone.html#bpy-types-geometrynodemeshcone"),
|
||||
("bpy.types.geometrynodemeshcube*", "modeling/geometry_nodes/mesh/primitives/cube.html#bpy-types-geometrynodemeshcube"),
|
||||
("bpy.types.geometrynodemeshgrid*", "modeling/geometry_nodes/mesh/primitives/grid.html#bpy-types-geometrynodemeshgrid"),
|
||||
|
|
|
@ -86,7 +86,7 @@ class Prefs(bpy.types.KeyConfigPreferences):
|
|||
update=update_fn,
|
||||
)
|
||||
|
||||
# Experimental: only show with developer extras, see: T96544.
|
||||
# Experimental: only show with developer extras, see: #96544.
|
||||
use_tweak_select_passthrough: BoolProperty(
|
||||
name="Tweak Select: Mouse Select & Move",
|
||||
description=(
|
||||
|
@ -96,7 +96,7 @@ class Prefs(bpy.types.KeyConfigPreferences):
|
|||
default=False,
|
||||
update=update_fn,
|
||||
)
|
||||
# Experimental: only show with developer extras, see: T96544.
|
||||
# Experimental: only show with developer extras, see: #96544.
|
||||
use_tweak_tool_lmb_interaction: BoolProperty(
|
||||
name="Tweak Tool: Left Mouse Select & Move",
|
||||
description=(
|
||||
|
|
|
@ -37,7 +37,7 @@ class Params:
|
|||
# instead be bound to a binding that doesn't de-select all, this way:
|
||||
# - Click-drag moves the current selection.
|
||||
# - Click selects only the item at the cursor position.
|
||||
# See: T97032.
|
||||
# See: #97032.
|
||||
"use_tweak_select_passthrough",
|
||||
"use_tweak_tool_lmb_interaction",
|
||||
"use_mouse_emulate_3_button",
|
||||
|
@ -465,7 +465,7 @@ def _template_items_tool_select(
|
|||
fallback=False,
|
||||
):
|
||||
if not params.legacy and not fallback:
|
||||
# Experimental support for LMB interaction for the tweak tool. see: T96544.
|
||||
# Experimental support for LMB interaction for the tweak tool. see: #96544.
|
||||
# NOTE: For RMB-select this is a much bigger change as it disables 3D cursor placement on LMB.
|
||||
# For LMB-select this means an LMB -drag will not first de-select all (similar to node/graph editor).
|
||||
select_passthrough = False
|
||||
|
@ -498,7 +498,7 @@ def _template_items_tool_select(
|
|||
{"properties": [("toggle", True), *operator_props]}),
|
||||
|
||||
# Fallback key-map must transform as the primary tool is expected
|
||||
# to be accessed via gizmos in this case. See: T96885.
|
||||
# to be accessed via gizmos in this case. See: #96885.
|
||||
*(() if not fallback else (
|
||||
("transform.translate", {"type": 'LEFTMOUSE', "value": 'CLICK_DRAG'},
|
||||
{"properties": [("release_confirm", True)]}),
|
||||
|
@ -3478,7 +3478,8 @@ def km_animation_channels(params):
|
|||
# Selection.
|
||||
*_template_items_select_actions(params, "anim.channels_select_all"),
|
||||
("anim.channels_select_box", {"type": 'B', "value": 'PRESS'}, None),
|
||||
("anim.channels_select_box", {"type": 'LEFTMOUSE', "value": 'CLICK_DRAG'}, None),
|
||||
("anim.channels_select_box", {"type": 'LEFTMOUSE', "value": 'CLICK_DRAG'},
|
||||
{"properties": [("extend", False)]}),
|
||||
("anim.channels_select_box", {"type": 'LEFTMOUSE', "value": 'CLICK_DRAG', "shift": True},
|
||||
{"properties": [("extend", True)]}),
|
||||
("anim.channels_select_box", {"type": 'LEFTMOUSE', "value": 'CLICK_DRAG', "ctrl": True},
|
||||
|
@ -4729,7 +4730,7 @@ def _template_paint_radial_control(paint, rotation=False, secondary_rotation=Fal
|
|||
|
||||
def _template_view3d_select(*, type, value, legacy, select_passthrough, exclude_mod=None):
|
||||
# NOTE: `exclude_mod` is needed since we don't want this tool to exclude Control-RMB actions when this is used
|
||||
# as a tool key-map with RMB-select and `use_fallback_tool` is enabled with RMB select. See T92467.
|
||||
# as a tool key-map with RMB-select and `use_fallback_tool` is enabled with RMB select. See #92467.
|
||||
|
||||
props_vert_without_handles = ()
|
||||
if select_passthrough:
|
||||
|
@ -5627,6 +5628,7 @@ def km_curves(params):
|
|||
("curves.disable_selection", {"type": 'ONE', "value": 'PRESS', "alt": True}, None),
|
||||
("curves.disable_selection", {"type": 'TWO', "value": 'PRESS', "alt": True}, None),
|
||||
*_template_items_select_actions(params, "curves.select_all"),
|
||||
("curves.select_linked", {"type": 'L', "value": 'PRESS', "ctrl": True}, None),
|
||||
])
|
||||
|
||||
return keymap
|
||||
|
@ -5681,7 +5683,7 @@ def km_object_non_modal(params):
|
|||
])
|
||||
else:
|
||||
items.extend([
|
||||
# NOTE: this shortcut (while not temporary) is not ideal, see: T89757.
|
||||
# NOTE: this shortcut (while not temporary) is not ideal, see: #89757.
|
||||
("object.transfer_mode", {"type": 'Q', "value": 'PRESS', "alt": True}, None),
|
||||
])
|
||||
|
||||
|
|
|
@ -790,7 +790,7 @@ class TransformsToDeltasAnim(Operator):
|
|||
continue
|
||||
|
||||
# first pass over F-Curves: ensure that we don't have conflicting
|
||||
# transforms already (e.g. if this was applied already) T29110.
|
||||
# transforms already (e.g. if this was applied already) #29110.
|
||||
existingFCurves = {}
|
||||
for fcu in adt.action.fcurves:
|
||||
# get "delta" path - i.e. the final paths which may clash
|
||||
|
|
|
@ -700,7 +700,7 @@ class PREFERENCES_OT_addon_install(Operator):
|
|||
addons_new.discard("modules")
|
||||
|
||||
# disable any addons we may have enabled previously and removed.
|
||||
# this is unlikely but do just in case. bug T23978.
|
||||
# this is unlikely but do just in case. bug #23978.
|
||||
for new_addon in addons_new:
|
||||
addon_utils.disable(new_addon, default_set=True)
|
||||
|
||||
|
|
|
@ -581,7 +581,7 @@ class LightMapPack(Operator):
|
|||
# Proper solution would be to make undo stack aware of such things,
|
||||
# but for now just disable redo. Keep undo here so unwanted changes to uv
|
||||
# coords might be undone.
|
||||
# This fixes infinite image creation reported there T30968 (sergey)
|
||||
# This fixes infinite image creation reported there #30968 (sergey)
|
||||
bl_options = {'UNDO'}
|
||||
|
||||
PREF_CONTEXT: bpy.props.EnumProperty(
|
||||
|
|
|
@ -90,7 +90,7 @@ def applyVertexDirt(me, blur_iterations, blur_strength, clamp_dirt, clamp_clean,
|
|||
tone_range = max_tone - min_tone
|
||||
|
||||
if tone_range < 0.0001:
|
||||
# weak, don't cancel, see T43345
|
||||
# weak, don't cancel, see #43345
|
||||
tone_range = 0.0
|
||||
else:
|
||||
tone_range = 1.0 / tone_range
|
||||
|
|
|
@ -42,7 +42,7 @@ class VIEW3D_OT_edit_mesh_extrude_individual_move(Operator):
|
|||
bpy.ops.mesh.extrude_vertices_move('INVOKE_REGION_WIN')
|
||||
|
||||
# ignore return from operators above because they are 'RUNNING_MODAL',
|
||||
# and cause this one not to be freed. T24671.
|
||||
# and cause this one not to be freed. #24671.
|
||||
return {'FINISHED'}
|
||||
|
||||
def invoke(self, context, _event):
|
||||
|
@ -104,7 +104,7 @@ class VIEW3D_OT_edit_mesh_extrude_move(Operator):
|
|||
'INVOKE_REGION_WIN',
|
||||
TRANSFORM_OT_translate={
|
||||
# Don't set the constraint axis since users will expect MMB
|
||||
# to use the user setting, see: T61637
|
||||
# to use the user setting, see: #61637
|
||||
# "orient_type": 'NORMAL',
|
||||
# Not a popular choice, too restrictive for retopo.
|
||||
# "constraint_axis": (True, True, False)})
|
||||
|
@ -114,7 +114,7 @@ class VIEW3D_OT_edit_mesh_extrude_move(Operator):
|
|||
bpy.ops.mesh.extrude_region_move('INVOKE_REGION_WIN')
|
||||
|
||||
# ignore return from operators above because they are 'RUNNING_MODAL',
|
||||
# and cause this one not to be freed. T24671.
|
||||
# and cause this one not to be freed. #24671.
|
||||
return {'FINISHED'}
|
||||
|
||||
def execute(self, context):
|
||||
|
|
|
@ -1725,7 +1725,7 @@ class WM_OT_properties_edit(Operator):
|
|||
for nt in adt.nla_tracks:
|
||||
_update_strips(nt.strips)
|
||||
|
||||
# Otherwise existing buttons which reference freed memory may crash Blender (T26510).
|
||||
# Otherwise existing buttons which reference freed memory may crash Blender (#26510).
|
||||
for win in context.window_manager.windows:
|
||||
for area in win.screen.areas:
|
||||
area.tag_redraw()
|
||||
|
|
|
@ -35,19 +35,10 @@ def draw_node_group_add_menu(context, layout):
|
|||
if node_tree:
|
||||
from nodeitems_builtins import node_tree_group_type
|
||||
|
||||
def contains_group(nodetree, group):
|
||||
if nodetree == group:
|
||||
return True
|
||||
for node in nodetree.nodes:
|
||||
if node.bl_idname in node_tree_group_type.values() and node.node_tree is not None:
|
||||
if contains_group(node.node_tree, group):
|
||||
return True
|
||||
return False
|
||||
|
||||
groups = [
|
||||
group for group in context.blend_data.node_groups
|
||||
if (group.bl_idname == node_tree.bl_idname and
|
||||
not contains_group(group, node_tree) and
|
||||
not group.contains_tree(node_tree) and
|
||||
not group.name.startswith('.'))
|
||||
]
|
||||
if groups:
|
||||
|
|
|
@ -485,7 +485,6 @@ class DATA_PT_customdata(MeshButtonsPanel, Panel):
|
|||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False
|
||||
|
||||
obj = context.object
|
||||
me = context.mesh
|
||||
col = layout.column()
|
||||
|
||||
|
|
|
@ -62,7 +62,6 @@ class PARTICLE_MT_context_menu(Menu):
|
|||
def draw(self, context):
|
||||
layout = self.layout
|
||||
psys = context.particle_system
|
||||
experimental = context.preferences.experimental
|
||||
|
||||
props = layout.operator(
|
||||
"particle.copy_particle_systems",
|
||||
|
@ -508,7 +507,7 @@ class PARTICLE_PT_hair_dynamics_structure(ParticleButtonsPanel, Panel):
|
|||
sub.prop(psys.settings, "bending_random", text="Random")
|
||||
col.prop(cloth, "bending_damping", text="Damping")
|
||||
# XXX has no noticeable effect with stiff hair structure springs
|
||||
#col.prop(cloth, "spring_damping", text="Damping")
|
||||
# col.prop(cloth, "spring_damping", text="Damping")
|
||||
|
||||
|
||||
class PARTICLE_PT_hair_dynamics_volume(ParticleButtonsPanel, Panel):
|
||||
|
@ -1100,7 +1099,7 @@ class PARTICLE_PT_physics_relations(ParticleButtonsPanel, Panel):
|
|||
if part.physics_type == 'KEYED':
|
||||
col = layout.column()
|
||||
# doesn't work yet
|
||||
#col.alert = key.valid
|
||||
# col.alert = key.valid
|
||||
col.prop(key, "object")
|
||||
col.prop(key, "system", text="System")
|
||||
sub = col.column(align=True)
|
||||
|
@ -1110,7 +1109,7 @@ class PARTICLE_PT_physics_relations(ParticleButtonsPanel, Panel):
|
|||
elif part.physics_type == 'BOIDS':
|
||||
sub = layout.column()
|
||||
# doesn't work yet
|
||||
#sub.alert = key.valid
|
||||
# sub.alert = key.valid
|
||||
sub.prop(key, "object")
|
||||
sub.prop(key, "system", text="System")
|
||||
layout.prop(key, "alliance")
|
||||
|
@ -1157,7 +1156,7 @@ class PARTICLE_PT_physics_fluid_interaction(ParticleButtonsPanel, Panel):
|
|||
if key:
|
||||
sub = layout.column()
|
||||
# doesn't work yet
|
||||
#sub.alert = key.valid
|
||||
# sub.alert = key.valid
|
||||
sub.prop(key, "object")
|
||||
sub.prop(key, "system", text="System")
|
||||
|
||||
|
|
|
@ -641,7 +641,6 @@ class RENDER_PT_eevee_next_film(RenderButtonsPanel, Panel):
|
|||
|
||||
scene = context.scene
|
||||
rd = scene.render
|
||||
props = scene.eevee
|
||||
|
||||
col = layout.column()
|
||||
col.prop(rd, "filter_size")
|
||||
|
|
|
@ -91,7 +91,7 @@ class TEXTURE_PT_preview(TextureButtonsPanel, Panel):
|
|||
else:
|
||||
layout.template_preview(tex, slot=slot)
|
||||
|
||||
# Show Alpha Button for Brush Textures, see T29502.
|
||||
# Show Alpha Button for Brush Textures, see #29502.
|
||||
idblock = context_tex_datablock(context)
|
||||
if isinstance(idblock, Brush):
|
||||
layout.prop(tex, "use_preview_alpha")
|
||||
|
|
|
@ -62,7 +62,7 @@ class NODE_HT_header(Header):
|
|||
|
||||
types_that_support_material = {'MESH', 'CURVE', 'SURFACE', 'FONT', 'META',
|
||||
'GPENCIL', 'VOLUME', 'CURVES', 'POINTCLOUD'}
|
||||
# disable material slot buttons when pinned, cannot find correct slot within id_from (T36589)
|
||||
# disable material slot buttons when pinned, cannot find correct slot within id_from (#36589)
|
||||
# disable also when the selected object does not support materials
|
||||
has_material_slots = not snode.pin and ob_type in types_that_support_material
|
||||
|
||||
|
|
|
@ -407,7 +407,7 @@ class SEQUENCER_MT_view(Menu):
|
|||
if st.view_type == 'PREVIEW':
|
||||
# Specifying the REGION_PREVIEW context is needed in preview-only
|
||||
# mode, else the lookup for the shortcut will fail in
|
||||
# wm_keymap_item_find_props() (see T32595).
|
||||
# wm_keymap_item_find_props() (see #32595).
|
||||
layout.operator_context = 'INVOKE_REGION_PREVIEW'
|
||||
layout.prop(st, "show_region_ui")
|
||||
layout.prop(st, "show_region_tool_header")
|
||||
|
@ -429,7 +429,7 @@ class SEQUENCER_MT_view(Menu):
|
|||
|
||||
layout.operator_context = 'INVOKE_REGION_WIN'
|
||||
if st.view_type == 'PREVIEW':
|
||||
# See above (T32595)
|
||||
# See above (#32595)
|
||||
layout.operator_context = 'INVOKE_REGION_PREVIEW'
|
||||
layout.operator("sequencer.view_selected", text="Frame Selected")
|
||||
|
||||
|
|
|
@ -326,7 +326,7 @@ class TOPBAR_MT_file_new(Menu):
|
|||
# Expand template paths.
|
||||
|
||||
# Use a set to avoid duplicate user/system templates.
|
||||
# This is a corner case, but users managed to do it! T76849.
|
||||
# This is a corner case, but users managed to do it! #76849.
|
||||
app_templates = set()
|
||||
for path in template_paths:
|
||||
for d in os.listdir(path):
|
||||
|
|
|
@ -2329,6 +2329,9 @@ class USERPREF_PT_experimental_new_features(ExperimentalPanel, Panel):
|
|||
({"property": "use_override_templates"},
|
||||
("blender/blender/issues/73318",
|
||||
"Milestone 4")),
|
||||
({"property": "use_new_volume_nodes"},
|
||||
("blender/blender/issues/103248",
|
||||
"#103248")),
|
||||
),
|
||||
)
|
||||
|
||||
|
|
|
@ -161,6 +161,8 @@ class VIEW3D_HT_tool_header(Header):
|
|||
sub.prop(context.object.data, "use_mirror_y", text="Y", toggle=True)
|
||||
sub.prop(context.object.data, "use_mirror_z", text="Z", toggle=True)
|
||||
|
||||
layout.prop(context.object.data, "use_sculpt_collision", icon='MOD_PHYSICS', icon_only=True, toggle=True)
|
||||
|
||||
# Expand panels from the side-bar as popovers.
|
||||
popover_kw = {"space_type": 'VIEW_3D', "region_type": 'UI', "category": "Tool"}
|
||||
|
||||
|
@ -890,7 +892,7 @@ class VIEW3D_HT_header(Header):
|
|||
row.active = (object_mode == 'EDIT') or (shading.type in {'WIREFRAME', 'SOLID'})
|
||||
|
||||
# While exposing `shading.show_xray(_wireframe)` is correct.
|
||||
# this hides the key shortcut from users: T70433.
|
||||
# this hides the key shortcut from users: #70433.
|
||||
if has_pose_mode:
|
||||
draw_depressed = overlay.show_xray_bone
|
||||
elif shading.type == 'WIREFRAME':
|
||||
|
@ -2052,6 +2054,7 @@ class VIEW3D_MT_select_edit_curves(Menu):
|
|||
layout.operator("curves.select_all", text="Invert").action = 'INVERT'
|
||||
layout.operator("curves.select_random", text="Random")
|
||||
layout.operator("curves.select_end", text="Endpoints")
|
||||
layout.operator("curves.select_linked", text="Linked")
|
||||
|
||||
|
||||
class VIEW3D_MT_select_sculpt_curves(Menu):
|
||||
|
@ -2267,7 +2270,7 @@ class VIEW3D_MT_add(Menu):
|
|||
# NOTE: don't use 'EXEC_SCREEN' or operators won't get the `v3d` context.
|
||||
|
||||
# NOTE: was `EXEC_AREA`, but this context does not have the `rv3d`, which prevents
|
||||
# "align_view" to work on first call (see T32719).
|
||||
# "align_view" to work on first call (see #32719).
|
||||
layout.operator_context = 'EXEC_REGION_WIN'
|
||||
|
||||
# layout.operator_menu_enum("object.mesh_add", "type", text="Mesh", icon='OUTLINER_OB_MESH')
|
||||
|
@ -5435,7 +5438,7 @@ class VIEW3D_MT_shading_ex_pie(Menu):
|
|||
pie.prop_enum(view.shading, "type", value='WIREFRAME')
|
||||
pie.prop_enum(view.shading, "type", value='SOLID')
|
||||
|
||||
# Note this duplicates "view3d.toggle_xray" logic, so we can see the active item: T58661.
|
||||
# Note this duplicates "view3d.toggle_xray" logic, so we can see the active item: #58661.
|
||||
if context.pose_object:
|
||||
pie.prop(view.overlay, "show_xray_bone", icon='XRAY')
|
||||
else:
|
||||
|
@ -6766,13 +6769,12 @@ class VIEW3D_PT_overlay_sculpt(Panel):
|
|||
def poll(cls, context):
|
||||
return (
|
||||
context.mode == 'SCULPT' and
|
||||
(context.sculpt_object and context.tool_settings.sculpt)
|
||||
context.sculpt_object
|
||||
)
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
tool_settings = context.tool_settings
|
||||
sculpt = tool_settings.sculpt
|
||||
|
||||
view = context.space_data
|
||||
overlay = view.overlay
|
||||
|
|
|
@ -639,7 +639,7 @@ class BUILTIN_KSI_DeltaScale(KeyingSetInfo):
|
|||
|
||||
# Note that this controls order of options in `insert keyframe` menu.
|
||||
# Better try to keep some logical order here beyond mere alphabetical one, also because of menu entries shortcut.
|
||||
# See also T51867.
|
||||
# See also #51867.
|
||||
classes = (
|
||||
BUILTIN_KSI_Available,
|
||||
BUILTIN_KSI_Location,
|
||||
|
|
|
@ -76,21 +76,11 @@ def node_group_items(context):
|
|||
|
||||
yield NodeItemCustom(draw=lambda self, layout, context: layout.separator())
|
||||
|
||||
def contains_group(nodetree, group):
|
||||
if nodetree == group:
|
||||
return True
|
||||
else:
|
||||
for node in nodetree.nodes:
|
||||
if node.bl_idname in node_tree_group_type.values() and node.node_tree is not None:
|
||||
if contains_group(node.node_tree, group):
|
||||
return True
|
||||
return False
|
||||
|
||||
for group in context.blend_data.node_groups:
|
||||
if group.bl_idname != ntree.bl_idname:
|
||||
continue
|
||||
# filter out recursive groups
|
||||
if contains_group(group, ntree):
|
||||
if group.contains_tree(ntree):
|
||||
continue
|
||||
# filter out hidden nodetrees
|
||||
if group.name.startswith('.'):
|
||||
|
|
|
@ -23,11 +23,15 @@ struct ID;
|
|||
|
||||
namespace blender::asset_system {
|
||||
|
||||
class AssetLibrary;
|
||||
|
||||
class AssetRepresentation {
|
||||
AssetIdentifier identifier_;
|
||||
/** Indicate if this is a local or external asset, and as such, which of the union members below
|
||||
* should be used. */
|
||||
const bool is_local_id_ = false;
|
||||
/** Asset library that owns this asset representation. */
|
||||
const AssetLibrary *owner_asset_library_;
|
||||
|
||||
struct ExternalAsset {
|
||||
std::string name;
|
||||
|
@ -44,10 +48,13 @@ class AssetRepresentation {
|
|||
/** Constructs an asset representation for an external ID. The asset will not be editable. */
|
||||
AssetRepresentation(AssetIdentifier &&identifier,
|
||||
StringRef name,
|
||||
std::unique_ptr<AssetMetaData> metadata);
|
||||
std::unique_ptr<AssetMetaData> metadata,
|
||||
const AssetLibrary &owner_asset_library);
|
||||
/** Constructs an asset representation for an ID stored in the current file. This makes the asset
|
||||
* local and fully editable. */
|
||||
AssetRepresentation(AssetIdentifier &&identifier, ID &id);
|
||||
AssetRepresentation(AssetIdentifier &&identifier,
|
||||
ID &id,
|
||||
const AssetLibrary &owner_asset_library);
|
||||
AssetRepresentation(AssetRepresentation &&other);
|
||||
/* Non-copyable type. */
|
||||
AssetRepresentation(const AssetRepresentation &other) = delete;
|
||||
|
@ -65,6 +72,7 @@ class AssetRepresentation {
|
|||
AssetMetaData &get_metadata() const;
|
||||
/** Returns if this asset is stored inside this current file, and as such fully editable. */
|
||||
bool is_local_id() const;
|
||||
const AssetLibrary &owner_asset_library() const;
|
||||
};
|
||||
|
||||
} // namespace blender::asset_system
|
||||
|
|
|
@ -169,13 +169,14 @@ AssetRepresentation &AssetLibrary::add_external_asset(StringRef relative_asset_p
|
|||
std::unique_ptr<AssetMetaData> metadata)
|
||||
{
|
||||
AssetIdentifier identifier = asset_identifier_from_library(relative_asset_path);
|
||||
return asset_storage_->add_external_asset(std::move(identifier), name, std::move(metadata));
|
||||
return asset_storage_->add_external_asset(
|
||||
std::move(identifier), name, std::move(metadata), *this);
|
||||
}
|
||||
|
||||
AssetRepresentation &AssetLibrary::add_local_id_asset(StringRef relative_asset_path, ID &id)
|
||||
{
|
||||
AssetIdentifier identifier = asset_identifier_from_library(relative_asset_path);
|
||||
return asset_storage_->add_local_id_asset(std::move(identifier), id);
|
||||
return asset_storage_->add_local_id_asset(std::move(identifier), id, *this);
|
||||
}
|
||||
|
||||
bool AssetLibrary::remove_asset(AssetRepresentation &asset)
|
||||
|
|
|
@ -17,15 +17,24 @@ namespace blender::asset_system {
|
|||
|
||||
AssetRepresentation::AssetRepresentation(AssetIdentifier &&identifier,
|
||||
StringRef name,
|
||||
std::unique_ptr<AssetMetaData> metadata)
|
||||
: identifier_(identifier), is_local_id_(false), external_asset_()
|
||||
std::unique_ptr<AssetMetaData> metadata,
|
||||
const AssetLibrary &owner_asset_library)
|
||||
: identifier_(identifier),
|
||||
is_local_id_(false),
|
||||
owner_asset_library_(&owner_asset_library),
|
||||
external_asset_()
|
||||
{
|
||||
external_asset_.name = name;
|
||||
external_asset_.metadata_ = std::move(metadata);
|
||||
}
|
||||
|
||||
AssetRepresentation::AssetRepresentation(AssetIdentifier &&identifier, ID &id)
|
||||
: identifier_(identifier), is_local_id_(true), local_asset_id_(&id)
|
||||
AssetRepresentation::AssetRepresentation(AssetIdentifier &&identifier,
|
||||
ID &id,
|
||||
const AssetLibrary &owner_asset_library)
|
||||
: identifier_(identifier),
|
||||
is_local_id_(true),
|
||||
owner_asset_library_(&owner_asset_library),
|
||||
local_asset_id_(&id)
|
||||
{
|
||||
if (!id.asset_data) {
|
||||
throw std::invalid_argument("Passed ID is not an asset");
|
||||
|
@ -75,6 +84,11 @@ bool AssetRepresentation::is_local_id() const
|
|||
return is_local_id_;
|
||||
}
|
||||
|
||||
const AssetLibrary &AssetRepresentation::owner_asset_library() const
|
||||
{
|
||||
return *owner_asset_library_;
|
||||
}
|
||||
|
||||
} // namespace blender::asset_system
|
||||
|
||||
using namespace blender;
|
||||
|
|
|
@ -15,18 +15,21 @@
|
|||
|
||||
namespace blender::asset_system {
|
||||
|
||||
AssetRepresentation &AssetStorage::add_local_id_asset(AssetIdentifier &&identifier, ID &id)
|
||||
AssetRepresentation &AssetStorage::add_local_id_asset(AssetIdentifier &&identifier,
|
||||
ID &id,
|
||||
const AssetLibrary &owner_asset_library)
|
||||
{
|
||||
return *local_id_assets_.lookup_key_or_add(
|
||||
std::make_unique<AssetRepresentation>(std::move(identifier), id));
|
||||
std::make_unique<AssetRepresentation>(std::move(identifier), id, owner_asset_library));
|
||||
}
|
||||
|
||||
AssetRepresentation &AssetStorage::add_external_asset(AssetIdentifier &&identifier,
|
||||
StringRef name,
|
||||
std::unique_ptr<AssetMetaData> metadata)
|
||||
std::unique_ptr<AssetMetaData> metadata,
|
||||
const AssetLibrary &owner_asset_library)
|
||||
{
|
||||
return *external_assets_.lookup_key_or_add(
|
||||
std::make_unique<AssetRepresentation>(std::move(identifier), name, std::move(metadata)));
|
||||
return *external_assets_.lookup_key_or_add(std::make_unique<AssetRepresentation>(
|
||||
std::move(identifier), name, std::move(metadata), owner_asset_library));
|
||||
}
|
||||
|
||||
bool AssetStorage::remove_asset(AssetRepresentation &asset)
|
||||
|
|
|
@ -35,9 +35,12 @@ class AssetStorage {
|
|||
/** See #AssetLibrary::add_external_asset(). */
|
||||
AssetRepresentation &add_external_asset(AssetIdentifier &&identifier,
|
||||
StringRef name,
|
||||
std::unique_ptr<AssetMetaData> metadata);
|
||||
std::unique_ptr<AssetMetaData> metadata,
|
||||
const AssetLibrary &owner_asset_library);
|
||||
/** See #AssetLibrary::add_external_asset(). */
|
||||
AssetRepresentation &add_local_id_asset(AssetIdentifier &&identifier, ID &id);
|
||||
AssetRepresentation &add_local_id_asset(AssetIdentifier &&identifier,
|
||||
ID &id,
|
||||
const AssetLibrary &owner_asset_library);
|
||||
|
||||
/** See #AssetLibrary::remove_asset(). */
|
||||
bool remove_asset(AssetRepresentation &asset);
|
||||
|
|
|
@ -165,7 +165,7 @@ int BLF_load_unique(const char *name)
|
|||
|
||||
/* XXX: Temporarily disable kerning in our main font. Kerning had been accidentally removed from
|
||||
* our font in 3.1. In 3.4 we disable kerning here in the new version to keep spacing the same
|
||||
* (T101506). Enable again later with change of font, placement, or rendering - Harley. */
|
||||
* (#101506). Enable again later with change of font, placement, or rendering - Harley. */
|
||||
if (font && BLI_str_endswith(filepath, BLF_DEFAULT_PROPORTIONAL_FONT)) {
|
||||
font->face_flags &= ~FT_FACE_FLAG_KERNING;
|
||||
}
|
||||
|
|
|
@ -271,7 +271,7 @@ struct bPoseChannel *BKE_pose_channel_active_if_layer_visible(struct Object *ob)
|
|||
* In this case the active-selected is an obvious choice when finding the target for a
|
||||
* constraint for eg. however from the users perspective the active pose bone of the
|
||||
* active object is the _real_ active bone, so any other non-active selected bone
|
||||
* is a candidate for being the other selected bone, see: T58447.
|
||||
* is a candidate for being the other selected bone, see: #58447.
|
||||
*/
|
||||
struct bPoseChannel *BKE_pose_channel_active_or_first_selected(struct Object *ob);
|
||||
/**
|
||||
|
|
|
@ -37,7 +37,7 @@ struct bActionGroup;
|
|||
/* Container for data required to do FCurve and Driver evaluation. */
|
||||
typedef struct AnimationEvalContext {
|
||||
/* For drivers, so that they have access to the dependency graph and the current view layer. See
|
||||
* T77086. */
|
||||
* #77086. */
|
||||
struct Depsgraph *depsgraph;
|
||||
|
||||
/* FCurves and Drivers can be evaluated at a different time than the current scene time, for
|
||||
|
|
|
@ -25,7 +25,7 @@ extern "C" {
|
|||
|
||||
/* Blender file format version. */
|
||||
#define BLENDER_FILE_VERSION BLENDER_VERSION
|
||||
#define BLENDER_FILE_SUBVERSION 8
|
||||
#define BLENDER_FILE_SUBVERSION 9
|
||||
|
||||
/* Minimum Blender version that supports reading file written with the current
|
||||
* version. Older Blender versions will test this and show a warning if the file
|
||||
|
|
|
@ -137,6 +137,7 @@ bool CustomData_has_referenced(const struct CustomData *data);
|
|||
* implemented for mloopuv/mloopcol, for now.
|
||||
*/
|
||||
void CustomData_data_copy_value(int type, const void *source, void *dest);
|
||||
void CustomData_data_set_default_value(int type, void *elem);
|
||||
|
||||
/**
|
||||
* Mixes the "value" (e.g. mloopuv uv or mloopcol colors) from one block into
|
||||
|
@ -506,6 +507,8 @@ void CustomData_clear_layer_flag(struct CustomData *data, int type, int flag);
|
|||
|
||||
void CustomData_bmesh_set_default(struct CustomData *data, void **block);
|
||||
void CustomData_bmesh_free_block(struct CustomData *data, void **block);
|
||||
void CustomData_bmesh_alloc_block(struct CustomData *data, void **block);
|
||||
|
||||
/**
|
||||
* Same as #CustomData_bmesh_free_block but zero the memory rather than freeing.
|
||||
*/
|
||||
|
@ -517,23 +520,6 @@ void CustomData_bmesh_free_block_data_exclude_by_type(struct CustomData *data,
|
|||
void *block,
|
||||
eCustomDataMask mask_exclude);
|
||||
|
||||
/**
|
||||
* Copy custom data to/from layers as in mesh/derived-mesh, to edit-mesh
|
||||
* blocks of data. the CustomData's must not be compatible.
|
||||
*
|
||||
* \param use_default_init: initializes data which can't be copied,
|
||||
* typically you'll want to use this if the BM_xxx create function
|
||||
* is called with BM_CREATE_SKIP_CD flag
|
||||
*/
|
||||
void CustomData_to_bmesh_block(const struct CustomData *source,
|
||||
struct CustomData *dest,
|
||||
int src_index,
|
||||
void **dest_block,
|
||||
bool use_default_init);
|
||||
void CustomData_from_bmesh_block(const struct CustomData *source,
|
||||
struct CustomData *dest,
|
||||
void *src_block,
|
||||
int dest_index);
|
||||
|
||||
/**
|
||||
* Query info over types.
|
||||
|
|
|
@ -134,7 +134,7 @@ typedef struct Main {
|
|||
|
||||
/**
|
||||
* When linking, disallow creation of new data-blocks.
|
||||
* Make sure we don't do this by accident, see T76738.
|
||||
* Make sure we don't do this by accident, see #76738.
|
||||
*/
|
||||
bool is_locked_for_linking;
|
||||
|
||||
|
|
|
@ -812,7 +812,7 @@ struct Mesh *BKE_mesh_merge_verts(struct Mesh *mesh,
|
|||
* Account for custom-data such as UVs becoming detached because of imprecision
|
||||
* in custom-data interpolation.
|
||||
* Without running this operation subdivision surface can cause UVs to be disconnected,
|
||||
* see: T81065.
|
||||
* see: #81065.
|
||||
*/
|
||||
void BKE_mesh_merge_customdata_for_apply_modifier(struct Mesh *me);
|
||||
|
||||
|
|
|
@ -170,7 +170,6 @@ void BKE_mesh_vert_edge_vert_map_create(
|
|||
*/
|
||||
void BKE_mesh_edge_loop_map_create(MeshElemMap **r_map,
|
||||
int **r_mem,
|
||||
const struct MEdge *medge,
|
||||
int totedge,
|
||||
const struct MPoly *mpoly,
|
||||
int totpoly,
|
||||
|
@ -183,7 +182,6 @@ void BKE_mesh_edge_loop_map_create(MeshElemMap **r_map,
|
|||
*/
|
||||
void BKE_mesh_edge_poly_map_create(MeshElemMap **r_map,
|
||||
int **r_mem,
|
||||
const struct MEdge *medge,
|
||||
int totedge,
|
||||
const struct MPoly *mpoly,
|
||||
int totpoly,
|
||||
|
@ -317,8 +315,7 @@ bool BKE_mesh_calc_islands_loop_poly_uvmap(float (*vert_positions)[3],
|
|||
* starting at 1 (0 being used as 'invalid' flag).
|
||||
* Note it's callers's responsibility to MEM_freeN returned array.
|
||||
*/
|
||||
int *BKE_mesh_calc_smoothgroups(const struct MEdge *medge,
|
||||
int totedge,
|
||||
int *BKE_mesh_calc_smoothgroups(int totedge,
|
||||
const struct MPoly *mpoly,
|
||||
int totpoly,
|
||||
const struct MLoop *mloop,
|
||||
|
|
|
@ -132,7 +132,7 @@ struct MeshRuntime {
|
|||
*
|
||||
* Modifiers that edit the mesh data in-place must set this to false
|
||||
* (most #eModifierTypeType_NonGeometrical modifiers). Otherwise the edit-mesh
|
||||
* data will be used for drawing, missing changes from modifiers. See T79517.
|
||||
* data will be used for drawing, missing changes from modifiers. See #79517.
|
||||
*/
|
||||
bool is_original_bmesh = false;
|
||||
|
||||
|
|
|
@ -36,10 +36,10 @@ struct PropertyRNA;
|
|||
/* Data Management */
|
||||
|
||||
/**
|
||||
* Remove the given NLA strip from the NLA track it occupies, free the strip's data,
|
||||
* and the strip itself.
|
||||
* Frees the given NLA strip, and calls #BKE_nlastrip_remove_and_free to
|
||||
* remove and free all children strips.
|
||||
*/
|
||||
void BKE_nlastrip_free(ListBase *strips, struct NlaStrip *strip, bool do_id_user);
|
||||
void BKE_nlastrip_free(struct NlaStrip *strip, bool do_id_user);
|
||||
/**
|
||||
* Remove the given NLA track from the set of NLA tracks, free the track's data,
|
||||
* and the track itself.
|
||||
|
@ -94,10 +94,22 @@ void BKE_nla_tracks_copy_from_adt(struct Main *bmain,
|
|||
struct NlaTrack *BKE_nlatrack_add(struct AnimData *adt,
|
||||
struct NlaTrack *prev,
|
||||
bool is_liboverride);
|
||||
|
||||
/**
|
||||
* Create a NLA Strip referencing the given Action.
|
||||
*/
|
||||
struct NlaStrip *BKE_nlastrip_new(struct bAction *act);
|
||||
|
||||
/*
|
||||
* Removes the given NLA strip from the list of strips provided.
|
||||
*/
|
||||
void BKE_nlastrip_remove(ListBase *strips, struct NlaStrip *strip);
|
||||
|
||||
/*
|
||||
* Removes the given NLA strip from the list of strips provided, and frees it's memory.
|
||||
*/
|
||||
void BKE_nlastrip_remove_and_free(ListBase *strips, struct NlaStrip *strip, const bool do_id_user);
|
||||
|
||||
/**
|
||||
* Add new NLA-strip to the top of the NLA stack - i.e.
|
||||
* into the last track if space, or a new one otherwise.
|
||||
|
@ -139,13 +151,9 @@ void BKE_nlastrips_sort_strips(ListBase *strips);
|
|||
void BKE_nlastrips_add_strip_unsafe(ListBase *strips, struct NlaStrip *strip);
|
||||
|
||||
/**
|
||||
* \brief NULL checks incoming strip and verifies no overlap / invalid
|
||||
* configuration against other strips in NLA Track.
|
||||
*
|
||||
* \param strips:
|
||||
* \param strip:
|
||||
* \return true
|
||||
* \return false
|
||||
* NULL checks incoming strip and verifies no overlap / invalid
|
||||
* configuration against other strips in NLA Track before calling
|
||||
* #BKE_nlastrips_add_strip_unsafe.
|
||||
*/
|
||||
bool BKE_nlastrips_add_strip(ListBase *strips, struct NlaStrip *strip);
|
||||
|
||||
|
@ -215,11 +223,16 @@ bool BKE_nlatrack_has_space(struct NlaTrack *nlt, float start, float end);
|
|||
void BKE_nlatrack_sort_strips(struct NlaTrack *nlt);
|
||||
|
||||
/**
|
||||
* Add the given NLA-Strip to the given NLA-Track, assuming that it
|
||||
* isn't currently attached to another one.
|
||||
* Add the given NLA-Strip to the given NLA-Track.
|
||||
* Calls #BKE_nlastrips_add_strip to check if strip can be added.
|
||||
*/
|
||||
bool BKE_nlatrack_add_strip(struct NlaTrack *nlt, struct NlaStrip *strip, bool is_liboverride);
|
||||
|
||||
/**
|
||||
* Remove the NLA-Strip from the given NLA-Track.
|
||||
*/
|
||||
void BKE_nlatrack_remove_strip(struct NlaTrack *track, struct NlaStrip *strip);
|
||||
|
||||
/**
|
||||
* Get the extents of the given NLA-Track including gaps between strips,
|
||||
* returning whether this succeeded or not
|
||||
|
|
|
@ -504,7 +504,13 @@ struct bNodeTree *ntreeFromID(struct ID *id);
|
|||
void ntreeFreeLocalNode(struct bNodeTree *ntree, struct bNode *node);
|
||||
void ntreeFreeLocalTree(struct bNodeTree *ntree);
|
||||
struct bNode *ntreeFindType(struct bNodeTree *ntree, int type);
|
||||
bool ntreeHasTree(const struct bNodeTree *ntree, const struct bNodeTree *lookup);
|
||||
|
||||
/**
|
||||
* Check recursively if a node tree contains another.
|
||||
*/
|
||||
bool ntreeContainsTree(const struct bNodeTree *tree_to_search_in,
|
||||
const struct bNodeTree *tree_to_search_for);
|
||||
|
||||
void ntreeUpdateAllNew(struct Main *main);
|
||||
void ntreeUpdateAllUsers(struct Main *main, struct ID *id);
|
||||
|
||||
|
@ -989,7 +995,7 @@ void node_type_size(struct bNodeType *ntype, int width, int minwidth, int maxwid
|
|||
void node_type_size_preset(struct bNodeType *ntype, eNodeSizePreset size);
|
||||
/**
|
||||
* \warning Nodes defining a storage type _must_ allocate this for new nodes.
|
||||
* Otherwise nodes will reload as undefined (T46619).
|
||||
* Otherwise nodes will reload as undefined (#46619).
|
||||
*/
|
||||
void node_type_storage(struct bNodeType *ntype,
|
||||
const char *storagename,
|
||||
|
|
|
@ -370,7 +370,7 @@ void BKE_object_dimensions_get(struct Object *ob, float r_vec[3]);
|
|||
* typically this caused by parenting, constraints or delta-scale.
|
||||
*
|
||||
* Re-using these values from the object causes a feedback loop
|
||||
* when multiple values are modified at once in some situations. see: T69536.
|
||||
* when multiple values are modified at once in some situations. see: #69536.
|
||||
*/
|
||||
void BKE_object_dimensions_set_ex(struct Object *ob,
|
||||
const float value[3],
|
||||
|
|
|
@ -775,7 +775,7 @@ void BKE_pbvh_node_get_bm_orco_data(PBVHNode *node,
|
|||
/**
|
||||
* \note doing a full search on all vertices here seems expensive,
|
||||
* however this is important to avoid having to recalculate bound-box & sync the buffers to the
|
||||
* GPU (which is far more expensive!) See: T47232.
|
||||
* GPU (which is far more expensive!) See: #47232.
|
||||
*/
|
||||
bool BKE_pbvh_node_has_vert_with_normal_update_tag(PBVH *pbvh, PBVHNode *node);
|
||||
|
||||
|
|
|
@ -911,7 +911,7 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
|
|||
|
||||
/* set the Mesh to only copy needed data */
|
||||
CustomData_MeshMasks mask = md_datamask->mask;
|
||||
/* needMapping check here fixes bug T28112, otherwise it's
|
||||
/* needMapping check here fixes bug #28112, otherwise it's
|
||||
* possible that it won't be copied */
|
||||
CustomData_MeshMasks_update(&mask, &append_mask);
|
||||
if (need_mapping) {
|
||||
|
@ -1678,7 +1678,7 @@ void makeDerivedMesh(struct Depsgraph *depsgraph,
|
|||
BLI_assert(ob->type == OB_MESH);
|
||||
|
||||
/* Evaluated meshes aren't supposed to be created on original instances. If you do,
|
||||
* they aren't cleaned up properly on mode switch, causing crashes, e.g T58150. */
|
||||
* they aren't cleaned up properly on mode switch, causing crashes, e.g #58150. */
|
||||
BLI_assert(ob->id.tag & LIB_TAG_COPIED_ON_WRITE);
|
||||
|
||||
BKE_object_free_derived_caches(ob);
|
||||
|
@ -1715,7 +1715,7 @@ Mesh *mesh_get_eval_final(struct Depsgraph *depsgraph,
|
|||
BLI_assert(DEG_is_evaluating(depsgraph) == false);
|
||||
|
||||
/* Evaluated meshes aren't supposed to be created on original instances. If you do,
|
||||
* they aren't cleaned up properly on mode switch, causing crashes, e.g T58150. */
|
||||
* they aren't cleaned up properly on mode switch, causing crashes, e.g #58150. */
|
||||
BLI_assert(ob->id.tag & LIB_TAG_COPIED_ON_WRITE);
|
||||
|
||||
/* if there's no evaluated mesh or the last data mask used doesn't include
|
||||
|
@ -1757,7 +1757,7 @@ Mesh *mesh_get_eval_deform(struct Depsgraph *depsgraph,
|
|||
BLI_assert(DEG_is_evaluating(depsgraph) == false);
|
||||
|
||||
/* Evaluated meshes aren't supposed to be created on original instances. If you do,
|
||||
* they aren't cleaned up properly on mode switch, causing crashes, e.g T58150. */
|
||||
* they aren't cleaned up properly on mode switch, causing crashes, e.g #58150. */
|
||||
BLI_assert(ob->id.tag & LIB_TAG_COPIED_ON_WRITE);
|
||||
|
||||
/* if there's no derived mesh or the last data mask used doesn't include
|
||||
|
|
|
@ -1406,7 +1406,7 @@ void calc_action_range(const bAction *act, float *start, float *end, short incl_
|
|||
* - no "selected only", since this is often used in the backend
|
||||
* - no "minimum length" (we will apply this later), otherwise
|
||||
* single-keyframe curves will increase the overall length by
|
||||
* a phantom frame (T50354)
|
||||
* a phantom frame (#50354)
|
||||
*/
|
||||
BKE_fcurve_calc_range(fcu, &nmin, &nmax, false, false);
|
||||
|
||||
|
|
|
@ -1461,7 +1461,7 @@ void BKE_animdata_blend_read_data(BlendDataReader *reader, AnimData *adt)
|
|||
|
||||
/* relink active track/strip - even though strictly speaking this should only be used
|
||||
* if we're in 'tweaking mode', we need to be able to have this loaded back for
|
||||
* undo, but also since users may not exit tweak-mode before saving (T24535).
|
||||
* undo, but also since users may not exit tweak-mode before saving (#24535).
|
||||
*/
|
||||
/* TODO: it's not really nice that anyone should be able to save the file in this
|
||||
* state, but it's going to be too hard to enforce this single case. */
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue