Nodes: use auto registration for nodes #110686

Merged
Jacques Lucke merged 29 commits from JacquesLucke/blender:auto-node-register into main 2023-08-09 22:01:10 +02:00
219 changed files with 7353 additions and 3365 deletions
Showing only changes of commit 98f7ab48a0 - Show all commits

View File

@ -26,6 +26,7 @@ set(WITH_FFTW3 OFF CACHE BOOL "" FORCE)
set(WITH_FREESTYLE OFF CACHE BOOL "" FORCE)
set(WITH_GMP OFF CACHE BOOL "" FORCE)
set(WITH_HARU OFF CACHE BOOL "" FORCE)
set(WITH_HYDRA OFF CACHE BOOL "" FORCE)
set(WITH_IK_ITASC OFF CACHE BOOL "" FORCE)
set(WITH_IK_SOLVER OFF CACHE BOOL "" FORCE)
set(WITH_IMAGE_CINEON OFF CACHE BOOL "" FORCE)
@ -55,6 +56,7 @@ set(WITH_OPENIMAGEDENOISE OFF CACHE BOOL "" FORCE)
set(WITH_OPENMP OFF CACHE BOOL "" FORCE)
set(WITH_OPENSUBDIV OFF CACHE BOOL "" FORCE)
set(WITH_OPENVDB OFF CACHE BOOL "" FORCE)
set(WITH_POTRACE OFF CACHE BOOL "" FORCE)
set(WITH_PUGIXML OFF CACHE BOOL "" FORCE)
set(WITH_PULSEAUDIO OFF CACHE BOOL "" FORCE)
@ -71,3 +73,10 @@ if(UNIX AND NOT APPLE)
set(WITH_X11_XINPUT OFF CACHE BOOL "" FORCE)
set(WITH_X11_XF86VMODE OFF CACHE BOOL "" FORCE)
endif()
# These should not have any impact but are disabled so they don't
# appear to be enabled in the list of items (which are mostly OFF).
set(WITH_CYCLES_DEVICE_OPTIX OFF CACHE BOOL "" FORCE)
set(WITH_CYCLES_EMBREE OFF CACHE BOOL "" FORCE)
set(WITH_CYCLES_PATH_GUIDING OFF CACHE BOOL "" FORCE)
set(WITH_OPENVDB_BLOSC OFF CACHE BOOL "" FORCE)

View File

@ -48,6 +48,7 @@ import pxr.Sdf as Sdf
import pxr.Usd as Usd
import pxr.UsdShade as UsdShade
class USDHookExample(bpy.types.USDHook):
bl_idname = "usd_hook_example"
bl_label = "Example"
@ -97,10 +98,12 @@ class USDHookExample(bpy.types.USDHook):
def register():
bpy.utils.register_class(USDHookExample)
bpy.utils.register_class(USDHookExample)
def unregister():
bpy.utils.unregister_class(USDHookExample)
bpy.utils.unregister_class(USDHookExample)
if __name__ == "__main__":
register()

View File

@ -19,6 +19,11 @@ float safe_modulo(float a, float b)
return (b != 0.0) ? fmod(a, b) : 0.0;
}
float safe_floored_modulo(float a, float b)
{
return (b != 0.0) ? a - floor(a / b) * b : 0.0;
}
float fract(float a)
{
return a - floor(a);

View File

@ -52,6 +52,8 @@ shader node_math(string math_type = "add",
Value = Value1 - floor(Value1);
else if (math_type == "modulo")
Value = safe_modulo(Value1, Value2);
else if (math_type == "floored_modulo")
Value = safe_floored_modulo(Value1, Value2);
else if (math_type == "trunc")
Value = trunc(Value1);
else if (math_type == "snap")

View File

@ -145,6 +145,8 @@ ccl_device float svm_math(NodeMathType type, float a, float b, float c)
return a - floorf(a);
case NODE_MATH_MODULO:
return safe_modulo(a, b);
case NODE_MATH_FLOORED_MODULO:
return safe_floored_modulo(a, b);
case NODE_MATH_TRUNC:
return a >= 0.0f ? floorf(a) : ceilf(a);
case NODE_MATH_SNAP:

View File

@ -182,6 +182,7 @@ typedef enum NodeMathType {
NODE_MATH_PINGPONG,
NODE_MATH_SMOOTH_MIN,
NODE_MATH_SMOOTH_MAX,
NODE_MATH_FLOORED_MODULO,
} NodeMathType;
typedef enum NodeVectorMathType {

View File

@ -6292,6 +6292,7 @@ NODE_DEFINE(MathNode)
type_enum.insert("less_than", NODE_MATH_LESS_THAN);
type_enum.insert("greater_than", NODE_MATH_GREATER_THAN);
type_enum.insert("modulo", NODE_MATH_MODULO);
type_enum.insert("floored_modulo", NODE_MATH_FLOORED_MODULO);
type_enum.insert("absolute", NODE_MATH_ABSOLUTE);
type_enum.insert("arctan2", NODE_MATH_ARCTAN2);
type_enum.insert("floor", NODE_MATH_FLOOR);

View File

@ -732,6 +732,11 @@ ccl_device float safe_modulo(float a, float b)
return (b != 0.0f) ? fmodf(a, b) : 0.0f;
}
ccl_device float safe_floored_modulo(float a, float b)
{
return (b != 0.0f) ? a - floorf(a / b) * b : 0.0f;
}
ccl_device_inline float sqr(float a)
{
return a * a;

View File

@ -219,6 +219,7 @@ class GHOST_DeviceVK {
device_features.dualSrcBlend = VK_TRUE;
device_features.logicOp = VK_TRUE;
device_features.imageCubeArray = VK_TRUE;
device_features.multiViewport = VK_TRUE;
#endif
VkDeviceCreateInfo device_create_info = {};

View File

@ -24,7 +24,7 @@ bool GHOST_EventPrinter::processEvent(GHOST_IEvent *event)
if (event->getType() == GHOST_kEventWindowUpdate) {
return false;
}
std::cout << "GHOST_EventPrinter::processEvent, time: " << (int32_t)event->getTime()
std::cout << "GHOST_EventPrinter::processEvent, time: " << int32_t(event->getTime())
<< ", type: ";
switch (event->getType()) {
case GHOST_kEventUnknown:
@ -58,15 +58,11 @@ bool GHOST_EventPrinter::processEvent(GHOST_IEvent *event)
case GHOST_kEventKeyUp: {
GHOST_TEventKeyData *keyData = (GHOST_TEventKeyData *)((GHOST_IEvent *)event)->getData();
char str[32] = {'\0'};
getKeyString(keyData->key, str);
std::cout << "GHOST_kEventKeyUp, key: " << str;
std::cout << "GHOST_kEventKeyUp, key: " << getKeyString(keyData->key);
} break;
case GHOST_kEventKeyDown: {
GHOST_TEventKeyData *keyData = (GHOST_TEventKeyData *)((GHOST_IEvent *)event)->getData();
char str[32] = {'\0'};
getKeyString(keyData->key, str);
std::cout << "GHOST_kEventKeyDown, key: " << str;
std::cout << "GHOST_kEventKeyDown, key: " << getKeyString(keyData->key);
} break;
case GHOST_kEventDraggingEntered: {
@ -159,161 +155,152 @@ bool GHOST_EventPrinter::processEvent(GHOST_IEvent *event)
return handled;
}
void GHOST_EventPrinter::getKeyString(GHOST_TKey key, char str[32]) const
const char *GHOST_EventPrinter::getKeyString(const GHOST_TKey key) const
{
if ((key >= GHOST_kKeyComma) && (key <= GHOST_kKeyRightBracket)) {
sprintf(str, "%c", char(key));
}
else if ((key >= GHOST_kKeyNumpad0) && (key <= GHOST_kKeyNumpad9)) {
sprintf(str, "Numpad %d", (key - GHOST_kKeyNumpad0));
}
else if ((key >= GHOST_kKeyF1) && (key <= GHOST_kKeyF24)) {
sprintf(str, "F%d", key - GHOST_kKeyF1 + 1);
}
else {
const char *tstr = nullptr;
switch (key) {
case GHOST_kKeyBackSpace:
tstr = "BackSpace";
break;
case GHOST_kKeyTab:
tstr = "Tab";
break;
case GHOST_kKeyLinefeed:
tstr = "Linefeed";
break;
case GHOST_kKeyClear:
tstr = "Clear";
break;
case GHOST_kKeyEnter:
tstr = "Enter";
break;
case GHOST_kKeyEsc:
tstr = "Esc";
break;
case GHOST_kKeySpace:
tstr = "Space";
break;
case GHOST_kKeyQuote:
tstr = "Quote";
break;
case GHOST_kKeyBackslash:
tstr = "\\";
break;
case GHOST_kKeyAccentGrave:
tstr = "`";
break;
case GHOST_kKeyLeftShift:
tstr = "LeftShift";
break;
case GHOST_kKeyRightShift:
tstr = "RightShift";
break;
case GHOST_kKeyLeftControl:
tstr = "LeftControl";
break;
case GHOST_kKeyRightControl:
tstr = "RightControl";
break;
case GHOST_kKeyLeftAlt:
tstr = "LeftAlt";
break;
case GHOST_kKeyRightAlt:
tstr = "RightAlt";
break;
case GHOST_kKeyLeftOS:
tstr = "LeftOS";
break;
case GHOST_kKeyRightOS:
tstr = "RightOS";
break;
case GHOST_kKeyApp:
tstr = "App";
break;
case GHOST_kKeyGrLess:
// PC german!
tstr = "GrLess";
break;
case GHOST_kKeyCapsLock:
tstr = "CapsLock";
break;
case GHOST_kKeyNumLock:
tstr = "NumLock";
break;
case GHOST_kKeyScrollLock:
tstr = "ScrollLock";
break;
case GHOST_kKeyLeftArrow:
tstr = "LeftArrow";
break;
case GHOST_kKeyRightArrow:
tstr = "RightArrow";
break;
case GHOST_kKeyUpArrow:
tstr = "UpArrow";
break;
case GHOST_kKeyDownArrow:
tstr = "DownArrow";
break;
case GHOST_kKeyPrintScreen:
tstr = "PrintScreen";
break;
case GHOST_kKeyPause:
tstr = "Pause";
break;
case GHOST_kKeyInsert:
tstr = "Insert";
break;
case GHOST_kKeyDelete:
tstr = "Delete";
break;
case GHOST_kKeyHome:
tstr = "Home";
break;
case GHOST_kKeyEnd:
tstr = "End";
break;
case GHOST_kKeyUpPage:
tstr = "UpPage";
break;
case GHOST_kKeyDownPage:
tstr = "DownPage";
break;
case GHOST_kKeyNumpadPeriod:
tstr = "NumpadPeriod";
break;
case GHOST_kKeyNumpadEnter:
tstr = "NumpadEnter";
break;
case GHOST_kKeyNumpadPlus:
tstr = "NumpadPlus";
break;
case GHOST_kKeyNumpadMinus:
tstr = "NumpadMinus";
break;
case GHOST_kKeyNumpadAsterisk:
tstr = "NumpadAsterisk";
break;
case GHOST_kKeyNumpadSlash:
tstr = "NumpadSlash";
break;
case GHOST_kKeyMediaPlay:
tstr = "MediaPlayPause";
break;
case GHOST_kKeyMediaStop:
tstr = "MediaStop";
break;
case GHOST_kKeyMediaFirst:
tstr = "MediaFirst";
break;
case GHOST_kKeyMediaLast:
tstr = "MediaLast";
break;
default:
tstr = "unknown";
break;
}
const char *tstr = nullptr;
sprintf(str, "%s", tstr);
#define CASE_KEY(k, v) \
case k: { \
tstr = v; \
break; \
}
switch (key) {
CASE_KEY(GHOST_kKeyBackSpace, "BackSpace");
CASE_KEY(GHOST_kKeyTab, "Tab");
CASE_KEY(GHOST_kKeyLinefeed, "Linefeed");
CASE_KEY(GHOST_kKeyClear, "Clear");
CASE_KEY(GHOST_kKeyEnter, "Enter");
CASE_KEY(GHOST_kKeyEsc, "Esc");
CASE_KEY(GHOST_kKeySpace, "Space");
CASE_KEY(GHOST_kKeyQuote, "Quote");
CASE_KEY(GHOST_kKeyBackslash, "\\");
CASE_KEY(GHOST_kKeyAccentGrave, "`");
CASE_KEY(GHOST_kKeyLeftShift, "LeftShift");
CASE_KEY(GHOST_kKeyRightShift, "RightShift");
CASE_KEY(GHOST_kKeyLeftControl, "LeftControl");
CASE_KEY(GHOST_kKeyRightControl, "RightControl");
CASE_KEY(GHOST_kKeyLeftAlt, "LeftAlt");
CASE_KEY(GHOST_kKeyRightAlt, "RightAlt");
CASE_KEY(GHOST_kKeyLeftOS, "LeftOS");
CASE_KEY(GHOST_kKeyRightOS, "RightOS");
CASE_KEY(GHOST_kKeyApp, "App");
CASE_KEY(GHOST_kKeyGrLess, "GrLess");
CASE_KEY(GHOST_kKeyCapsLock, "CapsLock");
CASE_KEY(GHOST_kKeyNumLock, "NumLock");
CASE_KEY(GHOST_kKeyScrollLock, "ScrollLock");
CASE_KEY(GHOST_kKeyLeftArrow, "LeftArrow");
CASE_KEY(GHOST_kKeyRightArrow, "RightArrow");
CASE_KEY(GHOST_kKeyUpArrow, "UpArrow");
CASE_KEY(GHOST_kKeyDownArrow, "DownArrow");
CASE_KEY(GHOST_kKeyPrintScreen, "PrintScreen");
CASE_KEY(GHOST_kKeyPause, "Pause");
CASE_KEY(GHOST_kKeyInsert, "Insert");
CASE_KEY(GHOST_kKeyDelete, "Delete");
CASE_KEY(GHOST_kKeyHome, "Home");
CASE_KEY(GHOST_kKeyEnd, "End");
CASE_KEY(GHOST_kKeyUpPage, "UpPage");
CASE_KEY(GHOST_kKeyDownPage, "DownPage");
CASE_KEY(GHOST_kKeyNumpadPeriod, "NumpadPeriod");
CASE_KEY(GHOST_kKeyNumpadEnter, "NumpadEnter");
CASE_KEY(GHOST_kKeyNumpadPlus, "NumpadPlus");
CASE_KEY(GHOST_kKeyNumpadMinus, "NumpadMinus");
CASE_KEY(GHOST_kKeyNumpadAsterisk, "NumpadAsterisk");
CASE_KEY(GHOST_kKeyNumpadSlash, "NumpadSlash");
CASE_KEY(GHOST_kKeyMediaPlay, "MediaPlayPause");
CASE_KEY(GHOST_kKeyMediaStop, "MediaStop");
CASE_KEY(GHOST_kKeyMediaFirst, "MediaFirst");
CASE_KEY(GHOST_kKeyMediaLast, "MediaLast");
CASE_KEY(GHOST_kKeyNumpad0, "Numpad 0");
CASE_KEY(GHOST_kKeyNumpad1, "Numpad 1");
CASE_KEY(GHOST_kKeyNumpad2, "Numpad 2");
CASE_KEY(GHOST_kKeyNumpad3, "Numpad 3");
CASE_KEY(GHOST_kKeyNumpad4, "Numpad 4");
CASE_KEY(GHOST_kKeyNumpad5, "Numpad 5");
CASE_KEY(GHOST_kKeyNumpad6, "Numpad 6");
CASE_KEY(GHOST_kKeyNumpad7, "Numpad 7");
CASE_KEY(GHOST_kKeyNumpad8, "Numpad 8");
CASE_KEY(GHOST_kKeyNumpad9, "Numpad 9");
CASE_KEY(GHOST_kKeyF1, "F1");
CASE_KEY(GHOST_kKeyF2, "F2");
CASE_KEY(GHOST_kKeyF3, "F3");
CASE_KEY(GHOST_kKeyF4, "F4");
CASE_KEY(GHOST_kKeyF5, "F5");
CASE_KEY(GHOST_kKeyF6, "F6");
CASE_KEY(GHOST_kKeyF7, "F7");
CASE_KEY(GHOST_kKeyF8, "F8");
CASE_KEY(GHOST_kKeyF9, "F9");
CASE_KEY(GHOST_kKeyF10, "F10");
CASE_KEY(GHOST_kKeyF11, "F11");
CASE_KEY(GHOST_kKeyF12, "F12");
CASE_KEY(GHOST_kKeyF13, "F13");
CASE_KEY(GHOST_kKeyF14, "F14");
CASE_KEY(GHOST_kKeyF15, "F15");
CASE_KEY(GHOST_kKeyF16, "F16");
CASE_KEY(GHOST_kKeyF17, "F17");
CASE_KEY(GHOST_kKeyF18, "F18");
CASE_KEY(GHOST_kKeyF19, "F19");
CASE_KEY(GHOST_kKeyF20, "F20");
CASE_KEY(GHOST_kKeyF21, "F21");
CASE_KEY(GHOST_kKeyF22, "F22");
CASE_KEY(GHOST_kKeyF23, "F23");
CASE_KEY(GHOST_kKeyF24, "F24");
CASE_KEY(GHOST_kKeyUnknown, "Unknown");
CASE_KEY(GHOST_kKeyComma, ",");
CASE_KEY(GHOST_kKeyMinus, "-");
CASE_KEY(GHOST_kKeyPlus, "=");
CASE_KEY(GHOST_kKeyPeriod, ".");
CASE_KEY(GHOST_kKeySlash, "/");
CASE_KEY(GHOST_kKey0, "0");
CASE_KEY(GHOST_kKey1, "1");
CASE_KEY(GHOST_kKey2, "2");
CASE_KEY(GHOST_kKey3, "3");
CASE_KEY(GHOST_kKey4, "4");
CASE_KEY(GHOST_kKey5, "5");
CASE_KEY(GHOST_kKey6, "6");
CASE_KEY(GHOST_kKey7, "7");
CASE_KEY(GHOST_kKey8, "8");
CASE_KEY(GHOST_kKey9, "9");
CASE_KEY(GHOST_kKeySemicolon, ";");
CASE_KEY(GHOST_kKeyEqual, "=");
CASE_KEY(GHOST_kKeyA, "A");
CASE_KEY(GHOST_kKeyB, "B");
CASE_KEY(GHOST_kKeyC, "C");
CASE_KEY(GHOST_kKeyD, "D");
CASE_KEY(GHOST_kKeyE, "E");
CASE_KEY(GHOST_kKeyF, "F");
CASE_KEY(GHOST_kKeyG, "G");
CASE_KEY(GHOST_kKeyH, "H");
CASE_KEY(GHOST_kKeyI, "I");
CASE_KEY(GHOST_kKeyJ, "J");
CASE_KEY(GHOST_kKeyK, "K");
CASE_KEY(GHOST_kKeyL, "L");
CASE_KEY(GHOST_kKeyM, "M");
CASE_KEY(GHOST_kKeyN, "N");
CASE_KEY(GHOST_kKeyO, "O");
CASE_KEY(GHOST_kKeyP, "P");
CASE_KEY(GHOST_kKeyQ, "Q");
CASE_KEY(GHOST_kKeyR, "R");
CASE_KEY(GHOST_kKeyS, "S");
CASE_KEY(GHOST_kKeyT, "T");
CASE_KEY(GHOST_kKeyU, "U");
CASE_KEY(GHOST_kKeyV, "V");
CASE_KEY(GHOST_kKeyW, "W");
CASE_KEY(GHOST_kKeyX, "X");
CASE_KEY(GHOST_kKeyY, "Y");
CASE_KEY(GHOST_kKeyZ, "Z");
CASE_KEY(GHOST_kKeyLeftBracket, "[");
CASE_KEY(GHOST_kKeyRightBracket, "]");
}
#undef CASE_KEY
/* Shouldn't happen (the value is not known to #GHOST_TKey). */
if (tstr == nullptr) {
tstr = "Invalid";
}
return tstr;
}

View File

@ -30,5 +30,5 @@ class GHOST_EventPrinter : public GHOST_IEventConsumer {
* \param key: The GHOST key code to convert.
* \param str: The GHOST key code converted to a readable string.
*/
void getKeyString(GHOST_TKey key, char str[32]) const;
const char *getKeyString(GHOST_TKey key) const;
};

File diff suppressed because it is too large Load Diff

View File

@ -89,10 +89,19 @@ void ghost_wl_dynload_libraries_exit();
#endif
struct GWL_Output {
/** Wayland core types. */
struct {
wl_output *output = nullptr;
} wl;
/** XDG native types. */
struct {
struct zxdg_output_v1 *output = nullptr;
} xdg;
GHOST_SystemWayland *system = nullptr;
struct wl_output *wl_output = nullptr;
struct zxdg_output_v1 *xdg_output = nullptr;
/** Dimensions in pixels. */
int32_t size_native[2] = {0, 0};
/** Dimensions in millimeter. */

View File

@ -126,7 +126,7 @@ static void initRawInput()
/* Success. */
}
else {
GHOST_PRINTF("could not register for RawInput: %d\n", (int)GetLastError());
GHOST_PRINTF("could not register for RawInput: %d\n", int(GetLastError()));
}
#undef DEVICE_COUNT
}
@ -178,7 +178,7 @@ uint64_t GHOST_SystemWin32::performanceCounterToMillis(__int64 perf_ticks) const
/* Calculate the time passed since system initialization. */
__int64 delta = (perf_ticks - m_start) * 1000;
uint64_t t = (uint64_t)(delta / m_freq);
uint64_t t = uint64_t(delta / m_freq);
return t;
}

View File

@ -1244,8 +1244,9 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
const XFocusChangeEvent &xfe = xe->xfocus;
/* TODO: make sure this is the correct place for activate/deactivate */
// printf("X: focus %s for window %d\n",
// xfe.type == FocusIn ? "in" : "out", (int) xfe.window);
#if 0
printf("X: focus %s for window %d\n", xfe.type == FocusIn ? "in" : "out", int(xfe.window));
#endif
/* May have to look at the type of event and filter some out. */
@ -1339,8 +1340,10 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
window->GetTabletData());
}
// printf("X: %s window %d\n",
// xce.type == EnterNotify ? "entering" : "leaving", (int) xce.window);
#if 0
printf(
"X: %s window %d\n", xce.type == EnterNotify ? "entering" : "leaving", int(xce.window));
#endif
if (xce.type == EnterNotify) {
m_windowManager->setActiveWindow(window);
@ -1482,7 +1485,7 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
window->GetTabletData().Pressure = axis_value / float(xtablet.PressureLevels);
}
/* NOTE(@broken): the (short) cast and the & 0xffff is bizarre and unexplained anywhere,
/* NOTE(@broken): the `short` cast and the & 0xffff is bizarre and unexplained anywhere,
* but I got garbage data without it. Found it in the `xidump.c` source.
*
* NOTE(@mont29): The '& 0xffff' just truncates the value to its two lowest bytes,

View File

@ -212,9 +212,33 @@ struct GWL_WindowFrame {
};
struct GWL_Window {
/** Wayland core types. */
struct {
wl_surface *surface = nullptr;
wl_egl_window *egl_window = nullptr;
} wl;
/** Wayland native types. */
struct {
wp_viewport *viewport = nullptr;
/**
* When set, only respond to the #wp_fractional_scale_v1_listener::preferred_scale callback
* and ignore updated scale based on #wl_surface_listener::enter & exit events.
*/
wp_fractional_scale_v1 *fractional_scale_handle = nullptr;
} wp;
/** XDG native types. */
struct {
/** A temporary token used for the window to be notified of it's activation. */
xdg_activation_token_v1 *activation_token = nullptr;
} xdg;
GHOST_WindowWayland *ghost_window = nullptr;
GHOST_SystemWayland *ghost_system = nullptr;
struct wl_surface *wl_surface = nullptr;
/**
* Outputs on which the window is currently shown on.
*
@ -223,16 +247,6 @@ struct GWL_Window {
*/
std::vector<GWL_Output *> outputs;
/** A temporary token used for the window to be notified of it's activation. */
xdg_activation_token_v1 *xdg_activation_token = nullptr;
wp_viewport *viewport = nullptr;
/**
* When set, only respond to the #wp_fractional_scale_v1_listener::preferred_scale callback
* and ignore updated scale based on #wl_surface_listener::enter & exit events.
*/
wp_fractional_scale_v1 *fractional_scale_handle = nullptr;
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
WGL_LibDecor_Window *libdecor = nullptr;
#endif
@ -253,8 +267,6 @@ struct GWL_Window {
std::mutex frame_pending_mutex;
#endif
wl_egl_window *egl_window = nullptr;
std::string title;
bool is_dialog = false;
@ -447,15 +459,15 @@ static bool gwl_window_viewport_set(GWL_Window *win,
bool *r_surface_needs_commit,
bool *r_surface_needs_buffer_scale)
{
if (win->viewport != nullptr) {
if (win->wp.viewport != nullptr) {
return false;
}
wp_viewporter *viewporter = win->ghost_system->wp_viewporter();
if (viewporter == nullptr) {
return false;
}
win->viewport = wp_viewporter_get_viewport(viewporter, win->wl_surface);
if (win->viewport == nullptr) {
win->wp.viewport = wp_viewporter_get_viewport(viewporter, win->wl.surface);
if (win->wp.viewport == nullptr) {
return false;
}
@ -467,14 +479,14 @@ static bool gwl_window_viewport_set(GWL_Window *win,
*r_surface_needs_buffer_scale = true;
}
else {
wl_surface_set_buffer_scale(win->wl_surface, win->frame.buffer_scale);
wl_surface_set_buffer_scale(win->wl.surface, win->frame.buffer_scale);
}
if (r_surface_needs_commit) {
*r_surface_needs_commit = true;
}
else {
wl_surface_commit(win->wl_surface);
wl_surface_commit(win->wl.surface);
}
}
@ -485,12 +497,12 @@ static bool gwl_window_viewport_unset(GWL_Window *win,
bool *r_surface_needs_commit,
bool *r_surface_needs_buffer_scale)
{
if (win->viewport == nullptr) {
if (win->wp.viewport == nullptr) {
return false;
}
wp_viewport_destroy(win->viewport);
win->viewport = nullptr;
wp_viewport_destroy(win->wp.viewport);
win->wp.viewport = nullptr;
GHOST_ASSERT(win->frame.buffer_scale == 1, "Unexpected scale!");
if (win->frame_pending.buffer_scale != win->frame.buffer_scale) {
@ -500,14 +512,14 @@ static bool gwl_window_viewport_unset(GWL_Window *win,
*r_surface_needs_buffer_scale = true;
}
else {
wl_surface_set_buffer_scale(win->wl_surface, win->frame.buffer_scale);
wl_surface_set_buffer_scale(win->wl.surface, win->frame.buffer_scale);
}
if (r_surface_needs_commit) {
*r_surface_needs_commit = true;
}
else {
wl_surface_commit(win->wl_surface);
wl_surface_commit(win->wl.surface);
}
}
return true;
@ -515,16 +527,16 @@ static bool gwl_window_viewport_unset(GWL_Window *win,
static bool gwl_window_viewport_size_update(GWL_Window *win)
{
if (win->viewport == nullptr) {
if (win->wp.viewport == nullptr) {
return false;
}
wp_viewport_set_source(win->viewport,
wp_viewport_set_source(win->wp.viewport,
wl_fixed_from_int(0),
wl_fixed_from_int(0),
wl_fixed_from_int(win->frame.size[0]),
wl_fixed_from_int(win->frame.size[1]));
wp_viewport_set_destination(
win->viewport,
win->wp.viewport,
gwl_window_fractional_from_viewport_round(win->frame, win->frame.size[0]),
gwl_window_fractional_from_viewport_round(win->frame, win->frame.size[1]));
return true;
@ -550,23 +562,23 @@ static void gwl_window_activate(GWL_Window *win)
return;
}
if (win->xdg_activation_token) {
if (win->xdg.activation_token) {
/* We're about to overwrite this with a new request. */
xdg_activation_token_v1_destroy(win->xdg_activation_token);
xdg_activation_token_v1_destroy(win->xdg.activation_token);
}
win->xdg_activation_token = xdg_activation_v1_get_activation_token(activation_manager);
win->xdg.activation_token = xdg_activation_v1_get_activation_token(activation_manager);
xdg_activation_token_v1_add_listener(
win->xdg_activation_token, xdg_activation_listener_get(), win);
win->xdg.activation_token, xdg_activation_listener_get(), win);
xdg_activation_token_v1_set_app_id(win->xdg_activation_token, GHOST_SystemWayland::xdg_app_id());
xdg_activation_token_v1_set_app_id(win->xdg.activation_token, GHOST_SystemWayland::xdg_app_id());
/* The serial of the input device requesting activation. */
{
uint32_t serial = 0;
wl_seat *seat = system->wl_seat_active_get_with_input_serial(serial);
if (seat) {
xdg_activation_token_v1_set_serial(win->xdg_activation_token, serial, seat);
xdg_activation_token_v1_set_serial(win->xdg.activation_token, serial, seat);
}
}
@ -577,12 +589,12 @@ static void gwl_window_activate(GWL_Window *win)
if (ghost_window_active) {
wl_surface *surface = ghost_window_active->wl_surface();
if (surface) {
xdg_activation_token_v1_set_surface(win->xdg_activation_token, surface);
xdg_activation_token_v1_set_surface(win->xdg.activation_token, surface);
}
}
}
xdg_activation_token_v1_commit(win->xdg_activation_token);
xdg_activation_token_v1_commit(win->xdg.activation_token);
}
/** \} */
@ -607,7 +619,7 @@ static void gwl_window_frame_pending_fractional_scale_set(GWL_Window *win,
gwl_window_viewport_size_update(win);
}
else {
if (win->viewport) {
if (win->wp.viewport) {
gwl_window_viewport_unset(win, r_surface_needs_commit, r_surface_needs_buffer_scale);
}
else {
@ -616,13 +628,13 @@ static void gwl_window_frame_pending_fractional_scale_set(GWL_Window *win,
*r_surface_needs_buffer_scale = true;
}
else {
wl_surface_set_buffer_scale(win->wl_surface, win->frame.buffer_scale);
wl_surface_set_buffer_scale(win->wl.surface, win->frame.buffer_scale);
}
if (r_surface_needs_commit) {
*r_surface_needs_commit = true;
}
else {
wl_surface_commit(win->wl_surface);
wl_surface_commit(win->wl.surface);
}
}
}
@ -654,7 +666,7 @@ static void gwl_window_frame_pending_size_set(GWL_Window *win,
*r_surface_needs_egl_resize = true;
}
else {
wl_egl_window_resize(win->egl_window, UNPACK2(win->frame.size), 0, 0);
wl_egl_window_resize(win->wl.egl_window, UNPACK2(win->frame.size), 0, 0);
}
win->ghost_window->notify_size();
@ -703,7 +715,7 @@ static void gwl_window_pending_actions_handle(GWL_Window *win)
win->ghost_window->outputs_changed_update_scale();
}
if (actions[PENDING_WINDOW_SURFACE_COMMIT]) {
wl_surface_commit(win->wl_surface);
wl_surface_commit(win->wl.surface);
}
}
@ -747,11 +759,11 @@ static void gwl_window_frame_update_from_pending_no_lock(GWL_Window *win)
}
if (surface_needs_egl_resize) {
wl_egl_window_resize(win->egl_window, UNPACK2(win->frame.size), 0, 0);
wl_egl_window_resize(win->wl.egl_window, UNPACK2(win->frame.size), 0, 0);
}
if (surface_needs_buffer_scale) {
wl_surface_set_buffer_scale(win->wl_surface, win->frame.buffer_scale);
wl_surface_set_buffer_scale(win->wl.surface, win->frame.buffer_scale);
}
if (win->xdg_decor) {
@ -771,7 +783,7 @@ static void gwl_window_frame_update_from_pending_no_lock(GWL_Window *win)
/* Postponing the commit avoids flickering when moving between monitors of different scale. */
gwl_window_pending_actions_tag(win, PENDING_WINDOW_SURFACE_COMMIT);
#else
wl_surface_commit(win->wl_surface);
wl_surface_commit(win->wl.surface);
#endif
}
@ -979,15 +991,15 @@ static void xdg_activation_handle_done(void *data,
const char *token)
{
GWL_Window *win = static_cast<GWL_Window *>(data);
if (xdg_activation_token_v1 != win->xdg_activation_token) {
if (xdg_activation_token_v1 != win->xdg.activation_token) {
return;
}
GHOST_SystemWayland *system = win->ghost_system;
xdg_activation_v1 *activation_manager = system->xdg_activation_manager();
xdg_activation_v1_activate(activation_manager, token, win->wl_surface);
xdg_activation_token_v1_destroy(win->xdg_activation_token);
win->xdg_activation_token = nullptr;
xdg_activation_v1_activate(activation_manager, token, win->wl.surface);
xdg_activation_token_v1_destroy(win->xdg.activation_token);
win->xdg.activation_token = nullptr;
}
static const xdg_activation_token_v1_listener xdg_activation_listener = {
@ -1338,22 +1350,22 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system,
window_->is_dialog = is_dialog;
/* Window surfaces. */
window_->wl_surface = wl_compositor_create_surface(system_->wl_compositor());
ghost_wl_surface_tag(window_->wl_surface);
window_->wl.surface = wl_compositor_create_surface(system_->wl_compositor());
ghost_wl_surface_tag(window_->wl.surface);
wl_surface_set_buffer_scale(window_->wl_surface, window_->frame.buffer_scale);
wl_surface_set_buffer_scale(window_->wl.surface, window_->frame.buffer_scale);
wl_surface_add_listener(window_->wl_surface, &wl_surface_listener, window_);
wl_surface_add_listener(window_->wl.surface, &wl_surface_listener, window_);
window_->egl_window = wl_egl_window_create(
window_->wl_surface, int(window_->frame.size[0]), int(window_->frame.size[1]));
window_->wl.egl_window = wl_egl_window_create(
window_->wl.surface, int(window_->frame.size[0]), int(window_->frame.size[1]));
wp_fractional_scale_manager_v1 *fractional_scale_manager = system->wp_fractional_scale_manager();
if (fractional_scale_manager) {
window_->fractional_scale_handle = wp_fractional_scale_manager_v1_get_fractional_scale(
fractional_scale_manager, window_->wl_surface);
window_->wp.fractional_scale_handle = wp_fractional_scale_manager_v1_get_fractional_scale(
fractional_scale_manager, window_->wl.surface);
wp_fractional_scale_v1_add_listener(
window_->fractional_scale_handle, &wp_fractional_scale_listener, window_);
window_->wp.fractional_scale_handle, &wp_fractional_scale_listener, window_);
}
/* NOTE: The limit is in points (not pixels) so Hi-DPI will limit to larger number of pixels.
@ -1371,7 +1383,7 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system,
/* create window decorations */
decor.frame = libdecor_decorate(
system_->libdecor_context(), window_->wl_surface, &libdecor_frame_iface, window_);
system_->libdecor_context(), window_->wl.surface, &libdecor_frame_iface, window_);
libdecor_frame_map(window_->libdecor->frame);
libdecor_frame_set_min_content_size(decor.frame, UNPACK2(size_min));
@ -1388,7 +1400,7 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system,
{
window_->xdg_decor = new WGL_XDG_Decor_Window;
WGL_XDG_Decor_Window &decor = *window_->xdg_decor;
decor.surface = xdg_wm_base_get_xdg_surface(system_->xdg_decor_shell(), window_->wl_surface);
decor.surface = xdg_wm_base_get_xdg_surface(system_->xdg_decor_shell(), window_->wl.surface);
decor.toplevel = xdg_surface_get_toplevel(decor.surface);
xdg_toplevel_set_min_size(decor.toplevel, UNPACK2(size_min));
@ -1415,10 +1427,10 @@ GHOST_WindowWayland::GHOST_WindowWayland(GHOST_SystemWayland *system,
gwl_window_title_set(window_, title);
wl_surface_set_user_data(window_->wl_surface, this);
wl_surface_set_user_data(window_->wl.surface, this);
/* Call top-level callbacks. */
wl_surface_commit(window_->wl_surface);
wl_surface_commit(window_->wl.surface);
wl_display_roundtrip(system_->wl_display());
#ifdef GHOST_OPENGL_ALPHA
@ -1480,7 +1492,7 @@ GHOST_TSuccess GHOST_WindowWayland::setWindowCursorGrab(GHOST_TGrabCursorMode mo
m_cursorGrabInitPos,
bounds,
m_cursorGrabAxis,
window_->wl_surface,
window_->wl.surface,
this->scale_params()))
{
return GHOST_kSuccess;
@ -1599,21 +1611,21 @@ GHOST_WindowWayland::~GHOST_WindowWayland()
releaseNativeHandles();
wl_egl_window_destroy(window_->egl_window);
wl_egl_window_destroy(window_->wl.egl_window);
if (window_->xdg_activation_token) {
xdg_activation_token_v1_destroy(window_->xdg_activation_token);
window_->xdg_activation_token = nullptr;
if (window_->xdg.activation_token) {
xdg_activation_token_v1_destroy(window_->xdg.activation_token);
window_->xdg.activation_token = nullptr;
}
if (window_->fractional_scale_handle) {
wp_fractional_scale_v1_destroy(window_->fractional_scale_handle);
window_->fractional_scale_handle = nullptr;
if (window_->wp.fractional_scale_handle) {
wp_fractional_scale_v1_destroy(window_->wp.fractional_scale_handle);
window_->wp.fractional_scale_handle = nullptr;
}
if (window_->viewport) {
wp_viewport_destroy(window_->viewport);
window_->viewport = nullptr;
if (window_->wp.viewport) {
wp_viewport_destroy(window_->wp.viewport);
window_->wp.viewport = nullptr;
}
#ifdef WITH_GHOST_WAYLAND_LIBDECOR
@ -1628,9 +1640,9 @@ GHOST_WindowWayland::~GHOST_WindowWayland()
/* Clear any pointers to this window. This is needed because there are no guarantees
* that flushing the display will the "leave" handlers before handling events. */
system_->window_surface_unref(window_->wl_surface);
system_->window_surface_unref(window_->wl.surface);
wl_surface_destroy(window_->wl_surface);
wl_surface_destroy(window_->wl.surface);
/* NOTE(@ideasman42): Flushing will often run the appropriate handlers event
* (#wl_surface_listener.leave in particular) to avoid attempted access to the freed surfaces.
@ -1744,7 +1756,7 @@ void GHOST_WindowWayland::setOpaque() const
/* Make the window opaque. */
region = wl_compositor_create_region(system_->wl_compositor());
wl_region_add(region, 0, 0, UNPACK2(window_->size));
wl_surface_set_opaque_region(window_->wl_surface, region);
wl_surface_set_opaque_region(window_->wl.surface, region);
wl_region_destroy(region);
}
#endif
@ -1763,8 +1775,8 @@ GHOST_Context *GHOST_WindowWayland::newDrawingContext(GHOST_TDrawingContextType
GHOST_kVulkanPlatformWayland,
0,
nullptr,
window_->wl_surface,
system_->wl_display(),
window_->wl.surface,
system_->wl.display(),
1,
2,
true);
@ -1781,7 +1793,7 @@ GHOST_Context *GHOST_WindowWayland::newDrawingContext(GHOST_TDrawingContextType
for (int minor = 6; minor >= 3; --minor) {
GHOST_Context *context = new GHOST_ContextEGL(system_,
m_wantStereoVisual,
EGLNativeWindowType(window_->egl_window),
EGLNativeWindowType(window_->wl.egl_window),
EGLNativeDisplayType(system_->wl_display()),
EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT,
4,
@ -1847,7 +1859,7 @@ wl_fixed_t GHOST_WindowWayland::wl_fixed_to_window(wl_fixed_t value) const
wl_surface *GHOST_WindowWayland::wl_surface() const
{
return window_->wl_surface;
return window_->wl.surface;
}
const std::vector<GWL_Output *> &GHOST_WindowWayland::outputs()
@ -1980,7 +1992,7 @@ bool GHOST_WindowWayland::outputs_changed_update_scale()
return false;
}
if (window_->fractional_scale_handle) {
if (window_->wp.fractional_scale_handle) {
#ifdef USE_EVENT_BACKGROUND_THREAD
std::lock_guard lock_frame_guard{window_->frame_pending_mutex};
#endif

View File

@ -423,7 +423,7 @@ GHOST_TSuccess GHOST_WindowWin32::setClientWidth(uint32_t width)
GHOST_TSuccess success;
GHOST_Rect cBnds, wBnds;
getClientBounds(cBnds);
if (cBnds.getWidth() != (int32_t)width) {
if (cBnds.getWidth() != int32_t(width)) {
getWindowBounds(wBnds);
int cx = wBnds.getWidth() + width - cBnds.getWidth();
int cy = wBnds.getHeight();
@ -442,7 +442,7 @@ GHOST_TSuccess GHOST_WindowWin32::setClientHeight(uint32_t height)
GHOST_TSuccess success;
GHOST_Rect cBnds, wBnds;
getClientBounds(cBnds);
if (cBnds.getHeight() != (int32_t)height) {
if (cBnds.getHeight() != int32_t(height)) {
getWindowBounds(wBnds);
int cx = wBnds.getWidth();
int cy = wBnds.getHeight() + height - cBnds.getHeight();
@ -461,7 +461,7 @@ GHOST_TSuccess GHOST_WindowWin32::setClientSize(uint32_t width, uint32_t height)
GHOST_TSuccess success;
GHOST_Rect cBnds, wBnds;
getClientBounds(cBnds);
if ((cBnds.getWidth() != (int32_t)width) || (cBnds.getHeight() != (int32_t)height)) {
if ((cBnds.getWidth() != int32_t(width)) || (cBnds.getHeight() != int32_t(height))) {
getWindowBounds(wBnds);
int cx = wBnds.getWidth() + width - cBnds.getWidth();
int cy = wBnds.getHeight() + height - cBnds.getHeight();

View File

@ -348,7 +348,7 @@ void GHOST_Wintab::getInput(std::vector<GHOST_WintabInfoWin32> &outWintabInfo)
*
* wintab.h defines orAltitude as a `uint` but documents orAltitude as positive for upward
* angles and negative for downward angles. WACOM uses negative altitude values to show that
* the pen is inverted; therefore we cast orAltitude as an (int) and then use the absolute
* the pen is inverted; therefore we cast orAltitude as an `int` and then use the absolute
* value.
*/

View File

@ -18,7 +18,7 @@ luma: [0.2126, 0.7152, 0.0722]
description: RRT version ut33
roles:
reference: Linear
reference: Linear CIE-XYZ E
# Internal scene linear space
scene_linear: Linear
@ -41,6 +41,7 @@ roles:
# For interop between configs, and to determine XYZ for rendering
aces_interchange: Linear ACES
cie_xyz_d65_interchange: Linear CIE-XYZ D65
# Specified by OCIO, not used in Blender
color_timing: Filmic Log
@ -61,6 +62,27 @@ active_displays: [sRGB]
active_views: [Standard, Filmic, Filmic Log, False Color, Raw]
colorspaces:
- !<ColorSpace>
name: Linear CIE-XYZ E
aliases: ["FilmLight: Linear - XYZ", Linear CIE-XYZ I-E]
family: Chromaticity
equalitygroup:
bitdepth: 32f
description: |
1931 CIE XYZ standard with assumed illuminant E white point
isdata: false
- !<ColorSpace>
name: Linear CIE-XYZ D65
aliases: [cie_xyz_d65, CIE-XYZ-D65, XYZ, Linear CIE-XYZ D65]
family: Chromaticity
equalitygroup:
bitdepth: 32f
description: |
1931 CIE XYZ with adapted illuminant D65 white point
isdata: false
from_scene_reference: !<FileTransform> {src: xyz_E_to_D65.spimtx, interpolation: linear}
- !<ColorSpace>
name: Linear
family: linear
@ -69,6 +91,10 @@ colorspaces:
description: |
Rec. 709 (Full Range), Blender native linear space
isdata: false
from_scene_reference: !<GroupTransform>
children:
- !<ColorSpaceTransform> {src: Linear CIE-XYZ E, dst: Linear CIE-XYZ D65}
- !<MatrixTransform> {matrix: [ 3.2410032329763587, -1.5373989694887855, -0.4986158819963629, 0, -0.9692242522025164, 1.8759299836951759, 0.0415542263400847, 0, 0.0556394198519755, -0.2040112061239099, 1.0571489771875333, 0, 0, 0, 0, 1]}
- !<ColorSpace>
name: Linear ACES
@ -80,7 +106,7 @@ colorspaces:
isdata: false
from_reference: !<GroupTransform>
children:
- !<FileTransform> {src: srgb_to_xyz.spimtx, interpolation: linear}
- !<ColorSpaceTransform> {src: Linear CIE-XYZ E, dst: Linear CIE-XYZ D65}
- !<BuiltinTransform> {style: "UTILITY - ACES-AP0_to_CIE-XYZ-D65_BFD", direction: inverse}
- !<ColorSpace>
@ -93,19 +119,9 @@ colorspaces:
isdata: false
from_reference: !<GroupTransform>
children:
- !<FileTransform> {src: srgb_to_xyz.spimtx, interpolation: linear}
- !<ColorSpaceTransform> {src: Linear CIE-XYZ E, dst: Linear CIE-XYZ D65}
- !<BuiltinTransform> {style: "UTILITY - ACES-AP1_to_CIE-XYZ-D65_BFD", direction: inverse}
- !<ColorSpace>
name: XYZ
family: linear
equalitygroup:
bitdepth: 32f
isdata: false
from_reference: !<GroupTransform>
children:
- !<FileTransform> {src: srgb_to_xyz.spimtx, interpolation: linear}
- !<ColorSpace>
name: sRGB
family:
@ -114,7 +130,10 @@ colorspaces:
description: |
sRGB display space
isdata: false
from_reference: !<ExponentWithLinearTransform> {gamma: 2.4, offset: 0.055, direction: inverse}
from_scene_reference: !<GroupTransform>
children:
- !<ColorSpaceTransform> {src: Linear CIE-XYZ E, dst: Linear}
- !<ExponentWithLinearTransform> {gamma: 2.4, offset: 0.055, direction: inverse}
- !<ColorSpace>
name: Non-Color
@ -135,11 +154,15 @@ colorspaces:
Log based filmic shaper with 16.5 stops of latitude, and 25 stops of dynamic range
isdata: false
from_reference: !<GroupTransform>
children:
- !<AllocationTransform> {allocation: lg2, vars: [-12.473931188, 12.526068812]}
- !<FileTransform> {src: filmic_desat65cube.spi3d, interpolation: best}
- !<AllocationTransform> {allocation: uniform, vars: [0, 0.66]}
to_reference: !<AllocationTransform> {allocation: lg2, vars: [-12.473931188, 4.026068812], direction: inverse}
children:
- !<ColorSpaceTransform> {src: Linear CIE-XYZ E, dst: Linear}
- !<AllocationTransform> {allocation: lg2, vars: [-12.473931188, 12.526068812]}
- !<FileTransform> {src: filmic_desat65cube.spi3d, interpolation: best}
- !<AllocationTransform> {allocation: uniform, vars: [0, 0.66]}
to_scene_reference: !<GroupTransform>
children:
- !<AllocationTransform> {allocation: lg2, vars: [-12.473931188, 4.026068812], direction: inverse}
- !<ColorSpaceTransform> {src: Linear CIE-XYZ E, dst: Linear, direction: inverse}
- !<ColorSpace>
name: Filmic sRGB
@ -150,9 +173,9 @@ colorspaces:
sRGB display space with Filmic view transform
isdata: false
from_reference: !<GroupTransform>
children:
- !<ColorSpaceTransform> {src: Linear, dst: Filmic Log}
- !<FileTransform> {src: filmic_to_0-70_1-03.spi1d, interpolation: linear}
children:
- !<ColorSpaceTransform> {src: Linear CIE-XYZ E, dst: Filmic Log}
- !<FileTransform> {src: filmic_to_0-70_1-03.spi1d, interpolation: linear}
- !<ColorSpace>
name: False Color
@ -163,61 +186,61 @@ colorspaces:
Filmic false color view transform
isdata: false
from_reference: !<GroupTransform>
children:
- !<ColorSpaceTransform> {src: Linear, dst: Filmic Log}
- !<MatrixTransform> {matrix: [0.2126729, 0.7151521, 0.0721750, 0, 0.2126729, 0.7151521, 0.0721750, 0, 0.2126729, 0.7151521, 0.0721750, 0, 0, 0, 0, 1]}
- !<FileTransform> {src: filmic_false_color.spi3d, interpolation: best}
children:
- !<ColorSpaceTransform> {src: Linear CIE-XYZ E, dst: Filmic Log}
- !<MatrixTransform> {matrix: [0.2126729, 0.7151521, 0.0721750, 0, 0.2126729, 0.7151521, 0.0721750, 0, 0.2126729, 0.7151521, 0.0721750, 0, 0, 0, 0, 1]}
- !<FileTransform> {src: filmic_false_color.spi3d, interpolation: best}
looks:
- !<Look>
name: Very High Contrast
process_space: Filmic Log
transform: !<GroupTransform>
children:
- !<FileTransform> {src: filmic_to_1.20_1-00.spi1d, interpolation: linear}
- !<FileTransform> {src: filmic_to_0-70_1-03.spi1d, interpolation: linear, direction: inverse}
children:
- !<FileTransform> {src: filmic_to_1.20_1-00.spi1d, interpolation: linear}
- !<FileTransform> {src: filmic_to_0-70_1-03.spi1d, interpolation: linear, direction: inverse}
- !<Look>
name: High Contrast
process_space: Filmic Log
transform: !<GroupTransform>
children:
- !<FileTransform> {src: filmic_to_0.99_1-0075.spi1d, interpolation: linear}
- !<FileTransform> {src: filmic_to_0-70_1-03.spi1d, interpolation: linear, direction: inverse}
children:
- !<FileTransform> {src: filmic_to_0.99_1-0075.spi1d, interpolation: linear}
- !<FileTransform> {src: filmic_to_0-70_1-03.spi1d, interpolation: linear, direction: inverse}
- !<Look>
name: Medium High Contrast
process_space: Filmic Log
transform: !<GroupTransform>
children:
- !<FileTransform> {src: filmic_to_0-85_1-011.spi1d, interpolation: best}
- !<FileTransform> {src: filmic_to_0-70_1-03.spi1d, interpolation: linear, direction: inverse}
children:
- !<FileTransform> {src: filmic_to_0-85_1-011.spi1d, interpolation: best}
- !<FileTransform> {src: filmic_to_0-70_1-03.spi1d, interpolation: linear, direction: inverse}
- !<Look>
name: Medium Contrast
process_space: Filmic Log
transform: !<GroupTransform>
children:
children:
- !<Look>
name: Medium Low Contrast
process_space: Filmic Log
transform: !<GroupTransform>
children:
- !<FileTransform> {src: filmic_to_0-60_1-04.spi1d, interpolation: linear}
- !<FileTransform> {src: filmic_to_0-70_1-03.spi1d, interpolation: linear, direction: inverse}
children:
- !<FileTransform> {src: filmic_to_0-60_1-04.spi1d, interpolation: linear}
- !<FileTransform> {src: filmic_to_0-70_1-03.spi1d, interpolation: linear, direction: inverse}
- !<Look>
name: Low Contrast
process_space: Filmic Log
transform: !<GroupTransform>
children:
- !<FileTransform> {src: filmic_to_0-48_1-09.spi1d, interpolation: linear}
- !<FileTransform> {src: filmic_to_0-70_1-03.spi1d, interpolation: linear, direction: inverse}
children:
- !<FileTransform> {src: filmic_to_0-48_1-09.spi1d, interpolation: linear}
- !<FileTransform> {src: filmic_to_0-70_1-03.spi1d, interpolation: linear, direction: inverse}
- !<Look>
name: Very Low Contrast
process_space: Filmic Log
transform: !<GroupTransform>
children:
- !<FileTransform> {src: filmic_to_0-35_1-30.spi1d, interpolation: linear}
- !<FileTransform> {src: filmic_to_0-70_1-03.spi1d, interpolation: linear, direction: inverse}
children:
- !<FileTransform> {src: filmic_to_0-35_1-30.spi1d, interpolation: linear}
- !<FileTransform> {src: filmic_to_0-70_1-03.spi1d, interpolation: linear, direction: inverse}

View File

@ -1,3 +0,0 @@
0.4124564 0.3575761 0.1804375 0
0.2126729 0.7151522 0.0721750 0
0.0193339 0.1191920 0.9503041 0

View File

@ -1,3 +0,0 @@
1.0521111 0.0000000 0.0000000 0
0.0000000 1.0000000 0.0000000 0
0.0000000 0.0000000 0.9184170 0

View File

@ -0,0 +1,3 @@
0.95318743 -0.02659057 0.02387315 0
-0.03824666 1.02884062 0.00940604 0
0.00260677 -0.00303325 1.08925647 0

View File

@ -79,6 +79,7 @@ const UserDef U_default = {
.scrollback = 256,
.node_margin = 80,
.node_preview_res = 120,
.transopts = USER_TR_TOOLTIPS,
.menuthreshold1 = 5,
.menuthreshold2 = 2,

View File

@ -23,24 +23,14 @@ addons_fake_modules = {}
# called only once at startup, avoids calling 'reset_all', correct but slower.
def _initialize():
path_list = paths()
for path in path_list:
def _initialize_once():
for path in paths():
_bpy.utils._sys_path_ensure_append(path)
# Original code:
# for addon in _preferences.addons:
# enable(addon.module)
# NOTE(@ideasman42): package support, may be implemented add-on (temporary for extension development).
addon_submodules = []
_initialize_extensions_repos_once()
for addon in _preferences.addons:
module = addon.module
if "." in module:
addon_submodules.append(module)
continue
enable(module)
for module in addon_submodules:
enable(module)
enable(addon.module)
def paths():
@ -56,6 +46,33 @@ def paths():
]
# A version of `paths` that includes extension repositories returning a list `(path, package)` pairs.
#
# Notes on the ``package`` value.
#
# - For top-level modules (the "addons" directories, the value is an empty string)
# because those add-ons can be imported directly.
# - For extension repositories the value is a module string (which can be imported for example)
# where any modules within the `path` can be imported as a sub-module.
# So for example, given a list value of: `("/tmp/repo", "bl_ext.temp_repo")`.
#
# An add-on located at `/tmp/repo/my_handy_addon.py` will have a unique module path of:
# `bl_ext.temp_repo.my_handy_addon`, which can be imported and will be the value of it's `Addon.module`.
def _paths_with_extension_repos():
import os
addon_paths = [(path, "") for path in paths()]
if _preferences.experimental.use_extension_repos:
for repo in _preferences.filepaths.extension_repos:
dirpath = repo.directory
if not os.path.isdir(dirpath):
continue
addon_paths.append((dirpath, "%s.%s" % (_ext_base_pkg_idname, repo.module)))
return addon_paths
def _fake_module(mod_name, mod_path, speedy=True, force_support=None):
global error_encoding
import os
@ -152,16 +169,14 @@ def modules_refresh(*, module_cache=addons_fake_modules):
error_encoding = False
error_duplicates.clear()
path_list = paths()
modules_stale = set(module_cache.keys())
for path in path_list:
for path, pkg_id in _paths_with_extension_repos():
# Force all user contributed add-ons to be 'TESTING'.
force_support = 'TESTING' if path.endswith("addons_contrib") else None
force_support = 'TESTING' if ((not pkg_id) and path.endswith("addons_contrib")) else None
for mod_name, mod_path in _bpy.path.module_names(path):
for mod_name, mod_path in _bpy.path.module_names(path, package=pkg_id):
modules_stale.discard(mod_name)
mod = module_cache.get(mod_name)
if mod:
@ -464,12 +479,11 @@ def reset_all(*, reload_scripts=False):
# initializes addons_fake_modules
modules_refresh()
# RELEASE SCRIPTS: official scripts distributed in Blender releases
paths_list = paths()
for path, pkg_id in _paths_with_extension_repos():
if not pkg_id:
_bpy.utils._sys_path_ensure_append(path)
for path in paths_list:
_bpy.utils._sys_path_ensure_append(path)
for mod_name, _mod_path in _bpy.path.module_names(path):
for mod_name, _mod_path in _bpy.path.module_names(path, package=pkg_id):
is_enabled, is_loaded = check(mod_name)
# first check if reload is needed before changing state.
@ -548,3 +562,162 @@ def module_bl_info(mod, *, info_basis=None):
addon_info["_init"] = None
return addon_info
# -----------------------------------------------------------------------------
# Extensions
# Module-like class, store singletons.
class _ext_global:
__slots__ = ()
# Store a map of `preferences.filepaths.extension_repos` -> `module_id`.
# Only needed to detect renaming between `bpy.app.handlers.extension_repos_update_{pre & post}` events.
idmap = {}
# The base package created by `JunctionModuleHandle`.
module_handle = None
# The name (in `sys.modules`) keep this short because it's stored as part of add-on modules name.
_ext_base_pkg_idname = "bl_ext"
def _extension_preferences_idmap():
repos_idmap = {}
if _preferences.experimental.use_extension_repos:
for repo in _preferences.filepaths.extension_repos:
repos_idmap[repo.as_pointer()] = repo.module
return repos_idmap
def _extension_dirpath_from_preferences():
repos_dict = {}
if _preferences.experimental.use_extension_repos:
for repo in _preferences.filepaths.extension_repos:
repos_dict[repo.module] = repo.directory
return repos_dict
def _extension_dirpath_from_handle():
repos_info = {}
for module_id, module in _ext_global.module_handle.submodule_items():
# Account for it being unset although this should never happen unless script authors
# meddle with the modules.
try:
dirpath = module.__path__[0]
except BaseException:
dirpath = ""
repos_info[module_id] = dirpath
return repos_info
# Use `bpy.app.handlers.extension_repos_update_{pre/post}` to track changes to extension repositories
# and sync the changes to the Python module.
@_bpy.app.handlers.persistent
def _initialize_extension_repos_pre(*_):
_ext_global.idmap = _extension_preferences_idmap()
@_bpy.app.handlers.persistent
def _initialize_extension_repos_post(*_):
# Map `module_id` -> `dirpath`.
repos_info_prev = _extension_dirpath_from_handle()
repos_info_next = _extension_dirpath_from_preferences()
# Map `repo.as_pointer()` -> `module_id`.
repos_idmap_prev = _ext_global.idmap
repos_idmap_next = _extension_preferences_idmap()
# Map `module_id` -> `repo.as_pointer()`.
repos_idmap_next_reverse = {value: key for key, value in repos_idmap_next.items()}
# Mainly needed when the `preferences.experimental.use_extension_repos` option is enabled at run-time.
#
# Filter `repos_idmap_prev` so only items which were also in the `repos_info_prev` are included.
# This is an awkward situation, they should be in sync, however when enabling the experimental option
# means the preferences wont have changed, but the module will not be in sync with the preferences.
# Support this by removing items in `repos_idmap_prev` which aren't also initialized in the managed package.
#
# The only situation this would be useful to keep is if we want to support renaming a package
# that manipulates all add-ons using it, when those add-ons are in the preferences but have not had
# their package loaded. It's possible we want to do this but is also reasonably obscure.
for repo_id_prev, module_id_prev in list(repos_idmap_prev.items()):
if module_id_prev not in repos_info_prev:
del repos_idmap_prev[repo_id_prev]
# NOTE(@ideasman42): supporting renaming at all is something we might limit to extensions
# which have no add-ons loaded as supporting renaming add-ons in-place seems error prone as the add-on
# may define internal variables based on the full package path.
submodules_add = [] # List of module names to add: `(module_id, dirpath)`.
submodules_del = [] # List of module names to remove: `module_id`.
submodules_rename_module = [] # List of module names: `(module_id_src, module_id_dst)`.
submodules_rename_dirpath = [] # List of module names: `(module_id, dirpath)`.
renamed_prev = set()
renamed_next = set()
# Detect rename modules & module directories.
for module_id_next, dirpath_next in repos_info_next.items():
# Lookup never fails, as the "next" values use: `preferences.filepaths.extension_repos`.
repo_id = repos_idmap_next_reverse[module_id_next]
# Lookup may fail if this is a newly added module.
# Don't attempt to setup `submodules_add` though as it's possible
# the module name persists while the underlying `repo_id` changes.
module_id_prev = repos_idmap_prev.get(repo_id)
if module_id_prev is None:
continue
# Detect rename.
if module_id_next != module_id_prev:
submodules_rename_module.append((module_id_prev, module_id_next))
renamed_prev.add(module_id_prev)
renamed_next.add(module_id_next)
# Detect `dirpath` change.
if dirpath_next != repos_info_prev[module_id_prev]:
submodules_rename_dirpath.append((module_id_next, dirpath_next))
# Detect added modules.
for module_id, dirpath in repos_info_next.items():
if (module_id not in repos_info_prev) and (module_id not in renamed_next):
submodules_add.append((module_id, dirpath))
# Detect deleted modules.
for module_id, _dirpath in repos_info_prev.items():
if (module_id not in repos_info_next) and (module_id not in renamed_prev):
submodules_del.append(module_id)
# Apply changes to the `_ext_base_pkg_idname` named module so it matches extension data from the preferences.
module_handle = _ext_global.module_handle
for module_id in submodules_del:
module_handle.unregister_submodule(module_id)
for module_id, dirpath in submodules_add:
module_handle.register_submodule(module_id, dirpath)
for module_id_prev, module_id_next in submodules_rename_module:
module_handle.rename_submodule(module_id_prev, module_id_next)
for module_id, dirpath in submodules_rename_dirpath:
module_handle.rename_directory(module_id, dirpath)
_ext_global.idmap.clear()
# Force refreshing if directory paths change.
if submodules_del or submodules_add or submodules_rename_dirpath:
modules._is_first = True
def _initialize_extensions_repos_once():
from bpy_extras.extensions.junction_module import JunctionModuleHandle
module_handle = JunctionModuleHandle(_ext_base_pkg_idname)
module_handle.register_module()
_ext_global.module_handle = module_handle
# Setup repositories for the first time.
# Intentionally don't call `_initialize_extension_repos_pre` as this is the first time,
# the previous state is not useful to read.
_initialize_extension_repos_post()
# Internal handlers intended for Blender's own handling of repositories.
_bpy.app.handlers._extension_repos_update_pre.append(_initialize_extension_repos_pre)
_bpy.app.handlers._extension_repos_update_post.append(_initialize_extension_repos_post)

View File

@ -355,7 +355,7 @@ def ensure_ext(filepath, ext, *, case_sensitive=False):
return filepath + ext
def module_names(path, *, recursive=False):
def module_names(path, *, recursive=False, package=""):
"""
Return a list of modules which can be imported from *path*.
@ -363,6 +363,8 @@ def module_names(path, *, recursive=False):
:type path: string
:arg recursive: Also return submodule names for packages.
:type recursive: bool
:arg package: Optional string, used as the prefix for module names (without the trailing ".").
:type package: string
:return: a list of string pairs (module_name, module_file).
:rtype: list of strings
"""
@ -371,22 +373,24 @@ def module_names(path, *, recursive=False):
modules = []
pacakge_prefix = (package + ".") if package else ""
for filename in sorted(_os.listdir(path)):
if filename == "modules":
if (filename == "modules") and (not pacakge_prefix):
pass # XXX, hard coded exception.
elif filename.endswith(".py") and filename != "__init__.py":
fullpath = join(path, filename)
modules.append((filename[0:-3], fullpath))
modules.append((pacakge_prefix + filename[0:-3], fullpath))
elif not filename.startswith("."):
# Skip hidden files since they are used by for version control.
directory = join(path, filename)
fullpath = join(directory, "__init__.py")
if isfile(fullpath):
modules.append((filename, fullpath))
modules.append((pacakge_prefix + filename, fullpath))
if recursive:
for mod_name, mod_path in module_names(directory, recursive=True):
modules.append((
"%s.%s" % (filename, mod_name),
"%s.%s" % (pacakge_prefix + filename, mod_name),
mod_path,
))

View File

@ -305,15 +305,15 @@ def load_scripts(*, reload_scripts=False, refresh_scripts=False):
bl_app_template_utils.reset(reload_scripts=reload_scripts)
del bl_app_template_utils
# deal with addons separately
_initialize = getattr(_addon_utils, "_initialize", None)
if _initialize is not None:
# first time, use fast-path
_initialize()
del _addon_utils._initialize
# Deal with add-ons separately.
_initialize_once = getattr(_addon_utils, "_initialize_once", None)
if _initialize_once is not None:
# First time, use fast-path.
_initialize_once()
del _addon_utils._initialize_once
else:
_addon_utils.reset_all(reload_scripts=reload_scripts)
del _initialize
del _initialize_once
if reload_scripts:
_bpy.context.window_manager.tag_script_reload()

View File

@ -0,0 +1,146 @@
# SPDX-FileCopyrightText: 2023 Blender Foundation
#
# SPDX-License-Identifier: GPL-2.0-or-later
"""
JunctionModuleHandle creates a module whose sub-modules are not located
in the same directory on the file-system as usual. Instead the sub-modules are
added into the package from different locations on the file-system.
The ``JunctionModuleHandle`` class is used to manipulate sub-modules at run-time.
This is needed to implement package management functionality, repositories can be added/removed at run-time.
"""
__all__ = (
"JunctionModuleHandle",
)
import sys
from types import ModuleType
from typing import (
Dict,
Optional,
Sequence,
Tuple,
)
def _module_file_set(module: ModuleType, name_full: str) -> None:
# File is just an identifier, as this doesn't reference an actual file,
# it just needs to be descriptive.
module.__name__ = name_full
module.__package__ = name_full
module.__file__ = "[{:s}]".format(name_full)
def _module_create(
name: str,
*,
parent: Optional[ModuleType] = None,
doc: Optional[str] = None,
) -> ModuleType:
if parent is not None:
name_full = parent.__name__ + "." + name
else:
name_full = name
module = ModuleType(name, doc)
_module_file_set(module, name_full)
if parent is not None:
setattr(parent, name, module)
return module
class JunctionModuleHandle:
__slots__ = (
"_module_name",
"_module",
"_submodules",
)
def __init__(self, module_name: str):
self._module_name: str = module_name
self._module: Optional[ModuleType] = None
self._submodules: Dict[str, ModuleType] = {}
def submodule_items(self) -> Sequence[Tuple[str, ModuleType]]:
return tuple(self._submodules.items())
def register_module(self) -> ModuleType:
"""
Register the base module in ``sys.modules``.
"""
if self._module is not None:
raise Exception("Module {!r} already registered!".format(self._module))
if self._module_name in sys.modules:
raise Exception("Module {:s} already in 'sys.modules'!".format(self._module_name))
module = _module_create(self._module_name)
sys.modules[self._module_name] = module
# Differentiate this, and allow access to the factory (may be useful).
# `module.__module_factory__ = self`
self._module = module
return module
def unregister_module(self) -> None:
"""
Unregister the base module in ``sys.modules``.
Keep everything except the modules name (allowing re-registration).
"""
# Cleanup `sys.modules`.
sys.modules.pop(self._module_name, None)
for submodule_name in self._submodules.keys():
sys.modules.pop("{:s}.{:s}".format(self._module_name, submodule_name), None)
# Remove from self.
self._submodules.clear()
self._module = None
def register_submodule(self, submodule_name: str, dirpath: str) -> ModuleType:
name_full = self._module_name + "." + submodule_name
if self._module is None:
raise Exception("Module not registered, cannot register a submodule!")
if submodule_name in self._submodules:
raise Exception("Module \"{:s}\" already registered!".format(submodule_name))
# Register.
submodule = _module_create(submodule_name, parent=self._module)
sys.modules[name_full] = submodule
submodule.__path__ = [dirpath]
setattr(self._module, submodule_name, submodule)
self._submodules[submodule_name] = submodule
return submodule
def unregister_submodule(self, submodule_name: str) -> None:
name_full = self._module_name + "." + submodule_name
if self._module is None:
raise Exception("Module not registered, cannot register a submodule!")
# Unregister.
submodule = self._submodules.pop(submodule_name, None)
if submodule is None:
raise Exception("Module \"{:s}\" not registered!".format(submodule_name))
delattr(self._module, submodule_name)
del sys.modules[name_full]
def rename_submodule(self, submodule_name_src: str, submodule_name_dst: str) -> None:
name_full_prev = self._module_name + "." + submodule_name_src
name_full_next = self._module_name + "." + submodule_name_dst
submodule = self._submodules.pop(submodule_name_src)
self._submodules[submodule_name_dst] = submodule
delattr(self._module, submodule_name_src)
setattr(self._module, submodule_name_dst, submodule)
_module_file_set(submodule, name_full_next)
del sys.modules[name_full_prev]
sys.modules[name_full_next] = submodule
def rename_directory(self, submodule_name: str, dirpath: str) -> None:
# TODO: how to deal with existing loaded modules?
# In practice this is mostly users setting up directories for the first time.
submodule = self._submodules[submodule_name]
submodule.__path__ = [dirpath]

View File

@ -846,7 +846,7 @@ class NODE_PT_overlay(Panel):
col.prop(overlay, "show_context_path", text="Context Path")
col.prop(snode, "show_annotation", text="Annotations")
if snode.supports_preview:
if snode.supports_previews:
col.separator()
col.prop(overlay, "show_previews", text="Previews")

View File

@ -501,6 +501,7 @@ class USERPREF_PT_edit_misc(EditingPanel, CenterAlignMixIn, Panel):
col = layout.column()
col.prop(edit, "sculpt_paint_overlay_color", text="Sculpt Overlay Color")
col.prop(edit, "node_margin", text="Node Auto-Offset Margin")
col.prop(edit, "node_preview_resolution", text="Node Preview Resolution")
# -----------------------------------------------------------------------------
@ -1531,6 +1532,62 @@ class USERPREF_UL_asset_libraries(bpy.types.UIList):
layout.prop(asset_library, "name", text="", emboss=False)
class USERPREF_PT_file_paths_extension_repos(FilePathsPanel, Panel):
bl_label = "Extension Repositories"
@classmethod
def poll(cls, context):
return context.preferences.experimental.use_extension_repos
def draw(self, context):
layout = self.layout
layout.use_property_split = False
layout.use_property_decorate = False
paths = context.preferences.filepaths
active_library_index = paths.active_extension_repo
row = layout.row()
row.template_list(
"USERPREF_UL_extension_repos", "user_extension_repos",
paths, "extension_repos",
paths, "active_extension_repo"
)
col = row.column(align=True)
col.operator("preferences.extension_repo_add", text="", icon='ADD')
props = col.operator("preferences.extension_repo_remove", text="", icon='REMOVE')
props.index = active_library_index
try:
active_repo = None if active_library_index < 0 else paths.extension_repos[active_library_index]
except IndexError:
active_repo = None
if active_repo is None:
return
layout.separator()
layout.prop(active_repo, "directory")
layout.prop(active_repo, "remote_path")
row = layout.row()
row.prop(active_repo, "use_cache")
row.prop(active_repo, "module")
class USERPREF_UL_extension_repos(bpy.types.UIList):
def draw_item(self, _context, layout, _data, item, icon, _active_data, _active_propname, _index):
repo = item
if self.layout_type in {'DEFAULT', 'COMPACT'}:
layout.prop(repo, "name", text="", emboss=False)
elif self.layout_type == 'GRID':
layout.alignment = 'CENTER'
layout.prop(repo, "name", text="", emboss=False)
# -----------------------------------------------------------------------------
# Save/Load Panels
@ -2407,6 +2464,7 @@ class USERPREF_PT_experimental_new_features(ExperimentalPanel, Panel):
({"property": "use_new_volume_nodes"}, ("blender/blender/issues/103248", "#103248")),
({"property": "use_rotation_socket"}, ("/blender/blender/issues/92967", "#92967")),
({"property": "use_node_group_operators"}, ("/blender/blender/issues/101778", "#101778")),
({"property": "use_shader_node_previews"}, ("blender/blender/issues/110353", "#110353")),
),
)
@ -2425,6 +2483,7 @@ class USERPREF_PT_experimental_prototypes(ExperimentalPanel, Panel):
({"property": "enable_workbench_next"}, ("blender/blender/issues/101619", "#101619")),
({"property": "use_grease_pencil_version3"}, ("blender/blender/projects/6", "Grease Pencil 3.0")),
({"property": "enable_overlay_next"}, ("blender/blender/issues/102179", "#102179")),
({"property": "use_extension_repos"}, ("/blender/blender/issues/106254", "#106254")),
),
)
@ -2538,6 +2597,7 @@ classes = (
USERPREF_PT_text_editor_presets,
USERPREF_PT_file_paths_development,
USERPREF_PT_file_paths_asset_libraries,
USERPREF_PT_file_paths_extension_repos,
USERPREF_PT_saveload_blend,
USERPREF_PT_saveload_blend_autosave,
@ -2575,6 +2635,7 @@ classes = (
# UI lists
USERPREF_UL_asset_libraries,
USERPREF_UL_extension_repos,
# Add dynamically generated editor theme panels last,
# so they show up last in the theme section.

View File

@ -53,6 +53,7 @@ set(SRC_DNA_INC
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_movieclip_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_nla_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_node_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_node_tree_interface_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_object_enums.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_object_fluidsim_types.h
${CMAKE_CURRENT_SOURCE_DIR}/makesdna/DNA_object_force_types.h

View File

@ -16,8 +16,8 @@ struct bAddon;
#ifdef __RNA_TYPES_H__
typedef struct bAddonPrefType {
/* type info */
char idname[64]; /* best keep the same size as #BKE_ST_MAXNAME */
/** Type info, match #bAddon::module. */
char idname[128];
/* RNA integration */
ExtensionRNA rna_ext;

View File

@ -29,7 +29,7 @@ extern "C" {
/* Blender file format version. */
#define BLENDER_FILE_VERSION BLENDER_VERSION
#define BLENDER_FILE_SUBVERSION 14
#define BLENDER_FILE_SUBVERSION 15
/* Minimum Blender version that supports reading file written with the current
* version. Older Blender versions will test this and cancel loading the file, showing a warning to

View File

@ -109,6 +109,8 @@ typedef enum {
BKE_CB_EVT_COMPOSITE_CANCEL,
BKE_CB_EVT_ANIMATION_PLAYBACK_PRE,
BKE_CB_EVT_ANIMATION_PLAYBACK_POST,
BKE_CB_EVT_EXTENSION_REPOS_UPDATE_PRE,
BKE_CB_EVT_EXTENSION_REPOS_UPDATE_POST,
BKE_CB_EVT_TOT,
} eCbEvent;

View File

@ -34,7 +34,6 @@ struct Library;
struct Main;
struct Object;
struct Scene;
struct SceneCollection;
struct ViewLayer;
typedef struct CollectionParent {
@ -322,14 +321,6 @@ void BKE_collection_blend_read_lib(struct BlendLibReader *reader, struct Collect
void BKE_collection_blend_read_expand(struct BlendExpander *expander,
struct Collection *collection);
void BKE_collection_compat_blend_read_data(struct BlendDataReader *reader,
struct SceneCollection *sc);
void BKE_collection_compat_blend_read_lib(struct BlendLibReader *reader,
struct ID *self_id,
struct SceneCollection *sc);
void BKE_collection_compat_blend_read_expand(struct BlendExpander *expander,
struct SceneCollection *sc);
/* Iteration callbacks. */
typedef void (*BKE_scene_objects_Cb)(struct Object *ob, void *data);

View File

@ -30,6 +30,12 @@ typedef struct Global {
*/
struct Main *main;
/**
* Preview main is stored to avoid loading the preview file in multiple scenarios.
* It is actually shared between shader node previews and asset previews.
*/
struct Main *pr_main;
/** Last saved location for images. */
char ima[1024]; /* 1024 = FILE_MAX */
/** Last used location for library link/append. */

View File

@ -57,6 +57,7 @@ void BKE_object_material_from_eval_data(struct Main *bmain,
struct Material *BKE_material_add(struct Main *bmain, const char *name);
struct Material *BKE_gpencil_material_add(struct Main *bmain, const char *name);
void BKE_gpencil_material_attr_init(struct Material *ma);
void BKE_material_make_node_previews_dirty(struct Material *ma);
/* UNUSED */
// void automatname(struct Material *);

View File

@ -94,6 +94,12 @@ class bNodeTreeRuntime : NonCopyable, NonMovable {
*/
uint8_t runtime_flag = 0;
/**
* Contains a number increased for each node-tree update.
* Store a state variable in the #NestedTreePreviews structure to compare if they differ.
*/
uint32_t previews_refresh_state = 0;
/**
* Storage of nodes based on their identifier. Also used as a contiguous array of nodes to
* allow simpler and more cache friendly iteration. Supports lookup by integer or by node.

View File

@ -0,0 +1,220 @@
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
#include "DNA_node_tree_interface_types.h"
#include "DNA_node_types.h"
#include "BKE_node.h"
#include <queue>
#include <type_traits>
#include "BLI_parameter_pack_utils.hh"
#include "BLI_vector.hh"
namespace blender::bke {
/* Runtime topology cache for linear access to items. */
struct bNodeTreeInterfaceCache {
Vector<bNodeTreeInterfaceItem *> items;
Vector<bNodeTreeInterfaceSocket *> inputs;
Vector<bNodeTreeInterfaceSocket *> outputs;
void rebuild(bNodeTreeInterface &tree_interface);
};
namespace node_interface {
namespace detail {
template<typename T> static bool item_is_type(const bNodeTreeInterfaceItem &item)
{
bool match = false;
switch (item.item_type) {
case NODE_INTERFACE_SOCKET: {
match |= std::is_same<T, bNodeTreeInterfaceSocket>::value;
break;
}
case NODE_INTERFACE_PANEL: {
match |= std::is_same<T, bNodeTreeInterfacePanel>::value;
break;
}
}
return match;
}
} // namespace detail
template<typename T> T &get_item_as(bNodeTreeInterfaceItem &item)
{
BLI_assert(detail::item_is_type<T>(item));
return reinterpret_cast<T &>(item);
}
template<typename T> const T &get_item_as(const bNodeTreeInterfaceItem &item)
{
BLI_assert(detail::item_is_type<T>(item));
return reinterpret_cast<const T &>(item);
}
template<typename T> T *get_item_as(bNodeTreeInterfaceItem *item)
{
if (item && detail::item_is_type<T>(*item)) {
return reinterpret_cast<T *>(item);
}
return nullptr;
}
template<typename T> const T *get_item_as(const bNodeTreeInterfaceItem *item)
{
if (item && detail::item_is_type<T>(*item)) {
return reinterpret_cast<const T *>(item);
}
return nullptr;
}
namespace socket_types {
constexpr const char *node_socket_data_float = "NodeSocketFloat";
constexpr const char *node_socket_data_int = "NodeSocketInt";
constexpr const char *node_socket_data_bool = "NodeSocketBool";
constexpr const char *node_socket_data_rotation = "NodeSocketRotation";
constexpr const char *node_socket_data_vector = "NodeSocketVector";
constexpr const char *node_socket_data_color = "NodeSocketColor";
constexpr const char *node_socket_data_string = "NodeSocketString";
constexpr const char *node_socket_data_object = "NodeSocketObject";
constexpr const char *node_socket_data_image = "NodeSocketImage";
constexpr const char *node_socket_data_collection = "NodeSocketCollection";
constexpr const char *node_socket_data_texture = "NodeSocketTexture";
constexpr const char *node_socket_data_material = "NodeSocketMaterial";
template<typename Fn> void socket_data_to_static_type(const char *socket_type, const Fn &fn)
{
if (STREQ(socket_type, socket_types::node_socket_data_float)) {
fn.template operator()<bNodeSocketValueFloat>();
}
else if (STREQ(socket_type, socket_types::node_socket_data_int)) {
fn.template operator()<bNodeSocketValueInt>();
}
else if (STREQ(socket_type, socket_types::node_socket_data_bool)) {
fn.template operator()<bNodeSocketValueBoolean>();
}
else if (STREQ(socket_type, socket_types::node_socket_data_rotation)) {
fn.template operator()<bNodeSocketValueRotation>();
}
else if (STREQ(socket_type, socket_types::node_socket_data_vector)) {
fn.template operator()<bNodeSocketValueVector>();
}
else if (STREQ(socket_type, socket_types::node_socket_data_color)) {
fn.template operator()<bNodeSocketValueRGBA>();
}
else if (STREQ(socket_type, socket_types::node_socket_data_string)) {
fn.template operator()<bNodeSocketValueString>();
}
else if (STREQ(socket_type, socket_types::node_socket_data_object)) {
fn.template operator()<bNodeSocketValueObject>();
}
else if (STREQ(socket_type, socket_types::node_socket_data_image)) {
fn.template operator()<bNodeSocketValueImage>();
}
else if (STREQ(socket_type, socket_types::node_socket_data_collection)) {
fn.template operator()<bNodeSocketValueCollection>();
}
else if (STREQ(socket_type, socket_types::node_socket_data_texture)) {
fn.template operator()<bNodeSocketValueTexture>();
}
else if (STREQ(socket_type, socket_types::node_socket_data_material)) {
fn.template operator()<bNodeSocketValueMaterial>();
}
}
namespace detail {
template<typename Fn> struct TypeTagExecutor {
const Fn &fn;
TypeTagExecutor(const Fn &fn_) : fn(fn_) {}
template<typename T> void operator()() const
{
fn(TypeTag<T>{});
}
};
} // namespace detail
template<typename Fn> void socket_data_to_static_type_tag(const char *socket_type, const Fn &fn)
{
detail::TypeTagExecutor executor{fn};
socket_data_to_static_type(socket_type, executor);
}
} // namespace socket_types
template<typename T> bool socket_data_is_type(const char *socket_type)
{
bool match = false;
socket_types::socket_data_to_static_type_tag(socket_type, [&match](auto type_tag) {
using SocketDataType = typename decltype(type_tag)::type;
match |= std::is_same_v<T, SocketDataType>;
});
return match;
}
template<typename T> T &get_socket_data_as(bNodeTreeInterfaceSocket &item)
{
BLI_assert(socket_data_is_type<T>(item.socket_type));
return *static_cast<T *>(item.socket_data);
}
template<typename T> const T &get_socket_data_as(const bNodeTreeInterfaceSocket &item)
{
BLI_assert(socket_data_is_type<T>(item.socket_type));
return *static_cast<const T *>(item.socket_data);
}
inline bNodeTreeInterfaceSocket *add_interface_socket_from_node(bNodeTree &ntree,
const bNode & /*from_node*/,
const bNodeSocket &from_sock,
const StringRefNull socket_type,
const StringRefNull name)
{
eNodeTreeInterfaceSocketFlag flag = eNodeTreeInterfaceSocketFlag(0);
SET_FLAG_FROM_TEST(flag, from_sock.in_out & SOCK_IN, NODE_INTERFACE_SOCKET_INPUT);
SET_FLAG_FROM_TEST(flag, from_sock.in_out & SOCK_OUT, NODE_INTERFACE_SOCKET_OUTPUT);
bNodeTreeInterfaceSocket *iosock = ntree.tree_interface.add_socket(
name.data(), from_sock.description, socket_type, flag, nullptr);
if (iosock == nullptr) {
return nullptr;
}
const bNodeSocketType *typeinfo = iosock->socket_typeinfo();
if (typeinfo->interface_from_socket) {
/* XXX Enable when bNodeSocketType callbacks have been updated. */
// typeinfo->interface_from_socket(ntree.id, iosock, &from_node, &from_sock);
}
return iosock;
}
inline bNodeTreeInterfaceSocket *add_interface_socket_from_node(bNodeTree &ntree,
const bNode &from_node,
const bNodeSocket &from_sock,
const StringRefNull socket_type)
{
return add_interface_socket_from_node(ntree, from_node, from_sock, socket_type, from_sock.name);
}
inline bNodeTreeInterfaceSocket *add_interface_socket_from_node(bNodeTree &ntree,
const bNode &from_node,
const bNodeSocket &from_sock)
{
return add_interface_socket_from_node(
ntree, from_node, from_sock, from_sock.typeinfo->idname, from_sock.name);
}
} // namespace node_interface
} // namespace blender::bke

View File

@ -15,6 +15,7 @@ extern "C" {
#include "BLI_compiler_attrs.h"
struct UserDef;
struct bUserExtensionRepo;
struct bUserAssetLibrary;
/* -------------------------------------------------------------------- */
@ -74,6 +75,31 @@ void BKE_preferences_asset_library_default_add(struct UserDef *userdef) ATTR_NON
/** \} */
/* -------------------------------------------------------------------- */
/** \name Extension Repositories
* \{ */
bUserExtensionRepo *BKE_preferences_extension_repo_add(UserDef *userdef,
const char *name,
const char *dirpath);
void BKE_preferences_extension_repo_remove(UserDef *userdef, bUserExtensionRepo *repo);
void BKE_preferences_extension_repo_name_set(UserDef *userdef,
bUserExtensionRepo *repo,
const char *name);
void BKE_preferences_extension_repo_module_set(UserDef *userdef,
bUserExtensionRepo *repo,
const char *module);
void BKE_preferences_extension_repo_path_set(bUserExtensionRepo *repo, const char *path);
bUserExtensionRepo *BKE_preferences_extension_repo_find_index(const UserDef *userdef, int index);
bUserExtensionRepo *BKE_preferences_extension_repo_find_by_module(const UserDef *userdef,
const char *module);
int BKE_preferences_extension_repo_get_index(const UserDef *userdef,
const bUserExtensionRepo *repo);
/** \} */
#ifdef __cplusplus
}
#endif

View File

@ -235,6 +235,8 @@ bool BKE_scene_uses_blender_eevee(const struct Scene *scene);
bool BKE_scene_uses_blender_workbench(const struct Scene *scene);
bool BKE_scene_uses_cycles(const struct Scene *scene);
bool BKE_scene_uses_shader_previews(const struct Scene *scene);
/**
* Return whether the Cycles experimental feature is enabled. It is invalid to call without first
* ensuring that Cycles is the active render engine (e.g. with #BKE_scene_uses_cycles).

View File

@ -235,6 +235,7 @@ set(SRC
intern/node_tree_anonymous_attributes.cc
intern/node_tree_dot_export.cc
intern/node_tree_field_inferencing.cc
intern/node_tree_interface.cc
intern/node_tree_update.cc
intern/node_tree_zones.cc
intern/object.cc
@ -454,6 +455,7 @@ set(SRC
BKE_node_runtime.hh
BKE_node_tree_anonymous_attributes.hh
BKE_node_tree_dot_export.hh
BKE_node_tree_interface.hh
BKE_node_tree_update.h
BKE_node_tree_zones.hh
BKE_object.h

View File

@ -730,8 +730,8 @@ static void animsys_blend_in_fcurves(PointerRNA *ptr,
case PROP_ENUM:
value_to_write = roundf(value_to_write);
break;
default: /* All other types are just handled as float, and value_to_write is already
correct. */
/* All other types are just handled as float, and value_to_write is already correct. */
default:
break;
}
}
@ -1072,8 +1072,8 @@ NlaEvalStrip *nlastrips_ctime_get_strip(ListBase *list,
return nullptr;
}
break;
case NLASTRIP_TYPE_TRANSITION: /* there must be strips to transition from and to (i.e. prev and
next required) */
/* There must be strips to transition from and to (i.e. `prev` and `next` required). */
case NLASTRIP_TYPE_TRANSITION:
if (ELEM(nullptr, estrip->prev, estrip->next)) {
return nullptr;
}

View File

@ -327,6 +327,7 @@ void BKE_blender_userdef_data_free(UserDef *userdef, bool clear_fonts)
BLI_freelistN(&userdef->autoexec_paths);
BLI_freelistN(&userdef->script_directories);
BLI_freelistN(&userdef->asset_libraries);
BLI_freelistN(&userdef->extension_repos);
BLI_freelistN(&userdef->uistyles);
BLI_freelistN(&userdef->uifonts);
@ -356,7 +357,7 @@ void BKE_blender_userdef_app_template_data_swap(UserDef *userdef_a, UserDef *use
} \
((void)0)
#define LIST_SWAP(id) \
#define LISTBASE_SWAP(id) \
{ \
SWAP(ListBase, userdef_a->id, userdef_b->id); \
} \
@ -373,12 +374,12 @@ void BKE_blender_userdef_app_template_data_swap(UserDef *userdef_a, UserDef *use
} \
((void)0)
LIST_SWAP(uistyles);
LIST_SWAP(uifonts);
LIST_SWAP(themes);
LIST_SWAP(addons);
LIST_SWAP(user_keymaps);
LIST_SWAP(user_keyconfig_prefs);
LISTBASE_SWAP(uistyles);
LISTBASE_SWAP(uifonts);
LISTBASE_SWAP(themes);
LISTBASE_SWAP(addons);
LISTBASE_SWAP(user_keymaps);
LISTBASE_SWAP(user_keyconfig_prefs);
DATA_SWAP(font_path_ui);
DATA_SWAP(font_path_ui_mono);
@ -394,7 +395,7 @@ void BKE_blender_userdef_app_template_data_swap(UserDef *userdef_a, UserDef *use
#undef SWAP_TYPELESS
#undef DATA_SWAP
#undef LIST_SWAP
#undef LISTBASE_SWAP
#undef FLAG_SWAP
}

View File

@ -256,18 +256,6 @@ static void collection_blend_write(BlendWriter *writer, ID *id, const void *id_a
BKE_collection_blend_write_nolib(writer, collection);
}
#ifdef USE_COLLECTION_COMPAT_28
void BKE_collection_compat_blend_read_data(BlendDataReader *reader, SceneCollection *sc)
{
BLO_read_list(reader, &sc->objects);
BLO_read_list(reader, &sc->scene_collections);
LISTBASE_FOREACH (SceneCollection *, nsc, &sc->scene_collections) {
BKE_collection_compat_blend_read_data(reader, nsc);
}
}
#endif
void BKE_collection_blend_read_data(BlendDataReader *reader, Collection *collection, ID *owner_id)
{
/* Special case for this pointer, do not rely on regular `lib_link` process here. Avoids needs
@ -306,19 +294,6 @@ void BKE_collection_blend_read_data(BlendDataReader *reader, Collection *collect
BLO_read_data_address(reader, &collection->preview);
BKE_previewimg_blend_read(reader, collection->preview);
#ifdef USE_COLLECTION_COMPAT_28
/* This runs before the very first doversion. */
BLO_read_data_address(reader, &collection->collection);
if (collection->collection != nullptr) {
BKE_collection_compat_blend_read_data(reader, collection->collection);
}
BLO_read_data_address(reader, &collection->view_layer);
if (collection->view_layer != nullptr) {
BKE_view_layer_blend_read_data(reader, collection->view_layer);
}
#endif
}
static void collection_blend_read_data(BlendDataReader *reader, ID *id)
@ -343,32 +318,8 @@ static void lib_link_collection_data(BlendLibReader *reader, ID *self_id, Collec
}
}
#ifdef USE_COLLECTION_COMPAT_28
void BKE_collection_compat_blend_read_lib(BlendLibReader *reader, ID *self_id, SceneCollection *sc)
{
LISTBASE_FOREACH (LinkData *, link, &sc->objects) {
BLO_read_id_address(reader, self_id, &link->data);
BLI_assert(link->data);
}
LISTBASE_FOREACH (SceneCollection *, nsc, &sc->scene_collections) {
BKE_collection_compat_blend_read_lib(reader, self_id, nsc);
}
}
#endif
void BKE_collection_blend_read_lib(BlendLibReader *reader, Collection *collection)
{
#ifdef USE_COLLECTION_COMPAT_28
if (collection->collection) {
BKE_collection_compat_blend_read_lib(reader, &collection->id, collection->collection);
}
if (collection->view_layer) {
BKE_view_layer_blend_read_lib(reader, &collection->id, collection->view_layer);
}
#endif
lib_link_collection_data(reader, &collection->id, collection);
}
@ -378,22 +329,8 @@ static void collection_blend_read_lib(BlendLibReader *reader, ID *id)
BKE_collection_blend_read_lib(reader, collection);
}
#ifdef USE_COLLECTION_COMPAT_28
void BKE_collection_compat_blend_read_expand(BlendExpander *expander, SceneCollection *sc)
{
LISTBASE_FOREACH (LinkData *, link, &sc->objects) {
BLO_expand(expander, link->data);
}
LISTBASE_FOREACH (SceneCollection *, nsc, &sc->scene_collections) {
BKE_collection_compat_blend_read_expand(expander, nsc);
}
}
#endif
void BKE_collection_blend_read_expand(BlendExpander *expander, Collection *collection)
{
BLI_assert(collection->runtime.gobject_hash == nullptr);
LISTBASE_FOREACH (CollectionObject *, cob, &collection->gobject) {
BLO_expand(expander, cob->ob);
}
@ -401,12 +338,6 @@ void BKE_collection_blend_read_expand(BlendExpander *expander, Collection *colle
LISTBASE_FOREACH (CollectionChild *, child, &collection->children) {
BLO_expand(expander, child->collection);
}
#ifdef USE_COLLECTION_COMPAT_28
if (collection->collection != nullptr) {
BKE_collection_compat_blend_read_expand(expander, collection->collection);
}
#endif
}
static void collection_blend_read_expand(BlendExpander *expander, ID *id)

View File

@ -225,12 +225,14 @@ void BKE_fluid_reallocate_copy_fluid(FluidDomainSettings *fds,
/* Skip if trying to copy from old boundary cell. */
if (xo < bwidth || yo < bwidth || zo < bwidth || xo >= o_res[0] - bwidth ||
yo >= o_res[1] - bwidth || zo >= o_res[2] - bwidth) {
yo >= o_res[1] - bwidth || zo >= o_res[2] - bwidth)
{
continue;
}
/* Skip if trying to copy into new boundary cell. */
if (xn < bwidth || yn < bwidth || zn < bwidth || xn >= n_res[0] - bwidth ||
yn >= n_res[1] - bwidth || zn >= n_res[2] - bwidth) {
yn >= n_res[1] - bwidth || zn >= n_res[2] - bwidth)
{
continue;
}
# endif

View File

@ -2399,10 +2399,6 @@ static void direct_link_layer_collections(BlendDataReader *reader, ListBase *lb,
{
BLO_read_list(reader, lb);
LISTBASE_FOREACH (LayerCollection *, lc, lb) {
#ifdef USE_COLLECTION_COMPAT_28
BLO_read_data_address(reader, &lc->scene_collection);
#endif
/* Master collection is not a real data-block. */
if (master) {
BLO_read_data_address(reader, &lc->collection);

View File

@ -304,6 +304,27 @@ void BKE_gpencil_material_attr_init(Material *ma)
}
}
static void nodetree_mark_previews_dirty_reccursive(bNodeTree *tree)
{
if (tree == nullptr) {
return;
}
tree->runtime->previews_refresh_state++;
for (bNode *node : tree->all_nodes()) {
if (node->type == NODE_GROUP) {
bNodeTree *nested_tree = reinterpret_cast<bNodeTree *>(node->id);
nodetree_mark_previews_dirty_reccursive(nested_tree);
}
}
}
void BKE_material_make_node_previews_dirty(Material *ma)
{
if (ma && ma->nodetree) {
nodetree_mark_previews_dirty_reccursive(ma->nodetree);
}
}
Material *BKE_material_add(Main *bmain, const char *name)
{
Material *ma;

File diff suppressed because it is too large Load Diff

View File

@ -478,6 +478,7 @@ class NodeTreeMainUpdater {
this->update_internal_links(ntree);
this->update_generic_callback(ntree);
this->remove_unused_previews_when_necessary(ntree);
this->make_node_previews_dirty(ntree);
this->propagate_runtime_flags(ntree);
if (ntree.type == NTREE_GEOMETRY) {
@ -723,6 +724,19 @@ class NodeTreeMainUpdater {
blender::bke::node_preview_remove_unused(&ntree);
}
void make_node_previews_dirty(bNodeTree &ntree)
{
ntree.runtime->previews_refresh_state++;
for (bNode *node : ntree.all_nodes()) {
if (node->type != NODE_GROUP) {
continue;
}
if (bNodeTree *nested_tree = reinterpret_cast<bNodeTree *>(node->id)) {
this->make_node_previews_dirty(*nested_tree);
}
}
}
void propagate_runtime_flags(const bNodeTree &ntree)
{
ntree.ensure_topology_cache();

View File

@ -1562,51 +1562,27 @@ float BKE_ocean_jminus_to_foam(float /*jminus*/, float /*coverage*/)
return 0.0f;
}
void BKE_ocean_eval_uv(struct Ocean * /*oc*/,
struct OceanResult * /*ocr*/,
float /*u*/,
float /*v*/)
{
}
void BKE_ocean_eval_uv(Ocean * /*oc*/, OceanResult * /*ocr*/, float /*u*/, float /*v*/) {}
/* use catmullrom interpolation rather than linear */
void BKE_ocean_eval_uv_catrom(struct Ocean * /*oc*/,
struct OceanResult * /*ocr*/,
float /*u*/,
float /*v*/)
{
}
void BKE_ocean_eval_uv_catrom(Ocean * /*oc*/, OceanResult * /*ocr*/, float /*u*/, float /*v*/) {}
void BKE_ocean_eval_xz(struct Ocean * /*oc*/,
struct OceanResult * /*ocr*/,
float /*x*/,
float /*z*/)
{
}
void BKE_ocean_eval_xz(Ocean * /*oc*/, OceanResult * /*ocr*/, float /*x*/, float /*z*/) {}
void BKE_ocean_eval_xz_catrom(struct Ocean * /*oc*/,
struct OceanResult * /*ocr*/,
float /*x*/,
float /*z*/)
{
}
void BKE_ocean_eval_xz_catrom(Ocean * /*oc*/, OceanResult * /*ocr*/, float /*x*/, float /*z*/) {}
void BKE_ocean_eval_ij(struct Ocean * /*oc*/, struct OceanResult * /*ocr*/, int /*i*/, int /*j*/)
{
}
void BKE_ocean_eval_ij(Ocean * /*oc*/, OceanResult * /*ocr*/, int /*i*/, int /*j*/) {}
void BKE_ocean_simulate(struct Ocean * /*o*/, float /*t*/, float /*scale*/, float /*chop_amount*/)
{
}
void BKE_ocean_simulate(Ocean * /*o*/, float /*t*/, float /*scale*/, float /*chop_amount*/) {}
struct Ocean *BKE_ocean_add()
Ocean *BKE_ocean_add()
{
Ocean *oc = static_cast<Ocean *>(MEM_callocN(sizeof(Ocean), "ocean sim data"));
return oc;
}
bool BKE_ocean_init(struct Ocean * /*o*/,
bool BKE_ocean_init(Ocean * /*o*/,
int /*M*/,
int /*N*/,
float /*Lx*/,
@ -1632,9 +1608,9 @@ bool BKE_ocean_init(struct Ocean * /*o*/,
return false;
}
void BKE_ocean_free_data(struct Ocean * /*oc*/) {}
void BKE_ocean_free_data(Ocean * /*oc*/) {}
void BKE_ocean_free(struct Ocean *oc)
void BKE_ocean_free(Ocean *oc)
{
if (!oc) {
return;
@ -1644,7 +1620,7 @@ void BKE_ocean_free(struct Ocean *oc)
/* ********* Baking/Caching ********* */
void BKE_ocean_free_cache(struct OceanCache *och)
void BKE_ocean_free_cache(OceanCache *och)
{
if (!och) {
return;
@ -1654,12 +1630,12 @@ void BKE_ocean_free_cache(struct OceanCache *och)
}
void BKE_ocean_cache_eval_uv(
struct OceanCache * /*och*/, struct OceanResult * /*ocr*/, int /*f*/, float /*u*/, float /*v*/)
OceanCache * /*och*/, OceanResult * /*ocr*/, int /*f*/, float /*u*/, float /*v*/)
{
}
void BKE_ocean_cache_eval_ij(
struct OceanCache * /*och*/, struct OceanResult * /*ocr*/, int /*f*/, int /*i*/, int /*j*/)
OceanCache * /*och*/, OceanResult * /*ocr*/, int /*f*/, int /*i*/, int /*j*/)
{
}
@ -1678,10 +1654,10 @@ OceanCache *BKE_ocean_init_cache(const char * /*bakepath*/,
return och;
}
void BKE_ocean_simulate_cache(struct OceanCache * /*och*/, int /*frame*/) {}
void BKE_ocean_simulate_cache(OceanCache * /*och*/, int /*frame*/) {}
void BKE_ocean_bake(struct Ocean * /*o*/,
struct OceanCache * /*och*/,
void BKE_ocean_bake(Ocean * /*o*/,
OceanCache * /*och*/,
void (*update_cb)(void *, float progress, int *cancel),
void * /*update_cb_data*/)
{
@ -1689,8 +1665,8 @@ void BKE_ocean_bake(struct Ocean * /*o*/,
(void)update_cb;
}
bool BKE_ocean_init_from_modifier(struct Ocean * /*ocean*/,
struct OceanModifierData const * /*omd*/,
bool BKE_ocean_init_from_modifier(Ocean * /*ocean*/,
OceanModifierData const * /*omd*/,
int /*resolution*/)
{
return true;

View File

@ -4360,8 +4360,8 @@ static void particles_fluid_step(ParticleSimulationData *sim,
return;
}
# if 0
/* Debugging: Print type of particle system and current particles. */
printf("system type is %d and particle type is %d\n", part->type, flagActivePart);
/* Debugging: Print type of particle system and current particles. */
printf("system type is %d and particle type is %d\n", part->type, flagActivePart);
# endif
/* Type of particle must match current particle system type
@ -4379,8 +4379,8 @@ printf("system type is %d and particle type is %d\n", part->type, flagActivePart
continue;
}
# if 0
/* Debugging: Print type of particle system and current particles. */
printf("system type is %d and particle type is %d\n", part->type, flagActivePart);
/* Debugging: Print type of particle system and current particles. */
printf("system type is %d and particle type is %d\n", part->type, flagActivePart);
# endif
/* Particle system has allocated 'tottypepart' particles - so break early before exceeded.
*/
@ -4438,16 +4438,22 @@ printf("system type is %d and particle type is %d\n", part->type, flagActivePart
mul_v3_v3(tmp, ob->scale);
add_v3_v3(pa->state.co, tmp);
# if 0
/* Debugging: Print particle coordinates. */
printf("pa->state.co[0]: %f, pa->state.co[1]: %f, pa->state.co[2]: %f\n", pa->state.co[0], pa->state.co[1], pa->state.co[2]);
/* Debugging: Print particle coordinates. */
printf("pa->state.co[0]: %f, pa->state.co[1]: %f, pa->state.co[2]: %f\n",
pa->state.co[0],
pa->state.co[1],
pa->state.co[2]);
# endif
/* Set particle velocity. */
const float velParticle[3] = {velX, velY, velZ};
copy_v3_v3(pa->state.vel, velParticle);
mul_v3_fl(pa->state.vel, fds->dx);
# if 0
/* Debugging: Print particle velocity. */
printf("pa->state.vel[0]: %f, pa->state.vel[1]: %f, pa->state.vel[2]: %f\n", pa->state.vel[0], pa->state.vel[1], pa->state.vel[2]);
/* Debugging: Print particle velocity. */
printf("pa->state.vel[0]: %f, pa->state.vel[1]: %f, pa->state.vel[2]: %f\n",
pa->state.vel[0],
pa->state.vel[1],
pa->state.vel[2]);
# endif
/* Set default angular velocity and particle rotation. */
zero_v3(pa->state.ave);
@ -4463,8 +4469,8 @@ printf("pa->state.vel[0]: %f, pa->state.vel[1]: %f, pa->state.vel[2]: %f\n", pa-
}
}
# if 0
/* Debugging: Print number of active particles. */
printf("active parts: %d\n", activeParts);
/* Debugging: Print number of active particles. */
printf("active parts: %d\n", activeParts);
# endif
totpart = psys->totpart = part->totpart = activeParts;

View File

@ -126,3 +126,128 @@ void BKE_preferences_asset_library_default_add(UserDef *userdef)
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Extension Repositories
* \{ */
/**
* A string copy that ensures: `[A-Za-z]+[A-Za-z0-9_]*`.
*/
static size_t strncpy_py_module(char *dst, const char *src, const size_t dst_maxncpy)
{
const size_t dst_len_max = dst_maxncpy - 1;
dst[0] = '\0';
size_t i_src = 0, i_dst = 0;
while (src[i_src] && (i_dst < dst_len_max)) {
const char c = src[i_src++];
const bool is_alpha = (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z');
/* The first character must be `[a-zA-Z]`. */
if (i_dst == 0 && !is_alpha) {
continue;
}
const bool is_num = (is_alpha == false) && ((c >= '0' && c <= '9') || c == '_');
if (!(is_alpha || is_num)) {
continue;
}
dst[i_dst++] = c;
}
dst[i_dst] = '\0';
return i_dst;
}
bUserExtensionRepo *BKE_preferences_extension_repo_add(UserDef *userdef,
const char *name,
const char *dirpath)
{
bUserExtensionRepo *repo = DNA_struct_default_alloc(bUserExtensionRepo);
BLI_addtail(&userdef->extension_repos, repo);
/* Set the unique ID-name. */
BKE_preferences_extension_repo_name_set(userdef, repo, name);
/* Set the unique module-name. */
BKE_preferences_extension_repo_module_set(userdef, repo, name);
/* Set the directory. */
STRNCPY(repo->dirpath, dirpath);
BLI_path_normalize(repo->dirpath);
BLI_path_slash_rstrip(repo->dirpath);
/* While not a strict rule, ignored paths that already exist, *
* pointing to the same path is going to logical problems with package-management. */
LISTBASE_FOREACH (const bUserExtensionRepo *, repo_iter, &userdef->extension_repos) {
if (repo == repo_iter) {
continue;
}
if (BLI_path_cmp(repo->dirpath, repo_iter->dirpath) == 0) {
repo->dirpath[0] = '\0';
break;
}
}
return repo;
}
void BKE_preferences_extension_repo_remove(UserDef *userdef, bUserExtensionRepo *repo)
{
BLI_freelinkN(&userdef->extension_repos, repo);
}
void BKE_preferences_extension_repo_name_set(UserDef *userdef,
bUserExtensionRepo *repo,
const char *name)
{
if (*name == '\0') {
name = "User Repository";
}
STRNCPY_UTF8(repo->name, name);
BLI_uniquename(&userdef->extension_repos,
repo,
name,
'.',
offsetof(bUserExtensionRepo, name),
sizeof(repo->name));
}
void BKE_preferences_extension_repo_module_set(UserDef *userdef,
bUserExtensionRepo *repo,
const char *module)
{
if (strncpy_py_module(repo->module, module, sizeof(repo->module)) == 0) {
STRNCPY(repo->module, "repository");
}
BLI_uniquename(&userdef->extension_repos,
repo,
module,
'_',
offsetof(bUserExtensionRepo, module),
sizeof(repo->module));
}
void BKE_preferences_extension_repo_path_set(bUserExtensionRepo *repo, const char *path)
{
STRNCPY(repo->dirpath, path);
}
bUserExtensionRepo *BKE_preferences_extension_repo_find_index(const UserDef *userdef, int index)
{
return static_cast<bUserExtensionRepo *>(BLI_findlink(&userdef->extension_repos, index));
}
bUserExtensionRepo *BKE_preferences_extension_repo_find_by_module(const UserDef *userdef,
const char *module)
{
return static_cast<bUserExtensionRepo *>(
BLI_findstring(&userdef->extension_repos, module, offsetof(bUserExtensionRepo, module)));
}
int BKE_preferences_extension_repo_get_index(const UserDef *userdef,
const bUserExtensionRepo *repo)
{
return BLI_findindex(&userdef->extension_repos, repo);
}
/** \} */

View File

@ -2397,29 +2397,25 @@ void BKE_rigidbody_calc_center_of_mass(Object *ob, float r_center[3])
{
zero_v3(r_center);
}
struct RigidBodyWorld *BKE_rigidbody_create_world(Scene *scene)
RigidBodyWorld *BKE_rigidbody_create_world(Scene *scene)
{
return nullptr;
}
struct RigidBodyWorld *BKE_rigidbody_world_copy(RigidBodyWorld *rbw, const int flag)
RigidBodyWorld *BKE_rigidbody_world_copy(RigidBodyWorld *rbw, const int flag)
{
return nullptr;
}
void BKE_rigidbody_world_groups_relink(struct RigidBodyWorld *rbw) {}
void BKE_rigidbody_world_id_loop(struct RigidBodyWorld *rbw,
RigidbodyWorldIDFunc func,
void *userdata)
{
}
struct RigidBodyOb *BKE_rigidbody_create_object(Scene *scene, Object *ob, short type)
void BKE_rigidbody_world_groups_relink(RigidBodyWorld *rbw) {}
void BKE_rigidbody_world_id_loop(RigidBodyWorld *rbw, RigidbodyWorldIDFunc func, void *userdata) {}
RigidBodyOb *BKE_rigidbody_create_object(Scene *scene, Object *ob, short type)
{
return nullptr;
}
struct RigidBodyCon *BKE_rigidbody_create_constraint(Scene *scene, Object *ob, short type)
RigidBodyCon *BKE_rigidbody_create_constraint(Scene *scene, Object *ob, short type)
{
return nullptr;
}
struct RigidBodyWorld *BKE_rigidbody_get_world(Scene *scene)
RigidBodyWorld *BKE_rigidbody_get_world(Scene *scene)
{
return nullptr;
}
@ -2432,9 +2428,7 @@ bool BKE_rigidbody_add_object(Main *bmain, Scene *scene, Object *ob, int type, R
return false;
}
void BKE_rigidbody_remove_object(struct Main *bmain, Scene *scene, Object *ob, const bool free_us)
{
}
void BKE_rigidbody_remove_object(Main *bmain, Scene *scene, Object *ob, const bool free_us) {}
void BKE_rigidbody_remove_constraint(Main *bmain, Scene *scene, Object *ob, const bool free_us) {}
void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime) {}
void BKE_rigidbody_aftertrans_update(

View File

@ -870,6 +870,13 @@ static void scene_foreach_id(ID *id, LibraryForeachIDData *data)
LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
BKE_LIB_FOREACHID_PROCESS_IDSUPER(data, view_layer->mat_override, IDWALK_CB_USER);
BKE_LIB_FOREACHID_PROCESS_FUNCTION_CALL(
data,
IDP_foreach_property(view_layer->id_properties,
IDP_TYPE_FILTER_ID,
BKE_lib_query_idpropertiesForeachIDLink_callback,
data));
BKE_view_layer_synced_ensure(scene, view_layer);
LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) {
BKE_LIB_FOREACHID_PROCESS_IDSUPER(
@ -1479,14 +1486,6 @@ static void scene_blend_read_data(BlendDataReader *reader, ID *id)
BKE_curvemapping_blend_read(reader, &sce->r.mblur_shutter_curve);
#ifdef USE_COLLECTION_COMPAT_28
/* this runs before the very first doversion */
if (sce->collection) {
BLO_read_data_address(reader, &sce->collection);
BKE_collection_compat_blend_read_data(reader, sce->collection);
}
#endif
/* insert into global old-new map for reading without UI (link_global accesses it again) */
BLO_read_glob_list(reader, &sce->view_layers);
LISTBASE_FOREACH (ViewLayer *, view_layer, &sce->view_layers) {
@ -1644,12 +1643,6 @@ static void scene_blend_read_lib(BlendLibReader *reader, ID *id)
/* Motion Tracking */
BLO_read_id_address(reader, id, &sce->clip);
#ifdef USE_COLLECTION_COMPAT_28
if (sce->collection) {
BKE_collection_compat_blend_read_lib(reader, id, sce->collection);
}
#endif
LISTBASE_FOREACH (ViewLayer *, view_layer, &sce->view_layers) {
BKE_view_layer_blend_read_lib(reader, id, view_layer);
}
@ -1736,12 +1729,6 @@ static void scene_blend_read_expand(BlendExpander *expander, ID *id)
BLO_expand(expander, sce->clip);
#ifdef USE_COLLECTION_COMPAT_28
if (sce->collection) {
BKE_collection_compat_blend_read_expand(expander, sce->collection);
}
#endif
if (sce->r.bake.cage_object) {
BLO_expand(expander, sce->r.bake.cage_object);
}
@ -3017,6 +3004,11 @@ bool BKE_scene_uses_cycles(const Scene *scene)
return STREQ(scene->r.engine, RE_engine_id_CYCLES);
}
bool BKE_scene_uses_shader_previews(const Scene *scene)
{
return BKE_scene_uses_blender_eevee(scene) || BKE_scene_uses_cycles(scene);
}
/* This enumeration has to match the one defined in the Cycles addon. */
enum eCyclesFeatureSet {
CYCLES_FEATURES_SUPPORTED = 0,

View File

@ -2275,7 +2275,8 @@ static void softbody_calc_forces(
/* check conditions for various options */
do_deflector = query_external_colliders(depsgraph, sb->collision_group);
#if 0
do_selfcollision=((ob->softflag & OB_SB_EDGES) && (sb->bspring)&& (ob->softflag & OB_SB_SELF));
do_selfcollision = ((ob->softflag & OB_SB_EDGES) && (sb->bspring) &&
(ob->softflag & OB_SB_SELF));
#endif
do_springcollision = do_deflector && (ob->softflag & OB_SB_EDGES) &&
(ob->softflag & OB_SB_EDGECOLL);

View File

@ -458,71 +458,38 @@ void BKE_sound_exit_once()
# if 0
bSound *BKE_sound_new_buffer(Main *bmain, bSound *source)
{
bSound *sound = nullptr;
bSound *sound = nullptr;
char name[MAX_ID_NAME + 5];
BLI_string_join(name, sizeof(name), "buf_", source->id.name);
sound = BKE_libblock_alloc(bmain, ID_SO, name);
sound->child_sound = source;
sound->type = SOUND_TYPE_BUFFER;
char name[MAX_ID_NAME + 5];
BLI_string_join(name, sizeof(name), "buf_", source->id.name);
sound_load(bmain, sound);
sound = BKE_libblock_alloc(bmain, ID_SO, name);
sound->child_sound = source;
sound->type = SOUND_TYPE_BUFFER;
sound_load(bmain, sound);
return sound;
return sound;
}
bSound *BKE_sound_new_limiter(Main *bmain, bSound *source, float start, float end)
{
bSound *sound = nullptr;
bSound *sound = nullptr;
char name[MAX_ID_NAME + 5];
BLI_string_join(name, sizeof(name), "lim_", source->id.name);
sound = BKE_libblock_alloc(bmain, ID_SO, name);
sound->child_sound = source;
sound->start = start;
sound->end = end;
sound->type = SOUND_TYPE_LIMITER;
char name[MAX_ID_NAME + 5];
BLI_string_join(name, sizeof(name), "lim_", source->id.name);
sound_load(bmain, sound);
sound = BKE_libblock_alloc(bmain, ID_SO, name);
sound->child_sound = source;
sound->start = start;
sound->end = end;
sound->type = SOUND_TYPE_LIMITER;
sound_load(bmain, sound);
return sound;
return sound;
}
# endif
@ -572,8 +539,8 @@ static void sound_load_audio(Main *bmain, bSound *sound, bool free_waveform)
/* XXX unused currently */
# if 0
switch (sound->type) {
case SOUND_TYPE_FILE:
switch (sound->type) {
case SOUND_TYPE_FILE:
# endif
{
char fullpath[FILE_MAX];
@ -596,16 +563,18 @@ case SOUND_TYPE_FILE:
}
/* XXX unused currently */
# if 0
break;
}
case SOUND_TYPE_BUFFER: if (sound->child_sound && sound->child_sound->handle) {
sound->handle = AUD_bufferSound(sound->child_sound->handle);
}
break;
case SOUND_TYPE_LIMITER: if (sound->child_sound && sound->child_sound->handle) {
sound->handle = AUD_limitSound(sound->child_sound, sound->start, sound->end);
}
break;
break;
}
case SOUND_TYPE_BUFFER:
if (sound->child_sound && sound->child_sound->handle) {
sound->handle = AUD_bufferSound(sound->child_sound->handle);
}
break;
case SOUND_TYPE_LIMITER:
if (sound->child_sound && sound->child_sound->handle) {
sound->handle = AUD_limitSound(sound->child_sound, sound->start, sound->end);
}
break;
}
# endif
if (sound->flags & SOUND_FLAGS_MONO) {
@ -1332,17 +1301,17 @@ bool BKE_sound_stream_info_get(Main *main,
# include "BLI_utildefines.h"
void BKE_sound_force_device(const char * /*device*/) {}
void BKE_sound_init_once(void) {}
void BKE_sound_init_once() {}
void BKE_sound_init(Main * /*bmain*/) {}
void BKE_sound_exit(void) {}
void BKE_sound_exit_once(void) {}
void BKE_sound_exit() {}
void BKE_sound_exit_once() {}
void BKE_sound_cache(bSound * /*sound*/) {}
void BKE_sound_delete_cache(bSound * /*sound*/) {}
void BKE_sound_load(Main * /*bmain*/, bSound * /*sound*/) {}
void BKE_sound_create_scene(Scene * /*scene*/) {}
void BKE_sound_destroy_scene(Scene * /*scene*/) {}
void BKE_sound_lock(void) {}
void BKE_sound_unlock(void) {}
void BKE_sound_lock() {}
void BKE_sound_unlock() {}
void BKE_sound_reset_scene_specs(Scene * /*scene*/) {}
void BKE_sound_mute_scene(Scene * /*scene*/, int /*muted*/) {}
void *BKE_sound_scene_add_scene_sound(Scene * /*scene*/,
@ -1421,7 +1390,7 @@ void BKE_sound_set_scene_sound_pitch_constant_range(void * /*handle*/,
float /*pitch*/)
{
}
float BKE_sound_get_length(struct Main * /*bmain*/, bSound * /*sound*/)
float BKE_sound_get_length(Main * /*bmain*/, bSound * /*sound*/)
{
return 0;
}
@ -1433,14 +1402,12 @@ char **BKE_sound_get_device_names()
void BKE_sound_free_waveform(bSound * /*sound*/) {}
bool BKE_sound_info_get(struct Main * /*main*/,
struct bSound * /*sound*/,
SoundInfo * /*sound_info*/)
bool BKE_sound_info_get(Main * /*main*/, bSound * /*sound*/, SoundInfo * /*sound_info*/)
{
return false;
}
bool BKE_sound_stream_info_get(struct Main * /*main*/,
bool BKE_sound_stream_info_get(Main * /*main*/,
const char * /*filepath*/,
int /*stream*/,
SoundStreamInfo * /*sound_info*/)

View File

@ -146,7 +146,7 @@ static bUnitDef buMetricLenDef[] = {
{"decimeter", "decimeters", "dm", nullptr, "10 Centimeters", "DECIMETERS", UN_SC_DM, 0.0, B_UNIT_DEF_SUPPRESS}, {"centimeter", "centimeters", "cm", nullptr, "Centimeters", "CENTIMETERS", UN_SC_CM, 0.0, B_UNIT_DEF_NONE}, {"millimeter", "millimeters", "mm", nullptr, "Millimeters", "MILLIMETERS", UN_SC_MM, 0.0, B_UNIT_DEF_NONE | B_UNIT_DEF_TENTH}, {"micrometer", "micrometers", "µm", "um", "Micrometers", "MICROMETERS", UN_SC_UM, 0.0, B_UNIT_DEF_NONE},
/* These get displayed because of float precision problems in the transform header,
* could work around, but for now probably people won't use these. */
* could work around, but for now probably people won't use these. */
#if 0
{"nanometer", "Nanometers", "nm", nullptr, 0.000000001, 0.0, B_UNIT_DEF_NONE}, {"picometer", "Picometers", "pm", nullptr, 0.000000000001, 0.0, B_UNIT_DEF_NONE},
#endif
@ -201,10 +201,8 @@ static bUnitDef buImperialMassDef[] = {
{"ounce", "ounces", "oz", nullptr, "Ounces", "OUNCES", UN_SC_OZ, 0.0, B_UNIT_DEF_NONE}, NULL_UNIT, };
static bUnitCollection buImperialMassCollection = {buImperialMassDef, 3, 0, UNIT_COLLECTION_LENGTH(buImperialMassDef)};
/* Even if user scales the system to a point where km^3 is used, velocity and
* acceleration aren't scaled: that's why we have so few units for them. */
* acceleration aren't scaled: that's why we have so few units for them. */
/* Velocity. */
static bUnitDef buMetricVelDef[] = {

View File

@ -53,6 +53,15 @@ char *BLI_strdupn(const char *str, size_t len) ATTR_MALLOC ATTR_WARN_UNUSED_RESU
*/
char *BLI_strdup(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) ATTR_MALLOC;
/**
* Duplicates the C-string \a str into a newly mallocN'd
* string and returns it.
*
* \param str: The string to be duplicated, can be null
* \retval Returns the duplicated string or null if \a str is null
*/
char *BLI_strdup_null(const char *str) ATTR_WARN_UNUSED_RESULT ATTR_MALLOC;
/**
* Appends the two strings, and returns new mallocN'ed string
* \param str1: first string for copy

View File

@ -22,6 +22,11 @@ MINLINE float safe_modf(float a, float b)
return (b != 0.0f) ? fmodf(a, b) : 0.0f;
}
MINLINE float safe_floored_modf(float a, float b)
{
return (b != 0.0f) ? a - floorf(a / b) * b : 0.0f;
}
MINLINE float safe_logf(float a, float base)
{
if (UNLIKELY(a <= 0.0f || base <= 0.0f)) {

View File

@ -795,14 +795,15 @@ void dist_squared_to_projected_aabb_precalc(struct DistProjectedAABBPrecalc *pre
float projmat_trans[4][4];
transpose_m4_m4(projmat_trans, projmat);
if (!isect_plane_plane_plane_v3(
projmat_trans[0], projmat_trans[1], projmat_trans[3], precalc->ray_origin)) {
projmat_trans[0], projmat_trans[1], projmat_trans[3], precalc->ray_origin))
{
/* Orthographic projection. */
isect_plane_plane_v3(px, py, precalc->ray_origin, precalc->ray_direction);
}
else {
/* Perspective projection. */
cross_v3_v3v3(precalc->ray_direction, py, px);
//normalize_v3(precalc->ray_direction);
// normalize_v3(precalc->ray_direction);
}
#else
if (!isect_plane_plane_v3(px, py, precalc->ray_origin, precalc->ray_direction)) {
@ -1870,7 +1871,7 @@ bool isect_ray_tri_watertight_v3(const float ray_origin[3],
* otherwise we won't match any of the other intersect functions here...
* which would be confusing. */
#if 0
|| (sign_T > *r_lambda * xor_signmask(det, sign_mask))
|| (sign_T > *r_lambda * xor_signmask(det, sign_mask))
#endif
)
{

View File

@ -42,6 +42,11 @@ char *BLI_strdup(const char *str)
return BLI_strdupn(str, strlen(str));
}
char *BLI_strdup_null(const char *str)
{
return (str != NULL) ? BLI_strdupn(str, strlen(str)) : NULL;
}
char *BLI_strdupcat(const char *__restrict str1, const char *__restrict str2)
{
/* include the NULL terminator of str2 only */

View File

@ -3377,6 +3377,7 @@ static BHead *read_userdef(BlendFileData *bfd, FileData *fd, BHead *bhead)
BLO_read_list(reader, &user->autoexec_paths);
BLO_read_list(reader, &user->script_directories);
BLO_read_list(reader, &user->asset_libraries);
BLO_read_list(reader, &user->extension_repos);
LISTBASE_FOREACH (wmKeyMap *, keymap, &user->user_keymaps) {
keymap->modal_items = nullptr;

File diff suppressed because it is too large Load Diff

View File

@ -251,168 +251,6 @@ static void do_version_workspaces_after_lib_link(Main *bmain)
}
}
#ifdef USE_COLLECTION_COMPAT_28
enum {
COLLECTION_DEPRECATED_VISIBLE = (1 << 0),
COLLECTION_DEPRECATED_VIEWPORT = (1 << 0),
COLLECTION_DEPRECATED_SELECTABLE = (1 << 1),
COLLECTION_DEPRECATED_DISABLED = (1 << 2),
COLLECTION_DEPRECATED_RENDER = (1 << 3),
};
static void do_version_view_layer_visibility(ViewLayer *view_layer)
{
/* Convert from deprecated VISIBLE flag to DISABLED */
LISTBASE_FOREACH (LayerCollection *, lc, &view_layer->layer_collections) {
if (lc->flag & COLLECTION_DEPRECATED_DISABLED) {
lc->flag &= ~COLLECTION_DEPRECATED_DISABLED;
}
if ((lc->flag & COLLECTION_DEPRECATED_VISIBLE) == 0) {
lc->flag |= COLLECTION_DEPRECATED_DISABLED;
}
lc->flag |= COLLECTION_DEPRECATED_VIEWPORT | COLLECTION_DEPRECATED_RENDER;
}
}
static void do_version_layer_collection_pre(ViewLayer *view_layer,
ListBase *lb,
GSet *enabled_set,
GSet *selectable_set)
{
/* Convert from deprecated DISABLED to new layer collection and collection flags */
LISTBASE_FOREACH (LayerCollection *, lc, lb) {
if (lc->scene_collection) {
if (!(lc->flag & COLLECTION_DEPRECATED_DISABLED)) {
BLI_gset_insert(enabled_set, lc->scene_collection);
}
if (lc->flag & COLLECTION_DEPRECATED_SELECTABLE) {
BLI_gset_insert(selectable_set, lc->scene_collection);
}
}
do_version_layer_collection_pre(
view_layer, &lc->layer_collections, enabled_set, selectable_set);
}
}
static void do_version_layer_collection_post(ViewLayer *view_layer,
ListBase *lb,
GSet *enabled_set,
GSet *selectable_set,
GHash *collection_map)
{
/* Apply layer collection exclude flags. */
LISTBASE_FOREACH (LayerCollection *, lc, lb) {
if (!(lc->collection->flag & COLLECTION_IS_MASTER)) {
SceneCollection *sc = static_cast<SceneCollection *>(
BLI_ghash_lookup(collection_map, lc->collection));
const bool enabled = (sc && BLI_gset_haskey(enabled_set, sc));
const bool selectable = (sc && BLI_gset_haskey(selectable_set, sc));
if (!enabled) {
lc->flag |= LAYER_COLLECTION_EXCLUDE;
}
if (enabled && !selectable) {
lc->collection->flag |= COLLECTION_HIDE_SELECT;
}
}
do_version_layer_collection_post(
view_layer, &lc->layer_collections, enabled_set, selectable_set, collection_map);
}
}
static void do_version_scene_collection_convert(
Main *bmain, ID *id, SceneCollection *sc, Collection *collection, GHash *collection_map)
{
if (collection_map) {
BLI_ghash_insert(collection_map, collection, sc);
}
for (SceneCollection *nsc = static_cast<SceneCollection *>(sc->scene_collections.first);
nsc != nullptr;)
{
SceneCollection *nsc_next = nsc->next;
Collection *ncollection = BKE_collection_add(bmain, collection, nsc->name);
ncollection->id.lib = id->lib;
do_version_scene_collection_convert(bmain, id, nsc, ncollection, collection_map);
nsc = nsc_next;
}
LISTBASE_FOREACH (LinkData *, link, &sc->objects) {
Object *ob = static_cast<Object *>(link->data);
if (ob) {
BKE_collection_object_add_notest(bmain, collection, ob);
id_us_min(&ob->id);
}
}
BLI_freelistN(&sc->objects);
MEM_freeN(sc);
}
static void do_version_group_collection_to_collection(Main *bmain, Collection *group)
{
/* Convert old 2.8 group collections to new unified collections. */
if (group->collection) {
do_version_scene_collection_convert(bmain, &group->id, group->collection, group, nullptr);
}
group->collection = nullptr;
group->view_layer = nullptr;
id_fake_user_set(&group->id);
}
static void do_version_scene_collection_to_collection(Main *bmain, Scene *scene)
{
/* Convert old 2.8 scene collections to new unified collections. */
/* Temporarily clear view layers so we don't do any layer collection syncing
* and destroy old flags that we want to restore. */
ListBase view_layers = scene->view_layers;
BLI_listbase_clear(&scene->view_layers);
if (!scene->master_collection) {
scene->master_collection = BKE_collection_master_add(scene);
}
/* Convert scene collections. */
GHash *collection_map = BLI_ghash_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, __func__);
if (scene->collection) {
do_version_scene_collection_convert(
bmain, &scene->id, scene->collection, scene->master_collection, collection_map);
scene->collection = nullptr;
}
scene->view_layers = view_layers;
/* Convert layer collections. */
LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
GSet *enabled_set = BLI_gset_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, __func__);
GSet *selectable_set = BLI_gset_new(BLI_ghashutil_ptrhash, BLI_ghashutil_ptrcmp, __func__);
do_version_layer_collection_pre(
view_layer, &view_layer->layer_collections, enabled_set, selectable_set);
BKE_layer_collection_doversion_2_80(scene, view_layer);
BKE_layer_collection_sync(scene, view_layer);
do_version_layer_collection_post(
view_layer, &view_layer->layer_collections, enabled_set, selectable_set, collection_map);
BLI_gset_free(enabled_set, nullptr);
BLI_gset_free(selectable_set, nullptr);
BKE_layer_collection_sync(scene, view_layer);
}
BLI_ghash_free(collection_map, nullptr, nullptr);
}
#endif
static void do_version_layers_to_collections(Main *bmain, Scene *scene)
{
/* Since we don't have access to FileData we check the (always valid) first
@ -2342,11 +2180,7 @@ static void update_wave_node_directions_and_offset(bNodeTree *ntree)
void do_versions_after_linking_280(FileData *fd, Main *bmain)
{
bool use_collection_compat_28 = true;
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 280, 0)) {
use_collection_compat_28 = false;
/* Convert group layer visibility flags to hidden nested collection. */
LISTBASE_FOREACH (Collection *, collection, &bmain->collections) {
/* Add fake user for all existing groups. */
@ -2568,18 +2402,6 @@ void do_versions_after_linking_280(FileData *fd, Main *bmain)
}
}
#ifdef USE_COLLECTION_COMPAT_28
if (use_collection_compat_28 && !MAIN_VERSION_FILE_ATLEAST(bmain, 280, 14)) {
LISTBASE_FOREACH (Collection *, group, &bmain->collections) {
do_version_group_collection_to_collection(bmain, group);
}
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
do_version_scene_collection_to_collection(bmain, scene);
}
}
#endif
/* Update Curve object Shape Key data layout to include the Radius property */
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 280, 23)) {
LISTBASE_FOREACH (Curve *, cu, &bmain->curves) {
@ -3150,11 +2972,7 @@ ENUM_OPERATORS(eNTreeDoVersionErrors, ~int8_t{});
/* NOLINTNEXTLINE: readability-function-size */
void blo_do_versions_280(FileData *fd, Library * /*lib*/, Main *bmain)
{
bool use_collection_compat_28 = true;
if (!MAIN_VERSION_FILE_ATLEAST(bmain, 280, 0)) {
use_collection_compat_28 = false;
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
scene->r.gauss = 1.5f;
}
@ -3272,24 +3090,6 @@ void blo_do_versions_280(FileData *fd, Library * /*lib*/, Main *bmain)
"shader nodes.\n");
}
#ifdef USE_COLLECTION_COMPAT_28
if (use_collection_compat_28 &&
(DNA_struct_elem_find(fd->filesdna, "ViewLayer", "FreestyleConfig", "freestyle_config") ==
false) &&
DNA_struct_elem_find(fd->filesdna, "Scene", "ListBase", "view_layers"))
{
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
view_layer->flag |= VIEW_LAYER_FREESTYLE;
view_layer->layflag = 0x7FFF; /* solid Z-transparency halo edge strand. */
view_layer->passflag = SCE_PASS_COMBINED | SCE_PASS_Z;
view_layer->pass_alpha_threshold = 0.5f;
BKE_freestyle_config_init(&view_layer->freestyle_config);
}
}
}
#endif
{
/* Init grease pencil edit line color */
if (!DNA_struct_elem_find(fd->filesdna, "bGPdata", "float", "line_color[4]")) {
@ -3334,22 +3134,6 @@ void blo_do_versions_280(FileData *fd, Library * /*lib*/, Main *bmain)
}
}
#ifdef USE_COLLECTION_COMPAT_28
if (use_collection_compat_28 && !MAIN_VERSION_FILE_ATLEAST(bmain, 280, 3)) {
LISTBASE_FOREACH (Scene *, scene, &bmain->scenes) {
LISTBASE_FOREACH (ViewLayer *, view_layer, &scene->view_layers) {
do_version_view_layer_visibility(view_layer);
}
}
LISTBASE_FOREACH (Collection *, group, &bmain->collections) {
if (group->view_layer != nullptr) {
do_version_view_layer_visibility(group->view_layer);
}
}
}
#endif
/* Files from this version included do get a valid `win->screen` pointer written for backward
* compatibility, however this should never be used nor needed, so clear these pointers here. */
if (MAIN_VERSION_FILE_ATLEAST(bmain, 280, 1)) {

View File

@ -847,6 +847,10 @@ void blo_do_versions_userdef(UserDef *userdef)
#endif
}
if (!USER_VERSION_ATLEAST(400, 15)) {
userdef->node_preview_res = 120;
}
/**
* Versioning code until next subversion bump goes here.
*

View File

@ -934,6 +934,10 @@ static void write_userdef(BlendWriter *writer, const UserDef *userdef)
BLO_write_struct(writer, bUserAssetLibrary, asset_library_ref);
}
LISTBASE_FOREACH (const bUserExtensionRepo *, repo_ref, &userdef->extension_repos) {
BLO_write_struct(writer, bUserExtensionRepo, repo_ref);
}
LISTBASE_FOREACH (const uiStyle *, style, &userdef->uistyles) {
BLO_write_struct(writer, uiStyle, style);
}

View File

@ -471,7 +471,7 @@ bool BM_mesh_boolean_knife(BMesh *bm,
}
#else
bool BM_mesh_boolean(BMesh * /*bm*/,
struct BMLoop *(*looptris)[3],
BMLoop *(*looptris)[3],
const int /*looptris_tot*/,
int (*test_fn)(BMFace *, void *),
void * /*user_data*/,
@ -494,7 +494,7 @@ bool BM_mesh_boolean(BMesh * /*bm*/,
* to the intersection result faces.
*/
bool BM_mesh_boolean_knife(BMesh * /*bm*/,
struct BMLoop *(*looptris)[3],
BMLoop *(*looptris)[3],
const int /*looptris_tot*/,
int (*test_fn)(BMFace *, void *),
void * /*user_data*/,

View File

@ -76,6 +76,9 @@ void MathNode::convert_to_operations(NodeConverter &converter,
case NODE_MATH_MODULO:
operation = new MathModuloOperation();
break;
case NODE_MATH_FLOORED_MODULO:
operation = new MathFlooredModuloOperation();
break;
case NODE_MATH_ABSOLUTE:
operation = new MathAbsoluteOperation();
break;

View File

@ -589,6 +589,36 @@ void MathModuloOperation::update_memory_buffer_partial(BuffersIterator<float> &i
}
}
void MathFlooredModuloOperation::execute_pixel_sampled(float output[4],
float x,
float y,
PixelSampler sampler)
{
float input_value1[4];
float input_value2[4];
input_value1_operation_->read_sampled(input_value1, x, y, sampler);
input_value2_operation_->read_sampled(input_value2, x, y, sampler);
if (input_value2[0] == 0) {
output[0] = 0.0;
}
else {
output[0] = input_value1[0] - floorf(input_value1[0] / input_value2[0]) * input_value2[0];
}
clamp_if_needed(output);
}
void MathFlooredModuloOperation::update_memory_buffer_partial(BuffersIterator<float> &it)
{
for (; !it.is_end(); ++it) {
const float value2 = *it.in(1);
*it.out = (value2 == 0) ? 0 : *it.in(0) - floorf(*it.in(0) / value2) * value2;
clamp_when_enabled(it.out);
}
}
void MathAbsoluteOperation::execute_pixel_sampled(float output[4],
float x,
float y,

View File

@ -224,6 +224,14 @@ class MathModuloOperation : public MathBaseOperation {
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class MathFlooredModuloOperation : public MathBaseOperation {
public:
void execute_pixel_sampled(float output[4], float x, float y, PixelSampler sampler) override;
protected:
void update_memory_buffer_partial(BuffersIterator<float> &it) override;
};
class MathAbsoluteOperation : public MathBaseOperation {
public:
void execute_pixel_sampled(float output[4], float x, float y, PixelSampler sampler) override;

View File

@ -317,4 +317,3 @@ if(WITH_OPENCOLORIO)
endif()
blender_add_lib(bf_realtime_compositor "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")

View File

@ -386,11 +386,13 @@ void dof_gather_accumulate_sample_pair(DofGatherData pair_data[2],
/* TODO(@fclem): Promote to parameter? dither with Noise? */
const float mirroring_min_distance = 15.0;
if (pair_data[0].coc < mirroring_threshold &&
(pair_data[1].coc - mirroring_min_distance) > pair_data[0].coc) {
(pair_data[1].coc - mirroring_min_distance) > pair_data[0].coc)
{
pair_data[1].coc = pair_data[0].coc;
}
else if (pair_data[1].coc < mirroring_threshold &&
(pair_data[0].coc - mirroring_min_distance) > pair_data[1].coc) {
(pair_data[0].coc - mirroring_min_distance) > pair_data[1].coc)
{
pair_data[0].coc = pair_data[1].coc;
}
#endif

View File

@ -350,7 +350,7 @@ void IrradianceCache::set_view(View & /*view*/)
grid_upload_ps_.bind_texture("irradiance_d_tx", &irradiance_d_tx);
grid_upload_ps_.bind_texture("validity_tx", &validity_tx);
grid_upload_ps_.bind_image("irradiance_atlas_img", &irradiance_atlas_tx_);
/* NOTE: We are read and writting the same texture that we are sampling from. If that causes an
/* NOTE: We are read and writing the same texture that we are sampling from. If that causes an
* issue, we should revert to manual trilinear interpolation. */
grid_upload_ps_.bind_texture("irradiance_atlas_tx", &irradiance_atlas_tx_);
/* If visibility is invalid, either it is still baking and visibility is stored with

View File

@ -49,7 +49,6 @@ class World {
Instance &inst_;
DefaultWorldNodeTree default_tree;
bool has_volume_ = false;
/* Used to detect if world change. */
::World *prev_original_world = nullptr;

View File

@ -216,4 +216,4 @@ vec3 sample_uniform_cone(vec3 rand, float angle, vec3 N, vec3 T, vec3 B)
return tH * mat3(N, T, B);
}
/** \} */
/** \} */

View File

@ -148,11 +148,13 @@ void dof_gather_accumulate_sample_pair(DofGatherData pair_data[2],
/* TODO(fclem) Promote to parameter? dither with Noise? */
const float mirroring_min_distance = 15.0;
if (pair_data[0].coc < mirroring_threshold &&
(pair_data[1].coc - mirroring_min_distance) > pair_data[0].coc) {
(pair_data[1].coc - mirroring_min_distance) > pair_data[0].coc)
{
pair_data[1].coc = pair_data[0].coc;
}
else if (pair_data[1].coc < mirroring_threshold &&
(pair_data[0].coc - mirroring_min_distance) > pair_data[1].coc) {
(pair_data[0].coc - mirroring_min_distance) > pair_data[1].coc)
{
pair_data[0].coc = pair_data[1].coc;
}
#endif

View File

@ -186,4 +186,4 @@ void main()
out_radiance = from_accumulation_space(out_radiance);
imageStore(out_radiance_img, texel_fullres, vec4(out_radiance, 0.0));
}
}

View File

@ -230,4 +230,4 @@ void main()
imageStore(out_radiance_img, texel_fullres, vec4(radiance_accum, 0.0));
imageStore(out_variance_img, texel_fullres, vec4(hit_variance));
imageStore(out_hit_depth_img, texel_fullres, vec4(hit_depth));
}
}

View File

@ -209,4 +209,4 @@ void main()
float out_variance = mix(in_variance, history_variance.x, mix_variance_fac);
/* This is feedback next frame as variance_history_tx. */
imageStore(out_variance_img, texel_fullres, vec4(out_variance));
}
}

View File

@ -64,4 +64,4 @@ void main()
imageStore(tile_mask_img, tile_co, uvec4(tile_mask));
}
}
}

View File

@ -36,4 +36,4 @@ void main()
uint tile_index = atomicAdd(ray_dispatch_buf.num_groups_x, 1u);
ray_tiles_buf[tile_index] = packUvec2x16(uvec2(tile));
}
}
}

View File

@ -73,4 +73,4 @@ void main()
atlas_store(result[2], atlas_coord, 2);
atlas_store(result[3], atlas_coord, 3);
}
}
}

View File

@ -157,7 +157,8 @@ vec3 volume_shadow(LightData ld, vec3 ray_wpos, vec3 L, float l_dist)
# if 0 /* TODO use shadow maps instead. */
vec3 shadow = vec3(1.0);
for (float s = 1.0; s < VOLUMETRIC_SHADOW_MAX_STEP && s <= volumes_info_buf.shadow_steps; s += 1.0) {
for (float s = 1.0; s < VOLUMETRIC_SHADOW_MAX_STEP && s <= volumes_info_buf.shadow_steps;
s += 1.0) {
vec3 pos = ray_wpos + L * s;
vec3 s_extinction = volume_participating_media_extinction(pos, volume_extinction);
shadow *= exp(-s_extinction * dd);

View File

@ -2834,7 +2834,7 @@ void DRW_draw_select_id(Depsgraph *depsgraph, ARegion *region, View3D *v3d, cons
drw_engines_cache_finish();
drw_task_graph_deinit();
#if 0 /* This is a workaround to a nasty bug that seems to be a nasty driver bug. (See #69377) */
#if 0 /* This is a workaround to a nasty bug that seems to be a nasty driver bug (see #69377). */
DRW_render_instance_buffer_finish();
#else
DST.buffer_finish_called = true;

View File

@ -353,6 +353,11 @@ bool ANIM_is_active_channel(bAnimListElem *ale)
bGPDlayer *gpl = (bGPDlayer *)ale->data;
return gpl->flag & GP_LAYER_ACTIVE;
}
case ANIMTYPE_GREASE_PENCIL_LAYER: {
GreasePencil *grease_pencil = reinterpret_cast<GreasePencil *>(ale->id);
return grease_pencil->is_layer_active(
static_cast<blender::bke::greasepencil::Layer *>(ale->data));
}
/* These channel types do not have active flags. */
case ANIMTYPE_MASKLAYER:
case ANIMTYPE_SHAPEKEY:
@ -3632,20 +3637,31 @@ static int click_select_channel_gplayer(bContext *C,
static int click_select_channel_grease_pencil_layer(bContext *C,
bAnimContext *ac,
bAnimListElem *ale,
const short /*selectmode*/,
const short selectmode,
const int /*filter*/)
{
/* TODO: Implement other selection modes. */
GreasePencilLayer *layer = static_cast<GreasePencilLayer *>(ale->data);
using namespace blender::bke::greasepencil;
Layer *layer = static_cast<Layer *>(ale->data);
GreasePencil *grease_pencil = reinterpret_cast<GreasePencil *>(ale->id);
/* Clear previous channel selection and set active flag on current selection */
ANIM_anim_channels_select_set(ac, ACHANNEL_SETFLAG_CLEAR);
if (selectmode == SELECT_INVERT) {
layer->base.flag ^= GP_LAYER_TREE_NODE_SELECT;
}
else if (selectmode == SELECT_EXTEND_RANGE) {
ANIM_anim_channels_select_set(ac, ACHANNEL_SETFLAG_EXTEND_RANGE);
animchannel_select_range(ac, ale);
}
else {
ANIM_anim_channels_select_set(ac, ACHANNEL_SETFLAG_CLEAR);
layer->base.flag |= GP_LAYER_TREE_NODE_SELECT;
}
layer->base.flag |= GP_LAYER_TREE_NODE_SELECT;
grease_pencil->active_layer = layer;
/* Active channel is not changed during range select. */
if (layer->is_selected() && (selectmode != SELECT_EXTEND_RANGE)) {
grease_pencil->set_active_layer(layer);
}
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_SELECTED, nullptr);
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, nullptr);
return (ND_ANIMCHAN | NA_EDITED);
}
@ -3787,8 +3803,7 @@ static int mouse_anim_channels(bContext *C,
/*todo*/
break;
case ANIMTYPE_GREASE_PENCIL_LAYER:
notifierFlags |= click_select_channel_grease_pencil_layer(
C, ac, ale, SELECT_REPLACE, filter);
notifierFlags |= click_select_channel_grease_pencil_layer(C, ac, ale, selectmode, filter);
break;
case ANIMTYPE_MASKDATABLOCK:
notifierFlags |= click_select_channel_maskdatablock(ale);

View File

@ -504,11 +504,10 @@ static float normalization_factor_get(Scene *scene, FCurve *fcu, short flag, flo
float min_coord = FLT_MAX;
fcurve_scene_coord_range_get(scene, fcu, &min_coord, &max_coord);
/* We use an ulps-based floating point comparison here, with the
/* We use an ULPS-based floating point comparison here, with the
* rationale that if there are too few possible values between
* `min_coord` and `max_coord`, then after display normalization it
* will certainly be a weird quantized experience for the user anyway.
*/
* will certainly be a weird quantized experience for the user anyway. */
if (min_coord < max_coord && ulp_diff_ff(min_coord, max_coord) > 256) {
/* Normalize. */
const float range = max_coord - min_coord;

View File

@ -324,9 +324,8 @@ int ANIM_add_driver_with_target(ReportList *reports,
/* handle curve-property mappings based on mapping_type */
switch (mapping_type) {
case CREATEDRIVER_MAPPING_N_N: /* N-N - Try to match as much as possible, * then use the first
one */
{
/* N-N - Try to match as much as possible, then use the first one. */
case CREATEDRIVER_MAPPING_N_N: {
/* Use the shorter of the two (to avoid out of bounds access) */
int dst_len = RNA_property_array_check(prop) ? RNA_property_array_length(&ptr, prop) : 1;
int src_len = RNA_property_array_check(prop) ? RNA_property_array_length(&ptr2, prop2) : 1;
@ -350,8 +349,8 @@ int ANIM_add_driver_with_target(ReportList *reports,
}
break;
}
case CREATEDRIVER_MAPPING_1_N: /* 1-N - Specified target index for all */
/* 1-N - Specified target index for all. */
case CREATEDRIVER_MAPPING_1_N:
default: {
int len = RNA_property_array_check(prop) ? RNA_property_array_length(&ptr, prop) : 1;
@ -373,8 +372,8 @@ int ANIM_add_driver_with_target(ReportList *reports,
break;
}
case CREATEDRIVER_MAPPING_1_1: /* 1-1 - Use the specified index (unless -1) */
{
/* 1-1 - Use the specified index (unless -1). */
case CREATEDRIVER_MAPPING_1_1: {
done_tot = add_driver_with_target(reports,
dst_id,
dst_path,

View File

@ -54,8 +54,10 @@ BLI_INLINE bool is_cfra_lt(const float a, const float b)
/* --------------- */
/* Animation data of Grease Pencil cels,
which are drawings positioned in time. */
/**
* Animation data of Grease Pencil cels,
* which are drawings positioned in time.
*/
struct GreasePencilCel {
int frame_number;
GreasePencilFrame frame;

View File

@ -166,9 +166,9 @@ static void dial_geom_draw(const float color[4],
imm_draw_circle_partial_wire_3d(
pos, 0.0f, 0.0f, 0.0f, 1.0f, DIAL_RESOLUTION, -arc_partial_deg / 2, arc_partial_deg);
# if 0
if (arc_inner_factor != 0.0f) {
BLI_assert(0);
}
if (arc_inner_factor != 0.0f) {
BLI_assert(0);
}
# endif
}
}

View File

@ -2469,9 +2469,9 @@ static int annotation_draw_modal(bContext *C, wmOperator *op, const wmEvent *eve
* Problem is that the stroke is converted to 3D only after it is finished.
* This approach should work better in tools that immediately apply in 3D space. */
#if 0
if (event->type == NDOF_MOTION) {
return OPERATOR_PASS_THROUGH;
}
if (event->type == NDOF_MOTION) {
return OPERATOR_PASS_THROUGH;
}
#endif
if (p->status == GP_STATUS_IDLING) {

View File

@ -172,5 +172,5 @@ void free_gpcopybuf();
void copy_gpdata();
void paste_gpdata();
void mirror_masklayer_frames( MaskLayer *mask_layer, short mode);
void mirror_masklayer_frames(MaskLayer *mask_layer, short mode);
#endif

View File

@ -0,0 +1,47 @@
/* SPDX-FileCopyrightText: 2023 Blender Foundation
*
* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
#include "RE_pipeline.h"
#include "IMB_imbuf.h"
struct bContext;
struct bNodeTree;
struct ImBuf;
struct Render;
namespace blender::ed::space_node {
struct NestedTreePreviews {
Render *previews_render = nullptr;
/** Use this map to keep track of the latest #ImBuf used (after freeing the render-result). */
blender::Map<int32_t, ImBuf *> previews_map;
int preview_size;
bool rendering = false;
bool restart_needed = false;
uint32_t cached_previews_refresh_state = -1;
uint32_t rendering_previews_refresh_state = -1;
NestedTreePreviews(const int size) : preview_size(size) {}
~NestedTreePreviews()
{
if (this->previews_render) {
RE_FreeRender(this->previews_render);
}
for (ImBuf *ibuf : this->previews_map.values()) {
IMB_freeImBuf(ibuf);
}
}
};
void free_previews(wmWindowManager &wm, SpaceNode &snode);
ImBuf *node_preview_acquire_ibuf(bNodeTree &ntree,
NestedTreePreviews &tree_previews,
const bNode &node);
void node_release_preview_ibuf(NestedTreePreviews &tree_previews);
NestedTreePreviews *get_nested_previews(const bContext &C, SpaceNode &snode);
void stop_preview_job(wmWindowManager &wm);
} // namespace blender::ed::space_node

View File

@ -9,6 +9,7 @@
#pragma once
#include "DNA_ID_enums.h"
#include "DNA_material_types.h"
#include "DNA_vec_types.h"
struct DEGEditorUpdateContext;
@ -22,6 +23,8 @@ struct ScrArea;
struct bContext;
struct bScreen;
struct PreviewImage;
struct ViewLayer;
struct World;
struct wmWindow;
struct wmWindowManager;
@ -64,7 +67,10 @@ enum ePreviewRenderMethod {
PR_ICON_DEFERRED = 2,
};
void ED_preview_ensure_dbase();
bool ED_check_engine_supports_preview(const Scene *scene);
const char *ED_preview_collection_name(ePreviewType pr_type);
void ED_preview_ensure_dbase(bool with_gpencil);
void ED_preview_free_dbase();
/**
@ -72,6 +78,17 @@ void ED_preview_free_dbase();
*/
bool ED_preview_id_is_supported(const ID *id);
void ED_preview_set_visibility(Main *pr_main,
Scene *scene,
ViewLayer *view_layer,
ePreviewType pr_type,
ePreviewRenderMethod pr_method);
struct World *ED_preview_prepare_world(Main *pr_main,
const Scene *scene,
const World *world,
ID_Type id_type,
ePreviewRenderMethod pr_method);
void ED_preview_shader_job(const bContext *C,
void *owner,
ID *id,

View File

@ -166,7 +166,7 @@ void uvedit_edge_select_shared_vert(const Scene *scene,
/**
* Selects shared UVs based on #sticky_flag.
*
* \param sticky_flag: Type of sticky selection :
* \param sticky_flag: Type of sticky selection:
* - #SI_STICKY_LOC: selects all UVs sharing same mesh vertex and UV coordinates.
* - #SI_STICKY_VERTEX: selects all UVs sharing same mesh vertex.
*/

View File

@ -756,9 +756,9 @@ void UI_popup_block_ex(bContext *C,
void *arg,
wmOperator *op);
#if 0 /* UNUSED */
void uiPupBlockOperator( bContext *C,
void uiPupBlockOperator(bContext *C,
uiBlockCreateFunc func,
wmOperator *op,
wmOperator *op,
wmOperatorCallContext opcontext);
#endif

View File

@ -1871,9 +1871,9 @@ static bool ui_selectcontext_begin(bContext *C, uiBut *but, uiSelectContextStore
}
/* ignored for now */
# if 0
else if (rna_type == PROP_BOOLEAN) {
other->val_b = RNA_property_boolean_get_index(&lptr, lprop, index);
}
else if (rna_type == PROP_BOOLEAN) {
other->val_b = RNA_property_boolean_get_index(&lptr, lprop, index);
}
# endif
}
else {
@ -1885,12 +1885,12 @@ static bool ui_selectcontext_begin(bContext *C, uiBut *but, uiSelectContextStore
}
/* ignored for now */
# if 0
else if (rna_type == PROP_BOOLEAN) {
other->val_b = RNA_property_boolean_get(&lptr, lprop);
}
else if (rna_type == PROP_ENUM) {
other->val_i = RNA_property_enum_get(&lptr, lprop);
}
else if (rna_type == PROP_BOOLEAN) {
other->val_b = RNA_property_boolean_get(&lptr, lprop);
}
else if (rna_type == PROP_ENUM) {
other->val_i = RNA_property_enum_get(&lptr, lprop);
}
# endif
}
}

View File

@ -21,6 +21,7 @@
#include "BLI_linklist.h"
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_math_vector_types.hh"
#include "BLI_memarena.h"
#include "BLI_smallhash.h"
#include "BLI_stack.h"
@ -64,6 +65,8 @@
#include "mesh_intern.h" /* Own include. */
using namespace blender;
/* Detect isolated holes and fill them. */
#define USE_NET_ISLAND_CONNECT
@ -147,8 +150,8 @@ struct KnifeLineHit {
};
struct KnifePosData {
float co[3];
float cage[3];
float3 co;
float3 cage;
/* At most one of vert, edge, or bmface should be non-null,
* saying whether the point is snapped to a vertex, edge, or in a face.
@ -1493,13 +1496,13 @@ static void knife_project_v2(const KnifeTool_OpData *kcd, const float co[3], flo
/* Ray is returned in world space. */
static void knife_input_ray_segment(KnifeTool_OpData *kcd,
const float mval[2],
const float ofs,
float r_origin[3],
float r_origin_ofs[3])
float r_end[3])
{
/* Unproject to find view ray. */
ED_view3d_unproject_v3(kcd->vc.region, mval[0], mval[1], 0.0f, r_origin);
ED_view3d_unproject_v3(kcd->vc.region, mval[0], mval[1], ofs, r_origin_ofs);
ED_view3d_win_to_segment_clipped(
kcd->vc.depsgraph, kcd->region, kcd->vc.v3d, mval, r_origin, r_end, false);
add_v3_v3(r_end, r_origin);
}
/* No longer used, but may be useful in the future. */
@ -1512,7 +1515,7 @@ static void UNUSED_FUNCTION(knifetool_recast_cageco)(KnifeTool_OpData *kcd,
float ray[3], ray_normal[3];
float co[3]; /* Unused. */
knife_input_ray_segment(kcd, mval, 1.0f, origin, origin_ofs);
knife_input_ray_segment(kcd, mval, origin, origin_ofs);
sub_v3_v3v3(ray, origin_ofs, origin);
normalize_v3_v3(ray_normal, ray);
@ -2850,7 +2853,6 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
void *val;
void **val_p;
float s[2], se1[2], se2[2], sint[2];
float r1[3], r2[3];
float d1, d2, lambda;
float vert_tol, vert_tol_sq;
float line_tol, line_tol_sq;
@ -3089,12 +3091,14 @@ static void knife_find_line_hits(KnifeTool_OpData *kcd)
d1 = len_v2v2(sint, se1);
d2 = len_v2v2(se2, se1);
if (!(d1 <= line_tol || d2 <= line_tol || fabsf(d1 - d2) <= line_tol)) {
float3 r1, r2;
float p_cage[3], p_cage_tmp[3];
lambda = d1 / d2;
/* Can't just interpolate between ends of kfe because
* that doesn't work with perspective transformation.
* Need to find 3d intersection of ray through sint. */
knife_input_ray_segment(kcd, sint, 1.0f, r1, r2);
knife_input_ray_segment(kcd, sint, r1, r2);
isect_kind = isect_line_line_v3(
kfe->v1->cageco, kfe->v2->cageco, r1, r2, p_cage, p_cage_tmp);
if (isect_kind >= 1 && point_is_visible(kcd, p_cage, sint, bm_elem_from_knife_edge(kfe))) {
@ -3210,19 +3214,16 @@ static BMFace *knife_find_closest_face(KnifeTool_OpData *kcd,
Object **r_ob,
uint *r_ob_index,
bool *is_space,
float r_co[3],
float r_cageco[3])
float3 &r_co,
float3 &r_cageco)
{
BMFace *f;
float dist = KMAXDIST;
float origin[3];
float origin_ofs[3];
float ray[3], ray_normal[3];
float3 origin;
float3 ray_normal;
/* Unproject to find view ray. */
knife_input_ray_segment(kcd, kcd->curr.mval, 1.0f, origin, origin_ofs);
sub_v3_v3v3(ray, origin_ofs, origin);
normalize_v3_v3(ray_normal, ray);
ED_view3d_win_to_ray_clipped(
kcd->vc.depsgraph, kcd->region, kcd->vc.v3d, kcd->curr.mval, origin, ray_normal, false);
f = knife_bvh_raycast(kcd, origin, ray_normal, 0.0f, nullptr, r_co, r_cageco, r_ob_index);
@ -3252,9 +3253,9 @@ static BMFace *knife_find_closest_face(KnifeTool_OpData *kcd,
/* Cheat for now; just put in the origin instead
* of a true coordinate on the face.
* This just puts a point 1.0f in front of the view. */
add_v3_v3v3(r_co, origin, ray);
r_co = origin + ray_normal;
/* Use this value for the cage location too as it's used to find near edges/vertices. */
copy_v3_v3(r_cageco, r_co);
r_cageco = r_co;
}
}
@ -3639,7 +3640,7 @@ static bool knife_snap_angle_relative(KnifeTool_OpData *kcd)
float ray_hit[3];
float lambda;
knife_input_ray_segment(kcd, kcd->curr.mval, 1.0f, curr_origin, curr_origin_ofs);
knife_input_ray_segment(kcd, kcd->curr.mval, curr_origin, curr_origin_ofs);
sub_v3_v3v3(curr_ray, curr_origin_ofs, curr_origin);
normalize_v3_v3(curr_ray_normal, curr_ray);
@ -3709,7 +3710,7 @@ static bool knife_snap_angle_relative(KnifeTool_OpData *kcd)
float prev_ray[3], prev_ray_normal[3];
float prev_co[3], prev_cage[3]; /* Unused. */
knife_input_ray_segment(kcd, kcd->prev.mval, 1.0f, prev_origin, prev_origin_ofs);
knife_input_ray_segment(kcd, kcd->prev.mval, prev_origin, prev_origin_ofs);
sub_v3_v3v3(prev_ray, prev_origin_ofs, prev_origin);
normalize_v3_v3(prev_ray_normal, prev_ray);
@ -3771,7 +3772,7 @@ static int knife_calculate_snap_ref_edges(KnifeTool_OpData *kcd)
float curr_ray[3], curr_ray_normal[3];
float curr_co[3], curr_cage[3]; /* Unused. */
knife_input_ray_segment(kcd, kcd->curr.mval, 1.0f, curr_origin, curr_origin_ofs);
knife_input_ray_segment(kcd, kcd->curr.mval, curr_origin, curr_origin_ofs);
sub_v3_v3v3(curr_ray, curr_origin_ofs, curr_origin);
normalize_v3_v3(curr_ray_normal, curr_ray);
@ -4274,7 +4275,7 @@ static int knife_update_active(KnifeTool_OpData *kcd)
float origin[3];
float origin_ofs[3];
knife_input_ray_segment(kcd, kcd->curr.mval, 1.0f, origin, origin_ofs);
knife_input_ray_segment(kcd, kcd->curr.mval, origin, origin_ofs);
if (!isect_line_plane_v3(
kcd->curr.cage, origin, origin_ofs, kcd->prev.cage, kcd->vc.rv3d->viewinv[2]))

View File

@ -4001,49 +4001,19 @@ static void brush_puff(PEData *data, int point_index, float mouse_distance)
/* NOLINTNEXTLINE: readability-redundant-preprocessor */
# if 0 /* Kind of works but looks worse than what's below. */
/* Move the unselected point on a vector based on the
* hair direction and the offset */
float c1[3], c2[3];
sub_v3_v3v3(dco, lastco, co);
mul_mat3_m4_v3(imat, dco); /* into particle space */
/* Move the unselected point on a vector based on the
* hair direction and the offset */
float c1[3], c2[3];
sub_v3_v3v3(dco, lastco, co);
mul_mat3_m4_v3(imat, dco); /* into particle space */
/* move the point along a vector perpendicular to the
* hairs direction, reduces odd kinks, */
cross_v3_v3v3(c1, ofs, dco);
cross_v3_v3v3(c2, c1, dco);
normalize_v3(c2);
mul_v3_fl(c2, len_v3(ofs));
add_v3_v3(key->co, c2);
/* move the point along a vector perpendicular to the
* hairs direction, reduces odd kinks, */
cross_v3_v3v3(c1, ofs, dco);
cross_v3_v3v3(c2, c1, dco);
normalize_v3(c2);
mul_v3_fl(c2, len_v3(ofs));
add_v3_v3(key->co, c2);
# else
/* Move the unselected point on a vector based on the
* the normal of the closest geometry */

View File

@ -157,7 +157,6 @@ struct IconPreview {
/** \name Preview for Buttons
* \{ */
static Main *G_pr_main = nullptr;
static Main *G_pr_main_grease_pencil = nullptr;
#ifndef WITH_HEADLESS
@ -180,21 +179,25 @@ static Main *load_main_from_memory(const void *blend, int blend_size)
}
#endif
void ED_preview_ensure_dbase()
void ED_preview_ensure_dbase(const bool with_gpencil)
{
#ifndef WITH_HEADLESS
static bool base_initialized = false;
static bool base_initialized_gpencil = false;
BLI_assert(BLI_thread_is_main());
if (!base_initialized) {
G_pr_main = load_main_from_memory(datatoc_preview_blend, datatoc_preview_blend_size);
G.pr_main = load_main_from_memory(datatoc_preview_blend, datatoc_preview_blend_size);
base_initialized = true;
}
if (!base_initialized_gpencil && with_gpencil) {
G_pr_main_grease_pencil = load_main_from_memory(datatoc_preview_grease_pencil_blend,
datatoc_preview_grease_pencil_blend_size);
base_initialized = true;
base_initialized_gpencil = true;
}
#endif
}
static bool check_engine_supports_preview(Scene *scene)
bool ED_check_engine_supports_preview(const Scene *scene)
{
RenderEngineType *type = RE_engines_find(scene->r.engine);
return (type->flag & RE_USE_PREVIEW) != 0;
@ -207,8 +210,8 @@ static bool preview_method_is_render(const ePreviewRenderMethod pr_method)
void ED_preview_free_dbase()
{
if (G_pr_main) {
BKE_main_free(G_pr_main);
if (G.pr_main) {
BKE_main_free(G.pr_main);
}
if (G_pr_main_grease_pencil) {
@ -225,7 +228,7 @@ static Scene *preview_get_scene(Main *pr_main)
return static_cast<Scene *>(pr_main->scenes.first);
}
static const char *preview_collection_name(const ePreviewType pr_type)
const char *ED_preview_collection_name(const ePreviewType pr_type)
{
switch (pr_type) {
case MA_FLAT:
@ -265,7 +268,7 @@ static void switch_preview_collection_visibility(ViewLayer *view_layer, const eP
{
/* Set appropriate layer as visible. */
LayerCollection *lc = static_cast<LayerCollection *>(view_layer->layer_collections.first);
const char *collection_name = preview_collection_name(pr_type);
const char *collection_name = ED_preview_collection_name(pr_type);
for (lc = static_cast<LayerCollection *>(lc->layer_collections.first); lc; lc = lc->next) {
if (STREQ(lc->collection->id.name + 2, collection_name)) {
@ -326,11 +329,11 @@ static void switch_preview_floor_visibility(Main *pr_main,
}
}
static void set_preview_visibility(Main *pr_main,
Scene *scene,
ViewLayer *view_layer,
const ePreviewType pr_type,
const ePreviewRenderMethod pr_method)
void ED_preview_set_visibility(Main *pr_main,
Scene *scene,
ViewLayer *view_layer,
const ePreviewType pr_type,
const ePreviewRenderMethod pr_method)
{
switch_preview_collection_visibility(view_layer, pr_type);
switch_preview_floor_visibility(pr_main, scene, view_layer, pr_method);
@ -443,13 +446,13 @@ static void preview_sync_exposure(World *dst, const World *src)
dst->range = src->range;
}
static World *preview_prepare_world(Main *pr_main,
const Scene *sce,
const World *world,
const ID_Type id_type,
const ePreviewRenderMethod pr_method)
World *ED_preview_prepare_world(Main *pr_main,
const Scene *scene,
const World *world,
const ID_Type id_type,
const ePreviewRenderMethod pr_method)
{
World *result = preview_get_world(pr_main, sce, id_type, pr_method);
World *result = preview_get_world(pr_main, scene, id_type, pr_method);
if (world) {
preview_sync_exposure(result, world);
}
@ -494,7 +497,7 @@ static Scene *preview_prepare_scene(
sce->r.cfra = scene->r.cfra;
/* Setup the world. */
sce->world = preview_prepare_world(
sce->world = ED_preview_prepare_world(
pr_main, sce, scene->world, static_cast<ID_Type>(id_type), sp->pr_method);
if (id_type == ID_TE) {
@ -531,7 +534,7 @@ static Scene *preview_prepare_scene(
(sp->pr_method == PR_ICON_RENDER && sp->pr_main == G_pr_main_grease_pencil) ?
MA_SPHERE_A :
(ePreviewType)mat->pr_type);
set_preview_visibility(pr_main, sce, view_layer, preview_type, sp->pr_method);
ED_preview_set_visibility(pr_main, sce, view_layer, preview_type, sp->pr_method);
}
else {
sce->display.render_aa = SCE_DISPLAY_AA_OFF;
@ -579,7 +582,7 @@ static Scene *preview_prepare_scene(
BLI_addtail(&pr_main->lights, la);
}
set_preview_visibility(pr_main, sce, view_layer, MA_LAMP, sp->pr_method);
ED_preview_set_visibility(pr_main, sce, view_layer, MA_LAMP, sp->pr_method);
if (sce->world) {
/* Only use lighting from the light. */
@ -608,7 +611,7 @@ static Scene *preview_prepare_scene(
BLI_addtail(&pr_main->worlds, wrld);
}
set_preview_visibility(pr_main, sce, view_layer, MA_SKY, sp->pr_method);
ED_preview_set_visibility(pr_main, sce, view_layer, MA_SKY, sp->pr_method);
sce->world = wrld;
}
@ -1522,7 +1525,7 @@ static void other_id_types_preview_render(IconPreview *ip,
}
if ((ma == nullptr) || (ma->gp_style == nullptr)) {
sp->pr_main = G_pr_main;
sp->pr_main = G.pr_main;
}
else {
sp->pr_main = G_pr_main_grease_pencil;
@ -1581,7 +1584,7 @@ static void icon_preview_startjob_all_sizes(void *customdata,
* necessary to know here what happens inside lower-level functions. */
const bool use_solid_render_mode = (ip->id != nullptr) && ELEM(GS(ip->id->name), ID_OB, ID_AC);
if (!use_solid_render_mode && preview_method_is_render(pr_method) &&
!check_engine_supports_preview(ip->scene))
!ED_check_engine_supports_preview(ip->scene))
{
continue;
}
@ -1929,7 +1932,7 @@ void ED_preview_icon_render(
bool stop = false, update = false;
float progress = 0.0f;
ED_preview_ensure_dbase();
ED_preview_ensure_dbase(true);
ip.bmain = CTX_data_main(C);
ip.scene = scene;
@ -1973,7 +1976,7 @@ void ED_preview_icon_job(
IconPreview *ip, *old_ip;
ED_preview_ensure_dbase();
ED_preview_ensure_dbase(true);
/* suspended start means it starts after 1 timer step, see WM_jobs_timer below */
wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C),
@ -2038,11 +2041,11 @@ void ED_preview_shader_job(const bContext *C,
/* Use workspace render only for buttons Window,
* since the other previews are related to the datablock. */
if (preview_method_is_render(method) && !check_engine_supports_preview(scene)) {
if (preview_method_is_render(method) && !ED_check_engine_supports_preview(scene)) {
return;
}
ED_preview_ensure_dbase();
ED_preview_ensure_dbase(true);
wm_job = WM_jobs_get(CTX_wm_manager(C),
CTX_wm_window(C),
@ -2075,7 +2078,7 @@ void ED_preview_shader_job(const bContext *C,
}
if ((ma == nullptr) || (ma->gp_style == nullptr)) {
sp->pr_main = G_pr_main;
sp->pr_main = G.pr_main;
}
else {
sp->pr_main = G_pr_main_grease_pencil;

View File

@ -41,6 +41,7 @@
#include "RE_pipeline.h"
#include "ED_node.hh"
#include "ED_node_preview.hh"
#include "ED_paint.hh"
#include "ED_render.hh"
#include "ED_view3d.hh"
@ -177,6 +178,11 @@ void ED_render_engine_changed(Main *bmain, const bool update_scene_data)
ED_render_engine_area_exit(bmain, area);
}
}
/* Invalidate all shader previews. */
blender::ed::space_node::stop_preview_job(*static_cast<wmWindowManager *>(bmain->wm.first));
LISTBASE_FOREACH (Material *, ma, &bmain->materials) {
BKE_material_make_node_previews_dirty(ma);
}
RE_FreePersistentData(nullptr);
/* Inform all render engines and draw managers. */
DEGEditorUpdateContext update_ctx = {nullptr};

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