WIP: Brush assets project #106303
|
@ -120,24 +120,24 @@ enable_testing()
|
|||
if(CMAKE_COMPILER_IS_GNUCC)
|
||||
if("${CMAKE_C_COMPILER_VERSION}" VERSION_LESS "11.0.0")
|
||||
message(FATAL_ERROR "\
|
||||
The minimum supported version of GCC is 11.0.0, found ${CMAKE_C_COMPILER_VERSION}"
|
||||
The minimum supported version of GCC is 11.0.0, found C compiler: ${CMAKE_C_COMPILER_VERSION}"
|
||||
)
|
||||
endif()
|
||||
if("${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS "11.0.0")
|
||||
message(FATAL_ERROR "\
|
||||
The minimum supported version of GCC is 11.0.0, found ${CMAKE_CXX_COMPILER_VERSION}"
|
||||
The minimum supported version of GCC is 11.0.0, found C++ compiler${CMAKE_CXX_COMPILER_VERSION}"
|
||||
)
|
||||
endif()
|
||||
elseif(CMAKE_C_COMPILER_ID MATCHES "Clang")
|
||||
if(CMAKE_COMPILER_IS_GNUCC)
|
||||
if("${CMAKE_C_COMPILER_VERSION}" VERSION_LESS "8.0")
|
||||
message(FATAL_ERROR "\
|
||||
The minimum supported version of CLANG is 8.0, found ${CMAKE_C_COMPILER_VERSION}"
|
||||
The minimum supported version of CLANG is 8.0, found C compiler ${CMAKE_C_COMPILER_VERSION}"
|
||||
)
|
||||
endif()
|
||||
if("${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS "8.0")
|
||||
message(FATAL_ERROR "\
|
||||
The minimum supported version of CLANG is 8.0, found ${CMAKE_CXX_COMPILER_VERSION}"
|
||||
The minimum supported version of CLANG is 8.0, found C++ compiler ${CMAKE_CXX_COMPILER_VERSION}"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
|
|
|
@ -21,3 +21,20 @@ diff -Naur orig/src/cmake/compiler.cmake external_openimageio/src/cmake/compiler
|
|||
endif (MSVC)
|
||||
|
||||
if (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD"
|
||||
diff --git a/src/libOpenImageIO/imageioplugin.cpp b/src/libOpenImageIO/imageioplugin.cpp
|
||||
index 9ad45042e..d2a0210ff 100644
|
||||
--- a/src/libOpenImageIO/imageioplugin.cpp
|
||||
+++ b/src/libOpenImageIO/imageioplugin.cpp
|
||||
@@ -469,12 +469,6 @@ pvt::catalog_all_plugins(std::string searchpath)
|
||||
|
||||
std::unique_lock<std::recursive_mutex> lock(imageio_mutex);
|
||||
append_if_env_exists(searchpath, "OIIO_LIBRARY_PATH", true);
|
||||
-#ifdef __APPLE__
|
||||
- append_if_env_exists(searchpath, "DYLD_LIBRARY_PATH");
|
||||
-#endif
|
||||
-#if defined(__linux__) || defined(__FreeBSD__)
|
||||
- append_if_env_exists(searchpath, "LD_LIBRARY_PATH");
|
||||
-#endif
|
||||
|
||||
size_t patlen = pattern.length();
|
||||
std::vector<std::string> dirs;
|
||||
|
|
|
@ -477,17 +477,17 @@ ccl_device
|
|||
|
||||
/* compute roughness */
|
||||
float anisotropy = clamp(param2, -0.99f, 0.99f);
|
||||
if (data_node.y == SVM_STACK_INVALID || fabsf(anisotropy) <= 1e-4f) {
|
||||
if (data_node.w == SVM_STACK_INVALID || fabsf(anisotropy) <= 1e-4f) {
|
||||
/* Isotropic case. */
|
||||
bsdf->T = zero_float3();
|
||||
bsdf->alpha_x = roughness;
|
||||
bsdf->alpha_y = roughness;
|
||||
}
|
||||
else {
|
||||
bsdf->T = stack_load_float3(stack, data_node.y);
|
||||
bsdf->T = stack_load_float3(stack, data_node.w);
|
||||
|
||||
/* rotate tangent */
|
||||
float rotation = stack_load_float(stack, data_node.z);
|
||||
float rotation = stack_load_float(stack, data_node.y);
|
||||
if (rotation != 0.0f) {
|
||||
bsdf->T = rotate_around_axis(bsdf->T, bsdf->N, rotation * M_2PI_F);
|
||||
}
|
||||
|
@ -512,8 +512,8 @@ ccl_device
|
|||
else {
|
||||
sd->flag |= bsdf_microfacet_ggx_setup(bsdf);
|
||||
if (type == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID) {
|
||||
kernel_assert(stack_valid(data_node.w));
|
||||
const Spectrum color = rgb_to_spectrum(stack_load_float3(stack, data_node.w));
|
||||
kernel_assert(stack_valid(data_node.z));
|
||||
const Spectrum color = rgb_to_spectrum(stack_load_float3(stack, data_node.z));
|
||||
bsdf_microfacet_setup_fresnel_constant(kg, bsdf, sd, color);
|
||||
}
|
||||
}
|
||||
|
@ -585,7 +585,7 @@ ccl_device
|
|||
fresnel->f0 = make_float3(F0_from_ior(ior));
|
||||
fresnel->f90 = one_spectrum();
|
||||
fresnel->exponent = -ior;
|
||||
const float3 color = stack_load_float3(stack, data_node.z);
|
||||
const float3 color = stack_load_float3(stack, data_node.y);
|
||||
fresnel->reflection_tint = reflective_caustics ? rgb_to_spectrum(color) : zero_spectrum();
|
||||
fresnel->transmission_tint = refractive_caustics ? rgb_to_spectrum(color) :
|
||||
zero_spectrum();
|
||||
|
@ -834,10 +834,10 @@ ccl_device
|
|||
bsdf->N = maybe_ensure_valid_specular_reflection(sd, N);
|
||||
bsdf->roughness1 = param1;
|
||||
bsdf->roughness2 = param2;
|
||||
bsdf->offset = -stack_load_float(stack, data_node.z);
|
||||
bsdf->offset = -stack_load_float(stack, data_node.y);
|
||||
|
||||
if (stack_valid(data_node.y)) {
|
||||
bsdf->T = normalize(stack_load_float3(stack, data_node.y));
|
||||
if (stack_valid(data_node.w)) {
|
||||
bsdf->T = normalize(stack_load_float3(stack, data_node.w));
|
||||
}
|
||||
else if (!(sd->type & PRIMITIVE_CURVE)) {
|
||||
bsdf->T = normalize(sd->dPdv);
|
||||
|
@ -866,12 +866,12 @@ ccl_device
|
|||
ccl_private Bssrdf *bssrdf = bssrdf_alloc(sd, weight);
|
||||
|
||||
if (bssrdf) {
|
||||
bssrdf->radius = rgb_to_spectrum(stack_load_float3(stack, data_node.z) * param1);
|
||||
bssrdf->radius = rgb_to_spectrum(stack_load_float3(stack, data_node.y) * param1);
|
||||
bssrdf->albedo = closure_weight;
|
||||
bssrdf->N = maybe_ensure_valid_specular_reflection(sd, N);
|
||||
bssrdf->ior = param2;
|
||||
bssrdf->alpha = 1.0f;
|
||||
bssrdf->anisotropy = stack_load_float(stack, data_node.w);
|
||||
bssrdf->anisotropy = stack_load_float(stack, data_node.z);
|
||||
|
||||
sd->flag |= bssrdf_setup(sd, bssrdf, path_flag, (ClosureType)type);
|
||||
}
|
||||
|
|
|
@ -2283,14 +2283,14 @@ bool BsdfBaseNode::has_bump()
|
|||
BsdfNode::BsdfNode(const NodeType *node_type) : BsdfBaseNode(node_type) {}
|
||||
|
||||
void BsdfNode::compile(SVMCompiler &compiler,
|
||||
ShaderInput *param1,
|
||||
ShaderInput *param2,
|
||||
ShaderInput *param3,
|
||||
ShaderInput *param4)
|
||||
ShaderInput *bsdf_y,
|
||||
ShaderInput *bsdf_z,
|
||||
ShaderInput *data_y,
|
||||
ShaderInput *data_z,
|
||||
ShaderInput *data_w)
|
||||
{
|
||||
ShaderInput *color_in = input("Color");
|
||||
ShaderInput *normal_in = input("Normal");
|
||||
ShaderInput *tangent_in = input("Tangent");
|
||||
|
||||
if (color_in->link) {
|
||||
compiler.add_node(NODE_CLOSURE_WEIGHT, compiler.stack_assign(color_in));
|
||||
|
@ -2300,21 +2300,20 @@ void BsdfNode::compile(SVMCompiler &compiler,
|
|||
}
|
||||
|
||||
int normal_offset = (normal_in) ? compiler.stack_assign_if_linked(normal_in) : SVM_STACK_INVALID;
|
||||
int tangent_offset = (tangent_in) ? compiler.stack_assign_if_linked(tangent_in) :
|
||||
SVM_STACK_INVALID;
|
||||
int param3_offset = (param3) ? compiler.stack_assign(param3) : SVM_STACK_INVALID;
|
||||
int param4_offset = (param4) ? compiler.stack_assign(param4) : SVM_STACK_INVALID;
|
||||
int data_y_offset = (data_y) ? compiler.stack_assign(data_y) : SVM_STACK_INVALID;
|
||||
int data_z_offset = (data_z) ? compiler.stack_assign(data_z) : SVM_STACK_INVALID;
|
||||
int data_w_offset = (data_w) ? compiler.stack_assign(data_w) : SVM_STACK_INVALID;
|
||||
|
||||
compiler.add_node(
|
||||
NODE_CLOSURE_BSDF,
|
||||
compiler.encode_uchar4(closure,
|
||||
(param1) ? compiler.stack_assign(param1) : SVM_STACK_INVALID,
|
||||
(param2) ? compiler.stack_assign(param2) : SVM_STACK_INVALID,
|
||||
(bsdf_y) ? compiler.stack_assign(bsdf_y) : SVM_STACK_INVALID,
|
||||
(bsdf_z) ? compiler.stack_assign(bsdf_z) : SVM_STACK_INVALID,
|
||||
compiler.closure_mix_weight_offset()),
|
||||
__float_as_int((param1) ? get_float(param1->socket_type) : 0.0f),
|
||||
__float_as_int((param2) ? get_float(param2->socket_type) : 0.0f));
|
||||
__float_as_int((bsdf_y) ? get_float(bsdf_y->socket_type) : 0.0f),
|
||||
__float_as_int((bsdf_z) ? get_float(bsdf_z->socket_type) : 0.0f));
|
||||
|
||||
compiler.add_node(normal_offset, tangent_offset, param3_offset, param4_offset);
|
||||
compiler.add_node(normal_offset, data_y_offset, data_z_offset, data_w_offset);
|
||||
}
|
||||
|
||||
void BsdfNode::compile(SVMCompiler &compiler)
|
||||
|
@ -2392,13 +2391,21 @@ void GlossyBsdfNode::compile(SVMCompiler &compiler)
|
|||
{
|
||||
closure = distribution;
|
||||
|
||||
ShaderInput *tangent = input("Tangent");
|
||||
tangent = compiler.is_linked(tangent) ? tangent : nullptr;
|
||||
|
||||
/* TODO: Just use weight for legacy MultiGGX? Would also simplify OSL. */
|
||||
if (closure == CLOSURE_BSDF_MICROFACET_MULTI_GGX_ID) {
|
||||
BsdfNode::compile(
|
||||
compiler, input("Roughness"), input("Anisotropy"), input("Rotation"), input("Color"));
|
||||
BsdfNode::compile(compiler,
|
||||
input("Roughness"),
|
||||
input("Anisotropy"),
|
||||
input("Rotation"),
|
||||
input("Color"),
|
||||
tangent);
|
||||
}
|
||||
else {
|
||||
BsdfNode::compile(compiler, input("Roughness"), input("Anisotropy"), input("Rotation"));
|
||||
BsdfNode::compile(
|
||||
compiler, input("Roughness"), input("Anisotropy"), input("Rotation"), nullptr, tangent);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3535,7 +3542,11 @@ void HairBsdfNode::compile(SVMCompiler &compiler)
|
|||
{
|
||||
closure = component;
|
||||
|
||||
BsdfNode::compile(compiler, input("RoughnessU"), input("RoughnessV"), input("Offset"));
|
||||
ShaderInput *tangent = input("Tangent");
|
||||
tangent = compiler.is_linked(tangent) ? tangent : nullptr;
|
||||
|
||||
BsdfNode::compile(
|
||||
compiler, input("RoughnessU"), input("RoughnessV"), input("Offset"), nullptr, tangent);
|
||||
}
|
||||
|
||||
void HairBsdfNode::compile(OSLCompiler &compiler)
|
||||
|
|
|
@ -479,10 +479,11 @@ class BsdfNode : public BsdfBaseNode {
|
|||
SHADER_NODE_BASE_CLASS(BsdfNode)
|
||||
|
||||
void compile(SVMCompiler &compiler,
|
||||
ShaderInput *param1,
|
||||
ShaderInput *param2,
|
||||
ShaderInput *param3 = NULL,
|
||||
ShaderInput *param4 = NULL);
|
||||
ShaderInput *bsdf_y,
|
||||
ShaderInput *bsdf_z,
|
||||
ShaderInput *data_y = nullptr,
|
||||
ShaderInput *data_z = nullptr,
|
||||
ShaderInput *data_w = nullptr);
|
||||
|
||||
NODE_SOCKET_API(float3, color)
|
||||
NODE_SOCKET_API(float3, normal)
|
||||
|
|
|
@ -294,9 +294,14 @@ int SVMCompiler::stack_assign(ShaderOutput *output)
|
|||
return output->stack_offset;
|
||||
}
|
||||
|
||||
bool SVMCompiler::is_linked(ShaderInput *input)
|
||||
{
|
||||
return (input->link || input->constant_folded_in);
|
||||
}
|
||||
|
||||
int SVMCompiler::stack_assign_if_linked(ShaderInput *input)
|
||||
{
|
||||
if (input->link || input->constant_folded_in) {
|
||||
if (is_linked(input)) {
|
||||
return stack_assign(input);
|
||||
}
|
||||
|
||||
|
|
|
@ -87,6 +87,7 @@ class SVMCompiler {
|
|||
|
||||
int stack_assign(ShaderOutput *output);
|
||||
int stack_assign(ShaderInput *input);
|
||||
bool is_linked(ShaderInput *input);
|
||||
int stack_assign_if_linked(ShaderInput *input);
|
||||
int stack_assign_if_linked(ShaderOutput *output);
|
||||
int stack_find_offset(int size);
|
||||
|
|
|
@ -123,6 +123,10 @@ typedef enum {
|
|||
* Supports IME text input methods (when `WITH_INPUT_IME` is defined).
|
||||
*/
|
||||
GHOST_kCapabilityInputIME = (1 << 6),
|
||||
/**
|
||||
* Support detecting the physical trackpad direction.
|
||||
*/
|
||||
GHOST_kCapabilityTrackpadPhysicalDirection = (1 << 7),
|
||||
} GHOST_TCapabilityFlag;
|
||||
|
||||
/**
|
||||
|
@ -132,7 +136,8 @@ typedef enum {
|
|||
#define GHOST_CAPABILITY_FLAG_ALL \
|
||||
(GHOST_kCapabilityCursorWarp | GHOST_kCapabilityWindowPosition | \
|
||||
GHOST_kCapabilityPrimaryClipboard | GHOST_kCapabilityGPUReadFrontBuffer | \
|
||||
GHOST_kCapabilityClipboardImages | GHOST_kCapabilityDesktopSample | GHOST_kCapabilityInputIME)
|
||||
GHOST_kCapabilityClipboardImages | GHOST_kCapabilityDesktopSample | \
|
||||
GHOST_kCapabilityInputIME | GHOST_kCapabilityTrackpadPhysicalDirection)
|
||||
|
||||
/* Xtilt and Ytilt represent how much the pen is tilted away from
|
||||
* vertically upright in either the X or Y direction, with X and Y the
|
||||
|
|
|
@ -108,6 +108,8 @@ static bool has_libdecor = true;
|
|||
# endif
|
||||
#endif
|
||||
|
||||
static signed char has_wl_trackpad_physical_direction = -1;
|
||||
|
||||
#include "IMB_imbuf.hh"
|
||||
#include "IMB_imbuf_types.hh"
|
||||
|
||||
|
@ -6410,6 +6412,8 @@ static void gwl_registry_wl_seat_add(GWL_Display *display, const GWL_RegisteryAd
|
|||
display->seats.push_back(seat);
|
||||
wl_seat_add_listener(seat->wl.seat, &seat_listener, seat);
|
||||
gwl_registry_entry_add(display, params, static_cast<void *>(seat));
|
||||
|
||||
has_wl_trackpad_physical_direction = version >= 9;
|
||||
}
|
||||
static void gwl_registry_wl_seat_update(GWL_Display *display,
|
||||
const GWL_RegisteryUpdate_Params ¶ms)
|
||||
|
@ -8367,6 +8371,9 @@ GHOST_TSuccess GHOST_SystemWayland::cursor_visibility_set(const bool visible)
|
|||
|
||||
GHOST_TCapabilityFlag GHOST_SystemWayland::getCapabilities() const
|
||||
{
|
||||
GHOST_ASSERT(has_wl_trackpad_physical_direction != -1,
|
||||
"The trackpad direction was expected to be initialized");
|
||||
|
||||
return GHOST_TCapabilityFlag(
|
||||
GHOST_CAPABILITY_FLAG_ALL &
|
||||
~(
|
||||
|
@ -8388,7 +8395,9 @@ GHOST_TCapabilityFlag GHOST_SystemWayland::getCapabilities() const
|
|||
* is negligible. */
|
||||
GHOST_kCapabilityGPUReadFrontBuffer |
|
||||
/* This WAYLAND back-end has not yet implemented desktop color sample. */
|
||||
GHOST_kCapabilityDesktopSample));
|
||||
GHOST_kCapabilityDesktopSample |
|
||||
/* This flag will eventually be removed. */
|
||||
(has_wl_trackpad_physical_direction ? 0 : GHOST_kCapabilityTrackpadPhysicalDirection)));
|
||||
}
|
||||
|
||||
bool GHOST_SystemWayland::cursor_grab_use_software_display_get(const GHOST_TGrabCursorMode mode)
|
||||
|
|
|
@ -7154,21 +7154,53 @@ def km_image_editor_tool_uv_rip_region(params):
|
|||
)
|
||||
|
||||
|
||||
def km_image_editor_tool_uv_sculpt_stroke(params):
|
||||
def km_image_editor_tool_uv_grab(params):
|
||||
return (
|
||||
"Image Editor Tool: Uv, Sculpt Stroke",
|
||||
"Image Editor Tool: Uv, Grab",
|
||||
{"space_type": 'IMAGE_EDITOR', "region_type": 'WINDOW'},
|
||||
{"items": [
|
||||
("sculpt.uv_sculpt_stroke", {"type": params.tool_mouse, "value": 'PRESS'}, None),
|
||||
("sculpt.uv_sculpt_stroke", {"type": params.tool_mouse, "value": 'PRESS', "ctrl": True},
|
||||
{"properties": [("mode", 'INVERT')]}),
|
||||
("sculpt.uv_sculpt_stroke", {"type": params.tool_mouse, "value": 'PRESS', "shift": True},
|
||||
{"properties": [("mode", 'RELAX')]}),
|
||||
("brush.scale_size", {"type": 'LEFT_BRACKET', "value": 'PRESS', "repeat": True},
|
||||
{"properties": [("scalar", 0.9)]}),
|
||||
("brush.scale_size", {"type": 'RIGHT_BRACKET', "value": 'PRESS', "repeat": True},
|
||||
{"properties": [("scalar", 1.0 / 0.9)]}),
|
||||
*_template_paint_radial_control("uv_sculpt"),
|
||||
("sculpt.uv_sculpt_grab", {"type": params.tool_mouse, "value": 'PRESS'}, None),
|
||||
("sculpt.uv_sculpt_grab", {"type": params.tool_mouse, "value": 'PRESS', "ctrl": True},
|
||||
{"properties": [("use_invert", True)]}),
|
||||
("sculpt.uv_sculpt_relax", {"type": params.tool_mouse, "value": 'PRESS', "shift": True}, None),
|
||||
("wm.radial_control", {"type": 'F', "value": 'PRESS'},
|
||||
{"properties": [("data_path_primary", "tool_settings.uv_sculpt.size"), ], }),
|
||||
("wm.radial_control", {"type": 'F', "value": 'PRESS', "shift": True},
|
||||
{"properties": [("data_path_primary", "tool_settings.uv_sculpt.strength"), ], }),
|
||||
]},
|
||||
)
|
||||
|
||||
|
||||
def km_image_editor_tool_uv_relax(params):
|
||||
return (
|
||||
"Image Editor Tool: Uv, Relax",
|
||||
{"space_type": 'IMAGE_EDITOR', "region_type": 'WINDOW'},
|
||||
{"items": [
|
||||
("sculpt.uv_sculpt_relax", {"type": params.tool_mouse, "value": 'PRESS'}, None),
|
||||
("sculpt.uv_sculpt_relax", {"type": params.tool_mouse, "value": 'PRESS', "ctrl": True},
|
||||
{"properties": [("use_invert", True)]}),
|
||||
("sculpt.uv_sculpt_relax", {"type": params.tool_mouse, "value": 'PRESS', "shift": True}, None),
|
||||
("wm.radial_control", {"type": 'F', "value": 'PRESS'},
|
||||
{"properties": [("data_path_primary", "tool_settings.uv_sculpt.size"), ], }),
|
||||
("wm.radial_control", {"type": 'F', "value": 'PRESS', "shift": True},
|
||||
{"properties": [("data_path_primary", "tool_settings.uv_sculpt.strength"), ], }),
|
||||
]},
|
||||
)
|
||||
|
||||
|
||||
def km_image_editor_tool_uv_pinch(params):
|
||||
return (
|
||||
"Image Editor Tool: Uv, Pinch",
|
||||
{"space_type": 'IMAGE_EDITOR', "region_type": 'WINDOW'},
|
||||
{"items": [
|
||||
("sculpt.uv_sculpt_pinch", {"type": params.tool_mouse, "value": 'PRESS'}, None),
|
||||
("sculpt.uv_sculpt_pinch", {"type": params.tool_mouse, "value": 'PRESS', "ctrl": True},
|
||||
{"properties": [("use_invert", True)]}),
|
||||
("sculpt.uv_sculpt_relax", {"type": params.tool_mouse, "value": 'PRESS', "shift": True}, None),
|
||||
("wm.radial_control", {"type": 'F', "value": 'PRESS'},
|
||||
{"properties": [("data_path_primary", "tool_settings.uv_sculpt.size"), ], }),
|
||||
("wm.radial_control", {"type": 'F', "value": 'PRESS', "shift": True},
|
||||
{"properties": [("data_path_primary", "tool_settings.uv_sculpt.strength"), ], }),
|
||||
]},
|
||||
)
|
||||
|
||||
|
@ -8930,7 +8962,9 @@ def generate_keymaps(params=None):
|
|||
*(km_image_editor_tool_uv_select_circle(params, fallback=fallback) for fallback in (False, True)),
|
||||
*(km_image_editor_tool_uv_select_lasso(params, fallback=fallback) for fallback in (False, True)),
|
||||
km_image_editor_tool_uv_rip_region(params),
|
||||
km_image_editor_tool_uv_sculpt_stroke(params),
|
||||
km_image_editor_tool_uv_grab(params),
|
||||
km_image_editor_tool_uv_relax(params),
|
||||
km_image_editor_tool_uv_pinch(params),
|
||||
km_image_editor_tool_uv_move(params),
|
||||
km_image_editor_tool_uv_rotate(params),
|
||||
km_image_editor_tool_uv_scale(params),
|
||||
|
|
|
@ -6,6 +6,7 @@ from __future__ import annotations
|
|||
|
||||
import bpy
|
||||
from bpy.types import (
|
||||
FileHandler,
|
||||
Operator,
|
||||
PropertyGroup,
|
||||
)
|
||||
|
@ -441,9 +442,27 @@ class NODE_OT_enum_definition_item_move(Operator):
|
|||
return {'FINISHED'}
|
||||
|
||||
|
||||
class NODE_FH_image_node(FileHandler):
|
||||
bl_idname = "NODE_FH_image_node"
|
||||
bl_label = "Image node"
|
||||
bl_import_operator = "node.add_file"
|
||||
bl_file_extensions = ";".join((*bpy.path.extensions_image, *bpy.path.extensions_movie))
|
||||
|
||||
@classmethod
|
||||
def poll_drop(cls, context):
|
||||
return (
|
||||
(context.area is not None) and
|
||||
(context.area.type == 'NODE_EDITOR') and
|
||||
(context.region is not None) and
|
||||
(context.region.type == 'WINDOW')
|
||||
)
|
||||
|
||||
|
||||
classes = (
|
||||
NodeSetting,
|
||||
|
||||
NODE_FH_image_node,
|
||||
|
||||
NODE_OT_add_node,
|
||||
NODE_OT_add_simulation_zone,
|
||||
NODE_OT_add_repeat_zone,
|
||||
|
|
|
@ -718,10 +718,6 @@ class IMAGE_HT_tool_header(Header):
|
|||
layout.popover("IMAGE_PT_tools_brush_display")
|
||||
layout.popover("IMAGE_PT_tools_brush_texture")
|
||||
layout.popover("IMAGE_PT_tools_mask_texture")
|
||||
elif tool_mode == 'UV':
|
||||
if (tool is not None) and tool.has_datablock:
|
||||
layout.popover("IMAGE_PT_uv_sculpt_curve")
|
||||
layout.popover("IMAGE_PT_uv_sculpt_options")
|
||||
|
||||
def draw_mode_settings(self, context):
|
||||
layout = self.layout
|
||||
|
@ -1348,50 +1344,21 @@ class IMAGE_PT_tools_imagepaint_symmetry(BrushButtonsPanel, Panel):
|
|||
row.prop(ipaint, "tile_y", text="Y", toggle=True)
|
||||
|
||||
|
||||
class UVSculptPanel(UnifiedPaintPanel):
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return cls.get_brush_mode(context) == 'UV_SCULPT'
|
||||
|
||||
|
||||
class IMAGE_PT_uv_sculpt_brush_select(Panel, BrushSelectPanel, ImagePaintPanel, UVSculptPanel):
|
||||
bl_context = ".uv_sculpt"
|
||||
bl_category = "Tool"
|
||||
bl_label = "Brushes"
|
||||
|
||||
|
||||
class IMAGE_PT_uv_sculpt_brush_settings(Panel, ImagePaintPanel, UVSculptPanel):
|
||||
bl_context = ".uv_sculpt"
|
||||
bl_category = "Tool"
|
||||
bl_label = "Brush Settings"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
tool_settings = context.tool_settings
|
||||
uvsculpt = tool_settings.uv_sculpt
|
||||
|
||||
brush = uvsculpt.brush
|
||||
|
||||
brush_settings(layout.column(), context, brush)
|
||||
|
||||
if brush:
|
||||
if brush.uv_sculpt_tool == 'RELAX':
|
||||
# Although this settings is stored in the scene,
|
||||
# it is only used by a single tool,
|
||||
# so it doesn't make sense from a user perspective to move it to the Options panel.
|
||||
layout.prop(tool_settings, "uv_relax_method")
|
||||
|
||||
|
||||
class IMAGE_PT_uv_sculpt_curve(Panel, FalloffPanel, ImagePaintPanel, UVSculptPanel):
|
||||
class IMAGE_PT_uv_sculpt_curve(Panel, ImagePaintPanel):
|
||||
bl_context = ".uv_sculpt" # Dot on purpose (access from top-bar).
|
||||
bl_parent_id = "IMAGE_PT_uv_sculpt_brush_settings"
|
||||
bl_category = "Tool"
|
||||
bl_label = "Falloff"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
props = context.scene.tool_settings.uv_sculpt
|
||||
layout.prop(props, "curve_preset", text="")
|
||||
if props.curve_preset == 'CUSTOM':
|
||||
layout.template_curve_mapping(props, "strength_curve")
|
||||
|
||||
class IMAGE_PT_uv_sculpt_options(Panel, ImagePaintPanel, UVSculptPanel):
|
||||
|
||||
class IMAGE_PT_uv_sculpt_options(Panel, ImagePaintPanel):
|
||||
bl_context = ".uv_sculpt" # Dot on purpose (access from top-bar).
|
||||
bl_category = "Tool"
|
||||
bl_label = "Options"
|
||||
|
@ -1400,12 +1367,10 @@ class IMAGE_PT_uv_sculpt_options(Panel, ImagePaintPanel, UVSculptPanel):
|
|||
layout = self.layout
|
||||
|
||||
tool_settings = context.tool_settings
|
||||
uvsculpt = tool_settings.uv_sculpt
|
||||
|
||||
col = layout.column()
|
||||
col.prop(tool_settings, "uv_sculpt_lock_borders")
|
||||
col.prop(tool_settings, "uv_sculpt_all_islands")
|
||||
col.prop(uvsculpt, "show_brush", text="Display Cursor")
|
||||
|
||||
|
||||
class ImageScopesPanel:
|
||||
|
@ -1789,8 +1754,6 @@ classes = (
|
|||
IMAGE_PT_paint_curve,
|
||||
IMAGE_PT_tools_brush_display,
|
||||
IMAGE_PT_tools_imagepaint_symmetry,
|
||||
IMAGE_PT_uv_sculpt_brush_select,
|
||||
IMAGE_PT_uv_sculpt_brush_settings,
|
||||
IMAGE_PT_uv_sculpt_options,
|
||||
IMAGE_PT_uv_sculpt_curve,
|
||||
IMAGE_PT_view_histogram,
|
||||
|
|
|
@ -2207,36 +2207,82 @@ class _defs_image_uv_edit:
|
|||
|
||||
class _defs_image_uv_sculpt:
|
||||
|
||||
@staticmethod
|
||||
def generate_from_brushes(context):
|
||||
def draw_cursor(context, _tool, xy):
|
||||
@ToolDef.from_fn
|
||||
def grab():
|
||||
def draw_settings(context, layout, tool):
|
||||
uv_sculpt = context.scene.tool_settings.uv_sculpt
|
||||
layout.prop(uv_sculpt, "size")
|
||||
layout.prop(uv_sculpt, "strength")
|
||||
layout.popover("IMAGE_PT_uv_sculpt_curve")
|
||||
layout.popover("IMAGE_PT_uv_sculpt_options")
|
||||
|
||||
def draw_cursor(context, tool, xy):
|
||||
from gpu_extras.presets import draw_circle_2d
|
||||
tool_settings = context.tool_settings
|
||||
uv_sculpt = tool_settings.uv_sculpt
|
||||
if not uv_sculpt.show_brush:
|
||||
return
|
||||
ups = tool_settings.unified_paint_settings
|
||||
if ups.use_unified_size:
|
||||
radius = ups.size
|
||||
else:
|
||||
brush = tool_settings.uv_sculpt.brush
|
||||
if brush is None:
|
||||
return
|
||||
radius = brush.size
|
||||
uv_sculpt = context.scene.tool_settings.uv_sculpt
|
||||
radius = uv_sculpt.size
|
||||
draw_circle_2d(xy, (1.0,) * 4, radius)
|
||||
|
||||
return generate_from_enum_ex(
|
||||
context,
|
||||
idname_prefix="builtin_brush.",
|
||||
icon_prefix="brush.uv_sculpt.",
|
||||
type=bpy.types.Brush,
|
||||
attr="uv_sculpt_tool",
|
||||
tooldef_keywords=dict(
|
||||
operator="sculpt.uv_sculpt_stroke",
|
||||
keymap="Image Editor Tool: Uv, Sculpt Stroke",
|
||||
draw_cursor=draw_cursor,
|
||||
options={'KEYMAP_FALLBACK'},
|
||||
),
|
||||
return dict(
|
||||
idname="sculpt.uv_sculpt_grab",
|
||||
label="Grab",
|
||||
icon="brush.uv_sculpt.grab",
|
||||
keymap=(),
|
||||
draw_cursor=draw_cursor,
|
||||
draw_settings=draw_settings,
|
||||
options={'KEYMAP_FALLBACK'},
|
||||
)
|
||||
|
||||
@ToolDef.from_fn
|
||||
def relax():
|
||||
def draw_settings(context, layout, tool):
|
||||
uv_sculpt = context.scene.tool_settings.uv_sculpt
|
||||
layout.prop(uv_sculpt, "size")
|
||||
layout.prop(uv_sculpt, "strength")
|
||||
layout.popover("IMAGE_PT_uv_sculpt_curve")
|
||||
layout.popover("IMAGE_PT_uv_sculpt_options")
|
||||
|
||||
props = tool.operator_properties("sculpt.uv_sculpt_relax")
|
||||
layout.prop(props, "relax_method", text="Method")
|
||||
|
||||
def draw_cursor(context, tool, xy):
|
||||
from gpu_extras.presets import draw_circle_2d
|
||||
uv_sculpt = context.scene.tool_settings.uv_sculpt
|
||||
radius = uv_sculpt.size
|
||||
draw_circle_2d(xy, (1.0,) * 4, radius)
|
||||
|
||||
return dict(
|
||||
idname="sculpt.uv_sculpt_relax",
|
||||
label="Relax",
|
||||
icon="brush.uv_sculpt.relax",
|
||||
keymap=(),
|
||||
draw_cursor=draw_cursor,
|
||||
draw_settings=draw_settings,
|
||||
options={'KEYMAP_FALLBACK'},
|
||||
)
|
||||
|
||||
@ToolDef.from_fn
|
||||
def pinch():
|
||||
def draw_settings(context, layout, tool):
|
||||
uv_sculpt = context.scene.tool_settings.uv_sculpt
|
||||
layout.prop(uv_sculpt, "size")
|
||||
layout.prop(uv_sculpt, "strength")
|
||||
layout.popover("IMAGE_PT_uv_sculpt_curve")
|
||||
layout.popover("IMAGE_PT_uv_sculpt_options")
|
||||
|
||||
def draw_cursor(context, tool, xy):
|
||||
from gpu_extras.presets import draw_circle_2d
|
||||
uv_sculpt = context.scene.tool_settings.uv_sculpt
|
||||
radius = uv_sculpt.size
|
||||
draw_circle_2d(xy, (1.0,) * 4, radius)
|
||||
|
||||
return dict(
|
||||
idname="sculpt.uv_sculpt_pinch",
|
||||
label="Pinch",
|
||||
icon="brush.uv_sculpt.pinch",
|
||||
keymap=(),
|
||||
draw_cursor=draw_cursor,
|
||||
draw_settings=draw_settings,
|
||||
options={'KEYMAP_FALLBACK'},
|
||||
)
|
||||
|
||||
|
||||
|
@ -3078,11 +3124,9 @@ class IMAGE_PT_tools_active(ToolSelectPanelHelper, Panel):
|
|||
None,
|
||||
_defs_image_uv_edit.rip_region,
|
||||
None,
|
||||
lambda context: (
|
||||
_defs_image_uv_sculpt.generate_from_brushes(context)
|
||||
if _defs_image_generic.poll_uvedit(context)
|
||||
else ()
|
||||
),
|
||||
_defs_image_uv_sculpt.grab,
|
||||
_defs_image_uv_sculpt.relax,
|
||||
_defs_image_uv_sculpt.pinch,
|
||||
],
|
||||
'MASK': [
|
||||
None,
|
||||
|
|
|
@ -1795,6 +1795,13 @@ class USERPREF_PT_input_touchpad(InputPanel, CenterAlignMixIn, Panel):
|
|||
col = layout.column()
|
||||
col.prop(inputs, "use_multitouch_gestures")
|
||||
|
||||
from _bpy import _wm_capabilities
|
||||
capabilities = _wm_capabilities()
|
||||
if not capabilities['TRACKPAD_PHYSICAL_DIRECTION']:
|
||||
row = col.row()
|
||||
row.active = inputs.use_multitouch_gestures
|
||||
row.prop(inputs, "touchpad_scroll_direction", text="Scroll Direction")
|
||||
|
||||
|
||||
class USERPREF_PT_input_tablet(InputPanel, CenterAlignMixIn, Panel):
|
||||
bl_label = "Tablet"
|
||||
|
|
|
@ -155,6 +155,14 @@ int clear_keyframe(Main *bmain,
|
|||
int array_index,
|
||||
eInsertKeyFlags /*flag*/);
|
||||
|
||||
/** Check if a flag is set for keyframing (per scene takes precedence). */
|
||||
bool is_keying_flag(const Scene *scene, eKeying_Flag flag);
|
||||
|
||||
/**
|
||||
* Get the settings for key-framing from the given scene.
|
||||
*/
|
||||
eInsertKeyFlags get_keyframing_flags(Scene *scene);
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
@ -173,9 +181,6 @@ bool is_autokey_on(const Scene *scene);
|
|||
/** Check the mode for auto-keyframing (per scene takes precedence). */
|
||||
bool is_autokey_mode(const Scene *scene, eAutokey_Mode mode);
|
||||
|
||||
/** Check if a flag is set for keyframing (per scene takes precedence). */
|
||||
bool is_keying_flag(const Scene *scene, eKeying_Flag flag);
|
||||
|
||||
/**
|
||||
* Auto-keyframing feature - checks for whether anything should be done for the current frame.
|
||||
*/
|
||||
|
|
|
@ -208,6 +208,27 @@ bool is_keying_flag(const Scene *scene, const eKeying_Flag flag)
|
|||
return U.keying_flag & flag;
|
||||
}
|
||||
|
||||
eInsertKeyFlags get_keyframing_flags(Scene *scene)
|
||||
{
|
||||
eInsertKeyFlags flag = INSERTKEY_NOFLAGS;
|
||||
|
||||
/* Visual keying. */
|
||||
if (is_keying_flag(scene, KEYING_FLAG_VISUALKEY)) {
|
||||
flag |= INSERTKEY_MATRIX;
|
||||
}
|
||||
|
||||
/* Cycle-aware keyframe insertion - preserve cycle period and flow. */
|
||||
if (is_keying_flag(scene, KEYING_FLAG_CYCLEAWARE)) {
|
||||
flag |= INSERTKEY_CYCLE_AWARE;
|
||||
}
|
||||
|
||||
if (is_keying_flag(scene, MANUALKEY_FLAG_INSERTNEEDED)) {
|
||||
flag |= INSERTKEY_NEEDED;
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
/** Used to make curves newly added to a cyclic Action cycle with the correct period. */
|
||||
static void make_new_fcurve_cyclic(FCurve *fcu, const blender::float2 &action_range)
|
||||
{
|
||||
|
|
|
@ -29,7 +29,7 @@ extern "C" {
|
|||
|
||||
/* Blender file format version. */
|
||||
#define BLENDER_FILE_VERSION BLENDER_VERSION
|
||||
#define BLENDER_FILE_SUBVERSION 23
|
||||
#define BLENDER_FILE_SUBVERSION 24
|
||||
|
||||
/* Minimum Blender version that supports reading file written with the current
|
||||
* version. Older Blender versions will test this and cancel loading the file, showing a warning to
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
* General operations for brushes.
|
||||
*/
|
||||
|
||||
#include "DNA_brush_enums.h"
|
||||
#include "DNA_color_types.h"
|
||||
#include "DNA_object_enums.h"
|
||||
|
||||
|
@ -93,6 +94,10 @@ float BKE_brush_curve_strength_clamped(const Brush *br, float p, float len);
|
|||
/**
|
||||
* Uses the brush curve control to find a strength value.
|
||||
*/
|
||||
float BKE_brush_curve_strength(eBrushCurvePreset preset,
|
||||
const CurveMapping *cumap,
|
||||
float distance,
|
||||
float brush_radius);
|
||||
float BKE_brush_curve_strength(const Brush *br, float p, float len);
|
||||
|
||||
/* Sampling. */
|
||||
|
|
|
@ -35,6 +35,16 @@ namespace blender::bke {
|
|||
|
||||
namespace greasepencil {
|
||||
|
||||
/* Previously, Grease Pencil used a radius convention where 1 `px` = 0.001 units. This `px`
|
||||
* was the brush size which would be stored in the stroke thickness and then scaled by the
|
||||
* point pressure factor. Finally, the render engine would divide this thickness value by
|
||||
* 2000 (we're going from a thickness to a radius, hence the factor of two) to convert back
|
||||
* into blender units. With Grease Pencil 3, the radius is no longer stored in `px` space,
|
||||
* but in blender units (world space) directly. Also note that there is no longer a stroke
|
||||
* "thickness" attribute, the radii are directly stored on the points.
|
||||
* For compatibility, legacy thickness values have to be multiplied by this factor. */
|
||||
constexpr float LEGACY_RADIUS_CONVERSION_FACTOR = 1.0f / 2000.0f;
|
||||
|
||||
class DrawingRuntime {
|
||||
public:
|
||||
/**
|
||||
|
|
|
@ -99,7 +99,6 @@ enum class PaintMode : int8_t {
|
|||
Texture3D = 3,
|
||||
/** Image space (2D painting). */
|
||||
Texture2D = 4,
|
||||
SculptUV = 5,
|
||||
GPencil = 6,
|
||||
/* Grease Pencil Vertex Paint */
|
||||
VertexGPencil = 7,
|
||||
|
@ -114,8 +113,6 @@ enum class PaintMode : int8_t {
|
|||
Invalid = 12,
|
||||
};
|
||||
|
||||
#define PAINT_MODE_HAS_BRUSH(mode) !ELEM(mode, PaintMode::SculptUV)
|
||||
|
||||
/* overlay invalidation */
|
||||
enum ePaintOverlayControlFlags {
|
||||
PAINT_OVERLAY_INVALID_TEXTURE_PRIMARY = 1,
|
||||
|
|
|
@ -2546,20 +2546,24 @@ void BKE_brush_randomize_texture_coords(UnifiedPaintSettings *ups, bool mask)
|
|||
}
|
||||
}
|
||||
|
||||
float BKE_brush_curve_strength(const Brush *br, float p, const float len)
|
||||
float BKE_brush_curve_strength(const eBrushCurvePreset preset,
|
||||
const CurveMapping *cumap,
|
||||
const float distance,
|
||||
const float brush_radius)
|
||||
{
|
||||
float p = distance;
|
||||
float strength = 1.0f;
|
||||
|
||||
if (p >= len) {
|
||||
if (p >= brush_radius) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
p = p / len;
|
||||
p = p / brush_radius;
|
||||
p = 1.0f - p;
|
||||
|
||||
switch (br->curve_preset) {
|
||||
switch (preset) {
|
||||
case BRUSH_CURVE_CUSTOM:
|
||||
strength = BKE_curvemapping_evaluateF(br->curve, 0, 1.0f - p);
|
||||
strength = BKE_curvemapping_evaluateF(cumap, 0, 1.0f - p);
|
||||
break;
|
||||
case BRUSH_CURVE_SHARP:
|
||||
strength = p * p;
|
||||
|
@ -2593,6 +2597,11 @@ float BKE_brush_curve_strength(const Brush *br, float p, const float len)
|
|||
return strength;
|
||||
}
|
||||
|
||||
float BKE_brush_curve_strength(const Brush *br, float p, const float len)
|
||||
{
|
||||
return BKE_brush_curve_strength(eBrushCurvePreset(br->curve_preset), br->curve, p, len);
|
||||
}
|
||||
|
||||
float BKE_brush_curve_strength_clamped(const Brush *br, float p, const float len)
|
||||
{
|
||||
float strength = BKE_brush_curve_strength(br, p, len);
|
||||
|
|
|
@ -813,13 +813,7 @@ static void legacy_gpencil_frame_to_grease_pencil_drawing(const bGPDframe &gpf,
|
|||
BLI_assert(points.size() == gps->totpoints);
|
||||
|
||||
const Span<bGPDspoint> src_points{gps->points, gps->totpoints};
|
||||
/* Previously, Grease Pencil used a radius convention where 1 `px` = 0.001 units. This `px`
|
||||
* was the brush size which would be stored in the stroke thickness and then scaled by the
|
||||
* point pressure factor. Finally, the render engine would divide this thickness value by
|
||||
* 2000 (we're going from a thickness to a radius, hence the factor of two) to convert back
|
||||
* into blender units. Store the radius now directly in blender units. This makes it
|
||||
* consistent with how hair curves handle the radius. */
|
||||
const float stroke_thickness = float(gps->thickness) / 2000.0f;
|
||||
const float stroke_thickness = float(gps->thickness) * LEGACY_RADIUS_CONVERSION_FACTOR;
|
||||
MutableSpan<float3> dst_positions = positions.slice(points);
|
||||
MutableSpan<float3> dst_handle_positions_left = has_bezier_stroke ?
|
||||
handle_positions_left.slice(points) :
|
||||
|
@ -1213,6 +1207,61 @@ static void thickness_factor_to_modifier(ConversionData &conversion_data,
|
|||
animdata_thickness_transfer.fcurves_convert_finalize();
|
||||
}
|
||||
|
||||
static void fcurve_convert_thickness_cb(FCurve &fcurve)
|
||||
{
|
||||
if (fcurve.bezt) {
|
||||
for (uint i = 0; i < fcurve.totvert; i++) {
|
||||
BezTriple &bezier_triple = fcurve.bezt[i];
|
||||
bezier_triple.vec[0][1] *= LEGACY_RADIUS_CONVERSION_FACTOR;
|
||||
bezier_triple.vec[1][1] *= LEGACY_RADIUS_CONVERSION_FACTOR;
|
||||
bezier_triple.vec[2][1] *= LEGACY_RADIUS_CONVERSION_FACTOR;
|
||||
}
|
||||
}
|
||||
if (fcurve.fpt) {
|
||||
for (uint i = 0; i < fcurve.totvert; i++) {
|
||||
FPoint &fpoint = fcurve.fpt[i];
|
||||
fpoint.vec[1] *= LEGACY_RADIUS_CONVERSION_FACTOR;
|
||||
}
|
||||
}
|
||||
fcurve.flag &= ~FCURVE_INT_VALUES;
|
||||
BKE_fcurve_handles_recalc(&fcurve);
|
||||
}
|
||||
|
||||
static void legacy_object_thickness_modifier_thickness_anim(ConversionData &conversion_data,
|
||||
Object &object)
|
||||
{
|
||||
if (BKE_animdata_from_id(&object.id) == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Note: At this point, the animation was already transferred to the destination object. Now we
|
||||
* just need to convert the fcurve data to be in the right space. */
|
||||
AnimDataConvertor animdata_convert_thickness(
|
||||
conversion_data,
|
||||
object.id,
|
||||
object.id,
|
||||
{{".thickness", ".thickness", fcurve_convert_thickness_cb}});
|
||||
|
||||
LISTBASE_FOREACH (ModifierData *, tmd, &object.modifiers) {
|
||||
if (ModifierType(tmd->type) != eModifierType_GreasePencilThickness) {
|
||||
continue;
|
||||
}
|
||||
|
||||
char modifier_name[MAX_NAME * 2];
|
||||
BLI_str_escape(modifier_name, tmd->name, sizeof(modifier_name));
|
||||
animdata_convert_thickness.root_path_src = fmt::format("modifiers[\"{}\"]", modifier_name);
|
||||
animdata_convert_thickness.root_path_dst = fmt::format("modifiers[\"{}\"]", modifier_name);
|
||||
|
||||
if (!animdata_convert_thickness.source_has_animation_to_convert()) {
|
||||
continue;
|
||||
}
|
||||
animdata_convert_thickness.fcurves_convert();
|
||||
}
|
||||
|
||||
animdata_convert_thickness.fcurves_convert_finalize();
|
||||
DEG_relations_tag_update(&conversion_data.bmain);
|
||||
}
|
||||
|
||||
static void layer_adjustments_to_modifiers(ConversionData &conversion_data,
|
||||
bGPdata &src_object_data,
|
||||
Object &dst_object)
|
||||
|
@ -1225,26 +1274,6 @@ static void layer_adjustments_to_modifiers(ConversionData &conversion_data,
|
|||
src_object_data.id,
|
||||
{{".tint_color", ".color"}, {".tint_factor", ".factor"}});
|
||||
|
||||
/* Ensure values are divided by 2k, to match conversion done for non-animated value. */
|
||||
constexpr float thickness_adjustement_factor = 1.0f / 2000.0f;
|
||||
auto fcurve_convert_thickness_cb = [&](FCurve &fcurve) {
|
||||
if (fcurve.bezt) {
|
||||
for (uint i = 0; i < fcurve.totvert; i++) {
|
||||
BezTriple &bezier_triple = fcurve.bezt[i];
|
||||
bezier_triple.vec[0][1] *= thickness_adjustement_factor;
|
||||
bezier_triple.vec[1][1] *= thickness_adjustement_factor;
|
||||
bezier_triple.vec[2][1] *= thickness_adjustement_factor;
|
||||
}
|
||||
}
|
||||
if (fcurve.fpt) {
|
||||
for (uint i = 0; i < fcurve.totvert; i++) {
|
||||
FPoint &fpoint = fcurve.fpt[i];
|
||||
fpoint.vec[1] *= thickness_adjustement_factor;
|
||||
}
|
||||
}
|
||||
fcurve.flag &= ~FCURVE_INT_VALUES;
|
||||
BKE_fcurve_handles_recalc(&fcurve);
|
||||
};
|
||||
AnimDataConvertor animdata_thickness_transfer(
|
||||
conversion_data,
|
||||
dst_object.id,
|
||||
|
@ -1301,7 +1330,7 @@ static void layer_adjustments_to_modifiers(ConversionData &conversion_data,
|
|||
/* Convert the "pixel" offset value into a radius value.
|
||||
* GPv2 used a conversion of 1 "px" = 0.001. */
|
||||
/* Note: this offset may be negative. */
|
||||
const float radius_offset = float(thickness_px) * thickness_adjustement_factor;
|
||||
const float radius_offset = float(thickness_px) * LEGACY_RADIUS_CONVERSION_FACTOR;
|
||||
|
||||
const auto offset_radius_ntree_ensure = [&](Library *owner_library) {
|
||||
if (bNodeTree **ntree = conversion_data.offset_radius_ntree_by_library.lookup_ptr(
|
||||
|
@ -2252,7 +2281,7 @@ static void legacy_object_modifier_thickness(ConversionData &conversion_data,
|
|||
md_thickness.flag |= MOD_GREASE_PENCIL_THICK_WEIGHT_FACTOR;
|
||||
}
|
||||
md_thickness.thickness_fac = legacy_md_thickness.thickness_fac;
|
||||
md_thickness.thickness = legacy_md_thickness.thickness;
|
||||
md_thickness.thickness = legacy_md_thickness.thickness * LEGACY_RADIUS_CONVERSION_FACTOR;
|
||||
|
||||
legacy_object_modifier_influence(md_thickness.influence,
|
||||
legacy_md_thickness.layername,
|
||||
|
@ -2914,6 +2943,8 @@ static void legacy_gpencil_object_ex(ConversionData &conversion_data, Object &ob
|
|||
}
|
||||
|
||||
legacy_object_modifiers(conversion_data, object);
|
||||
/* Convert the animation of the "uniform thickness" setting of the thickness modifier. */
|
||||
legacy_object_thickness_modifier_thickness_anim(conversion_data, object);
|
||||
|
||||
/* Layer adjustments should be added after all other modifiers. */
|
||||
layer_adjustments_to_modifiers(conversion_data, *gpd, object);
|
||||
|
@ -2975,95 +3006,87 @@ void legacy_main(Main &bmain, BlendFileReadReport & /*reports*/)
|
|||
void lineart_wrap_v3(const LineartGpencilModifierData *lmd_legacy,
|
||||
GreasePencilLineartModifierData *lmd)
|
||||
{
|
||||
#define LMD_WRAP(var) lmd->var = lmd_legacy->var
|
||||
|
||||
LMD_WRAP(edge_types);
|
||||
LMD_WRAP(source_type);
|
||||
LMD_WRAP(use_multiple_levels);
|
||||
LMD_WRAP(level_start);
|
||||
LMD_WRAP(level_end);
|
||||
LMD_WRAP(source_camera);
|
||||
LMD_WRAP(light_contour_object);
|
||||
LMD_WRAP(source_object);
|
||||
LMD_WRAP(source_collection);
|
||||
LMD_WRAP(target_material);
|
||||
lmd->edge_types = lmd_legacy->edge_types;
|
||||
lmd->source_type = lmd_legacy->source_type;
|
||||
lmd->use_multiple_levels = lmd_legacy->use_multiple_levels;
|
||||
lmd->level_start = lmd_legacy->level_start;
|
||||
lmd->level_end = lmd_legacy->level_end;
|
||||
lmd->source_camera = lmd_legacy->source_camera;
|
||||
lmd->light_contour_object = lmd_legacy->light_contour_object;
|
||||
lmd->source_object = lmd_legacy->source_object;
|
||||
lmd->source_collection = lmd_legacy->source_collection;
|
||||
lmd->target_material = lmd_legacy->target_material;
|
||||
STRNCPY(lmd->source_vertex_group, lmd_legacy->source_vertex_group);
|
||||
STRNCPY(lmd->vgname, lmd_legacy->vgname);
|
||||
LMD_WRAP(overscan);
|
||||
LMD_WRAP(shadow_camera_fov);
|
||||
LMD_WRAP(shadow_camera_size);
|
||||
LMD_WRAP(shadow_camera_near);
|
||||
LMD_WRAP(shadow_camera_far);
|
||||
LMD_WRAP(opacity);
|
||||
lmd->overscan = lmd_legacy->overscan;
|
||||
lmd->shadow_camera_fov = lmd_legacy->shadow_camera_fov;
|
||||
lmd->shadow_camera_size = lmd_legacy->shadow_camera_size;
|
||||
lmd->shadow_camera_near = lmd_legacy->shadow_camera_near;
|
||||
lmd->shadow_camera_far = lmd_legacy->shadow_camera_far;
|
||||
lmd->opacity = lmd_legacy->opacity;
|
||||
lmd->thickness = lmd_legacy->thickness / 2;
|
||||
LMD_WRAP(mask_switches);
|
||||
LMD_WRAP(material_mask_bits);
|
||||
LMD_WRAP(intersection_mask);
|
||||
LMD_WRAP(shadow_selection);
|
||||
LMD_WRAP(silhouette_selection);
|
||||
LMD_WRAP(crease_threshold);
|
||||
LMD_WRAP(angle_splitting_threshold);
|
||||
LMD_WRAP(chain_smooth_tolerance);
|
||||
LMD_WRAP(chaining_image_threshold);
|
||||
LMD_WRAP(calculation_flags);
|
||||
LMD_WRAP(flags);
|
||||
LMD_WRAP(stroke_depth_offset);
|
||||
LMD_WRAP(level_start_override);
|
||||
LMD_WRAP(level_end_override);
|
||||
LMD_WRAP(edge_types_override);
|
||||
LMD_WRAP(shadow_selection_override);
|
||||
LMD_WRAP(shadow_use_silhouette_override);
|
||||
LMD_WRAP(cache);
|
||||
LMD_WRAP(la_data_ptr);
|
||||
|
||||
#undef LMD_WRAP
|
||||
lmd->mask_switches = lmd_legacy->mask_switches;
|
||||
lmd->material_mask_bits = lmd_legacy->material_mask_bits;
|
||||
lmd->intersection_mask = lmd_legacy->intersection_mask;
|
||||
lmd->shadow_selection = lmd_legacy->shadow_selection;
|
||||
lmd->silhouette_selection = lmd_legacy->silhouette_selection;
|
||||
lmd->crease_threshold = lmd_legacy->crease_threshold;
|
||||
lmd->angle_splitting_threshold = lmd_legacy->angle_splitting_threshold;
|
||||
lmd->chain_smooth_tolerance = lmd_legacy->chain_smooth_tolerance;
|
||||
lmd->chaining_image_threshold = lmd_legacy->chaining_image_threshold;
|
||||
lmd->calculation_flags = lmd_legacy->calculation_flags;
|
||||
lmd->flags = lmd_legacy->flags;
|
||||
lmd->stroke_depth_offset = lmd_legacy->stroke_depth_offset;
|
||||
lmd->level_start_override = lmd_legacy->level_start_override;
|
||||
lmd->level_end_override = lmd_legacy->level_end_override;
|
||||
lmd->edge_types_override = lmd_legacy->edge_types_override;
|
||||
lmd->shadow_selection_override = lmd_legacy->shadow_selection_override;
|
||||
lmd->shadow_use_silhouette_override = lmd_legacy->shadow_use_silhouette_override;
|
||||
lmd->cache = lmd_legacy->cache;
|
||||
lmd->la_data_ptr = lmd_legacy->la_data_ptr;
|
||||
}
|
||||
|
||||
void lineart_unwrap_v3(LineartGpencilModifierData *lmd_legacy,
|
||||
const GreasePencilLineartModifierData *lmd)
|
||||
{
|
||||
#define LMD_UNWRAP(var) lmd_legacy->var = lmd->var
|
||||
|
||||
LMD_UNWRAP(edge_types);
|
||||
LMD_UNWRAP(source_type);
|
||||
LMD_UNWRAP(use_multiple_levels);
|
||||
LMD_UNWRAP(level_start);
|
||||
LMD_UNWRAP(level_end);
|
||||
LMD_UNWRAP(source_camera);
|
||||
LMD_UNWRAP(light_contour_object);
|
||||
LMD_UNWRAP(source_object);
|
||||
LMD_UNWRAP(source_collection);
|
||||
LMD_UNWRAP(target_material);
|
||||
lmd_legacy->edge_types = lmd->edge_types;
|
||||
lmd_legacy->source_type = lmd->source_type;
|
||||
lmd_legacy->use_multiple_levels = lmd->use_multiple_levels;
|
||||
lmd_legacy->level_start = lmd->level_start;
|
||||
lmd_legacy->level_end = lmd->level_end;
|
||||
lmd_legacy->source_camera = lmd->source_camera;
|
||||
lmd_legacy->light_contour_object = lmd->light_contour_object;
|
||||
lmd_legacy->source_object = lmd->source_object;
|
||||
lmd_legacy->source_collection = lmd->source_collection;
|
||||
lmd_legacy->target_material = lmd->target_material;
|
||||
STRNCPY(lmd_legacy->source_vertex_group, lmd->source_vertex_group);
|
||||
STRNCPY(lmd_legacy->vgname, lmd->vgname);
|
||||
LMD_UNWRAP(overscan);
|
||||
LMD_UNWRAP(shadow_camera_fov);
|
||||
LMD_UNWRAP(shadow_camera_size);
|
||||
LMD_UNWRAP(shadow_camera_near);
|
||||
LMD_UNWRAP(shadow_camera_far);
|
||||
LMD_UNWRAP(opacity);
|
||||
lmd_legacy->overscan = lmd->overscan;
|
||||
lmd_legacy->shadow_camera_fov = lmd->shadow_camera_fov;
|
||||
lmd_legacy->shadow_camera_size = lmd->shadow_camera_size;
|
||||
lmd_legacy->shadow_camera_near = lmd->shadow_camera_near;
|
||||
lmd_legacy->shadow_camera_far = lmd->shadow_camera_far;
|
||||
lmd_legacy->opacity = lmd->opacity;
|
||||
lmd_legacy->thickness = lmd->thickness * 2;
|
||||
LMD_UNWRAP(mask_switches);
|
||||
LMD_UNWRAP(material_mask_bits);
|
||||
LMD_UNWRAP(intersection_mask);
|
||||
LMD_UNWRAP(shadow_selection);
|
||||
LMD_UNWRAP(silhouette_selection);
|
||||
LMD_UNWRAP(crease_threshold);
|
||||
LMD_UNWRAP(angle_splitting_threshold);
|
||||
LMD_UNWRAP(chain_smooth_tolerance);
|
||||
LMD_UNWRAP(chaining_image_threshold);
|
||||
LMD_UNWRAP(calculation_flags);
|
||||
LMD_UNWRAP(flags);
|
||||
LMD_UNWRAP(stroke_depth_offset);
|
||||
LMD_UNWRAP(level_start_override);
|
||||
LMD_UNWRAP(level_end_override);
|
||||
LMD_UNWRAP(edge_types_override);
|
||||
LMD_UNWRAP(shadow_selection_override);
|
||||
LMD_UNWRAP(shadow_use_silhouette_override);
|
||||
LMD_UNWRAP(cache);
|
||||
LMD_UNWRAP(la_data_ptr);
|
||||
|
||||
#undef LMD_UNWRAP
|
||||
lmd_legacy->mask_switches = lmd->mask_switches;
|
||||
lmd_legacy->material_mask_bits = lmd->material_mask_bits;
|
||||
lmd_legacy->intersection_mask = lmd->intersection_mask;
|
||||
lmd_legacy->shadow_selection = lmd->shadow_selection;
|
||||
lmd_legacy->silhouette_selection = lmd->silhouette_selection;
|
||||
lmd_legacy->crease_threshold = lmd->crease_threshold;
|
||||
lmd_legacy->angle_splitting_threshold = lmd->angle_splitting_threshold;
|
||||
lmd_legacy->chain_smooth_tolerance = lmd->chain_smooth_tolerance;
|
||||
lmd_legacy->chaining_image_threshold = lmd->chaining_image_threshold;
|
||||
lmd_legacy->calculation_flags = lmd->calculation_flags;
|
||||
lmd_legacy->flags = lmd->flags;
|
||||
lmd_legacy->stroke_depth_offset = lmd->stroke_depth_offset;
|
||||
lmd_legacy->level_start_override = lmd->level_start_override;
|
||||
lmd_legacy->level_end_override = lmd->level_end_override;
|
||||
lmd_legacy->edge_types_override = lmd->edge_types_override;
|
||||
lmd_legacy->shadow_selection_override = lmd->shadow_selection_override;
|
||||
lmd_legacy->shadow_use_silhouette_override = lmd->shadow_use_silhouette_override;
|
||||
lmd_legacy->cache = lmd->cache;
|
||||
lmd_legacy->la_data_ptr = lmd->la_data_ptr;
|
||||
}
|
||||
|
||||
} // namespace blender::bke::greasepencil::convert
|
||||
|
|
|
@ -350,9 +350,6 @@ bool BKE_paint_ensure_from_paintmode(Main *bmain, Scene *sce, PaintMode mode)
|
|||
paint_tmp = (Paint *)&ts->imapaint;
|
||||
paint_ptr = &paint_tmp;
|
||||
break;
|
||||
case PaintMode::SculptUV:
|
||||
paint_ptr = (Paint **)&ts->uvsculpt;
|
||||
break;
|
||||
case PaintMode::GPencil:
|
||||
paint_ptr = (Paint **)&ts->gp_paint;
|
||||
break;
|
||||
|
@ -396,8 +393,6 @@ Paint *BKE_paint_get_active_from_paintmode(Scene *sce, PaintMode mode)
|
|||
case PaintMode::Texture2D:
|
||||
case PaintMode::Texture3D:
|
||||
return &ts->imapaint.paint;
|
||||
case PaintMode::SculptUV:
|
||||
return &ts->uvsculpt->paint;
|
||||
case PaintMode::GPencil:
|
||||
return &ts->gp_paint->paint;
|
||||
case PaintMode::VertexGPencil:
|
||||
|
@ -432,8 +427,6 @@ const EnumPropertyItem *BKE_paint_get_tool_enum_from_paintmode(const PaintMode m
|
|||
case PaintMode::Texture2D:
|
||||
case PaintMode::Texture3D:
|
||||
return rna_enum_brush_image_tool_items;
|
||||
case PaintMode::SculptUV:
|
||||
return rna_enum_brush_uv_sculpt_tool_items;
|
||||
case PaintMode::GPencil:
|
||||
return rna_enum_brush_gpencil_types_items;
|
||||
case PaintMode::VertexGPencil:
|
||||
|
@ -479,8 +472,6 @@ Paint *BKE_paint_get_active(Scene *sce, ViewLayer *view_layer)
|
|||
return &ts->gp_weightpaint->paint;
|
||||
case OB_MODE_SCULPT_CURVES:
|
||||
return &ts->curves_sculpt->paint;
|
||||
case OB_MODE_EDIT:
|
||||
return ts->uvsculpt ? &ts->uvsculpt->paint : nullptr;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -509,9 +500,6 @@ Paint *BKE_paint_get_active_from_context(const bContext *C)
|
|||
if (sima->mode == SI_MODE_PAINT) {
|
||||
return &ts->imapaint.paint;
|
||||
}
|
||||
if (sima->mode == SI_MODE_UV) {
|
||||
return &ts->uvsculpt->paint;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return &ts->imapaint.paint;
|
||||
|
@ -540,9 +528,6 @@ PaintMode BKE_paintmode_get_active_from_context(const bContext *C)
|
|||
if (sima->mode == SI_MODE_PAINT) {
|
||||
return PaintMode::Texture2D;
|
||||
}
|
||||
if (sima->mode == SI_MODE_UV) {
|
||||
return PaintMode::SculptUV;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return PaintMode::Texture2D;
|
||||
|
@ -570,8 +555,6 @@ PaintMode BKE_paintmode_get_active_from_context(const bContext *C)
|
|||
return PaintMode::Weight;
|
||||
case OB_MODE_TEXTURE_PAINT:
|
||||
return PaintMode::Texture3D;
|
||||
case OB_MODE_EDIT:
|
||||
return PaintMode::SculptUV;
|
||||
case OB_MODE_SCULPT_CURVES:
|
||||
return PaintMode::SculptCurves;
|
||||
default:
|
||||
|
@ -620,8 +603,6 @@ PaintMode BKE_paintmode_get_from_tool(const bToolRef *tref)
|
|||
switch (tref->mode) {
|
||||
case SI_MODE_PAINT:
|
||||
return PaintMode::Texture2D;
|
||||
case SI_MODE_UV:
|
||||
return PaintMode::SculptUV;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -779,9 +760,6 @@ void BKE_paint_brush_set_default_references(ToolSettings *ts)
|
|||
if (ts->vpaint) {
|
||||
paint_brush_set_default_reference(&ts->vpaint->paint);
|
||||
}
|
||||
if (ts->uvsculpt) {
|
||||
paint_brush_set_default_reference(&ts->uvsculpt->paint);
|
||||
}
|
||||
if (ts->gp_paint) {
|
||||
paint_brush_set_default_reference(&ts->gp_paint->paint);
|
||||
}
|
||||
|
@ -834,9 +812,6 @@ static void paint_runtime_init(const ToolSettings *ts, Paint *paint)
|
|||
else if (ts->wpaint && paint == &ts->wpaint->paint) {
|
||||
paint->runtime.ob_mode = OB_MODE_WEIGHT_PAINT;
|
||||
}
|
||||
else if (ts->uvsculpt && paint == &ts->uvsculpt->paint) {
|
||||
paint->runtime.ob_mode = OB_MODE_EDIT;
|
||||
}
|
||||
else if (ts->gp_paint && paint == &ts->gp_paint->paint) {
|
||||
paint->runtime.ob_mode = OB_MODE_PAINT_GPENCIL_LEGACY;
|
||||
}
|
||||
|
@ -871,8 +846,6 @@ uint BKE_paint_get_brush_tool_offset_from_paintmode(const PaintMode mode)
|
|||
return offsetof(Brush, vertexpaint_tool);
|
||||
case PaintMode::Weight:
|
||||
return offsetof(Brush, weightpaint_tool);
|
||||
case PaintMode::SculptUV:
|
||||
return offsetof(Brush, uv_sculpt_tool);
|
||||
case PaintMode::GPencil:
|
||||
return offsetof(Brush, gpencil_tool);
|
||||
case PaintMode::VertexGPencil:
|
||||
|
@ -1213,8 +1186,6 @@ eObjectMode BKE_paint_object_mode_from_paintmode(const PaintMode mode)
|
|||
case PaintMode::Texture2D:
|
||||
case PaintMode::Texture3D:
|
||||
return OB_MODE_TEXTURE_PAINT;
|
||||
case PaintMode::SculptUV:
|
||||
return OB_MODE_EDIT;
|
||||
case PaintMode::SculptCurves:
|
||||
return OB_MODE_SCULPT_CURVES;
|
||||
case PaintMode::GPencil:
|
||||
|
@ -1247,7 +1218,6 @@ bool BKE_paint_ensure(Main *bmain, ToolSettings *ts, Paint **r_paint)
|
|||
(Paint *)ts->sculpt,
|
||||
(Paint *)ts->vpaint,
|
||||
(Paint *)ts->wpaint,
|
||||
(Paint *)ts->uvsculpt,
|
||||
(Paint *)ts->curves_sculpt,
|
||||
(Paint *)&ts->imapaint));
|
||||
#ifndef NDEBUG
|
||||
|
@ -1289,10 +1259,6 @@ bool BKE_paint_ensure(Main *bmain, ToolSettings *ts, Paint **r_paint)
|
|||
GpWeightPaint *data = MEM_cnew<GpWeightPaint>(__func__);
|
||||
paint = &data->paint;
|
||||
}
|
||||
else if ((UvSculpt **)r_paint == &ts->uvsculpt) {
|
||||
UvSculpt *data = MEM_cnew<UvSculpt>(__func__);
|
||||
paint = &data->paint;
|
||||
}
|
||||
else if ((CurvesSculpt **)r_paint == &ts->curves_sculpt) {
|
||||
CurvesSculpt *data = MEM_cnew<CurvesSculpt>(__func__);
|
||||
paint = &data->paint;
|
||||
|
|
|
@ -705,14 +705,6 @@ static void scene_foreach_toolsettings(LibraryForeachIDData *data,
|
|||
}
|
||||
toolsett_old->sculpt->gravity_object = gravity_object_old;
|
||||
}
|
||||
if (toolsett_old->uvsculpt) {
|
||||
paint = toolsett->uvsculpt ? &toolsett->uvsculpt->paint : nullptr;
|
||||
paint_old = &toolsett_old->uvsculpt->paint;
|
||||
BKE_LIB_FOREACHID_UNDO_PRESERVE_PROCESS_FUNCTION_CALL(
|
||||
data,
|
||||
do_undo_restore,
|
||||
scene_foreach_paint(data, paint, do_undo_restore, reader, paint_old));
|
||||
}
|
||||
if (toolsett_old->gp_paint) {
|
||||
paint = toolsett->gp_paint ? &toolsett->gp_paint->paint : nullptr;
|
||||
paint_old = &toolsett_old->gp_paint->paint;
|
||||
|
@ -1038,9 +1030,8 @@ static void scene_blend_write(BlendWriter *writer, ID *id, const void *id_addres
|
|||
|
||||
BKE_paint_blend_write(writer, &tos->sculpt->paint);
|
||||
}
|
||||
if (tos->uvsculpt) {
|
||||
BLO_write_struct(writer, UvSculpt, tos->uvsculpt);
|
||||
BKE_paint_blend_write(writer, &tos->uvsculpt->paint);
|
||||
if (tos->uvsculpt.strength_curve) {
|
||||
BKE_curvemapping_blend_write(writer, tos->uvsculpt.strength_curve);
|
||||
}
|
||||
if (tos->gp_paint) {
|
||||
BLO_write_struct(writer, GpPaint, tos->gp_paint);
|
||||
|
@ -1242,7 +1233,6 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id)
|
|||
direct_link_paint_helper(reader, sce, (Paint **)&sce->toolsettings->sculpt);
|
||||
direct_link_paint_helper(reader, sce, (Paint **)&sce->toolsettings->vpaint);
|
||||
direct_link_paint_helper(reader, sce, (Paint **)&sce->toolsettings->wpaint);
|
||||
direct_link_paint_helper(reader, sce, (Paint **)&sce->toolsettings->uvsculpt);
|
||||
direct_link_paint_helper(reader, sce, (Paint **)&sce->toolsettings->gp_paint);
|
||||
direct_link_paint_helper(reader, sce, (Paint **)&sce->toolsettings->gp_vertexpaint);
|
||||
direct_link_paint_helper(reader, sce, (Paint **)&sce->toolsettings->gp_sculptpaint);
|
||||
|
@ -1255,6 +1245,11 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id)
|
|||
sce->toolsettings->particle.scene = nullptr;
|
||||
sce->toolsettings->particle.object = nullptr;
|
||||
sce->toolsettings->gp_sculpt.paintcursor = nullptr;
|
||||
if (sce->toolsettings->uvsculpt.strength_curve) {
|
||||
BLO_read_struct(reader, CurveMapping, &sce->toolsettings->uvsculpt.strength_curve);
|
||||
BKE_curvemapping_blend_read(reader, sce->toolsettings->uvsculpt.strength_curve);
|
||||
BKE_curvemapping_init(sce->toolsettings->uvsculpt.strength_curve);
|
||||
}
|
||||
|
||||
if (sce->toolsettings->sculpt) {
|
||||
BLO_read_struct(reader, CurveMapping, &sce->toolsettings->sculpt->automasking_cavity_curve);
|
||||
|
@ -1654,9 +1649,9 @@ ToolSettings *BKE_toolsettings_copy(ToolSettings *toolsettings, const int flag)
|
|||
BKE_curvemapping_init(ts->sculpt->automasking_cavity_curve_op);
|
||||
}
|
||||
}
|
||||
if (ts->uvsculpt) {
|
||||
ts->uvsculpt = static_cast<UvSculpt *>(MEM_dupallocN(ts->uvsculpt));
|
||||
BKE_paint_copy(&ts->uvsculpt->paint, &ts->uvsculpt->paint, flag);
|
||||
if (ts->uvsculpt.strength_curve) {
|
||||
ts->uvsculpt.strength_curve = BKE_curvemapping_copy(ts->uvsculpt.strength_curve);
|
||||
BKE_curvemapping_init(ts->uvsculpt.strength_curve);
|
||||
}
|
||||
if (ts->gp_paint) {
|
||||
ts->gp_paint = static_cast<GpPaint *>(MEM_dupallocN(ts->gp_paint));
|
||||
|
@ -1720,9 +1715,8 @@ void BKE_toolsettings_free(ToolSettings *toolsettings)
|
|||
BKE_paint_free(&toolsettings->sculpt->paint);
|
||||
MEM_freeN(toolsettings->sculpt);
|
||||
}
|
||||
if (toolsettings->uvsculpt) {
|
||||
BKE_paint_free(&toolsettings->uvsculpt->paint);
|
||||
MEM_freeN(toolsettings->uvsculpt);
|
||||
if (toolsettings->uvsculpt.strength_curve) {
|
||||
BKE_curvemapping_free(toolsettings->uvsculpt.strength_curve);
|
||||
}
|
||||
if (toolsettings->gp_paint) {
|
||||
BKE_paint_free(&toolsettings->gp_paint->paint);
|
||||
|
|
|
@ -797,9 +797,6 @@ static void do_version_curvemapping_walker(Main *bmain, void (*callback)(CurveMa
|
|||
if (ts->sculpt) {
|
||||
callback(ts->sculpt->paint.cavity_curve);
|
||||
}
|
||||
if (ts->uvsculpt) {
|
||||
callback(ts->uvsculpt->paint.cavity_curve);
|
||||
}
|
||||
if (ts->gp_paint) {
|
||||
callback(ts->gp_paint->paint.cavity_curve);
|
||||
}
|
||||
|
|
|
@ -3491,12 +3491,6 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain)
|
|||
}
|
||||
|
||||
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 302, 6)) {
|
||||
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
|
||||
ToolSettings *ts = scene->toolsettings;
|
||||
if (ts->uv_relax_method == 0) {
|
||||
ts->uv_relax_method = UV_SCULPT_TOOL_RELAX_LAPLACIAN;
|
||||
}
|
||||
}
|
||||
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
|
||||
ToolSettings *tool_settings = scene->toolsettings;
|
||||
tool_settings->snap_flag_seq = tool_settings->snap_flag &
|
||||
|
|
|
@ -1966,13 +1966,6 @@ static void versioning_nodes_dynamic_sockets_2(bNodeTree &ntree)
|
|||
static void versioning_grease_pencil_stroke_radii_scaling(GreasePencil *grease_pencil)
|
||||
{
|
||||
using namespace blender;
|
||||
/* Previously, Grease Pencil used a radius convention where 1 `px` = 0.001 units. This `px` was
|
||||
* the brush size which would be stored in the stroke thickness and then scaled by the point
|
||||
* pressure factor. Finally, the render engine would divide this thickness value by 2000 (we're
|
||||
* going from a thickness to a radius, hence the factor of two) to convert back into blender
|
||||
* units.
|
||||
* Store the radius now directly in blender units. This makes it consistent with how hair curves
|
||||
* handle the radius. */
|
||||
for (GreasePencilDrawingBase *base : grease_pencil->drawings()) {
|
||||
if (base->type != GP_DRAWING) {
|
||||
continue;
|
||||
|
@ -1981,7 +1974,7 @@ static void versioning_grease_pencil_stroke_radii_scaling(GreasePencil *grease_p
|
|||
MutableSpan<float> radii = drawing.radii_for_write();
|
||||
threading::parallel_for(radii.index_range(), 8192, [&](const IndexRange range) {
|
||||
for (const int i : range) {
|
||||
radii[i] /= 2000.0f;
|
||||
radii[i] *= bke::greasepencil::LEGACY_RADIUS_CONVERSION_FACTOR;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -2983,9 +2976,6 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain)
|
|||
input_sample_values[2] = ts->curves_sculpt != nullptr ?
|
||||
ts->curves_sculpt->paint.num_input_samples_deprecated :
|
||||
1;
|
||||
input_sample_values[3] = ts->uvsculpt != nullptr ?
|
||||
ts->uvsculpt->paint.num_input_samples_deprecated :
|
||||
1;
|
||||
|
||||
input_sample_values[4] = ts->gp_paint != nullptr ?
|
||||
ts->gp_paint->paint.num_input_samples_deprecated :
|
||||
|
@ -3265,6 +3255,18 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain)
|
|||
}
|
||||
|
||||
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 23)) {
|
||||
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
|
||||
ToolSettings *ts = scene->toolsettings;
|
||||
if (!ts->uvsculpt.strength_curve) {
|
||||
ts->uvsculpt.size = 50;
|
||||
ts->uvsculpt.strength = 1.0f;
|
||||
ts->uvsculpt.curve_preset = BRUSH_CURVE_SMOOTH;
|
||||
ts->uvsculpt.strength_curve = BKE_curvemapping_add(1, 0.0f, 0.0f, 1.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 402, 24)) {
|
||||
update_paint_modes_for_brush_assets(*bmain);
|
||||
}
|
||||
|
||||
|
|
|
@ -59,15 +59,17 @@ void Light::sync(ShadowModule &shadows, const Object *ob, float threshold)
|
|||
this->color = float3(&la->r) * la->energy;
|
||||
|
||||
float3 scale;
|
||||
this->object_mat = ob->object_to_world();
|
||||
this->object_mat.view<3, 3>() = normalize_and_get_size(this->object_mat.view<3, 3>(), scale);
|
||||
float4x4 object_to_world = ob->object_to_world();
|
||||
object_to_world.view<3, 3>() = normalize_and_get_size(object_to_world.view<3, 3>(), scale);
|
||||
|
||||
/* Make sure we have consistent handedness (in case of negatively scaled Z axis). */
|
||||
float3 back = cross(float3(this->_right), float3(this->_up));
|
||||
if (dot(back, float3(this->_back)) < 0.0f) {
|
||||
negate_v3(this->_up);
|
||||
float3 back = cross(float3(object_to_world.x_axis()), float3(object_to_world.y_axis()));
|
||||
if (dot(back, float3(object_to_world.z_axis())) < 0.0f) {
|
||||
negate_v3(object_to_world.y_axis());
|
||||
}
|
||||
|
||||
this->object_to_world = object_to_world;
|
||||
|
||||
shape_parameters_set(la, scale, threshold);
|
||||
|
||||
const bool diffuse_visibility = (ob->visibility_flag & OB_HIDE_DIFFUSE) == 0;
|
||||
|
@ -93,7 +95,7 @@ void Light::sync(ShadowModule &shadows, const Object *ob, float threshold)
|
|||
if (la->mode & LA_SHADOW) {
|
||||
shadow_ensure(shadows);
|
||||
if (is_sun_light(this->type)) {
|
||||
this->directional->sync(this->object_mat,
|
||||
this->directional->sync(object_to_world,
|
||||
1.0f,
|
||||
la->sun_angle * la->shadow_softness_factor,
|
||||
la->shadow_trace_distance);
|
||||
|
@ -113,7 +115,7 @@ void Light::sync(ShadowModule &shadows, const Object *ob, float threshold)
|
|||
shadow_radius = la->shadow_softness_factor * la->radius;
|
||||
}
|
||||
this->punctual->sync(this->type,
|
||||
this->object_mat,
|
||||
object_to_world,
|
||||
la->spotsize,
|
||||
radius,
|
||||
this->local.influence_radius_max,
|
||||
|
@ -293,7 +295,9 @@ float Light::point_radiance_get()
|
|||
void Light::debug_draw()
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
drw_debug_sphere(float3(_position), local.influence_radius_max, float4(0.8f, 0.3f, 0.0f, 1.0f));
|
||||
drw_debug_sphere(transform_location(this->object_to_world),
|
||||
local.influence_radius_max,
|
||||
float4(0.8f, 0.3f, 0.0f, 1.0f));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -43,6 +43,80 @@ constexpr GPUSamplerState with_filter = {GPU_SAMPLER_FILTERING_LINEAR};
|
|||
|
||||
#define UBO_MIN_MAX_SUPPORTED_SIZE 1 << 14
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Transform
|
||||
* \{ */
|
||||
|
||||
struct Transform {
|
||||
/* The transform is stored transposed for compactness. */
|
||||
float4 x, y, z;
|
||||
#if IS_CPP
|
||||
Transform() = default;
|
||||
Transform(const float4x4 &tx)
|
||||
: x(tx[0][0], tx[1][0], tx[2][0], tx[3][0]),
|
||||
y(tx[0][1], tx[1][1], tx[2][1], tx[3][1]),
|
||||
z(tx[0][2], tx[1][2], tx[2][2], tx[3][2])
|
||||
{
|
||||
}
|
||||
|
||||
operator float4x4() const
|
||||
{
|
||||
return float4x4(float4(x.x, y.x, z.x, 0.0f),
|
||||
float4(x.y, y.y, z.y, 0.0f),
|
||||
float4(x.z, y.z, z.z, 0.0f),
|
||||
float4(x.w, y.w, z.w, 1.0f));
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
static inline float3 transform_x_axis(Transform t)
|
||||
{
|
||||
return float3(t.x.x, t.y.x, t.z.x);
|
||||
}
|
||||
static inline float3 transform_y_axis(Transform t)
|
||||
{
|
||||
return float3(t.x.y, t.y.y, t.z.y);
|
||||
}
|
||||
static inline float3 transform_z_axis(Transform t)
|
||||
{
|
||||
return float3(t.x.z, t.y.z, t.z.z);
|
||||
}
|
||||
static inline float3 transform_location(Transform t)
|
||||
{
|
||||
return float3(t.x.w, t.y.w, t.z.w);
|
||||
}
|
||||
|
||||
static inline float3 transform_point(Transform t, float3 point)
|
||||
{
|
||||
return float4(point, 1.0f) * float3x4(t.x, t.y, t.z);
|
||||
}
|
||||
|
||||
static inline float3 transform_direction(Transform t, float3 direction)
|
||||
{
|
||||
return direction * float3x3(float3(t.x.x, t.x.y, t.x.z),
|
||||
float3(t.y.x, t.y.y, t.y.z),
|
||||
float3(t.z.x, t.z.y, t.z.z));
|
||||
}
|
||||
|
||||
static inline float3 transform_direction_transposed(Transform t, float3 direction)
|
||||
{
|
||||
return float3x3(float3(t.x.x, t.x.y, t.x.z),
|
||||
float3(t.y.x, t.y.y, t.y.z),
|
||||
float3(t.z.x, t.z.y, t.z.z)) *
|
||||
direction;
|
||||
}
|
||||
|
||||
/* Assumes the transform has unit scale. */
|
||||
static inline float3 transform_point_inversed(Transform t, float3 point)
|
||||
{
|
||||
return float3x3(float3(t.x.x, t.x.y, t.x.z),
|
||||
float3(t.y.x, t.y.y, t.y.z),
|
||||
float3(t.z.x, t.z.y, t.z.z)) *
|
||||
(point - transform_location(t));
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Debug Mode
|
||||
* \{ */
|
||||
|
@ -870,21 +944,8 @@ BLI_STATIC_ASSERT(sizeof(LightSunData) == sizeof(LightLocalData), "Data size mus
|
|||
#endif
|
||||
|
||||
struct LightData {
|
||||
/** Normalized object to world matrix. */
|
||||
/* TODO(fclem): Use float4x3. */
|
||||
float4x4 object_mat;
|
||||
/** Aliases for axes. */
|
||||
#ifndef USE_GPU_SHADER_CREATE_INFO
|
||||
# define _right object_mat[0]
|
||||
# define _up object_mat[1]
|
||||
# define _back object_mat[2]
|
||||
# define _position object_mat[3]
|
||||
#else
|
||||
# define _right object_mat[0].xyz
|
||||
# define _up object_mat[1].xyz
|
||||
# define _back object_mat[2].xyz
|
||||
# define _position object_mat[3].xyz
|
||||
#endif
|
||||
/** Normalized object to world matrix. Stored transposed for compactness. */
|
||||
Transform object_to_world;
|
||||
|
||||
/** Power depending on shader type. Referenced by LightingType. */
|
||||
float4 power;
|
||||
|
@ -922,6 +983,23 @@ struct LightData {
|
|||
};
|
||||
BLI_STATIC_ASSERT_ALIGN(LightData, 16)
|
||||
|
||||
static inline float3 light_x_axis(LightData light)
|
||||
{
|
||||
return transform_x_axis(light.object_to_world);
|
||||
}
|
||||
static inline float3 light_y_axis(LightData light)
|
||||
{
|
||||
return transform_y_axis(light.object_to_world);
|
||||
}
|
||||
static inline float3 light_z_axis(LightData light)
|
||||
{
|
||||
return transform_z_axis(light.object_to_world);
|
||||
}
|
||||
static inline float3 light_position_get(LightData light)
|
||||
{
|
||||
return transform_location(light.object_to_world);
|
||||
}
|
||||
|
||||
#ifdef GPU_SHADER
|
||||
# define CHECK_TYPE_PAIR(a, b)
|
||||
# define CHECK_TYPE(a, b)
|
||||
|
|
|
@ -370,11 +370,7 @@ void ShadowPunctual::end_sync(Light &light, float lod_bias)
|
|||
compute_projection_boundaries(
|
||||
light.type, light_radius_, shadow_radius_, max_distance_, near, far, side, shift);
|
||||
|
||||
float4x4 obmat_tmp = light.object_mat;
|
||||
|
||||
/* Clear embedded custom data. */
|
||||
obmat_tmp[0][3] = obmat_tmp[1][3] = obmat_tmp[2][3] = 0.0f;
|
||||
obmat_tmp[3][3] = 1.0f;
|
||||
float4x4 obmat_tmp = light.object_to_world;
|
||||
|
||||
/* Acquire missing tile-maps. */
|
||||
while (tilemaps_.size() < tilemaps_needed_) {
|
||||
|
@ -519,7 +515,9 @@ void ShadowDirectional::cascade_tilemaps_distribution(Light &light, const Camera
|
|||
float2 farthest_tilemap_center = local_view_direction * half_size * (levels_range.size() - 1);
|
||||
|
||||
/* Offset for smooth level transitions. */
|
||||
light.object_mat.location() = near_point;
|
||||
light.object_to_world.x.w = near_point.x;
|
||||
light.object_to_world.y.w = near_point.y;
|
||||
light.object_to_world.z.w = near_point.z;
|
||||
|
||||
/* Offset in tiles from the scene origin to the center of the first tile-maps. */
|
||||
int2 origin_offset = int2(round(float2(near_point) / tile_size));
|
||||
|
@ -637,7 +635,10 @@ void ShadowDirectional::clipmap_tilemaps_distribution(Light &light,
|
|||
light.type = LIGHT_SUN;
|
||||
|
||||
/* Used for selecting the clipmap level. */
|
||||
light.object_mat.location() = camera.position() * float3x3(object_mat_.view<3, 3>());
|
||||
float3 location = camera.position() * float3x3(object_mat_.view<3, 3>());
|
||||
light.object_to_world.x.w = location.x;
|
||||
light.object_to_world.y.w = location.y;
|
||||
light.object_to_world.z.w = location.z;
|
||||
/* Used as origin for the clipmap_base_offset trick. */
|
||||
light.sun.clipmap_origin = float2(level_offset_max * tile_size_max);
|
||||
|
||||
|
|
|
@ -117,10 +117,8 @@ void SyncModule::sync_mesh(Object *ob,
|
|||
return;
|
||||
}
|
||||
|
||||
if ((ob->dt < OB_SOLID) && !DRW_state_is_scene_render()) {
|
||||
/** NOTE:
|
||||
* EEVEE doesn't render meshes with bounds or wire display type in the viewport,
|
||||
* but Cycles does. */
|
||||
if ((ob->dt < OB_SOLID) && ((inst_.is_viewport() && inst_.v3d->shading.type != OB_RENDER))) {
|
||||
/** Do not render objects with display type lower than solid when in material preview mode. */
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -38,11 +38,14 @@ void main()
|
|||
LightSpotData spot = light_spot_data_get(light);
|
||||
/* Only for < ~170 degree Cone due to plane extraction precision. */
|
||||
if (spot.spot_tan < 10.0) {
|
||||
vec3 x_axis = light_x_axis(light);
|
||||
vec3 y_axis = light_y_axis(light);
|
||||
vec3 z_axis = light_z_axis(light);
|
||||
Pyramid pyramid = shape_pyramid_non_oblique(
|
||||
light._position,
|
||||
light._position - light._back * spot.influence_radius_max,
|
||||
light._right * spot.influence_radius_max * spot.spot_tan / spot.spot_size_inv.x,
|
||||
light._up * spot.influence_radius_max * spot.spot_tan / spot.spot_size_inv.y);
|
||||
light_position_get(light),
|
||||
light_position_get(light) - z_axis * spot.influence_radius_max,
|
||||
x_axis * spot.influence_radius_max * spot.spot_tan / spot.spot_size_inv.x,
|
||||
y_axis * spot.influence_radius_max * spot.spot_tan / spot.spot_size_inv.y);
|
||||
if (!intersect_view(pyramid)) {
|
||||
return;
|
||||
}
|
||||
|
@ -52,7 +55,7 @@ void main()
|
|||
case LIGHT_ELLIPSE:
|
||||
case LIGHT_OMNI_SPHERE:
|
||||
case LIGHT_OMNI_DISK:
|
||||
sphere.center = light._position;
|
||||
sphere.center = light_position_get(light);
|
||||
sphere.radius = light_local_data_get(light).influence_radius_max;
|
||||
break;
|
||||
default:
|
||||
|
@ -66,7 +69,7 @@ void main()
|
|||
if (intersect_view(sphere)) {
|
||||
uint index = atomicAdd(light_cull_buf.visible_count, 1u);
|
||||
|
||||
float z_dist = dot(drw_view_forward(), light._position) -
|
||||
float z_dist = dot(drw_view_forward(), light_position_get(light)) -
|
||||
dot(drw_view_forward(), drw_view_position());
|
||||
out_zdist_buf[index] = z_dist;
|
||||
out_key_buf[index] = l_idx;
|
||||
|
|
|
@ -148,10 +148,10 @@ void main()
|
|||
LightData light = light_buf[l_idx];
|
||||
|
||||
/* Culling in view space for precision and simplicity. */
|
||||
vec3 vP = drw_point_world_to_view(light._position);
|
||||
vec3 v_right = drw_normal_world_to_view(light._right);
|
||||
vec3 v_up = drw_normal_world_to_view(light._up);
|
||||
vec3 v_back = drw_normal_world_to_view(light._back);
|
||||
vec3 vP = drw_point_world_to_view(light_position_get(light));
|
||||
vec3 v_right = drw_normal_world_to_view(light_x_axis(light));
|
||||
vec3 v_up = drw_normal_world_to_view(light_y_axis(light));
|
||||
vec3 v_back = drw_normal_world_to_view(light_z_axis(light));
|
||||
float radius = light_local_data_get(light).influence_radius_max;
|
||||
|
||||
Sphere sphere = shape_sphere(vP, radius);
|
||||
|
|
|
@ -36,7 +36,7 @@ void main()
|
|||
continue;
|
||||
}
|
||||
LightData light = light_buf[index];
|
||||
vec3 P = light._position;
|
||||
vec3 P = light_position_get(light);
|
||||
/* TODO(fclem): Could have better bounds for spot and area lights. */
|
||||
float radius = light_local_data_get(light).influence_radius_max;
|
||||
float z_dist = dot(drw_view_forward(), P) - dot(drw_view_forward(), drw_view_position());
|
||||
|
|
|
@ -24,11 +24,11 @@ LightVector light_vector_get(LightData light, const bool is_directional, vec3 P)
|
|||
{
|
||||
LightVector lv;
|
||||
if (is_directional) {
|
||||
lv.L = light._back;
|
||||
lv.L = light_z_axis(light);
|
||||
lv.dist = 1.0;
|
||||
}
|
||||
else {
|
||||
lv.L = light._position - P;
|
||||
lv.L = light_position_get(light) - P;
|
||||
float inv_distance = inversesqrt(length_squared(lv.L));
|
||||
lv.L *= inv_distance;
|
||||
lv.dist = 1.0 / inv_distance;
|
||||
|
@ -42,21 +42,17 @@ LightVector light_shape_vector_get(LightData light, const bool is_directional, v
|
|||
if (!is_directional && is_area_light(light.type)) {
|
||||
LightAreaData area = light_area_data_get(light);
|
||||
|
||||
vec3 L = P - light._position;
|
||||
vec2 closest_point = vec2(dot(light._right, L), dot(light._up, L));
|
||||
closest_point /= area.size;
|
||||
|
||||
vec3 lP = transform_point_inversed(light.object_to_world, P);
|
||||
vec2 ls_closest_point = lP.xy;
|
||||
if (light.type == LIGHT_ELLIPSE) {
|
||||
closest_point /= max(1.0, length(closest_point));
|
||||
ls_closest_point /= max(1.0, length(ls_closest_point / area.size));
|
||||
}
|
||||
else {
|
||||
closest_point = clamp(closest_point, -1.0, 1.0);
|
||||
ls_closest_point = clamp(ls_closest_point, -area.size, area.size);
|
||||
}
|
||||
closest_point *= area.size;
|
||||
vec3 ws_closest_point = transform_point(light.object_to_world, vec3(ls_closest_point, 0.0));
|
||||
|
||||
vec3 L_prime = light._right * closest_point.x + light._up * closest_point.y;
|
||||
|
||||
L = L_prime - L;
|
||||
vec3 L = ws_closest_point - P;
|
||||
float inv_distance = inversesqrt(length_squared(L));
|
||||
LightVector lv;
|
||||
lv.L = L * inv_distance;
|
||||
|
@ -70,19 +66,7 @@ LightVector light_shape_vector_get(LightData light, const bool is_directional, v
|
|||
/* Rotate vector to light's local space. Does not translate. */
|
||||
vec3 light_world_to_local(LightData light, vec3 L)
|
||||
{
|
||||
/* Avoid relying on compiler to optimize this.
|
||||
* vec3 lL = transpose(mat3(light.object_mat)) * L; */
|
||||
vec3 lL;
|
||||
lL.x = dot(light.object_mat[0].xyz, L);
|
||||
lL.y = dot(light.object_mat[1].xyz, L);
|
||||
lL.z = dot(light.object_mat[2].xyz, L);
|
||||
return lL;
|
||||
}
|
||||
|
||||
/* Transform position from light's local space to world space. Does translation. */
|
||||
vec3 light_local_position_to_world(LightData light, vec3 lP)
|
||||
{
|
||||
return mat3(light.object_mat) * lP + light._position;
|
||||
return transform_direction_transposed(light.object_to_world, L);
|
||||
}
|
||||
|
||||
/* From Frostbite PBR Course
|
||||
|
@ -101,7 +85,7 @@ float light_spot_attenuation(LightData light, vec3 L)
|
|||
vec3 lL = light_world_to_local(light, L);
|
||||
float ellipse = inversesqrt(1.0 + length_squared(lL.xy * spot.spot_size_inv / lL.z));
|
||||
float spotmask = smoothstep(0.0, 1.0, ellipse * spot.spot_mul + spot.spot_bias);
|
||||
return spotmask * step(0.0, -dot(L, -light._back));
|
||||
return (lL.z > 0.0) ? spotmask : 0.0;
|
||||
}
|
||||
|
||||
float light_attenuation_common(LightData light, const bool is_directional, vec3 L)
|
||||
|
@ -113,7 +97,7 @@ float light_attenuation_common(LightData light, const bool is_directional, vec3
|
|||
return light_spot_attenuation(light, L);
|
||||
}
|
||||
if (is_area_light(light.type)) {
|
||||
return step(0.0, -dot(L, -light._back));
|
||||
return float(dot(L, light_z_axis(light)) > 0.0);
|
||||
}
|
||||
return 1.0;
|
||||
}
|
||||
|
@ -202,7 +186,7 @@ float light_point_light(LightData light, const bool is_directional, LightVector
|
|||
|
||||
if (is_area_light(light.type)) {
|
||||
/* Modulate by light plane orientation / solid angle. */
|
||||
power *= saturate(dot(light._back, lv.L));
|
||||
power *= saturate(dot(light_z_axis(light), lv.L));
|
||||
}
|
||||
return power;
|
||||
}
|
||||
|
@ -227,12 +211,15 @@ float light_ltc(
|
|||
return 1.0;
|
||||
}
|
||||
|
||||
vec3 Px = light_x_axis(light);
|
||||
vec3 Py = light_y_axis(light);
|
||||
|
||||
if (light.type == LIGHT_RECT) {
|
||||
LightAreaData area = light_area_data_get(light);
|
||||
|
||||
vec3 corners[4];
|
||||
corners[0] = light._right * area.size.x + light._up * -area.size.y;
|
||||
corners[1] = light._right * area.size.x + light._up * area.size.y;
|
||||
corners[0] = Px * area.size.x + Py * -area.size.y;
|
||||
corners[1] = Px * area.size.x + Py * area.size.y;
|
||||
corners[2] = -corners[0];
|
||||
corners[3] = -corners[1];
|
||||
|
||||
|
@ -247,9 +234,6 @@ float light_ltc(
|
|||
return ltc_evaluate_quad(utility_tx, corners, vec3(0.0, 0.0, 1.0));
|
||||
}
|
||||
else {
|
||||
vec3 Px = light._right;
|
||||
vec3 Py = light._up;
|
||||
|
||||
if (!is_area_light(light.type)) {
|
||||
make_orthonormal_basis(lv.L, Px, Py);
|
||||
}
|
||||
|
|
|
@ -124,11 +124,6 @@ bool debug_tilemaps(vec3 P, LightData light)
|
|||
out_color_add = vec4(debug_tile_state_color(light.type, tile), 0.0);
|
||||
out_color_mul = vec4(0.0);
|
||||
|
||||
# ifdef DRW_DEBUG_PRINT
|
||||
if (all(equal(ivec2(gl_FragCoord.xy), ivec2(0)))) {
|
||||
drw_print(light.object_mat);
|
||||
}
|
||||
# endif
|
||||
return true;
|
||||
}
|
||||
#else
|
||||
|
@ -144,11 +139,6 @@ bool debug_tilemaps(vec3 P, LightData light)
|
|||
out_color_add = vec4(debug_tile_state_color(tile), 0.0);
|
||||
out_color_mul = vec4(0.0);
|
||||
|
||||
# ifdef DRW_DEBUG_PRINT
|
||||
if (all(equal(ivec2(gl_FragCoord.xy), ivec2(0)))) {
|
||||
drw_print(light.object_mat);
|
||||
}
|
||||
# endif
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
@ -186,7 +176,7 @@ void debug_random_tilemap_color(vec3 P, LightData light)
|
|||
coord = shadow_directional_coordinates(light, lP);
|
||||
}
|
||||
else {
|
||||
vec3 lP = light_world_to_local(light, P - light._position);
|
||||
vec3 lP = light_world_to_local(light, P - light_position_get(light));
|
||||
int face_id = shadow_punctual_face_index_get(lP);
|
||||
lP = shadow_punctual_local_position_to_face_local(face_id, lP);
|
||||
coord = shadow_punctual_coordinates(light, lP, face_id);
|
||||
|
|
|
@ -152,12 +152,12 @@ vec3 shadow_punctual_reconstruct_position(ShadowSampleParams params,
|
|||
vec3 lP = project_point(wininv, clip_P);
|
||||
int face_id = params.tilemap_index - light.tilemap_index;
|
||||
lP = shadow_punctual_face_local_to_local_position(face_id, lP);
|
||||
return mat3(light.object_mat) * lP + light._position;
|
||||
return transform_point(light.object_to_world, lP);
|
||||
}
|
||||
|
||||
ShadowSampleParams shadow_punctual_sample_params_get(LightData light, vec3 P)
|
||||
{
|
||||
vec3 lP = (P - light._position) * mat3(light.object_mat);
|
||||
vec3 lP = transform_point_inversed(light.object_to_world, P);
|
||||
|
||||
int face_id = shadow_punctual_face_index_get(lP);
|
||||
/* Local Light Space > Face Local (View) Space. */
|
||||
|
@ -205,7 +205,7 @@ ShadowDirectionalSampleInfo shadow_directional_sample_info_get(LightData light,
|
|||
info.clip_near = orderedIntBitsToFloat(light.clip_near);
|
||||
info.clip_far = orderedIntBitsToFloat(light.clip_far);
|
||||
|
||||
int level = shadow_directional_level(light, lP - light._position);
|
||||
int level = shadow_directional_level(light, lP - light_position_get(light));
|
||||
/* This difference needs to be less than 32 for the later shift to be valid.
|
||||
* This is ensured by ShadowDirectional::clipmap_level_range(). */
|
||||
info.level_relative = level - light_sun_data_get(light).clipmap_lod_min;
|
||||
|
@ -234,14 +234,14 @@ vec3 shadow_directional_reconstruct_position(ShadowSampleParams params, LightDat
|
|||
lP.xy = clipmap_pos + info.clipmap_origin;
|
||||
lP.z = (params.uv.z + info.clip_near) * -1.0;
|
||||
|
||||
return mat3(light.object_mat) * lP;
|
||||
return transform_direction_transposed(light.object_to_world, lP);
|
||||
}
|
||||
|
||||
ShadowSampleParams shadow_directional_sample_params_get(usampler2D tilemaps_tx,
|
||||
LightData light,
|
||||
vec3 P)
|
||||
{
|
||||
vec3 lP = P * mat3(light.object_mat);
|
||||
vec3 lP = transform_direction(light.object_to_world, P);
|
||||
ShadowDirectionalSampleInfo info = shadow_directional_sample_info_get(light, lP);
|
||||
|
||||
ShadowCoordinates coord = shadow_directional_coordinates(light, lP);
|
||||
|
|
|
@ -55,15 +55,15 @@ void shadow_tag_usage_tilemap_directional(uint l_idx, vec3 P, vec3 V, float radi
|
|||
|
||||
/* TODO(Miguel Pozo): Implement lod_bias support. */
|
||||
if (radius == 0.0) {
|
||||
int level = shadow_directional_level(light, lP - light._position);
|
||||
int level = shadow_directional_level(light, lP - light_position_get(light));
|
||||
ShadowCoordinates coord = shadow_directional_coordinates_at_level(light, lP, level);
|
||||
shadow_tag_usage_tile(light, coord.tile_coord, 0, coord.tilemap_index);
|
||||
}
|
||||
else {
|
||||
vec3 start_lP = light_world_to_local(light, P - V * radius);
|
||||
vec3 end_lP = light_world_to_local(light, P + V * radius);
|
||||
int min_level = shadow_directional_level(light, start_lP - light._position);
|
||||
int max_level = shadow_directional_level(light, end_lP - light._position);
|
||||
int min_level = shadow_directional_level(light, start_lP - light_position_get(light));
|
||||
int max_level = shadow_directional_level(light, end_lP - light_position_get(light));
|
||||
|
||||
for (int level = min_level; level <= max_level; level++) {
|
||||
ShadowCoordinates coord_min = shadow_directional_coordinates_at_level(
|
||||
|
@ -89,7 +89,7 @@ void shadow_tag_usage_tilemap_punctual(
|
|||
return;
|
||||
}
|
||||
|
||||
vec3 lP = light_world_to_local(light, P - light._position);
|
||||
vec3 lP = light_world_to_local(light, P - light_position_get(light));
|
||||
float dist_to_light = max(length(lP) - radius, 1e-5);
|
||||
if (dist_to_light > light_local_data_get(light).influence_radius_max) {
|
||||
return;
|
||||
|
|
|
@ -111,7 +111,9 @@ void main()
|
|||
set_clipmap_data(light, 0, 2, 0.0, 0.0);
|
||||
|
||||
light.tilemap_index = light_sun_data_get(light).clipmap_lod_min;
|
||||
light._position = vec3(0.0);
|
||||
light.object_to_world.x = float4(1.0, 0.0, 0.0, 0.0);
|
||||
light.object_to_world.y = float4(0.0, 1.0, 0.0, 0.0);
|
||||
light.object_to_world.z = float4(0.0, 0.0, 1.0, 0.0);
|
||||
light.lod_bias = 0;
|
||||
|
||||
float lod_min_tile_size = exp2(float(light_sun_data_get(light).clipmap_lod_min)) /
|
||||
|
@ -226,7 +228,9 @@ void main()
|
|||
// clipmap_lod_max = 2; /* 3 tile-maps. */
|
||||
set_clipmap_data(light, 0, 2, 0.0, 0.0);
|
||||
light.tilemap_index = 1;
|
||||
light._position = vec3(0.0);
|
||||
light.object_to_world.x = float4(1.0, 0.0, 0.0, 0.0);
|
||||
light.object_to_world.y = float4(0.0, 1.0, 0.0, 0.0);
|
||||
light.object_to_world.z = float4(0.0, 0.0, 1.0, 0.0);
|
||||
light.lod_bias = light_sun_data_get(light).clipmap_lod_min - 1;
|
||||
float lod_tile_size = exp2(float(light_sun_data_get(light).clipmap_lod_min)) /
|
||||
float(SHADOW_TILEMAP_RES);
|
||||
|
|
|
@ -53,7 +53,7 @@ void main()
|
|||
float local_min = FLT_MAX;
|
||||
float local_max = -FLT_MAX;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
float z = dot(box.corners[i].xyz, -light._back);
|
||||
float z = dot(box.corners[i].xyz, -light_z_axis(light));
|
||||
local_min = min(local_min, z);
|
||||
local_max = max(local_max, z);
|
||||
}
|
||||
|
|
|
@ -105,7 +105,7 @@ ShadowSamplingTile shadow_tile_load(usampler2D tilemaps_tx, ivec2 tile_co, int t
|
|||
* This function should be the inverse of ShadowDirectional::coverage_get().
|
||||
*
|
||||
* \a lP shading point position in light space, relative to the to camera position snapped to
|
||||
* the smallest clip-map level (`shadow_world_to_local(light, P) - light._position`).
|
||||
* the smallest clip-map level (`shadow_world_to_local(light, P) - light_position_get(light)`).
|
||||
*/
|
||||
|
||||
float shadow_directional_level_fractional(LightData light, vec3 lP)
|
||||
|
@ -149,7 +149,7 @@ float shadow_punctual_footprint_ratio(LightData light,
|
|||
* This gives a good approximation of what LOD to select to get a somewhat uniform shadow map
|
||||
* resolution in screen space. */
|
||||
|
||||
float dist_to_light = distance(P, light._position);
|
||||
float dist_to_light = distance(P, light_position_get(light));
|
||||
float footprint_ratio = dist_to_light;
|
||||
/* Project the radius to the screen. 1 unit away from the camera the same way
|
||||
* pixel_world_radius_inv was computed. Not needed in orthographic mode. */
|
||||
|
@ -225,7 +225,7 @@ ShadowCoordinates shadow_directional_coordinates_at_level(LightData light, vec3
|
|||
*/
|
||||
ShadowCoordinates shadow_directional_coordinates(LightData light, vec3 lP)
|
||||
{
|
||||
int level = shadow_directional_level(light, lP - light._position);
|
||||
int level = shadow_directional_level(light, lP - light_position_get(light));
|
||||
return shadow_directional_coordinates_at_level(light, lP, level);
|
||||
}
|
||||
|
||||
|
|
|
@ -247,7 +247,7 @@ ShadowTracingSample shadow_map_trace_sample(ShadowMapTracingState state,
|
|||
/* Ray position is ray local position with origin at light origin. */
|
||||
vec4 ray_pos = ray.origin + ray.direction * state.ray_time;
|
||||
|
||||
int level = shadow_directional_level(ray.light, ray_pos.xyz - ray.light._position);
|
||||
int level = shadow_directional_level(ray.light, ray_pos.xyz - light_position_get(ray.light));
|
||||
/* This difference needs to be less than 32 for the later shift to be valid.
|
||||
* This is ensured by ShadowDirectional::clipmap_level_range(). */
|
||||
int level_relative = level - light_sun_data_get(ray.light).clipmap_lod_min;
|
||||
|
@ -460,7 +460,7 @@ vec3 shadow_pcf_offset(LightData light, const bool is_directional, vec3 P, vec3
|
|||
/* Scale the offset based on shadow LOD. */
|
||||
if (is_directional) {
|
||||
vec3 lP = light_world_to_local(light, P);
|
||||
float level = shadow_directional_level_fractional(light, lP - light._position);
|
||||
float level = shadow_directional_level_fractional(light, lP - light_position_get(light));
|
||||
float pcf_scale = mix(0.5, 1.0, fract(level));
|
||||
pcf_offset *= pcf_scale;
|
||||
}
|
||||
|
@ -550,7 +550,7 @@ ShadowEvalResult shadow_eval(LightData light,
|
|||
P += N_bias * normal_offset;
|
||||
|
||||
vec3 lP = is_directional ? light_world_to_local(light, P) :
|
||||
light_world_to_local(light, P - light._position);
|
||||
light_world_to_local(light, P - light_position_get(light));
|
||||
vec3 lNg = light_world_to_local(light, Ng);
|
||||
/* Invert horizon clipping. */
|
||||
lNg = (is_transmission) ? -lNg : lNg;
|
||||
|
|
|
@ -199,7 +199,7 @@ vec3 volume_light(LightData light, const bool is_directional, LightVector lv)
|
|||
|
||||
if (light.type == LIGHT_RECT || light.type == LIGHT_ELLIPSE) {
|
||||
/* Modulate by light plane orientation / solid angle. */
|
||||
power *= saturate(dot(light._back, lv.L));
|
||||
power *= saturate(dot(light_z_axis(light), lv.L));
|
||||
}
|
||||
}
|
||||
return light.color * light.power[LIGHT_VOLUME] * power;
|
||||
|
|
|
@ -525,8 +525,7 @@ GPENCIL_tLayer *grease_pencil_layer_cache_add(GPENCIL_PrivateData *pd,
|
|||
const GreasePencil &grease_pencil = *static_cast<GreasePencil *>(ob->data);
|
||||
|
||||
const bool is_in_front = (ob->dtx & OB_DRAW_IN_FRONT);
|
||||
/* Grease Pencil 3 doesn't have this. */
|
||||
const bool is_screenspace = false;
|
||||
|
||||
const bool override_vertcol = (pd->v3d_color_type != -1);
|
||||
const bool is_vert_col_mode = (pd->v3d_color_type == V3D_SHADING_VERTEX_COLOR) ||
|
||||
(ob->mode == OB_MODE_VERTEX_PAINT) || pd->is_render;
|
||||
|
@ -541,9 +540,9 @@ GPENCIL_tLayer *grease_pencil_layer_cache_add(GPENCIL_PrivateData *pd,
|
|||
const float vert_col_opacity = (override_vertcol) ?
|
||||
(is_vert_col_mode ? pd->vertex_paint_opacity : 0.0f) :
|
||||
(pd->is_render ? 1.0f : pd->vertex_paint_opacity);
|
||||
/* Negate thickness sign to tag that strokes are in screen space.
|
||||
* Convert to world units (by default, 1 meter = 1000 pixels). */
|
||||
const float thickness_scale = (is_screenspace) ? -1.0f : 1.0f / 1000.0f;
|
||||
/* Negate thickness sign to tag that strokes are in screen space (this is no longer used in
|
||||
* GPv3). Convert to world units (by default, 1 meter = 1000 pixels). */
|
||||
const float thickness_scale = blender::bke::greasepencil::LEGACY_RADIUS_CONVERSION_FACTOR;
|
||||
/* If the layer is used as a mask (but is otherwise not visible in the render), render it with a
|
||||
* opacity of 0 so that it can still mask other layers. */
|
||||
const float layer_opacity = !is_used_as_mask ? grease_pencil_layer_final_opacity_get(
|
||||
|
|
|
@ -750,9 +750,9 @@ static void grease_pencil_geom_batch_ensure(Object &object,
|
|||
const float3 pos = math::transform_point(layer_space_to_object_space, positions[point_i]);
|
||||
copy_v3_v3(s_vert.pos, pos);
|
||||
s_vert.radius = radii[point_i] * ((end_cap == GP_STROKE_CAP_TYPE_ROUND) ? 1.0f : -1.0f);
|
||||
/* Convert to legacy "pixel" space. The shader expects the values to be in this space.
|
||||
* Otherwise the values will get clamped. */
|
||||
s_vert.radius *= 1000.0f;
|
||||
/* Convert to legacy "pixel" space. We divide here, because the shader expects the values to
|
||||
* be in the `px` space rather than world space. Otherwise the values will get clamped. */
|
||||
s_vert.radius /= bke::greasepencil::LEGACY_RADIUS_CONVERSION_FACTOR;
|
||||
s_vert.opacity = opacities[point_i] *
|
||||
((start_cap == GP_STROKE_CAP_TYPE_ROUND) ? 1.0f : -1.0f);
|
||||
s_vert.point_id = verts_range[idx];
|
||||
|
|
|
@ -383,7 +383,7 @@ PassType *drw_volume_object_mesh_init(PassType &ps,
|
|||
volume_infos.grids_xform[grid_id++] = float4x4::identity();
|
||||
}
|
||||
}
|
||||
else if (!fds->fluid) {
|
||||
else if (fds->fluid) {
|
||||
/* Smoke Simulation. */
|
||||
DRW_smoke_ensure(fmd, fds->flags & FLUID_DOMAIN_USE_NOISE);
|
||||
|
||||
|
|
|
@ -5142,7 +5142,7 @@ static void achannel_setting_slider_cb(bContext *C, void *id_poin, void *fcu_poi
|
|||
cfra = BKE_nla_tweakedit_remap(adt, float(scene->r.cfra), NLATIME_CONVERT_UNMAP);
|
||||
|
||||
/* Get flags for keyframing. */
|
||||
flag = ANIM_get_keyframing_flags(scene);
|
||||
flag = blender::animrig::get_keyframing_flags(scene);
|
||||
|
||||
/* try to resolve the path stored in the F-Curve */
|
||||
if (RNA_path_resolve_property(&id_ptr, fcu->rna_path, &ptr, &prop)) {
|
||||
|
@ -5205,7 +5205,7 @@ static void achannel_setting_slider_shapekey_cb(bContext *C, void *key_poin, voi
|
|||
key->adt, anim_eval_context.eval_time, NLATIME_CONVERT_UNMAP);
|
||||
|
||||
/* get flags for keyframing */
|
||||
flag = ANIM_get_keyframing_flags(scene);
|
||||
flag = blender::animrig::get_keyframing_flags(scene);
|
||||
|
||||
/* try to resolve the path stored in the F-Curve */
|
||||
if (RNA_path_resolve_property(&id_ptr, rna_path ? rna_path->c_str() : nullptr, &ptr, &prop)) {
|
||||
|
@ -5261,7 +5261,7 @@ static void achannel_setting_slider_nla_curve_cb(bContext *C, void * /*id_poin*/
|
|||
cfra = float(scene->r.cfra);
|
||||
|
||||
/* get flags for keyframing */
|
||||
flag = ANIM_get_keyframing_flags(scene);
|
||||
flag = blender::animrig::get_keyframing_flags(scene);
|
||||
|
||||
/* Get pointer and property from the slider -
|
||||
* this should all match up with the NlaStrip required. */
|
||||
|
|
|
@ -70,31 +70,6 @@ static KeyingSet *keyingset_get_from_op_with_error(wmOperator *op,
|
|||
|
||||
static int delete_key_using_keying_set(bContext *C, wmOperator *op, KeyingSet *ks);
|
||||
|
||||
/* ************************************************** */
|
||||
/* Keyframing Setting Wrangling */
|
||||
|
||||
eInsertKeyFlags ANIM_get_keyframing_flags(Scene *scene)
|
||||
{
|
||||
using namespace blender::animrig;
|
||||
eInsertKeyFlags flag = INSERTKEY_NOFLAGS;
|
||||
|
||||
/* Visual keying. */
|
||||
if (is_keying_flag(scene, KEYING_FLAG_VISUALKEY)) {
|
||||
flag |= INSERTKEY_MATRIX;
|
||||
}
|
||||
|
||||
/* Cycle-aware keyframe insertion - preserve cycle period and flow. */
|
||||
if (is_keying_flag(scene, KEYING_FLAG_CYCLEAWARE)) {
|
||||
flag |= INSERTKEY_CYCLE_AWARE;
|
||||
}
|
||||
|
||||
if (is_keying_flag(scene, MANUALKEY_FLAG_INSERTNEEDED)) {
|
||||
flag |= INSERTKEY_NEEDED;
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
||||
/* ******************************************* */
|
||||
/* Animation Data Validation */
|
||||
|
||||
|
@ -389,7 +364,7 @@ static int insert_key(bContext *C, wmOperator *op)
|
|||
Scene *scene = CTX_data_scene(C);
|
||||
const float scene_frame = BKE_scene_frame_get(scene);
|
||||
|
||||
const eInsertKeyFlags insert_key_flags = ANIM_get_keyframing_flags(scene);
|
||||
const eInsertKeyFlags insert_key_flags = animrig::get_keyframing_flags(scene);
|
||||
const eBezTriple_KeyframeType key_type = eBezTriple_KeyframeType(
|
||||
scene->toolsettings->keyframe_type);
|
||||
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
|
||||
|
@ -976,7 +951,7 @@ static int insert_key_button_exec(bContext *C, wmOperator *op)
|
|||
const bool all = RNA_boolean_get(op->ptr, "all");
|
||||
eInsertKeyFlags flag = INSERTKEY_NOFLAGS;
|
||||
|
||||
flag = ANIM_get_keyframing_flags(scene);
|
||||
flag = get_keyframing_flags(scene);
|
||||
|
||||
if (!(but = UI_context_active_but_prop_get(C, &ptr, &prop, &index))) {
|
||||
/* pass event on if no active button found */
|
||||
|
|
|
@ -101,7 +101,7 @@ static int add_default_keyingset_exec(bContext *C, wmOperator * /*op*/)
|
|||
*/
|
||||
const eKS_Settings flag = KEYINGSET_ABSOLUTE;
|
||||
|
||||
const eInsertKeyFlags keyingflag = ANIM_get_keyframing_flags(scene);
|
||||
const eInsertKeyFlags keyingflag = blender::animrig::get_keyframing_flags(scene);
|
||||
|
||||
/* Call the API func, and set the active keyingset index. */
|
||||
BKE_keyingset_add(&scene->keyingsets, nullptr, nullptr, flag, keyingflag);
|
||||
|
@ -285,7 +285,7 @@ static int add_keyingset_button_exec(bContext *C, wmOperator *op)
|
|||
*/
|
||||
const eKS_Settings flag = KEYINGSET_ABSOLUTE;
|
||||
|
||||
const eInsertKeyFlags keyingflag = ANIM_get_keyframing_flags(scene);
|
||||
const eInsertKeyFlags keyingflag = blender::animrig::get_keyframing_flags(scene);
|
||||
|
||||
/* Call the API func, and set the active keyingset index. */
|
||||
keyingset = BKE_keyingset_add(
|
||||
|
@ -1136,7 +1136,7 @@ int ANIM_apply_keyingset(bContext *C,
|
|||
}
|
||||
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
const eInsertKeyFlags base_kflags = ANIM_get_keyframing_flags(scene);
|
||||
const eInsertKeyFlags base_kflags = blender::animrig::get_keyframing_flags(scene);
|
||||
eInsertKeyFlags kflag = INSERTKEY_NOFLAGS;
|
||||
if (mode == MODIFYKEY_MODE_INSERT) {
|
||||
/* use context settings as base */
|
||||
|
|
|
@ -261,16 +261,12 @@ static int grease_pencil_stroke_simplify_exec(bContext *C, wmOperator *op)
|
|||
[positions, radii](int64_t first_index, int64_t last_index, int64_t index) {
|
||||
const float dist_position = dist_to_line_v3(
|
||||
positions[index], positions[first_index], positions[last_index]);
|
||||
/* We divide the distance by 2000.0f to convert from "pixels" to an actual
|
||||
* distance. For some reason, grease pencil strokes the thickness of strokes in
|
||||
* pixels rather than object space distance. */
|
||||
const float dist_radii = dist_to_interpolated(positions[index],
|
||||
positions[first_index],
|
||||
positions[last_index],
|
||||
radii[index],
|
||||
radii[first_index],
|
||||
radii[last_index]) /
|
||||
2000.0f;
|
||||
radii[last_index]);
|
||||
return math::max(dist_position, dist_radii);
|
||||
};
|
||||
|
||||
|
@ -2231,7 +2227,8 @@ static int grease_pencil_paste_strokes_exec(bContext *C, wmOperator *op)
|
|||
}
|
||||
|
||||
/* Ensure active keyframe. */
|
||||
if (!ensure_active_keyframe(scene, grease_pencil)) {
|
||||
bool inserted_keyframe = false;
|
||||
if (!ensure_active_keyframe(scene, grease_pencil, inserted_keyframe)) {
|
||||
BKE_report(op->reports, RPT_ERROR, "No Grease Pencil frame to draw on");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
@ -2256,6 +2253,10 @@ static int grease_pencil_paste_strokes_exec(bContext *C, wmOperator *op)
|
|||
DEG_id_tag_update(&grease_pencil.id, ID_RECALC_GEOMETRY);
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_DATA, &grease_pencil);
|
||||
|
||||
if (inserted_keyframe) {
|
||||
WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, nullptr);
|
||||
}
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
|
|
|
@ -335,7 +335,9 @@ void create_keyframe_edit_data_selected_frames_list(KeyframeEditData *ked,
|
|||
}
|
||||
}
|
||||
|
||||
bool ensure_active_keyframe(const Scene &scene, GreasePencil &grease_pencil)
|
||||
bool ensure_active_keyframe(const Scene &scene,
|
||||
GreasePencil &grease_pencil,
|
||||
bool &r_inserted_keyframe)
|
||||
{
|
||||
const int current_frame = scene.r.cfra;
|
||||
bke::greasepencil::Layer &active_layer = *grease_pencil.get_active_layer();
|
||||
|
@ -366,6 +368,7 @@ bool ensure_active_keyframe(const Scene &scene, GreasePencil &grease_pencil)
|
|||
/* Otherwise we just insert a blank keyframe at the current frame. */
|
||||
grease_pencil.insert_blank_frame(active_layer, current_frame, 0, BEZT_KEYTYPE_KEYFRAME);
|
||||
}
|
||||
r_inserted_keyframe = true;
|
||||
}
|
||||
/* There should now always be a drawing at the current frame. */
|
||||
BLI_assert(active_layer.has_drawing_at(current_frame));
|
||||
|
|
|
@ -1172,11 +1172,14 @@ int grease_pencil_draw_operator_invoke(bContext *C, wmOperator *op)
|
|||
}
|
||||
|
||||
/* Ensure a drawing at the current keyframe. */
|
||||
if (!ed::greasepencil::ensure_active_keyframe(*scene, grease_pencil)) {
|
||||
bool inserted_keyframe = false;
|
||||
if (!ed::greasepencil::ensure_active_keyframe(*scene, grease_pencil, inserted_keyframe)) {
|
||||
BKE_report(op->reports, RPT_ERROR, "No Grease Pencil frame to draw on");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
if (inserted_keyframe) {
|
||||
WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, nullptr);
|
||||
}
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
||||
|
|
|
@ -209,7 +209,9 @@ bool has_any_frame_selected(const bke::greasepencil::Layer &layer);
|
|||
* create one when auto-key is on (taking additive drawing setting into account).
|
||||
* \return false when no keyframe could be found or created.
|
||||
*/
|
||||
bool ensure_active_keyframe(const Scene &scene, GreasePencil &grease_pencil);
|
||||
bool ensure_active_keyframe(const Scene &scene,
|
||||
GreasePencil &grease_pencil,
|
||||
bool &r_inserted_keyframe);
|
||||
|
||||
void create_keyframe_edit_data_selected_frames_list(KeyframeEditData *ked,
|
||||
const bke::greasepencil::Layer &layer);
|
||||
|
|
|
@ -39,15 +39,6 @@ struct NlaKeyframingContext;
|
|||
/** \name Key-Framing Management
|
||||
* \{ */
|
||||
|
||||
/**
|
||||
* Get the active settings for key-framing settings from context (specifically the given scene)
|
||||
* \param use_autokey_mode: include settings from key-framing mode in the result
|
||||
* (i.e. replace only).
|
||||
*/
|
||||
eInsertKeyFlags ANIM_get_keyframing_flags(Scene *scene);
|
||||
|
||||
/* -------- */
|
||||
|
||||
/**
|
||||
* \brief Lesser Key-framing API call.
|
||||
*
|
||||
|
|
|
@ -68,7 +68,9 @@ bool ui_but_is_interactive_ex(const uiBut *but, const bool labeledit, const bool
|
|||
if (but->type == UI_BTYPE_LABEL) {
|
||||
if (for_tooltip) {
|
||||
/* It's important labels are considered interactive for the purpose of showing tooltip. */
|
||||
if (!ui_but_drag_is_draggable(but) && but->tip_func == nullptr) {
|
||||
if (!ui_but_drag_is_draggable(but) && but->tip_func == nullptr &&
|
||||
(but->tip == nullptr || but->tip[0] == '\0'))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -279,10 +279,14 @@ static int grease_pencil_sculpt_paint_invoke(bContext *C, wmOperator *op, const
|
|||
}
|
||||
|
||||
/* Ensure a drawing at the current keyframe. */
|
||||
if (!ed::greasepencil::ensure_active_keyframe(*scene, grease_pencil)) {
|
||||
bool inserted_keyframe = false;
|
||||
if (!ed::greasepencil::ensure_active_keyframe(*scene, grease_pencil, inserted_keyframe)) {
|
||||
BKE_report(op->reports, RPT_ERROR, "No Grease Pencil frame to draw on");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
if (inserted_keyframe) {
|
||||
WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, nullptr);
|
||||
}
|
||||
|
||||
op->customdata = paint_stroke_new(C,
|
||||
op,
|
||||
|
|
|
@ -709,7 +709,7 @@ void PaintOperation::on_stroke_done(const bContext &C)
|
|||
drawing.tag_topology_changed();
|
||||
|
||||
DEG_id_tag_update(&grease_pencil.id, ID_RECALC_GEOMETRY);
|
||||
WM_main_add_notifier(NC_GEOM | ND_DATA, &grease_pencil.id);
|
||||
WM_event_add_notifier(&C, NC_GEOM | ND_DATA, &grease_pencil.id);
|
||||
}
|
||||
|
||||
std::unique_ptr<GreasePencilStrokeOperation> new_paint_operation()
|
||||
|
|
|
@ -1215,7 +1215,6 @@ static bool paint_use_2d_cursor(PaintMode mode)
|
|||
return false;
|
||||
case PaintMode::Texture3D:
|
||||
case PaintMode::Texture2D:
|
||||
case PaintMode::SculptUV:
|
||||
case PaintMode::VertexGPencil:
|
||||
case PaintMode::SculptGPencil:
|
||||
case PaintMode::WeightGPencil:
|
||||
|
|
|
@ -320,7 +320,9 @@ void paint_curve_mask_cache_update(CurveMaskCache *curve_mask_cache,
|
|||
|
||||
/* `sculpt_uv.cc` */
|
||||
|
||||
void SCULPT_OT_uv_sculpt_stroke(wmOperatorType *ot);
|
||||
void SCULPT_OT_uv_sculpt_grab(wmOperatorType *ot);
|
||||
void SCULPT_OT_uv_sculpt_relax(wmOperatorType *ot);
|
||||
void SCULPT_OT_uv_sculpt_pinch(wmOperatorType *ot);
|
||||
|
||||
/* paint_utils.cc */
|
||||
|
||||
|
|
|
@ -1902,7 +1902,9 @@ void ED_operatortypes_paint()
|
|||
WM_operatortype_append(PAINT_OT_weight_sample_group);
|
||||
|
||||
/* uv */
|
||||
WM_operatortype_append(SCULPT_OT_uv_sculpt_stroke);
|
||||
WM_operatortype_append(SCULPT_OT_uv_sculpt_grab);
|
||||
WM_operatortype_append(SCULPT_OT_uv_sculpt_relax);
|
||||
WM_operatortype_append(SCULPT_OT_uv_sculpt_pinch);
|
||||
|
||||
/* vertex selection */
|
||||
WM_operatortype_append(PAINT_OT_vert_select_all);
|
||||
|
|
|
@ -40,12 +40,25 @@
|
|||
|
||||
#include "RNA_access.hh"
|
||||
#include "RNA_define.hh"
|
||||
#include "RNA_enum_types.hh"
|
||||
|
||||
#include "paint_intern.hh"
|
||||
#include "uvedit_intern.hh"
|
||||
|
||||
#include "UI_view2d.hh"
|
||||
|
||||
typedef enum eBrushUVSculptTool {
|
||||
UV_SCULPT_TOOL_GRAB = 0,
|
||||
UV_SCULPT_TOOL_RELAX = 1,
|
||||
UV_SCULPT_TOOL_PINCH = 2,
|
||||
} eBrushUVSculptTool;
|
||||
|
||||
enum {
|
||||
UV_SCULPT_TOOL_RELAX_LAPLACIAN = 0,
|
||||
UV_SCULPT_TOOL_RELAX_HC = 1,
|
||||
UV_SCULPT_TOOL_RELAX_COTAN = 2,
|
||||
};
|
||||
|
||||
/* When set, the UV element is on the boundary of the graph.
|
||||
* i.e. Instead of a 2-dimensional laplace operator, use a 1-dimensional version.
|
||||
* Visually, UV elements on the graph boundary appear as borders of the UV Island. */
|
||||
|
@ -73,7 +86,7 @@ struct UVInitialStrokeElement {
|
|||
/** index to unique UV. */
|
||||
int uv;
|
||||
|
||||
/** Strength of brush on initial position. */
|
||||
/** Strength on initial position. */
|
||||
float strength;
|
||||
|
||||
/** initial UV position. */
|
||||
|
@ -91,7 +104,7 @@ struct UVInitialStroke {
|
|||
float init_coord[2];
|
||||
};
|
||||
|
||||
/** Custom data for UV smoothing brush. */
|
||||
/** Custom data for UV smoothing. */
|
||||
struct UvSculptData {
|
||||
/**
|
||||
* Contains the first of each set of coincident UVs.
|
||||
|
@ -111,14 +124,14 @@ struct UvSculptData {
|
|||
/** data for initial stroke, used by tools like grab */
|
||||
UVInitialStroke *initial_stroke;
|
||||
|
||||
/** Timer to be used for airbrush-type brush. */
|
||||
/** Timer to be used for airbrush-type. */
|
||||
wmTimer *timer;
|
||||
|
||||
/** To determine quickly adjacent UVs. */
|
||||
UvElementMap *elementMap;
|
||||
|
||||
/** UV-smooth Paint for fast reference. */
|
||||
Paint *uvsculpt;
|
||||
/** UV-smooth for fast reference. */
|
||||
UvSculpt *uvsculpt;
|
||||
|
||||
/** Tool to use. duplicating here to change if modifier keys are pressed. */
|
||||
char tool;
|
||||
|
@ -144,6 +157,18 @@ static void apply_sculpt_data_constraints(UvSculptData *sculptdata, float uv[2])
|
|||
uv[1] = clamp_f(uv[1], v, v + 1.0f);
|
||||
}
|
||||
|
||||
static float calc_strength(const UvSculptData *sculptdata, float p, const float len)
|
||||
{
|
||||
float strength = BKE_brush_curve_strength(eBrushCurvePreset(sculptdata->uvsculpt->curve_preset),
|
||||
sculptdata->uvsculpt->strength_curve,
|
||||
p,
|
||||
len);
|
||||
|
||||
CLAMP(strength, 0.0f, 1.0f);
|
||||
|
||||
return strength;
|
||||
}
|
||||
|
||||
/*********** Improved Laplacian Relaxation Operator ************************/
|
||||
/* original code by Raul Fernandez Hernandez "farsthary" *
|
||||
* adapted to uv smoothing by Antony Riakiatakis *
|
||||
|
@ -164,7 +189,6 @@ static void HC_relaxation_iteration_uv(UvSculptData *sculptdata,
|
|||
float diff[2];
|
||||
int i;
|
||||
const float radius = sqrtf(radius_sq);
|
||||
Brush *brush = BKE_paint_brush(sculptdata->uvsculpt);
|
||||
|
||||
Temp_UVData *tmp_uvdata = (Temp_UVData *)MEM_callocN(
|
||||
sculptdata->totalUniqueUvs * sizeof(Temp_UVData), "Temporal data");
|
||||
|
@ -205,7 +229,7 @@ static void HC_relaxation_iteration_uv(UvSculptData *sculptdata,
|
|||
if (dist <= radius_sq) {
|
||||
UvElement *element;
|
||||
float strength;
|
||||
strength = alpha * BKE_brush_curve_strength_clamped(brush, sqrtf(dist), radius);
|
||||
strength = alpha * calc_strength(sculptdata, sqrtf(dist), radius);
|
||||
|
||||
sculptdata->uv[i].uv[0] = (1.0f - strength) * sculptdata->uv[i].uv[0] +
|
||||
strength *
|
||||
|
@ -250,7 +274,6 @@ static void laplacian_relaxation_iteration_uv(UvSculptData *sculptdata,
|
|||
float diff[2];
|
||||
int i;
|
||||
const float radius = sqrtf(radius_sq);
|
||||
Brush *brush = BKE_paint_brush(sculptdata->uvsculpt);
|
||||
|
||||
Temp_UVData *tmp_uvdata = (Temp_UVData *)MEM_callocN(
|
||||
sculptdata->totalUniqueUvs * sizeof(Temp_UVData), "Temporal data");
|
||||
|
@ -288,7 +311,7 @@ static void laplacian_relaxation_iteration_uv(UvSculptData *sculptdata,
|
|||
if (dist <= radius_sq) {
|
||||
UvElement *element;
|
||||
float strength;
|
||||
strength = alpha * BKE_brush_curve_strength_clamped(brush, sqrtf(dist), radius);
|
||||
strength = alpha * calc_strength(sculptdata, sqrtf(dist), radius);
|
||||
|
||||
sculptdata->uv[i].uv[0] = (1.0f - strength) * sculptdata->uv[i].uv[0] +
|
||||
strength * tmp_uvdata[i].p[0];
|
||||
|
@ -412,14 +435,13 @@ static void relaxation_iteration_uv(UvSculptData *sculptdata,
|
|||
add_weighted_edge(delta_buf, storage, head_prev, head_curr, *luv_prev, *luv_curr, weight_next);
|
||||
}
|
||||
|
||||
Brush *brush = BKE_paint_brush(sculptdata->uvsculpt);
|
||||
for (int i = 0; i < sculptdata->totalUniqueUvs; i++) {
|
||||
UvAdjacencyElement *adj_el = &sculptdata->uv[i];
|
||||
if (adj_el->is_locked) {
|
||||
continue; /* Locked UVs can't move. */
|
||||
}
|
||||
|
||||
/* Is UV within brush's influence? */
|
||||
/* Is UV within influence? */
|
||||
float diff[2];
|
||||
sub_v2_v2v2(diff, adj_el->uv, mouse_coord);
|
||||
diff[1] /= aspect_ratio;
|
||||
|
@ -427,8 +449,7 @@ static void relaxation_iteration_uv(UvSculptData *sculptdata,
|
|||
if (dist_sq > radius_sq) {
|
||||
continue;
|
||||
}
|
||||
const float strength = alpha * BKE_brush_curve_strength_clamped(
|
||||
brush, sqrtf(dist_sq), sqrtf(radius_sq));
|
||||
const float strength = alpha * calc_strength(sculptdata, sqrtf(dist_sq), sqrtf(radius_sq));
|
||||
|
||||
const float *delta_sum = delta_buf[adj_el->element - storage];
|
||||
|
||||
|
@ -460,15 +481,12 @@ static void uv_sculpt_stroke_apply(bContext *C,
|
|||
const wmEvent *event,
|
||||
Object *obedit)
|
||||
{
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
ARegion *region = CTX_wm_region(C);
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
UvSculptData *sculptdata = (UvSculptData *)op->customdata;
|
||||
Brush *brush = BKE_paint_brush(sculptdata->uvsculpt);
|
||||
ToolSettings *toolsettings = CTX_data_tool_settings(C);
|
||||
eBrushUVSculptTool tool = eBrushUVSculptTool(sculptdata->tool);
|
||||
int invert = sculptdata->invert ? -1 : 1;
|
||||
float alpha = BKE_brush_alpha_get(scene, brush);
|
||||
float alpha = sculptdata->uvsculpt->strength;
|
||||
|
||||
float co[2];
|
||||
UI_view2d_region_to_view(®ion->v2d, event->mval[0], event->mval[1], &co[0], &co[1]);
|
||||
|
@ -481,7 +499,7 @@ static void uv_sculpt_stroke_apply(bContext *C,
|
|||
float zoomx, zoomy;
|
||||
ED_space_image_get_zoom(sima, region, &zoomx, &zoomy);
|
||||
|
||||
const float radius = BKE_brush_size_get(scene, brush) / (width * zoomx);
|
||||
const float radius = sculptdata->uvsculpt->size / (width * zoomx);
|
||||
float aspectRatio = width / float(height);
|
||||
|
||||
/* We will compare squares to save some computation */
|
||||
|
@ -505,7 +523,7 @@ static void uv_sculpt_stroke_apply(bContext *C,
|
|||
if (dist <= radius_sq) {
|
||||
UvElement *element;
|
||||
float strength;
|
||||
strength = alpha * BKE_brush_curve_strength_clamped(brush, sqrtf(dist), radius);
|
||||
strength = alpha * calc_strength(sculptdata, sqrtf(dist), radius);
|
||||
normalize_v2(diff);
|
||||
|
||||
sculptdata->uv[i].uv[0] -= strength * diff[0] * 0.001f;
|
||||
|
@ -531,7 +549,7 @@ static void uv_sculpt_stroke_apply(bContext *C,
|
|||
alpha,
|
||||
radius_sq,
|
||||
aspectRatio,
|
||||
toolsettings->uv_relax_method);
|
||||
RNA_enum_get(op->ptr, "relax_method"));
|
||||
break;
|
||||
}
|
||||
case UV_SCULPT_TOOL_GRAB: {
|
||||
|
@ -637,11 +655,10 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm
|
|||
UvSculptData *data = MEM_cnew<UvSculptData>(__func__);
|
||||
BMEditMesh *em = BKE_editmesh_from_object(obedit);
|
||||
BMesh *bm = em->bm;
|
||||
Brush *brush = BKE_paint_brush(&ts->uvsculpt->paint);
|
||||
|
||||
op->customdata = data;
|
||||
|
||||
BKE_curvemapping_init(brush->curve);
|
||||
BKE_curvemapping_init(ts->uvsculpt.strength_curve);
|
||||
|
||||
if (!data) {
|
||||
return nullptr;
|
||||
|
@ -658,12 +675,18 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm
|
|||
|
||||
bool do_island_optimization = !(ts->uv_sculpt_settings & UV_SCULPT_ALL_ISLANDS);
|
||||
int island_index = 0;
|
||||
data->tool = (RNA_enum_get(op->ptr, "mode") == BRUSH_STROKE_SMOOTH) ?
|
||||
UV_SCULPT_TOOL_RELAX :
|
||||
eBrushUVSculptTool(brush->uv_sculpt_tool);
|
||||
data->invert = (RNA_enum_get(op->ptr, "mode") == BRUSH_STROKE_INVERT) ? 1 : 0;
|
||||
if (STREQ(op->type->idname, "SCULPT_OT_uv_sculpt_relax")) {
|
||||
data->tool = UV_SCULPT_TOOL_RELAX;
|
||||
}
|
||||
else if (STREQ(op->type->idname, "SCULPT_OT_uv_sculpt_grab")) {
|
||||
data->tool = UV_SCULPT_TOOL_GRAB;
|
||||
}
|
||||
else {
|
||||
data->tool = UV_SCULPT_TOOL_PINCH;
|
||||
}
|
||||
data->invert = RNA_boolean_get(op->ptr, "use_invert");
|
||||
|
||||
data->uvsculpt = &ts->uvsculpt->paint;
|
||||
data->uvsculpt = &ts->uvsculpt;
|
||||
|
||||
/* Winding was added to island detection in 5197aa04c6bd
|
||||
* However the sculpt tools can flip faces, potentially creating orphaned islands.
|
||||
|
@ -834,12 +857,8 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm
|
|||
|
||||
/* Allocate initial selection for grab tool */
|
||||
if (data->tool == UV_SCULPT_TOOL_GRAB) {
|
||||
UvSculptData *sculptdata = (UvSculptData *)op->customdata;
|
||||
Brush *brush = BKE_paint_brush(sculptdata->uvsculpt);
|
||||
|
||||
float alpha = BKE_brush_alpha_get(scene, brush);
|
||||
|
||||
float radius = BKE_brush_size_get(scene, brush);
|
||||
float alpha = data->uvsculpt->strength;
|
||||
float radius = data->uvsculpt->size;
|
||||
int width, height;
|
||||
ED_space_image_get_size(sima, &width, &height);
|
||||
float zoomx, zoomy;
|
||||
|
@ -875,7 +894,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm
|
|||
float dist = dot_v2v2(diff, diff);
|
||||
if (dist <= radius_sq) {
|
||||
float strength;
|
||||
strength = alpha * BKE_brush_curve_strength_clamped(brush, sqrtf(dist), radius);
|
||||
strength = alpha * calc_strength(data, sqrtf(dist), radius);
|
||||
|
||||
data->initial_stroke->initialSelection[counter].uv = i;
|
||||
data->initial_stroke->initialSelection[counter].strength = strength;
|
||||
|
@ -946,57 +965,78 @@ static int uv_sculpt_stroke_modal(bContext *C, wmOperator *op, const wmEvent *ev
|
|||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
||||
static bool uv_sculpt_stroke_poll(bContext *C)
|
||||
static void register_common_props(wmOperatorType *ot)
|
||||
{
|
||||
if (ED_operator_uvedit_space_image(C)) {
|
||||
/* While these values could be initialized on demand,
|
||||
* the only case this would be useful is running from the operator search popup.
|
||||
* This is such a corner case that it's simpler to check a brush has already been created
|
||||
* (something the tool system ensures). */
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
ToolSettings *ts = scene->toolsettings;
|
||||
Brush *brush = BKE_paint_brush(&ts->uvsculpt->paint);
|
||||
if (brush != nullptr) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SCULPT_OT_uv_sculpt_stroke(wmOperatorType *ot)
|
||||
{
|
||||
static const EnumPropertyItem stroke_mode_items[] = {
|
||||
{BRUSH_STROKE_NORMAL, "NORMAL", 0, "Regular", "Apply brush normally"},
|
||||
{BRUSH_STROKE_INVERT,
|
||||
"INVERT",
|
||||
0,
|
||||
"Invert",
|
||||
"Invert action of brush for duration of stroke"},
|
||||
{BRUSH_STROKE_SMOOTH,
|
||||
"RELAX",
|
||||
0,
|
||||
"Relax",
|
||||
"Switch brush to relax mode for duration of stroke"},
|
||||
{0},
|
||||
};
|
||||
|
||||
/* identifiers */
|
||||
ot->name = "Sculpt UVs";
|
||||
ot->description = "Sculpt UVs using a brush";
|
||||
ot->idname = "SCULPT_OT_uv_sculpt_stroke";
|
||||
|
||||
/* api callbacks */
|
||||
ot->invoke = uv_sculpt_stroke_invoke;
|
||||
ot->modal = uv_sculpt_stroke_modal;
|
||||
ot->poll = uv_sculpt_stroke_poll;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
/* props */
|
||||
PropertyRNA *prop;
|
||||
|
||||
prop = RNA_def_enum(
|
||||
ot->srna, "mode", stroke_mode_items, BRUSH_STROKE_NORMAL, "Mode", "Stroke Mode");
|
||||
prop = RNA_def_boolean(
|
||||
ot->srna, "use_invert", false, "Invert", "Invert action for the duration of the stroke");
|
||||
RNA_def_property_flag(prop, PropertyFlag(PROP_SKIP_SAVE));
|
||||
}
|
||||
|
||||
void SCULPT_OT_uv_sculpt_grab(wmOperatorType *ot)
|
||||
{
|
||||
ot->name = "Grab UVs";
|
||||
ot->description = "Grab UVs";
|
||||
ot->idname = "SCULPT_OT_uv_sculpt_grab";
|
||||
|
||||
ot->invoke = uv_sculpt_stroke_invoke;
|
||||
ot->modal = uv_sculpt_stroke_modal;
|
||||
ot->poll = ED_operator_uvedit_space_image;
|
||||
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
register_common_props(ot);
|
||||
}
|
||||
|
||||
void SCULPT_OT_uv_sculpt_relax(wmOperatorType *ot)
|
||||
{
|
||||
ot->name = "Relax UVs";
|
||||
ot->description = "Relax UVs";
|
||||
ot->idname = "SCULPT_OT_uv_sculpt_relax";
|
||||
|
||||
ot->invoke = uv_sculpt_stroke_invoke;
|
||||
ot->modal = uv_sculpt_stroke_modal;
|
||||
ot->poll = ED_operator_uvedit_space_image;
|
||||
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
register_common_props(ot);
|
||||
|
||||
static const EnumPropertyItem relax_method_items[] = {
|
||||
{UV_SCULPT_TOOL_RELAX_LAPLACIAN,
|
||||
"LAPLACIAN",
|
||||
0,
|
||||
"Laplacian",
|
||||
"Use Laplacian method for relaxation"},
|
||||
{UV_SCULPT_TOOL_RELAX_HC, "HC", 0, "HC", "Use HC method for relaxation"},
|
||||
{UV_SCULPT_TOOL_RELAX_COTAN,
|
||||
"COTAN",
|
||||
0,
|
||||
"Geometry",
|
||||
"Use Geometry (cotangent) relaxation, making UVs follow the underlying 3D geometry"},
|
||||
{0, nullptr, 0, nullptr, nullptr},
|
||||
};
|
||||
|
||||
RNA_def_enum(ot->srna,
|
||||
"relax_method",
|
||||
relax_method_items,
|
||||
CURVE_PRESET_SMOOTH,
|
||||
"Relax Method",
|
||||
"Algorithm used for UV relaxation");
|
||||
}
|
||||
|
||||
void SCULPT_OT_uv_sculpt_pinch(wmOperatorType *ot)
|
||||
{
|
||||
ot->name = "Pinch UVs";
|
||||
ot->description = "Pinch UVs";
|
||||
ot->idname = "SCULPT_OT_uv_sculpt_pinch";
|
||||
|
||||
ot->invoke = uv_sculpt_stroke_invoke;
|
||||
ot->modal = uv_sculpt_stroke_modal;
|
||||
ot->poll = ED_operator_uvedit_space_image;
|
||||
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
register_common_props(ot);
|
||||
}
|
||||
|
|
|
@ -909,7 +909,7 @@ static void insert_action_keys(bAnimContext *ac, short mode)
|
|||
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, eAnimCont_Types(ac->datatype));
|
||||
|
||||
/* Init keyframing flag. */
|
||||
flag = ANIM_get_keyframing_flags(scene);
|
||||
flag = blender::animrig::get_keyframing_flags(scene);
|
||||
|
||||
/* GPLayers specific flags */
|
||||
if (ts->gpencil_flags & GP_TOOL_FLAG_RETAIN_LAST) {
|
||||
|
|
|
@ -145,7 +145,7 @@ static void insert_graph_keys(bAnimContext *ac, eGraphKeys_InsertKey_Types mode)
|
|||
}
|
||||
|
||||
/* Init key-framing flag. */
|
||||
eInsertKeyFlags flag = ANIM_get_keyframing_flags(scene);
|
||||
eInsertKeyFlags flag = blender::animrig::get_keyframing_flags(scene);
|
||||
KeyframeSettings settings = get_keyframe_settings(true);
|
||||
settings.keyframe_type = eBezTriple_KeyframeType(ts->keyframe_type);
|
||||
|
||||
|
|
|
@ -331,10 +331,8 @@ bool space_image_main_region_poll(bContext *C)
|
|||
static bool space_image_main_area_not_uv_brush_poll(bContext *C)
|
||||
{
|
||||
SpaceImage *sima = CTX_wm_space_image(C);
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
ToolSettings *toolsettings = scene->toolsettings;
|
||||
|
||||
if (sima && !toolsettings->uvsculpt && (CTX_data_edit_object(C) == nullptr)) {
|
||||
if (sima && (CTX_data_edit_object(C) == nullptr)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
set(INC
|
||||
../include
|
||||
../io
|
||||
../../asset_system
|
||||
../../blenkernel
|
||||
../../blenloader
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "DNA_node_types.h"
|
||||
#include "DNA_texture_types.h"
|
||||
|
||||
#include "BLI_easing.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_math_geom.h"
|
||||
|
||||
|
@ -50,6 +51,9 @@
|
|||
|
||||
#include "UI_view2d.hh"
|
||||
|
||||
#include "io_utils.hh"
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "node_intern.hh" /* own include */
|
||||
|
||||
namespace blender::ed::space_node {
|
||||
|
@ -683,17 +687,58 @@ static bool node_add_file_poll(bContext *C)
|
|||
ELEM(snode->nodetree->type, NTREE_SHADER, NTREE_TEXTURE, NTREE_COMPOSIT, NTREE_GEOMETRY);
|
||||
}
|
||||
|
||||
/** Node stack animation data, sorts nodes so each node is placed on top of each other. */
|
||||
struct NodeStackAnimationData {
|
||||
Vector<bNode *> nodes;
|
||||
wmTimer *anim_timer;
|
||||
};
|
||||
|
||||
static int node_add_file_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
{
|
||||
NodeStackAnimationData *data = static_cast<NodeStackAnimationData *>(op->customdata);
|
||||
|
||||
if (event->type != TIMER || data == nullptr || data->anim_timer != event->customdata) {
|
||||
return OPERATOR_PASS_THROUGH;
|
||||
}
|
||||
|
||||
const float node_stack_anim_duration = 0.25f;
|
||||
const float duration = float(data->anim_timer->time_duration);
|
||||
const float prev_duration = duration - float(data->anim_timer->time_delta);
|
||||
const float clamped_duration = math::min(duration, node_stack_anim_duration);
|
||||
const float delta_factor =
|
||||
BLI_easing_cubic_ease_in_out(clamped_duration, 0.0f, 1.0f, node_stack_anim_duration) -
|
||||
BLI_easing_cubic_ease_in_out(prev_duration, 0.0f, 1.0f, node_stack_anim_duration);
|
||||
|
||||
bool redraw = false;
|
||||
/* Each node is pushed by all previous nodes in the stack. */
|
||||
float stack_offset = 0.0f;
|
||||
|
||||
for (bNode *node : data->nodes) {
|
||||
node->locy -= stack_offset;
|
||||
stack_offset += (node->runtime->totr.ymax - node->runtime->totr.ymin) * delta_factor;
|
||||
redraw = true;
|
||||
}
|
||||
|
||||
if (redraw) {
|
||||
ED_region_tag_redraw(CTX_wm_region(C));
|
||||
}
|
||||
|
||||
/* End stack animation. */
|
||||
if (duration > node_stack_anim_duration) {
|
||||
WM_event_timer_remove(CTX_wm_manager(C), nullptr, data->anim_timer);
|
||||
MEM_delete(data);
|
||||
op->customdata = nullptr;
|
||||
return (OPERATOR_FINISHED | OPERATOR_PASS_THROUGH);
|
||||
}
|
||||
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
||||
static int node_add_file_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Main *bmain = CTX_data_main(C);
|
||||
SpaceNode &snode = *CTX_wm_space_node(C);
|
||||
int type = 0;
|
||||
|
||||
Image *ima = (Image *)WM_operator_drop_load_path(C, op, ID_IM);
|
||||
if (!ima) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
switch (snode.nodetree->type) {
|
||||
case NTREE_SHADER:
|
||||
type = SH_NODE_TEX_IMAGE;
|
||||
|
@ -710,36 +755,82 @@ static int node_add_file_exec(bContext *C, wmOperator *op)
|
|||
default:
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
Vector<Image *> images;
|
||||
/* Load all paths as ID Images. */
|
||||
const Vector<std::string> paths = ed::io::paths_from_operator_properties(op->ptr);
|
||||
for (const std::string &path : paths) {
|
||||
RNA_string_set(op->ptr, "filepath", path.c_str());
|
||||
Image *image = (Image *)WM_operator_drop_load_path(C, op, ID_IM);
|
||||
if (!image) {
|
||||
BKE_report(op->reports, RPT_WARNING, fmt::format("Could not load {}", path).c_str());
|
||||
continue;
|
||||
}
|
||||
images.append(image);
|
||||
/* When adding new image file via drag-drop we need to load #ImBuf in order
|
||||
* to get proper image source. */
|
||||
BKE_image_signal(bmain, image, nullptr, IMA_SIGNAL_RELOAD);
|
||||
WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, image);
|
||||
}
|
||||
|
||||
ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
|
||||
/* If not path is provided, try to get a ID Image from operator. */
|
||||
if (paths.is_empty()) {
|
||||
Image *image = (Image *)WM_operator_drop_load_path(C, op, ID_IM);
|
||||
if (image) {
|
||||
images.append(image);
|
||||
}
|
||||
}
|
||||
|
||||
bNode *node = add_static_node(*C, type, snode.runtime->cursor);
|
||||
float2 position = snode.runtime->cursor;
|
||||
Vector<bNode *> nodes;
|
||||
/* Add a node for each image. */
|
||||
for (Image *image : images) {
|
||||
bNode *node = add_static_node(*C, type, position);
|
||||
if (!node) {
|
||||
BKE_report(op->reports, RPT_WARNING, "Could not add an image node");
|
||||
continue;
|
||||
}
|
||||
if (type == GEO_NODE_IMAGE_TEXTURE) {
|
||||
bNodeSocket *image_socket = (bNodeSocket *)node->inputs.first;
|
||||
bNodeSocketValueImage *socket_value = (bNodeSocketValueImage *)image_socket->default_value;
|
||||
socket_value->value = image;
|
||||
}
|
||||
else {
|
||||
node->id = (ID *)image;
|
||||
}
|
||||
nodes.append(node);
|
||||
/* Initial offset between nodes. */
|
||||
position[1] -= 20.0f;
|
||||
}
|
||||
|
||||
if (!node) {
|
||||
BKE_report(op->reports, RPT_WARNING, "Could not add an image node");
|
||||
if (nodes.is_empty()) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
if (type == GEO_NODE_IMAGE_TEXTURE) {
|
||||
bNodeSocket *image_socket = (bNodeSocket *)node->inputs.first;
|
||||
bNodeSocketValueImage *socket_value = (bNodeSocketValueImage *)image_socket->default_value;
|
||||
socket_value->value = ima;
|
||||
}
|
||||
else {
|
||||
node->id = (ID *)ima;
|
||||
/* Set new nodes as selected. */
|
||||
bNodeTree &node_tree = *snode.edittree;
|
||||
node_deselect_all(node_tree);
|
||||
for (bNode *node : nodes) {
|
||||
nodeSetSelected(node, true);
|
||||
}
|
||||
ED_node_set_active(bmain, &snode, &node_tree, nodes[0], nullptr);
|
||||
|
||||
/* When adding new image file via drag-drop we need to load #ImBuf in order
|
||||
* to get proper image source. */
|
||||
if (RNA_struct_property_is_set(op->ptr, "filepath")) {
|
||||
BKE_image_signal(bmain, ima, nullptr, IMA_SIGNAL_RELOAD);
|
||||
WM_event_add_notifier(C, NC_IMAGE | NA_EDITED, ima);
|
||||
}
|
||||
ED_preview_kill_jobs(CTX_wm_manager(C), CTX_data_main(C));
|
||||
|
||||
ED_node_tree_propagate_change(C, bmain, snode.edittree);
|
||||
DEG_relations_tag_update(bmain);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
if (nodes.size() == 1) {
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
/* Start the stack animation, so each node is placed on top of each other. */
|
||||
NodeStackAnimationData *data = MEM_new<NodeStackAnimationData>(__func__);
|
||||
data->nodes = std::move(nodes);
|
||||
data->anim_timer = WM_event_timer_add(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.02);
|
||||
op->customdata = data;
|
||||
WM_event_add_modal_handler(C, op);
|
||||
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
||||
static int node_add_file_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
|
@ -774,6 +865,7 @@ void NODE_OT_add_file(wmOperatorType *ot)
|
|||
|
||||
/* callbacks */
|
||||
ot->exec = node_add_file_exec;
|
||||
ot->modal = node_add_file_modal;
|
||||
ot->invoke = node_add_file_invoke;
|
||||
ot->poll = node_add_file_poll;
|
||||
|
||||
|
@ -784,7 +876,8 @@ void NODE_OT_add_file(wmOperatorType *ot)
|
|||
FILE_TYPE_FOLDER | FILE_TYPE_IMAGE | FILE_TYPE_MOVIE,
|
||||
FILE_SPECIAL,
|
||||
FILE_OPENFILE,
|
||||
WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH,
|
||||
WM_FILESEL_FILEPATH | WM_FILESEL_RELPATH | WM_FILESEL_DIRECTORY |
|
||||
WM_FILESEL_FILES,
|
||||
FILE_DEFAULTDISPLAY,
|
||||
FILE_SORT_DEFAULT);
|
||||
WM_operator_properties_id_lookup(ot, true);
|
||||
|
|
|
@ -3424,7 +3424,8 @@ static void node_draw_basis(const bContext &C,
|
|||
nullptr,
|
||||
0,
|
||||
0,
|
||||
"");
|
||||
TIP_(node.typeinfo->ui_description));
|
||||
|
||||
if (node.flag & NODE_MUTED) {
|
||||
UI_but_flag_enable(but, UI_BUT_INACTIVE);
|
||||
}
|
||||
|
@ -3661,7 +3662,7 @@ static void node_draw_hidden(const bContext &C,
|
|||
nullptr,
|
||||
0,
|
||||
0,
|
||||
"");
|
||||
TIP_(node.typeinfo->ui_description));
|
||||
|
||||
/* Outline. */
|
||||
{
|
||||
|
|
|
@ -879,13 +879,8 @@ static bool node_collection_drop_poll(bContext *C, wmDrag *drag, const wmEvent *
|
|||
return WM_drag_is_ID_type(drag, ID_GR) && !UI_but_active_drop_name(C);
|
||||
}
|
||||
|
||||
static bool node_ima_drop_poll(bContext * /*C*/, wmDrag *drag, const wmEvent * /*event*/)
|
||||
static bool node_id_im_drop_poll(bContext * /*C*/, wmDrag *drag, const wmEvent * /*event*/)
|
||||
{
|
||||
if (drag->type == WM_DRAG_PATH) {
|
||||
const eFileSel_File_Types file_type = static_cast<eFileSel_File_Types>(
|
||||
WM_drag_get_path_file_type(drag));
|
||||
return ELEM(file_type, FILE_TYPE_IMAGE, FILE_TYPE_MOVIE);
|
||||
}
|
||||
return WM_drag_is_ID_type(drag, ID_IM);
|
||||
}
|
||||
|
||||
|
@ -915,22 +910,14 @@ static void node_id_drop_copy(bContext *C, wmDrag *drag, wmDropBox *drop)
|
|||
RNA_int_set(drop->ptr, "session_uid", int(id->session_uid));
|
||||
}
|
||||
|
||||
static void node_id_path_drop_copy(bContext *C, wmDrag *drag, wmDropBox *drop)
|
||||
static void node_id_im_drop_copy(bContext *C, wmDrag *drag, wmDropBox *drop)
|
||||
{
|
||||
ID *id = WM_drag_get_local_ID_or_import_from_asset(C, drag, 0);
|
||||
|
||||
if (id) {
|
||||
RNA_int_set(drop->ptr, "session_uid", int(id->session_uid));
|
||||
RNA_struct_property_unset(drop->ptr, "filepath");
|
||||
return;
|
||||
}
|
||||
|
||||
const char *path = WM_drag_get_single_path(drag);
|
||||
if (path) {
|
||||
RNA_string_set(drop->ptr, "filepath", path);
|
||||
RNA_struct_property_unset(drop->ptr, "name");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* this region dropbox definition */
|
||||
|
@ -958,8 +945,8 @@ static void node_dropboxes()
|
|||
nullptr);
|
||||
WM_dropbox_add(lb,
|
||||
"NODE_OT_add_file",
|
||||
node_ima_drop_poll,
|
||||
node_id_path_drop_copy,
|
||||
node_id_im_drop_poll,
|
||||
node_id_im_drop_copy,
|
||||
WM_drag_free_imported_drag_ID,
|
||||
nullptr);
|
||||
WM_dropbox_add(lb,
|
||||
|
|
|
@ -784,7 +784,9 @@ static void sort_time_beztmaps(const blender::MutableSpan<BeztMap> bezms)
|
|||
}
|
||||
|
||||
/* This function firstly adjusts the pointers that the transdata has to each BezTriple. */
|
||||
static void beztmap_to_data(TransInfo *t, FCurve *fcu, const blender::Span<BeztMap> bezms)
|
||||
static void update_transdata_bezt_pointers(TransInfo *t,
|
||||
FCurve *fcu,
|
||||
const blender::Span<BeztMap> bezms)
|
||||
{
|
||||
TransData2D *td2d;
|
||||
TransData *td;
|
||||
|
@ -882,7 +884,7 @@ static void remake_graph_transdata(TransInfo *t, const blender::Span<FCurve *> f
|
|||
/* NOTE: none of these functions use 'use_handle', it could be removed. */
|
||||
blender::Vector<BeztMap> bezms = bezt_to_beztmaps(fcu->bezt, fcu->totvert);
|
||||
sort_time_beztmaps(bezms);
|
||||
beztmap_to_data(t, fcu, bezms);
|
||||
update_transdata_bezt_pointers(t, fcu, bezms);
|
||||
|
||||
/* Re-sort actual beztriples
|
||||
* (perhaps this could be done using the beztmaps to save time?). */
|
||||
|
|
|
@ -2430,6 +2430,25 @@ mat4 MAT4x4(mat3x4 m)
|
|||
{
|
||||
return mat4(m[0], m[1], m[2], vec4(0.0, 0.0, 0.0, 1.0));
|
||||
}
|
||||
mat4 MAT4x4(mat4x3 m)
|
||||
{
|
||||
return mat4(m[0][0],
|
||||
m[0][1],
|
||||
m[0][2],
|
||||
0.0,
|
||||
m[1][0],
|
||||
m[1][1],
|
||||
m[1][2],
|
||||
0.0,
|
||||
m[2][0],
|
||||
m[2][1],
|
||||
m[2][2],
|
||||
0.0,
|
||||
m[3][0],
|
||||
m[3][1],
|
||||
m[3][2],
|
||||
0.0);
|
||||
}
|
||||
mat4 MAT4x4(mat2 m)
|
||||
{
|
||||
return mat4(vec4(m[0].xy, 0.0, 0.0),
|
||||
|
|
|
@ -35,43 +35,32 @@ class CommandBufferLog : public VKCommandBufferInterface {
|
|||
|
||||
void begin_recording() override
|
||||
{
|
||||
BLI_assert_msg(!is_recording_,
|
||||
"`CommandBufferLog::begin_recording` is called, when the command buffer is "
|
||||
"already recording.");
|
||||
EXPECT_FALSE(is_recording_);
|
||||
is_recording_ = true;
|
||||
}
|
||||
|
||||
void end_recording() override
|
||||
{
|
||||
BLI_assert_msg(is_recording_,
|
||||
"`CommandBufferLog::end_recording` is called, when the command buffer is "
|
||||
"not recording.");
|
||||
EXPECT_TRUE(is_recording_);
|
||||
is_recording_ = false;
|
||||
}
|
||||
|
||||
void submit_with_cpu_synchronization() override
|
||||
{
|
||||
BLI_assert_msg(!is_recording_, "`CommandBufferLog` is submitted when still recording.");
|
||||
BLI_assert_msg(!is_cpu_synchronizing_,
|
||||
"`CommandBufferLog::submit_with_cpu_synchronization` is called, when the "
|
||||
"command buffer is "
|
||||
"still synchronizing.");
|
||||
EXPECT_FALSE(is_recording_);
|
||||
EXPECT_FALSE(is_cpu_synchronizing_);
|
||||
is_cpu_synchronizing_ = true;
|
||||
};
|
||||
void wait_for_cpu_synchronization() override
|
||||
{
|
||||
BLI_assert_msg(!is_recording_, "`CommandBufferLog` is synchronizing when still recording.");
|
||||
BLI_assert_msg(
|
||||
is_cpu_synchronizing_,
|
||||
"`CommandBufferLog::wait_for_cpu_synchronization` is called, when the command buffer is "
|
||||
"not synchronizing.");
|
||||
EXPECT_FALSE(is_recording_);
|
||||
EXPECT_TRUE(is_cpu_synchronizing_);
|
||||
is_cpu_synchronizing_ = false;
|
||||
};
|
||||
|
||||
void bind_pipeline(VkPipelineBindPoint pipeline_bind_point, VkPipeline pipeline) override
|
||||
{
|
||||
BLI_assert_msg(is_recording_,
|
||||
"Command is added to command buffer, which isn't in recording state.");
|
||||
EXPECT_TRUE(is_recording_);
|
||||
std::stringstream ss;
|
||||
ss << "bind_pipeline(";
|
||||
ss << "pipeline_bind_point=" << to_string(pipeline_bind_point);
|
||||
|
@ -95,8 +84,7 @@ class CommandBufferLog : public VKCommandBufferInterface {
|
|||
p_descriptor_sets,
|
||||
dynamic_offset_count,
|
||||
p_dynamic_offsets);
|
||||
BLI_assert_msg(is_recording_,
|
||||
"Command is added to command buffer, which isn't in recording state.");
|
||||
EXPECT_TRUE(is_recording_);
|
||||
std::stringstream ss;
|
||||
ss << "bind_descriptor_sets(";
|
||||
ss << "pipeline_bind_point=" << to_string(pipeline_bind_point);
|
||||
|
@ -109,9 +97,8 @@ class CommandBufferLog : public VKCommandBufferInterface {
|
|||
void bind_index_buffer(VkBuffer buffer, VkDeviceSize offset, VkIndexType index_type) override
|
||||
{
|
||||
UNUSED_VARS(buffer, offset, index_type);
|
||||
BLI_assert_msg(is_recording_,
|
||||
"Command is added to command buffer, which isn't in recording state.");
|
||||
BLI_assert_unreachable();
|
||||
EXPECT_TRUE(is_recording_);
|
||||
GTEST_FAIL() << __func__ << " not implemented!";
|
||||
}
|
||||
|
||||
void bind_vertex_buffers(uint32_t first_binding,
|
||||
|
@ -120,9 +107,8 @@ class CommandBufferLog : public VKCommandBufferInterface {
|
|||
const VkDeviceSize *p_offsets) override
|
||||
{
|
||||
UNUSED_VARS(first_binding, binding_count, p_buffers, p_offsets);
|
||||
BLI_assert_msg(is_recording_,
|
||||
"Command is added to command buffer, which isn't in recording state.");
|
||||
BLI_assert_unreachable();
|
||||
EXPECT_TRUE(is_recording_);
|
||||
GTEST_FAIL() << __func__ << " not implemented!";
|
||||
}
|
||||
|
||||
void draw(uint32_t vertex_count,
|
||||
|
@ -131,9 +117,8 @@ class CommandBufferLog : public VKCommandBufferInterface {
|
|||
uint32_t first_instance) override
|
||||
{
|
||||
UNUSED_VARS(vertex_count, instance_count, first_vertex, first_instance);
|
||||
BLI_assert_msg(is_recording_,
|
||||
"Command is added to command buffer, which isn't in recording state.");
|
||||
BLI_assert_unreachable();
|
||||
EXPECT_TRUE(is_recording_);
|
||||
GTEST_FAIL() << __func__ << " not implemented!";
|
||||
}
|
||||
|
||||
void draw_indexed(uint32_t index_count,
|
||||
|
@ -143,9 +128,8 @@ class CommandBufferLog : public VKCommandBufferInterface {
|
|||
uint32_t first_instance) override
|
||||
{
|
||||
UNUSED_VARS(index_count, instance_count, first_index, vertex_offset, first_instance);
|
||||
BLI_assert_msg(is_recording_,
|
||||
"Command is added to command buffer, which isn't in recording state.");
|
||||
BLI_assert_unreachable();
|
||||
EXPECT_TRUE(is_recording_);
|
||||
GTEST_FAIL() << __func__ << " not implemented!";
|
||||
}
|
||||
|
||||
void draw_indirect(VkBuffer buffer,
|
||||
|
@ -154,9 +138,8 @@ class CommandBufferLog : public VKCommandBufferInterface {
|
|||
uint32_t stride) override
|
||||
{
|
||||
UNUSED_VARS(buffer, offset, draw_count, stride);
|
||||
BLI_assert_msg(is_recording_,
|
||||
"Command is added to command buffer, which isn't in recording state.");
|
||||
BLI_assert_unreachable();
|
||||
EXPECT_TRUE(is_recording_);
|
||||
GTEST_FAIL() << __func__ << " not implemented!";
|
||||
}
|
||||
|
||||
void draw_indexed_indirect(VkBuffer buffer,
|
||||
|
@ -165,16 +148,14 @@ class CommandBufferLog : public VKCommandBufferInterface {
|
|||
uint32_t stride) override
|
||||
{
|
||||
UNUSED_VARS(buffer, offset, draw_count, stride);
|
||||
BLI_assert_msg(is_recording_,
|
||||
"Command is added to command buffer, which isn't in recording state.");
|
||||
BLI_assert_unreachable();
|
||||
EXPECT_TRUE(is_recording_);
|
||||
GTEST_FAIL() << __func__ << " not implemented!";
|
||||
}
|
||||
|
||||
void dispatch(uint32_t group_count_x, uint32_t group_count_y, uint32_t group_count_z) override
|
||||
{
|
||||
UNUSED_VARS(group_count_x, group_count_y, group_count_z);
|
||||
BLI_assert_msg(is_recording_,
|
||||
"Command is added to command buffer, which isn't in recording state.");
|
||||
EXPECT_TRUE(is_recording_);
|
||||
std::stringstream ss;
|
||||
ss << "dispatch(";
|
||||
ss << "group_count_x=" << group_count_x;
|
||||
|
@ -186,8 +167,7 @@ class CommandBufferLog : public VKCommandBufferInterface {
|
|||
|
||||
void dispatch_indirect(VkBuffer buffer, VkDeviceSize offset) override
|
||||
{
|
||||
BLI_assert_msg(is_recording_,
|
||||
"Command is added to command buffer, which isn't in recording state.");
|
||||
EXPECT_TRUE(is_recording_);
|
||||
std::stringstream ss;
|
||||
ss << "dispatch_indirect(";
|
||||
ss << "buffer=" << to_string(buffer);
|
||||
|
@ -201,8 +181,7 @@ class CommandBufferLog : public VKCommandBufferInterface {
|
|||
uint32_t region_count,
|
||||
const VkBufferCopy *p_regions) override
|
||||
{
|
||||
BLI_assert_msg(is_recording_,
|
||||
"Command is added to command buffer, which isn't in recording state.");
|
||||
EXPECT_TRUE(is_recording_);
|
||||
std::stringstream ss;
|
||||
ss << "copy_buffer(";
|
||||
ss << "src_buffer=" << to_string(src_buffer);
|
||||
|
@ -222,8 +201,7 @@ class CommandBufferLog : public VKCommandBufferInterface {
|
|||
uint32_t region_count,
|
||||
const VkImageCopy *p_regions) override
|
||||
{
|
||||
BLI_assert_msg(is_recording_,
|
||||
"Command is added to command buffer, which isn't in recording state.");
|
||||
EXPECT_TRUE(is_recording_);
|
||||
std::stringstream ss;
|
||||
ss << "copy_image(";
|
||||
ss << "src_image=" << to_string(src_image);
|
||||
|
@ -246,8 +224,7 @@ class CommandBufferLog : public VKCommandBufferInterface {
|
|||
const VkImageBlit *p_regions,
|
||||
VkFilter filter) override
|
||||
{
|
||||
BLI_assert_msg(is_recording_,
|
||||
"Command is added to command buffer, which isn't in recording state.");
|
||||
EXPECT_TRUE(is_recording_);
|
||||
std::stringstream ss;
|
||||
ss << "blit_image(";
|
||||
ss << "src_image=" << to_string(src_image);
|
||||
|
@ -269,8 +246,7 @@ class CommandBufferLog : public VKCommandBufferInterface {
|
|||
uint32_t region_count,
|
||||
const VkBufferImageCopy *p_regions) override
|
||||
{
|
||||
BLI_assert_msg(is_recording_,
|
||||
"Command is added to command buffer, which isn't in recording state.");
|
||||
EXPECT_TRUE(is_recording_);
|
||||
std::stringstream ss;
|
||||
ss << "copy_buffer_to_image(";
|
||||
ss << "src_buffer=" << to_string(src_buffer);
|
||||
|
@ -291,8 +267,7 @@ class CommandBufferLog : public VKCommandBufferInterface {
|
|||
uint32_t region_count,
|
||||
const VkBufferImageCopy *p_regions) override
|
||||
{
|
||||
BLI_assert_msg(is_recording_,
|
||||
"Command is added to command buffer, which isn't in recording state.");
|
||||
EXPECT_TRUE(is_recording_);
|
||||
std::stringstream ss;
|
||||
ss << "copy_image_to_buffer(";
|
||||
ss << "src_image=" << to_string(src_image);
|
||||
|
@ -312,8 +287,7 @@ class CommandBufferLog : public VKCommandBufferInterface {
|
|||
VkDeviceSize size,
|
||||
uint32_t data) override
|
||||
{
|
||||
BLI_assert_msg(is_recording_,
|
||||
"Command is added to command buffer, which isn't in recording state.");
|
||||
EXPECT_TRUE(is_recording_);
|
||||
std::stringstream ss;
|
||||
ss << "fill_buffer(";
|
||||
ss << "dst_buffer=" << to_string(dst_buffer);
|
||||
|
@ -331,8 +305,7 @@ class CommandBufferLog : public VKCommandBufferInterface {
|
|||
const VkImageSubresourceRange *p_ranges) override
|
||||
{
|
||||
UNUSED_VARS(p_color, range_count, p_ranges);
|
||||
BLI_assert_msg(is_recording_,
|
||||
"Command is added to command buffer, which isn't in recording state.");
|
||||
EXPECT_TRUE(is_recording_);
|
||||
std::stringstream ss;
|
||||
ss << "clear_color_image(";
|
||||
ss << "image=" << to_string(image);
|
||||
|
@ -348,9 +321,8 @@ class CommandBufferLog : public VKCommandBufferInterface {
|
|||
const VkImageSubresourceRange *p_ranges) override
|
||||
{
|
||||
UNUSED_VARS(image, image_layout, p_depth_stencil, range_count, p_ranges);
|
||||
BLI_assert_msg(is_recording_,
|
||||
"Command is added to command buffer, which isn't in recording state.");
|
||||
BLI_assert_unreachable();
|
||||
EXPECT_TRUE(is_recording_);
|
||||
GTEST_FAIL() << __func__ << " not implemented!";
|
||||
}
|
||||
|
||||
void clear_attachments(uint32_t attachment_count,
|
||||
|
@ -359,9 +331,8 @@ class CommandBufferLog : public VKCommandBufferInterface {
|
|||
const VkClearRect *p_rects) override
|
||||
{
|
||||
UNUSED_VARS(attachment_count, p_attachments, rect_count, p_rects);
|
||||
BLI_assert_msg(is_recording_,
|
||||
"Command is added to command buffer, which isn't in recording state.");
|
||||
BLI_assert_unreachable();
|
||||
EXPECT_TRUE(is_recording_);
|
||||
GTEST_FAIL() << __func__ << " not implemented!";
|
||||
}
|
||||
|
||||
void pipeline_barrier(VkPipelineStageFlags src_stage_mask,
|
||||
|
@ -375,8 +346,7 @@ class CommandBufferLog : public VKCommandBufferInterface {
|
|||
const VkImageMemoryBarrier *p_image_memory_barriers) override
|
||||
{
|
||||
UNUSED_VARS(dependency_flags, memory_barrier_count, p_memory_barriers);
|
||||
BLI_assert_msg(is_recording_,
|
||||
"Command is added to command buffer, which isn't in recording state.");
|
||||
EXPECT_TRUE(is_recording_);
|
||||
std::stringstream ss;
|
||||
ss << "pipeline_barrier(";
|
||||
ss << "src_stage_mask=" << to_string_vk_pipeline_stage_flags(src_stage_mask);
|
||||
|
@ -404,25 +374,22 @@ class CommandBufferLog : public VKCommandBufferInterface {
|
|||
const void *p_values) override
|
||||
{
|
||||
UNUSED_VARS(layout, stage_flags, offset, size, p_values);
|
||||
BLI_assert_msg(is_recording_,
|
||||
"Command is added to command buffer, which isn't in recording state.");
|
||||
BLI_assert_unreachable();
|
||||
EXPECT_TRUE(is_recording_);
|
||||
GTEST_FAIL() << __func__ << " not implemented!";
|
||||
}
|
||||
|
||||
void begin_render_pass(const VkRenderPassBeginInfo *p_render_pass_begin,
|
||||
VkSubpassContents contents) override
|
||||
{
|
||||
UNUSED_VARS(p_render_pass_begin, contents);
|
||||
BLI_assert_msg(is_recording_,
|
||||
"Command is added to command buffer, which isn't in recording state.");
|
||||
BLI_assert_unreachable();
|
||||
EXPECT_TRUE(is_recording_);
|
||||
GTEST_FAIL() << __func__ << " not implemented!";
|
||||
}
|
||||
|
||||
void end_render_pass() override
|
||||
{
|
||||
BLI_assert_msg(is_recording_,
|
||||
"Command is added to command buffer, which isn't in recording state.");
|
||||
BLI_assert_unreachable();
|
||||
EXPECT_TRUE(is_recording_);
|
||||
GTEST_FAIL() << __func__ << " not implemented!";
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -55,6 +55,43 @@ std::string to_string(VkDescriptorSet vk_handle)
|
|||
return to_string_handle(uint64_t(vk_handle));
|
||||
}
|
||||
|
||||
const char *to_string(const VkAttachmentLoadOp vk_attachment_load_op)
|
||||
{
|
||||
switch (vk_attachment_load_op) {
|
||||
case VK_ATTACHMENT_LOAD_OP_LOAD:
|
||||
return STRINGIFY(VK_ATTACHMENT_LOAD_OP_LOAD);
|
||||
|
||||
case VK_ATTACHMENT_LOAD_OP_CLEAR:
|
||||
return STRINGIFY(VK_ATTACHMENT_LOAD_OP_CLEAR);
|
||||
|
||||
case VK_ATTACHMENT_LOAD_OP_DONT_CARE:
|
||||
return STRINGIFY(VK_ATTACHMENT_LOAD_OP_DONT_CARE);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return STRINGIFY_ARG(vk_attachment_load_op);
|
||||
}
|
||||
|
||||
const char *to_string(const VkAttachmentStoreOp vk_attachment_store_op)
|
||||
{
|
||||
switch (vk_attachment_store_op) {
|
||||
case VK_ATTACHMENT_STORE_OP_STORE:
|
||||
return STRINGIFY(VK_ATTACHMENT_STORE_OP_STORE);
|
||||
|
||||
case VK_ATTACHMENT_STORE_OP_DONT_CARE:
|
||||
return STRINGIFY(VK_ATTACHMENT_STORE_OP_DONT_CARE);
|
||||
|
||||
/* Extensions for VK_KHR_dynamic_rendering. */
|
||||
case VK_ATTACHMENT_STORE_OP_NONE_KHR:
|
||||
return STRINGIFY(VK_ATTACHMENT_STORE_OP_NONE_KHR);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return STRINGIFY_ARG(vk_attachment_store_op);
|
||||
}
|
||||
|
||||
const char *to_string(const VkFilter vk_filter)
|
||||
{
|
||||
switch (vk_filter) {
|
||||
|
@ -258,6 +295,30 @@ const char *to_string(const VkPipelineBindPoint vk_pipeline_bind_point)
|
|||
return STRINGIFY_ARG(vk_pipeline_bind_point);
|
||||
}
|
||||
|
||||
const char *to_string(const VkResolveModeFlagBits vk_resolve_mode_flag_bits)
|
||||
{
|
||||
switch (vk_resolve_mode_flag_bits) {
|
||||
case VK_RESOLVE_MODE_NONE:
|
||||
return STRINGIFY(VK_RESOLVE_MODE_NONE);
|
||||
|
||||
case VK_RESOLVE_MODE_SAMPLE_ZERO_BIT:
|
||||
return STRINGIFY(VK_RESOLVE_MODE_SAMPLE_ZERO_BIT);
|
||||
|
||||
case VK_RESOLVE_MODE_AVERAGE_BIT:
|
||||
return STRINGIFY(VK_RESOLVE_MODE_AVERAGE_BIT);
|
||||
|
||||
case VK_RESOLVE_MODE_MIN_BIT:
|
||||
return STRINGIFY(VK_RESOLVE_MODE_MIN_BIT);
|
||||
|
||||
case VK_RESOLVE_MODE_MAX_BIT:
|
||||
return STRINGIFY(VK_RESOLVE_MODE_MAX_BIT);
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return STRINGIFY_ARG(vk_resolve_mode_flag_bits);
|
||||
}
|
||||
|
||||
const char *to_string(const VkSubpassContents vk_subpass_contents)
|
||||
{
|
||||
switch (vk_subpass_contents) {
|
||||
|
@ -455,6 +516,36 @@ std::string to_string_vk_pipeline_stage_flags(const VkPipelineStageFlags vk_pipe
|
|||
return result;
|
||||
}
|
||||
|
||||
std::string to_string_vk_rendering_flags(const VkRenderingFlags vk_rendering_flags)
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
||||
if (vk_rendering_flags & VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT) {
|
||||
ss << STRINGIFY(VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT) << ", ";
|
||||
}
|
||||
if (vk_rendering_flags & VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT_KHR) {
|
||||
ss << STRINGIFY(VK_RENDERING_CONTENTS_SECONDARY_COMMAND_BUFFERS_BIT_KHR) << ", ";
|
||||
}
|
||||
if (vk_rendering_flags & VK_RENDERING_SUSPENDING_BIT) {
|
||||
ss << STRINGIFY(VK_RENDERING_SUSPENDING_BIT) << ", ";
|
||||
}
|
||||
if (vk_rendering_flags & VK_RENDERING_SUSPENDING_BIT_KHR) {
|
||||
ss << STRINGIFY(VK_RENDERING_SUSPENDING_BIT_KHR) << ", ";
|
||||
}
|
||||
if (vk_rendering_flags & VK_RENDERING_RESUMING_BIT) {
|
||||
ss << STRINGIFY(VK_RENDERING_RESUMING_BIT) << ", ";
|
||||
}
|
||||
if (vk_rendering_flags & VK_RENDERING_RESUMING_BIT_KHR) {
|
||||
ss << STRINGIFY(VK_RENDERING_RESUMING_BIT_KHR) << ", ";
|
||||
}
|
||||
|
||||
std::string result = ss.str();
|
||||
if (result.size() >= 2) {
|
||||
result.erase(result.size() - 2, 2);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string to_string_vk_shader_stage_flags(const VkShaderStageFlags vk_shader_stage_flags)
|
||||
{
|
||||
std::stringstream ss;
|
||||
|
@ -739,4 +830,56 @@ std::string to_string(const VkRenderPassBeginInfo &vk_render_pass_begin_info,
|
|||
return ss.str();
|
||||
}
|
||||
|
||||
std::string to_string(const VkRenderingAttachmentInfo &vk_rendering_attachment_info,
|
||||
int indentation_level)
|
||||
{
|
||||
UNUSED_VARS(indentation_level);
|
||||
std::stringstream ss;
|
||||
ss << "image_view=" << vk_rendering_attachment_info.imageView;
|
||||
ss << ", image_layout=" << to_string(vk_rendering_attachment_info.imageLayout);
|
||||
ss << ", resolve_mode=" << to_string(vk_rendering_attachment_info.resolveMode);
|
||||
ss << ", resolve_image_view=" << vk_rendering_attachment_info.resolveImageView;
|
||||
ss << ", resolve_image_layout=" << to_string(vk_rendering_attachment_info.resolveImageLayout);
|
||||
ss << ", load_op=" << to_string(vk_rendering_attachment_info.loadOp);
|
||||
ss << ", store_op=" << to_string(vk_rendering_attachment_info.storeOp);
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
std::string to_string(const VkRenderingInfo &vk_rendering_info, int indentation_level)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "flags=" << to_string_vk_rendering_flags(vk_rendering_info.flags);
|
||||
ss << ", render_area=" << std::endl;
|
||||
ss << std::string(indentation_level * 2 + 2, ' ')
|
||||
<< to_string(vk_rendering_info.renderArea, indentation_level + 1);
|
||||
ss << std::string(indentation_level * 2, ' ');
|
||||
ss << ", layer_count=" << vk_rendering_info.layerCount;
|
||||
ss << ", view_mask=" << vk_rendering_info.viewMask;
|
||||
ss << ", color_attachment_count=" << vk_rendering_info.colorAttachmentCount;
|
||||
ss << ", p_color_attachments=" << std::endl;
|
||||
for (const VkRenderingAttachmentInfo &vk_rendering_attachment : Span<VkRenderingAttachmentInfo>(
|
||||
vk_rendering_info.pColorAttachments, vk_rendering_info.colorAttachmentCount))
|
||||
{
|
||||
ss << std::string(indentation_level * 2 + 2, ' ')
|
||||
<< to_string(vk_rendering_attachment, indentation_level + 1) << std::endl;
|
||||
}
|
||||
if (vk_rendering_info.pDepthAttachment != nullptr) {
|
||||
ss << std::string(indentation_level * 2, ' ');
|
||||
ss << ", p_depth_attachment=" << std::endl;
|
||||
ss << std::string(indentation_level * 2 + 2, ' ')
|
||||
<< to_string(*vk_rendering_info.pDepthAttachment, indentation_level + 1);
|
||||
ss << std::endl;
|
||||
}
|
||||
if (vk_rendering_info.pStencilAttachment != nullptr) {
|
||||
ss << std::string(indentation_level * 2, ' ');
|
||||
ss << ", p_stencil_attachment=" << std::endl;
|
||||
ss << std::string(indentation_level * 2 + 2, ' ')
|
||||
<< to_string(*vk_rendering_info.pStencilAttachment, indentation_level + 1);
|
||||
ss << std::endl;
|
||||
}
|
||||
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
} // namespace blender::gpu
|
||||
|
|
|
@ -19,16 +19,20 @@ std::string to_string(VkPipelineLayout vk_handle);
|
|||
std::string to_string(VkRenderPass vk_handle);
|
||||
std::string to_string(VkFramebuffer vk_handle);
|
||||
|
||||
const char *to_string(VkAttachmentLoadOp vk_attachment_load_op);
|
||||
const char *to_string(VkAttachmentStoreOp vk_attachment_store_op);
|
||||
const char *to_string(VkFilter vk_filter);
|
||||
const char *to_string(VkImageLayout vk_image_layout);
|
||||
const char *to_string(VkIndexType vk_index_type);
|
||||
const char *to_string(VkObjectType vk_object_type);
|
||||
const char *to_string(VkPipelineBindPoint vk_pipeline_bind_point);
|
||||
const char *to_string(VkResolveModeFlagBits vk_resolve_mode_flag_bits);
|
||||
const char *to_string(VkSubpassContents vk_subpass_contents);
|
||||
std::string to_string_vk_access_flags(VkAccessFlags vk_access_flags);
|
||||
std::string to_string_vk_dependency_flags(VkDependencyFlags vk_dependency_flags);
|
||||
std::string to_string_vk_image_aspect_flags(VkImageAspectFlags vk_image_aspect_flags);
|
||||
std::string to_string_vk_pipeline_stage_flags(VkPipelineStageFlags vk_pipeline_stage_flags);
|
||||
std::string to_string_vk_rendering_flags(VkRenderingFlags vk_rendering_flags);
|
||||
std::string to_string_vk_shader_stage_flags(VkShaderStageFlags vk_shader_stage_flags);
|
||||
std::string to_string(const VkBufferCopy &vk_buffer_copy, int indentation_level = 0);
|
||||
std::string to_string(const VkBufferImageCopy &vk_buffer_image_copy, int indentation_level = 0);
|
||||
|
@ -54,4 +58,8 @@ std::string to_string(const VkOffset3D &vk_offset3_d, int indentation_level = 0)
|
|||
std::string to_string(const VkRect2D &vk_rect2_d, int indentation_level = 0);
|
||||
std::string to_string(const VkRenderPassBeginInfo &vk_render_pass_begin_info,
|
||||
int indentation_level = 0);
|
||||
std::string to_string(const VkRenderingAttachmentInfo &vk_rendering_attachment_info,
|
||||
int indentation_level = 0);
|
||||
std::string to_string(const VkRenderingInfo &vk_rendering_info, int indentation_level = 0);
|
||||
|
||||
} // namespace blender::gpu
|
||||
|
|
|
@ -36,6 +36,7 @@ FEATURES = [
|
|||
# List of extensions blender uses. These can extend enum flags.
|
||||
EXTENSIONS = [
|
||||
"VK_KHR_swapchain",
|
||||
"VK_KHR_dynamic_rendering",
|
||||
]
|
||||
|
||||
# List of vkCmd commands blender uses.
|
||||
|
@ -58,8 +59,8 @@ COMMANDS_TO_GEN = [
|
|||
"vkCmdBindVertexBuffers",
|
||||
"vkCmdBindPipeline",
|
||||
|
||||
"vkCmdBeginRenderPass",
|
||||
"vkCmdEndRenderPass",
|
||||
"vkCmdBeginRendering",
|
||||
"vkCmdEndRendering",
|
||||
"vkCmdDraw",
|
||||
"vkCmdDrawIndexed",
|
||||
"vkCmdDrawIndirect",
|
||||
|
|
|
@ -483,13 +483,6 @@ typedef enum eBrushSculptTool {
|
|||
SCULPT_TOOL_DISPLACEMENT_SMEAR = 32,
|
||||
} eBrushSculptTool;
|
||||
|
||||
/** #Brush.uv_sculpt_tool */
|
||||
typedef enum eBrushUVSculptTool {
|
||||
UV_SCULPT_TOOL_GRAB = 0,
|
||||
UV_SCULPT_TOOL_RELAX = 1,
|
||||
UV_SCULPT_TOOL_PINCH = 2,
|
||||
} eBrushUVSculptTool;
|
||||
|
||||
/* Brush.curves_sculpt_tool. */
|
||||
typedef enum eBrushCurvesSculptTool {
|
||||
CURVES_SCULPT_TOOL_COMB = 0,
|
||||
|
|
|
@ -273,8 +273,6 @@ typedef struct Brush {
|
|||
|
||||
/** Active sculpt tool. */
|
||||
char sculpt_tool;
|
||||
/** Active sculpt tool. */
|
||||
char uv_sculpt_tool;
|
||||
/** Active vertex paint. */
|
||||
char vertexpaint_tool;
|
||||
/** Active weight paint. */
|
||||
|
@ -293,7 +291,7 @@ typedef struct Brush {
|
|||
char gpencil_weight_tool;
|
||||
/** Active curves sculpt tool (#eBrushCurvesSculptTool). */
|
||||
char curves_sculpt_tool;
|
||||
char _pad1[5];
|
||||
char _pad1[6];
|
||||
|
||||
float autosmooth_factor;
|
||||
|
||||
|
|
|
@ -408,8 +408,7 @@
|
|||
\
|
||||
/* UV painting */ \
|
||||
.uv_sculpt_settings = 0, \
|
||||
.uv_relax_method = UV_SCULPT_TOOL_RELAX_LAPLACIAN, \
|
||||
\
|
||||
\
|
||||
/* Placement */ \
|
||||
.snap_mode_tools = SCE_SNAP_TO_GEOM,\
|
||||
.plane_axis = 2,\
|
||||
|
|
|
@ -860,13 +860,6 @@ enum {
|
|||
UV_SCULPT_ALL_ISLANDS = 2,
|
||||
};
|
||||
|
||||
/** #ToolSettings::uv_relax_method */
|
||||
enum {
|
||||
UV_SCULPT_TOOL_RELAX_LAPLACIAN = 1,
|
||||
UV_SCULPT_TOOL_RELAX_HC = 2,
|
||||
UV_SCULPT_TOOL_RELAX_COTAN = 3,
|
||||
};
|
||||
|
||||
/* Stereo Flags. */
|
||||
#define STEREO_RIGHT_NAME "right"
|
||||
#define STEREO_LEFT_NAME "left"
|
||||
|
@ -1099,7 +1092,11 @@ typedef struct CurvesSculpt {
|
|||
} CurvesSculpt;
|
||||
|
||||
typedef struct UvSculpt {
|
||||
Paint paint;
|
||||
struct CurveMapping *strength_curve;
|
||||
int size;
|
||||
float strength;
|
||||
int8_t curve_preset; /* #eBrushCurvePreset. */
|
||||
char _pad[7];
|
||||
} UvSculpt;
|
||||
|
||||
/** Grease pencil drawing brushes. */
|
||||
|
@ -1512,7 +1509,7 @@ typedef struct ToolSettings {
|
|||
VPaint *wpaint;
|
||||
Sculpt *sculpt;
|
||||
/** UV smooth. */
|
||||
UvSculpt *uvsculpt;
|
||||
UvSculpt uvsculpt;
|
||||
/** Gpencil paint. */
|
||||
GpPaint *gp_paint;
|
||||
/** Gpencil vertex paint. */
|
||||
|
@ -1664,10 +1661,11 @@ typedef struct ToolSettings {
|
|||
|
||||
/* UV painting. */
|
||||
char uv_sculpt_settings;
|
||||
char uv_relax_method;
|
||||
|
||||
char workspace_tool_type;
|
||||
|
||||
char _pad5[1];
|
||||
|
||||
/**
|
||||
* XXX: these `sculpt_paint_*` fields are deprecated, use the
|
||||
* unified_paint_settings field instead!
|
||||
|
|
|
@ -788,7 +788,12 @@ typedef struct UserDef {
|
|||
char pref_flag;
|
||||
char savetime;
|
||||
char mouse_emulate_3_button_modifier;
|
||||
char _pad4[1];
|
||||
/**
|
||||
* Workaround for WAYLAND (at time of writing compositors don't support this info).
|
||||
* #eUserpref_TrackpadScrollDir type
|
||||
* TODO: Remove this once this API is better supported by Wayland compositors, see #107676.
|
||||
*/
|
||||
char trackpad_scroll_direction;
|
||||
/** FILE_MAXDIR length. */
|
||||
char tempdir[768];
|
||||
char fontdir[768];
|
||||
|
@ -1533,6 +1538,11 @@ typedef enum eUserpref_EmulateMMBMod {
|
|||
USER_EMU_MMB_MOD_OSKEY = 1,
|
||||
} eUserpref_EmulateMMBMod;
|
||||
|
||||
typedef enum eUserpref_TrackpadScrollDir {
|
||||
USER_TRACKPAD_SCROLL_DIR_TRADITIONAL = 0,
|
||||
USER_TRACKPAD_SCROLL_DIR_NATURAL = 1,
|
||||
} eUserpref_TrackpadScrollDir;
|
||||
|
||||
typedef enum eUserpref_DiskCacheCompression {
|
||||
USER_SEQ_DISK_CACHE_COMPRESSION_NONE = 0,
|
||||
USER_SEQ_DISK_CACHE_COMPRESSION_LOW = 1,
|
||||
|
|
|
@ -109,7 +109,6 @@ DEF_ENUM(rna_enum_operator_property_tag_items)
|
|||
|
||||
DEF_ENUM(rna_enum_brush_automasking_flag_items)
|
||||
DEF_ENUM(rna_enum_brush_sculpt_tool_items)
|
||||
DEF_ENUM(rna_enum_brush_uv_sculpt_tool_items)
|
||||
DEF_ENUM(rna_enum_brush_vertex_tool_items)
|
||||
DEF_ENUM(rna_enum_brush_weight_tool_items)
|
||||
DEF_ENUM(rna_enum_brush_gpencil_types_items)
|
||||
|
@ -118,6 +117,7 @@ DEF_ENUM(rna_enum_brush_gpencil_sculpt_types_items)
|
|||
DEF_ENUM(rna_enum_brush_gpencil_weight_types_items)
|
||||
DEF_ENUM(rna_enum_brush_curves_sculpt_tool_items)
|
||||
DEF_ENUM(rna_enum_brush_image_tool_items)
|
||||
DEF_ENUM(rna_enum_brush_curve_preset_items)
|
||||
|
||||
DEF_ENUM(rna_enum_grease_pencil_selectmode_items)
|
||||
|
||||
|
|
|
@ -94,6 +94,20 @@ static const EnumPropertyItem rna_enum_brush_texture_slot_map_texture_mode_items
|
|||
};
|
||||
#endif
|
||||
|
||||
const EnumPropertyItem rna_enum_brush_curve_preset_items[] = {
|
||||
{BRUSH_CURVE_CUSTOM, "CUSTOM", ICON_RNDCURVE, "Custom", ""},
|
||||
{BRUSH_CURVE_SMOOTH, "SMOOTH", ICON_SMOOTHCURVE, "Smooth", ""},
|
||||
{BRUSH_CURVE_SMOOTHER, "SMOOTHER", ICON_SMOOTHCURVE, "Smoother", ""},
|
||||
{BRUSH_CURVE_SPHERE, "SPHERE", ICON_SPHERECURVE, "Sphere", ""},
|
||||
{BRUSH_CURVE_ROOT, "ROOT", ICON_ROOTCURVE, "Root", ""},
|
||||
{BRUSH_CURVE_SHARP, "SHARP", ICON_SHARPCURVE, "Sharp", ""},
|
||||
{BRUSH_CURVE_LIN, "LIN", ICON_LINCURVE, "Linear", ""},
|
||||
{BRUSH_CURVE_POW4, "POW4", ICON_SHARPCURVE, "Sharper", ""},
|
||||
{BRUSH_CURVE_INVSQUARE, "INVSQUARE", ICON_INVERSESQUARECURVE, "Inverse Square", ""},
|
||||
{BRUSH_CURVE_CONSTANT, "CONSTANT", ICON_NOCURVE, "Constant", ""},
|
||||
{0, nullptr, 0, nullptr, nullptr},
|
||||
};
|
||||
|
||||
/* Note: we don't actually turn these into a single enum bit-mask property,
|
||||
* instead we construct individual boolean properties. */
|
||||
const EnumPropertyItem rna_enum_brush_automasking_flag_items[] = {
|
||||
|
@ -185,13 +199,6 @@ const EnumPropertyItem rna_enum_brush_sculpt_tool_items[] = {
|
|||
{0, nullptr, 0, nullptr, nullptr},
|
||||
};
|
||||
|
||||
const EnumPropertyItem rna_enum_brush_uv_sculpt_tool_items[] = {
|
||||
{UV_SCULPT_TOOL_GRAB, "GRAB", 0, "Grab", "Grab UVs"},
|
||||
{UV_SCULPT_TOOL_RELAX, "RELAX", 0, "Relax", "Relax UVs"},
|
||||
{UV_SCULPT_TOOL_PINCH, "PINCH", 0, "Pinch", "Pinch UVs"},
|
||||
{0, nullptr, 0, nullptr, nullptr},
|
||||
};
|
||||
|
||||
const EnumPropertyItem rna_enum_brush_vertex_tool_items[] = {
|
||||
{VPAINT_TOOL_DRAW, "DRAW", ICON_BRUSH_MIX, "Draw", ""},
|
||||
{VPAINT_TOOL_BLUR, "BLUR", ICON_BRUSH_BLUR, "Blur", ""},
|
||||
|
@ -2419,20 +2426,6 @@ static void rna_def_brush(BlenderRNA *brna)
|
|||
{0, nullptr, 0, nullptr, nullptr},
|
||||
};
|
||||
|
||||
static const EnumPropertyItem brush_curve_preset_items[] = {
|
||||
{BRUSH_CURVE_CUSTOM, "CUSTOM", ICON_RNDCURVE, "Custom", ""},
|
||||
{BRUSH_CURVE_SMOOTH, "SMOOTH", ICON_SMOOTHCURVE, "Smooth", ""},
|
||||
{BRUSH_CURVE_SMOOTHER, "SMOOTHER", ICON_SMOOTHCURVE, "Smoother", ""},
|
||||
{BRUSH_CURVE_SPHERE, "SPHERE", ICON_SPHERECURVE, "Sphere", ""},
|
||||
{BRUSH_CURVE_ROOT, "ROOT", ICON_ROOTCURVE, "Root", ""},
|
||||
{BRUSH_CURVE_SHARP, "SHARP", ICON_SHARPCURVE, "Sharp", ""},
|
||||
{BRUSH_CURVE_LIN, "LIN", ICON_LINCURVE, "Linear", ""},
|
||||
{BRUSH_CURVE_POW4, "POW4", ICON_SHARPCURVE, "Sharper", ""},
|
||||
{BRUSH_CURVE_INVSQUARE, "INVSQUARE", ICON_INVERSESQUARECURVE, "Inverse Square", ""},
|
||||
{BRUSH_CURVE_CONSTANT, "CONSTANT", ICON_NOCURVE, "Constant", ""},
|
||||
{0, nullptr, 0, nullptr, nullptr},
|
||||
};
|
||||
|
||||
static const EnumPropertyItem brush_deformation_target_items[] = {
|
||||
{BRUSH_DEFORM_TARGET_GEOMETRY,
|
||||
"GEOMETRY",
|
||||
|
@ -2619,11 +2612,6 @@ static void rna_def_brush(BlenderRNA *brna)
|
|||
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_BRUSH);
|
||||
RNA_def_property_update(prop, 0, "rna_Brush_update_and_reset_icon");
|
||||
|
||||
prop = RNA_def_property(srna, "uv_sculpt_tool", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, rna_enum_brush_uv_sculpt_tool_items);
|
||||
RNA_def_property_ui_text(prop, "UV Sculpt Tool", "");
|
||||
RNA_def_property_update(prop, 0, "rna_Brush_update_and_reset_icon");
|
||||
|
||||
prop = RNA_def_property(srna, "vertex_tool", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, nullptr, "vertexpaint_tool");
|
||||
RNA_def_property_enum_items(prop, rna_enum_brush_vertex_tool_items);
|
||||
|
@ -2703,7 +2691,7 @@ static void rna_def_brush(BlenderRNA *brna)
|
|||
RNA_def_property_update(prop, 0, "rna_Brush_update");
|
||||
|
||||
prop = RNA_def_property(srna, "curve_preset", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, brush_curve_preset_items);
|
||||
RNA_def_property_enum_items(prop, rna_enum_brush_curve_preset_items);
|
||||
RNA_def_property_ui_text(prop, "Curve Preset", "");
|
||||
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_CURVES); /* Abusing id_curves :/ */
|
||||
RNA_def_property_update(prop, 0, "rna_Brush_update");
|
||||
|
|
|
@ -85,23 +85,6 @@ const EnumPropertyItem rna_enum_exr_codec_items[] = {
|
|||
};
|
||||
#endif
|
||||
|
||||
#ifndef RNA_RUNTIME
|
||||
static const EnumPropertyItem uv_sculpt_relaxation_items[] = {
|
||||
{UV_SCULPT_TOOL_RELAX_LAPLACIAN,
|
||||
"LAPLACIAN",
|
||||
0,
|
||||
"Laplacian",
|
||||
"Use Laplacian method for relaxation"},
|
||||
{UV_SCULPT_TOOL_RELAX_HC, "HC", 0, "HC", "Use HC method for relaxation"},
|
||||
{UV_SCULPT_TOOL_RELAX_COTAN,
|
||||
"COTAN",
|
||||
0,
|
||||
"Geometry",
|
||||
"Use Geometry (cotangent) relaxation, making UVs follow the underlying 3D geometry"},
|
||||
{0, nullptr, 0, nullptr, nullptr},
|
||||
};
|
||||
#endif
|
||||
|
||||
const EnumPropertyItem rna_enum_snap_source_items[] = {
|
||||
{SCE_SNAP_SOURCE_CLOSEST, "CLOSEST", 0, "Closest", "Snap closest point onto target"},
|
||||
{SCE_SNAP_SOURCE_CENTER, "CENTER", 0, "Center", "Snap transformation center onto target"},
|
||||
|
@ -3331,12 +3314,6 @@ static void rna_def_tool_settings(BlenderRNA *brna)
|
|||
RNA_def_property_flag(prop, PROP_DEG_SYNC_ONLY);
|
||||
RNA_def_property_ui_text(prop, "Sculpt All Islands", "Brush operates on all islands");
|
||||
|
||||
prop = RNA_def_property(srna, "uv_relax_method", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, nullptr, "uv_relax_method");
|
||||
RNA_def_property_flag(prop, PROP_DEG_SYNC_ONLY);
|
||||
RNA_def_property_enum_items(prop, uv_sculpt_relaxation_items);
|
||||
RNA_def_property_ui_text(prop, "Relaxation Method", "Algorithm used for UV relaxation");
|
||||
|
||||
prop = RNA_def_property(srna, "lock_object_mode", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, nullptr, "object_flag", SCE_OBJECT_MODE_LOCK);
|
||||
RNA_def_property_flag(prop, PROP_DEG_SYNC_ONLY);
|
||||
|
|
|
@ -110,6 +110,7 @@ const EnumPropertyItem rna_enum_symmetrize_direction_items[] = {
|
|||
# include "MEM_guardedalloc.h"
|
||||
|
||||
# include "BKE_collection.hh"
|
||||
# include "BKE_colortools.hh"
|
||||
# include "BKE_context.hh"
|
||||
# include "BKE_gpencil_legacy.h"
|
||||
# include "BKE_object.hh"
|
||||
|
@ -429,6 +430,18 @@ static void rna_ImaPaint_canvas_update(bContext *C, PointerRNA * /*ptr*/)
|
|||
}
|
||||
}
|
||||
|
||||
static void rna_UvSculpt_curve_preset_set(PointerRNA *ptr, int value)
|
||||
{
|
||||
Scene *scene = reinterpret_cast<Scene *>(ptr->owner_id);
|
||||
if (value == BRUSH_CURVE_CUSTOM) {
|
||||
if (!scene->toolsettings->uvsculpt.strength_curve) {
|
||||
scene->toolsettings->uvsculpt.strength_curve = BKE_curvemapping_add(
|
||||
1, 0.0f, 0.0f, 1.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
scene->toolsettings->uvsculpt.curve_preset = int8_t(value);
|
||||
}
|
||||
|
||||
/** \name Paint mode settings
|
||||
* \{ */
|
||||
|
||||
|
@ -886,10 +899,34 @@ static void rna_def_sculpt(BlenderRNA *brna)
|
|||
static void rna_def_uv_sculpt(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
srna = RNA_def_struct(brna, "UvSculpt", "Paint");
|
||||
RNA_def_struct_path_func(srna, "rna_UvSculpt_path");
|
||||
RNA_def_struct_ui_text(srna, "UV Sculpting", "");
|
||||
|
||||
prop = RNA_def_property(srna, "size", PROP_INT, PROP_PIXEL);
|
||||
RNA_def_property_ui_range(prop, 1, 500, 1, 1);
|
||||
RNA_def_property_range(prop, 1, 5000);
|
||||
RNA_def_property_ui_text(prop, "Size", "");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, nullptr);
|
||||
|
||||
prop = RNA_def_property(srna, "strength", PROP_FLOAT, PROP_FACTOR);
|
||||
RNA_def_property_range(prop, 0.0f, 1.0f);
|
||||
RNA_def_property_ui_text(prop, "Strength", "");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, nullptr);
|
||||
|
||||
prop = RNA_def_property(srna, "strength_curve", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_struct_type(prop, "CurveMapping");
|
||||
RNA_def_property_pointer_funcs(prop, nullptr, nullptr, nullptr, nullptr);
|
||||
RNA_def_property_ui_text(prop, "Strength Curve", "");
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, nullptr);
|
||||
|
||||
prop = RNA_def_property(srna, "curve_preset", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_items(prop, rna_enum_brush_curve_preset_items);
|
||||
RNA_def_property_ui_text(prop, "Strength Curve Preset", "");
|
||||
RNA_def_property_enum_funcs(prop, nullptr, "rna_UvSculpt_curve_preset_set", nullptr);
|
||||
RNA_def_property_update(prop, NC_SCENE | ND_TOOLSETTINGS, nullptr);
|
||||
}
|
||||
|
||||
static void rna_def_gp_paint(BlenderRNA *brna)
|
||||
|
|
|
@ -6570,6 +6570,20 @@ static void rna_def_userdef_input(BlenderRNA *brna)
|
|||
prop = RNA_def_property(srna, "invert_zoom_wheel", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, nullptr, "uiflag", USER_WHEELZOOMDIR);
|
||||
RNA_def_property_ui_text(prop, "Wheel Invert Zoom", "Swap the Mouse Wheel zoom direction");
|
||||
|
||||
static const EnumPropertyItem touchpad_scroll_direction_items[] = {
|
||||
{USER_TRACKPAD_SCROLL_DIR_TRADITIONAL,
|
||||
"TRADITIONAL",
|
||||
0,
|
||||
"Traditional",
|
||||
"Traditional scroll direction"},
|
||||
{USER_TRACKPAD_SCROLL_DIR_NATURAL, "NATURAL", 0, "Natural", "Natural scroll direction"},
|
||||
{0, nullptr, 0, nullptr, nullptr},
|
||||
};
|
||||
prop = RNA_def_property(srna, "touchpad_scroll_direction", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, nullptr, "trackpad_scroll_direction");
|
||||
RNA_def_property_enum_items(prop, touchpad_scroll_direction_items);
|
||||
RNA_def_property_ui_text(prop, "Touchpad Scroll Direction", "Scroll direction (Wayland only)");
|
||||
}
|
||||
|
||||
static void rna_def_userdef_keymap(BlenderRNA *brna)
|
||||
|
|
|
@ -593,6 +593,57 @@ static PyObject *bpy_ghost_backend(PyObject * /*self*/)
|
|||
return PyUnicode_FromString(WM_ghost_backend());
|
||||
}
|
||||
|
||||
/* NOTE(@ideasman42): This is a private function because the keys in the returned dictionary,
|
||||
* are not considered stable. Sometimes a function is temporarily only supported by one platform.
|
||||
* Once all platforms support the functionality there is no need for the flag
|
||||
* and it can be removed. This is at odds with a public API that has values which are
|
||||
* intended to be kept between releases.
|
||||
* If this were to be made public we would have to document that this is subject to change. */
|
||||
|
||||
PyDoc_STRVAR(
|
||||
/* Wrap. */
|
||||
bpy_wm_capabilities_doc,
|
||||
".. function:: _wm_capabilities()\n"
|
||||
"\n"
|
||||
" :return: A dictionary of capabilities (string keys, boolean values).\n"
|
||||
" :rtype: dict\n");
|
||||
static PyObject *bpy_wm_capabilities(PyObject *self)
|
||||
{
|
||||
static _Py_Identifier PyId_capabilities = {"_wm_capabilities_", -1};
|
||||
|
||||
PyObject *result = nullptr;
|
||||
switch (_PyObject_LookupAttrId(self, &PyId_capabilities, &result)) {
|
||||
case 1:
|
||||
return result;
|
||||
case 0:
|
||||
break;
|
||||
default:
|
||||
/* Unlikely, but there may be an error, forward it. */
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
result = PyDict_New();
|
||||
|
||||
const eWM_CapabilitiesFlag flag = WM_capabilities_flag();
|
||||
|
||||
#define SetFlagItem(x) \
|
||||
PyDict_SetItemString(result, STRINGIFY(x), PyBool_FromLong((WM_CAPABILITY_##x) & flag));
|
||||
|
||||
SetFlagItem(CURSOR_WARP);
|
||||
SetFlagItem(WINDOW_POSITION);
|
||||
SetFlagItem(PRIMARY_CLIPBOARD);
|
||||
SetFlagItem(GPU_FRONT_BUFFER_READ);
|
||||
SetFlagItem(CLIPBOARD_IMAGES);
|
||||
SetFlagItem(DESKTOP_SAMPLE);
|
||||
SetFlagItem(INPUT_IME);
|
||||
SetFlagItem(TRACKPAD_PHYSICAL_DIRECTION);
|
||||
|
||||
#undef SetFlagItem
|
||||
|
||||
_PyObject_SetAttrId(self, &PyId_capabilities, result);
|
||||
return result;
|
||||
}
|
||||
|
||||
#if (defined(__GNUC__) && !defined(__clang__))
|
||||
# pragma GCC diagnostic push
|
||||
# pragma GCC diagnostic ignored "-Wcast-function-type"
|
||||
|
@ -631,6 +682,7 @@ static PyMethodDef bpy_methods[] = {
|
|||
METH_VARARGS | METH_KEYWORDS,
|
||||
bpy_driver_secure_code_test_doc},
|
||||
{"_ghost_backend", (PyCFunction)bpy_ghost_backend, METH_NOARGS, bpy_ghost_backend_doc},
|
||||
{"_wm_capabilities", (PyCFunction)bpy_wm_capabilities, METH_NOARGS, bpy_wm_capabilities_doc},
|
||||
|
||||
{nullptr, nullptr, 0, nullptr},
|
||||
};
|
||||
|
@ -719,7 +771,7 @@ void BPy_init_modules(bContext *C)
|
|||
BPY_rna_types_extend_capi();
|
||||
|
||||
#define PYMODULE_ADD_METHOD(mod, meth) \
|
||||
PyModule_AddObject(mod, (meth)->ml_name, (PyObject *)PyCFunction_New(meth, nullptr))
|
||||
PyModule_AddObject(mod, (meth)->ml_name, (PyObject *)PyCFunction_New(meth, mod))
|
||||
|
||||
for (int i = 0; bpy_methods[i].ml_name; i++) {
|
||||
PyMethodDef *m = &bpy_methods[i];
|
||||
|
|
|
@ -186,10 +186,12 @@ enum eWM_CapabilitiesFlag {
|
|||
WM_CAPABILITY_DESKTOP_SAMPLE = (1 << 5),
|
||||
/** Support for IME input methods. */
|
||||
WM_CAPABILITY_INPUT_IME = (1 << 6),
|
||||
/** Trackpad physical scroll detection. */
|
||||
WM_CAPABILITY_TRACKPAD_PHYSICAL_DIRECTION = (1 << 7),
|
||||
/** The initial value, indicates the value needs to be set by inspecting GHOST. */
|
||||
WM_CAPABILITY_INITIALIZED = (1u << 31),
|
||||
};
|
||||
ENUM_OPERATORS(eWM_CapabilitiesFlag, WM_CAPABILITY_CLIPBOARD_IMAGES)
|
||||
ENUM_OPERATORS(eWM_CapabilitiesFlag, WM_CAPABILITY_TRACKPAD_PHYSICAL_DIRECTION)
|
||||
|
||||
eWM_CapabilitiesFlag WM_capabilities_flag();
|
||||
|
||||
|
|
|
@ -5632,6 +5632,23 @@ void wm_event_add_ghostevent(wmWindowManager *wm,
|
|||
event.flag |= WM_EVENT_SCROLL_INVERT;
|
||||
}
|
||||
|
||||
#if !defined(WIN32) && !defined(__APPLE__)
|
||||
/* Ensure "auto" is used when supported. */
|
||||
char trackpad_scroll_direction = U.trackpad_scroll_direction;
|
||||
if ((WM_capabilities_flag() & WM_CAPABILITY_TRACKPAD_PHYSICAL_DIRECTION) == 0) {
|
||||
switch (eUserpref_TrackpadScrollDir(trackpad_scroll_direction)) {
|
||||
case USER_TRACKPAD_SCROLL_DIR_TRADITIONAL: {
|
||||
event.flag &= ~WM_EVENT_SCROLL_INVERT;
|
||||
break;
|
||||
}
|
||||
case USER_TRACKPAD_SCROLL_DIR_NATURAL: {
|
||||
event.flag |= WM_EVENT_SCROLL_INVERT;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
wm_event_add_trackpad(win, &event, delta[0], delta[1]);
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -2077,6 +2077,9 @@ eWM_CapabilitiesFlag WM_capabilities_flag()
|
|||
if (ghost_flag & GHOST_kCapabilityInputIME) {
|
||||
flag |= WM_CAPABILITY_INPUT_IME;
|
||||
}
|
||||
if (ghost_flag & GHOST_kCapabilityTrackpadPhysicalDirection) {
|
||||
flag |= WM_CAPABILITY_TRACKPAD_PHYSICAL_DIRECTION;
|
||||
}
|
||||
|
||||
return flag;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue