Vulkan: Clearing Framebuffer + Scissors #106044
|
@ -309,7 +309,7 @@ class Device {
|
||||||
static uint devices_initialized_mask;
|
static uint devices_initialized_mask;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Device, which is GPU, with some common functionality for GPU backends */
|
/* Device, which is GPU, with some common functionality for GPU back-ends. */
|
||||||
class GPUDevice : public Device {
|
class GPUDevice : public Device {
|
||||||
protected:
|
protected:
|
||||||
GPUDevice(const DeviceInfo &info_, Stats &stats_, Profiler &profiler_)
|
GPUDevice(const DeviceInfo &info_, Stats &stats_, Profiler &profiler_)
|
||||||
|
|
|
@ -924,19 +924,9 @@ extern bool GHOST_setConsoleWindowState(GHOST_TConsoleWindowState action);
|
||||||
extern bool GHOST_UseNativePixels(void);
|
extern bool GHOST_UseNativePixels(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Warp the cursor, if supported.
|
* Return features which are supported by the GHOST back-end.
|
||||||
*/
|
*/
|
||||||
extern bool GHOST_SupportsCursorWarp(void);
|
extern GHOST_TCapabilityFlag GHOST_GetCapabilities(void);
|
||||||
|
|
||||||
/**
|
|
||||||
* Support positioning windows (when false `wmWindow.x,y` are meaningless).
|
|
||||||
*/
|
|
||||||
extern bool GHOST_SupportsWindowPosition(void);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Support a separate primary clipboard.
|
|
||||||
*/
|
|
||||||
extern bool GHOST_SupportsPrimaryClipboard(void);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Assign the callback which generates a back-trace (may be NULL).
|
* Assign the callback which generates a back-trace (may be NULL).
|
||||||
|
|
|
@ -318,19 +318,11 @@ class GHOST_ISystem {
|
||||||
virtual bool useNativePixel(void) = 0;
|
virtual bool useNativePixel(void) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return true when warping the cursor is supported.
|
* Return features supported by the system back-end.
|
||||||
|
*
|
||||||
|
* The resulting value doesn't change at run-time.
|
||||||
*/
|
*/
|
||||||
virtual bool supportsCursorWarp() = 0;
|
virtual GHOST_TCapabilityFlag getCapabilities() const = 0;
|
||||||
|
|
||||||
/**
|
|
||||||
* Return true getting/setting the window position is supported.
|
|
||||||
*/
|
|
||||||
virtual bool supportsWindowPosition() = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return true when a separate primary clipboard is supported.
|
|
||||||
*/
|
|
||||||
virtual bool supportsPrimaryClipboard() = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Focus window after opening, or put them in the background.
|
* Focus window after opening, or put them in the background.
|
||||||
|
|
|
@ -9,6 +9,9 @@
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* This is used by `GHOST_C-api.h` too, cannot use C++ conventions. */
|
||||||
|
// NOLINTBEGIN: modernize-use-using
|
||||||
|
|
||||||
#ifdef WITH_CXX_GUARDEDALLOC
|
#ifdef WITH_CXX_GUARDEDALLOC
|
||||||
# include "MEM_guardedalloc.h"
|
# include "MEM_guardedalloc.h"
|
||||||
#else
|
#else
|
||||||
|
@ -74,6 +77,37 @@ typedef void *GHOST_TUserDataPtr;
|
||||||
|
|
||||||
typedef enum { GHOST_kFailure = 0, GHOST_kSuccess } GHOST_TSuccess;
|
typedef enum { GHOST_kFailure = 0, GHOST_kSuccess } GHOST_TSuccess;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Static flag (relating to the back-ends support for features).
|
||||||
|
*
|
||||||
|
* \note When adding new capabilities, add to #GHOST_CAPABILITY_FLAG_ALL,
|
||||||
|
* then mask out of from the `getCapabilities(..)` callback with an explanation for why
|
||||||
|
* the feature is not supported.
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
/**
|
||||||
|
* Set when warping the cursor is supported (re-positioning the users cursor).
|
||||||
|
*/
|
||||||
|
GHOST_kCapabilityCursorWarp = (1 << 0),
|
||||||
|
/**
|
||||||
|
* Set when getting/setting the window position is supported.
|
||||||
|
*/
|
||||||
|
GHOST_kCapabilityWindowPosition = (1 << 1),
|
||||||
|
/**
|
||||||
|
* Set when a separate primary clipboard is supported.
|
||||||
|
* This is a convention for X11/WAYLAND, select text & MMB to paste (without an explicit copy).
|
||||||
|
*/
|
||||||
|
GHOST_kCapabilityPrimaryClipboard = (1 << 2),
|
||||||
|
} GHOST_TCapabilityFlag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Back-ends should use this, masking out features which are not supported
|
||||||
|
* with notes as to why those features cannot be supported.
|
||||||
|
*/
|
||||||
|
#define GHOST_CAPABILITY_FLAG_ALL \
|
||||||
|
(GHOST_kCapabilityCursorWarp | GHOST_kCapabilityWindowPosition | \
|
||||||
|
GHOST_kCapabilityPrimaryClipboard)
|
||||||
|
|
||||||
/* Xtilt and Ytilt represent how much the pen is tilted away from
|
/* Xtilt and Ytilt represent how much the pen is tilted away from
|
||||||
* vertically upright in either the X or Y direction, with X and Y the
|
* vertically upright in either the X or Y direction, with X and Y the
|
||||||
* axes of the tablet surface.
|
* axes of the tablet surface.
|
||||||
|
@ -848,3 +882,5 @@ typedef struct GHOST_XrControllerModelData {
|
||||||
} GHOST_XrControllerModelData;
|
} GHOST_XrControllerModelData;
|
||||||
|
|
||||||
#endif /* WITH_XR_OPENXR */
|
#endif /* WITH_XR_OPENXR */
|
||||||
|
|
||||||
|
// NOLINTEND: modernize-use-using
|
||||||
|
|
|
@ -895,22 +895,10 @@ bool GHOST_UseNativePixels(void)
|
||||||
return system->useNativePixel();
|
return system->useNativePixel();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GHOST_SupportsCursorWarp(void)
|
GHOST_TCapabilityFlag GHOST_GetCapabilities(void)
|
||||||
{
|
{
|
||||||
GHOST_ISystem *system = GHOST_ISystem::getSystem();
|
GHOST_ISystem *system = GHOST_ISystem::getSystem();
|
||||||
return system->supportsCursorWarp();
|
return system->getCapabilities();
|
||||||
}
|
|
||||||
|
|
||||||
bool GHOST_SupportsWindowPosition(void)
|
|
||||||
{
|
|
||||||
GHOST_ISystem *system = GHOST_ISystem::getSystem();
|
|
||||||
return system->supportsWindowPosition();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GHOST_SupportsPrimaryClipboard(void)
|
|
||||||
{
|
|
||||||
GHOST_ISystem *system = GHOST_ISystem::getSystem();
|
|
||||||
return system->supportsPrimaryClipboard();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GHOST_SetBacktraceHandler(GHOST_TBacktraceFn backtrace_fn)
|
void GHOST_SetBacktraceHandler(GHOST_TBacktraceFn backtrace_fn)
|
||||||
|
|
|
@ -418,21 +418,6 @@ void GHOST_System::setAutoFocus(const bool auto_focus)
|
||||||
m_autoFocus = auto_focus;
|
m_autoFocus = auto_focus;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GHOST_System::supportsCursorWarp()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GHOST_System::supportsWindowPosition()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GHOST_System::supportsPrimaryClipboard()
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GHOST_System::initDebug(GHOST_Debug debug)
|
void GHOST_System::initDebug(GHOST_Debug debug)
|
||||||
{
|
{
|
||||||
m_is_debug_enabled = debug.flags & GHOST_kDebugDefault;
|
m_is_debug_enabled = debug.flags & GHOST_kDebugDefault;
|
||||||
|
|
|
@ -150,10 +150,6 @@ class GHOST_System : public GHOST_ISystem {
|
||||||
bool useNativePixel(void);
|
bool useNativePixel(void);
|
||||||
bool m_nativePixel;
|
bool m_nativePixel;
|
||||||
|
|
||||||
bool supportsCursorWarp(void);
|
|
||||||
bool supportsWindowPosition(void);
|
|
||||||
bool supportsPrimaryClipboard(void);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Focus window after opening, or put them in the background.
|
* Focus window after opening, or put them in the background.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -193,6 +193,8 @@ class GHOST_SystemCocoa : public GHOST_System {
|
||||||
*/
|
*/
|
||||||
GHOST_TSuccess getButtons(GHOST_Buttons &buttons) const;
|
GHOST_TSuccess getButtons(GHOST_Buttons &buttons) const;
|
||||||
|
|
||||||
|
GHOST_TCapabilityFlag getCapabilities() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns Clipboard data
|
* Returns Clipboard data
|
||||||
* \param selection: Indicate which buffer to return.
|
* \param selection: Indicate which buffer to return.
|
||||||
|
|
|
@ -900,6 +900,14 @@ GHOST_TSuccess GHOST_SystemCocoa::getButtons(GHOST_Buttons &buttons) const
|
||||||
return GHOST_kSuccess;
|
return GHOST_kSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GHOST_TCapabilityFlag GHOST_SystemCocoa::getCapabilities() const
|
||||||
|
{
|
||||||
|
return GHOST_TCapabilityFlag(GHOST_CAPABILITY_FLAG_ALL &
|
||||||
|
~(
|
||||||
|
/* Cocoa has no support for a primary selection clipboard. */
|
||||||
|
GHOST_kCapabilityPrimaryClipboard));
|
||||||
|
}
|
||||||
|
|
||||||
#pragma mark Event handlers
|
#pragma mark Event handlers
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -42,6 +42,13 @@ class GHOST_SystemHeadless : public GHOST_System {
|
||||||
{
|
{
|
||||||
return GHOST_kSuccess;
|
return GHOST_kSuccess;
|
||||||
}
|
}
|
||||||
|
GHOST_TCapabilityFlag getCapabilities() const override
|
||||||
|
{
|
||||||
|
return GHOST_TCapabilityFlag(GHOST_CAPABILITY_FLAG_ALL &
|
||||||
|
/* No windowing functionality supported. */
|
||||||
|
~(GHOST_kCapabilityWindowPosition | GHOST_kCapabilityCursorWarp |
|
||||||
|
GHOST_kCapabilityPrimaryClipboard));
|
||||||
|
}
|
||||||
char *getClipboard(bool /*selection*/) const override
|
char *getClipboard(bool /*selection*/) const override
|
||||||
{
|
{
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
|
@ -715,7 +715,7 @@ GHOST_WindowSDL *GHOST_SystemSDL::findGhostWindow(SDL_Window *sdl_win)
|
||||||
if (sdl_win == nullptr) {
|
if (sdl_win == nullptr) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
/* It is not entirely safe to do this as the backptr may point
|
/* It is not entirely safe to do this as the back-pointer may point
|
||||||
* to a window that has recently been removed.
|
* to a window that has recently been removed.
|
||||||
* We should always check the window manager's list of windows
|
* We should always check the window manager's list of windows
|
||||||
* and only process events on these windows. */
|
* and only process events on these windows. */
|
||||||
|
@ -751,6 +751,15 @@ GHOST_TSuccess GHOST_SystemSDL::getButtons(GHOST_Buttons &buttons) const
|
||||||
return GHOST_kSuccess;
|
return GHOST_kSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GHOST_TCapabilityFlag GHOST_SystemSDL::getCapabilities() const
|
||||||
|
{
|
||||||
|
return GHOST_TCapabilityFlag(
|
||||||
|
GHOST_CAPABILITY_FLAG_ALL &
|
||||||
|
~(
|
||||||
|
/* This SDL back-end has not yet implemented primary clipboard. */
|
||||||
|
GHOST_kCapabilityPrimaryClipboard));
|
||||||
|
}
|
||||||
|
|
||||||
char *GHOST_SystemSDL::getClipboard(bool /*selection*/) const
|
char *GHOST_SystemSDL::getClipboard(bool /*selection*/) const
|
||||||
{
|
{
|
||||||
return (char *)SDL_GetClipboardText();
|
return (char *)SDL_GetClipboardText();
|
||||||
|
|
|
@ -42,6 +42,8 @@ class GHOST_SystemSDL : public GHOST_System {
|
||||||
|
|
||||||
GHOST_TSuccess getButtons(GHOST_Buttons &buttons) const;
|
GHOST_TSuccess getButtons(GHOST_Buttons &buttons) const;
|
||||||
|
|
||||||
|
GHOST_TCapabilityFlag getCapabilities() const;
|
||||||
|
|
||||||
char *getClipboard(bool selection) const;
|
char *getClipboard(bool selection) const;
|
||||||
|
|
||||||
void putClipboard(const char *buffer, bool selection) const;
|
void putClipboard(const char *buffer, bool selection) const;
|
||||||
|
|
|
@ -6675,22 +6675,16 @@ GHOST_TSuccess GHOST_SystemWayland::cursor_visibility_set(const bool visible)
|
||||||
return GHOST_kSuccess;
|
return GHOST_kSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GHOST_SystemWayland::supportsCursorWarp()
|
GHOST_TCapabilityFlag GHOST_SystemWayland::getCapabilities() const
|
||||||
{
|
{
|
||||||
/* WAYLAND doesn't support setting the cursor position directly,
|
return GHOST_TCapabilityFlag(
|
||||||
* this is an intentional choice, forcing us to use a software cursor in this case. */
|
GHOST_CAPABILITY_FLAG_ALL &
|
||||||
return false;
|
~(
|
||||||
}
|
/* WAYLAND doesn't support accessing the window position. */
|
||||||
|
GHOST_kCapabilityWindowPosition |
|
||||||
bool GHOST_SystemWayland::supportsWindowPosition()
|
/* WAYLAND doesn't support setting the cursor position directly,
|
||||||
{
|
* this is an intentional choice, forcing us to use a software cursor in this case. */
|
||||||
/* WAYLAND doesn't support accessing the window position. */
|
GHOST_kCapabilityCursorWarp));
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GHOST_SystemWayland::supportsPrimaryClipboard()
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GHOST_SystemWayland::cursor_grab_use_software_display_get(const GHOST_TGrabCursorMode mode)
|
bool GHOST_SystemWayland::cursor_grab_use_software_display_get(const GHOST_TGrabCursorMode mode)
|
||||||
|
@ -7038,7 +7032,7 @@ bool GHOST_SystemWayland::window_cursor_grab_set(const GHOST_TGrabCursorMode mod
|
||||||
const struct GWL_SeatStateGrab grab_state_next = seat_grab_state_from_mode(mode,
|
const struct GWL_SeatStateGrab grab_state_next = seat_grab_state_from_mode(mode,
|
||||||
use_software_confine);
|
use_software_confine);
|
||||||
|
|
||||||
/* Check for wrap as #supportsCursorWarp isn't supported. */
|
/* Check for wrap as #GHOST_kCapabilityCursorWarp isn't supported. */
|
||||||
const bool use_visible = !(ELEM(mode, GHOST_kGrabHide, GHOST_kGrabWrap) || use_software_confine);
|
const bool use_visible = !(ELEM(mode, GHOST_kGrabHide, GHOST_kGrabWrap) || use_software_confine);
|
||||||
const bool is_hardware_cursor = !cursor_is_software(mode, use_software_confine);
|
const bool is_hardware_cursor = !cursor_is_software(mode, use_software_confine);
|
||||||
|
|
||||||
|
|
|
@ -142,9 +142,7 @@ class GHOST_SystemWayland : public GHOST_System {
|
||||||
const bool is_dialog,
|
const bool is_dialog,
|
||||||
const GHOST_IWindow *parentWindow) override;
|
const GHOST_IWindow *parentWindow) override;
|
||||||
|
|
||||||
bool supportsCursorWarp() override;
|
GHOST_TCapabilityFlag getCapabilities() const override;
|
||||||
bool supportsWindowPosition() override;
|
|
||||||
bool supportsPrimaryClipboard() override;
|
|
||||||
|
|
||||||
/* WAYLAND utility functions (share window/system logic). */
|
/* WAYLAND utility functions (share window/system logic). */
|
||||||
|
|
||||||
|
|
|
@ -496,6 +496,14 @@ GHOST_TSuccess GHOST_SystemWin32::getButtons(GHOST_Buttons &buttons) const
|
||||||
return GHOST_kSuccess;
|
return GHOST_kSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GHOST_TCapabilityFlag GHOST_SystemWin32::getCapabilities() const
|
||||||
|
{
|
||||||
|
return GHOST_TCapabilityFlag(GHOST_CAPABILITY_FLAG_ALL &
|
||||||
|
~(
|
||||||
|
/* WIN32 has no support for a primary selection clipboard. */
|
||||||
|
GHOST_kCapabilityPrimaryClipboard));
|
||||||
|
}
|
||||||
|
|
||||||
GHOST_TSuccess GHOST_SystemWin32::init()
|
GHOST_TSuccess GHOST_SystemWin32::init()
|
||||||
{
|
{
|
||||||
GHOST_TSuccess success = GHOST_System::init();
|
GHOST_TSuccess success = GHOST_System::init();
|
||||||
|
|
|
@ -199,6 +199,8 @@ class GHOST_SystemWin32 : public GHOST_System {
|
||||||
*/
|
*/
|
||||||
GHOST_TSuccess getButtons(GHOST_Buttons &buttons) const;
|
GHOST_TSuccess getButtons(GHOST_Buttons &buttons) const;
|
||||||
|
|
||||||
|
GHOST_TCapabilityFlag getCapabilities() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns unsigned char from CUT_BUFFER0
|
* Returns unsigned char from CUT_BUFFER0
|
||||||
* \param selection: Used by X11 only.
|
* \param selection: Used by X11 only.
|
||||||
|
|
|
@ -497,7 +497,7 @@ GHOST_WindowX11 *GHOST_SystemX11::findGhostWindow(Window xwind) const
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* It is not entirely safe to do this as the backptr may point
|
/* It is not entirely safe to do this as the back-pointer may point
|
||||||
* to a window that has recently been removed.
|
* to a window that has recently been removed.
|
||||||
* We should always check the window manager's list of windows
|
* We should always check the window manager's list of windows
|
||||||
* and only process events on these windows. */
|
* and only process events on these windows. */
|
||||||
|
@ -1740,9 +1740,9 @@ GHOST_TSuccess GHOST_SystemX11::setCursorPosition(int32_t x, int32_t y)
|
||||||
return GHOST_kSuccess;
|
return GHOST_kSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GHOST_SystemX11::supportsPrimaryClipboard()
|
GHOST_TCapabilityFlag GHOST_SystemX11::getCapabilities() const
|
||||||
{
|
{
|
||||||
return true;
|
return GHOST_TCapabilityFlag(GHOST_CAPABILITY_FLAG_ALL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GHOST_SystemX11::addDirtyWindow(GHOST_WindowX11 *bad_wind)
|
void GHOST_SystemX11::addDirtyWindow(GHOST_WindowX11 *bad_wind)
|
||||||
|
|
|
@ -168,7 +168,7 @@ class GHOST_SystemX11 : public GHOST_System {
|
||||||
*/
|
*/
|
||||||
GHOST_TSuccess getButtons(GHOST_Buttons &buttons) const;
|
GHOST_TSuccess getButtons(GHOST_Buttons &buttons) const;
|
||||||
|
|
||||||
bool supportsPrimaryClipboard() override;
|
GHOST_TCapabilityFlag getCapabilities() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag a window as dirty. This will
|
* Flag a window as dirty. This will
|
||||||
|
|
|
@ -1479,7 +1479,7 @@ struct FaceDetails {
|
||||||
/* Details about the fallback fonts we ship, so that we can load only when needed. */
|
/* Details about the fallback fonts we ship, so that we can load only when needed. */
|
||||||
static const struct FaceDetails static_face_details[] = {
|
static const struct FaceDetails static_face_details[] = {
|
||||||
{"lastresort.woff2", UINT32_MAX, UINT32_MAX, UINT32_MAX, UINT32_MAX},
|
{"lastresort.woff2", UINT32_MAX, UINT32_MAX, UINT32_MAX, UINT32_MAX},
|
||||||
{"Noto Sans CJK Regular.woff2", 0x30000083L, 0x2BDF3C10L, 0x16L, 0},
|
{"Noto Sans CJK Regular.woff2", 0x30000083L, 0x29DF3C10L, 0x16L, 0},
|
||||||
{"NotoEmoji-VariableFont_wght.woff2", 0x80000003L, 0x241E4ACL, 0x14000000L, 0x4000000L},
|
{"NotoEmoji-VariableFont_wght.woff2", 0x80000003L, 0x241E4ACL, 0x14000000L, 0x4000000L},
|
||||||
{"NotoSansArabic-VariableFont_wdth,wght.woff2",
|
{"NotoSansArabic-VariableFont_wdth,wght.woff2",
|
||||||
TT_UCR_ARABIC,
|
TT_UCR_ARABIC,
|
||||||
|
|
|
@ -631,20 +631,53 @@ static FT_UInt blf_glyph_index_from_charcode(FontBLF **font, const uint charcode
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Not found in main font, so look in the others. */
|
/* First look in currently-loaded cached fonts that match the coverage bit. Super fast. */
|
||||||
FontBLF *last_resort = NULL;
|
|
||||||
int coverage_bit = blf_charcode_to_coverage_bit(charcode);
|
int coverage_bit = blf_charcode_to_coverage_bit(charcode);
|
||||||
|
for (int i = 0; i < BLF_MAX_FONT; i++) {
|
||||||
|
FontBLF *f = global_font[i];
|
||||||
|
if (!f || f == *font || !(f->face) || !(f->flags & BLF_DEFAULT) ||
|
||||||
|
(!((*font)->flags & BLF_MONOSPACED) && (f->flags & BLF_MONOSPACED)) ||
|
||||||
|
f->flags & BLF_LAST_RESORT) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (coverage_bit < 0 || blf_font_has_coverage_bit(f, coverage_bit)) {
|
||||||
|
glyph_index = blf_get_char_index(f, charcode);
|
||||||
|
if (glyph_index) {
|
||||||
|
*font = f;
|
||||||
|
return glyph_index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Next look only in unloaded fonts that match the coverage bit. */
|
||||||
|
for (int i = 0; i < BLF_MAX_FONT; i++) {
|
||||||
|
FontBLF *f = global_font[i];
|
||||||
|
if (!f || f == *font || (f->face) || !(f->flags & BLF_DEFAULT) ||
|
||||||
|
(!((*font)->flags & BLF_MONOSPACED) && (f->flags & BLF_MONOSPACED)) ||
|
||||||
|
f->flags & BLF_LAST_RESORT) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (coverage_bit < 0 || blf_font_has_coverage_bit(f, coverage_bit)) {
|
||||||
|
glyph_index = blf_get_char_index(f, charcode);
|
||||||
|
if (glyph_index) {
|
||||||
|
*font = f;
|
||||||
|
return glyph_index;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Last look in anything else. Also check if we have a last-resort font. */
|
||||||
|
FontBLF *last_resort = NULL;
|
||||||
for (int i = 0; i < BLF_MAX_FONT; i++) {
|
for (int i = 0; i < BLF_MAX_FONT; i++) {
|
||||||
FontBLF *f = global_font[i];
|
FontBLF *f = global_font[i];
|
||||||
if (!f || f == *font || !(f->flags & BLF_DEFAULT)) {
|
if (!f || f == *font || !(f->flags & BLF_DEFAULT)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (f->flags & BLF_LAST_RESORT) {
|
if (f->flags & BLF_LAST_RESORT) {
|
||||||
last_resort = f;
|
last_resort = f;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (coverage_bit < 0 || blf_font_has_coverage_bit(f, coverage_bit)) {
|
if (coverage_bit >= 0 && !blf_font_has_coverage_bit(f, coverage_bit)) {
|
||||||
glyph_index = blf_get_char_index(f, charcode);
|
glyph_index = blf_get_char_index(f, charcode);
|
||||||
if (glyph_index) {
|
if (glyph_index) {
|
||||||
*font = f;
|
*font = f;
|
||||||
|
|
|
@ -132,22 +132,22 @@ bool CustomData_bmesh_has_free(const struct CustomData *data);
|
||||||
bool CustomData_has_referenced(const struct CustomData *data);
|
bool CustomData_has_referenced(const struct CustomData *data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copies the "value" (e.g. mloopuv uv or mloopcol colors) from one block to
|
* Copies the "value" (e.g. `mloopuv` UV or `mloopcol` colors) from one block to
|
||||||
* another, while not overwriting anything else (e.g. flags). probably only
|
* another, while not overwriting anything else (e.g. flags). probably only
|
||||||
* implemented for mloopuv/mloopcol, for now.
|
* implemented for `mloopuv/mloopcol`, for now.
|
||||||
*/
|
*/
|
||||||
void CustomData_data_copy_value(int type, const void *source, void *dest);
|
void CustomData_data_copy_value(int type, const void *source, void *dest);
|
||||||
void CustomData_data_set_default_value(int type, void *elem);
|
void CustomData_data_set_default_value(int type, void *elem);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mixes the "value" (e.g. mloopuv uv or mloopcol colors) from one block into
|
* Mixes the "value" (e.g. `mloopuv` UV or `mloopcol` colors) from one block into
|
||||||
* another, while not overwriting anything else (e.g. flags).
|
* another, while not overwriting anything else (e.g. flags).
|
||||||
*/
|
*/
|
||||||
void CustomData_data_mix_value(
|
void CustomData_data_mix_value(
|
||||||
int type, const void *source, void *dest, int mixmode, float mixfactor);
|
int type, const void *source, void *dest, int mixmode, float mixfactor);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compares if data1 is equal to data2. type is a valid CustomData type
|
* Compares if data1 is equal to data2. type is a valid #CustomData type
|
||||||
* enum (e.g. #CD_PROP_FLOAT). the layer type's equal function is used to compare
|
* enum (e.g. #CD_PROP_FLOAT). the layer type's equal function is used to compare
|
||||||
* the data, if it exists, otherwise #memcmp is used.
|
* the data, if it exists, otherwise #memcmp is used.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -501,7 +501,7 @@ struct GPUTexture *BKE_image_create_gpu_texture_from_ibuf(struct Image *image, s
|
||||||
*
|
*
|
||||||
* This is provided as a separate function and not implemented as part of the GPU texture retrieval
|
* This is provided as a separate function and not implemented as part of the GPU texture retrieval
|
||||||
* functions because the current cache system only allows a single pass, layer, and stereo view to
|
* functions because the current cache system only allows a single pass, layer, and stereo view to
|
||||||
* be cached, so possible frequent invalidations of the cache can have performance implications,
|
* be cached, so possible frequent cache invalidation can have performance implications,
|
||||||
* and making invalidation explicit by calling this function will help make that clear and pave the
|
* and making invalidation explicit by calling this function will help make that clear and pave the
|
||||||
* way for a more complete cache system in the future.
|
* way for a more complete cache system in the future.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "BLI_string.h"
|
#include "BLI_string.h"
|
||||||
#include "BLI_string_utf8.h"
|
#include "BLI_string_utf8.h"
|
||||||
#include "BLI_string_utils.h"
|
#include "BLI_string_utils.h"
|
||||||
|
#include "BLI_tempfile.h"
|
||||||
#include "BLI_utildefines.h"
|
#include "BLI_utildefines.h"
|
||||||
|
|
||||||
#include "BKE_appdir.h" /* own include */
|
#include "BKE_appdir.h" /* own include */
|
||||||
|
@ -1089,7 +1090,7 @@ void BKE_appdir_app_templates(ListBase *templates)
|
||||||
* Also make sure the temp dir has a trailing slash
|
* Also make sure the temp dir has a trailing slash
|
||||||
*
|
*
|
||||||
* \param tempdir: The full path to the temporary temp directory.
|
* \param tempdir: The full path to the temporary temp directory.
|
||||||
* \param tempdir_len: The size of the \a tempdir buffer.
|
* \param tempdir_maxlen: The size of the \a tempdir buffer.
|
||||||
* \param userdir: Directory specified in user preferences (may be NULL).
|
* \param userdir: Directory specified in user preferences (may be NULL).
|
||||||
* note that by default this is an empty string, only use when non-empty.
|
* note that by default this is an empty string, only use when non-empty.
|
||||||
*/
|
*/
|
||||||
|
@ -1098,37 +1099,14 @@ static void where_is_temp(char *tempdir, const size_t tempdir_maxlen, const char
|
||||||
|
|
||||||
tempdir[0] = '\0';
|
tempdir[0] = '\0';
|
||||||
|
|
||||||
if (userdir && BLI_is_dir(userdir)) {
|
if (userdir && userdir[0] != '\0' && BLI_is_dir(userdir)) {
|
||||||
BLI_strncpy(tempdir, userdir, tempdir_maxlen);
|
BLI_strncpy(tempdir, userdir, tempdir_maxlen);
|
||||||
}
|
/* Add a trailing slash if needed. */
|
||||||
|
|
||||||
if (tempdir[0] == '\0') {
|
|
||||||
const char *env_vars[] = {
|
|
||||||
#ifdef WIN32
|
|
||||||
"TEMP",
|
|
||||||
#else
|
|
||||||
/* Non standard (could be removed). */
|
|
||||||
"TMP",
|
|
||||||
/* Posix standard. */
|
|
||||||
"TMPDIR",
|
|
||||||
#endif
|
|
||||||
};
|
|
||||||
for (int i = 0; i < ARRAY_SIZE(env_vars); i++) {
|
|
||||||
const char *tmp = BLI_getenv(env_vars[i]);
|
|
||||||
if (tmp && (tmp[0] != '\0') && BLI_is_dir(tmp)) {
|
|
||||||
BLI_strncpy(tempdir, tmp, tempdir_maxlen);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tempdir[0] == '\0') {
|
|
||||||
BLI_strncpy(tempdir, "/tmp/", tempdir_maxlen);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
/* add a trailing slash if needed */
|
|
||||||
BLI_path_slash_ensure(tempdir, tempdir_maxlen);
|
BLI_path_slash_ensure(tempdir, tempdir_maxlen);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BLI_temp_directory_path_get(tempdir, tempdir_maxlen);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tempdir_session_create(char *tempdir_session,
|
static void tempdir_session_create(char *tempdir_session,
|
||||||
|
|
|
@ -1015,7 +1015,7 @@ static void layerInterp_mloopcol(const void **sources,
|
||||||
/** \name Callbacks for #OrigSpaceLoop
|
/** \name Callbacks for #OrigSpaceLoop
|
||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
/* origspace is almost exact copy of mloopuv's, keep in sync */
|
/* origspace is almost exact copy of #MLoopUV, keep in sync. */
|
||||||
static void layerCopyValue_mloop_origspace(const void *source,
|
static void layerCopyValue_mloop_origspace(const void *source,
|
||||||
void *dest,
|
void *dest,
|
||||||
const int /*mixmode*/,
|
const int /*mixmode*/,
|
||||||
|
|
|
@ -1847,6 +1847,13 @@ static void sculpt_update_object(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_paint_tool) {
|
if (is_paint_tool) {
|
||||||
|
if (ss->vcol_domain == ATTR_DOMAIN_CORNER) {
|
||||||
|
/* Ensure pbvh nodes have loop indices; the sculpt undo system
|
||||||
|
* needs them for color attributes.
|
||||||
|
*/
|
||||||
|
BKE_pbvh_ensure_node_loops(ss->pbvh);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We should rebuild the PBVH_pixels when painting canvas changes.
|
* We should rebuild the PBVH_pixels when painting canvas changes.
|
||||||
*
|
*
|
||||||
|
|
|
@ -15,6 +15,8 @@
|
||||||
* This design allows some function overloads to be more efficient with certain types.
|
* This design allows some function overloads to be more efficient with certain types.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#include "BLI_math_base.hh"
|
#include "BLI_math_base.hh"
|
||||||
|
|
||||||
namespace blender::math {
|
namespace blender::math {
|
||||||
|
|
|
@ -18,6 +18,8 @@
|
||||||
* the fastest and more correct option.
|
* the fastest and more correct option.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#include "BLI_math_angle_types.hh"
|
#include "BLI_math_angle_types.hh"
|
||||||
#include "BLI_math_base.hh"
|
#include "BLI_math_base.hh"
|
||||||
#include "BLI_math_basis_types.hh"
|
#include "BLI_math_basis_types.hh"
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
* - Curve Tangent-Space: X-left, Y-up, Z-forward
|
* - Curve Tangent-Space: X-left, Y-up, Z-forward
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#include "BLI_math_base.hh"
|
#include "BLI_math_base.hh"
|
||||||
#include "BLI_math_vector_types.hh"
|
#include "BLI_math_vector_types.hh"
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,8 @@
|
||||||
* eg: `Euler3 my_euler(EulerOrder::XYZ); my_euler = my_quaternion:`
|
* eg: `Euler3 my_euler(EulerOrder::XYZ); my_euler = my_quaternion:`
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#include "BLI_math_angle_types.hh"
|
#include "BLI_math_angle_types.hh"
|
||||||
#include "BLI_math_base.hh"
|
#include "BLI_math_base.hh"
|
||||||
#include "BLI_math_basis_types.hh"
|
#include "BLI_math_basis_types.hh"
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
* \ingroup bli
|
* \ingroup bli
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
#include "BLI_math_angle_types.hh"
|
#include "BLI_math_angle_types.hh"
|
||||||
#include "BLI_math_base.hh"
|
#include "BLI_math_base.hh"
|
||||||
#include "BLI_math_basis_types.hh"
|
#include "BLI_math_basis_types.hh"
|
||||||
|
|
|
@ -19,6 +19,7 @@ extern "C" {
|
||||||
/**
|
/**
|
||||||
* Stored in R8G8 format. Load it in the following format:
|
* Stored in R8G8 format. Load it in the following format:
|
||||||
* - DX10: DXGI_FORMAT_R8G8_UNORM
|
* - DX10: DXGI_FORMAT_R8G8_UNORM
|
||||||
|
* - GPU: GPU_RG8 texture format and GPU_DATA_UBYTE data format.
|
||||||
*/
|
*/
|
||||||
extern const unsigned char areaTexBytes[];
|
extern const unsigned char areaTexBytes[];
|
||||||
|
|
||||||
|
@ -30,6 +31,7 @@ extern const unsigned char areaTexBytes[];
|
||||||
/**
|
/**
|
||||||
* Stored in R8 format. Load it in the following format:
|
* Stored in R8 format. Load it in the following format:
|
||||||
* - DX10: DXGI_FORMAT_R8_UNORM
|
* - DX10: DXGI_FORMAT_R8_UNORM
|
||||||
|
* - GPU: GPU_R8 texture format and GPU_DATA_UBYTE data format.
|
||||||
*/
|
*/
|
||||||
extern const unsigned char searchTexBytes[];
|
extern const unsigned char searchTexBytes[];
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
* Copyright 2023 Blender Foundation. */
|
||||||
|
|
||||||
|
/** \file
|
||||||
|
* \ingroup bli
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "BLI_sys_types.h"
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Get the path to a directory suitable for temporary files.
|
||||||
|
*
|
||||||
|
* The return path is guaranteed to exist and to be a directory, as well as to contain a trailing
|
||||||
|
* directory separator.
|
||||||
|
*
|
||||||
|
* At maximum the buffer_size number of characters is written to the temp_directory. The directory
|
||||||
|
* path is always null-terminated. */
|
||||||
|
void BLI_temp_directory_path_get(char *temp_directory, const size_t buffer_size);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -24,7 +24,7 @@ struct ProjCameraInfo *BLI_uvproject_camera_info(struct Object *ob,
|
||||||
float winy);
|
float winy);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply UV from uvinfo (camera).
|
* Apply UV from #ProjCameraInfo (camera).
|
||||||
*/
|
*/
|
||||||
void BLI_uvproject_from_camera(float target[2], float source[3], struct ProjCameraInfo *uci);
|
void BLI_uvproject_from_camera(float target[2], float source[3], struct ProjCameraInfo *uci);
|
||||||
|
|
||||||
|
|
|
@ -131,6 +131,7 @@ set(SRC
|
||||||
intern/scanfill_utils.c
|
intern/scanfill_utils.c
|
||||||
intern/serialize.cc
|
intern/serialize.cc
|
||||||
intern/session_uuid.c
|
intern/session_uuid.c
|
||||||
|
intern/smaa_textures.c
|
||||||
intern/smallhash.c
|
intern/smallhash.c
|
||||||
intern/sort.c
|
intern/sort.c
|
||||||
intern/sort_utils.c
|
intern/sort_utils.c
|
||||||
|
@ -147,6 +148,7 @@ set(SRC
|
||||||
intern/task_pool.cc
|
intern/task_pool.cc
|
||||||
intern/task_range.cc
|
intern/task_range.cc
|
||||||
intern/task_scheduler.cc
|
intern/task_scheduler.cc
|
||||||
|
intern/tempfile.c
|
||||||
intern/threads.cc
|
intern/threads.cc
|
||||||
intern/time.c
|
intern/time.c
|
||||||
intern/timecode.c
|
intern/timecode.c
|
||||||
|
@ -329,6 +331,7 @@ set(SRC
|
||||||
BLI_set_slots.hh
|
BLI_set_slots.hh
|
||||||
BLI_shared_cache.hh
|
BLI_shared_cache.hh
|
||||||
BLI_simd.h
|
BLI_simd.h
|
||||||
|
BLI_smaa_textures.h
|
||||||
BLI_smallhash.h
|
BLI_smallhash.h
|
||||||
BLI_sort.h
|
BLI_sort.h
|
||||||
BLI_sort.hh
|
BLI_sort.hh
|
||||||
|
@ -347,6 +350,7 @@ set(SRC
|
||||||
BLI_system.h
|
BLI_system.h
|
||||||
BLI_task.h
|
BLI_task.h
|
||||||
BLI_task.hh
|
BLI_task.hh
|
||||||
|
BLI_tempfile.h
|
||||||
BLI_threads.h
|
BLI_threads.h
|
||||||
BLI_timecode.h
|
BLI_timecode.h
|
||||||
BLI_timeit.hh
|
BLI_timeit.hh
|
||||||
|
@ -533,6 +537,7 @@ if(WITH_GTESTS)
|
||||||
tests/BLI_string_utf8_test.cc
|
tests/BLI_string_utf8_test.cc
|
||||||
tests/BLI_task_graph_test.cc
|
tests/BLI_task_graph_test.cc
|
||||||
tests/BLI_task_test.cc
|
tests/BLI_task_test.cc
|
||||||
|
tests/BLI_tempfile_test.cc
|
||||||
tests/BLI_uuid_test.cc
|
tests/BLI_uuid_test.cc
|
||||||
tests/BLI_vector_set_test.cc
|
tests/BLI_vector_set_test.cc
|
||||||
tests/BLI_vector_test.cc
|
tests/BLI_vector_test.cc
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
* 2013 Fernando Navarro <fernandn@microsoft.com>
|
* 2013 Fernando Navarro <fernandn@microsoft.com>
|
||||||
* 2013 Diego Gutierrez <diegog@unizar.es> */
|
* 2013 Diego Gutierrez <diegog@unizar.es> */
|
||||||
|
|
||||||
#include "smaa_textures.h"
|
#include "BLI_smaa_textures.h"
|
||||||
|
|
||||||
/* Don't re-wrap large data definitions. */
|
/* Don't re-wrap large data definitions. */
|
||||||
/* clang-format off */
|
/* clang-format off */
|
||||||
|
@ -13,6 +13,7 @@
|
||||||
/**
|
/**
|
||||||
* Stored in R8G8 format. Load it in the following format:
|
* Stored in R8G8 format. Load it in the following format:
|
||||||
* - DX10: DXGI_FORMAT_R8G8_UNORM
|
* - DX10: DXGI_FORMAT_R8G8_UNORM
|
||||||
|
* - GPU: GPU_RG8 texture format and GPU_DATA_UBYTE data format.
|
||||||
*/
|
*/
|
||||||
const unsigned char areaTexBytes[] = {
|
const unsigned char areaTexBytes[] = {
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
|
@ -14954,6 +14955,7 @@ const unsigned char areaTexBytes[] = {
|
||||||
/**
|
/**
|
||||||
* Stored in R8 format. Load it in the following format:
|
* Stored in R8 format. Load it in the following format:
|
||||||
* - DX10: DXGI_FORMAT_R8_UNORM
|
* - DX10: DXGI_FORMAT_R8_UNORM
|
||||||
|
* - GPU: GPU_R8 texture format and GPU_DATA_UBYTE data format.
|
||||||
*/
|
*/
|
||||||
const unsigned char searchTexBytes[] = {
|
const unsigned char searchTexBytes[] = {
|
||||||
0xfe, 0xfe, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x7f, 0x7f,
|
0xfe, 0xfe, 0x00, 0x7f, 0x7f, 0x00, 0x00, 0xfe, 0xfe, 0x00, 0x7f, 0x7f,
|
|
@ -0,0 +1,42 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
* Copyright 2023 Blender Foundation. */
|
||||||
|
|
||||||
|
#include "BLI_tempfile.h"
|
||||||
|
|
||||||
|
#include "BLI_fileops.h"
|
||||||
|
#include "BLI_path_util.h"
|
||||||
|
#include "BLI_string.h"
|
||||||
|
|
||||||
|
void BLI_temp_directory_path_get(char *temp_directory, const size_t buffer_size)
|
||||||
|
{
|
||||||
|
temp_directory[0] = '\0';
|
||||||
|
|
||||||
|
const char *env_vars[] = {
|
||||||
|
#ifdef WIN32
|
||||||
|
"TEMP",
|
||||||
|
#else
|
||||||
|
/* Non standard (could be removed). */
|
||||||
|
"TMP",
|
||||||
|
/* Posix standard. */
|
||||||
|
"TMPDIR",
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int i = 0; i < ARRAY_SIZE(env_vars); i++) {
|
||||||
|
const char *tmp = BLI_getenv(env_vars[i]);
|
||||||
|
if (tmp && (tmp[0] != '\0') && BLI_is_dir(tmp)) {
|
||||||
|
BLI_strncpy(temp_directory, tmp, buffer_size);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (temp_directory[0] == '\0') {
|
||||||
|
BLI_strncpy(temp_directory, "/tmp/", buffer_size);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/* Add a trailing slash if needed. */
|
||||||
|
BLI_path_slash_ensure(temp_directory, buffer_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
BLI_dir_create_recursive(temp_directory);
|
||||||
|
}
|
|
@ -1,11 +1,16 @@
|
||||||
/* SPDX-License-Identifier: Apache-2.0 */
|
/* SPDX-License-Identifier: Apache-2.0 */
|
||||||
|
|
||||||
#include "testing/testing.h"
|
#include "testing/testing.h"
|
||||||
|
|
||||||
#include "BLI_fileops.hh"
|
#include "BLI_fileops.hh"
|
||||||
#include "BLI_path_util.h"
|
#include "BLI_path_util.h"
|
||||||
#include "BLI_string.h"
|
#include "BLI_string.h"
|
||||||
|
#include "BLI_system.h"
|
||||||
|
#include "BLI_tempfile.h"
|
||||||
#include "BLI_threads.h"
|
#include "BLI_threads.h"
|
||||||
|
|
||||||
|
#include BLI_SYSTEM_PID_H
|
||||||
|
|
||||||
namespace blender::tests {
|
namespace blender::tests {
|
||||||
|
|
||||||
class ChangeWorkingDirectoryTest : public testing::Test {
|
class ChangeWorkingDirectoryTest : public testing::Test {
|
||||||
|
@ -26,6 +31,20 @@ class ChangeWorkingDirectoryTest : public testing::Test {
|
||||||
|
|
||||||
BLI_threadapi_exit();
|
BLI_threadapi_exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Make a pseudo-unique file name file within the temp directory in a cross-platform manner. */
|
||||||
|
static std::string make_pseudo_unique_temp_filename()
|
||||||
|
{
|
||||||
|
char temp_dir[FILE_MAX];
|
||||||
|
BLI_temp_directory_path_get(temp_dir, sizeof(temp_dir));
|
||||||
|
|
||||||
|
const std::string directory_name = "blender_test_" + std::to_string(getpid());
|
||||||
|
|
||||||
|
char filepath[FILE_MAX];
|
||||||
|
BLI_path_join(filepath, sizeof(filepath), temp_dir, directory_name.c_str());
|
||||||
|
|
||||||
|
return filepath;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST(fileops, fstream_open_string_filename)
|
TEST(fileops, fstream_open_string_filename)
|
||||||
|
@ -71,7 +90,7 @@ TEST_F(ChangeWorkingDirectoryTest, change_working_directory)
|
||||||
ASSERT_TRUE(original_cwd == original_cwd_buff)
|
ASSERT_TRUE(original_cwd == original_cwd_buff)
|
||||||
<< "Returned CWD path unexpectedly different than given char buffer.";
|
<< "Returned CWD path unexpectedly different than given char buffer.";
|
||||||
|
|
||||||
std::string temp_file_name(std::tmpnam(nullptr));
|
std::string temp_file_name = make_pseudo_unique_temp_filename();
|
||||||
test_temp_dir = temp_file_name + "_новый";
|
test_temp_dir = temp_file_name + "_новый";
|
||||||
|
|
||||||
if (BLI_exists(test_temp_dir.c_str())) {
|
if (BLI_exists(test_temp_dir.c_str())) {
|
||||||
|
@ -94,7 +113,7 @@ TEST_F(ChangeWorkingDirectoryTest, change_working_directory)
|
||||||
<< "Returned CWD path unexpectedly different than given char buffer.";
|
<< "Returned CWD path unexpectedly different than given char buffer.";
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
/* The name returned by std::tmpnam is fine but the Apple OS method
|
/* The name returned by `std::tmpnam` is fine but the Apple OS method
|
||||||
* picks the true var folder, not the alias, meaning the below
|
* picks the true var folder, not the alias, meaning the below
|
||||||
* comparison always fails unless we prepend with the correct value. */
|
* comparison always fails unless we prepend with the correct value. */
|
||||||
test_temp_dir = "/private" + test_temp_dir;
|
test_temp_dir = "/private" + test_temp_dir;
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
/* SPDX-License-Identifier: Apache-2.0 */
|
||||||
|
|
||||||
|
#include "BLI_tempfile.h"
|
||||||
|
|
||||||
|
#include "BLI_fileops.h"
|
||||||
|
#include "BLI_path_util.h"
|
||||||
|
|
||||||
|
#include "testing/testing.h"
|
||||||
|
|
||||||
|
namespace blender::tests {
|
||||||
|
|
||||||
|
TEST(BLI_tempfile, BLI_temp_directory_path_get)
|
||||||
|
{
|
||||||
|
char temp_dir[FILE_MAX];
|
||||||
|
BLI_temp_directory_path_get(temp_dir, sizeof(temp_dir));
|
||||||
|
|
||||||
|
ASSERT_STRNE(temp_dir, "");
|
||||||
|
|
||||||
|
EXPECT_EQ(temp_dir[strlen(temp_dir) - 1], SEP);
|
||||||
|
|
||||||
|
EXPECT_TRUE(BLI_exists(temp_dir));
|
||||||
|
EXPECT_TRUE(BLI_is_dir(temp_dir));
|
||||||
|
|
||||||
|
EXPECT_TRUE(BLI_path_is_abs_from_cwd(temp_dir));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace blender::tests
|
|
@ -91,7 +91,7 @@
|
||||||
* \subsection bm_ops Operators
|
* \subsection bm_ops Operators
|
||||||
*
|
*
|
||||||
* Operators are an integral part of BMesh. Unlike regular blender operators,
|
* Operators are an integral part of BMesh. Unlike regular blender operators,
|
||||||
* BMesh operators **bmo's** are designed to be nested (e.g. call other operators).
|
* BMesh operators (abbreviated to `bmo`) are designed to be nested (e.g. call other operators).
|
||||||
*
|
*
|
||||||
* Each operator has a number of input/output "slots"
|
* Each operator has a number of input/output "slots"
|
||||||
* which are used to pass settings & data into/out of the operator
|
* which are used to pass settings & data into/out of the operator
|
||||||
|
|
|
@ -269,7 +269,7 @@ static void convolve(float *dst, MemoryBuffer *in1, MemoryBuffer *in2)
|
||||||
data1 = (fREAL *)MEM_callocN(3 * w2 * h2 * sizeof(fREAL), "convolve_fast FHT data1");
|
data1 = (fREAL *)MEM_callocN(3 * w2 * h2 * sizeof(fREAL), "convolve_fast FHT data1");
|
||||||
data2 = (fREAL *)MEM_callocN(w2 * h2 * sizeof(fREAL), "convolve_fast FHT data2");
|
data2 = (fREAL *)MEM_callocN(w2 * h2 * sizeof(fREAL), "convolve_fast FHT data2");
|
||||||
|
|
||||||
/* Normalize convolutor. */
|
/* Normalize convolution. */
|
||||||
wt[0] = wt[1] = wt[2] = 0.0f;
|
wt[0] = wt[1] = wt[2] = 0.0f;
|
||||||
for (y = 0; y < kernel_height; y++) {
|
for (y = 0; y < kernel_height; y++) {
|
||||||
colp = (fRGB *)&kernel_buffer[y * kernel_width * COM_DATA_TYPE_COLOR_CHANNELS];
|
colp = (fRGB *)&kernel_buffer[y * kernel_width * COM_DATA_TYPE_COLOR_CHANNELS];
|
||||||
|
|
|
@ -63,17 +63,21 @@ set(SRC
|
||||||
COM_utilities.hh
|
COM_utilities.hh
|
||||||
|
|
||||||
algorithms/intern/algorithm_parallel_reduction.cc
|
algorithms/intern/algorithm_parallel_reduction.cc
|
||||||
|
algorithms/intern/smaa.cc
|
||||||
algorithms/intern/symmetric_separable_blur.cc
|
algorithms/intern/symmetric_separable_blur.cc
|
||||||
|
|
||||||
algorithms/COM_algorithm_parallel_reduction.hh
|
algorithms/COM_algorithm_parallel_reduction.hh
|
||||||
|
algorithms/COM_algorithm_smaa.hh
|
||||||
algorithms/COM_algorithm_symmetric_separable_blur.hh
|
algorithms/COM_algorithm_symmetric_separable_blur.hh
|
||||||
|
|
||||||
cached_resources/intern/morphological_distance_feather_weights.cc
|
cached_resources/intern/morphological_distance_feather_weights.cc
|
||||||
|
cached_resources/intern/smaa_precomputed_textures.cc
|
||||||
cached_resources/intern/symmetric_blur_weights.cc
|
cached_resources/intern/symmetric_blur_weights.cc
|
||||||
cached_resources/intern/symmetric_separable_blur_weights.cc
|
cached_resources/intern/symmetric_separable_blur_weights.cc
|
||||||
|
|
||||||
cached_resources/COM_cached_resource.hh
|
cached_resources/COM_cached_resource.hh
|
||||||
cached_resources/COM_morphological_distance_feather_weights.hh
|
cached_resources/COM_morphological_distance_feather_weights.hh
|
||||||
|
cached_resources/COM_smaa_precomputed_textures.hh
|
||||||
cached_resources/COM_symmetric_blur_weights.hh
|
cached_resources/COM_symmetric_blur_weights.hh
|
||||||
cached_resources/COM_symmetric_separable_blur_weights.hh
|
cached_resources/COM_symmetric_separable_blur_weights.hh
|
||||||
)
|
)
|
||||||
|
@ -122,6 +126,9 @@ set(GLSL_SRC
|
||||||
shaders/compositor_read_pass.glsl
|
shaders/compositor_read_pass.glsl
|
||||||
shaders/compositor_realize_on_domain.glsl
|
shaders/compositor_realize_on_domain.glsl
|
||||||
shaders/compositor_screen_lens_distortion.glsl
|
shaders/compositor_screen_lens_distortion.glsl
|
||||||
|
shaders/compositor_smaa_blending_weight_calculation.glsl
|
||||||
|
shaders/compositor_smaa_edge_detection.glsl
|
||||||
|
shaders/compositor_smaa_neighborhood_blending.glsl
|
||||||
shaders/compositor_split_viewer.glsl
|
shaders/compositor_split_viewer.glsl
|
||||||
shaders/compositor_symmetric_blur.glsl
|
shaders/compositor_symmetric_blur.glsl
|
||||||
shaders/compositor_symmetric_blur_variable_size.glsl
|
shaders/compositor_symmetric_blur_variable_size.glsl
|
||||||
|
@ -211,6 +218,7 @@ set(SRC_SHADER_CREATE_INFOS
|
||||||
shaders/infos/compositor_read_pass_info.hh
|
shaders/infos/compositor_read_pass_info.hh
|
||||||
shaders/infos/compositor_realize_on_domain_info.hh
|
shaders/infos/compositor_realize_on_domain_info.hh
|
||||||
shaders/infos/compositor_screen_lens_distortion_info.hh
|
shaders/infos/compositor_screen_lens_distortion_info.hh
|
||||||
|
shaders/infos/compositor_smaa_info.hh
|
||||||
shaders/infos/compositor_split_viewer_info.hh
|
shaders/infos/compositor_split_viewer_info.hh
|
||||||
shaders/infos/compositor_symmetric_blur_info.hh
|
shaders/infos/compositor_symmetric_blur_info.hh
|
||||||
shaders/infos/compositor_symmetric_blur_variable_size_info.hh
|
shaders/infos/compositor_symmetric_blur_variable_size_info.hh
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include "BLI_math_vector_types.hh"
|
#include "BLI_math_vector_types.hh"
|
||||||
|
|
||||||
#include "COM_morphological_distance_feather_weights.hh"
|
#include "COM_morphological_distance_feather_weights.hh"
|
||||||
|
#include "COM_smaa_precomputed_textures.hh"
|
||||||
#include "COM_symmetric_blur_weights.hh"
|
#include "COM_symmetric_blur_weights.hh"
|
||||||
#include "COM_symmetric_separable_blur_weights.hh"
|
#include "COM_symmetric_separable_blur_weights.hh"
|
||||||
|
|
||||||
|
@ -47,6 +48,9 @@ class StaticCacheManager {
|
||||||
Map<MorphologicalDistanceFeatherWeightsKey, std::unique_ptr<MorphologicalDistanceFeatherWeights>>
|
Map<MorphologicalDistanceFeatherWeightsKey, std::unique_ptr<MorphologicalDistanceFeatherWeights>>
|
||||||
morphological_distance_feather_weights_;
|
morphological_distance_feather_weights_;
|
||||||
|
|
||||||
|
/* A unique pointers that stores the cached SMAAPrecomputedTextures, if one is cached. */
|
||||||
|
std::unique_ptr<SMAAPrecomputedTextures> smaa_precomputed_textures_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/* Reset the cache manager by deleting the cached resources that are no longer needed because
|
/* Reset the cache manager by deleting the cached resources that are no longer needed because
|
||||||
* they weren't used in the last evaluation and prepare the remaining cached resources to track
|
* they weren't used in the last evaluation and prepare the remaining cached resources to track
|
||||||
|
@ -72,6 +76,11 @@ class StaticCacheManager {
|
||||||
* cached for the next evaluation. */
|
* cached for the next evaluation. */
|
||||||
MorphologicalDistanceFeatherWeights &get_morphological_distance_feather_weights(int type,
|
MorphologicalDistanceFeatherWeights &get_morphological_distance_feather_weights(int type,
|
||||||
int radius);
|
int radius);
|
||||||
|
|
||||||
|
/* Check if a cached SMAA precomputed texture exists, if it does, return it, otherwise, return
|
||||||
|
* a newly created one and store it in the manager. In both cases, tag the cached resource as
|
||||||
|
* needed to keep it cached for the next evaluation. */
|
||||||
|
SMAAPrecomputedTextures &get_smaa_precomputed_textures();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace blender::realtime_compositor
|
} // namespace blender::realtime_compositor
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "COM_context.hh"
|
||||||
|
#include "COM_result.hh"
|
||||||
|
|
||||||
|
namespace blender::realtime_compositor {
|
||||||
|
|
||||||
|
/* Anti-alias the given input using the SMAA algorithm and write the result into the given output.
|
||||||
|
* See the SMAA_THRESHOLD, SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR, and SMAA_CORNER_ROUNDING defines
|
||||||
|
* in gpu_shader_smaa_lib.glsl for information on the parameters. */
|
||||||
|
void smaa(Context &context,
|
||||||
|
Result &input,
|
||||||
|
Result &output,
|
||||||
|
float threshold,
|
||||||
|
float local_contrast_adaptation_factor,
|
||||||
|
int corner_rounding);
|
||||||
|
|
||||||
|
} // namespace blender::realtime_compositor
|
|
@ -0,0 +1,115 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
#include "IMB_colormanagement.h"
|
||||||
|
|
||||||
|
#include "GPU_shader.h"
|
||||||
|
#include "GPU_texture.h"
|
||||||
|
|
||||||
|
#include "COM_context.hh"
|
||||||
|
#include "COM_utilities.hh"
|
||||||
|
|
||||||
|
#include "COM_algorithm_smaa.hh"
|
||||||
|
|
||||||
|
#include "COM_smaa_precomputed_textures.hh"
|
||||||
|
|
||||||
|
namespace blender::realtime_compositor {
|
||||||
|
|
||||||
|
static Result detect_edges(Context &context,
|
||||||
|
Result &input,
|
||||||
|
float threshold,
|
||||||
|
float local_contrast_adaptation_factor)
|
||||||
|
{
|
||||||
|
GPUShader *shader = context.shader_manager().get("compositor_smaa_edge_detection");
|
||||||
|
GPU_shader_bind(shader);
|
||||||
|
|
||||||
|
float luminance_coefficients[3];
|
||||||
|
IMB_colormanagement_get_luminance_coefficients(luminance_coefficients);
|
||||||
|
|
||||||
|
GPU_shader_uniform_3fv(shader, "luminance_coefficients", luminance_coefficients);
|
||||||
|
GPU_shader_uniform_1f(shader, "smaa_threshold", threshold);
|
||||||
|
GPU_shader_uniform_1f(
|
||||||
|
shader, "smaa_local_contrast_adaptation_factor", local_contrast_adaptation_factor);
|
||||||
|
|
||||||
|
GPU_texture_filter_mode(input.texture(), true);
|
||||||
|
input.bind_as_texture(shader, "input_tx");
|
||||||
|
|
||||||
|
Result edges = Result::Temporary(ResultType::Color, context.texture_pool());
|
||||||
|
edges.allocate_texture(input.domain());
|
||||||
|
edges.bind_as_image(shader, "edges_img");
|
||||||
|
|
||||||
|
compute_dispatch_threads_at_least(shader, input.domain().size);
|
||||||
|
|
||||||
|
GPU_shader_unbind();
|
||||||
|
input.unbind_as_texture();
|
||||||
|
edges.unbind_as_image();
|
||||||
|
|
||||||
|
return edges;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Result calculate_blending_weights(Context &context, Result &edges, int corner_rounding)
|
||||||
|
{
|
||||||
|
GPUShader *shader = context.shader_manager().get("compositor_smaa_blending_weight_calculation");
|
||||||
|
GPU_shader_bind(shader);
|
||||||
|
|
||||||
|
GPU_shader_uniform_1i(shader, "smaa_corner_rounding", corner_rounding);
|
||||||
|
|
||||||
|
GPU_texture_filter_mode(edges.texture(), true);
|
||||||
|
edges.bind_as_texture(shader, "edges_tx");
|
||||||
|
|
||||||
|
const SMAAPrecomputedTextures &smaa_precomputed_textures =
|
||||||
|
context.cache_manager().get_smaa_precomputed_textures();
|
||||||
|
smaa_precomputed_textures.bind_area_texture(shader, "area_tx");
|
||||||
|
smaa_precomputed_textures.bind_search_texture(shader, "search_tx");
|
||||||
|
|
||||||
|
Result weights = Result::Temporary(ResultType::Color, context.texture_pool());
|
||||||
|
weights.allocate_texture(edges.domain());
|
||||||
|
weights.bind_as_image(shader, "weights_img");
|
||||||
|
|
||||||
|
compute_dispatch_threads_at_least(shader, edges.domain().size);
|
||||||
|
|
||||||
|
GPU_shader_unbind();
|
||||||
|
edges.unbind_as_texture();
|
||||||
|
smaa_precomputed_textures.unbind_area_texture();
|
||||||
|
smaa_precomputed_textures.unbind_search_texture();
|
||||||
|
weights.unbind_as_image();
|
||||||
|
|
||||||
|
return weights;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void blend_neighborhood(Context &context, Result &input, Result &weights, Result &output)
|
||||||
|
{
|
||||||
|
GPUShader *shader = context.shader_manager().get("compositor_smaa_neighborhood_blending");
|
||||||
|
GPU_shader_bind(shader);
|
||||||
|
|
||||||
|
GPU_texture_filter_mode(input.texture(), true);
|
||||||
|
input.bind_as_texture(shader, "input_tx");
|
||||||
|
|
||||||
|
GPU_texture_filter_mode(weights.texture(), true);
|
||||||
|
weights.bind_as_texture(shader, "weights_tx");
|
||||||
|
|
||||||
|
output.allocate_texture(input.domain());
|
||||||
|
output.bind_as_image(shader, "output_img");
|
||||||
|
|
||||||
|
compute_dispatch_threads_at_least(shader, input.domain().size);
|
||||||
|
|
||||||
|
GPU_shader_unbind();
|
||||||
|
input.unbind_as_texture();
|
||||||
|
weights.unbind_as_texture();
|
||||||
|
output.unbind_as_image();
|
||||||
|
}
|
||||||
|
|
||||||
|
void smaa(Context &context,
|
||||||
|
Result &input,
|
||||||
|
Result &output,
|
||||||
|
float threshold,
|
||||||
|
float local_contrast_adaptation_factor,
|
||||||
|
int corner_rounding)
|
||||||
|
{
|
||||||
|
Result edges = detect_edges(context, input, threshold, local_contrast_adaptation_factor);
|
||||||
|
Result weights = calculate_blending_weights(context, edges, corner_rounding);
|
||||||
|
edges.release();
|
||||||
|
blend_neighborhood(context, input, weights, output);
|
||||||
|
weights.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace blender::realtime_compositor
|
|
@ -0,0 +1,36 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "GPU_shader.h"
|
||||||
|
#include "GPU_texture.h"
|
||||||
|
|
||||||
|
#include "COM_cached_resource.hh"
|
||||||
|
|
||||||
|
namespace blender::realtime_compositor {
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------------------------------
|
||||||
|
* SMAA Precomputed Textures.
|
||||||
|
*
|
||||||
|
* A cached resource that caches the precomputed textures needed by the SMAA algorithm. The
|
||||||
|
* precomputed textures are constants, so this is a parameterless cached resource. */
|
||||||
|
class SMAAPrecomputedTextures : public CachedResource {
|
||||||
|
private:
|
||||||
|
GPUTexture *search_texture_ = nullptr;
|
||||||
|
GPUTexture *area_texture_ = nullptr;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SMAAPrecomputedTextures();
|
||||||
|
|
||||||
|
~SMAAPrecomputedTextures();
|
||||||
|
|
||||||
|
void bind_search_texture(GPUShader *shader, const char *sampler_name) const;
|
||||||
|
|
||||||
|
void unbind_search_texture() const;
|
||||||
|
|
||||||
|
void bind_area_texture(GPUShader *shader, const char *sampler_name) const;
|
||||||
|
|
||||||
|
void unbind_area_texture() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace blender::realtime_compositor
|
|
@ -0,0 +1,64 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
#include "BLI_smaa_textures.h"
|
||||||
|
|
||||||
|
#include "GPU_shader.h"
|
||||||
|
#include "GPU_texture.h"
|
||||||
|
|
||||||
|
#include "COM_smaa_precomputed_textures.hh"
|
||||||
|
|
||||||
|
namespace blender::realtime_compositor {
|
||||||
|
|
||||||
|
SMAAPrecomputedTextures::SMAAPrecomputedTextures()
|
||||||
|
{
|
||||||
|
search_texture_ = GPU_texture_create_2d("SMAA Search",
|
||||||
|
SEARCHTEX_WIDTH,
|
||||||
|
SEARCHTEX_HEIGHT,
|
||||||
|
1,
|
||||||
|
GPU_R8,
|
||||||
|
GPU_TEXTURE_USAGE_SHADER_READ,
|
||||||
|
nullptr);
|
||||||
|
GPU_texture_update(search_texture_, GPU_DATA_UBYTE, searchTexBytes);
|
||||||
|
GPU_texture_filter_mode(search_texture_, true);
|
||||||
|
|
||||||
|
area_texture_ = GPU_texture_create_2d("SMAA Area",
|
||||||
|
AREATEX_WIDTH,
|
||||||
|
AREATEX_HEIGHT,
|
||||||
|
1,
|
||||||
|
GPU_RG8,
|
||||||
|
GPU_TEXTURE_USAGE_SHADER_READ,
|
||||||
|
nullptr);
|
||||||
|
GPU_texture_update(area_texture_, GPU_DATA_UBYTE, areaTexBytes);
|
||||||
|
GPU_texture_filter_mode(area_texture_, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
SMAAPrecomputedTextures::~SMAAPrecomputedTextures()
|
||||||
|
{
|
||||||
|
GPU_texture_free(search_texture_);
|
||||||
|
GPU_texture_free(area_texture_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMAAPrecomputedTextures::bind_search_texture(GPUShader *shader,
|
||||||
|
const char *sampler_name) const
|
||||||
|
{
|
||||||
|
const int texture_image_unit = GPU_shader_get_sampler_binding(shader, sampler_name);
|
||||||
|
GPU_texture_bind(search_texture_, texture_image_unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMAAPrecomputedTextures::unbind_search_texture() const
|
||||||
|
{
|
||||||
|
GPU_texture_unbind(search_texture_);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMAAPrecomputedTextures::bind_area_texture(GPUShader *shader, const char *sampler_name) const
|
||||||
|
{
|
||||||
|
const int texture_image_unit = GPU_shader_get_sampler_binding(shader, sampler_name);
|
||||||
|
GPU_texture_bind(area_texture_, texture_image_unit);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SMAAPrecomputedTextures::unbind_area_texture() const
|
||||||
|
{
|
||||||
|
GPU_texture_unbind(area_texture_);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace blender::realtime_compositor
|
|
@ -5,6 +5,7 @@
|
||||||
#include "BLI_math_vector_types.hh"
|
#include "BLI_math_vector_types.hh"
|
||||||
|
|
||||||
#include "COM_morphological_distance_feather_weights.hh"
|
#include "COM_morphological_distance_feather_weights.hh"
|
||||||
|
#include "COM_smaa_precomputed_textures.hh"
|
||||||
#include "COM_symmetric_blur_weights.hh"
|
#include "COM_symmetric_blur_weights.hh"
|
||||||
#include "COM_symmetric_separable_blur_weights.hh"
|
#include "COM_symmetric_separable_blur_weights.hh"
|
||||||
|
|
||||||
|
@ -22,6 +23,9 @@ void StaticCacheManager::reset()
|
||||||
symmetric_blur_weights_.remove_if([](auto item) { return !item.value->needed; });
|
symmetric_blur_weights_.remove_if([](auto item) { return !item.value->needed; });
|
||||||
symmetric_separable_blur_weights_.remove_if([](auto item) { return !item.value->needed; });
|
symmetric_separable_blur_weights_.remove_if([](auto item) { return !item.value->needed; });
|
||||||
morphological_distance_feather_weights_.remove_if([](auto item) { return !item.value->needed; });
|
morphological_distance_feather_weights_.remove_if([](auto item) { return !item.value->needed; });
|
||||||
|
if (smaa_precomputed_textures_ && !smaa_precomputed_textures_->needed) {
|
||||||
|
smaa_precomputed_textures_.reset();
|
||||||
|
}
|
||||||
|
|
||||||
/* Second, reset the needed status of the remaining resources to false to ready them to track
|
/* Second, reset the needed status of the remaining resources to false to ready them to track
|
||||||
* their needed status for the next evaluation. */
|
* their needed status for the next evaluation. */
|
||||||
|
@ -34,6 +38,9 @@ void StaticCacheManager::reset()
|
||||||
for (auto &value : morphological_distance_feather_weights_.values()) {
|
for (auto &value : morphological_distance_feather_weights_.values()) {
|
||||||
value->needed = false;
|
value->needed = false;
|
||||||
}
|
}
|
||||||
|
if (smaa_precomputed_textures_) {
|
||||||
|
smaa_precomputed_textures_->needed = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SymmetricBlurWeights &StaticCacheManager::get_symmetric_blur_weights(int type, float2 radius)
|
SymmetricBlurWeights &StaticCacheManager::get_symmetric_blur_weights(int type, float2 radius)
|
||||||
|
@ -71,4 +78,14 @@ MorphologicalDistanceFeatherWeights &StaticCacheManager::
|
||||||
return weights;
|
return weights;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SMAAPrecomputedTextures &StaticCacheManager::get_smaa_precomputed_textures()
|
||||||
|
{
|
||||||
|
if (!smaa_precomputed_textures_) {
|
||||||
|
smaa_precomputed_textures_ = std::make_unique<SMAAPrecomputedTextures>();
|
||||||
|
}
|
||||||
|
|
||||||
|
smaa_precomputed_textures_->needed = true;
|
||||||
|
return *smaa_precomputed_textures_;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace blender::realtime_compositor
|
} // namespace blender::realtime_compositor
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
|
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
/* The dispatch domain covers the output image size, which might be a fraction of the input image
|
/* The dispatch domain covers the output image size, which might be a fraction of the input image
|
||||||
|
@ -7,16 +5,9 @@ void main()
|
||||||
* one. */
|
* one. */
|
||||||
ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
|
ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
|
||||||
|
|
||||||
/* Since the output image might be a fraction of the input image size, and since we want to
|
/* Add 0.5 to evaluate the input sampler at the center of the pixel and divide by the image size
|
||||||
* evaluate the input sampler at the center of the output pixel, we add an offset equal to half
|
* to get the coordinates into the sampler's expected [0, 1] range. */
|
||||||
* the number of input pixels that covers a single output pixel. In case the input and output
|
vec2 normalized_coordinates = (vec2(texel) + vec2(0.5)) / vec2(imageSize(output_img));
|
||||||
* have the same size, this will be 0.5, which is the offset required to evaluate the sampler at
|
|
||||||
* the center of the pixel. */
|
|
||||||
vec2 offset = vec2(texture_size(input_tx) / imageSize(output_img)) / 2.0;
|
|
||||||
|
|
||||||
/* Add the aforementioned offset and divide by the output image size to get the coordinates into
|
|
||||||
* the sampler's expected [0, 1] range. */
|
|
||||||
vec2 normalized_coordinates = (vec2(texel) + offset) / vec2(imageSize(output_img));
|
|
||||||
|
|
||||||
vec4 input_color = texture(input_tx, normalized_coordinates);
|
vec4 input_color = texture(input_tx, normalized_coordinates);
|
||||||
float luminance = dot(input_color.rgb, luminance_coefficients);
|
float luminance = dot(input_color.rgb, luminance_coefficients);
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
#pragma BLENDER_REQUIRE(gpu_shader_smaa_lib.glsl)
|
||||||
|
#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
|
||||||
|
|
||||||
|
/* Add 0.5 to evaluate the input sampler at the center of the pixel and divide by the image size
|
||||||
|
* to get the coordinates into the sampler's expected [0, 1] range. */
|
||||||
|
vec2 coordinates = (vec2(texel) + vec2(0.5)) / vec2(texture_size(edges_tx));
|
||||||
|
|
||||||
|
float4 offset[3];
|
||||||
|
vec2 pixel_coordinates;
|
||||||
|
SMAABlendingWeightCalculationVS(coordinates, pixel_coordinates, offset);
|
||||||
|
|
||||||
|
vec4 weights = SMAABlendingWeightCalculationPS(
|
||||||
|
coordinates, pixel_coordinates, offset, edges_tx, area_tx, search_tx, vec4(0.0));
|
||||||
|
imageStore(weights_img, texel, weights);
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
#pragma BLENDER_REQUIRE(gpu_shader_smaa_lib.glsl)
|
||||||
|
#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
|
||||||
|
|
||||||
|
/* Add 0.5 to evaluate the input sampler at the center of the pixel and divide by the image size
|
||||||
|
* to get the coordinates into the sampler's expected [0, 1] range. */
|
||||||
|
vec2 coordinates = (vec2(texel) + vec2(0.5)) / vec2(texture_size(input_tx));
|
||||||
|
|
||||||
|
float4 offset[3];
|
||||||
|
SMAAEdgeDetectionVS(coordinates, offset);
|
||||||
|
|
||||||
|
vec2 edge = SMAALumaEdgeDetectionPS(coordinates, offset, input_tx);
|
||||||
|
imageStore(edges_img, texel, vec4(edge, vec2(0.0)));
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
#pragma BLENDER_REQUIRE(gpu_shader_smaa_lib.glsl)
|
||||||
|
#pragma BLENDER_REQUIRE(gpu_shader_compositor_texture_utilities.glsl)
|
||||||
|
|
||||||
|
void main()
|
||||||
|
{
|
||||||
|
ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
|
||||||
|
|
||||||
|
/* Add 0.5 to evaluate the input sampler at the center of the pixel and divide by the image size
|
||||||
|
* to get the coordinates into the sampler's expected [0, 1] range. */
|
||||||
|
vec2 coordinates = (vec2(texel) + vec2(0.5)) / vec2(texture_size(input_tx));
|
||||||
|
|
||||||
|
vec4 offset;
|
||||||
|
SMAANeighborhoodBlendingVS(coordinates, offset);
|
||||||
|
|
||||||
|
vec4 result = SMAANeighborhoodBlendingPS(coordinates, offset, input_tx, weights_tx);
|
||||||
|
imageStore(output_img, texel, result);
|
||||||
|
}
|
|
@ -0,0 +1,44 @@
|
||||||
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
|
||||||
|
#include "gpu_shader_create_info.hh"
|
||||||
|
|
||||||
|
GPU_SHADER_CREATE_INFO(compositor_smaa_edge_detection)
|
||||||
|
.local_group_size(16, 16)
|
||||||
|
.define("SMAA_GLSL_3")
|
||||||
|
.define("SMAA_RT_METRICS",
|
||||||
|
"vec4(1.0 / vec2(textureSize(input_tx, 0)), vec2(textureSize(input_tx, 0)))")
|
||||||
|
.define("SMAA_LUMA_WEIGHT", "vec4(luminance_coefficients, 0.0)")
|
||||||
|
.define("SMAA_THRESHOLD", "smaa_threshold")
|
||||||
|
.define("SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR", "smaa_local_contrast_adaptation_factor")
|
||||||
|
.push_constant(Type::VEC3, "luminance_coefficients")
|
||||||
|
.push_constant(Type::FLOAT, "smaa_threshold")
|
||||||
|
.push_constant(Type::FLOAT, "smaa_local_contrast_adaptation_factor")
|
||||||
|
.sampler(0, ImageType::FLOAT_2D, "input_tx")
|
||||||
|
.image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "edges_img")
|
||||||
|
.compute_source("compositor_smaa_edge_detection.glsl")
|
||||||
|
.do_static_compilation(true);
|
||||||
|
|
||||||
|
GPU_SHADER_CREATE_INFO(compositor_smaa_blending_weight_calculation)
|
||||||
|
.local_group_size(16, 16)
|
||||||
|
.define("SMAA_GLSL_3")
|
||||||
|
.define("SMAA_RT_METRICS",
|
||||||
|
"vec4(1.0 / vec2(textureSize(edges_tx, 0)), vec2(textureSize(edges_tx, 0)))")
|
||||||
|
.define("SMAA_CORNER_ROUNDING", "smaa_corner_rounding")
|
||||||
|
.push_constant(Type::INT, "smaa_corner_rounding")
|
||||||
|
.sampler(0, ImageType::FLOAT_2D, "edges_tx")
|
||||||
|
.sampler(1, ImageType::FLOAT_2D, "area_tx")
|
||||||
|
.sampler(2, ImageType::FLOAT_2D, "search_tx")
|
||||||
|
.image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "weights_img")
|
||||||
|
.compute_source("compositor_smaa_blending_weight_calculation.glsl")
|
||||||
|
.do_static_compilation(true);
|
||||||
|
|
||||||
|
GPU_SHADER_CREATE_INFO(compositor_smaa_neighborhood_blending)
|
||||||
|
.local_group_size(16, 16)
|
||||||
|
.define("SMAA_GLSL_3")
|
||||||
|
.define("SMAA_RT_METRICS",
|
||||||
|
"vec4(1.0 / vec2(textureSize(input_tx, 0)), vec2(textureSize(input_tx, 0)))")
|
||||||
|
.sampler(0, ImageType::FLOAT_2D, "input_tx")
|
||||||
|
.sampler(1, ImageType::FLOAT_2D, "weights_tx")
|
||||||
|
.image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
|
||||||
|
.compute_source("compositor_smaa_neighborhood_blending.glsl")
|
||||||
|
.do_static_compilation(true);
|
|
@ -41,7 +41,7 @@ static inline bool is_removable_relation(const Relation *relation)
|
||||||
|
|
||||||
/* If the relation connects two different IDs there is a high risk that the removal of the
|
/* If the relation connects two different IDs there is a high risk that the removal of the
|
||||||
* relation will make it so visibility flushing is not possible at runtime. This happens with
|
* relation will make it so visibility flushing is not possible at runtime. This happens with
|
||||||
* relations like the DoF on camera of custom shape on bines: such relation do not lead to an
|
* relations like the DoF on camera of custom shape on bones: such relation do not lead to an
|
||||||
* actual depsgraph evaluation operation as they are handled on render engine level.
|
* actual depsgraph evaluation operation as they are handled on render engine level.
|
||||||
*
|
*
|
||||||
* The indirectly linked objects could have some of their components invisible as well, so
|
* The indirectly linked objects could have some of their components invisible as well, so
|
||||||
|
|
|
@ -103,7 +103,6 @@ set(SRC
|
||||||
intern/draw_view.c
|
intern/draw_view.c
|
||||||
intern/draw_view_data.cc
|
intern/draw_view_data.cc
|
||||||
intern/draw_volume.cc
|
intern/draw_volume.cc
|
||||||
intern/smaa_textures.c
|
|
||||||
engines/basic/basic_engine.c
|
engines/basic/basic_engine.c
|
||||||
engines/basic/basic_shader.c
|
engines/basic/basic_shader.c
|
||||||
engines/compositor/compositor_engine.cc
|
engines/compositor/compositor_engine.cc
|
||||||
|
@ -260,7 +259,6 @@ set(SRC
|
||||||
intern/draw_view.hh
|
intern/draw_view.hh
|
||||||
intern/draw_view_data.h
|
intern/draw_view_data.h
|
||||||
intern/mesh_extractors/extract_mesh.hh
|
intern/mesh_extractors/extract_mesh.hh
|
||||||
intern/smaa_textures.h
|
|
||||||
engines/basic/basic_engine.h
|
engines/basic/basic_engine.h
|
||||||
engines/basic/basic_private.h
|
engines/basic/basic_private.h
|
||||||
engines/compositor/compositor_engine.h
|
engines/compositor/compositor_engine.h
|
||||||
|
@ -554,7 +552,6 @@ set(GLSL_SRC
|
||||||
intern/shaders/common_math_lib.glsl
|
intern/shaders/common_math_lib.glsl
|
||||||
intern/shaders/common_pointcloud_lib.glsl
|
intern/shaders/common_pointcloud_lib.glsl
|
||||||
intern/shaders/common_shape_lib.glsl
|
intern/shaders/common_shape_lib.glsl
|
||||||
intern/shaders/common_smaa_lib.glsl
|
|
||||||
intern/shaders/common_subdiv_custom_data_interp_comp.glsl
|
intern/shaders/common_subdiv_custom_data_interp_comp.glsl
|
||||||
intern/shaders/common_subdiv_ibo_lines_comp.glsl
|
intern/shaders/common_subdiv_ibo_lines_comp.glsl
|
||||||
intern/shaders/common_subdiv_ibo_tris_comp.glsl
|
intern/shaders/common_subdiv_ibo_tris_comp.glsl
|
||||||
|
|
|
@ -85,7 +85,7 @@ void eevee_shader_material_create_info_amend(GPUMaterial *gpumat,
|
||||||
info.vertex_inputs_.clear();
|
info.vertex_inputs_.clear();
|
||||||
}
|
}
|
||||||
else if (do_fragment_attrib_load && !info.vertex_out_interfaces_.is_empty()) {
|
else if (do_fragment_attrib_load && !info.vertex_out_interfaces_.is_empty()) {
|
||||||
/* Codegen outputs only one interface. */
|
/* Code-generation outputs only one interface. */
|
||||||
const StageInterfaceInfo &iface = *info.vertex_out_interfaces_.first();
|
const StageInterfaceInfo &iface = *info.vertex_out_interfaces_.first();
|
||||||
/* Globals the attrib_load() can write to when it is in the fragment shader. */
|
/* Globals the attrib_load() can write to when it is in the fragment shader. */
|
||||||
attr_load << "struct " << iface.name << " {\n";
|
attr_load << "struct " << iface.name << " {\n";
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
#include "gpencil_engine.h"
|
#include "gpencil_engine.h"
|
||||||
|
|
||||||
#include "smaa_textures.h"
|
#include "BLI_smaa_textures.h"
|
||||||
|
|
||||||
void GPENCIL_antialiasing_init(struct GPENCIL_Data *vedata)
|
void GPENCIL_antialiasing_init(struct GPENCIL_Data *vedata)
|
||||||
{
|
{
|
||||||
|
|
|
@ -21,7 +21,6 @@ extern char datatoc_gpencil_vfx_frag_glsl[];
|
||||||
|
|
||||||
extern char datatoc_common_colormanagement_lib_glsl[];
|
extern char datatoc_common_colormanagement_lib_glsl[];
|
||||||
extern char datatoc_common_fullscreen_vert_glsl[];
|
extern char datatoc_common_fullscreen_vert_glsl[];
|
||||||
extern char datatoc_common_smaa_lib_glsl[];
|
|
||||||
extern char datatoc_common_view_lib_glsl[];
|
extern char datatoc_common_view_lib_glsl[];
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
#pragma BLENDER_REQUIRE(common_smaa_lib.glsl)
|
#pragma BLENDER_REQUIRE(gpu_shader_smaa_lib.glsl)
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
#pragma BLENDER_REQUIRE(common_smaa_lib.glsl)
|
#pragma BLENDER_REQUIRE(gpu_shader_smaa_lib.glsl)
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
|
|
|
@ -61,10 +61,8 @@ void OVERLAY_edit_mesh_cache_init(OVERLAY_Data *vedata)
|
||||||
bool show_face_dots = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_FACE_DOT) != 0 ||
|
bool show_face_dots = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_FACE_DOT) != 0 ||
|
||||||
pd->edit_mesh.do_zbufclip;
|
pd->edit_mesh.do_zbufclip;
|
||||||
|
|
||||||
bool show_retopology = (v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_RETOPOLOGY) != 0;
|
bool show_retopology = RETOPOLOGY_ENABLED(v3d);
|
||||||
float retopology_offset = (show_retopology) ?
|
float retopology_offset = RETOPOLOGY_OFFSET(v3d);
|
||||||
max_ff(v3d->overlay.retopology_offset, FLT_EPSILON) :
|
|
||||||
0.0f;
|
|
||||||
|
|
||||||
pd->edit_mesh.do_faces = true;
|
pd->edit_mesh.do_faces = true;
|
||||||
pd->edit_mesh.do_edges = true;
|
pd->edit_mesh.do_edges = true;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#include "gpu_shader_create_info.hh"
|
#include "gpu_shader_create_info.hh"
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/** \name Outline Prepass
|
/** \name Outline Pre-pass
|
||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
GPU_SHADER_INTERFACE_INFO(overlay_outline_prepass_iface, "interp").flat(Type::UINT, "ob_id");
|
GPU_SHADER_INTERFACE_INFO(overlay_outline_prepass_iface, "interp").flat(Type::UINT, "ob_id");
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
#pragma BLENDER_REQUIRE(common_smaa_lib.glsl)
|
#pragma BLENDER_REQUIRE(gpu_shader_smaa_lib.glsl)
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
|
|
||||||
#pragma BLENDER_REQUIRE(common_smaa_lib.glsl)
|
#pragma BLENDER_REQUIRE(gpu_shader_smaa_lib.glsl)
|
||||||
|
|
||||||
void main()
|
void main()
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
|
|
||||||
#include "BLI_jitter_2d.h"
|
#include "BLI_jitter_2d.h"
|
||||||
|
|
||||||
#include "smaa_textures.h"
|
#include "BLI_smaa_textures.h"
|
||||||
|
|
||||||
#include "workbench_private.h"
|
#include "workbench_private.h"
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
#include "workbench_private.hh"
|
#include "workbench_private.hh"
|
||||||
|
|
||||||
#include "BLI_jitter_2d.h"
|
#include "BLI_jitter_2d.h"
|
||||||
#include "smaa_textures.h"
|
#include "BLI_smaa_textures.h"
|
||||||
|
|
||||||
namespace blender::workbench {
|
namespace blender::workbench {
|
||||||
|
|
||||||
|
|
|
@ -188,7 +188,7 @@ bool DRW_object_is_renderable(const Object *ob)
|
||||||
if (ob->type == OB_MESH) {
|
if (ob->type == OB_MESH) {
|
||||||
if ((ob == DST.draw_ctx.object_edit) || DRW_object_is_in_edit_mode(ob)) {
|
if ((ob == DST.draw_ctx.object_edit) || DRW_object_is_in_edit_mode(ob)) {
|
||||||
View3D *v3d = DST.draw_ctx.v3d;
|
View3D *v3d = DST.draw_ctx.v3d;
|
||||||
if (v3d && v3d->overlay.edit_flag & V3D_OVERLAY_EDIT_RETOPOLOGY) {
|
if (v3d && RETOPOLOGY_ENABLED(v3d)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -281,6 +281,12 @@ static bool find_fcurve_segment(FCurve *fcu,
|
||||||
ListBase find_fcurve_segments(FCurve *fcu)
|
ListBase find_fcurve_segments(FCurve *fcu)
|
||||||
{
|
{
|
||||||
ListBase segments = {NULL, NULL};
|
ListBase segments = {NULL, NULL};
|
||||||
|
|
||||||
|
/* Ignore baked curves. */
|
||||||
|
if (!fcu->bezt) {
|
||||||
|
return segments;
|
||||||
|
}
|
||||||
|
|
||||||
int segment_start_idx = 0;
|
int segment_start_idx = 0;
|
||||||
int segment_len = 0;
|
int segment_len = 0;
|
||||||
int current_index = 0;
|
int current_index = 0;
|
||||||
|
|
|
@ -1097,7 +1097,7 @@ static void extrude_points_from_selected_vertices(const ViewContext *vc,
|
||||||
if (sel_exists) {
|
if (sel_exists) {
|
||||||
float disp_3d[3];
|
float disp_3d[3];
|
||||||
sub_v3_v3v3(disp_3d, location, center);
|
sub_v3_v3v3(disp_3d, location, center);
|
||||||
/* Reimplemenented due to unexpected behavior for extrusion of 2-point spline. */
|
/* Reimplemented due to unexpected behavior for extrusion of 2-point spline. */
|
||||||
extrude_vertices_from_selected_endpoints(editnurb, nurbs, cu, disp_3d);
|
extrude_vertices_from_selected_endpoints(editnurb, nurbs, cu, disp_3d);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -695,6 +695,7 @@ static void snap_curves_to_surface_exec_object(Object &curves_ob,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
curves.tag_positions_changed();
|
||||||
DEG_id_tag_update(&curves_id.id, ID_RECALC_GEOMETRY);
|
DEG_id_tag_update(&curves_id.id, ID_RECALC_GEOMETRY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1328,6 +1328,14 @@ void ED_view3d_shade_update(struct Main *bmain, struct View3D *v3d, struct ScrAr
|
||||||
#define XRAY_ENABLED(v3d) SHADING_XRAY_ENABLED((v3d)->shading)
|
#define XRAY_ENABLED(v3d) SHADING_XRAY_ENABLED((v3d)->shading)
|
||||||
#define XRAY_ACTIVE(v3d) SHADING_XRAY_ACTIVE((v3d)->shading)
|
#define XRAY_ACTIVE(v3d) SHADING_XRAY_ACTIVE((v3d)->shading)
|
||||||
|
|
||||||
|
#define OVERLAY_RETOPOLOGY_ENABLED(overlay) \
|
||||||
|
(((overlay).edit_flag & V3D_OVERLAY_EDIT_RETOPOLOGY) != 0)
|
||||||
|
#define OVERLAY_RETOPOLOGY_OFFSET(overlay) \
|
||||||
|
(OVERLAY_RETOPOLOGY_ENABLED(overlay) ? max_ff((overlay).retopology_offset, FLT_EPSILON) : 0.0f)
|
||||||
|
|
||||||
|
#define RETOPOLOGY_ENABLED(v3d) (OVERLAY_RETOPOLOGY_ENABLED((v3d)->overlay))
|
||||||
|
#define RETOPOLOGY_OFFSET(v3d) (OVERLAY_RETOPOLOGY_OFFSET((v3d)->overlay))
|
||||||
|
|
||||||
/* view3d_draw_legacy.c */
|
/* view3d_draw_legacy.c */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -512,6 +512,7 @@ bool paintface_mouse_select(bContext *C,
|
||||||
ED_region_tag_redraw(CTX_wm_region(C)); /* XXX: should redraw all 3D views. */
|
ED_region_tag_redraw(CTX_wm_region(C)); /* XXX: should redraw all 3D views. */
|
||||||
changed = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
|
select_poly.finish();
|
||||||
return changed || found;
|
return changed || found;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,11 +34,13 @@
|
||||||
#include "ED_mesh.h"
|
#include "ED_mesh.h"
|
||||||
|
|
||||||
#include "paint_intern.h" /* own include */
|
#include "paint_intern.h" /* own include */
|
||||||
|
#include "sculpt_intern.hh"
|
||||||
|
|
||||||
using blender::Array;
|
using blender::Array;
|
||||||
using blender::ColorGeometry4f;
|
using blender::ColorGeometry4f;
|
||||||
using blender::GMutableSpan;
|
using blender::GMutableSpan;
|
||||||
using blender::IndexMask;
|
using blender::IndexMask;
|
||||||
|
using blender::IndexRange;
|
||||||
using blender::Vector;
|
using blender::Vector;
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
@ -245,20 +247,20 @@ void PAINT_OT_vertex_color_smooth(wmOperatorType *ot)
|
||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
template<typename TransformFn>
|
template<typename TransformFn>
|
||||||
static bool transform_active_color(Mesh &mesh, const TransformFn &transform_fn)
|
static void transform_active_color_data(Mesh &mesh, const TransformFn &transform_fn)
|
||||||
{
|
{
|
||||||
using namespace blender;
|
using namespace blender;
|
||||||
const StringRef name = mesh.active_color_attribute;
|
const StringRef name = mesh.active_color_attribute;
|
||||||
bke::MutableAttributeAccessor attributes = mesh.attributes_for_write();
|
bke::MutableAttributeAccessor attributes = mesh.attributes_for_write();
|
||||||
if (!attributes.contains(name)) {
|
if (!attributes.contains(name)) {
|
||||||
BLI_assert_unreachable();
|
BLI_assert_unreachable();
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bke::GAttributeWriter color_attribute = attributes.lookup_for_write(name);
|
bke::GAttributeWriter color_attribute = attributes.lookup_for_write(name);
|
||||||
if (!color_attribute) {
|
if (!color_attribute) {
|
||||||
BLI_assert_unreachable();
|
BLI_assert_unreachable();
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector<int64_t> indices;
|
Vector<int64_t> indices;
|
||||||
|
@ -286,8 +288,34 @@ static bool transform_active_color(Mesh &mesh, const TransformFn &transform_fn)
|
||||||
color_attribute.finish();
|
color_attribute.finish();
|
||||||
|
|
||||||
DEG_id_tag_update(&mesh.id, 0);
|
DEG_id_tag_update(&mesh.id, 0);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
template<typename TransformFn>
|
||||||
|
static void transform_active_color(bContext *C, wmOperator *op, const TransformFn &transform_fn)
|
||||||
|
{
|
||||||
|
Object *obact = CTX_data_active_object(C);
|
||||||
|
|
||||||
|
/* Ensure valid sculpt state. */
|
||||||
|
BKE_sculpt_update_object_for_edit(
|
||||||
|
CTX_data_ensure_evaluated_depsgraph(C), obact, true, false, true);
|
||||||
|
|
||||||
|
SCULPT_undo_push_begin(obact, op);
|
||||||
|
PBVHNode **nodes;
|
||||||
|
int nodes_num;
|
||||||
|
|
||||||
|
BKE_pbvh_search_gather(obact->sculpt->pbvh, nullptr, nullptr, &nodes, &nodes_num);
|
||||||
|
for (int i : IndexRange(nodes_num)) {
|
||||||
|
SCULPT_undo_push_node(obact, nodes[i], SCULPT_UNDO_COLOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
transform_active_color_data(*BKE_mesh_from_object(obact), transform_fn);
|
||||||
|
|
||||||
|
for (int i : IndexRange(nodes_num)) {
|
||||||
|
BKE_pbvh_node_mark_update_color(nodes[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
SCULPT_undo_push_end(obact);
|
||||||
|
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obact);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vertex_color_brightness_contrast_exec(bContext *C, wmOperator *op)
|
static int vertex_color_brightness_contrast_exec(bContext *C, wmOperator *op)
|
||||||
|
@ -323,14 +351,12 @@ static int vertex_color_brightness_contrast_exec(bContext *C, wmOperator *op)
|
||||||
return OPERATOR_CANCELLED;
|
return OPERATOR_CANCELLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
transform_active_color(*me, [&](ColorGeometry4f &color) {
|
transform_active_color(C, op, [&](ColorGeometry4f &color) {
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
color[i] = gain * color[i] + offset;
|
color[i] = gain * color[i] + offset;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obact);
|
|
||||||
|
|
||||||
return OPERATOR_FINISHED;
|
return OPERATOR_FINISHED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -371,7 +397,7 @@ static int vertex_color_hsv_exec(bContext *C, wmOperator *op)
|
||||||
return OPERATOR_CANCELLED;
|
return OPERATOR_CANCELLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
transform_active_color(*me, [&](ColorGeometry4f &color) {
|
transform_active_color(C, op, [&](ColorGeometry4f &color) {
|
||||||
float hsv[3];
|
float hsv[3];
|
||||||
rgb_to_hsv_v(color, hsv);
|
rgb_to_hsv_v(color, hsv);
|
||||||
|
|
||||||
|
@ -388,8 +414,6 @@ static int vertex_color_hsv_exec(bContext *C, wmOperator *op)
|
||||||
hsv_to_rgb_v(hsv, color);
|
hsv_to_rgb_v(hsv, color);
|
||||||
});
|
});
|
||||||
|
|
||||||
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obact);
|
|
||||||
|
|
||||||
return OPERATOR_FINISHED;
|
return OPERATOR_FINISHED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -413,7 +437,7 @@ void PAINT_OT_vertex_color_hsv(wmOperatorType *ot)
|
||||||
RNA_def_float(ot->srna, "v", 1.0f, 0.0f, 2.0f, "Value", "", 0.0f, 2.0f);
|
RNA_def_float(ot->srna, "v", 1.0f, 0.0f, 2.0f, "Value", "", 0.0f, 2.0f);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int vertex_color_invert_exec(bContext *C, wmOperator * /*op*/)
|
static int vertex_color_invert_exec(bContext *C, wmOperator *op)
|
||||||
{
|
{
|
||||||
Object *obact = CTX_data_active_object(C);
|
Object *obact = CTX_data_active_object(C);
|
||||||
|
|
||||||
|
@ -423,14 +447,12 @@ static int vertex_color_invert_exec(bContext *C, wmOperator * /*op*/)
|
||||||
return OPERATOR_CANCELLED;
|
return OPERATOR_CANCELLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
transform_active_color(*me, [&](ColorGeometry4f &color) {
|
transform_active_color(C, op, [&](ColorGeometry4f &color) {
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
color[i] = 1.0f - color[i];
|
color[i] = 1.0f - color[i];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, obact);
|
|
||||||
|
|
||||||
return OPERATOR_FINISHED;
|
return OPERATOR_FINISHED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -462,7 +484,7 @@ static int vertex_color_levels_exec(bContext *C, wmOperator *op)
|
||||||
return OPERATOR_CANCELLED;
|
return OPERATOR_CANCELLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
transform_active_color(*me, [&](ColorGeometry4f &color) {
|
transform_active_color(C, op, [&](ColorGeometry4f &color) {
|
||||||
for (int i = 0; i < 3; i++) {
|
for (int i = 0; i < 3; i++) {
|
||||||
color[i] = gain * (color[i] + offset);
|
color[i] = gain * (color[i] + offset);
|
||||||
}
|
}
|
||||||
|
|
|
@ -480,7 +480,7 @@ void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *region
|
||||||
/** \name Timeline - Caches
|
/** \name Timeline - Caches
|
||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
static bool timeline_cache_is_hidden_by_setting(SpaceAction *saction, PTCacheID *pid)
|
static bool timeline_cache_is_hidden_by_setting(const SpaceAction *saction, const PTCacheID *pid)
|
||||||
{
|
{
|
||||||
switch (pid->type) {
|
switch (pid->type) {
|
||||||
case PTCACHE_TYPE_SOFTBODY:
|
case PTCACHE_TYPE_SOFTBODY:
|
||||||
|
@ -674,14 +674,14 @@ static void timeline_cache_draw_single(PTCacheID *pid, float y_offset, float hei
|
||||||
GPU_matrix_pop();
|
GPU_matrix_pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
void timeline_draw_cache(SpaceAction *saction, Object *ob, Scene *scene)
|
void timeline_draw_cache(const SpaceAction *saction, const Object *ob, const Scene *scene)
|
||||||
{
|
{
|
||||||
if ((saction->cache_display & TIME_CACHE_DISPLAY) == 0 || ob == nullptr) {
|
if ((saction->cache_display & TIME_CACHE_DISPLAY) == 0 || ob == nullptr) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ListBase pidlist;
|
ListBase pidlist;
|
||||||
BKE_ptcache_ids_from_object(&pidlist, ob, scene, 0);
|
BKE_ptcache_ids_from_object(&pidlist, const_cast<Object *>(ob), const_cast<Scene *>(scene), 0);
|
||||||
|
|
||||||
uint pos_id = GPU_vertformat_attr_add(
|
uint pos_id = GPU_vertformat_attr_add(
|
||||||
immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
|
||||||
|
|
|
@ -35,7 +35,7 @@ void draw_channel_names(bContext *C, bAnimContext *ac, ARegion *region);
|
||||||
*/
|
*/
|
||||||
void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *region);
|
void draw_channel_strips(bAnimContext *ac, SpaceAction *saction, ARegion *region);
|
||||||
|
|
||||||
void timeline_draw_cache(SpaceAction *saction, Object *ob, Scene *scene);
|
void timeline_draw_cache(const SpaceAction *saction, const Object *ob, const Scene *scene);
|
||||||
|
|
||||||
/* ***************************************** */
|
/* ***************************************** */
|
||||||
/* action_select.c */
|
/* action_select.c */
|
||||||
|
|
|
@ -44,6 +44,8 @@
|
||||||
|
|
||||||
#include "BLO_read_write.h"
|
#include "BLO_read_write.h"
|
||||||
|
|
||||||
|
#include "GPU_matrix.h"
|
||||||
|
|
||||||
#include "action_intern.hh" /* own include */
|
#include "action_intern.hh" /* own include */
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
|
@ -212,11 +214,6 @@ static void action_main_region_draw(const bContext *C, ARegion *region)
|
||||||
ED_markers_draw(C, marker_flag);
|
ED_markers_draw(C, marker_flag);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* caches */
|
|
||||||
if (saction->mode == SACTCONT_TIMELINE) {
|
|
||||||
timeline_draw_cache(saction, obact, scene);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* preview range */
|
/* preview range */
|
||||||
UI_view2d_view_ortho(v2d);
|
UI_view2d_view_ortho(v2d);
|
||||||
ANIM_draw_previewrange(C, v2d, 0);
|
ANIM_draw_previewrange(C, v2d, 0);
|
||||||
|
@ -240,8 +237,17 @@ static void action_main_region_draw_overlay(const bContext *C, ARegion *region)
|
||||||
/* draw entirely, view changes should be handled here */
|
/* draw entirely, view changes should be handled here */
|
||||||
const SpaceAction *saction = CTX_wm_space_action(C);
|
const SpaceAction *saction = CTX_wm_space_action(C);
|
||||||
const Scene *scene = CTX_data_scene(C);
|
const Scene *scene = CTX_data_scene(C);
|
||||||
|
const Object *obact = CTX_data_active_object(C);
|
||||||
View2D *v2d = ®ion->v2d;
|
View2D *v2d = ®ion->v2d;
|
||||||
|
|
||||||
|
/* caches */
|
||||||
|
if (saction->mode == SACTCONT_TIMELINE) {
|
||||||
|
GPU_matrix_push_projection();
|
||||||
|
UI_view2d_view_orthoSpecial(region, v2d, 1);
|
||||||
|
timeline_draw_cache(saction, obact, scene);
|
||||||
|
GPU_matrix_pop_projection();
|
||||||
|
}
|
||||||
|
|
||||||
/* scrubbing region */
|
/* scrubbing region */
|
||||||
ED_time_scrub_draw_current_frame(region, scene, saction->flag & SACTION_DRAWTIME);
|
ED_time_scrub_draw_current_frame(region, scene, saction->flag & SACTION_DRAWTIME);
|
||||||
|
|
||||||
|
|
|
@ -703,7 +703,7 @@ static void draw_fcurve_curve_samples(bAnimContext *ac,
|
||||||
const uint shdr_pos,
|
const uint shdr_pos,
|
||||||
const bool draw_extrapolation)
|
const bool draw_extrapolation)
|
||||||
{
|
{
|
||||||
if (!draw_extrapolation) {
|
if (!draw_extrapolation && fcu->totvert == 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -816,7 +816,7 @@ static bool fcurve_can_use_simple_bezt_drawing(FCurve *fcu)
|
||||||
static void draw_fcurve_curve_bezts(
|
static void draw_fcurve_curve_bezts(
|
||||||
bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d, uint pos, const bool draw_extrapolation)
|
bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d, uint pos, const bool draw_extrapolation)
|
||||||
{
|
{
|
||||||
if (!draw_extrapolation) {
|
if (!draw_extrapolation && fcu->totvert == 1) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1136,12 +1136,11 @@ static void gaussian_smooth_free_operator_data(void *operator_data)
|
||||||
static void gaussian_smooth_draw_status_header(bContext *C, tGraphSliderOp *gso)
|
static void gaussian_smooth_draw_status_header(bContext *C, tGraphSliderOp *gso)
|
||||||
{
|
{
|
||||||
char status_str[UI_MAX_DRAW_STR];
|
char status_str[UI_MAX_DRAW_STR];
|
||||||
char mode_str[32];
|
|
||||||
char slider_string[UI_MAX_DRAW_STR];
|
char slider_string[UI_MAX_DRAW_STR];
|
||||||
|
|
||||||
ED_slider_status_string_get(gso->slider, slider_string, UI_MAX_DRAW_STR);
|
ED_slider_status_string_get(gso->slider, slider_string, UI_MAX_DRAW_STR);
|
||||||
|
|
||||||
strcpy(mode_str, TIP_("Gauss Smooth"));
|
const char *mode_str = TIP_("Gaussian Smooth");
|
||||||
|
|
||||||
if (hasNumInput(&gso->num)) {
|
if (hasNumInput(&gso->num)) {
|
||||||
char str_ofs[NUM_STR_REP_LEN];
|
char str_ofs[NUM_STR_REP_LEN];
|
||||||
|
@ -1274,7 +1273,7 @@ void GRAPH_OT_gaussian_smooth(wmOperatorType *ot)
|
||||||
/* Identifiers. */
|
/* Identifiers. */
|
||||||
ot->name = "Gaussian Smooth";
|
ot->name = "Gaussian Smooth";
|
||||||
ot->idname = "GRAPH_OT_gaussian_smooth";
|
ot->idname = "GRAPH_OT_gaussian_smooth";
|
||||||
ot->description = "Smooth the curve using a Gauss filter";
|
ot->description = "Smooth the curve using a Gaussian filter";
|
||||||
|
|
||||||
/* API callbacks. */
|
/* API callbacks. */
|
||||||
ot->invoke = gaussian_smooth_invoke;
|
ot->invoke = gaussian_smooth_invoke;
|
||||||
|
@ -1301,7 +1300,7 @@ void GRAPH_OT_gaussian_smooth(wmOperatorType *ot)
|
||||||
0.001f,
|
0.001f,
|
||||||
FLT_MAX,
|
FLT_MAX,
|
||||||
"Sigma",
|
"Sigma",
|
||||||
"The shape of the gauss distribution, lower values make it sharper",
|
"The shape of the gaussian distribution, lower values make it sharper",
|
||||||
0.001f,
|
0.001f,
|
||||||
100.0f);
|
100.0f);
|
||||||
|
|
||||||
|
|
|
@ -805,7 +805,7 @@ static bool image_undosys_step_encode(struct bContext *C, struct Main * /*bmain*
|
||||||
us_reference = reinterpret_cast<ImageUndoStep *>(us_reference->step.prev);
|
us_reference = reinterpret_cast<ImageUndoStep *>(us_reference->step.prev);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize undo tiles from ptiles (if they exist). */
|
/* Initialize undo tiles from paint-tiles (if they exist). */
|
||||||
for (PaintTile *ptile : us->paint_tile_map->map.values()) {
|
for (PaintTile *ptile : us->paint_tile_map->map.values()) {
|
||||||
if (ptile->valid) {
|
if (ptile->valid) {
|
||||||
UndoImageHandle *uh = uhandle_ensure(&us->handles, ptile->image, &ptile->iuser);
|
UndoImageHandle *uh = uhandle_ensure(&us->handles, ptile->image, &ptile->iuser);
|
||||||
|
|
|
@ -263,8 +263,11 @@ static int node_clipboard_paste_exec(bContext *C, wmOperator *op)
|
||||||
const float2 offset = (mouse_location - center) / UI_SCALE_FAC;
|
const float2 offset = (mouse_location - center) / UI_SCALE_FAC;
|
||||||
|
|
||||||
for (bNode *new_node : node_map.values()) {
|
for (bNode *new_node : node_map.values()) {
|
||||||
new_node->locx += offset.x;
|
/* Skip the offset for parented nodes since the location is in parent space. */
|
||||||
new_node->locy += offset.y;
|
if (new_node->parent == nullptr) {
|
||||||
|
new_node->locx += offset.x;
|
||||||
|
new_node->locy += offset.y;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2722,7 +2722,8 @@ static void frame_node_prepare_for_draw(bNode &node, Span<bNode *> nodes)
|
||||||
const float has_label = node.label[0] != '\0';
|
const float has_label = node.label[0] != '\0';
|
||||||
|
|
||||||
const float label_height = frame_node_label_height(*data);
|
const float label_height = frame_node_label_height(*data);
|
||||||
/* Add an additional 25 % to account for the descenders. This works well in most cases. */
|
/* Add an additional 25% to account for the glyphs descender.
|
||||||
|
* This works well in most cases. */
|
||||||
const float margin_top = 0.5f * margin + (has_label ? 1.25f * label_height : 0.5f * margin);
|
const float margin_top = 0.5f * margin + (has_label ? 1.25f * label_height : 0.5f * margin);
|
||||||
|
|
||||||
/* Initialize rect from current frame size. */
|
/* Initialize rect from current frame size. */
|
||||||
|
|
|
@ -419,16 +419,6 @@ static int transform_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
||||||
exit_code = transformEvent(t, event);
|
exit_code = transformEvent(t, event);
|
||||||
t->context = NULL;
|
t->context = NULL;
|
||||||
|
|
||||||
/* XXX, workaround: active needs to be calculated before transforming,
|
|
||||||
* since we're not reading from 'td->center' in this case. see: #40241 */
|
|
||||||
if (t->tsnap.source_operation == SCE_SNAP_SOURCE_ACTIVE) {
|
|
||||||
/* In camera view, tsnap callback is not set
|
|
||||||
* (see #initSnappingMode() in transform_snap.c, and #40348). */
|
|
||||||
if (t->tsnap.snap_source_fn && ((t->tsnap.status & SNAP_SOURCE_FOUND) == 0)) {
|
|
||||||
t->tsnap.snap_source_fn(t);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
transformApply(C, t);
|
transformApply(C, t);
|
||||||
|
|
||||||
exit_code |= transformEnd(C, t);
|
exit_code |= transformEnd(C, t);
|
||||||
|
|
|
@ -947,6 +947,11 @@ static void setSnappingCallback(TransInfo *t)
|
||||||
break;
|
break;
|
||||||
case SCE_SNAP_SOURCE_ACTIVE:
|
case SCE_SNAP_SOURCE_ACTIVE:
|
||||||
t->tsnap.snap_source_fn = snap_source_active_fn;
|
t->tsnap.snap_source_fn = snap_source_active_fn;
|
||||||
|
|
||||||
|
/* XXX, workaround: active needs to be calculated before transforming, otherwise
|
||||||
|
* `t->tsnap.snap_source` will be calculated with the transformed data since we're not
|
||||||
|
* reading from 'td->center' in this case. (See: #40241 and #40348). */
|
||||||
|
snap_source_active_fn(t);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1230,13 +1235,18 @@ static void snap_source_active_fn(TransInfo *t)
|
||||||
{
|
{
|
||||||
/* Only need to calculate once */
|
/* Only need to calculate once */
|
||||||
if ((t->tsnap.status & SNAP_SOURCE_FOUND) == 0) {
|
if ((t->tsnap.status & SNAP_SOURCE_FOUND) == 0) {
|
||||||
if (calculateCenterActive(t, true, t->tsnap.snap_source)) {
|
if (t->around == V3D_AROUND_ACTIVE) {
|
||||||
|
/* Just copy the already calculated active center. */
|
||||||
|
copy_v3_v3(t->tsnap.snap_source, t->center_global);
|
||||||
|
TargetSnapOffset(t, nullptr);
|
||||||
|
t->tsnap.status |= SNAP_SOURCE_FOUND;
|
||||||
|
}
|
||||||
|
else if (calculateCenterActive(t, true, t->tsnap.snap_source)) {
|
||||||
TargetSnapOffset(t, nullptr);
|
TargetSnapOffset(t, nullptr);
|
||||||
|
|
||||||
t->tsnap.status |= SNAP_SOURCE_FOUND;
|
t->tsnap.status |= SNAP_SOURCE_FOUND;
|
||||||
}
|
}
|
||||||
/* No active, default to median */
|
|
||||||
else {
|
else {
|
||||||
|
/* No active, default to median, */
|
||||||
t->tsnap.source_operation = SCE_SNAP_SOURCE_MEDIAN;
|
t->tsnap.source_operation = SCE_SNAP_SOURCE_MEDIAN;
|
||||||
t->tsnap.snap_source_fn = snap_source_median_fn;
|
t->tsnap.snap_source_fn = snap_source_median_fn;
|
||||||
snap_source_median_fn(t);
|
snap_source_median_fn(t);
|
||||||
|
|
|
@ -1166,8 +1166,8 @@ static bool uv_snap_uvs_to_adjacent_unselected(Scene *scene, Object *obedit)
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
|
const BMUVOffsets offsets = BM_uv_map_get_offsets(em->bm);
|
||||||
|
|
||||||
/* index every vert that has a selected UV using it, but only once so as to
|
/* Index every vert that has a selected UV using it, but only once so as to
|
||||||
* get unique indices and to count how much to malloc */
|
* get unique indices and to count how much to `malloc`. */
|
||||||
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
|
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
|
||||||
if (uvedit_face_visible_test(scene, f)) {
|
if (uvedit_face_visible_test(scene, f)) {
|
||||||
BM_elem_flag_enable(f, BM_ELEM_TAG);
|
BM_elem_flag_enable(f, BM_ELEM_TAG);
|
||||||
|
|
|
@ -280,7 +280,7 @@ class Occupancy {
|
||||||
mutable float witness_distance_; /* Signed distance to nearest placed island. */
|
mutable float witness_distance_; /* Signed distance to nearest placed island. */
|
||||||
mutable uint triangle_hint_; /* Hint to a previously suspected overlapping triangle. */
|
mutable uint triangle_hint_; /* Hint to a previously suspected overlapping triangle. */
|
||||||
|
|
||||||
const float terminal = 1048576.0f; /* A "very" large number, much bigger than 4 * bitmap_radix */
|
const float terminal = 1048576.0f; /* 4 * bitmap_radix < terminal < INT_MAX / 4. */
|
||||||
};
|
};
|
||||||
|
|
||||||
Occupancy::Occupancy(const float initial_scale)
|
Occupancy::Occupancy(const float initial_scale)
|
||||||
|
@ -352,8 +352,9 @@ float Occupancy::trace_triangle(const float2 &uv0,
|
||||||
if (iy0 <= witness_.y && witness_.y < iy1) {
|
if (iy0 <= witness_.y && witness_.y < iy1) {
|
||||||
const float distance = signed_distance_fat_triangle(witness_, uv0s, uv1s, uv2s);
|
const float distance = signed_distance_fat_triangle(witness_, uv0s, uv1s, uv2s);
|
||||||
const float extent = epsilon - distance - witness_distance_;
|
const float extent = epsilon - distance - witness_distance_;
|
||||||
if (extent > 0.0f) {
|
const float pixel_round_off = -0.1f; /* Go faster on nearly-axis aligned edges. */
|
||||||
return extent; /* Witness observes occupied. */
|
if (extent > pixel_round_off) {
|
||||||
|
return std::max(0.0f, extent); /* Witness observes occupied. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -392,7 +393,7 @@ float Occupancy::trace_island(PackIsland *island,
|
||||||
|
|
||||||
if (!write) {
|
if (!write) {
|
||||||
if (uv.x <= 0.0f || uv.y <= 0.0f) {
|
if (uv.x <= 0.0f || uv.y <= 0.0f) {
|
||||||
return std::max(-uv.x, -uv.y); /* Occupied. */
|
return terminal; /* Occupied. */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const float2 origin(island->bounds_rect.xmin, island->bounds_rect.ymin);
|
const float2 origin(island->bounds_rect.xmin, island->bounds_rect.ymin);
|
||||||
|
@ -421,9 +422,21 @@ static float2 find_best_fit_for_island(
|
||||||
const float size_x_scaled = BLI_rctf_size_x(&island->bounds_rect) * scale;
|
const float size_x_scaled = BLI_rctf_size_x(&island->bounds_rect) * scale;
|
||||||
const float size_y_scaled = BLI_rctf_size_y(&island->bounds_rect) * scale;
|
const float size_y_scaled = BLI_rctf_size_y(&island->bounds_rect) * scale;
|
||||||
|
|
||||||
/* Scan using an "Alpaca"-style search, first vertically. */
|
/* Scan using an "Alpaca"-style search, first horizontally using "less-than". */
|
||||||
|
|
||||||
int t = 0;
|
int t = int(ceilf(size_x_scaled * occupancy.bitmap_scale_reciprocal));
|
||||||
|
while (t < scan_line) {
|
||||||
|
const float t_bscaled = t / occupancy.bitmap_scale_reciprocal;
|
||||||
|
const float2 probe(t_bscaled - size_x_scaled, scan_line_bscaled - size_y_scaled);
|
||||||
|
const float extent = occupancy.trace_island(island, scale, margin, probe, false);
|
||||||
|
if (extent < 0.0f) {
|
||||||
|
return probe;
|
||||||
|
}
|
||||||
|
t = t + std::max(1, int(extent));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Then scan vertically using "less-than-or-equal" */
|
||||||
|
t = int(ceilf(size_y_scaled * occupancy.bitmap_scale_reciprocal));
|
||||||
while (t <= scan_line) {
|
while (t <= scan_line) {
|
||||||
const float t_bscaled = t / occupancy.bitmap_scale_reciprocal;
|
const float t_bscaled = t / occupancy.bitmap_scale_reciprocal;
|
||||||
const float2 probe(scan_line_bscaled - size_x_scaled, t_bscaled - size_y_scaled);
|
const float2 probe(scan_line_bscaled - size_x_scaled, t_bscaled - size_y_scaled);
|
||||||
|
@ -434,17 +447,6 @@ static float2 find_best_fit_for_island(
|
||||||
t = t + std::max(1, int(extent));
|
t = t + std::max(1, int(extent));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now scan horizontally. */
|
|
||||||
t = 0;
|
|
||||||
while (t <= scan_line) {
|
|
||||||
const float t_bscaled = t / occupancy.bitmap_scale_reciprocal;
|
|
||||||
const float2 probe(t_bscaled - size_x_scaled, scan_line_bscaled - size_y_scaled);
|
|
||||||
const float extent = occupancy.trace_island(island, scale, margin, probe, false);
|
|
||||||
if (extent < 0.0f) {
|
|
||||||
return probe;
|
|
||||||
}
|
|
||||||
t = t + std::max(1, int(extent));
|
|
||||||
}
|
|
||||||
return float2(-1, -1);
|
return float2(-1, -1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -458,7 +460,7 @@ static float guess_initial_scale(const Span<PackIsland *> islands,
|
||||||
sum += BLI_rctf_size_x(&island->bounds_rect) * scale + 2 * margin;
|
sum += BLI_rctf_size_x(&island->bounds_rect) * scale + 2 * margin;
|
||||||
sum += BLI_rctf_size_y(&island->bounds_rect) * scale + 2 * margin;
|
sum += BLI_rctf_size_y(&island->bounds_rect) * scale + 2 * margin;
|
||||||
}
|
}
|
||||||
return sqrtf(sum) / 3.0f;
|
return sqrtf(sum) / 6.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -437,6 +437,7 @@ set(GLSL_SRC
|
||||||
shaders/common/gpu_shader_math_matrix_lib.glsl
|
shaders/common/gpu_shader_math_matrix_lib.glsl
|
||||||
shaders/common/gpu_shader_math_rotation_lib.glsl
|
shaders/common/gpu_shader_math_rotation_lib.glsl
|
||||||
shaders/common/gpu_shader_math_vector_lib.glsl
|
shaders/common/gpu_shader_math_vector_lib.glsl
|
||||||
|
shaders/common/gpu_shader_smaa_lib.glsl
|
||||||
shaders/common/gpu_shader_test_lib.glsl
|
shaders/common/gpu_shader_test_lib.glsl
|
||||||
shaders/common/gpu_shader_utildefines_lib.glsl
|
shaders/common/gpu_shader_utildefines_lib.glsl
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
typedef struct TestOutputRawData TestOutputRawData;
|
typedef struct TestOutputRawData TestOutputRawData;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* NOTE: float3 has differing stride and alignment rules across different GPU backends. If 12 byte
|
/* NOTE: float3 has differing stride and alignment rules across different GPU back-ends. If 12 byte
|
||||||
* stride and alignment is essential, use `packed_float3` to avoid data read issues. This is
|
* stride and alignment is essential, use `packed_float3` to avoid data read issues. This is
|
||||||
* required in the common use-case where a float3 and an int/float are paired together for optimal
|
* required in the common use-case where a float3 and an int/float are paired together for optimal
|
||||||
* data transfer. */
|
* data transfer. */
|
||||||
|
|
|
@ -34,9 +34,9 @@ namespace gpu {
|
||||||
class GLBackend : public GPUBackend {
|
class GLBackend : public GPUBackend {
|
||||||
private:
|
private:
|
||||||
GLSharedOrphanLists shared_orphan_list_;
|
GLSharedOrphanLists shared_orphan_list_;
|
||||||
#ifdef WITH_RENDERDOC
|
#ifdef WITH_RENDERDOC
|
||||||
renderdoc::api::Renderdoc renderdoc_;
|
renderdoc::api::Renderdoc renderdoc_;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
GLBackend()
|
GLBackend()
|
||||||
|
|
|
@ -774,14 +774,19 @@ float2 SMAALumaEdgeDetectionPS(float2 texcoord,
|
||||||
delta.xy = abs(L - float2(Lleft, Ltop));
|
delta.xy = abs(L - float2(Lleft, Ltop));
|
||||||
float2 edges = step(threshold, delta.xy);
|
float2 edges = step(threshold, delta.xy);
|
||||||
|
|
||||||
# ifndef SMAA_NO_DISCARD
|
# ifdef GPU_FRAGMENT_SHADER
|
||||||
# ifdef GPU_FRAGMENT_SHADER
|
# ifndef SMAA_NO_DISCARD
|
||||||
// Then discard if there is no edge:
|
// Then discard if there is no edge:
|
||||||
if (dot(edges, float2(1.0, 1.0)) == 0.0) {
|
if (dot(edges, float2(1.0, 1.0)) == 0.0) {
|
||||||
discard;
|
discard;
|
||||||
return float2(0.0, 0.0);
|
return float2(0.0, 0.0);
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
|
# elif defined(GPU_COMPUTE_SHADER)
|
||||||
|
// Then return early if there is no edge:
|
||||||
|
if (dot(edges, float2(1.0, 1.0)) == 0.0) {
|
||||||
|
return float2(0.0);
|
||||||
|
}
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
// Calculate right and bottom deltas:
|
// Calculate right and bottom deltas:
|
||||||
|
@ -802,9 +807,7 @@ float2 SMAALumaEdgeDetectionPS(float2 texcoord,
|
||||||
float finalDelta = max(maxDelta.x, maxDelta.y);
|
float finalDelta = max(maxDelta.x, maxDelta.y);
|
||||||
|
|
||||||
// Local contrast adaptation:
|
// Local contrast adaptation:
|
||||||
# if !defined(SHADER_API_OPENGL)
|
|
||||||
edges.xy *= step(finalDelta, SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR * delta.xy);
|
edges.xy *= step(finalDelta, SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR * delta.xy);
|
||||||
# endif
|
|
||||||
|
|
||||||
return edges;
|
return edges;
|
||||||
}
|
}
|
||||||
|
@ -882,9 +885,7 @@ float2 SMAAColorEdgeDetectionPS(float2 texcoord,
|
||||||
float finalDelta = max(maxDelta.x, maxDelta.y);
|
float finalDelta = max(maxDelta.x, maxDelta.y);
|
||||||
|
|
||||||
// Local contrast adaptation:
|
// Local contrast adaptation:
|
||||||
# if !defined(SHADER_API_OPENGL)
|
|
||||||
edges.xy *= step(finalDelta, SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR * delta.xy);
|
edges.xy *= step(finalDelta, SMAA_LOCAL_CONTRAST_ADAPTATION_FACTOR * delta.xy);
|
||||||
# endif
|
|
||||||
|
|
||||||
return edges;
|
return edges;
|
||||||
}
|
}
|
|
@ -17,7 +17,7 @@
|
||||||
#define RUN_UNSUPPORTED false
|
#define RUN_UNSUPPORTED false
|
||||||
|
|
||||||
/* Skip tests that haven't been developed yet due to non standard data types or it needs an
|
/* Skip tests that haven't been developed yet due to non standard data types or it needs an
|
||||||
* framebuffer to create the texture. */
|
* frame-buffer to create the texture. */
|
||||||
#define RUN_SRGB_UNIMPLEMENTED false
|
#define RUN_SRGB_UNIMPLEMENTED false
|
||||||
#define RUN_NON_STANDARD_UNIMPLEMENTED false
|
#define RUN_NON_STANDARD_UNIMPLEMENTED false
|
||||||
#define RUN_COMPONENT_UNIMPLEMENTED false
|
#define RUN_COMPONENT_UNIMPLEMENTED false
|
||||||
|
@ -168,7 +168,7 @@ static void texture_create_upload_read_pixel()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/** \name Roundtrip testing GPU_DATA_FLOAT
|
/** \name Round-trip testing GPU_DATA_FLOAT
|
||||||
* \{ */
|
* \{ */
|
||||||
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA8()
|
static void test_texture_roundtrip__GPU_DATA_FLOAT__GPU_RGBA8()
|
||||||
{
|
{
|
||||||
|
@ -422,7 +422,7 @@ GPU_TEST(texture_roundtrip__GPU_DATA_FLOAT__GPU_DEPTH_COMPONENT16);
|
||||||
/* \} */
|
/* \} */
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/** \name Roundtrip testing GPU_DATA_HALF_FLOAT
|
/** \name Round-trip testing GPU_DATA_HALF_FLOAT
|
||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
static void test_texture_roundtrip__GPU_DATA_HALF_FLOAT__GPU_RGBA16F()
|
static void test_texture_roundtrip__GPU_DATA_HALF_FLOAT__GPU_RGBA16F()
|
||||||
|
@ -454,7 +454,7 @@ GPU_TEST(texture_roundtrip__GPU_DATA_HALF_FLOAT__GPU_RGB16F);
|
||||||
/* \} */
|
/* \} */
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/** \name Roundtrip testing GPU_DATA_INT
|
/** \name Round-trip testing GPU_DATA_INT
|
||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
static void test_texture_roundtrip__GPU_DATA_INT__GPU_RGBA8I()
|
static void test_texture_roundtrip__GPU_DATA_INT__GPU_RGBA8I()
|
||||||
|
@ -534,7 +534,7 @@ GPU_TEST(texture_roundtrip__GPU_DATA_INT__GPU_RGB32I);
|
||||||
/* \} */
|
/* \} */
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/** \name Roundtrip testing GPU_DATA_UINT
|
/** \name Round-trip testing GPU_DATA_UINT
|
||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
static void test_texture_roundtrip__GPU_DATA_UINT__GPU_RGBA8UI()
|
static void test_texture_roundtrip__GPU_DATA_UINT__GPU_RGBA8UI()
|
||||||
|
@ -648,7 +648,7 @@ GPU_TEST(texture_roundtrip__GPU_DATA_UINT__GPU_DEPTH_COMPONENT16);
|
||||||
/* \} */
|
/* \} */
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/** \name Roundtrip testing GPU_DATA_UBYTE
|
/** \name Round-trip testing GPU_DATA_UBYTE
|
||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
static void test_texture_roundtrip__GPU_DATA_UBYTE__GPU_RGBA8UI()
|
static void test_texture_roundtrip__GPU_DATA_UBYTE__GPU_RGBA8UI()
|
||||||
|
@ -717,7 +717,7 @@ GPU_TEST(texture_roundtrip__GPU_DATA_UBYTE__GPU_SRGB8);
|
||||||
/* \} */
|
/* \} */
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/** \name Roundtrip testing GPU_DATA_UINT_24_8
|
/** \name Round-trip testing GPU_DATA_UINT_24_8
|
||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
#if RUN_UNSUPPORTED
|
#if RUN_UNSUPPORTED
|
||||||
|
@ -737,7 +737,7 @@ GPU_TEST(texture_roundtrip__GPU_DATA_UINT_24_8__GPU_DEPTH24_STENCIL8);
|
||||||
/* \} */
|
/* \} */
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/** \name Roundtrip testing GPU_DATA_10_11_11_REV
|
/** \name Round-trip testing GPU_DATA_10_11_11_REV
|
||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
static void test_texture_roundtrip__GPU_DATA_10_11_11_REV__GPU_R11F_G11F_B10F()
|
static void test_texture_roundtrip__GPU_DATA_10_11_11_REV__GPU_R11F_G11F_B10F()
|
||||||
|
@ -749,7 +749,7 @@ GPU_TEST(texture_roundtrip__GPU_DATA_10_11_11_REV__GPU_R11F_G11F_B10F);
|
||||||
/* \} */
|
/* \} */
|
||||||
|
|
||||||
/* -------------------------------------------------------------------- */
|
/* -------------------------------------------------------------------- */
|
||||||
/** \name Roundtrip testing GPU_DATA_2_10_10_10_REV
|
/** \name Round-trip testing GPU_DATA_2_10_10_10_REV
|
||||||
* \{ */
|
* \{ */
|
||||||
|
|
||||||
static void test_texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2()
|
static void test_texture_roundtrip__GPU_DATA_2_10_10_10_REV__GPU_RGB10_A2()
|
||||||
|
|
|
@ -89,7 +89,7 @@ typedef struct NoiseGpencilModifierData {
|
||||||
char layername[64];
|
char layername[64];
|
||||||
/** Material name. */
|
/** Material name. */
|
||||||
char materialname[64] DNA_DEPRECATED;
|
char materialname[64] DNA_DEPRECATED;
|
||||||
/** Optional vertexgroup name, MAX_VGROUP_NAME. */
|
/** Optional vertex-group name, #MAX_VGROUP_NAME. */
|
||||||
char vgname[64];
|
char vgname[64];
|
||||||
/** Custom index for passes. */
|
/** Custom index for passes. */
|
||||||
int pass_index;
|
int pass_index;
|
||||||
|
@ -175,7 +175,7 @@ typedef struct ThickGpencilModifierData {
|
||||||
char layername[64];
|
char layername[64];
|
||||||
/** Material name. */
|
/** Material name. */
|
||||||
char materialname[64] DNA_DEPRECATED;
|
char materialname[64] DNA_DEPRECATED;
|
||||||
/** Optional vertexgroup name, MAX_VGROUP_NAME. */
|
/** Optional vertex-group name, #MAX_VGROUP_NAME. */
|
||||||
char vgname[64];
|
char vgname[64];
|
||||||
/** Custom index for passes. */
|
/** Custom index for passes. */
|
||||||
int pass_index;
|
int pass_index;
|
||||||
|
@ -308,7 +308,7 @@ typedef struct OpacityGpencilModifierData {
|
||||||
char layername[64];
|
char layername[64];
|
||||||
/** Material name. */
|
/** Material name. */
|
||||||
char materialname[64] DNA_DEPRECATED;
|
char materialname[64] DNA_DEPRECATED;
|
||||||
/** Optional vertexgroup name, MAX_VGROUP_NAME. */
|
/** Optional vertex-group name, #MAX_VGROUP_NAME. */
|
||||||
char vgname[64];
|
char vgname[64];
|
||||||
/** Custom index for passes. */
|
/** Custom index for passes. */
|
||||||
int pass_index;
|
int pass_index;
|
||||||
|
@ -457,11 +457,11 @@ typedef struct BuildGpencilModifierData {
|
||||||
*/
|
*/
|
||||||
short time_alignment;
|
short time_alignment;
|
||||||
|
|
||||||
/* Speed factor for GP_BUILD_TIMEMODE_DRAWSPEED. */
|
/** Speed factor for #GP_BUILD_TIMEMODE_DRAWSPEED. */
|
||||||
float speed_fac;
|
float speed_fac;
|
||||||
/* Maxmium time gap between strokes for GP_BUILD_TIMEMODE_DRAWSPEED. */
|
/** Maximum time gap between strokes for #GP_BUILD_TIMEMODE_DRAWSPEED. */
|
||||||
float speed_maxgap;
|
float speed_maxgap;
|
||||||
/* Which time mode should be used. */
|
/** Which time mode should be used. */
|
||||||
short time_mode;
|
short time_mode;
|
||||||
char _pad[6];
|
char _pad[6];
|
||||||
|
|
||||||
|
@ -473,7 +473,7 @@ typedef struct BuildGpencilModifierData {
|
||||||
|
|
||||||
/** Weight fading at the end of the stroke. */
|
/** Weight fading at the end of the stroke. */
|
||||||
float fade_fac;
|
float fade_fac;
|
||||||
/** Target vertexgroup name, MAX_VGROUP_NAME. */
|
/** Target vertex-group name, #MAX_VGROUP_NAME. */
|
||||||
char target_vgname[64];
|
char target_vgname[64];
|
||||||
/** Fading strength of opacity and thickness */
|
/** Fading strength of opacity and thickness */
|
||||||
float fade_opacity_strength;
|
float fade_opacity_strength;
|
||||||
|
@ -508,11 +508,11 @@ typedef enum eBuildGpencil_TimeAlignment {
|
||||||
} eBuildGpencil_TimeAlignment;
|
} eBuildGpencil_TimeAlignment;
|
||||||
|
|
||||||
typedef enum eBuildGpencil_TimeMode {
|
typedef enum eBuildGpencil_TimeMode {
|
||||||
/* Use a number of frames build. */
|
/** Use a number of frames build. */
|
||||||
GP_BUILD_TIMEMODE_FRAMES = 0,
|
GP_BUILD_TIMEMODE_FRAMES = 0,
|
||||||
/* Use manual percentage to build. */
|
/** Use manual percentage to build. */
|
||||||
GP_BUILD_TIMEMODE_PERCENTAGE = 1,
|
GP_BUILD_TIMEMODE_PERCENTAGE = 1,
|
||||||
/* Use factor of recorded speed to build. */
|
/** Use factor of recorded speed to build. */
|
||||||
GP_BUILD_TIMEMODE_DRAWSPEED = 2,
|
GP_BUILD_TIMEMODE_DRAWSPEED = 2,
|
||||||
} eBuildGpencil_TimeMode;
|
} eBuildGpencil_TimeMode;
|
||||||
|
|
||||||
|
@ -536,7 +536,7 @@ typedef struct LatticeGpencilModifierData {
|
||||||
char layername[64];
|
char layername[64];
|
||||||
/** Material name. */
|
/** Material name. */
|
||||||
char materialname[64] DNA_DEPRECATED;
|
char materialname[64] DNA_DEPRECATED;
|
||||||
/** Optional vertexgroup name, MAX_VGROUP_NAME. */
|
/** Optional vertex-group name, #MAX_VGROUP_NAME. */
|
||||||
char vgname[64];
|
char vgname[64];
|
||||||
/** Custom index for passes. */
|
/** Custom index for passes. */
|
||||||
int pass_index;
|
int pass_index;
|
||||||
|
@ -685,7 +685,7 @@ typedef struct HookGpencilModifierData {
|
||||||
char layername[64];
|
char layername[64];
|
||||||
/** Material name. */
|
/** Material name. */
|
||||||
char materialname[64] DNA_DEPRECATED;
|
char materialname[64] DNA_DEPRECATED;
|
||||||
/** Optional vertexgroup name, MAX_VGROUP_NAME. */
|
/** Optional vertex-group name, #MAX_VGROUP_NAME. */
|
||||||
char vgname[64];
|
char vgname[64];
|
||||||
/** Custom index for passes. */
|
/** Custom index for passes. */
|
||||||
int pass_index;
|
int pass_index;
|
||||||
|
@ -694,7 +694,7 @@ typedef struct HookGpencilModifierData {
|
||||||
char _pad[4];
|
char _pad[4];
|
||||||
|
|
||||||
int flag;
|
int flag;
|
||||||
/** Use enums from WarpGpencilModifier (exact same functionality). */
|
/** #eHookGpencil_Falloff. */
|
||||||
char falloff_type;
|
char falloff_type;
|
||||||
char _pad1[3];
|
char _pad1[3];
|
||||||
/** Matrix making current transform unmodified. */
|
/** Matrix making current transform unmodified. */
|
||||||
|
@ -790,7 +790,7 @@ typedef struct OffsetGpencilModifierData {
|
||||||
char layername[64];
|
char layername[64];
|
||||||
/** Material name. */
|
/** Material name. */
|
||||||
char materialname[64] DNA_DEPRECATED;
|
char materialname[64] DNA_DEPRECATED;
|
||||||
/** Optional vertexgroup name, MAX_VGROUP_NAME. */
|
/** Optional vertex-group name, #MAX_VGROUP_NAME. */
|
||||||
char vgname[64];
|
char vgname[64];
|
||||||
/** Custom index for passes. */
|
/** Custom index for passes. */
|
||||||
int pass_index;
|
int pass_index;
|
||||||
|
@ -832,7 +832,7 @@ typedef struct SmoothGpencilModifierData {
|
||||||
char layername[64];
|
char layername[64];
|
||||||
/** Material name. */
|
/** Material name. */
|
||||||
char materialname[64] DNA_DEPRECATED;
|
char materialname[64] DNA_DEPRECATED;
|
||||||
/** Optional vertexgroup name, MAX_VGROUP_NAME. */
|
/** Optional vertex-group name, #MAX_VGROUP_NAME. */
|
||||||
char vgname[64];
|
char vgname[64];
|
||||||
/** Custom index for passes. */
|
/** Custom index for passes. */
|
||||||
int pass_index;
|
int pass_index;
|
||||||
|
@ -871,7 +871,7 @@ typedef struct ArmatureGpencilModifierData {
|
||||||
struct Object *object;
|
struct Object *object;
|
||||||
/** Stored input of previous modifier, for vertex-group blending. */
|
/** Stored input of previous modifier, for vertex-group blending. */
|
||||||
float (*vert_coords_prev)[3];
|
float (*vert_coords_prev)[3];
|
||||||
/** MAX_VGROUP_NAME. */
|
/** #MAX_VGROUP_NAME. */
|
||||||
char vgname[64];
|
char vgname[64];
|
||||||
|
|
||||||
} ArmatureGpencilModifierData;
|
} ArmatureGpencilModifierData;
|
||||||
|
@ -919,7 +919,7 @@ typedef struct TintGpencilModifierData {
|
||||||
char layername[64];
|
char layername[64];
|
||||||
/** Material name. */
|
/** Material name. */
|
||||||
char materialname[64] DNA_DEPRECATED;
|
char materialname[64] DNA_DEPRECATED;
|
||||||
/** Optional vertexgroup name, MAX_VGROUP_NAME. */
|
/** Optional vertex-group name, #MAX_VGROUP_NAME. */
|
||||||
char vgname[64];
|
char vgname[64];
|
||||||
/** Custom index for passes. */
|
/** Custom index for passes. */
|
||||||
int pass_index;
|
int pass_index;
|
||||||
|
@ -965,7 +965,7 @@ typedef struct TextureGpencilModifierData {
|
||||||
char layername[64];
|
char layername[64];
|
||||||
/** Material name. */
|
/** Material name. */
|
||||||
char materialname[64] DNA_DEPRECATED;
|
char materialname[64] DNA_DEPRECATED;
|
||||||
/** Optional vertexgroup name, MAX_VGROUP_NAME. */
|
/** Optional vertex-group name, #MAX_VGROUP_NAME. */
|
||||||
char vgname[64];
|
char vgname[64];
|
||||||
/** Custom index for passes. */
|
/** Custom index for passes. */
|
||||||
int pass_index;
|
int pass_index;
|
||||||
|
@ -1010,13 +1010,13 @@ typedef enum eTextureGpencil_Mode {
|
||||||
|
|
||||||
typedef struct WeightProxGpencilModifierData {
|
typedef struct WeightProxGpencilModifierData {
|
||||||
GpencilModifierData modifier;
|
GpencilModifierData modifier;
|
||||||
/** Target vertexgroup name, MAX_VGROUP_NAME. */
|
/** Target vertex-group name, #MAX_VGROUP_NAME. */
|
||||||
char target_vgname[64];
|
char target_vgname[64];
|
||||||
/** Material for filtering. */
|
/** Material for filtering. */
|
||||||
struct Material *material;
|
struct Material *material;
|
||||||
/** Layer name. */
|
/** Layer name. */
|
||||||
char layername[64];
|
char layername[64];
|
||||||
/** Optional vertexgroup filter name, MAX_VGROUP_NAME. */
|
/** Optional vertex-group filter name, #MAX_VGROUP_NAME. */
|
||||||
char vgname[64];
|
char vgname[64];
|
||||||
/** Custom index for passes. */
|
/** Custom index for passes. */
|
||||||
int pass_index;
|
int pass_index;
|
||||||
|
@ -1036,13 +1036,13 @@ typedef struct WeightProxGpencilModifierData {
|
||||||
|
|
||||||
typedef struct WeightAngleGpencilModifierData {
|
typedef struct WeightAngleGpencilModifierData {
|
||||||
GpencilModifierData modifier;
|
GpencilModifierData modifier;
|
||||||
/** Target vertexgroup name, MAX_VGROUP_NAME. */
|
/** Target vertex-group name, #MAX_VGROUP_NAME. */
|
||||||
char target_vgname[64];
|
char target_vgname[64];
|
||||||
/** Material for filtering. */
|
/** Material for filtering. */
|
||||||
struct Material *material;
|
struct Material *material;
|
||||||
/** Layer name. */
|
/** Layer name. */
|
||||||
char layername[64];
|
char layername[64];
|
||||||
/** Optional vertexgroup filter name, MAX_VGROUP_NAME. */
|
/** Optional vertex-group filter name, #MAX_VGROUP_NAME. */
|
||||||
char vgname[64];
|
char vgname[64];
|
||||||
/** Custom index for passes. */
|
/** Custom index for passes. */
|
||||||
int pass_index;
|
int pass_index;
|
||||||
|
@ -1209,7 +1209,7 @@ typedef struct LineartGpencilModifierData {
|
||||||
char _pad2[6];
|
char _pad2[6];
|
||||||
|
|
||||||
struct LineartCache *cache;
|
struct LineartCache *cache;
|
||||||
/* Keep a pointer to the render buffer so we can call destroy from ModifierData. */
|
/** Keep a pointer to the render buffer so we can call destroy from #ModifierData. */
|
||||||
struct LineartData *la_data_ptr;
|
struct LineartData *la_data_ptr;
|
||||||
|
|
||||||
} LineartGpencilModifierData;
|
} LineartGpencilModifierData;
|
||||||
|
@ -1224,7 +1224,7 @@ typedef struct ShrinkwrapGpencilModifierData {
|
||||||
struct Material *material;
|
struct Material *material;
|
||||||
/** Layer name. */
|
/** Layer name. */
|
||||||
char layername[64];
|
char layername[64];
|
||||||
/** Optional vertexgroup filter name, MAX_VGROUP_NAME. */
|
/** Optional vertex-group filter name, #MAX_VGROUP_NAME. */
|
||||||
char vgname[64];
|
char vgname[64];
|
||||||
/** Custom index for passes. */
|
/** Custom index for passes. */
|
||||||
int pass_index;
|
int pass_index;
|
||||||
|
@ -1274,7 +1274,7 @@ typedef struct EnvelopeGpencilModifierData {
|
||||||
struct Material *material;
|
struct Material *material;
|
||||||
/** Layer name. */
|
/** Layer name. */
|
||||||
char layername[64];
|
char layername[64];
|
||||||
/** Optional vertexgroup name, MAX_VGROUP_NAME. */
|
/** Optional vertex-group name, #MAX_VGROUP_NAME. */
|
||||||
char vgname[64];
|
char vgname[64];
|
||||||
/** Custom index for passes. */
|
/** Custom index for passes. */
|
||||||
int pass_index;
|
int pass_index;
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "UI_interface.h"
|
#include "UI_interface.h"
|
||||||
#include "UI_resources.h"
|
#include "UI_resources.h"
|
||||||
|
|
||||||
|
#include "COM_algorithm_smaa.hh"
|
||||||
#include "COM_node_operation.hh"
|
#include "COM_node_operation.hh"
|
||||||
|
|
||||||
#include "node_composite_util.hh"
|
#include "node_composite_util.hh"
|
||||||
|
@ -18,9 +19,13 @@
|
||||||
|
|
||||||
namespace blender::nodes::node_composite_antialiasing_cc {
|
namespace blender::nodes::node_composite_antialiasing_cc {
|
||||||
|
|
||||||
|
NODE_STORAGE_FUNCS(NodeAntiAliasingData)
|
||||||
|
|
||||||
static void cmp_node_antialiasing_declare(NodeDeclarationBuilder &b)
|
static void cmp_node_antialiasing_declare(NodeDeclarationBuilder &b)
|
||||||
{
|
{
|
||||||
b.add_input<decl::Color>(N_("Image")).default_value({1.0f, 1.0f, 1.0f, 1.0f});
|
b.add_input<decl::Color>(N_("Image"))
|
||||||
|
.default_value({1.0f, 1.0f, 1.0f, 1.0f})
|
||||||
|
.compositor_domain_priority(0);
|
||||||
b.add_output<decl::Color>(N_("Image"));
|
b.add_output<decl::Color>(N_("Image"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,8 +59,33 @@ class AntiAliasingOperation : public NodeOperation {
|
||||||
|
|
||||||
void execute() override
|
void execute() override
|
||||||
{
|
{
|
||||||
get_input("Image").pass_through(get_result("Image"));
|
smaa(context(),
|
||||||
context().set_info_message("Viewport compositor setup not fully supported");
|
get_input("Image"),
|
||||||
|
get_result("Image"),
|
||||||
|
get_threshold(),
|
||||||
|
get_local_contrast_adaptation_factor(),
|
||||||
|
get_corner_rounding());
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Blender encodes the threshold in the [0, 1] range, while the SMAA algorithm expects it in
|
||||||
|
* the [0, 0.5] range. */
|
||||||
|
float get_threshold()
|
||||||
|
{
|
||||||
|
return node_storage(bnode()).threshold / 2.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Blender encodes the local contrast adaptation factor in the [0, 1] range, while the SMAA
|
||||||
|
* algorithm expects it in the [0, 10] range. */
|
||||||
|
float get_local_contrast_adaptation_factor()
|
||||||
|
{
|
||||||
|
return node_storage(bnode()).threshold * 10.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Blender encodes the corner rounding factor in the float [0, 1] range, while the SMAA algorithm
|
||||||
|
* expects it in the integer [0, 100] range. */
|
||||||
|
int get_corner_rounding()
|
||||||
|
{
|
||||||
|
return int(node_storage(bnode()).corner_rounding * 100.0f);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -81,8 +111,6 @@ void register_node_type_cmp_antialiasing()
|
||||||
node_type_storage(
|
node_type_storage(
|
||||||
&ntype, "NodeAntiAliasingData", node_free_standard_storage, node_copy_standard_storage);
|
&ntype, "NodeAntiAliasingData", node_free_standard_storage, node_copy_standard_storage);
|
||||||
ntype.get_compositor_operation = file_ns::get_compositor_operation;
|
ntype.get_compositor_operation = file_ns::get_compositor_operation;
|
||||||
ntype.realtime_compositor_unsupported_message = N_(
|
|
||||||
"Node not supported in the Viewport compositor");
|
|
||||||
|
|
||||||
nodeRegisterType(&ntype);
|
nodeRegisterType(&ntype);
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,7 +106,7 @@ class BlurOperation : public NodeOperation {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!get_input("Size").is_single_value() && get_variable_size()) {
|
if (use_variable_size()) {
|
||||||
execute_variable_size();
|
execute_variable_size();
|
||||||
}
|
}
|
||||||
else if (use_separable_filter()) {
|
else if (use_separable_filter()) {
|
||||||
|
@ -261,6 +261,12 @@ class BlurOperation : public NodeOperation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool use_variable_size()
|
||||||
|
{
|
||||||
|
return get_variable_size() && !get_input("Size").is_single_value() &&
|
||||||
|
node_storage(bnode()).filtertype != R_FILTER_FAST_GAUSS;
|
||||||
|
}
|
||||||
|
|
||||||
float2 get_size_factor()
|
float2 get_size_factor()
|
||||||
{
|
{
|
||||||
return float2(node_storage(bnode()).percentx, node_storage(bnode()).percenty) / 100.0f;
|
return float2(node_storage(bnode()).percentx, node_storage(bnode()).percenty) / 100.0f;
|
||||||
|
|
|
@ -179,7 +179,7 @@ struct GrabState {
|
||||||
static bool wm_software_cursor_needed(void)
|
static bool wm_software_cursor_needed(void)
|
||||||
{
|
{
|
||||||
if (UNLIKELY(g_software_cursor.enabled == -1)) {
|
if (UNLIKELY(g_software_cursor.enabled == -1)) {
|
||||||
g_software_cursor.enabled = !GHOST_SupportsCursorWarp();
|
g_software_cursor.enabled = !(WM_capabilities_flag() & WM_CAPABILITY_CURSOR_WARP);
|
||||||
}
|
}
|
||||||
return g_software_cursor.enabled;
|
return g_software_cursor.enabled;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5165,7 +5165,8 @@ static void attach_ndof_data(wmEvent *event, const GHOST_TEventNDOFMotionData *g
|
||||||
static wmWindow *wm_event_cursor_other_windows(wmWindowManager *wm, wmWindow *win, wmEvent *event)
|
static wmWindow *wm_event_cursor_other_windows(wmWindowManager *wm, wmWindow *win, wmEvent *event)
|
||||||
{
|
{
|
||||||
/* If GHOST doesn't support window positioning, don't use this feature at all. */
|
/* If GHOST doesn't support window positioning, don't use this feature at all. */
|
||||||
const static int8_t supports_window_position = GHOST_SupportsWindowPosition();
|
const static int8_t supports_window_position = (WM_capabilities_flag() &
|
||||||
|
WM_CAPABILITY_WINDOW_POSITION) != 0;
|
||||||
if (!supports_window_position) {
|
if (!supports_window_position) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -998,7 +998,11 @@ wmWindow *WM_window_open(bContext *C,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ****************** Operators ****************** */
|
/** \} */
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------- */
|
||||||
|
/** \name Operators
|
||||||
|
* \{ */
|
||||||
|
|
||||||
int wm_window_close_exec(bContext *C, wmOperator *UNUSED(op))
|
int wm_window_close_exec(bContext *C, wmOperator *UNUSED(op))
|
||||||
{
|
{
|
||||||
|
@ -1063,7 +1067,11 @@ int wm_window_fullscreen_toggle_exec(bContext *C, wmOperator *UNUSED(op))
|
||||||
return OPERATOR_FINISHED;
|
return OPERATOR_FINISHED;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ************ events *************** */
|
/** \} */
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------- */
|
||||||
|
/** \name Events
|
||||||
|
* \{ */
|
||||||
|
|
||||||
void wm_cursor_position_from_ghost_client_coords(wmWindow *win, int *x, int *y)
|
void wm_cursor_position_from_ghost_client_coords(wmWindow *win, int *x, int *y)
|
||||||
{
|
{
|
||||||
|
@ -1827,14 +1835,14 @@ eWM_CapabilitiesFlag WM_capabilities_flag(void)
|
||||||
return flag;
|
return flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
flag = 0;
|
const GHOST_TCapabilityFlag ghost_flag = GHOST_GetCapabilities();
|
||||||
if (GHOST_SupportsCursorWarp()) {
|
if (ghost_flag & GHOST_kCapabilityCursorWarp) {
|
||||||
flag |= WM_CAPABILITY_CURSOR_WARP;
|
flag |= WM_CAPABILITY_CURSOR_WARP;
|
||||||
}
|
}
|
||||||
if (GHOST_SupportsWindowPosition()) {
|
if (ghost_flag & GHOST_kCapabilityWindowPosition) {
|
||||||
flag |= WM_CAPABILITY_WINDOW_POSITION;
|
flag |= WM_CAPABILITY_WINDOW_POSITION;
|
||||||
}
|
}
|
||||||
if (GHOST_SupportsPrimaryClipboard()) {
|
if (ghost_flag & GHOST_kCapabilityPrimaryClipboard) {
|
||||||
flag |= WM_CAPABILITY_PRIMARY_CLIPBOARD;
|
flag |= WM_CAPABILITY_PRIMARY_CLIPBOARD;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -100,6 +100,7 @@ dict_custom = {
|
||||||
"dialogs",
|
"dialogs",
|
||||||
"digitizers",
|
"digitizers",
|
||||||
"dihedral",
|
"dihedral",
|
||||||
|
"directionality",
|
||||||
"discoverability",
|
"discoverability",
|
||||||
"discretization",
|
"discretization",
|
||||||
"discretized",
|
"discretized",
|
||||||
|
@ -144,6 +145,7 @@ dict_custom = {
|
||||||
"interdependencies",
|
"interdependencies",
|
||||||
"interferences",
|
"interferences",
|
||||||
"interocular",
|
"interocular",
|
||||||
|
"interpolator",
|
||||||
"invariant",
|
"invariant",
|
||||||
"invariants",
|
"invariants",
|
||||||
"invisibilities",
|
"invisibilities",
|
||||||
|
@ -157,6 +159,8 @@ dict_custom = {
|
||||||
"linearizing",
|
"linearizing",
|
||||||
"linkable",
|
"linkable",
|
||||||
"lockless",
|
"lockless",
|
||||||
|
"looper",
|
||||||
|
"loopers",
|
||||||
"losslessly",
|
"losslessly",
|
||||||
"luminances",
|
"luminances",
|
||||||
"mappable",
|
"mappable",
|
||||||
|
@ -174,6 +178,8 @@ dict_custom = {
|
||||||
"occludee",
|
"occludee",
|
||||||
"occluder",
|
"occluder",
|
||||||
"occluders",
|
"occluders",
|
||||||
|
"octant",
|
||||||
|
"octants",
|
||||||
"optionals",
|
"optionals",
|
||||||
"orthogonalize",
|
"orthogonalize",
|
||||||
"orthogonally",
|
"orthogonally",
|
||||||
|
@ -186,6 +192,7 @@ dict_custom = {
|
||||||
"parallelize",
|
"parallelize",
|
||||||
"parallelizing",
|
"parallelizing",
|
||||||
"parameterization",
|
"parameterization",
|
||||||
|
"parameterless",
|
||||||
"parametrization",
|
"parametrization",
|
||||||
"parentless",
|
"parentless",
|
||||||
"passepartout",
|
"passepartout",
|
||||||
|
@ -247,6 +254,8 @@ dict_custom = {
|
||||||
"redistributions",
|
"redistributions",
|
||||||
"registerable",
|
"registerable",
|
||||||
"reimplement",
|
"reimplement",
|
||||||
|
"reimplemented",
|
||||||
|
"reimplementing",
|
||||||
"remappable",
|
"remappable",
|
||||||
"remapper",
|
"remapper",
|
||||||
"remappings",
|
"remappings",
|
||||||
|
@ -258,9 +267,14 @@ dict_custom = {
|
||||||
"reparameterization",
|
"reparameterization",
|
||||||
"reparametization",
|
"reparametization",
|
||||||
"representable",
|
"representable",
|
||||||
|
"reprojected",
|
||||||
"reprojecting",
|
"reprojecting",
|
||||||
|
"reprojection",
|
||||||
|
"reprojections",
|
||||||
"repurpose",
|
"repurpose",
|
||||||
"respecialized",
|
"respecialized",
|
||||||
|
"resynced",
|
||||||
|
"resyncing",
|
||||||
"retiming",
|
"retiming",
|
||||||
"reusability",
|
"reusability",
|
||||||
"saveable",
|
"saveable",
|
||||||
|
@ -325,6 +339,7 @@ dict_custom = {
|
||||||
"undistored",
|
"undistored",
|
||||||
"undistorted",
|
"undistorted",
|
||||||
"undistorting",
|
"undistorting",
|
||||||
|
"unduplicated",
|
||||||
"uneditable",
|
"uneditable",
|
||||||
"unflagged",
|
"unflagged",
|
||||||
"unflip",
|
"unflip",
|
||||||
|
@ -368,6 +383,7 @@ dict_custom = {
|
||||||
"unpoision",
|
"unpoision",
|
||||||
"unproject",
|
"unproject",
|
||||||
"unquantifiable",
|
"unquantifiable",
|
||||||
|
"unreferenced",
|
||||||
"unregister",
|
"unregister",
|
||||||
"unregistering",
|
"unregistering",
|
||||||
"unregisters",
|
"unregisters",
|
||||||
|
@ -429,6 +445,7 @@ dict_custom = {
|
||||||
"addon",
|
"addon",
|
||||||
"addons",
|
"addons",
|
||||||
"autocomplete",
|
"autocomplete",
|
||||||
|
"codegen",
|
||||||
"colospace",
|
"colospace",
|
||||||
"datablock",
|
"datablock",
|
||||||
"datablocks",
|
"datablocks",
|
||||||
|
@ -451,6 +468,7 @@ dict_custom = {
|
||||||
"config", # configuration.
|
"config", # configuration.
|
||||||
"coord",
|
"coord",
|
||||||
"coords",
|
"coords",
|
||||||
|
"ctrl", # control (modifier key).
|
||||||
"iter", # iteration.
|
"iter", # iteration.
|
||||||
"multi",
|
"multi",
|
||||||
"numpad", # numeric-pad.
|
"numpad", # numeric-pad.
|
||||||
|
|
Loading…
Reference in New Issue