Merge branch 'master' into greasepencil-object
This commit is contained in:
21
GNUmakefile
21
GNUmakefile
@@ -163,9 +163,8 @@ CPU:=$(shell uname -m)
|
||||
BLENDER_DIR:=$(shell pwd -P)
|
||||
BUILD_TYPE:=Release
|
||||
|
||||
ifndef BUILD_CMAKE_ARGS
|
||||
BUILD_CMAKE_ARGS:=
|
||||
endif
|
||||
# CMake arguments, assigned to local variable to make it mutable.
|
||||
CMAKE_CONFIG_ARGS := $(BUILD_CMAKE_ARGS)
|
||||
|
||||
ifndef BUILD_DIR
|
||||
BUILD_DIR:=$(shell dirname "$(BLENDER_DIR)")/build_$(OS_NCASE)
|
||||
@@ -213,34 +212,34 @@ ifneq "$(findstring debug, $(MAKECMDGOALS))" ""
|
||||
endif
|
||||
ifneq "$(findstring full, $(MAKECMDGOALS))" ""
|
||||
BUILD_DIR:=$(BUILD_DIR)_full
|
||||
BUILD_CMAKE_ARGS:=$(BUILD_CMAKE_ARGS) -C"$(BLENDER_DIR)/build_files/cmake/config/blender_full.cmake"
|
||||
CMAKE_CONFIG_ARGS:=-C"$(BLENDER_DIR)/build_files/cmake/config/blender_full.cmake" $(CMAKE_CONFIG_ARGS)
|
||||
endif
|
||||
ifneq "$(findstring lite, $(MAKECMDGOALS))" ""
|
||||
BUILD_DIR:=$(BUILD_DIR)_lite
|
||||
BUILD_CMAKE_ARGS:=$(BUILD_CMAKE_ARGS) -C"$(BLENDER_DIR)/build_files/cmake/config/blender_lite.cmake"
|
||||
CMAKE_CONFIG_ARGS:=-C"$(BLENDER_DIR)/build_files/cmake/config/blender_lite.cmake" $(CMAKE_CONFIG_ARGS)
|
||||
endif
|
||||
ifneq "$(findstring cycles, $(MAKECMDGOALS))" ""
|
||||
BUILD_DIR:=$(BUILD_DIR)_cycles
|
||||
BUILD_CMAKE_ARGS:=$(BUILD_CMAKE_ARGS) -C"$(BLENDER_DIR)/build_files/cmake/config/cycles_standalone.cmake"
|
||||
CMAKE_CONFIG_ARGS:=-C"$(BLENDER_DIR)/build_files/cmake/config/cycles_standalone.cmake" $(CMAKE_CONFIG_ARGS)
|
||||
endif
|
||||
ifneq "$(findstring headless, $(MAKECMDGOALS))" ""
|
||||
BUILD_DIR:=$(BUILD_DIR)_headless
|
||||
BUILD_CMAKE_ARGS:=$(BUILD_CMAKE_ARGS) -C"$(BLENDER_DIR)/build_files/cmake/config/blender_headless.cmake"
|
||||
CMAKE_CONFIG_ARGS:=-C"$(BLENDER_DIR)/build_files/cmake/config/blender_headless.cmake" $(CMAKE_CONFIG_ARGS)
|
||||
endif
|
||||
ifneq "$(findstring bpy, $(MAKECMDGOALS))" ""
|
||||
BUILD_DIR:=$(BUILD_DIR)_bpy
|
||||
BUILD_CMAKE_ARGS:=$(BUILD_CMAKE_ARGS) -C"$(BLENDER_DIR)/build_files/cmake/config/bpy_module.cmake"
|
||||
CMAKE_CONFIG_ARGS:=-C"$(BLENDER_DIR)/build_files/cmake/config/bpy_module.cmake" $(CMAKE_CONFIG_ARGS)
|
||||
endif
|
||||
|
||||
ifneq "$(findstring developer, $(MAKECMDGOALS))" ""
|
||||
BUILD_CMAKE_ARGS:=$(BUILD_CMAKE_ARGS) -C"$(BLENDER_DIR)/build_files/cmake/config/blender_developer.cmake"
|
||||
CMAKE_CONFIG_ARGS:=-C"$(BLENDER_DIR)/build_files/cmake/config/blender_developer.cmake" $(CMAKE_CONFIG_ARGS)
|
||||
endif
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# build tool
|
||||
|
||||
ifneq "$(findstring ninja, $(MAKECMDGOALS))" ""
|
||||
BUILD_CMAKE_ARGS:=$(BUILD_CMAKE_ARGS) -G Ninja
|
||||
CMAKE_CONFIG_ARGS:=$(CMAKE_CONFIG_ARGS) -G Ninja
|
||||
BUILD_COMMAND:=ninja
|
||||
DEPS_BUILD_COMMAND:=ninja
|
||||
else
|
||||
@@ -288,7 +287,7 @@ endif
|
||||
# -----------------------------------------------------------------------------
|
||||
# Macro for configuring cmake
|
||||
|
||||
CMAKE_CONFIG = cmake $(BUILD_CMAKE_ARGS) \
|
||||
CMAKE_CONFIG = cmake $(CMAKE_CONFIG_ARGS) \
|
||||
-H"$(BLENDER_DIR)" \
|
||||
-B"$(BUILD_DIR)" \
|
||||
-DCMAKE_BUILD_TYPE_INIT:STRING=$(BUILD_TYPE)
|
||||
|
13
extern/audaspace/plugins/ffmpeg/FFMPEGReader.cpp
vendored
13
extern/audaspace/plugins/ffmpeg/FFMPEGReader.cpp
vendored
@@ -292,8 +292,8 @@ int FFMPEGReader::read_packet(void* opaque, uint8_t* buf, int buf_size)
|
||||
{
|
||||
FFMPEGReader* reader = reinterpret_cast<FFMPEGReader*>(opaque);
|
||||
|
||||
int64_t remaining_buffer_size = reader->m_membuffer->getSize() - reader->m_membufferpos;
|
||||
int64_t size = std::min(static_cast<int64_t>(buf_size), remaining_buffer_size);
|
||||
int size = std::min(buf_size, reader->m_membuffer->getSize() - reader->m_membufferpos);
|
||||
|
||||
if(size < 0)
|
||||
return -1;
|
||||
|
||||
@@ -319,7 +319,14 @@ int64_t FFMPEGReader::seek_packet(void* opaque, int64_t offset, int whence)
|
||||
return reader->m_membuffer->getSize();
|
||||
}
|
||||
|
||||
return (reader->m_membufferpos += offset);
|
||||
int64_t position = reader->m_membufferpos + offset;
|
||||
|
||||
if(position > reader->m_membuffer->getSize())
|
||||
position = reader->m_membuffer->getSize();
|
||||
|
||||
reader->m_membufferpos = int(position);
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
bool FFMPEGReader::isSeekable() const
|
||||
|
@@ -112,7 +112,7 @@ private:
|
||||
/**
|
||||
* Reading position of the buffer.
|
||||
*/
|
||||
int64_t m_membufferpos;
|
||||
int m_membufferpos;
|
||||
|
||||
/**
|
||||
* Whether the audio data has to be interleaved after reading.
|
||||
|
4
extern/wcwidth/README.blender
vendored
4
extern/wcwidth/README.blender
vendored
@@ -2,4 +2,6 @@ Project: WC Width
|
||||
URL: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
|
||||
License: ICS
|
||||
Upstream version: 2007-05-26
|
||||
Local modifications: None
|
||||
Local modifications:
|
||||
* Fix T33192
|
||||
Bad encoding of utf-8 on windows systems.
|
||||
|
12
extern/wcwidth/wcwidth.c
vendored
12
extern/wcwidth/wcwidth.c
vendored
@@ -59,8 +59,6 @@
|
||||
* Latest version: http://www.cl.cam.ac.uk/~mgk25/ucs/wcwidth.c
|
||||
*/
|
||||
|
||||
#include <wchar.h>
|
||||
|
||||
#include "wcwidth.h"
|
||||
|
||||
struct interval {
|
||||
@@ -69,7 +67,7 @@ struct interval {
|
||||
};
|
||||
|
||||
/* auxiliary function for binary search in interval table */
|
||||
static int bisearch(wchar_t ucs, const struct interval *table, int max) {
|
||||
static int bisearch(char32_t ucs, const struct interval *table, int max) {
|
||||
int min = 0;
|
||||
int mid;
|
||||
|
||||
@@ -121,7 +119,7 @@ static int bisearch(wchar_t ucs, const struct interval *table, int max) {
|
||||
* in ISO 10646.
|
||||
*/
|
||||
|
||||
int mk_wcwidth(wchar_t ucs)
|
||||
int mk_wcwidth(char32_t ucs)
|
||||
{
|
||||
/* sorted list of non-overlapping intervals of non-spacing characters */
|
||||
/* generated by "uniset +cat=Me +cat=Mn +cat=Cf -00AD +1160-11FF +200B c" */
|
||||
@@ -206,7 +204,7 @@ int mk_wcwidth(wchar_t ucs)
|
||||
}
|
||||
|
||||
|
||||
int mk_wcswidth(const wchar_t *pwcs, size_t n)
|
||||
int mk_wcswidth(const char32_t *pwcs, size_t n)
|
||||
{
|
||||
int w, width = 0;
|
||||
|
||||
@@ -229,7 +227,7 @@ int mk_wcswidth(const wchar_t *pwcs, size_t n)
|
||||
* the traditional terminal character-width behaviour. It is not
|
||||
* otherwise recommended for general use.
|
||||
*/
|
||||
int mk_wcwidth_cjk(wchar_t ucs)
|
||||
int mk_wcwidth_cjk(char32_t ucs)
|
||||
{
|
||||
/* sorted list of non-overlapping intervals of East Asian Ambiguous
|
||||
* characters, generated by "uniset +WIDTH-A -cat=Me -cat=Mn -cat=Cf c" */
|
||||
@@ -297,7 +295,7 @@ int mk_wcwidth_cjk(wchar_t ucs)
|
||||
}
|
||||
|
||||
|
||||
int mk_wcswidth_cjk(const wchar_t *pwcs, size_t n)
|
||||
int mk_wcswidth_cjk(const char32_t *pwcs, size_t n)
|
||||
{
|
||||
int w, width = 0;
|
||||
|
||||
|
18
extern/wcwidth/wcwidth.h
vendored
18
extern/wcwidth/wcwidth.h
vendored
@@ -20,11 +20,19 @@
|
||||
#ifndef __WCWIDTH_H__
|
||||
#define __WCWIDTH_H__
|
||||
|
||||
#include <wchar.h>
|
||||
#ifndef __cplusplus
|
||||
# if defined(__APPLE__)
|
||||
/* The <uchar.h> standard header is missing on macOS. */
|
||||
#include <stddef.h>
|
||||
typedef unsigned int char32_t;
|
||||
# else
|
||||
# include <uchar.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
int mk_wcwidth(wchar_t ucs);
|
||||
int mk_wcswidth(const wchar_t *pwcs, size_t n);
|
||||
int mk_wcwidth_cjk(wchar_t ucs);
|
||||
int mk_wcswidth_cjk(const wchar_t *pwcs, size_t n);
|
||||
int mk_wcwidth(char32_t ucs);
|
||||
int mk_wcswidth(const char32_t *pwcs, size_t n);
|
||||
int mk_wcwidth_cjk(char32_t ucs);
|
||||
int mk_wcswidth_cjk(const char32_t *pwcs, size_t n);
|
||||
|
||||
#endif
|
||||
|
@@ -44,7 +44,7 @@ template<bool always = false> ccl_device_forceinline uint get_object_id()
|
||||
#endif
|
||||
// Choose between always returning object ID or only for instances
|
||||
if (always)
|
||||
// Can just remove the high bit since instace always contains object ID
|
||||
// Can just remove the high bit since instance always contains object ID
|
||||
return object & 0x7FFFFF;
|
||||
// Set to OBJECT_NONE if this is not an instanced object
|
||||
else if (object & 0x800000)
|
||||
@@ -263,8 +263,12 @@ extern "C" __global__ void __intersection__curve()
|
||||
const uint type = kernel_tex_fetch(__prim_type, prim);
|
||||
const uint visibility = optixGetPayload_4();
|
||||
|
||||
const float3 P = optixGetObjectRayOrigin();
|
||||
const float3 dir = optixGetObjectRayDirection();
|
||||
float3 P = optixGetObjectRayOrigin();
|
||||
float3 dir = optixGetObjectRayDirection();
|
||||
|
||||
// The direction is not normalized by default, but the curve intersection routine expects that
|
||||
float len;
|
||||
dir = normalize_len(dir, &len);
|
||||
|
||||
# ifdef __OBJECT_MOTION__
|
||||
const float time = optixGetRayTime();
|
||||
@@ -274,11 +278,14 @@ extern "C" __global__ void __intersection__curve()
|
||||
|
||||
Intersection isect;
|
||||
isect.t = optixGetRayTmax();
|
||||
// Transform maximum distance into object space
|
||||
if (isect.t != FLT_MAX)
|
||||
isect.t *= len;
|
||||
|
||||
if (!(kernel_data.curve.curveflags & CURVE_KN_INTERPOLATE) ?
|
||||
curve_intersect(NULL, &isect, P, dir, visibility, object, prim, time, type) :
|
||||
cardinal_curve_intersect(NULL, &isect, P, dir, visibility, object, prim, time, type)) {
|
||||
optixReportIntersection(isect.t,
|
||||
optixReportIntersection(isect.t / len,
|
||||
type & PRIMITIVE_ALL,
|
||||
__float_as_int(isect.u), // Attribute_0
|
||||
__float_as_int(isect.v)); // Attribute_1
|
||||
|
@@ -1411,13 +1411,9 @@ def km_graph_editor(params):
|
||||
{"properties": [("mode", 'RIGHT'), ("extend", False)]}),
|
||||
*_template_items_select_actions(params, "graph.select_all"),
|
||||
("graph.select_box", {"type": 'B', "value": 'PRESS'},
|
||||
{"properties": [("axis_range", False), ("include_handles", False)]}),
|
||||
{"properties": [("axis_range", False)]}),
|
||||
("graph.select_box", {"type": 'B', "value": 'PRESS', "alt": True},
|
||||
{"properties": [("axis_range", True), ("include_handles", False)]}),
|
||||
("graph.select_box", {"type": 'B', "value": 'PRESS', "ctrl": True},
|
||||
{"properties": [("axis_range", False), ("include_handles", True)]}),
|
||||
("graph.select_box", {"type": 'B', "value": 'PRESS', "ctrl": True, "alt": True},
|
||||
{"properties": [("axis_range", True), ("include_handles", True)]}),
|
||||
{"properties": [("axis_range", True)]}),
|
||||
("graph.select_box", {"type": params.select_tweak, "value": 'ANY'},
|
||||
{"properties": [("tweak", True), ("mode", 'SET')]}),
|
||||
("graph.select_box", {"type": params.select_tweak, "value": 'ANY', "shift": True},
|
||||
@@ -2225,7 +2221,7 @@ def km_text(params):
|
||||
{"properties": [("direction", 'UP')]}),
|
||||
("text.move_lines", {"type": 'DOWN_ARROW', "value": 'PRESS', "shift": True, "ctrl": True},
|
||||
{"properties": [("direction", 'DOWN')]}),
|
||||
("text.indent", {"type": 'TAB', "value": 'PRESS'}, None),
|
||||
("text.indent_or_autocomplete", {"type": 'TAB', "value": 'PRESS'}, None),
|
||||
("text.unindent", {"type": 'TAB', "value": 'PRESS', "shift": True}, None),
|
||||
("text.comment_toggle", {"type": 'SLASH', "value": 'PRESS', "ctrl": True}, None),
|
||||
("text.move", {"type": 'HOME', "value": 'PRESS'},
|
||||
@@ -2305,7 +2301,6 @@ def km_text(params):
|
||||
{"properties": [("lines", 1)]}),
|
||||
("text.line_break", {"type": 'RET', "value": 'PRESS'}, None),
|
||||
("text.line_break", {"type": 'NUMPAD_ENTER', "value": 'PRESS'}, None),
|
||||
("text.autocomplete", {"type": 'SPACE', "value": 'PRESS', "ctrl": True}, None),
|
||||
("text.line_number", {"type": 'TEXTINPUT', "value": 'ANY', "any": True}, None),
|
||||
op_menu("TEXT_MT_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}),
|
||||
("text.insert", {"type": 'TEXTINPUT', "value": 'ANY', "any": True}, None),
|
||||
@@ -2535,7 +2530,6 @@ def km_console(params):
|
||||
{"properties": [("interactive", True)]}),
|
||||
("console.execute", {"type": 'NUMPAD_ENTER', "value": 'PRESS'},
|
||||
{"properties": [("interactive", True)]}),
|
||||
("console.autocomplete", {"type": 'SPACE', "value": 'PRESS', "ctrl": True}, None),
|
||||
("console.copy_as_script", {"type": 'C', "value": 'PRESS', "shift": True, "ctrl": True}, None),
|
||||
("console.copy", {"type": 'C', "value": 'PRESS', "ctrl": True}, None),
|
||||
("console.paste", {"type": 'V', "value": 'PRESS', "ctrl": True}, None),
|
||||
@@ -2543,7 +2537,7 @@ def km_console(params):
|
||||
("console.select_word", {"type": 'LEFTMOUSE', "value": 'DOUBLE_CLICK'}, None),
|
||||
("console.insert", {"type": 'TAB', "value": 'PRESS', "ctrl": True},
|
||||
{"properties": [("text", '\t')]}),
|
||||
("console.indent", {"type": 'TAB', "value": 'PRESS'}, None),
|
||||
("console.indent_or_autocomplete", {"type": 'TAB', "value": 'PRESS'}, None),
|
||||
("console.unindent", {"type": 'TAB', "value": 'PRESS', "shift": True}, None),
|
||||
op_menu("CONSOLE_MT_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}),
|
||||
("console.insert", {"type": 'TEXTINPUT', "value": 'ANY', "any": True}, None),
|
||||
|
@@ -860,19 +860,15 @@ def km_graph_editor(params):
|
||||
("graph.select_all", {"type": 'A', "value": 'PRESS', "ctrl": True, "shift": True}, {"properties": [("action", 'DESELECT')]}),
|
||||
("graph.select_all", {"type": 'I', "value": 'PRESS', "ctrl": True}, {"properties": [("action", 'INVERT')]}),
|
||||
("graph.select_box", {"type": 'Q', "value": 'PRESS'},
|
||||
{"properties": [("axis_range", False), ("include_handles", False)]}),
|
||||
{"properties": [("axis_range", False)]}),
|
||||
("graph.select_box", {"type": 'Q', "value": 'PRESS', "alt": True},
|
||||
{"properties": [("axis_range", True), ("include_handles", False)]}),
|
||||
("graph.select_box", {"type": 'Q', "value": 'PRESS', "ctrl": True},
|
||||
{"properties": [("axis_range", False), ("include_handles", True)]}),
|
||||
("graph.select_box", {"type": 'Q', "value": 'PRESS', "ctrl": True, "alt": True},
|
||||
{"properties": [("axis_range", True), ("include_handles", True)]}),
|
||||
{"properties": [("axis_range", True)]}),
|
||||
("graph.select_box", {"type": 'EVT_TWEAK_L', "value": 'ANY'},
|
||||
{"properties":[("tweak", True), ("axis_range", False), ("include_handles", False), ("mode", 'SET')]}),
|
||||
{"properties":[("tweak", True), ("axis_range", False), ("mode", 'SET')]}),
|
||||
("graph.select_box", {"type": 'EVT_TWEAK_L', "value": 'ANY', "shift": True},
|
||||
{"properties":[("tweak", True), ("axis_range", False), ("include_handles", False), ("mode", 'ADD')]}),
|
||||
{"properties":[("tweak", True), ("axis_range", False), ("mode", 'ADD')]}),
|
||||
("graph.select_box", {"type": 'EVT_TWEAK_L', "value": 'ANY', "ctrl": True},
|
||||
{"properties":[("tweak", True), ("axis_range", False),("include_handles", False), ("mode", 'SUB')]}),
|
||||
{"properties":[("tweak", True), ("axis_range", False), ("mode", 'SUB')]}),
|
||||
("graph.select_more", {"type": 'UP_ARROW', "value": 'PRESS'}, None),
|
||||
("graph.select_less", {"type": 'DOWN_ARROW', "value": 'PRESS'}, None),
|
||||
("graph.select_linked", {"type": 'RIGHT_BRACKET', "value": 'PRESS'}, None),
|
||||
@@ -1587,7 +1583,7 @@ def km_text(params):
|
||||
{"properties": [("direction", 'UP')]}),
|
||||
("text.move_lines", {"type": 'DOWN_ARROW', "value": 'PRESS', "shift": True, "ctrl": True},
|
||||
{"properties": [("direction", 'DOWN')]}),
|
||||
("text.indent", {"type": 'TAB', "value": 'PRESS'}, None),
|
||||
("text.indent_or_autocomplete", {"type": 'TAB', "value": 'PRESS'}, None),
|
||||
("text.unindent", {"type": 'TAB', "value": 'PRESS', "shift": True}, None),
|
||||
("text.uncomment", {"type": 'D', "value": 'PRESS', "shift": True, "ctrl": True}, None),
|
||||
("text.move", {"type": 'HOME', "value": 'PRESS'},
|
||||
@@ -1668,7 +1664,6 @@ def km_text(params):
|
||||
("text.line_break", {"type": 'RET', "value": 'PRESS'}, None),
|
||||
("text.line_break", {"type": 'NUMPAD_ENTER', "value": 'PRESS'}, None),
|
||||
op_menu("TEXT_MT_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS', "any": True}),
|
||||
("text.autocomplete", {"type": 'SPACE', "value": 'PRESS', "ctrl": True}, None),
|
||||
("text.line_number", {"type": 'TEXTINPUT', "value": 'ANY', "any": True}, None),
|
||||
("text.insert", {"type": 'TEXTINPUT', "value": 'ANY', "any": True}, None),
|
||||
])
|
||||
@@ -1878,7 +1873,6 @@ def km_console(params):
|
||||
{"properties": [("interactive", True)]}),
|
||||
("console.execute", {"type": 'NUMPAD_ENTER', "value": 'PRESS'},
|
||||
{"properties": [("interactive", True)]}),
|
||||
("console.autocomplete", {"type": 'SPACE', "value": 'PRESS', "ctrl": True}, None),
|
||||
("console.copy_as_script", {"type": 'C', "value": 'PRESS', "shift": True, "ctrl": True}, None),
|
||||
("console.copy", {"type": 'C', "value": 'PRESS', "ctrl": True}, None),
|
||||
("console.paste", {"type": 'V', "value": 'PRESS', "ctrl": True}, None),
|
||||
@@ -1886,10 +1880,10 @@ def km_console(params):
|
||||
("console.select_word", {"type": 'LEFTMOUSE', "value": 'DOUBLE_CLICK'}, None),
|
||||
("console.insert", {"type": 'TAB', "value": 'PRESS', "ctrl": True},
|
||||
{"properties": [("text", '\t')]}),
|
||||
("console.indent", {"type": 'TAB', "value": 'PRESS'}, None),
|
||||
("console.indent_or_autocomplete", {"type": 'TAB', "value": 'PRESS'}, None),
|
||||
("console.unindent", {"type": 'TAB', "value": 'PRESS', "shift": True}, None),
|
||||
("console.insert", {"type": 'TEXTINPUT', "value": 'ANY', "any": True}, None),
|
||||
op_menu("CONSOLE_MT_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}),
|
||||
("console.insert", {"type": 'TEXTINPUT', "value": 'ANY', "any": True}, None),
|
||||
])
|
||||
|
||||
return keymap
|
||||
|
@@ -504,7 +504,7 @@ int blf_font_draw_mono(FontBLF *font, const char *str, size_t len, int cwidth)
|
||||
/* do not return this loop if clipped, we want every character tested */
|
||||
blf_glyph_render(font, gc, g, (float)pen_x, (float)pen_y);
|
||||
|
||||
col = BLI_wcwidth((wchar_t)c);
|
||||
col = BLI_wcwidth((char32_t)c);
|
||||
if (col < 0) {
|
||||
col = 1;
|
||||
}
|
||||
|
@@ -35,6 +35,8 @@ struct Path;
|
||||
struct TextBox;
|
||||
struct rctf;
|
||||
|
||||
typedef int eBezTriple_Flag__Alias;
|
||||
|
||||
typedef struct CurveCache {
|
||||
ListBase disp;
|
||||
ListBase bev;
|
||||
@@ -242,6 +244,12 @@ void BKE_nurb_handle_calc(struct BezTriple *bezt,
|
||||
struct BezTriple *next,
|
||||
const bool is_fcurve,
|
||||
const char smoothing);
|
||||
void BKE_nurb_handle_calc_ex(struct BezTriple *bezt,
|
||||
struct BezTriple *prev,
|
||||
struct BezTriple *next,
|
||||
const eBezTriple_Flag__Alias handle_sel_flag,
|
||||
const bool is_fcurve,
|
||||
const char smoothing);
|
||||
void BKE_nurb_handle_calc_simple(struct Nurb *nu, struct BezTriple *bezt);
|
||||
void BKE_nurb_handle_calc_simple_auto(struct Nurb *nu, struct BezTriple *bezt);
|
||||
|
||||
@@ -249,7 +257,9 @@ void BKE_nurb_handle_smooth_fcurve(struct BezTriple *bezt, int total, bool cycli
|
||||
|
||||
void BKE_nurb_handles_calc(struct Nurb *nu);
|
||||
void BKE_nurb_handles_autocalc(struct Nurb *nu, int flag);
|
||||
void BKE_nurb_bezt_handle_test(struct BezTriple *bezt, const bool use_handle);
|
||||
void BKE_nurb_bezt_handle_test(struct BezTriple *bezt,
|
||||
const eBezTriple_Flag__Alias sel_flag,
|
||||
const bool use_handle);
|
||||
void BKE_nurb_handles_test(struct Nurb *nu, const bool use_handles);
|
||||
|
||||
/* **** Depsgraph evaluation **** */
|
||||
|
@@ -328,7 +328,8 @@ eFCU_Cycle_Type BKE_fcurve_get_cycle_type(struct FCurve *fcu);
|
||||
/* -------- Curve Sanity -------- */
|
||||
|
||||
void calchandles_fcurve(struct FCurve *fcu);
|
||||
void testhandles_fcurve(struct FCurve *fcu, const bool use_handle);
|
||||
void calchandles_fcurve_ex(struct FCurve *fcu, eBezTriple_Flag handle_sel_flag);
|
||||
void testhandles_fcurve(struct FCurve *fcu, eBezTriple_Flag sel_flag, const bool use_handle);
|
||||
void sort_time_fcurve(struct FCurve *fcu);
|
||||
short test_time_fcurve(struct FCurve *fcu);
|
||||
|
||||
|
@@ -27,8 +27,6 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <wchar.h>
|
||||
|
||||
struct CharInfo;
|
||||
struct Curve;
|
||||
struct Main;
|
||||
@@ -48,7 +46,7 @@ typedef struct EditFontSelBox {
|
||||
} EditFontSelBox;
|
||||
|
||||
typedef struct EditFont {
|
||||
wchar_t *textbuf;
|
||||
char32_t *textbuf;
|
||||
struct CharInfo *textbufinfo;
|
||||
|
||||
/* array of rectangles & rotation */
|
||||
@@ -90,7 +88,7 @@ bool BKE_vfont_to_curve_ex(struct Object *ob,
|
||||
struct Curve *cu,
|
||||
int mode,
|
||||
struct ListBase *r_nubase,
|
||||
const wchar_t **r_text,
|
||||
const char32_t **r_text,
|
||||
int *r_text_len,
|
||||
bool *r_text_free,
|
||||
struct CharTrans **r_chartransdata);
|
||||
@@ -101,13 +99,13 @@ int BKE_vfont_select_get(struct Object *ob, int *r_start, int *r_end);
|
||||
void BKE_vfont_select_clamp(struct Object *ob);
|
||||
|
||||
void BKE_vfont_clipboard_free(void);
|
||||
void BKE_vfont_clipboard_set(const wchar_t *text_buf,
|
||||
void BKE_vfont_clipboard_set(const char32_t *text_buf,
|
||||
const struct CharInfo *info_buf,
|
||||
const size_t len);
|
||||
void BKE_vfont_clipboard_get(wchar_t **r_text_buf,
|
||||
void BKE_vfont_clipboard_get(char32_t **r_text_buf,
|
||||
struct CharInfo **r_info_buf,
|
||||
size_t *r_len_utf8,
|
||||
size_t *r_len_wchar);
|
||||
size_t *r_len_utf32);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@@ -3201,6 +3201,7 @@ void BKE_curve_bevelList_make(Object *ob, ListBase *nurbs, bool for_render)
|
||||
static void calchandleNurb_intern(BezTriple *bezt,
|
||||
const BezTriple *prev,
|
||||
const BezTriple *next,
|
||||
eBezTriple_Flag handle_sel_flag,
|
||||
bool is_fcurve,
|
||||
bool skip_align,
|
||||
char fcurve_smoothing)
|
||||
@@ -3402,7 +3403,7 @@ static void calchandleNurb_intern(BezTriple *bezt,
|
||||
|
||||
len_ratio = len_a / len_b;
|
||||
|
||||
if (bezt->f1 & SELECT) { /* order of calculation */
|
||||
if (bezt->f1 & handle_sel_flag) { /* order of calculation */
|
||||
if (ELEM(bezt->h2, HD_ALIGN, HD_ALIGN_DOUBLESIDE)) { /* aligned */
|
||||
if (len_a > eps) {
|
||||
len = 1.0f / len_ratio;
|
||||
@@ -3443,7 +3444,7 @@ static void calchandleNurb_intern(BezTriple *bezt,
|
||||
#undef p2_h2
|
||||
}
|
||||
|
||||
static void calchandlesNurb_intern(Nurb *nu, bool skip_align)
|
||||
static void calchandlesNurb_intern(Nurb *nu, eBezTriple_Flag handle_sel_flag, bool skip_align)
|
||||
{
|
||||
BezTriple *bezt, *prev, *next;
|
||||
int a;
|
||||
@@ -3466,7 +3467,7 @@ static void calchandlesNurb_intern(Nurb *nu, bool skip_align)
|
||||
next = bezt + 1;
|
||||
|
||||
while (a--) {
|
||||
calchandleNurb_intern(bezt, prev, next, 0, skip_align, 0);
|
||||
calchandleNurb_intern(bezt, prev, next, handle_sel_flag, 0, skip_align, 0);
|
||||
prev = bezt;
|
||||
if (a == 1) {
|
||||
if (nu->flagu & CU_NURB_CYCLIC) {
|
||||
@@ -4038,15 +4039,36 @@ void BKE_nurb_handle_smooth_fcurve(BezTriple *bezt, int total, bool cycle)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Recalculate the handles of a nurb bezier-triple. Acts based on handle selection with `SELECT`
|
||||
* flag. To use a different flag, use #BKE_nurb_handle_calc_ex().
|
||||
*/
|
||||
void BKE_nurb_handle_calc(
|
||||
BezTriple *bezt, BezTriple *prev, BezTriple *next, const bool is_fcurve, const char smoothing)
|
||||
{
|
||||
calchandleNurb_intern(bezt, prev, next, is_fcurve, false, smoothing);
|
||||
calchandleNurb_intern(bezt, prev, next, SELECT, is_fcurve, false, smoothing);
|
||||
}
|
||||
|
||||
/**
|
||||
* Variant of #BKE_nurb_handle_calc() that allows calculating based on a different select flag.
|
||||
*
|
||||
* \param sel_flag: The flag (bezt.f1/2/3) value to use to determine selection. Usually `SELECT`,
|
||||
* but may want to use a different one at times (if caller does not operate on
|
||||
* selection).
|
||||
*/
|
||||
void BKE_nurb_handle_calc_ex(BezTriple *bezt,
|
||||
BezTriple *prev,
|
||||
BezTriple *next,
|
||||
const eBezTriple_Flag__Alias handle_sel_flag,
|
||||
const bool is_fcurve,
|
||||
const char smoothing)
|
||||
{
|
||||
calchandleNurb_intern(bezt, prev, next, handle_sel_flag, is_fcurve, false, smoothing);
|
||||
}
|
||||
|
||||
void BKE_nurb_handles_calc(Nurb *nu) /* first, if needed, set handle flags */
|
||||
{
|
||||
calchandlesNurb_intern(nu, false);
|
||||
calchandlesNurb_intern(nu, SELECT, false);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -4101,11 +4123,21 @@ void BKE_nurb_handle_calc_simple_auto(Nurb *nu, BezTriple *bezt)
|
||||
}
|
||||
|
||||
/**
|
||||
* Update selected handle types to ensure valid state, e.g. deduce "Auto" types to concrete ones.
|
||||
* Thereby \a sel_flag defines what qualifies as selected.
|
||||
* Use when something has changed handle positions.
|
||||
*
|
||||
* The caller needs to recalculate handles.
|
||||
*
|
||||
* \param sel_flag: The flag (bezt.f1/2/3) value to use to determine selection. Usually `SELECT`,
|
||||
* but may want to use a different one at times (if caller does not operate on
|
||||
* selection).
|
||||
* \param use_handle: Check selection state of individual handles, otherwise always update both
|
||||
* handles if the key is selected.
|
||||
*/
|
||||
void BKE_nurb_bezt_handle_test(BezTriple *bezt, const bool use_handle)
|
||||
void BKE_nurb_bezt_handle_test(BezTriple *bezt,
|
||||
const eBezTriple_Flag__Alias sel_flag,
|
||||
const bool use_handle)
|
||||
{
|
||||
short flag = 0;
|
||||
|
||||
@@ -4114,18 +4146,18 @@ void BKE_nurb_bezt_handle_test(BezTriple *bezt, const bool use_handle)
|
||||
#define SEL_F3 (1 << 2)
|
||||
|
||||
if (use_handle) {
|
||||
if (bezt->f1 & SELECT) {
|
||||
if (bezt->f1 & sel_flag) {
|
||||
flag |= SEL_F1;
|
||||
}
|
||||
if (bezt->f2 & SELECT) {
|
||||
if (bezt->f2 & sel_flag) {
|
||||
flag |= SEL_F2;
|
||||
}
|
||||
if (bezt->f3 & SELECT) {
|
||||
if (bezt->f3 & sel_flag) {
|
||||
flag |= SEL_F3;
|
||||
}
|
||||
}
|
||||
else {
|
||||
flag = (bezt->f2 & SELECT) ? (SEL_F1 | SEL_F2 | SEL_F3) : 0;
|
||||
flag = (bezt->f2 & sel_flag) ? (SEL_F1 | SEL_F2 | SEL_F3) : 0;
|
||||
}
|
||||
|
||||
/* check for partial selection */
|
||||
@@ -4166,7 +4198,7 @@ void BKE_nurb_handles_test(Nurb *nu, const bool use_handle)
|
||||
bezt = nu->bezt;
|
||||
a = nu->pntsu;
|
||||
while (a--) {
|
||||
BKE_nurb_bezt_handle_test(bezt, use_handle);
|
||||
BKE_nurb_bezt_handle_test(bezt, SELECT, use_handle);
|
||||
bezt++;
|
||||
}
|
||||
|
||||
@@ -4639,7 +4671,7 @@ void BKE_curve_nurbs_vert_coords_apply_with_mat4(ListBase *lb,
|
||||
}
|
||||
}
|
||||
|
||||
calchandlesNurb_intern(nu, true);
|
||||
calchandlesNurb_intern(nu, SELECT, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4677,7 +4709,7 @@ void BKE_curve_nurbs_vert_coords_apply(ListBase *lb,
|
||||
}
|
||||
}
|
||||
|
||||
calchandlesNurb_intern(nu, true);
|
||||
calchandlesNurb_intern(nu, SELECT, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1036,10 +1036,14 @@ static BezTriple *cycle_offset_triple(
|
||||
return out;
|
||||
}
|
||||
|
||||
/* This function recalculates the handles of an F-Curve
|
||||
* If the BezTriples have been rearranged, sort them first before using this.
|
||||
/**
|
||||
* Variant of #calchandles_fcurve() that allows calculating based on a different select flag.
|
||||
*
|
||||
* \param sel_flag: The flag (bezt.f1/2/3) value to use to determine selection. Usually `SELECT`,
|
||||
* but may want to use a different one at times (if caller does not operate on
|
||||
* selection).
|
||||
*/
|
||||
void calchandles_fcurve(FCurve *fcu)
|
||||
void calchandles_fcurve_ex(FCurve *fcu, eBezTriple_Flag handle_sel_flag)
|
||||
{
|
||||
BezTriple *bezt, *prev, *next;
|
||||
int a = fcu->totvert;
|
||||
@@ -1075,7 +1079,7 @@ void calchandles_fcurve(FCurve *fcu)
|
||||
}
|
||||
|
||||
/* calculate auto-handles */
|
||||
BKE_nurb_handle_calc(bezt, prev, next, true, fcu->auto_smoothing);
|
||||
BKE_nurb_handle_calc_ex(bezt, prev, next, handle_sel_flag, true, fcu->auto_smoothing);
|
||||
|
||||
/* for automatic ease in and out */
|
||||
if (BEZT_IS_AUTOH(bezt) && !cycle) {
|
||||
@@ -1121,7 +1125,29 @@ void calchandles_fcurve(FCurve *fcu)
|
||||
}
|
||||
}
|
||||
|
||||
void testhandles_fcurve(FCurve *fcu, const bool use_handle)
|
||||
/**
|
||||
* This function recalculates the handles of an F-Curve. Acts based on selection with `SELECT`
|
||||
* flag. To use a different flag, use #calchandles_fcurve_ex().
|
||||
*
|
||||
* If the BezTriples have been rearranged, sort them first before using this.
|
||||
*/
|
||||
void calchandles_fcurve(FCurve *fcu)
|
||||
{
|
||||
calchandles_fcurve_ex(fcu, SELECT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update handles, making sure the handle-types are valid (e.g. correctly deduced from an "Auto"
|
||||
* type), and recalculating their position vectors.
|
||||
* Use when something has changed handle positions.
|
||||
*
|
||||
* \param sel_flag: The flag (bezt.f1/2/3) value to use to determine selection. Usually `SELECT`,
|
||||
* but may want to use a different one at times (if caller does not operate on
|
||||
* selection).
|
||||
* \param use_handle: Check selection state of individual handles, otherwise always update both
|
||||
* handles if the key is selected.
|
||||
*/
|
||||
void testhandles_fcurve(FCurve *fcu, eBezTriple_Flag sel_flag, const bool use_handle)
|
||||
{
|
||||
BezTriple *bezt;
|
||||
unsigned int a;
|
||||
@@ -1133,11 +1159,11 @@ void testhandles_fcurve(FCurve *fcu, const bool use_handle)
|
||||
|
||||
/* loop over beztriples */
|
||||
for (a = 0, bezt = fcu->bezt; a < fcu->totvert; a++, bezt++) {
|
||||
BKE_nurb_bezt_handle_test(bezt, use_handle);
|
||||
BKE_nurb_bezt_handle_test(bezt, sel_flag, use_handle);
|
||||
}
|
||||
|
||||
/* recalculate handles */
|
||||
calchandles_fcurve(fcu);
|
||||
calchandles_fcurve_ex(fcu, sel_flag);
|
||||
}
|
||||
|
||||
/* This function sorts BezTriples so that they are arranged in chronological order,
|
||||
|
@@ -25,7 +25,6 @@
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <wchar.h>
|
||||
#include <wctype.h>
|
||||
|
||||
#include "CLG_log.h"
|
||||
@@ -691,7 +690,7 @@ static bool vfont_to_curve(Object *ob,
|
||||
int mode,
|
||||
VFontToCurveIter *iter_data,
|
||||
ListBase *r_nubase,
|
||||
const wchar_t **r_text,
|
||||
const char32_t **r_text,
|
||||
int *r_text_len,
|
||||
bool *r_text_free,
|
||||
struct CharTrans **r_chartransdata)
|
||||
@@ -712,8 +711,8 @@ static bool vfont_to_curve(Object *ob,
|
||||
int curbox;
|
||||
int selstart, selend;
|
||||
int cnr = 0, lnr = 0, wsnr = 0;
|
||||
const wchar_t *mem = NULL;
|
||||
wchar_t ascii;
|
||||
const char32_t *mem = NULL;
|
||||
char32_t ascii;
|
||||
bool ok = false;
|
||||
const float font_size = cu->fsize * iter_data->scale_to_fit;
|
||||
const float xof_scale = cu->xof / font_size;
|
||||
@@ -759,16 +758,16 @@ static bool vfont_to_curve(Object *ob,
|
||||
custrinfo = ef->textbufinfo;
|
||||
}
|
||||
else {
|
||||
wchar_t *mem_tmp;
|
||||
char32_t *mem_tmp;
|
||||
slen = cu->len_wchar;
|
||||
|
||||
/* Create unicode string */
|
||||
mem_tmp = MEM_malloc_arrayN((slen + 1), sizeof(wchar_t), "convertedmem");
|
||||
mem_tmp = MEM_malloc_arrayN((slen + 1), sizeof(*mem_tmp), "convertedmem");
|
||||
if (!mem_tmp) {
|
||||
return ok;
|
||||
}
|
||||
|
||||
BLI_strncpy_wchar_from_utf8(mem_tmp, cu->str, slen + 1);
|
||||
BLI_str_utf8_as_utf32(mem_tmp, cu->str, slen + 1);
|
||||
|
||||
if (cu->strinfo == NULL) { /* old file */
|
||||
cu->strinfo = MEM_calloc_arrayN((slen + 4), sizeof(CharInfo), "strinfo compat");
|
||||
@@ -1605,7 +1604,7 @@ bool BKE_vfont_to_curve_ex(Object *ob,
|
||||
Curve *cu,
|
||||
int mode,
|
||||
ListBase *r_nubase,
|
||||
const wchar_t **r_text,
|
||||
const char32_t **r_text,
|
||||
int *r_text_len,
|
||||
bool *r_text_free,
|
||||
struct CharTrans **r_chartransdata)
|
||||
@@ -1649,9 +1648,9 @@ bool BKE_vfont_to_curve(Object *ob, int mode)
|
||||
* \{ */
|
||||
|
||||
static struct {
|
||||
wchar_t *text_buffer;
|
||||
char32_t *text_buffer;
|
||||
CharInfo *info_buffer;
|
||||
size_t len_wchar;
|
||||
size_t len_utf32;
|
||||
size_t len_utf8;
|
||||
} g_vfont_clipboard = {NULL};
|
||||
|
||||
@@ -1659,19 +1658,19 @@ void BKE_vfont_clipboard_free(void)
|
||||
{
|
||||
MEM_SAFE_FREE(g_vfont_clipboard.text_buffer);
|
||||
MEM_SAFE_FREE(g_vfont_clipboard.info_buffer);
|
||||
g_vfont_clipboard.len_wchar = 0;
|
||||
g_vfont_clipboard.len_utf32 = 0;
|
||||
g_vfont_clipboard.len_utf8 = 0;
|
||||
}
|
||||
|
||||
void BKE_vfont_clipboard_set(const wchar_t *text_buf, const CharInfo *info_buf, const size_t len)
|
||||
void BKE_vfont_clipboard_set(const char32_t *text_buf, const CharInfo *info_buf, const size_t len)
|
||||
{
|
||||
wchar_t *text;
|
||||
char32_t *text;
|
||||
CharInfo *info;
|
||||
|
||||
/* clean previous buffers*/
|
||||
BKE_vfont_clipboard_free();
|
||||
|
||||
text = MEM_malloc_arrayN((len + 1), sizeof(wchar_t), __func__);
|
||||
text = MEM_malloc_arrayN((len + 1), sizeof(*text), __func__);
|
||||
if (text == NULL) {
|
||||
return;
|
||||
}
|
||||
@@ -1682,21 +1681,21 @@ void BKE_vfont_clipboard_set(const wchar_t *text_buf, const CharInfo *info_buf,
|
||||
return;
|
||||
}
|
||||
|
||||
memcpy(text, text_buf, len * sizeof(wchar_t));
|
||||
memcpy(text, text_buf, len * sizeof(*text));
|
||||
text[len] = '\0';
|
||||
memcpy(info, info_buf, len * sizeof(CharInfo));
|
||||
|
||||
/* store new buffers */
|
||||
g_vfont_clipboard.text_buffer = text;
|
||||
g_vfont_clipboard.info_buffer = info;
|
||||
g_vfont_clipboard.len_utf8 = BLI_wstrlen_utf8(text);
|
||||
g_vfont_clipboard.len_wchar = len;
|
||||
g_vfont_clipboard.len_utf8 = BLI_str_utf32_as_utf8_len(text);
|
||||
g_vfont_clipboard.len_utf32 = len;
|
||||
}
|
||||
|
||||
void BKE_vfont_clipboard_get(wchar_t **r_text_buf,
|
||||
void BKE_vfont_clipboard_get(char32_t **r_text_buf,
|
||||
CharInfo **r_info_buf,
|
||||
size_t *r_len_utf8,
|
||||
size_t *r_len_wchar)
|
||||
size_t *r_len_utf32)
|
||||
{
|
||||
if (r_text_buf) {
|
||||
*r_text_buf = g_vfont_clipboard.text_buffer;
|
||||
@@ -1706,8 +1705,8 @@ void BKE_vfont_clipboard_get(wchar_t **r_text_buf,
|
||||
*r_info_buf = g_vfont_clipboard.info_buffer;
|
||||
}
|
||||
|
||||
if (r_len_wchar) {
|
||||
*r_len_wchar = g_vfont_clipboard.len_wchar;
|
||||
if (r_len_utf32) {
|
||||
*r_len_utf32 = g_vfont_clipboard.len_utf32;
|
||||
}
|
||||
|
||||
if (r_len_utf8) {
|
||||
|
@@ -36,6 +36,7 @@
|
||||
#include "BKE_main.h"
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_ghash.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_string.h"
|
||||
|
||||
@@ -148,6 +149,10 @@ void BKE_override_library_clear(IDOverrideLibrary *override, const bool do_id_us
|
||||
{
|
||||
BLI_assert(override != NULL);
|
||||
|
||||
if (override->runtime != NULL) {
|
||||
BLI_ghash_clear(override->runtime, NULL, NULL);
|
||||
}
|
||||
|
||||
for (IDOverrideLibraryProperty *op = override->properties.first; op; op = op->next) {
|
||||
bke_override_property_clear(op);
|
||||
}
|
||||
@@ -164,6 +169,11 @@ void BKE_override_library_free(struct IDOverrideLibrary **override, const bool d
|
||||
{
|
||||
BLI_assert(*override != NULL);
|
||||
|
||||
if ((*override)->runtime != NULL) {
|
||||
BLI_ghash_free((*override)->runtime, NULL, NULL);
|
||||
(*override)->runtime = NULL;
|
||||
}
|
||||
|
||||
BKE_override_library_clear(*override, do_id_user);
|
||||
MEM_freeN(*override);
|
||||
*override = NULL;
|
||||
@@ -285,15 +295,28 @@ bool BKE_override_library_create_from_tag(Main *bmain)
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* We only build override GHash on request. */
|
||||
BLI_INLINE IDOverrideLibraryRuntime *override_library_rna_path_mapping_ensure(
|
||||
IDOverrideLibrary *override)
|
||||
{
|
||||
if (override->runtime == NULL) {
|
||||
override->runtime = BLI_ghash_new(BLI_ghashutil_strhash_p, BLI_ghashutil_strcmp, __func__);
|
||||
for (IDOverrideLibraryProperty *op = override->properties.first; op != NULL; op = op->next) {
|
||||
BLI_ghash_insert(override->runtime, op->rna_path, op);
|
||||
}
|
||||
}
|
||||
|
||||
return override->runtime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Find override property from given RNA path, if it exists.
|
||||
*/
|
||||
IDOverrideLibraryProperty *BKE_override_library_property_find(IDOverrideLibrary *override,
|
||||
const char *rna_path)
|
||||
{
|
||||
/* XXX TODO we'll most likely want a runtime ghash to store that mapping at some point. */
|
||||
return BLI_findstring_ptr(
|
||||
&override->properties, rna_path, offsetof(IDOverrideLibraryProperty, rna_path));
|
||||
IDOverrideLibraryRuntime *override_runtime = override_library_rna_path_mapping_ensure(override);
|
||||
return BLI_ghash_lookup(override_runtime, rna_path);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -303,7 +326,6 @@ IDOverrideLibraryProperty *BKE_override_library_property_get(IDOverrideLibrary *
|
||||
const char *rna_path,
|
||||
bool *r_created)
|
||||
{
|
||||
/* XXX TODO we'll most likely want a runtime ghash to store that mapping at some point. */
|
||||
IDOverrideLibraryProperty *op = BKE_override_library_property_find(override, rna_path);
|
||||
|
||||
if (op == NULL) {
|
||||
@@ -311,6 +333,10 @@ IDOverrideLibraryProperty *BKE_override_library_property_get(IDOverrideLibrary *
|
||||
op->rna_path = BLI_strdup(rna_path);
|
||||
BLI_addtail(&override->properties, op);
|
||||
|
||||
IDOverrideLibraryRuntime *override_runtime = override_library_rna_path_mapping_ensure(
|
||||
override);
|
||||
BLI_ghash_insert(override_runtime, op->rna_path, op);
|
||||
|
||||
if (r_created) {
|
||||
*r_created = true;
|
||||
}
|
||||
@@ -355,6 +381,9 @@ void BKE_override_library_property_delete(IDOverrideLibrary *override,
|
||||
IDOverrideLibraryProperty *override_property)
|
||||
{
|
||||
bke_override_property_clear(override_property);
|
||||
if (override->runtime != NULL) {
|
||||
BLI_ghash_remove(override->runtime, override_property->rna_path, NULL, NULL);
|
||||
}
|
||||
BLI_freelinkN(&override->properties, override_property);
|
||||
}
|
||||
|
||||
|
@@ -491,7 +491,7 @@ static void make_duplis_font(const DupliContext *ctx)
|
||||
float vec[3], obmat[4][4], pmat[4][4], fsize, xof, yof;
|
||||
int text_len, a;
|
||||
size_t family_len;
|
||||
const wchar_t *text = NULL;
|
||||
const char32_t *text = NULL;
|
||||
bool text_free = false;
|
||||
|
||||
/* font dupliverts not supported inside collections */
|
||||
|
@@ -25,7 +25,6 @@
|
||||
#include <string.h> /* strstr */
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <wchar.h>
|
||||
#include <wctype.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
@@ -45,7 +45,7 @@ void BLI_str_cursor_step_utf8(const char *str,
|
||||
eStrCursorJumpType jump,
|
||||
bool use_init_step);
|
||||
|
||||
void BLI_str_cursor_step_wchar(const wchar_t *str,
|
||||
void BLI_str_cursor_step_utf32(const char32_t *str,
|
||||
size_t maxlen,
|
||||
int *pos,
|
||||
eStrCursorJumpDirection direction,
|
||||
|
@@ -26,6 +26,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
#include "BLI_compiler_attrs.h"
|
||||
#include "BLI_sys_types.h"
|
||||
|
||||
char *BLI_strncpy_utf8(char *__restrict dst, const char *__restrict src, size_t maxncpy)
|
||||
ATTR_NONNULL();
|
||||
@@ -48,6 +49,13 @@ unsigned int BLI_str_utf8_as_unicode_and_size_safe(const char *__restrict p,
|
||||
unsigned int BLI_str_utf8_as_unicode_step(const char *__restrict p, size_t *__restrict index)
|
||||
ATTR_NONNULL();
|
||||
size_t BLI_str_utf8_from_unicode(unsigned int c, char *outbuf);
|
||||
size_t BLI_str_utf8_as_utf32(char32_t *__restrict dst_w,
|
||||
const char *__restrict src_c,
|
||||
const size_t maxncpy) ATTR_NONNULL();
|
||||
size_t BLI_str_utf32_as_utf8(char *__restrict dst,
|
||||
const char32_t *__restrict src,
|
||||
const size_t maxncpy) ATTR_NONNULL();
|
||||
size_t BLI_str_utf32_as_utf8_len(const char32_t *src) ATTR_NONNULL();
|
||||
|
||||
char *BLI_str_find_prev_char_utf8(const char *str, const char *p) ATTR_NONNULL();
|
||||
char *BLI_str_find_next_char_utf8(const char *p, const char *end) ATTR_NONNULL(1);
|
||||
@@ -68,8 +76,8 @@ size_t BLI_strncpy_wchar_from_utf8(wchar_t *__restrict dst,
|
||||
const size_t maxcpy) ATTR_NONNULL();
|
||||
|
||||
/* count columns that character/string occupies, based on wcwidth.c */
|
||||
int BLI_wcwidth(wchar_t ucs);
|
||||
int BLI_wcswidth(const wchar_t *pwcs, size_t n) ATTR_NONNULL();
|
||||
int BLI_wcwidth(char32_t ucs);
|
||||
int BLI_wcswidth(const char32_t *pwcs, size_t n) ATTR_NONNULL();
|
||||
/* warning, can return -1 on bad chars */
|
||||
int BLI_str_utf8_char_width(const char *p) ATTR_NONNULL();
|
||||
int BLI_str_utf8_char_width_safe(const char *p) ATTR_NONNULL();
|
||||
|
@@ -72,6 +72,15 @@ typedef uint64_t u_int64_t;
|
||||
#include <stddef.h> /* size_t define */
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef __cplusplus
|
||||
# if defined(__APPLE__)
|
||||
/* The <uchar.h> standard header is missing on macOS. */
|
||||
typedef unsigned int char32_t;
|
||||
# else
|
||||
# include <uchar.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
typedef unsigned int uint;
|
||||
typedef unsigned short ushort;
|
||||
typedef unsigned long ulong;
|
||||
|
@@ -211,12 +211,12 @@ void BLI_str_cursor_step_utf8(const char *str,
|
||||
}
|
||||
}
|
||||
|
||||
/* wchar_t version of BLI_str_cursor_step_utf8 (keep in sync!)
|
||||
/* UTF32 version of BLI_str_cursor_step_utf8 (keep in sync!)
|
||||
* less complex since it doesn't need to do multi-byte stepping.
|
||||
*/
|
||||
|
||||
/* helper funcs so we can match BLI_str_cursor_step_utf8 */
|
||||
static bool wchar_t_step_next(const wchar_t *UNUSED(str), size_t maxlen, int *pos)
|
||||
static bool cursor_step_next_utf32(const char32_t *UNUSED(str), size_t maxlen, int *pos)
|
||||
{
|
||||
if ((*pos) >= (int)maxlen) {
|
||||
return false;
|
||||
@@ -225,7 +225,7 @@ static bool wchar_t_step_next(const wchar_t *UNUSED(str), size_t maxlen, int *po
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool wchar_t_step_prev(const wchar_t *UNUSED(str), size_t UNUSED(maxlen), int *pos)
|
||||
static bool cursor_step_prev_utf32(const char32_t *UNUSED(str), size_t UNUSED(maxlen), int *pos)
|
||||
{
|
||||
if ((*pos) <= 0) {
|
||||
return false;
|
||||
@@ -234,7 +234,7 @@ static bool wchar_t_step_prev(const wchar_t *UNUSED(str), size_t UNUSED(maxlen),
|
||||
return true;
|
||||
}
|
||||
|
||||
void BLI_str_cursor_step_wchar(const wchar_t *str,
|
||||
void BLI_str_cursor_step_utf32(const char32_t *str,
|
||||
size_t maxlen,
|
||||
int *pos,
|
||||
eStrCursorJumpDirection direction,
|
||||
@@ -245,7 +245,7 @@ void BLI_str_cursor_step_wchar(const wchar_t *str,
|
||||
|
||||
if (direction == STRCUR_DIR_NEXT) {
|
||||
if (use_init_step) {
|
||||
wchar_t_step_next(str, maxlen, pos);
|
||||
cursor_step_next_utf32(str, maxlen, pos);
|
||||
}
|
||||
else {
|
||||
BLI_assert(jump == STRCUR_JUMP_DELIM);
|
||||
@@ -259,7 +259,7 @@ void BLI_str_cursor_step_wchar(const wchar_t *str,
|
||||
* look at function cursor_delim_type_unicode() for complete
|
||||
* list of special character, ctr -> */
|
||||
while ((*pos) < maxlen) {
|
||||
if (wchar_t_step_next(str, maxlen, pos)) {
|
||||
if (cursor_step_next_utf32(str, maxlen, pos)) {
|
||||
if ((jump != STRCUR_JUMP_ALL) &&
|
||||
(delim_type != cursor_delim_type_unicode((uint)str[*pos]))) {
|
||||
break;
|
||||
@@ -273,7 +273,7 @@ void BLI_str_cursor_step_wchar(const wchar_t *str,
|
||||
}
|
||||
else if (direction == STRCUR_DIR_PREV) {
|
||||
if (use_init_step) {
|
||||
wchar_t_step_prev(str, maxlen, pos);
|
||||
cursor_step_prev_utf32(str, maxlen, pos);
|
||||
}
|
||||
else {
|
||||
BLI_assert(jump == STRCUR_JUMP_DELIM);
|
||||
@@ -288,7 +288,7 @@ void BLI_str_cursor_step_wchar(const wchar_t *str,
|
||||
* list of special character, ctr -> */
|
||||
while ((*pos) > 0) {
|
||||
const int pos_prev = *pos;
|
||||
if (wchar_t_step_prev(str, maxlen, pos)) {
|
||||
if (cursor_step_prev_utf32(str, maxlen, pos)) {
|
||||
if ((jump != STRCUR_JUMP_ALL) &&
|
||||
(delim_type != cursor_delim_type_unicode((uint)str[*pos]))) {
|
||||
/* left only: compensate for index/change in direction */
|
||||
|
@@ -430,6 +430,11 @@ size_t BLI_strncpy_wchar_from_utf8(wchar_t *__restrict dst_w,
|
||||
size_t step = 0;
|
||||
uint unicode = BLI_str_utf8_as_unicode_and_size(src_c, &step);
|
||||
if (unicode != BLI_UTF8_ERR) {
|
||||
/* TODO: `wchar_t` type is an implementation-defined and may represent
|
||||
* 16-bit or 32-bit depending on operating system.
|
||||
* So the ideal would be to do the corresponding encoding.
|
||||
* But for now just assert that it has no conflicting use. */
|
||||
BLI_assert(step <= sizeof(wchar_t));
|
||||
*dst_w = (wchar_t)unicode;
|
||||
src_c += step;
|
||||
}
|
||||
@@ -451,12 +456,12 @@ size_t BLI_strncpy_wchar_from_utf8(wchar_t *__restrict dst_w,
|
||||
|
||||
/* count columns that character/string occupies, based on wcwidth.c */
|
||||
|
||||
int BLI_wcwidth(wchar_t ucs)
|
||||
int BLI_wcwidth(char32_t ucs)
|
||||
{
|
||||
return mk_wcwidth(ucs);
|
||||
}
|
||||
|
||||
int BLI_wcswidth(const wchar_t *pwcs, size_t n)
|
||||
int BLI_wcswidth(const char32_t *pwcs, size_t n)
|
||||
{
|
||||
return mk_wcswidth(pwcs, n);
|
||||
}
|
||||
@@ -468,7 +473,7 @@ int BLI_str_utf8_char_width(const char *p)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return BLI_wcwidth((wchar_t)unicode);
|
||||
return BLI_wcwidth((char32_t)unicode);
|
||||
}
|
||||
|
||||
int BLI_str_utf8_char_width_safe(const char *p)
|
||||
@@ -480,7 +485,7 @@ int BLI_str_utf8_char_width_safe(const char *p)
|
||||
return 1;
|
||||
}
|
||||
|
||||
columns = BLI_wcwidth((wchar_t)unicode);
|
||||
columns = BLI_wcwidth((char32_t)unicode);
|
||||
|
||||
return (columns < 0) ? 1 : columns;
|
||||
}
|
||||
@@ -726,6 +731,88 @@ size_t BLI_str_utf8_from_unicode(uint c, char *outbuf)
|
||||
return len;
|
||||
}
|
||||
|
||||
size_t BLI_str_utf8_as_utf32(char32_t *__restrict dst_w,
|
||||
const char *__restrict src_c,
|
||||
const size_t maxncpy)
|
||||
{
|
||||
const size_t maxlen = maxncpy - 1;
|
||||
size_t len = 0;
|
||||
|
||||
BLI_assert(maxncpy != 0);
|
||||
|
||||
#ifdef DEBUG_STRSIZE
|
||||
memset(dst_w, 0xff, sizeof(*dst_w) * maxncpy);
|
||||
#endif
|
||||
|
||||
while (*src_c && len != maxlen) {
|
||||
size_t step = 0;
|
||||
uint unicode = BLI_str_utf8_as_unicode_and_size(src_c, &step);
|
||||
if (unicode != BLI_UTF8_ERR) {
|
||||
*dst_w = unicode;
|
||||
src_c += step;
|
||||
}
|
||||
else {
|
||||
*dst_w = '?';
|
||||
src_c = BLI_str_find_next_char_utf8(src_c, NULL);
|
||||
}
|
||||
dst_w++;
|
||||
len++;
|
||||
}
|
||||
|
||||
*dst_w = 0;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
size_t BLI_str_utf32_as_utf8(char *__restrict dst,
|
||||
const char32_t *__restrict src,
|
||||
const size_t maxncpy)
|
||||
{
|
||||
const size_t maxlen = maxncpy - 1;
|
||||
/* 6 is max utf8 length of an unicode char. */
|
||||
const int64_t maxlen_secured = (int64_t)maxlen - 6;
|
||||
size_t len = 0;
|
||||
|
||||
BLI_assert(maxncpy != 0);
|
||||
|
||||
#ifdef DEBUG_STRSIZE
|
||||
memset(dst, 0xff, sizeof(*dst) * maxncpy);
|
||||
#endif
|
||||
|
||||
while (*src && len <= maxlen_secured) {
|
||||
len += BLI_str_utf8_from_unicode((uint)*src++, dst + len);
|
||||
}
|
||||
|
||||
/* We have to be more careful for the last six bytes,
|
||||
* to avoid buffer overflow in case utf8-encoded char would be too long for our dst buffer. */
|
||||
while (*src) {
|
||||
char t[6];
|
||||
size_t l = BLI_str_utf8_from_unicode((uint)*src++, t);
|
||||
BLI_assert(l <= 6);
|
||||
if (len + l > maxlen) {
|
||||
break;
|
||||
}
|
||||
memcpy(dst + len, t, l);
|
||||
len += l;
|
||||
}
|
||||
|
||||
dst[len] = '\0';
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/* utf32 len in utf8 */
|
||||
size_t BLI_str_utf32_as_utf8_len(const char32_t *src)
|
||||
{
|
||||
size_t len = 0;
|
||||
|
||||
while (*src) {
|
||||
len += BLI_str_utf8_from_unicode((uint)*src++, NULL);
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
/* was g_utf8_find_prev_char */
|
||||
/**
|
||||
* BLI_str_find_prev_char_utf8:
|
||||
|
@@ -2668,6 +2668,7 @@ static void direct_link_id(FileData *fd, ID *id)
|
||||
if (id->override_library) {
|
||||
id->override_library = newdataadr(fd, id->override_library);
|
||||
link_list_ex(fd, &id->override_library->properties, direct_link_id_override_property_cb);
|
||||
id->override_library->runtime = NULL;
|
||||
}
|
||||
|
||||
DrawDataList *drawdata = DRW_drawdatalist_from_id(id);
|
||||
|
@@ -5492,7 +5492,11 @@ static void build_vmesh(BevelParams *bp, BMesh *bm, BevVert *bv)
|
||||
}
|
||||
else { /* Get the last of the two BoundVerts. */
|
||||
weld2 = bndv;
|
||||
move_weld_profile_planes(bv, weld1, weld2); /* Profile recalculated in next loop. */
|
||||
move_weld_profile_planes(bv, weld1, weld2);
|
||||
if (!bp->use_custom_profile) { /* Else profile recalculated in next loop. */
|
||||
calculate_profile(bp, weld1, !weld1->is_profile_start, false);
|
||||
calculate_profile(bp, weld2, !weld2->is_profile_start, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
} while ((bndv = bndv->next) != vm->boundstart);
|
||||
|
@@ -1403,9 +1403,11 @@ void DepsgraphRelationBuilder::build_action(bAction *action)
|
||||
if (built_map_.checkIsBuiltAndTag(action)) {
|
||||
return;
|
||||
}
|
||||
TimeSourceKey time_src_key;
|
||||
ComponentKey animation_key(&action->id, NodeType::ANIMATION);
|
||||
add_relation(time_src_key, animation_key, "TimeSrc -> Animation");
|
||||
if (!BLI_listbase_is_empty(&action->curves)) {
|
||||
TimeSourceKey time_src_key;
|
||||
ComponentKey animation_key(&action->id, NodeType::ANIMATION);
|
||||
add_relation(time_src_key, animation_key, "TimeSrc -> Animation");
|
||||
}
|
||||
}
|
||||
|
||||
void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu)
|
||||
|
@@ -501,10 +501,16 @@ void ANIM_editkeyframes_refresh(bAnimContext *ac)
|
||||
ok |= KEYFRAME_OK_KEY; \
|
||||
\
|
||||
if (ked && (ked->iterflags & KEYFRAME_ITER_INCL_HANDLES)) { \
|
||||
if (check(0)) \
|
||||
ok |= KEYFRAME_OK_H1; \
|
||||
if (check(2)) \
|
||||
ok |= KEYFRAME_OK_H2; \
|
||||
/* Only act on visible items, so check handle visiblity state. */ \
|
||||
const bool handles_visible = ((ked->iterflags & KEYFRAME_ITER_HANDLES_DEFAULT_INVISIBLE) ? \
|
||||
(BEZT_ISSEL_ANY(bezt)) : \
|
||||
true); \
|
||||
if (handles_visible) { \
|
||||
if (check(0)) \
|
||||
ok |= KEYFRAME_OK_H1; \
|
||||
if (check(2)) \
|
||||
ok |= KEYFRAME_OK_H2; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
(void)0
|
||||
@@ -1054,7 +1060,11 @@ KeyframeEditFunc ANIM_editkeyframes_mirror(short type)
|
||||
/* Sets the selected bezier handles to type 'auto' */
|
||||
static short set_bezier_auto(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
|
||||
{
|
||||
if ((bezt->f1 & SELECT) || (bezt->f3 & SELECT)) {
|
||||
/* If the key is selected, always apply to both handles. */
|
||||
if (bezt->f2 & SELECT) {
|
||||
bezt->h1 = bezt->h2 = HD_AUTO;
|
||||
}
|
||||
else {
|
||||
if (bezt->f1 & SELECT) {
|
||||
bezt->h1 = HD_AUTO;
|
||||
}
|
||||
@@ -1064,6 +1074,7 @@ static short set_bezier_auto(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
|
||||
|
||||
ENSURE_HANDLES_MATCH(bezt);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1072,7 +1083,11 @@ static short set_bezier_auto(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
|
||||
*/
|
||||
static short set_bezier_auto_clamped(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
|
||||
{
|
||||
if ((bezt->f1 & SELECT) || (bezt->f3 & SELECT)) {
|
||||
/* If the key is selected, always apply to both handles. */
|
||||
if (bezt->f2 & SELECT) {
|
||||
bezt->h1 = bezt->h2 = HD_AUTO_ANIM;
|
||||
}
|
||||
else {
|
||||
if (bezt->f1 & SELECT) {
|
||||
bezt->h1 = HD_AUTO_ANIM;
|
||||
}
|
||||
@@ -1082,18 +1097,26 @@ static short set_bezier_auto_clamped(KeyframeEditData *UNUSED(ked), BezTriple *b
|
||||
|
||||
ENSURE_HANDLES_MATCH(bezt);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Sets the selected bezier handles to type 'vector' */
|
||||
static short set_bezier_vector(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
|
||||
{
|
||||
if (bezt->f1 & SELECT) {
|
||||
bezt->h1 = HD_VECT;
|
||||
/* If the key is selected, always apply to both handles. */
|
||||
if (bezt->f2 & SELECT) {
|
||||
bezt->h1 = bezt->h2 = HD_VECT;
|
||||
}
|
||||
if (bezt->f3 & SELECT) {
|
||||
bezt->h2 = HD_VECT;
|
||||
else {
|
||||
if (bezt->f1 & SELECT) {
|
||||
bezt->h1 = HD_VECT;
|
||||
}
|
||||
if (bezt->f3 & SELECT) {
|
||||
bezt->h2 = HD_VECT;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1114,24 +1137,38 @@ static short bezier_isfree(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
|
||||
/* Sets selected bezier handles to type 'align' */
|
||||
static short set_bezier_align(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
|
||||
{
|
||||
if (bezt->f1 & SELECT) {
|
||||
bezt->h1 = HD_ALIGN;
|
||||
/* If the key is selected, always apply to both handles. */
|
||||
if (bezt->f2 & SELECT) {
|
||||
bezt->h1 = bezt->h2 = HD_ALIGN;
|
||||
}
|
||||
if (bezt->f3 & SELECT) {
|
||||
bezt->h2 = HD_ALIGN;
|
||||
else {
|
||||
if (bezt->f1 & SELECT) {
|
||||
bezt->h1 = HD_ALIGN;
|
||||
}
|
||||
if (bezt->f3 & SELECT) {
|
||||
bezt->h2 = HD_ALIGN;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Sets selected bezier handles to type 'free' */
|
||||
static short set_bezier_free(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
|
||||
{
|
||||
if (bezt->f1 & SELECT) {
|
||||
bezt->h1 = HD_FREE;
|
||||
/* If the key is selected, always apply to both handles. */
|
||||
if (bezt->f2 & SELECT) {
|
||||
bezt->h1 = bezt->h2 = HD_FREE;
|
||||
}
|
||||
if (bezt->f3 & SELECT) {
|
||||
bezt->h2 = HD_FREE;
|
||||
else {
|
||||
if (bezt->f1 & SELECT) {
|
||||
bezt->h1 = HD_FREE;
|
||||
}
|
||||
if (bezt->f3 & SELECT) {
|
||||
bezt->h2 = HD_FREE;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1422,8 +1459,13 @@ KeyframeEditFunc ANIM_editkeyframes_easing(short mode)
|
||||
|
||||
static short select_bezier_add(KeyframeEditData *ked, BezTriple *bezt)
|
||||
{
|
||||
/* Only act on visible items, so check handle visiblity state. */
|
||||
const bool handles_visible = ked && ((ked->iterflags & KEYFRAME_ITER_HANDLES_DEFAULT_INVISIBLE) ?
|
||||
(BEZT_ISSEL_ANY(bezt)) :
|
||||
true);
|
||||
|
||||
/* if we've got info on what to select, use it, otherwise select all */
|
||||
if ((ked) && (ked->iterflags & KEYFRAME_ITER_INCL_HANDLES)) {
|
||||
if ((ked) && (ked->iterflags & KEYFRAME_ITER_INCL_HANDLES) && handles_visible) {
|
||||
if (ked->curflags & KEYFRAME_OK_KEY) {
|
||||
bezt->f2 |= SELECT;
|
||||
}
|
||||
@@ -1443,8 +1485,13 @@ static short select_bezier_add(KeyframeEditData *ked, BezTriple *bezt)
|
||||
|
||||
static short select_bezier_subtract(KeyframeEditData *ked, BezTriple *bezt)
|
||||
{
|
||||
/* Only act on visible items, so check handle visiblity state. */
|
||||
const bool handles_visible = ked && ((ked->iterflags & KEYFRAME_ITER_HANDLES_DEFAULT_INVISIBLE) ?
|
||||
(BEZT_ISSEL_ANY(bezt)) :
|
||||
true);
|
||||
|
||||
/* if we've got info on what to deselect, use it, otherwise deselect all */
|
||||
if ((ked) && (ked->iterflags & KEYFRAME_ITER_INCL_HANDLES)) {
|
||||
if ((ked) && (ked->iterflags & KEYFRAME_ITER_INCL_HANDLES) && handles_visible) {
|
||||
if (ked->curflags & KEYFRAME_OK_KEY) {
|
||||
bezt->f2 &= ~SELECT;
|
||||
}
|
||||
|
@@ -468,7 +468,8 @@ static int kill_selection(Object *obedit, int ins) /* 1 == new character */
|
||||
if (ins == 0) {
|
||||
getfrom++;
|
||||
}
|
||||
size = (ef->len * sizeof(wchar_t)) - (selstart * sizeof(wchar_t)) + (offset * sizeof(wchar_t));
|
||||
size = (ef->len * sizeof(*ef->textbuf)) - (selstart * sizeof(*ef->textbuf)) +
|
||||
(offset * sizeof(*ef->textbuf));
|
||||
memmove(ef->textbuf + selstart, ef->textbuf + getfrom, size);
|
||||
memmove(ef->textbufinfo + selstart,
|
||||
ef->textbufinfo + getfrom,
|
||||
@@ -488,7 +489,7 @@ static int kill_selection(Object *obedit, int ins) /* 1 == new character */
|
||||
|
||||
/* text_update_edited(C, scene, obedit, 1, FO_EDIT); */
|
||||
static bool font_paste_wchar(Object *obedit,
|
||||
const wchar_t *str,
|
||||
const char32_t *str,
|
||||
const size_t str_len,
|
||||
/* optional */
|
||||
struct CharInfo *str_info)
|
||||
@@ -507,9 +508,10 @@ static bool font_paste_wchar(Object *obedit,
|
||||
kill_selection(obedit, 0);
|
||||
|
||||
if (str_len) {
|
||||
int size = (ef->len * sizeof(wchar_t)) - (ef->pos * sizeof(wchar_t)) + sizeof(wchar_t);
|
||||
int size = (ef->len * sizeof(*ef->textbuf)) - (ef->pos * sizeof(*ef->textbuf)) +
|
||||
sizeof(*ef->textbuf);
|
||||
memmove(ef->textbuf + ef->pos + str_len, ef->textbuf + ef->pos, size);
|
||||
memcpy(ef->textbuf + ef->pos, str, str_len * sizeof(wchar_t));
|
||||
memcpy(ef->textbuf + ef->pos, str, str_len * sizeof(*ef->textbuf));
|
||||
|
||||
memmove(ef->textbufinfo + ef->pos + str_len,
|
||||
ef->textbufinfo + ef->pos,
|
||||
@@ -538,9 +540,9 @@ static bool font_paste_utf8(bContext *C, const char *str, const size_t str_len)
|
||||
|
||||
int tmplen;
|
||||
|
||||
wchar_t *mem = MEM_mallocN((sizeof(wchar_t) * (str_len + 1)), __func__);
|
||||
char32_t *mem = MEM_mallocN((sizeof(*mem) * (str_len + 1)), __func__);
|
||||
|
||||
tmplen = BLI_strncpy_wchar_from_utf8(mem, str, str_len + 1);
|
||||
tmplen = BLI_str_utf8_as_utf32(mem, str, str_len + 1);
|
||||
|
||||
retval = font_paste_wchar(obedit, mem, tmplen, NULL);
|
||||
|
||||
@@ -919,7 +921,7 @@ static void copy_selection(Object *obedit)
|
||||
Curve *cu = obedit->data;
|
||||
EditFont *ef = cu->editfont;
|
||||
char *buf = NULL;
|
||||
wchar_t *text_buf;
|
||||
char32_t *text_buf;
|
||||
size_t len_utf8;
|
||||
|
||||
/* internal clipboard (for style) */
|
||||
@@ -930,7 +932,7 @@ static void copy_selection(Object *obedit)
|
||||
/* system clipboard */
|
||||
buf = MEM_mallocN(len_utf8 + 1, __func__);
|
||||
if (buf) {
|
||||
BLI_strncpy_wchar_as_utf8(buf, text_buf, len_utf8 + 1);
|
||||
BLI_str_utf32_as_utf8(buf, text_buf, len_utf8 + 1);
|
||||
WM_clipboard_text_set(buf, false);
|
||||
MEM_freeN(buf);
|
||||
}
|
||||
@@ -1004,7 +1006,7 @@ void FONT_OT_text_cut(wmOperatorType *ot)
|
||||
|
||||
static bool paste_selection(Object *obedit, ReportList *reports)
|
||||
{
|
||||
wchar_t *text_buf;
|
||||
char32_t *text_buf;
|
||||
CharInfo *info_buf;
|
||||
size_t len;
|
||||
|
||||
@@ -1024,7 +1026,7 @@ static int paste_text_exec(bContext *C, wmOperator *op)
|
||||
Object *obedit = CTX_data_edit_object(C);
|
||||
int retval;
|
||||
size_t len_utf8;
|
||||
wchar_t *text_buf;
|
||||
char32_t *text_buf;
|
||||
|
||||
/* Store both clipboards as utf8 for comparison,
|
||||
* Give priority to the internal 'vfont' clipboard with its 'CharInfo' text styles
|
||||
@@ -1050,7 +1052,7 @@ static int paste_text_exec(bContext *C, wmOperator *op)
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
BLI_strncpy_wchar_as_utf8(clipboard_vfont.buf, text_buf, len_utf8 + 1);
|
||||
BLI_str_utf32_as_utf8(clipboard_vfont.buf, text_buf, len_utf8 + 1);
|
||||
}
|
||||
|
||||
if (clipboard_vfont.buf && STREQ(clipboard_vfont.buf, clipboard_system.buf)) {
|
||||
@@ -1164,7 +1166,7 @@ static int move_cursor(bContext *C, int type, const bool select)
|
||||
|
||||
case PREV_WORD: {
|
||||
int pos = ef->pos;
|
||||
BLI_str_cursor_step_wchar(
|
||||
BLI_str_cursor_step_utf32(
|
||||
ef->textbuf, ef->len, &pos, STRCUR_DIR_PREV, STRCUR_JUMP_DELIM, true);
|
||||
ef->pos = pos;
|
||||
cursmove = FO_CURS;
|
||||
@@ -1173,7 +1175,7 @@ static int move_cursor(bContext *C, int type, const bool select)
|
||||
|
||||
case NEXT_WORD: {
|
||||
int pos = ef->pos;
|
||||
BLI_str_cursor_step_wchar(
|
||||
BLI_str_cursor_step_utf32(
|
||||
ef->textbuf, ef->len, &pos, STRCUR_DIR_NEXT, STRCUR_JUMP_DELIM, true);
|
||||
ef->pos = pos;
|
||||
cursmove = FO_CURS;
|
||||
@@ -1528,7 +1530,7 @@ static int delete_exec(bContext *C, wmOperator *op)
|
||||
break;
|
||||
case DEL_NEXT_WORD: {
|
||||
int pos = ef->pos;
|
||||
BLI_str_cursor_step_wchar(
|
||||
BLI_str_cursor_step_utf32(
|
||||
ef->textbuf, ef->len, &pos, STRCUR_DIR_NEXT, STRCUR_JUMP_DELIM, true);
|
||||
range[0] = ef->pos;
|
||||
range[1] = pos;
|
||||
@@ -1537,7 +1539,7 @@ static int delete_exec(bContext *C, wmOperator *op)
|
||||
|
||||
case DEL_PREV_WORD: {
|
||||
int pos = ef->pos;
|
||||
BLI_str_cursor_step_wchar(
|
||||
BLI_str_cursor_step_utf32(
|
||||
ef->textbuf, ef->len, &pos, STRCUR_DIR_PREV, STRCUR_JUMP_DELIM, true);
|
||||
range[0] = pos;
|
||||
range[1] = ef->pos;
|
||||
@@ -1864,12 +1866,12 @@ void ED_curve_editfont_make(Object *obedit)
|
||||
if (ef == NULL) {
|
||||
ef = cu->editfont = MEM_callocN(sizeof(EditFont), "editfont");
|
||||
|
||||
ef->textbuf = MEM_callocN((MAXTEXT + 4) * sizeof(wchar_t), "texteditbuf");
|
||||
ef->textbuf = MEM_callocN((MAXTEXT + 4) * sizeof(*ef->textbuf), "texteditbuf");
|
||||
ef->textbufinfo = MEM_callocN((MAXTEXT + 4) * sizeof(CharInfo), "texteditbufinfo");
|
||||
}
|
||||
|
||||
/* Convert the original text to wchar_t */
|
||||
len_wchar = BLI_strncpy_wchar_from_utf8(ef->textbuf, cu->str, MAXTEXT + 4);
|
||||
len_wchar = BLI_str_utf8_as_utf32(ef->textbuf, cu->str, MAXTEXT + 4);
|
||||
BLI_assert(len_wchar == cu->len_wchar);
|
||||
ef->len = len_wchar;
|
||||
BLI_assert(ef->len >= 0);
|
||||
@@ -1901,13 +1903,13 @@ void ED_curve_editfont_load(Object *obedit)
|
||||
|
||||
/* Calculate the actual string length in UTF-8 variable characters */
|
||||
cu->len_wchar = ef->len;
|
||||
cu->len = BLI_wstrlen_utf8(ef->textbuf);
|
||||
cu->len = BLI_str_utf32_as_utf8_len(ef->textbuf);
|
||||
|
||||
/* Alloc memory for UTF-8 variable char length string */
|
||||
cu->str = MEM_mallocN(cu->len + sizeof(wchar_t), "str");
|
||||
cu->str = MEM_mallocN(cu->len + sizeof(char32_t), "str");
|
||||
|
||||
/* Copy the wchar to UTF-8 */
|
||||
BLI_strncpy_wchar_as_utf8(cu->str, ef->textbuf, cu->len + 1);
|
||||
BLI_str_utf32_as_utf8(cu->str, ef->textbuf, cu->len + 1);
|
||||
|
||||
if (cu->strinfo) {
|
||||
MEM_freeN(cu->strinfo);
|
||||
@@ -1943,7 +1945,7 @@ static int set_case(bContext *C, int ccase)
|
||||
Object *obedit = CTX_data_edit_object(C);
|
||||
Curve *cu = obedit->data;
|
||||
EditFont *ef = cu->editfont;
|
||||
wchar_t *str;
|
||||
char32_t *str;
|
||||
int len;
|
||||
int selstart, selend;
|
||||
|
||||
@@ -2010,18 +2012,16 @@ static int toggle_case_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
Object *obedit = CTX_data_edit_object(C);
|
||||
Curve *cu = obedit->data;
|
||||
EditFont *ef = cu->editfont;
|
||||
wchar_t *str;
|
||||
int len, ccase = CASE_UPPER;
|
||||
char32_t *str;
|
||||
int ccase = CASE_UPPER;
|
||||
|
||||
len = wcslen(ef->textbuf);
|
||||
str = ef->textbuf;
|
||||
while (len) {
|
||||
while (*str) {
|
||||
if (*str >= 'a' && *str <= 'z') {
|
||||
ccase = CASE_LOWER;
|
||||
break;
|
||||
}
|
||||
|
||||
len--;
|
||||
str++;
|
||||
}
|
||||
|
||||
|
@@ -20,7 +20,6 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
@@ -58,7 +57,7 @@
|
||||
* \{ */
|
||||
|
||||
typedef struct UndoFont {
|
||||
wchar_t *textbuf;
|
||||
char32_t *textbuf;
|
||||
struct CharInfo *textbufinfo;
|
||||
|
||||
int len, pos, selstart, selend;
|
||||
@@ -233,7 +232,7 @@ static void undofont_to_editfont(UndoFont *uf, Curve *cu)
|
||||
uf_arraystore_expand(uf);
|
||||
#endif
|
||||
|
||||
final_size = sizeof(wchar_t) * (uf->len + 1);
|
||||
final_size = sizeof(*ef->textbuf) * (uf->len + 1);
|
||||
memcpy(ef->textbuf, uf->textbuf, final_size);
|
||||
|
||||
final_size = sizeof(CharInfo) * (uf->len + 1);
|
||||
@@ -259,7 +258,8 @@ static void *undofont_from_editfont(UndoFont *uf, Curve *cu)
|
||||
|
||||
size_t final_size;
|
||||
|
||||
final_size = sizeof(wchar_t) * (ef->len + 1);
|
||||
BLI_assert(sizeof(*uf->textbuf) == sizeof(*ef->textbuf));
|
||||
final_size = sizeof(*uf->textbuf) * (ef->len + 1);
|
||||
uf->textbuf = MEM_mallocN(final_size, __func__);
|
||||
memcpy(uf->textbuf, ef->textbuf, final_size);
|
||||
|
||||
|
@@ -141,6 +141,12 @@ typedef enum eKeyframeIterFlags {
|
||||
|
||||
/* Perform NLA time remapping (global -> strip) for the "f2" parameter */
|
||||
KED_F2_NLA_UNMAP = (1 << 2),
|
||||
|
||||
/* Set this when handles aren't visible by default and you want to perform additional checks to
|
||||
* get the actual visibility state. E.g. in some cases handles are only drawn if either a handle
|
||||
* or their control point is selected. The selection state will have to be checked in the
|
||||
* iterator callbacks then. */
|
||||
KEYFRAME_ITER_HANDLES_DEFAULT_INVISIBLE = (1 << 3),
|
||||
} eKeyframeIterFlags;
|
||||
|
||||
/* --- Generic Properties for Keyframe Edit Tools ----- */
|
||||
|
@@ -923,6 +923,7 @@ bool edit_modifier_poll_generic(bContext *C,
|
||||
{
|
||||
PointerRNA ptr = CTX_data_pointer_get_type(C, "modifier", rna_type);
|
||||
Object *ob = (ptr.owner_id) ? (Object *)ptr.owner_id : ED_object_active_context(C);
|
||||
ModifierData *mod = ptr.data; /* May be NULL. */
|
||||
|
||||
if (!ob || ID_IS_LINKED(ob)) {
|
||||
return 0;
|
||||
@@ -935,8 +936,10 @@ bool edit_modifier_poll_generic(bContext *C,
|
||||
}
|
||||
|
||||
if (ID_IS_OVERRIDE_LIBRARY(ob)) {
|
||||
CTX_wm_operator_poll_msg_set(C, "Cannot edit modifiers coming from library override");
|
||||
return (((ModifierData *)ptr.data)->flag & eModifierFlag_OverrideLibrary_Local) != 0;
|
||||
if ((mod != NULL) && (mod->flag & eModifierFlag_OverrideLibrary_Local) == 0) {
|
||||
CTX_wm_operator_poll_msg_set(C, "Cannot edit modifiers coming from library override");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_editmode_allowed && CTX_data_edit_object(C) != NULL) {
|
||||
|
@@ -51,6 +51,7 @@ void CONSOLE_OT_delete(struct wmOperatorType *ot);
|
||||
void CONSOLE_OT_insert(struct wmOperatorType *ot);
|
||||
|
||||
void CONSOLE_OT_indent(struct wmOperatorType *ot);
|
||||
void CONSOLE_OT_indent_or_autocomplete(struct wmOperatorType *ot);
|
||||
void CONSOLE_OT_unindent(struct wmOperatorType *ot);
|
||||
|
||||
void CONSOLE_OT_history_append(struct wmOperatorType *ot);
|
||||
|
@@ -473,6 +473,44 @@ void CONSOLE_OT_insert(wmOperatorType *ot)
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Indent or Autocomplete Operator
|
||||
* \{ */
|
||||
|
||||
static int console_indent_or_autocomplete_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
ConsoleLine *ci = console_history_verify(C);
|
||||
bool text_before_cursor = ci->cursor != 0 && !ELEM(ci->line[ci->cursor - 1], ' ', '\t');
|
||||
if (text_before_cursor) {
|
||||
WM_operator_name_call(C, "CONSOLE_OT_autocomplete", WM_OP_INVOKE_DEFAULT, NULL);
|
||||
}
|
||||
else {
|
||||
WM_operator_name_call(C, "CONSOLE_OT_indent", WM_OP_EXEC_DEFAULT, NULL);
|
||||
}
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void CONSOLE_OT_indent_or_autocomplete(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Indent or Autocomplete";
|
||||
ot->idname = "CONSOLE_OT_indent_or_autocomplete";
|
||||
ot->description = "Indent selected text or autocomplete";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec = console_indent_or_autocomplete_exec;
|
||||
ot->poll = ED_operator_console_active;
|
||||
|
||||
/* flags */
|
||||
ot->flag = 0;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Indent Operator
|
||||
* \{ */
|
||||
|
||||
static int console_indent_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
SpaceConsole *sc = CTX_wm_space_console(C);
|
||||
@@ -518,6 +556,8 @@ void CONSOLE_OT_indent(wmOperatorType *ot)
|
||||
ot->poll = ED_operator_console_active;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
static int console_unindent_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
SpaceConsole *sc = CTX_wm_space_console(C);
|
||||
|
@@ -245,6 +245,7 @@ static void console_operatortypes(void)
|
||||
WM_operatortype_append(CONSOLE_OT_insert);
|
||||
|
||||
WM_operatortype_append(CONSOLE_OT_indent);
|
||||
WM_operatortype_append(CONSOLE_OT_indent_or_autocomplete);
|
||||
WM_operatortype_append(CONSOLE_OT_unindent);
|
||||
|
||||
/* for use by python only */
|
||||
|
@@ -281,7 +281,7 @@ static void graphedit_activekey_handles_cb(bContext *C, void *fcu_ptr, void *bez
|
||||
bezt->h2 = HD_ALIGN;
|
||||
}
|
||||
else {
|
||||
BKE_nurb_bezt_handle_test(bezt, true);
|
||||
BKE_nurb_bezt_handle_test(bezt, SELECT, true);
|
||||
}
|
||||
|
||||
/* now call standard updates */
|
||||
|
@@ -552,6 +552,10 @@ static void box_select_graphkeys(bAnimContext *ac,
|
||||
ked.data = &scaled_rectf;
|
||||
}
|
||||
|
||||
if (sipo->flag & SIPO_SELVHANDLESONLY) {
|
||||
ked.iterflags |= KEYFRAME_ITER_HANDLES_DEFAULT_INVISIBLE;
|
||||
}
|
||||
|
||||
/* treat handles separately? */
|
||||
if (incl_handles) {
|
||||
ked.iterflags |= KEYFRAME_ITER_INCL_HANDLES;
|
||||
@@ -722,7 +726,7 @@ void GRAPH_OT_select_box(wmOperatorType *ot)
|
||||
ot->prop = RNA_def_boolean(ot->srna, "axis_range", 0, "Axis Range", "");
|
||||
RNA_def_boolean(ot->srna,
|
||||
"include_handles",
|
||||
0,
|
||||
true,
|
||||
"Include Handles",
|
||||
"Are handles tested individually against the selection criteria");
|
||||
|
||||
@@ -1417,23 +1421,42 @@ void GRAPH_OT_select_leftright(wmOperatorType *ot)
|
||||
*/
|
||||
|
||||
/* option 1) select keyframe directly under mouse */
|
||||
static void mouse_graph_keys(bAnimContext *ac,
|
||||
const int mval[2],
|
||||
short select_mode,
|
||||
const bool deselect_all,
|
||||
const bool curves_only)
|
||||
static int mouse_graph_keys(bAnimContext *ac,
|
||||
const int mval[2],
|
||||
eEditKeyframes_Select select_mode,
|
||||
const bool deselect_all,
|
||||
const bool curves_only,
|
||||
bool wait_to_deselect_others)
|
||||
{
|
||||
SpaceGraph *sipo = (SpaceGraph *)ac->sl;
|
||||
tNearestVertInfo *nvi;
|
||||
BezTriple *bezt = NULL;
|
||||
bool run_modal = false;
|
||||
|
||||
/* find the beztriple that we're selecting, and the handle that was clicked on */
|
||||
nvi = find_nearest_fcurve_vert(ac, mval);
|
||||
|
||||
if (select_mode != SELECT_REPLACE) {
|
||||
/* The modal execution to delay deselecting other items is only needed for normal click
|
||||
* selection, i.e. for SELECT_REPLACE. */
|
||||
wait_to_deselect_others = false;
|
||||
}
|
||||
|
||||
sipo->runtime.flag &= ~(SIPO_RUNTIME_FLAG_TWEAK_HANDLES_LEFT |
|
||||
SIPO_RUNTIME_FLAG_TWEAK_HANDLES_RIGHT);
|
||||
|
||||
const bool already_selected =
|
||||
(nvi != NULL) && (((nvi->hpoint == NEAREST_HANDLE_KEY) && (nvi->bezt->f2 & SELECT)) ||
|
||||
((nvi->hpoint == NEAREST_HANDLE_LEFT) && (nvi->bezt->f1 & SELECT)) ||
|
||||
((nvi->hpoint == NEAREST_HANDLE_RIGHT) && (nvi->bezt->f3 & SELECT)));
|
||||
|
||||
if (wait_to_deselect_others && nvi && already_selected) {
|
||||
run_modal = true;
|
||||
}
|
||||
/* For replacing selection, if we have something to select, we have to clear existing selection.
|
||||
* The same goes if we found nothing to select, and deselect_all is true
|
||||
* (deselect on nothing behavior). */
|
||||
if ((nvi != NULL && select_mode == SELECT_REPLACE) || (nvi == NULL && deselect_all)) {
|
||||
else if ((nvi != NULL && select_mode == SELECT_REPLACE) || (nvi == NULL && deselect_all)) {
|
||||
/* reset selection mode */
|
||||
select_mode = SELECT_ADD;
|
||||
|
||||
@@ -1450,7 +1473,7 @@ static void mouse_graph_keys(bAnimContext *ac,
|
||||
}
|
||||
|
||||
if (nvi == NULL) {
|
||||
return;
|
||||
return deselect_all ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
/* if points can be selected on this F-Curve */
|
||||
@@ -1461,17 +1484,9 @@ static void mouse_graph_keys(bAnimContext *ac,
|
||||
bezt = nvi->bezt; /* used to check bezt seletion is set */
|
||||
/* depends on selection mode */
|
||||
if (select_mode == SELECT_INVERT) {
|
||||
/* keyframe - invert select of all */
|
||||
if (nvi->hpoint == NEAREST_HANDLE_KEY) {
|
||||
if (BEZT_ISSEL_ANY(bezt)) {
|
||||
BEZT_DESEL_ALL(bezt);
|
||||
}
|
||||
else {
|
||||
BEZT_SEL_ALL(bezt);
|
||||
}
|
||||
bezt->f2 ^= SELECT;
|
||||
}
|
||||
|
||||
/* handles - toggle selection of relevant handle */
|
||||
else if (nvi->hpoint == NEAREST_HANDLE_LEFT) {
|
||||
/* toggle selection */
|
||||
bezt->f1 ^= SELECT;
|
||||
@@ -1482,11 +1497,9 @@ static void mouse_graph_keys(bAnimContext *ac,
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* if the keyframe was clicked on, select all verts of given beztriple */
|
||||
if (nvi->hpoint == NEAREST_HANDLE_KEY) {
|
||||
BEZT_SEL_ALL(bezt);
|
||||
bezt->f2 |= SELECT;
|
||||
}
|
||||
/* otherwise, select the handle that applied */
|
||||
else if (nvi->hpoint == NEAREST_HANDLE_LEFT) {
|
||||
bezt->f1 |= SELECT;
|
||||
}
|
||||
@@ -1547,8 +1560,17 @@ static void mouse_graph_keys(bAnimContext *ac,
|
||||
ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, nvi->fcu, nvi->ctype);
|
||||
}
|
||||
|
||||
if (nvi->hpoint == NEAREST_HANDLE_LEFT) {
|
||||
sipo->runtime.flag |= SIPO_RUNTIME_FLAG_TWEAK_HANDLES_LEFT;
|
||||
}
|
||||
else if (nvi->hpoint == NEAREST_HANDLE_RIGHT) {
|
||||
sipo->runtime.flag |= SIPO_RUNTIME_FLAG_TWEAK_HANDLES_RIGHT;
|
||||
}
|
||||
|
||||
/* free temp sample data for filtering */
|
||||
MEM_freeN(nvi);
|
||||
|
||||
return run_modal ? OPERATOR_RUNNING_MODAL : OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
/* Option 2) Selects all the keyframes on either side of the current frame
|
||||
@@ -1556,11 +1578,15 @@ static void mouse_graph_keys(bAnimContext *ac,
|
||||
/* (see graphkeys_select_leftright) */
|
||||
|
||||
/* Option 3) Selects all visible keyframes in the same frame as the mouse click */
|
||||
static void graphkeys_mselect_column(bAnimContext *ac, const int mval[2], short select_mode)
|
||||
static int graphkeys_mselect_column(bAnimContext *ac,
|
||||
const int mval[2],
|
||||
eEditKeyframes_Select select_mode,
|
||||
bool wait_to_deselect_others)
|
||||
{
|
||||
ListBase anim_data = {NULL, NULL};
|
||||
bAnimListElem *ale;
|
||||
int filter;
|
||||
bool run_modal = false;
|
||||
|
||||
KeyframeEditFunc select_cb, ok_cb;
|
||||
KeyframeEditData ked;
|
||||
@@ -1572,15 +1598,22 @@ static void graphkeys_mselect_column(bAnimContext *ac, const int mval[2], short
|
||||
|
||||
/* check if anything to select */
|
||||
if (nvi == NULL) {
|
||||
return;
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
/* get frame number on which elements should be selected */
|
||||
// TODO: should we restrict to integer frames only?
|
||||
selx = nvi->frame;
|
||||
|
||||
/* if select mode is replace, deselect all keyframes first */
|
||||
if (select_mode == SELECT_REPLACE) {
|
||||
if (select_mode != SELECT_REPLACE) {
|
||||
/* Doesn't need to deselect anything -> Pass. */
|
||||
}
|
||||
else if (wait_to_deselect_others && (nvi->bezt->f2 & SELECT)) {
|
||||
run_modal = true;
|
||||
}
|
||||
/* If select mode is replace (and we don't do delayed deselection on mouse release), deselect all
|
||||
* keyframes first. */
|
||||
else {
|
||||
/* reset selection mode to add to selection */
|
||||
select_mode = SELECT_ADD;
|
||||
|
||||
@@ -1622,12 +1655,14 @@ static void graphkeys_mselect_column(bAnimContext *ac, const int mval[2], short
|
||||
MEM_freeN(nvi);
|
||||
BLI_freelistN(&ked.list);
|
||||
ANIM_animdata_freelist(&anim_data);
|
||||
|
||||
return run_modal ? OPERATOR_RUNNING_MODAL : OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
/* ------------------- */
|
||||
|
||||
/* handle clicking */
|
||||
static int graphkeys_clickselect_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
static int graphkeys_clickselect_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
bAnimContext ac;
|
||||
|
||||
@@ -1639,27 +1674,37 @@ static int graphkeys_clickselect_invoke(bContext *C, wmOperator *op, const wmEve
|
||||
/* select mode is either replace (deselect all, then add) or add/extend */
|
||||
const short selectmode = RNA_boolean_get(op->ptr, "extend") ? SELECT_INVERT : SELECT_REPLACE;
|
||||
const bool deselect_all = RNA_boolean_get(op->ptr, "deselect_all");
|
||||
/* See #WM_operator_properties_generic_select() for a detailed description of the how and why of
|
||||
* this. */
|
||||
const bool wait_to_deselect_others = RNA_boolean_get(op->ptr, "wait_to_deselect_others");
|
||||
int mval[2];
|
||||
int ret_val;
|
||||
|
||||
mval[0] = RNA_int_get(op->ptr, "mouse_x");
|
||||
mval[1] = RNA_int_get(op->ptr, "mouse_y");
|
||||
|
||||
/* figure out action to take */
|
||||
if (RNA_boolean_get(op->ptr, "column")) {
|
||||
/* select all keyframes in the same frame as the one that was under the mouse */
|
||||
graphkeys_mselect_column(&ac, event->mval, selectmode);
|
||||
ret_val = graphkeys_mselect_column(&ac, mval, selectmode, wait_to_deselect_others);
|
||||
}
|
||||
else if (RNA_boolean_get(op->ptr, "curves")) {
|
||||
/* select all keyframes in the same F-Curve as the one under the mouse */
|
||||
mouse_graph_keys(&ac, event->mval, selectmode, deselect_all, true);
|
||||
ret_val = mouse_graph_keys(&ac, mval, selectmode, deselect_all, true, wait_to_deselect_others);
|
||||
}
|
||||
else {
|
||||
/* select keyframe under mouse */
|
||||
mouse_graph_keys(&ac, event->mval, selectmode, deselect_all, false);
|
||||
ret_val = mouse_graph_keys(
|
||||
&ac, mval, selectmode, deselect_all, false, wait_to_deselect_others);
|
||||
}
|
||||
|
||||
/* set notifier that keyframe selection (and also channel selection in some cases) has changed */
|
||||
/* set notifier that keyframe selection (and also channel selection in some cases) has
|
||||
* changed */
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_SELECTED, NULL);
|
||||
|
||||
/* for tweak grab to work */
|
||||
return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
|
||||
return ret_val | OPERATOR_PASS_THROUGH;
|
||||
}
|
||||
|
||||
void GRAPH_OT_clickselect(wmOperatorType *ot)
|
||||
@@ -1672,19 +1717,22 @@ void GRAPH_OT_clickselect(wmOperatorType *ot)
|
||||
ot->description = "Select keyframes by clicking on them";
|
||||
|
||||
/* callbacks */
|
||||
ot->invoke = graphkeys_clickselect_invoke;
|
||||
ot->poll = graphop_visible_keyframes_poll;
|
||||
ot->exec = graphkeys_clickselect_exec;
|
||||
ot->invoke = WM_generic_select_invoke;
|
||||
ot->modal = WM_generic_select_modal;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_UNDO;
|
||||
|
||||
/* properties */
|
||||
prop = RNA_def_boolean(
|
||||
ot->srna,
|
||||
"extend",
|
||||
0,
|
||||
"Extend Select",
|
||||
"Toggle keyframe selection instead of leaving newly selected keyframes only"); // SHIFTKEY
|
||||
WM_operator_properties_generic_select(ot);
|
||||
prop = RNA_def_boolean(ot->srna,
|
||||
"extend",
|
||||
0,
|
||||
"Extend Select",
|
||||
"Toggle keyframe selection instead of leaving newly selected "
|
||||
"keyframes only"); // SHIFTKEY
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
|
||||
prop = RNA_def_boolean(ot->srna,
|
||||
@@ -1694,12 +1742,12 @@ void GRAPH_OT_clickselect(wmOperatorType *ot)
|
||||
"Deselect all when nothing under the cursor");
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
|
||||
prop = RNA_def_boolean(
|
||||
ot->srna,
|
||||
"column",
|
||||
0,
|
||||
"Column Select",
|
||||
"Select all keyframes that occur on the same frame as the one under the mouse"); // ALTKEY
|
||||
prop = RNA_def_boolean(ot->srna,
|
||||
"column",
|
||||
0,
|
||||
"Column Select",
|
||||
"Select all keyframes that occur on the same frame as the one under "
|
||||
"the mouse"); // ALTKEY
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
|
||||
prop = RNA_def_boolean(ot->srna,
|
||||
|
@@ -796,6 +796,9 @@ static void graph_refresh(const bContext *C, ScrArea *sa)
|
||||
ED_area_tag_redraw(sa);
|
||||
}
|
||||
|
||||
sipo->runtime.flag &= ~(SIPO_RUNTIME_FLAG_TWEAK_HANDLES_LEFT |
|
||||
SIPO_RUNTIME_FLAG_TWEAK_HANDLES_RIGHT);
|
||||
|
||||
/* init/adjust F-Curve colors */
|
||||
graph_refresh_fcurve_colors(C);
|
||||
}
|
||||
|
@@ -203,6 +203,7 @@ static void text_operatortypes(void)
|
||||
WM_operatortype_append(TEXT_OT_comment_toggle);
|
||||
WM_operatortype_append(TEXT_OT_unindent);
|
||||
WM_operatortype_append(TEXT_OT_indent);
|
||||
WM_operatortype_append(TEXT_OT_indent_or_autocomplete);
|
||||
|
||||
WM_operatortype_append(TEXT_OT_select_line);
|
||||
WM_operatortype_append(TEXT_OT_select_all);
|
||||
|
@@ -137,6 +137,7 @@ void TEXT_OT_convert_whitespace(struct wmOperatorType *ot);
|
||||
void TEXT_OT_comment_toggle(struct wmOperatorType *ot);
|
||||
void TEXT_OT_unindent(struct wmOperatorType *ot);
|
||||
void TEXT_OT_indent(struct wmOperatorType *ot);
|
||||
void TEXT_OT_indent_or_autocomplete(struct wmOperatorType *ot);
|
||||
|
||||
void TEXT_OT_line_break(struct wmOperatorType *ot);
|
||||
void TEXT_OT_insert(struct wmOperatorType *ot);
|
||||
|
@@ -1068,6 +1068,41 @@ void TEXT_OT_cut(wmOperatorType *ot)
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Indent or Autocomplete Operator
|
||||
* \{ */
|
||||
|
||||
static int text_indent_or_autocomplete_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
Text *text = CTX_data_edit_text(C);
|
||||
TextLine *line = text->curl;
|
||||
bool text_before_cursor = text->curc != 0 && !ELEM(line->line[text->curc - 1], ' ', '\t');
|
||||
if (text_before_cursor && (txt_has_sel(text) == false)) {
|
||||
WM_operator_name_call(C, "TEXT_OT_autocomplete", WM_OP_INVOKE_DEFAULT, NULL);
|
||||
}
|
||||
else {
|
||||
WM_operator_name_call(C, "TEXT_OT_indent", WM_OP_EXEC_DEFAULT, NULL);
|
||||
}
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void TEXT_OT_indent_or_autocomplete(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Indent or Autocomplete";
|
||||
ot->idname = "TEXT_OT_indent_or_autocomplete";
|
||||
ot->description = "Indent selected text or autocomplete";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec = text_indent_or_autocomplete_exec;
|
||||
ot->poll = text_edit_poll;
|
||||
|
||||
/* flags */
|
||||
ot->flag = 0;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Indent Operator
|
||||
* \{ */
|
||||
|
@@ -2359,6 +2359,7 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
|
||||
|
||||
/* Needed to translate tweak events to mouse buttons. */
|
||||
t->launch_event = event ? WM_userdef_event_type_from_keymap_type(event->type) : -1;
|
||||
t->is_launch_event_tweak = event ? ISTWEAK(event->type) : false;
|
||||
|
||||
/* XXX Remove this when wm_operator_call_internal doesn't use window->eventstate
|
||||
* (which can have type = 0) */
|
||||
|
@@ -213,7 +213,8 @@ typedef struct TransData2D {
|
||||
float ih1[2], ih2[2];
|
||||
} TransData2D;
|
||||
|
||||
/** Used to store 2 handles for each #TransData in case the other handle wasn't selected. */
|
||||
/** Used to store 2 handles for each #TransData in case the other handle wasn't selected. Also to
|
||||
* unset temporary flags. */
|
||||
typedef struct TransDataCurveHandleFlags {
|
||||
char ih1, ih2;
|
||||
char *h1, *h2;
|
||||
@@ -631,6 +632,9 @@ typedef struct TransInfo {
|
||||
/*************** NEW STUFF *********************/
|
||||
/** event type used to launch transform. */
|
||||
short launch_event;
|
||||
/** Is the actual launch event a tweak event? (launch_event above is set to the corresponding
|
||||
* mouse button then.) */
|
||||
bool is_launch_event_tweak;
|
||||
|
||||
struct {
|
||||
/** Orientation type when when we're not constrained.
|
||||
|
@@ -921,10 +921,17 @@ typedef struct tRetainedKeyframe {
|
||||
size_t del_count; /* number of keyframes of this sort that have been deleted so far */
|
||||
} tRetainedKeyframe;
|
||||
|
||||
/* Called during special_aftertrans_update to make sure selected keyframes replace
|
||||
/**
|
||||
* Called during special_aftertrans_update to make sure selected keyframes replace
|
||||
* any other keyframes which may reside on that frame (that is not selected).
|
||||
*
|
||||
* \param sel_flag: The flag (bezt.f1/2/3) value to use to determine selection. Usually `SELECT`,
|
||||
* but may want to use a different one at times (if caller does not operate on
|
||||
* selection).
|
||||
*/
|
||||
static void posttrans_fcurve_clean(FCurve *fcu, const bool use_handle)
|
||||
static void posttrans_fcurve_clean(FCurve *fcu,
|
||||
const eBezTriple_Flag sel_flag,
|
||||
const bool use_handle)
|
||||
{
|
||||
/* NOTE: We assume that all keys are sorted */
|
||||
ListBase retained_keys = {NULL, NULL};
|
||||
@@ -1036,7 +1043,7 @@ static void posttrans_fcurve_clean(FCurve *fcu, const bool use_handle)
|
||||
}
|
||||
|
||||
/* 3) Recalculate handles */
|
||||
testhandles_fcurve(fcu, use_handle);
|
||||
testhandles_fcurve(fcu, sel_flag, use_handle);
|
||||
|
||||
/* cleanup */
|
||||
BLI_freelistN(&retained_keys);
|
||||
@@ -1064,11 +1071,11 @@ static void posttrans_action_clean(bAnimContext *ac, bAction *act)
|
||||
|
||||
if (adt) {
|
||||
ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 0);
|
||||
posttrans_fcurve_clean(ale->key_data, false); /* only use handles in graph editor */
|
||||
posttrans_fcurve_clean(ale->key_data, SELECT, false); /* only use handles in graph editor */
|
||||
ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 0);
|
||||
}
|
||||
else {
|
||||
posttrans_fcurve_clean(ale->key_data, false); /* only use handles in graph editor */
|
||||
posttrans_fcurve_clean(ale->key_data, SELECT, false); /* only use handles in graph editor */
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1090,7 +1097,7 @@ typedef struct BeztMap {
|
||||
/* This function converts an FCurve's BezTriple array to a BeztMap array
|
||||
* NOTE: this allocates memory that will need to get freed later
|
||||
*/
|
||||
static BeztMap *bezt_to_beztmaps(BezTriple *bezts, int totvert, const short UNUSED(use_handle))
|
||||
static BeztMap *bezt_to_beztmaps(BezTriple *bezts, int totvert)
|
||||
{
|
||||
BezTriple *bezt = bezts;
|
||||
BezTriple *prevbezt = NULL;
|
||||
@@ -1118,7 +1125,7 @@ static BeztMap *bezt_to_beztmaps(BezTriple *bezts, int totvert, const short UNUS
|
||||
}
|
||||
|
||||
/* This function copies the code of sort_time_ipocurve, but acts on BeztMap structs instead */
|
||||
static void sort_time_beztmaps(BeztMap *bezms, int totvert, const short UNUSED(use_handle))
|
||||
static void sort_time_beztmaps(BeztMap *bezms, int totvert)
|
||||
{
|
||||
BeztMap *bezm;
|
||||
int i, ok = 1;
|
||||
@@ -1163,8 +1170,7 @@ static void sort_time_beztmaps(BeztMap *bezms, int totvert, const short UNUSED(u
|
||||
}
|
||||
|
||||
/* This function firstly adjusts the pointers that the transdata has to each BezTriple */
|
||||
static void beztmap_to_data(
|
||||
TransInfo *t, FCurve *fcu, BeztMap *bezms, int totvert, const short UNUSED(use_handle))
|
||||
static void beztmap_to_data(TransInfo *t, FCurve *fcu, BeztMap *bezms, int totvert)
|
||||
{
|
||||
BezTriple *bezts = fcu->bezt;
|
||||
BeztMap *bezm;
|
||||
@@ -1270,9 +1276,9 @@ void remake_graph_transdata(TransInfo *t, ListBase *anim_data)
|
||||
|
||||
/* adjust transform-data pointers */
|
||||
/* note, none of these functions use 'use_handle', it could be removed */
|
||||
bezm = bezt_to_beztmaps(fcu->bezt, fcu->totvert, use_handle);
|
||||
sort_time_beztmaps(bezm, fcu->totvert, use_handle);
|
||||
beztmap_to_data(t, fcu, bezm, fcu->totvert, use_handle);
|
||||
bezm = bezt_to_beztmaps(fcu->bezt, fcu->totvert);
|
||||
sort_time_beztmaps(bezm, fcu->totvert);
|
||||
beztmap_to_data(t, fcu, bezm, fcu->totvert);
|
||||
|
||||
/* free mapping stuff */
|
||||
MEM_freeN(bezm);
|
||||
@@ -1281,7 +1287,7 @@ void remake_graph_transdata(TransInfo *t, ListBase *anim_data)
|
||||
sort_time_fcurve(fcu);
|
||||
|
||||
/* make sure handles are all set correctly */
|
||||
testhandles_fcurve(fcu, use_handle);
|
||||
testhandles_fcurve(fcu, BEZT_FLAG_TEMP_TAG, use_handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1959,11 +1965,11 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
|
||||
if ((saction->flag & SACTION_NOTRANSKEYCULL) == 0 && ((canceled == 0) || (duplicate))) {
|
||||
if (adt) {
|
||||
ANIM_nla_mapping_apply_fcurve(adt, fcu, 0, 0);
|
||||
posttrans_fcurve_clean(fcu, false); /* only use handles in graph editor */
|
||||
posttrans_fcurve_clean(fcu, SELECT, false); /* only use handles in graph editor */
|
||||
ANIM_nla_mapping_apply_fcurve(adt, fcu, 1, 0);
|
||||
}
|
||||
else {
|
||||
posttrans_fcurve_clean(fcu, false); /* only use handles in graph editor */
|
||||
posttrans_fcurve_clean(fcu, SELECT, false); /* only use handles in graph editor */
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2103,11 +2109,11 @@ void special_aftertrans_update(bContext *C, TransInfo *t)
|
||||
if ((sipo->flag & SIPO_NOTRANSKEYCULL) == 0 && ((canceled == 0) || (duplicate))) {
|
||||
if (adt) {
|
||||
ANIM_nla_mapping_apply_fcurve(adt, fcu, 0, 0);
|
||||
posttrans_fcurve_clean(fcu, use_handle);
|
||||
posttrans_fcurve_clean(fcu, BEZT_FLAG_TEMP_TAG, use_handle);
|
||||
ANIM_nla_mapping_apply_fcurve(adt, fcu, 1, 0);
|
||||
}
|
||||
else {
|
||||
posttrans_fcurve_clean(fcu, use_handle);
|
||||
posttrans_fcurve_clean(fcu, BEZT_FLAG_TEMP_TAG, use_handle);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
@@ -156,21 +156,55 @@ static bool graph_edit_use_local_center(TransInfo *t)
|
||||
return ((t->around == V3D_AROUND_LOCAL_ORIGINS) && (graph_edit_is_translation_mode(t) == false));
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the effective selection of a triple for transform, i.e. return if the left handle, right
|
||||
* handle and/or the center point should be affected by transform.
|
||||
*/
|
||||
static void graph_bezt_get_transform_selection(const TransInfo *t,
|
||||
const BezTriple *bezt,
|
||||
const bool use_handle,
|
||||
bool *r_left_handle,
|
||||
bool *r_key,
|
||||
bool *r_right_handle)
|
||||
{
|
||||
SpaceGraph *sipo = (SpaceGraph *)t->sa->spacedata.first;
|
||||
bool key = (bezt->f2 & SELECT) != 0;
|
||||
bool left = use_handle ? ((bezt->f1 & SELECT) != 0) : key;
|
||||
bool right = use_handle ? ((bezt->f3 & SELECT) != 0) : key;
|
||||
|
||||
if (use_handle && t->is_launch_event_tweak) {
|
||||
if (sipo->runtime.flag & SIPO_RUNTIME_FLAG_TWEAK_HANDLES_LEFT) {
|
||||
key = right = false;
|
||||
}
|
||||
else if (sipo->runtime.flag & SIPO_RUNTIME_FLAG_TWEAK_HANDLES_RIGHT) {
|
||||
left = key = false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Whenever we move the key, we also move both handles. */
|
||||
if (key) {
|
||||
left = right = true;
|
||||
}
|
||||
|
||||
*r_key = key;
|
||||
*r_left_handle = left;
|
||||
*r_right_handle = right;
|
||||
}
|
||||
|
||||
static void graph_key_shortest_dist(
|
||||
TransInfo *t, FCurve *fcu, TransData *td_start, TransData *td, int cfra, bool use_handle)
|
||||
{
|
||||
int j = 0;
|
||||
TransData *td_iter = td_start;
|
||||
bool sel_key, sel_left, sel_right;
|
||||
|
||||
td->dist = FLT_MAX;
|
||||
for (; j < fcu->totvert; j++) {
|
||||
BezTriple *bezt = fcu->bezt + j;
|
||||
if (FrameOnMouseSide(t->frame_side, bezt->vec[1][0], cfra)) {
|
||||
const bool sel2 = (bezt->f2 & SELECT) != 0;
|
||||
const bool sel1 = use_handle ? (bezt->f1 & SELECT) != 0 : sel2;
|
||||
const bool sel3 = use_handle ? (bezt->f3 & SELECT) != 0 : sel2;
|
||||
graph_bezt_get_transform_selection(t, bezt, use_handle, &sel_left, &sel_key, &sel_right);
|
||||
|
||||
if (sel1 || sel2 || sel3) {
|
||||
if (sel_left || sel_key || sel_right) {
|
||||
td->dist = td->rdist = min_ff(td->dist, fabs(td_iter->center[0] - td->center[0]));
|
||||
}
|
||||
|
||||
@@ -179,6 +213,15 @@ static void graph_key_shortest_dist(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* It is important to note that this doesn't always act on the selection (like it's usually done),
|
||||
* it acts on a subset of it. E.g. the selection code may leave a hint that we just dragged on a
|
||||
* left or right handle (SIPO_RUNTIME_FLAG_TWEAK_HANDLES_LEFT/RIGHT) and then we only transform the
|
||||
* selected left or right handles accordingly.
|
||||
* The points to be transformed are tagged with BEZT_FLAG_TEMP_TAG; some lower level curve
|
||||
* functions may need to be made aware of this. It's ugly that these act based on selection state
|
||||
* anyway.
|
||||
*/
|
||||
void createTransGraphEditData(bContext *C, TransInfo *t)
|
||||
{
|
||||
SpaceGraph *sipo = (SpaceGraph *)t->sa->spacedata.first;
|
||||
@@ -198,11 +241,11 @@ void createTransGraphEditData(bContext *C, TransInfo *t)
|
||||
BezTriple *bezt;
|
||||
int count = 0, i;
|
||||
float mtx[3][3], smtx[3][3];
|
||||
const bool is_translation_mode = graph_edit_is_translation_mode(t);
|
||||
const bool use_handle = !(sipo->flag & SIPO_NOHANDLES);
|
||||
const bool use_local_center = graph_edit_use_local_center(t);
|
||||
const bool is_prop_edit = (t->flag & T_PROP_EDIT) != 0;
|
||||
short anim_map_flag = ANIM_UNITCONV_ONLYSEL | ANIM_UNITCONV_SELVERTS;
|
||||
bool sel_key, sel_left, sel_right;
|
||||
|
||||
/* determine what type of data we are operating on */
|
||||
if (ANIM_animdata_get_context(C, &ac) == 0) {
|
||||
@@ -253,33 +296,29 @@ void createTransGraphEditData(bContext *C, TransInfo *t)
|
||||
cfra = (float)CFRA;
|
||||
}
|
||||
|
||||
/* Only include BezTriples whose 'keyframe'
|
||||
* occurs on the same side of the current frame as mouse. */
|
||||
for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
|
||||
/* Only include BezTriples whose 'keyframe'
|
||||
* occurs on the same side of the current frame as mouse. */
|
||||
if (FrameOnMouseSide(t->frame_side, bezt->vec[1][0], cfra)) {
|
||||
const bool sel2 = (bezt->f2 & SELECT) != 0;
|
||||
const bool sel1 = use_handle ? (bezt->f1 & SELECT) != 0 : sel2;
|
||||
const bool sel3 = use_handle ? (bezt->f3 & SELECT) != 0 : sel2;
|
||||
graph_bezt_get_transform_selection(t, bezt, use_handle, &sel_left, &sel_key, &sel_right);
|
||||
|
||||
if (is_prop_edit) {
|
||||
curvecount += 3;
|
||||
if (sel2 || sel1 || sel3) {
|
||||
if (sel_key || sel_left || sel_right) {
|
||||
selected = true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (!is_translation_mode || !(sel2)) {
|
||||
if (sel1) {
|
||||
count++;
|
||||
}
|
||||
if (sel_left) {
|
||||
count++;
|
||||
}
|
||||
|
||||
if (sel3) {
|
||||
count++;
|
||||
}
|
||||
if (sel_right) {
|
||||
count++;
|
||||
}
|
||||
|
||||
/* only include main vert if selected */
|
||||
if (sel2 && !use_local_center) {
|
||||
if (sel_key && !use_local_center) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
@@ -366,19 +405,21 @@ void createTransGraphEditData(bContext *C, TransInfo *t)
|
||||
unit_scale = ANIM_unit_mapping_get_factor(
|
||||
ac.scene, ale->id, ale->key_data, anim_map_flag, &offset);
|
||||
|
||||
/* only include BezTriples whose 'keyframe' occurs on the same side
|
||||
* of the current frame as mouse (if applicable) */
|
||||
for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
|
||||
if (FrameOnMouseSide(t->frame_side, bezt->vec[1][0], cfra)) {
|
||||
const bool sel2 = (bezt->f2 & SELECT) != 0;
|
||||
const bool sel1 = use_handle ? (bezt->f1 & SELECT) != 0 : sel2;
|
||||
const bool sel3 = use_handle ? (bezt->f3 & SELECT) != 0 : sel2;
|
||||
/* Ensure temp flag is cleared for all triples, we use it. */
|
||||
bezt->f1 &= ~BEZT_FLAG_TEMP_TAG;
|
||||
bezt->f2 &= ~BEZT_FLAG_TEMP_TAG;
|
||||
bezt->f3 &= ~BEZT_FLAG_TEMP_TAG;
|
||||
|
||||
/* only include BezTriples whose 'keyframe' occurs on the same side
|
||||
* of the current frame as mouse (if applicable) */
|
||||
if (FrameOnMouseSide(t->frame_side, bezt->vec[1][0], cfra)) {
|
||||
TransDataCurveHandleFlags *hdata = NULL;
|
||||
/* short h1=1, h2=1; */ /* UNUSED */
|
||||
|
||||
graph_bezt_get_transform_selection(t, bezt, use_handle, &sel_left, &sel_key, &sel_right);
|
||||
|
||||
if (is_prop_edit) {
|
||||
bool is_sel = (sel2 || sel1 || sel3);
|
||||
bool is_sel = (sel_key || sel_left || sel_right);
|
||||
/* we always select all handles for proportional editing if central handle is selected */
|
||||
initTransDataCurveHandles(td, bezt);
|
||||
bezt_to_transdata(td++,
|
||||
@@ -422,69 +463,69 @@ void createTransGraphEditData(bContext *C, TransInfo *t)
|
||||
smtx,
|
||||
unit_scale,
|
||||
offset);
|
||||
|
||||
if (is_sel) {
|
||||
bezt->f1 |= BEZT_FLAG_TEMP_TAG;
|
||||
bezt->f2 |= BEZT_FLAG_TEMP_TAG;
|
||||
bezt->f3 |= BEZT_FLAG_TEMP_TAG;
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* only include handles if selected, irrespective of the interpolation modes.
|
||||
* also, only treat handles specially if the center point isn't selected.
|
||||
*/
|
||||
if (!is_translation_mode || !(sel2)) {
|
||||
if (sel1) {
|
||||
hdata = initTransDataCurveHandles(td, bezt);
|
||||
bezt_to_transdata(td++,
|
||||
td2d++,
|
||||
tdg++,
|
||||
adt,
|
||||
bezt,
|
||||
0,
|
||||
sel1,
|
||||
true,
|
||||
intvals,
|
||||
mtx,
|
||||
smtx,
|
||||
unit_scale,
|
||||
offset);
|
||||
}
|
||||
else {
|
||||
/* h1 = 0; */ /* UNUSED */
|
||||
}
|
||||
if (sel_left) {
|
||||
hdata = initTransDataCurveHandles(td, bezt);
|
||||
bezt_to_transdata(td++,
|
||||
td2d++,
|
||||
tdg++,
|
||||
adt,
|
||||
bezt,
|
||||
0,
|
||||
sel_left,
|
||||
true,
|
||||
intvals,
|
||||
mtx,
|
||||
smtx,
|
||||
unit_scale,
|
||||
offset);
|
||||
bezt->f1 |= BEZT_FLAG_TEMP_TAG;
|
||||
}
|
||||
|
||||
if (sel3) {
|
||||
if (hdata == NULL) {
|
||||
hdata = initTransDataCurveHandles(td, bezt);
|
||||
}
|
||||
bezt_to_transdata(td++,
|
||||
td2d++,
|
||||
tdg++,
|
||||
adt,
|
||||
bezt,
|
||||
2,
|
||||
sel3,
|
||||
true,
|
||||
intvals,
|
||||
mtx,
|
||||
smtx,
|
||||
unit_scale,
|
||||
offset);
|
||||
}
|
||||
else {
|
||||
/* h2 = 0; */ /* UNUSED */
|
||||
if (sel_right) {
|
||||
if (hdata == NULL) {
|
||||
hdata = initTransDataCurveHandles(td, bezt);
|
||||
}
|
||||
bezt_to_transdata(td++,
|
||||
td2d++,
|
||||
tdg++,
|
||||
adt,
|
||||
bezt,
|
||||
2,
|
||||
sel_right,
|
||||
true,
|
||||
intvals,
|
||||
mtx,
|
||||
smtx,
|
||||
unit_scale,
|
||||
offset);
|
||||
bezt->f3 |= BEZT_FLAG_TEMP_TAG;
|
||||
}
|
||||
|
||||
/* only include main vert if selected */
|
||||
if (sel2 && !use_local_center) {
|
||||
if (sel_key && !use_local_center) {
|
||||
/* move handles relative to center */
|
||||
if (is_translation_mode) {
|
||||
if (sel1) {
|
||||
if (graph_edit_is_translation_mode(t)) {
|
||||
if (sel_left) {
|
||||
td->flag |= TD_MOVEHANDLE1;
|
||||
}
|
||||
if (sel3) {
|
||||
if (sel_right) {
|
||||
td->flag |= TD_MOVEHANDLE2;
|
||||
}
|
||||
}
|
||||
|
||||
/* if handles were not selected, store their selection status */
|
||||
if (!(sel1) || !(sel3)) {
|
||||
if (!(sel_left) || !(sel_right)) {
|
||||
if (hdata == NULL) {
|
||||
hdata = initTransDataCurveHandles(td, bezt);
|
||||
}
|
||||
@@ -496,13 +537,14 @@ void createTransGraphEditData(bContext *C, TransInfo *t)
|
||||
adt,
|
||||
bezt,
|
||||
1,
|
||||
sel2,
|
||||
sel_key,
|
||||
false,
|
||||
intvals,
|
||||
mtx,
|
||||
smtx,
|
||||
unit_scale,
|
||||
offset);
|
||||
bezt->f2 |= BEZT_FLAG_TEMP_TAG;
|
||||
}
|
||||
/* Special hack (must be done after #initTransDataCurveHandles(),
|
||||
* as that stores handle settings to restore...):
|
||||
@@ -513,7 +555,7 @@ void createTransGraphEditData(bContext *C, TransInfo *t)
|
||||
*/
|
||||
if (ELEM(bezt->h1, HD_AUTO, HD_AUTO_ANIM) && ELEM(bezt->h2, HD_AUTO, HD_AUTO_ANIM) &&
|
||||
ELEM(t->mode, TFM_ROTATION, TFM_RESIZE)) {
|
||||
if (hdata && (sel1) && (sel3)) {
|
||||
if (hdata && (sel_left) && (sel_right)) {
|
||||
bezt->h1 = HD_ALIGN;
|
||||
bezt->h2 = HD_ALIGN;
|
||||
}
|
||||
@@ -523,7 +565,7 @@ void createTransGraphEditData(bContext *C, TransInfo *t)
|
||||
}
|
||||
|
||||
/* Sets handles based on the selection */
|
||||
testhandles_fcurve(fcu, use_handle);
|
||||
testhandles_fcurve(fcu, BEZT_FLAG_TEMP_TAG, use_handle);
|
||||
}
|
||||
|
||||
if (is_prop_edit) {
|
||||
@@ -551,15 +593,13 @@ void createTransGraphEditData(bContext *C, TransInfo *t)
|
||||
cfra = (float)CFRA;
|
||||
}
|
||||
|
||||
/* only include BezTriples whose 'keyframe' occurs on the
|
||||
* same side of the current frame as mouse (if applicable) */
|
||||
for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
|
||||
/* only include BezTriples whose 'keyframe' occurs on the
|
||||
* same side of the current frame as mouse (if applicable) */
|
||||
if (FrameOnMouseSide(t->frame_side, bezt->vec[1][0], cfra)) {
|
||||
const bool sel2 = (bezt->f2 & SELECT) != 0;
|
||||
const bool sel1 = use_handle ? (bezt->f1 & SELECT) != 0 : sel2;
|
||||
const bool sel3 = use_handle ? (bezt->f3 & SELECT) != 0 : sel2;
|
||||
graph_bezt_get_transform_selection(t, bezt, use_handle, &sel_left, &sel_key, &sel_right);
|
||||
|
||||
if (sel1 || sel2) {
|
||||
if (sel_left || sel_key) {
|
||||
td->dist = td->rdist = 0.0f;
|
||||
}
|
||||
else {
|
||||
@@ -567,7 +607,7 @@ void createTransGraphEditData(bContext *C, TransInfo *t)
|
||||
}
|
||||
td++;
|
||||
|
||||
if (sel2) {
|
||||
if (sel_key) {
|
||||
td->dist = td->rdist = 0.0f;
|
||||
}
|
||||
else {
|
||||
@@ -575,7 +615,7 @@ void createTransGraphEditData(bContext *C, TransInfo *t)
|
||||
}
|
||||
td++;
|
||||
|
||||
if (sel3 || sel2) {
|
||||
if (sel_right || sel_key) {
|
||||
td->dist = td->rdist = 0.0f;
|
||||
}
|
||||
else {
|
||||
|
@@ -448,7 +448,7 @@ static void recalcData_graphedit(TransInfo *t)
|
||||
dosort++;
|
||||
}
|
||||
else {
|
||||
calchandles_fcurve(fcu);
|
||||
calchandles_fcurve_ex(fcu, BEZT_FLAG_TEMP_TAG);
|
||||
}
|
||||
|
||||
/* set refresh tags for objects using this animation,
|
||||
|
@@ -32,6 +32,7 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
struct FileData;
|
||||
struct GHash;
|
||||
struct GPUTexture;
|
||||
struct ID;
|
||||
struct Library;
|
||||
@@ -206,6 +207,9 @@ typedef struct IDOverrideLibraryProperty {
|
||||
ListBase operations;
|
||||
} IDOverrideLibraryProperty;
|
||||
|
||||
/* We do not need a full struct for that currently, just a GHash. */
|
||||
typedef struct GHash IDOverrideLibraryRuntime;
|
||||
|
||||
/* Main container for all overriding data info of a data-block. */
|
||||
typedef struct IDOverrideLibrary {
|
||||
/** Reference linked ID which this one overrides. */
|
||||
@@ -220,6 +224,8 @@ typedef struct IDOverrideLibrary {
|
||||
/* Temp ID storing extra override data (used for differential operations only currently).
|
||||
* Always NULL outside of read/write context. */
|
||||
struct ID *storage;
|
||||
|
||||
IDOverrideLibraryRuntime *runtime;
|
||||
} IDOverrideLibrary;
|
||||
|
||||
enum eOverrideLibrary_Flag {
|
||||
|
@@ -483,6 +483,13 @@ typedef enum eGraphEdit_Runtime_Flag {
|
||||
SIPO_RUNTIME_FLAG_NEED_CHAN_SYNC = (1 << 0),
|
||||
/** Temporary flag to force fcurves to recalculate colors. */
|
||||
SIPO_RUNTIME_FLAG_NEED_CHAN_SYNC_COLOR = (1 << 1),
|
||||
|
||||
/**
|
||||
* These flags are for the mouse-select code to communicate with the transform code. Click
|
||||
* dragging (tweaking) a handle sets the according left/right flag which transform code uses then
|
||||
* to limit translation to this side. */
|
||||
SIPO_RUNTIME_FLAG_TWEAK_HANDLES_LEFT = (1 << 2),
|
||||
SIPO_RUNTIME_FLAG_TWEAK_HANDLES_RIGHT = (1 << 3),
|
||||
} eGraphEdit_Runtime_Flag;
|
||||
|
||||
/** \} */
|
||||
|
@@ -3604,7 +3604,7 @@ char *RNA_property_string_get_default_alloc(PointerRNA *ptr,
|
||||
/* this is the length without \0 terminator */
|
||||
int RNA_property_string_default_length(PointerRNA *UNUSED(ptr), PropertyRNA *prop)
|
||||
{
|
||||
StringPropertyRNA *sprop = (StringPropertyRNA *)prop;
|
||||
StringPropertyRNA *sprop = (StringPropertyRNA *)rna_ensure_property(prop);
|
||||
|
||||
BLI_assert(RNA_property_type(prop) == PROP_STRING);
|
||||
|
||||
|
@@ -27,6 +27,8 @@
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_string.h"
|
||||
|
||||
#define DEBUG_OVERRIDE_TIMEIT
|
||||
|
||||
#ifdef DEBUG_OVERRIDE_TIMEIT
|
||||
# include "PIL_time_utildefines.h"
|
||||
#endif
|
||||
|
@@ -585,7 +585,7 @@ static void rna_Curve_body_set(PointerRNA *ptr, const char *value)
|
||||
MEM_freeN(cu->strinfo);
|
||||
}
|
||||
|
||||
cu->str = MEM_mallocN(len_bytes + sizeof(wchar_t), "str");
|
||||
cu->str = MEM_mallocN(len_bytes + sizeof(char32_t), "str");
|
||||
cu->strinfo = MEM_callocN((len_chars + 4) * sizeof(CharInfo), "strinfo");
|
||||
|
||||
BLI_strncpy(cu->str, value, len_bytes + 1);
|
||||
|
@@ -396,8 +396,38 @@ void WM_operator_properties_select_operation_simple(wmOperatorType *ot)
|
||||
RNA_def_property_flag(prop, PROP_SKIP_SAVE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Selecting and tweaking items are overlapping operations. Getting both to work without conflicts
|
||||
* requires special care. See
|
||||
* https://wiki.blender.org/wiki/Human_Interface_Guidelines/Selection#Select-tweaking for the
|
||||
* desired behavior.
|
||||
*
|
||||
* For default click selection (with no modifier keys held), the select operators can do the
|
||||
* following:
|
||||
* - On a mouse press on an unselected item, change selection and finish immidiately after.
|
||||
* This sends an undo push and allows transform to take over should a tweak event be caught now.
|
||||
* - On a mouse press on a selected item, don't change selection state, but start modal execution
|
||||
* of the operator. Idea is that we wait with deselecting other items until we know that the
|
||||
* intention wasn't to tweak (mouse press+drag) all selected items.
|
||||
* - If a tweak is recognized before the release event happens, cancel the operator, so that
|
||||
* transform can take over and no undo-push is sent.
|
||||
* - If the release event occurs rather than a tweak one, deselect all items but the one under the
|
||||
* cursor, and finish the modal operator.
|
||||
*
|
||||
* This utility, together with #WM_generic_select_invoke() and #WM_generic_select_modal() should
|
||||
* help getting the wanted behavior to work. Most generic logic should be handled in these, so that
|
||||
* the select operators only have to care for the case dependent handling.
|
||||
*
|
||||
* Every select operator has slightly diferent requirements, e.g. VSE strip selection also needs to
|
||||
* account for handle selection. This should be the baseline behavior though.
|
||||
*/
|
||||
void WM_operator_properties_generic_select(wmOperatorType *ot)
|
||||
{
|
||||
/* On the initial mouse press, this is set by #WM_generic_select_modal() to let the select
|
||||
* operator exec callback know that it should not __yet__ deselect other items when clicking on
|
||||
* an already selected one. Instead should make sure the operator executes modal then (see
|
||||
* #WM_generic_select_modal()), so that the exec callback can be called a second time on the
|
||||
* mouse release event to do this part. */
|
||||
PropertyRNA *prop = RNA_def_boolean(
|
||||
ot->srna, "wait_to_deselect_others", false, "Wait to Deselect Others", "");
|
||||
RNA_def_property_flag(prop, PROP_HIDDEN | PROP_SKIP_SAVE);
|
||||
|
@@ -721,6 +721,13 @@ void WM_operator_properties_free(PointerRNA *ptr)
|
||||
/** \name Default Operator Callbacks
|
||||
* \{ */
|
||||
|
||||
/**
|
||||
* Helper to get select and tweak-transform to work conflict free and as desired. See
|
||||
* #WM_operator_properties_generic_select() for details.
|
||||
*
|
||||
* To be used together with #WM_generic_select_invoke() and
|
||||
* #WM_operator_properties_generic_select().
|
||||
*/
|
||||
int WM_generic_select_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
{
|
||||
PropertyRNA *wait_to_deselect_prop = RNA_struct_find_property(op->ptr,
|
||||
@@ -787,6 +794,13 @@ int WM_generic_select_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
return OPERATOR_RUNNING_MODAL | OPERATOR_PASS_THROUGH;
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper to get select and tweak-transform to work conflict free and as desired. See
|
||||
* #WM_operator_properties_generic_select() for details.
|
||||
*
|
||||
* To be used together with #WM_generic_select_modal() and
|
||||
* #WM_operator_properties_generic_select().
|
||||
*/
|
||||
int WM_generic_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
{
|
||||
RNA_int_set(op->ptr, "mouse_x", event->mval[0]);
|
||||
|
Reference in New Issue
Block a user