Nodes: use auto registration for nodes #110686
|
@ -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)
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 = {};
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
@ -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. */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
))
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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]
|
|
@ -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")
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
|
@ -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
|
||||
|
|
|
@ -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).
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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*/)
|
||||
|
|
|
@ -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[] = {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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
|
||||
)
|
||||
{
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
@ -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)) {
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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*/,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -317,4 +317,3 @@ if(WITH_OPENCOLORIO)
|
|||
endif()
|
||||
|
||||
blender_add_lib(bf_realtime_compositor "${SRC}" "${INC}" "${INC_SYS}" "${LIB}")
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -216,4 +216,4 @@ vec3 sample_uniform_cone(vec3 rand, float angle, vec3 N, vec3 T, vec3 B)
|
|||
return tH * mat3(N, T, B);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
/** \} */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -186,4 +186,4 @@ void main()
|
|||
out_radiance = from_accumulation_space(out_radiance);
|
||||
|
||||
imageStore(out_radiance_img, texel_fullres, vec4(out_radiance, 0.0));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -64,4 +64,4 @@ void main()
|
|||
|
||||
imageStore(tile_mask_img, tile_co, uvec4(tile_mask));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -73,4 +73,4 @@ void main()
|
|||
atlas_store(result[2], atlas_coord, 2);
|
||||
atlas_store(result[3], atlas_coord, 3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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,
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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]))
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
Loading…
Reference in New Issue