BLF: Subpixel Positioning, Anti-aliasing, Hinting #105441

Merged
Harley Acheson merged 11 commits from Harley/blender:Subpixel into main 2023-09-21 22:43:24 +02:00
99 changed files with 774 additions and 721 deletions
Showing only changes of commit cfd32746da - Show all commits

View File

@ -1162,7 +1162,7 @@ context_type_map = {
"annotation_data": ("GreasePencil", False),
"annotation_data_owner": ("ID", False),
"armature": ("Armature", False),
"asset_library_ref": ("AssetLibraryReference", False),
"asset_library_reference": ("AssetLibraryReference", False),
"bone": ("Bone", False),
"brush": ("Brush", False),
"camera": ("Camera", False),
@ -1212,7 +1212,7 @@ context_type_map = {
"scene": ("Scene", False),
"sculpt_object": ("Object", False),
"selectable_objects": ("Object", True),
"selected_asset_files": ("FileSelectEntry", True),
"selected_assets": ("AssetRepresentation", True),
"selected_bones": ("EditBone", True),
"selected_editable_actions": ("Action", True),
"selected_editable_bones": ("EditBone", True),

View File

@ -629,24 +629,24 @@ ccl_device int bsdf_microfacet_sample(ccl_private const ShaderClosure *sc,
/* Decide between refraction and reflection based on the energy. */
const float pdf_reflect = average(reflectance) / average(reflectance + transmittance);
const bool do_refract = (rand.z >= pdf_reflect);
/* Compute actual reflected or refracted direction. */
*wo = do_refract ? refract_angle(wi, H, cos_HO, m_inv_eta) : 2.0f * cos_HI * H - wi;
if ((dot(Ng, *wo) < 0) != do_refract) {
return LABEL_NONE;
}
if (do_refract) {
*wo = refract_angle(wi, H, cos_HO, m_inv_eta);
*eval = transmittance;
*pdf = 1.0f - pdf_reflect;
/* If the IOR is close enough to 1.0, just treat the interaction as specular. */
m_singular = m_singular || (fabsf(m_eta - 1.0f) < 1e-4f);
}
else {
/* Eq. 39 - compute actual reflected direction */
*wo = 2 * cos_HI * H - wi;
*eval = reflectance;
*pdf = pdf_reflect;
}
if ((dot(Ng, *wo) < 0) != do_refract) {
return LABEL_NONE;
}
if (m_singular) {
/* Some high number for MIS. */
*pdf *= 1e6f;

View File

@ -15,7 +15,7 @@ CCL_NAMESPACE_BEGIN
struct GuidingRISSample {
float3 rand;
float2 sampled_roughness;
/* The relative ior of the outgoing media and the incoming media. */
/* The relative IOR of the outgoing media and the incoming media. */
float eta{1.0f};
int label;
float3 wo;

View File

@ -68,7 +68,7 @@ void GHOST_ShowMessageBox(GHOST_SystemHandle systemhandle,
const char *link,
GHOST_DialogOptions dialog_options)
{
GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
const GHOST_ISystem *system = (const GHOST_ISystem *)systemhandle;
system->showMessageBox(title, message, help_label, continue_label, link, dialog_options);
}
@ -86,7 +86,7 @@ GHOST_TSuccess GHOST_DisposeEventConsumer(GHOST_EventConsumerHandle consumerhand
uint64_t GHOST_GetMilliSeconds(GHOST_SystemHandle systemhandle)
{
GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
const GHOST_ISystem *system = (const GHOST_ISystem *)systemhandle;
return system->getMilliSeconds();
}
@ -113,7 +113,7 @@ GHOST_TSuccess GHOST_RemoveTimer(GHOST_SystemHandle systemhandle,
uint8_t GHOST_GetNumDisplays(GHOST_SystemHandle systemhandle)
{
GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
const GHOST_ISystem *system = (const GHOST_ISystem *)systemhandle;
return system->getNumDisplays();
}
@ -122,7 +122,7 @@ void GHOST_GetMainDisplayDimensions(GHOST_SystemHandle systemhandle,
uint32_t *width,
uint32_t *height)
{
GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
const GHOST_ISystem *system = (const GHOST_ISystem *)systemhandle;
system->getMainDisplayDimensions(*width, *height);
}
@ -131,7 +131,7 @@ void GHOST_GetAllDisplayDimensions(GHOST_SystemHandle systemhandle,
uint32_t *width,
uint32_t *height)
{
GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
const GHOST_ISystem *system = (const GHOST_ISystem *)systemhandle;
system->getAllDisplayDimensions(*width, *height);
}
@ -180,7 +180,7 @@ GHOST_WindowHandle GHOST_CreateWindow(GHOST_SystemHandle systemhandle,
GHOST_TUserDataPtr GHOST_GetWindowUserData(GHOST_WindowHandle windowhandle)
{
GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
const GHOST_IWindow *window = (const GHOST_IWindow *)windowhandle;
return window->getUserData();
}
@ -193,7 +193,7 @@ void GHOST_SetWindowUserData(GHOST_WindowHandle windowhandle, GHOST_TUserDataPtr
bool GHOST_IsDialogWindow(GHOST_WindowHandle windowhandle)
{
GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
const GHOST_IWindow *window = (const GHOST_IWindow *)windowhandle;
return window->isDialog();
}
@ -305,7 +305,7 @@ GHOST_TSuccess GHOST_EndProgressBar(GHOST_WindowHandle windowhandle)
GHOST_TStandardCursor GHOST_GetCursorShape(GHOST_WindowHandle windowhandle)
{
GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
const GHOST_IWindow *window = (const GHOST_IWindow *)windowhandle;
return window->getCursorShape();
}
@ -350,7 +350,7 @@ GHOST_TSuccess GHOST_GetCursorBitmap(GHOST_WindowHandle windowhandle,
bool GHOST_GetCursorVisibility(GHOST_WindowHandle windowhandle)
{
GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
const GHOST_IWindow *window = (const GHOST_IWindow *)windowhandle;
return window->getCursorVisibility();
}
@ -449,7 +449,7 @@ GHOST_TSuccess GHOST_GetModifierKeyState(GHOST_SystemHandle systemhandle,
GHOST_TModifierKey mask,
bool *r_is_down)
{
GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
const GHOST_ISystem *system = (const GHOST_ISystem *)systemhandle;
GHOST_TSuccess result;
bool is_down = false;
@ -463,7 +463,7 @@ GHOST_TSuccess GHOST_GetButtonState(GHOST_SystemHandle systemhandle,
GHOST_TButton mask,
bool *r_is_down)
{
GHOST_ISystem *system = (GHOST_ISystem *)systemhandle;
const GHOST_ISystem *system = (const GHOST_ISystem *)systemhandle;
GHOST_TSuccess result;
bool is_down = false;
@ -518,7 +518,7 @@ GHOST_TEventDataPtr GHOST_GetEventData(GHOST_EventHandle eventhandle)
GHOST_TimerProcPtr GHOST_GetTimerProc(GHOST_TimerTaskHandle timertaskhandle)
{
GHOST_ITimerTask *timertask = (GHOST_ITimerTask *)timertaskhandle;
const GHOST_ITimerTask *timertask = (const GHOST_ITimerTask *)timertaskhandle;
return timertask->getTimerProc();
}
@ -532,7 +532,7 @@ void GHOST_SetTimerProc(GHOST_TimerTaskHandle timertaskhandle, GHOST_TimerProcPt
GHOST_TUserDataPtr GHOST_GetTimerTaskUserData(GHOST_TimerTaskHandle timertaskhandle)
{
GHOST_ITimerTask *timertask = (GHOST_ITimerTask *)timertaskhandle;
const GHOST_ITimerTask *timertask = (const GHOST_ITimerTask *)timertaskhandle;
return timertask->getUserData();
}
@ -546,7 +546,7 @@ void GHOST_SetTimerTaskUserData(GHOST_TimerTaskHandle timertaskhandle, GHOST_TUs
bool GHOST_GetValid(GHOST_WindowHandle windowhandle)
{
GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
const GHOST_IWindow *window = (const GHOST_IWindow *)windowhandle;
return window->getValid();
}
@ -581,7 +581,7 @@ void GHOST_SetTitle(GHOST_WindowHandle windowhandle, const char *title)
char *GHOST_GetTitle(GHOST_WindowHandle windowhandle)
{
GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
const GHOST_IWindow *window = (const GHOST_IWindow *)windowhandle;
std::string title = window->getTitle();
const size_t ctitle_size = title.size() + 1;
@ -598,7 +598,7 @@ char *GHOST_GetTitle(GHOST_WindowHandle windowhandle)
GHOST_RectangleHandle GHOST_GetWindowBounds(GHOST_WindowHandle windowhandle)
{
GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
const GHOST_IWindow *window = (const GHOST_IWindow *)windowhandle;
GHOST_Rect *rectangle = nullptr;
rectangle = new GHOST_Rect();
@ -609,7 +609,7 @@ GHOST_RectangleHandle GHOST_GetWindowBounds(GHOST_WindowHandle windowhandle)
GHOST_RectangleHandle GHOST_GetClientBounds(GHOST_WindowHandle windowhandle)
{
GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
const GHOST_IWindow *window = (const GHOST_IWindow *)windowhandle;
GHOST_Rect *rectangle = nullptr;
rectangle = new GHOST_Rect();
@ -649,7 +649,7 @@ GHOST_TSuccess GHOST_SetClientSize(GHOST_WindowHandle windowhandle,
void GHOST_ScreenToClient(
GHOST_WindowHandle windowhandle, int32_t inX, int32_t inY, int32_t *outX, int32_t *outY)
{
GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
const GHOST_IWindow *window = (const GHOST_IWindow *)windowhandle;
window->screenToClient(inX, inY, *outX, *outY);
}
@ -657,14 +657,14 @@ void GHOST_ScreenToClient(
void GHOST_ClientToScreen(
GHOST_WindowHandle windowhandle, int32_t inX, int32_t inY, int32_t *outX, int32_t *outY)
{
GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
const GHOST_IWindow *window = (const GHOST_IWindow *)windowhandle;
window->clientToScreen(inX, inY, *outX, *outY);
}
GHOST_TWindowState GHOST_GetWindowState(GHOST_WindowHandle windowhandle)
{
GHOST_IWindow *window = (GHOST_IWindow *)windowhandle;
const GHOST_IWindow *window = (const GHOST_IWindow *)windowhandle;
return window->getState();
}
@ -770,7 +770,7 @@ void GHOST_SetTabletAPI(GHOST_SystemHandle systemhandle, GHOST_TTabletAPI api)
GHOST_TSuccess GHOST_GetPixelAtCursor(float r_color[3])
{
GHOST_ISystem *system = GHOST_ISystem::getSystem();
const GHOST_ISystem *system = GHOST_ISystem::getSystem();
return system->getPixelAtCursor(r_color);
}
@ -881,31 +881,31 @@ GHOST_TSuccess GHOST_ClipRectangle(GHOST_RectangleHandle rectanglehandle,
char *GHOST_getClipboard(bool selection)
{
GHOST_ISystem *system = GHOST_ISystem::getSystem();
const GHOST_ISystem *system = GHOST_ISystem::getSystem();
return system->getClipboard(selection);
}
void GHOST_putClipboard(const char *buffer, bool selection)
{
GHOST_ISystem *system = GHOST_ISystem::getSystem();
const GHOST_ISystem *system = GHOST_ISystem::getSystem();
system->putClipboard(buffer, selection);
}
GHOST_TSuccess GHOST_hasClipboardImage()
{
GHOST_ISystem *system = GHOST_ISystem::getSystem();
const GHOST_ISystem *system = GHOST_ISystem::getSystem();
return system->hasClipboardImage();
}
uint *GHOST_getClipboardImage(int *r_width, int *r_height)
{
GHOST_ISystem *system = GHOST_ISystem::getSystem();
const GHOST_ISystem *system = GHOST_ISystem::getSystem();
return system->getClipboardImage(r_width, r_height);
}
GHOST_TSuccess GHOST_putClipboardImage(uint *rgba, int width, int height)
{
GHOST_ISystem *system = GHOST_ISystem::getSystem();
const GHOST_ISystem *system = GHOST_ISystem::getSystem();
return system->putClipboardImage(rgba, width, height);
}
@ -923,7 +923,7 @@ bool GHOST_UseNativePixels()
GHOST_TCapabilityFlag GHOST_GetCapabilities()
{
GHOST_ISystem *system = GHOST_ISystem::getSystem();
const GHOST_ISystem *system = GHOST_ISystem::getSystem();
return system->getCapabilities();
}
@ -1036,7 +1036,7 @@ void GHOST_XrDrawViewFunc(GHOST_XrContextHandle xr_contexthandle, GHOST_XrDrawVi
int GHOST_XrSessionNeedsUpsideDownDrawing(const GHOST_XrContextHandle xr_contexthandle)
{
GHOST_IXrContext *xr_context = (GHOST_IXrContext *)xr_contexthandle;
const GHOST_IXrContext *xr_context = (const GHOST_IXrContext *)xr_contexthandle;
GHOST_XR_CAPI_CALL_RET(xr_context->needsUpsideDownDrawing(), xr_context);
return 0; /* Only reached if exception is thrown. */

View File

@ -99,7 +99,7 @@ GHOST_DropTargetX11::~GHOST_DropTargetX11()
}
}
char *GHOST_DropTargetX11::FileUrlDecode(char *fileUrl)
char *GHOST_DropTargetX11::FileUrlDecode(const char *fileUrl)
{
if (strncmp(fileUrl, "file://", 7) == 0) {
return GHOST_URL_decode_alloc(fileUrl + 7);
@ -108,7 +108,7 @@ char *GHOST_DropTargetX11::FileUrlDecode(char *fileUrl)
return nullptr;
}
void *GHOST_DropTargetX11::getURIListGhostData(uchar *dropBuffer, int dropBufferSize)
void *GHOST_DropTargetX11::getURIListGhostData(const uchar *dropBuffer, int dropBufferSize)
{
GHOST_TStringArray *strArray = nullptr;
int totPaths = 0, curLength = 0;
@ -158,7 +158,7 @@ void *GHOST_DropTargetX11::getURIListGhostData(uchar *dropBuffer, int dropBuffer
return strArray;
}
void *GHOST_DropTargetX11::getGhostData(Atom dropType, uchar *dropBuffer, int dropBufferSize)
void *GHOST_DropTargetX11::getGhostData(Atom dropType, const uchar *dropBuffer, int dropBufferSize)
{
void *data = nullptr;
uchar *tmpBuffer = (uchar *)malloc(dropBufferSize + 1);
@ -174,7 +174,7 @@ void *GHOST_DropTargetX11::getGhostData(Atom dropType, uchar *dropBuffer, int dr
}
else if (dropType == dndTypeURL) {
/* need to be tested */
char *decodedPath = FileUrlDecode((char *)tmpBuffer);
char *decodedPath = FileUrlDecode((const char *)tmpBuffer);
if (decodedPath) {
m_draggedObjectType = GHOST_kDragnDropTypeString;

View File

@ -42,7 +42,7 @@ class GHOST_DropTargetX11 {
* \param dropBufferSize: Size of returned buffer.
* \return Pointer to data.
*/
void *getGhostData(Atom dropType, unsigned char *dropBuffer, int dropBufferSize);
void *getGhostData(Atom dropType, const unsigned char *dropBuffer, int dropBufferSize);
private:
/* Internal helper functions */
@ -63,14 +63,14 @@ class GHOST_DropTargetX11 {
* \param dropBufferSize: Size of dropped buffer.
* \return pointer to newly created GHOST data.
*/
void *getURIListGhostData(unsigned char *dropBuffer, int dropBufferSize);
void *getURIListGhostData(const unsigned char *dropBuffer, int dropBufferSize);
/**
* Fully decode file URL (i.e. converts `file:///a%20b/test` to `/a b/test`)
* \param fileUrl: - file path URL to be fully decoded.
* \return decoded file path (result should be free-d).
*/
char *FileUrlDecode(char *fileUrl);
char *FileUrlDecode(const char *fileUrl);
/* The associated GHOST_WindowWin32. */
GHOST_WindowX11 *m_window;

View File

@ -125,7 +125,7 @@ GHOST_TSuccess GHOST_EventManager::removeConsumer(GHOST_IEventConsumer *consumer
return success;
}
void GHOST_EventManager::removeWindowEvents(GHOST_IWindow *window)
void GHOST_EventManager::removeWindowEvents(const GHOST_IWindow *window)
{
TEventStack::iterator iter;
iter = m_events.begin();
@ -147,7 +147,7 @@ void GHOST_EventManager::removeWindowEvents(GHOST_IWindow *window)
}
}
void GHOST_EventManager::removeTypeEvents(GHOST_TEventType type, GHOST_IWindow *window)
void GHOST_EventManager::removeTypeEvents(GHOST_TEventType type, const GHOST_IWindow *window)
{
TEventStack::iterator iter;
iter = m_events.begin();

View File

@ -90,7 +90,7 @@ class GHOST_EventManager {
* Removes all events for a window from the stack.
* \param window: The window to remove events for.
*/
void removeWindowEvents(GHOST_IWindow *window);
void removeWindowEvents(const GHOST_IWindow *window);
/**
* Removes all events of a certain type from the stack.
@ -99,7 +99,7 @@ class GHOST_EventManager {
* \param type: The type of events to be removed.
* \param window: The window to remove the events for.
*/
void removeTypeEvents(GHOST_TEventType type, GHOST_IWindow *window = nullptr);
void removeTypeEvents(GHOST_TEventType type, const GHOST_IWindow *window = nullptr);
protected:
/**

View File

@ -25,34 +25,34 @@ GHOST_TSuccess GHOST_DisposeSystemPaths()
const char *GHOST_getSystemDir(int version, const char *versionstr)
{
GHOST_ISystemPaths *systemPaths = GHOST_ISystemPaths::get();
const GHOST_ISystemPaths *systemPaths = GHOST_ISystemPaths::get();
return systemPaths ? systemPaths->getSystemDir(version, versionstr) : nullptr;
}
const char *GHOST_getUserDir(int version, const char *versionstr)
{
GHOST_ISystemPaths *systemPaths = GHOST_ISystemPaths::get();
const GHOST_ISystemPaths *systemPaths = GHOST_ISystemPaths::get();
/* Shouldn't be `nullptr`. */
return systemPaths ? systemPaths->getUserDir(version, versionstr) : nullptr;
}
const char *GHOST_getUserSpecialDir(GHOST_TUserSpecialDirTypes type)
{
GHOST_ISystemPaths *systemPaths = GHOST_ISystemPaths::get();
const GHOST_ISystemPaths *systemPaths = GHOST_ISystemPaths::get();
/* Shouldn't be `nullptr`. */
return systemPaths ? systemPaths->getUserSpecialDir(type) : nullptr;
}
const char *GHOST_getBinaryDir()
{
GHOST_ISystemPaths *systemPaths = GHOST_ISystemPaths::get();
const GHOST_ISystemPaths *systemPaths = GHOST_ISystemPaths::get();
/* Shouldn't be `nullptr`. */
return systemPaths ? systemPaths->getBinaryDir() : nullptr;
}
void GHOST_addToSystemRecentFiles(const char *filepath)
{
GHOST_ISystemPaths *systemPaths = GHOST_ISystemPaths::get();
const GHOST_ISystemPaths *systemPaths = GHOST_ISystemPaths::get();
if (systemPaths) {
systemPaths->addToSystemRecentFiles(filepath);
}

View File

@ -818,7 +818,7 @@ GHOST_IWindow *GHOST_SystemCocoa::getWindowUnderCursor(int32_t x, int32_t y)
return nil;
}
return m_windowManager->getWindowAssociatedWithOSWindow((void *)nswindow);
return m_windowManager->getWindowAssociatedWithOSWindow((const void *)nswindow);
}
/**
@ -1468,7 +1468,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleTabletEvent(void *eventPtr, short eventT
NSEvent *event = (NSEvent *)eventPtr;
GHOST_IWindow *window;
window = m_windowManager->getWindowAssociatedWithOSWindow((void *)[event window]);
window = m_windowManager->getWindowAssociatedWithOSWindow((const void *)[event window]);
if (!window) {
// printf("\nW failure for event 0x%x",[event type]);
return GHOST_kFailure;
@ -1545,7 +1545,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleMouseEvent(void *eventPtr)
* however, if mouse exits window(s), the windows become inactive, until you click.
* We then fall back to the active window from ghost. */
window = (GHOST_WindowCocoa *)m_windowManager->getWindowAssociatedWithOSWindow(
(void *)[event window]);
(const void *)[event window]);
if (!window) {
window = (GHOST_WindowCocoa *)m_windowManager->getActiveWindow();
if (!window) {
@ -1853,7 +1853,7 @@ GHOST_TSuccess GHOST_SystemCocoa::handleKeyEvent(void *eventPtr)
GHOST_TKey keyCode;
NSString *charsIgnoringModifiers;
window = m_windowManager->getWindowAssociatedWithOSWindow((void *)[event window]);
window = m_windowManager->getWindowAssociatedWithOSWindow((const void *)[event window]);
if (!window) {
// printf("\nW failure for event 0x%x",[event type]);
return GHOST_kFailure;

View File

@ -1947,7 +1947,7 @@ static void keyboard_depressed_state_push_events_from_change(
GWL_Seat *seat, const GWL_KeyboardDepressedState &key_depressed_prev)
{
GHOST_IWindow *win = ghost_wl_surface_user_data(seat->keyboard.wl.surface_window);
GHOST_SystemWayland *system = seat->system;
const GHOST_SystemWayland *system = seat->system;
/* Separate key up and down into separate passes so key down events always come after key up.
* Do this so users of GHOST can use the last pressed or released modifier to check
@ -6262,7 +6262,7 @@ GHOST_TSuccess GHOST_SystemWayland::getCursorPosition(int32_t &x, int32_t &y) co
}
if (wl_surface *wl_surface_focus = seat_state_pointer->wl.surface_window) {
GHOST_WindowWayland *win = ghost_wl_surface_user_data(wl_surface_focus);
const GHOST_WindowWayland *win = ghost_wl_surface_user_data(wl_surface_focus);
return getCursorPositionClientRelative_impl(seat_state_pointer, win, x, y);
}
return GHOST_kFailure;
@ -6713,8 +6713,8 @@ GHOST_TSuccess GHOST_SystemWayland::cursor_shape_check(const GHOST_TStandardCurs
return GHOST_kSuccess;
}
GHOST_TSuccess GHOST_SystemWayland::cursor_shape_custom_set(uint8_t *bitmap,
uint8_t *mask,
GHOST_TSuccess GHOST_SystemWayland::cursor_shape_custom_set(const uint8_t *bitmap,
const uint8_t *mask,
const int sizex,
const int sizey,
const int hotX,
@ -7155,7 +7155,7 @@ bool GHOST_SystemWayland::output_unref(wl_output *wl_output)
/* NOTE: keep in sync with `output_scale_update`. */
GWL_Output *output = ghost_wl_output_user_data(wl_output);
GHOST_WindowManager *window_manager = getWindowManager();
const GHOST_WindowManager *window_manager = getWindowManager();
if (window_manager) {
for (GHOST_IWindow *iwin : window_manager->getWindows()) {
GHOST_WindowWayland *win = static_cast<GHOST_WindowWayland *>(iwin);

View File

@ -191,8 +191,8 @@ class GHOST_SystemWayland : public GHOST_System {
GHOST_TSuccess cursor_shape_check(GHOST_TStandardCursor cursorShape);
GHOST_TSuccess cursor_shape_custom_set(uint8_t *bitmap,
uint8_t *mask,
GHOST_TSuccess cursor_shape_custom_set(const uint8_t *bitmap,
const uint8_t *mask,
int sizex,
int sizey,
int hotX,

View File

@ -487,7 +487,7 @@ GHOST_IWindow *GHOST_SystemWin32::getWindowUnderCursor(int32_t /*x*/, int32_t /*
return nullptr;
}
return m_windowManager->getWindowAssociatedWithOSWindow((void *)win);
return m_windowManager->getWindowAssociatedWithOSWindow((const void *)win);
}
GHOST_TSuccess GHOST_SystemWin32::getModifierKeys(GHOST_ModifierKeys &keys) const

View File

@ -791,7 +791,7 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
(void)class_presence;
if (xe->type == xi_presence) {
XDevicePresenceNotifyEvent *notify_event = (XDevicePresenceNotifyEvent *)xe;
const XDevicePresenceNotifyEvent *notify_event = (const XDevicePresenceNotifyEvent *)xe;
if (ELEM(notify_event->devchange, DeviceEnabled, DeviceDisabled, DeviceAdded, DeviceRemoved))
{
refreshXInputDevices();
@ -825,7 +825,7 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
if (window->GetTabletData().Active != GHOST_kTabletModeNone) {
bool any_proximity = false;
for (GHOST_TabletX11 &xtablet : m_xtablets) {
for (const GHOST_TabletX11 &xtablet : m_xtablets) {
if (checkTabletProximity(xe->xany.display, xtablet.Device)) {
any_proximity = true;
}
@ -1456,7 +1456,7 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
#ifdef WITH_X11_XINPUT
for (GHOST_TabletX11 &xtablet : m_xtablets) {
if (ELEM(xe->type, xtablet.MotionEvent, xtablet.PressEvent)) {
XDeviceMotionEvent *data = (XDeviceMotionEvent *)xe;
const XDeviceMotionEvent *data = (const XDeviceMotionEvent *)xe;
if (data->deviceid != xtablet.ID) {
continue;
}
@ -1504,7 +1504,7 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
# undef AXIS_VALUE_GET
}
else if (xe->type == xtablet.ProxInEvent) {
XProximityNotifyEvent *data = (XProximityNotifyEvent *)xe;
const XProximityNotifyEvent *data = (const XProximityNotifyEvent *)xe;
if (data->deviceid != xtablet.ID) {
continue;
}
@ -2369,7 +2369,7 @@ class DialogData {
}
/* Is the mouse inside the given button */
bool isInsideButton(const XEvent &e, uint button_num)
bool isInsideButton(const XEvent &e, uint button_num) const
{
return (
(e.xmotion.y > int(height - padding_y - button_height)) &&

View File

@ -152,7 +152,7 @@ const std::vector<GHOST_IWindow *> &GHOST_WindowManager::getWindows() const
return m_windows;
}
GHOST_IWindow *GHOST_WindowManager::getWindowAssociatedWithOSWindow(void *osWindow)
GHOST_IWindow *GHOST_WindowManager::getWindowAssociatedWithOSWindow(const void *osWindow)
{
std::vector<GHOST_IWindow *>::iterator iter;

View File

@ -108,7 +108,7 @@ class GHOST_WindowManager {
* \param osWindow: The OS window object/handle.
* \return The associated window, null if none corresponds.
*/
GHOST_IWindow *getWindowAssociatedWithOSWindow(void *osWindow);
GHOST_IWindow *getWindowAssociatedWithOSWindow(const void *osWindow);
protected:
/** The list of windows managed */

View File

@ -1122,7 +1122,7 @@ static void libdecor_frame_handle_configure(libdecor_frame *frame,
{
GWL_Window *win = static_cast<GWL_Window *>(data);
# ifdef USE_EVENT_BACKGROUND_THREAD
GHOST_SystemWayland *system = win->ghost_system;
const GHOST_SystemWayland *system = win->ghost_system;
const bool is_main_thread = system->main_thread_id == std::this_thread::get_id();
if (!is_main_thread) {
gwl_window_pending_actions_tag(win, PENDING_WINDOW_FRAME_CONFIGURE);
@ -1220,7 +1220,7 @@ static void xdg_surface_handle_configure(void *data,
win->xdg_decor->pending.ack_configure_serial = serial;
#ifdef USE_EVENT_BACKGROUND_THREAD
GHOST_SystemWayland *system = win->ghost_system;
const GHOST_SystemWayland *system = win->ghost_system;
const bool is_main_thread = system->main_thread_id == std::this_thread::get_id();
if (!is_main_thread) {
/* NOTE(@ideasman42): this only gets one redraw,

View File

@ -894,7 +894,7 @@ void *GHOST_XrSession::getActionCustomdata(const char *action_set_name, const ch
uint32_t GHOST_XrSession::getActionCount(const char *action_set_name)
{
GHOST_XrActionSet *action_set = find_action_set(m_oxr.get(), action_set_name);
const GHOST_XrActionSet *action_set = find_action_set(m_oxr.get(), action_set_name);
if (action_set == nullptr) {
return 0;
}

View File

@ -2386,7 +2386,6 @@ url_manual_mapping = (
("bpy.ops.anim.channels_expand*", "editors/graph_editor/channels/editing.html#bpy-ops-anim-channels-expand"),
("bpy.ops.anim.keyframe_delete*", "animation/keyframes/editing.html#bpy-ops-anim-keyframe-delete"),
("bpy.ops.anim.keyframe_insert*", "animation/keyframes/editing.html#bpy-ops-anim-keyframe-insert"),
("bpy.ops.armature.bone_layers*", "animation/armatures/bones/editing/change_layers.html#bpy-ops-armature-bone-layers"),
("bpy.ops.armature.select_less*", "animation/armatures/bones/selecting.html#bpy-ops-armature-select-less"),
("bpy.ops.armature.select_more*", "animation/armatures/bones/selecting.html#bpy-ops-armature-select-more"),
("bpy.ops.asset.bundle_install*", "editors/asset_browser.html#bpy-ops-asset-bundle-install"),

View File

@ -5710,8 +5710,8 @@ def km_edit_armature(params):
op_menu("VIEW3D_MT_bone_options_disable", {"type": 'W', "value": 'PRESS', "alt": True}),
# Armature/bone layers.
("armature.layers_show_all", {"type": 'ACCENT_GRAVE', "value": 'PRESS', "ctrl": True}, None),
("armature.armature_layers", {"type": 'M', "value": 'PRESS', "shift": True}, None),
("armature.bone_layers", {"type": 'M', "value": 'PRESS'}, None),
op_menu("VIEW3D_MT_bone_collections", {"type": 'M', "value": 'PRESS', "shift": True}),
("armature.move_to_collection", {"type": 'M', "value": 'PRESS'}, None),
# Special transforms.
op_tool_optional(
("transform.bbone_resize", {"type": 'S', "value": 'PRESS', "shift": True, "ctrl": True, "alt": True}, None),

View File

@ -20,10 +20,10 @@ from bpy_extras.asset_utils import (
class AssetBrowserMetadataOperator:
@classmethod
def poll(cls, context):
if not SpaceAssetInfo.is_asset_browser_poll(context) or not context.asset_file_handle:
if not SpaceAssetInfo.is_asset_browser_poll(context) or not context.asset:
return False
if not context.asset_file_handle.local_id:
if not context.asset.local_id:
Operator.poll_message_set(
"Asset metadata from external asset libraries can't be "
"edited, only assets stored in the current file can"
@ -58,13 +58,13 @@ class ASSET_OT_tag_remove(AssetBrowserMetadataOperator, Operator):
if not super().poll(context):
return False
active_asset_file = context.asset_file_handle
asset_metadata = active_asset_file.asset_data
active_asset = context.asset
asset_metadata = active_asset.metadata
return asset_metadata.active_tag in range(len(asset_metadata.tags))
def execute(self, context):
active_asset_file = context.asset_file_handle
asset_metadata = active_asset_file.asset_data
active_asset = context.asset
asset_metadata = active_asset.metadata
tag = asset_metadata.tags[asset_metadata.active_tag]
asset_metadata.tags.remove(tag)
@ -84,24 +84,24 @@ class ASSET_OT_open_containing_blend_file(Operator):
@classmethod
def poll(cls, context):
asset_file_handle = getattr(context, "asset_file_handle", None)
asset = getattr(context, "asset", None)
if not asset_file_handle:
if not asset:
cls.poll_message_set("No asset selected")
return False
if asset_file_handle.local_id:
if asset.local_id:
cls.poll_message_set("Selected asset is contained in the current file")
return False
return True
def execute(self, context):
asset_file_handle = context.asset_file_handle
asset = context.asset
if asset_file_handle.local_id:
if asset.local_id:
self.report({'WARNING'}, "This asset is stored in the current blend file")
return {'CANCELLED'}
asset_lib_path = bpy.types.AssetHandle.get_full_library_path(asset_file_handle)
asset_lib_path = asset.full_library_path
self.open_in_new_blender(asset_lib_path)
wm = context.window_manager

View File

@ -1027,7 +1027,7 @@ class WM_OT_url_open(Operator):
@staticmethod
def _add_utm_param_to_url(url, utm_source):
import urllib
import urllib.parse
# Make sure we have a scheme otherwise we can't parse the url.
if not url.startswith(("http://", "https://")):

View File

@ -24,7 +24,7 @@ class FILEBROWSER_HT_header(Header):
layout.separator_spacer()
if params.asset_library_ref not in {'LOCAL', 'ESSENTIALS'}:
if params.asset_library_reference not in {'LOCAL', 'ESSENTIALS'}:
layout.prop(params, "import_type", text="")
layout.separator_spacer()
@ -709,58 +709,58 @@ class ASSETBROWSER_PT_metadata(asset_utils.AssetBrowserPanel, Panel):
bl_options = {'HIDE_HEADER'}
@staticmethod
def metadata_prop(layout, asset_data, propname):
def metadata_prop(layout, asset_metadata, propname):
"""
Only display properties that are either set or can be modified (i.e. the
asset is in the current file). Empty, non-editable fields are not really useful.
"""
if getattr(asset_data, propname) or not asset_data.is_property_readonly(propname):
layout.prop(asset_data, propname)
if getattr(asset_metadata, propname) or not asset_metadata.is_property_readonly(propname):
layout.prop(asset_metadata, propname)
def draw(self, context):
layout = self.layout
wm = context.window_manager
asset_file_handle = context.asset_file_handle
asset = context.asset
if asset_file_handle is None:
if asset is None:
layout.label(text="No active asset", icon='INFO')
return
prefs = context.preferences
show_asset_debug_info = prefs.view.show_developer_ui and prefs.experimental.show_asset_debug_info
is_local_asset = bool(asset_file_handle.local_id)
is_local_asset = bool(asset.local_id)
layout.use_property_split = True
layout.use_property_decorate = False # No animation.
if is_local_asset:
# If the active file is an ID, use its name directly so renaming is possible from right here.
layout.prop(asset_file_handle.local_id, "name")
layout.prop(asset.local_id, "name")
if show_asset_debug_info:
col = layout.column(align=True)
col.label(text="Asset Catalog:")
col.prop(asset_file_handle.local_id.asset_data, "catalog_id", text="UUID")
col.prop(asset_file_handle.local_id.asset_data, "catalog_simple_name", text="Simple Name")
col.prop(asset.local_id.asset_data, "catalog_id", text="UUID")
col.prop(asset.local_id.asset_data, "catalog_simple_name", text="Simple Name")
else:
layout.prop(asset_file_handle, "name")
layout.prop(asset, "name")
if show_asset_debug_info:
col = layout.column(align=True)
col.enabled = False
col.label(text="Asset Catalog:")
col.prop(asset_file_handle.asset_data, "catalog_id", text="UUID")
col.prop(asset_file_handle.asset_data, "catalog_simple_name", text="Simple Name")
col.prop(asset.metadata, "catalog_id", text="UUID")
col.prop(asset.metadata, "catalog_simple_name", text="Simple Name")
row = layout.row(align=True)
row.prop(wm, "asset_path_dummy", text="Source", icon='CURRENT_FILE' if is_local_asset else 'NONE')
row.operator("asset.open_containing_blend_file", text="", icon='TOOL_SETTINGS')
asset_data = asset_file_handle.asset_data
self.metadata_prop(layout, asset_data, "description")
self.metadata_prop(layout, asset_data, "license")
self.metadata_prop(layout, asset_data, "copyright")
self.metadata_prop(layout, asset_data, "author")
metadata = asset.metadata
self.metadata_prop(layout, metadata, "description")
self.metadata_prop(layout, metadata, "license")
self.metadata_prop(layout, metadata, "copyright")
self.metadata_prop(layout, metadata, "author")
class ASSETBROWSER_PT_metadata_preview(asset_utils.AssetMetaDataPanel, Panel):
@ -877,14 +877,14 @@ classes = (
def asset_path_str_get(_self):
asset_file_handle = bpy.context.asset_file_handle
if asset_file_handle is None:
asset = bpy.context.asset
if asset is None:
return ""
if asset_file_handle.local_id:
if asset.local_id:
return "Current File"
return bpy.types.AssetHandle.get_full_library_path(asset_file_handle)
return asset.full_library_path
def register_props():

View File

@ -5331,8 +5331,8 @@ class VIEW3D_MT_edit_armature(Menu):
layout.separator()
layout.operator_context = 'INVOKE_DEFAULT'
layout.operator("armature.armature_layers")
layout.operator("armature.bone_layers")
layout.operator("armature.move_to_collection", text="Move to Bone Collection")
layout.menu("VIEW3D_MT_bone_collections")
layout.separator()

View File

@ -143,10 +143,13 @@ void ANIM_bonecoll_hide(struct BoneCollection *bcoll);
bool ANIM_armature_bonecoll_assign(struct BoneCollection *bcoll, struct Bone *bone);
bool ANIM_armature_bonecoll_assign_editbone(struct BoneCollection *bcoll, struct EditBone *ebone);
bool ANIM_armature_bonecoll_assign_and_move(struct BoneCollection *bcoll, struct Bone *bone);
bool ANIM_armature_bonecoll_assign_and_move_editbone(struct BoneCollection *bcoll,
struct EditBone *ebone);
bool ANIM_armature_bonecoll_unassign(struct BoneCollection *bcoll, struct Bone *bone);
void ANIM_armature_bonecoll_unassign_all(struct Bone *bone);
bool ANIM_armature_bonecoll_unassign_editbone(struct BoneCollection *bcoll,
struct EditBone *ebone);
void ANIM_armature_bonecoll_unassign_all(struct Bone *bone);
void ANIM_armature_bonecoll_unassign_all_editbone(struct EditBone *ebone);
/* Assign the edit bone to the armature's active collection. */
void ANIM_armature_bonecoll_assign_active(const struct bArmature *armature,

View File

@ -342,6 +342,13 @@ bool ANIM_armature_bonecoll_assign_and_move(BoneCollection *bcoll, Bone *bone)
return ANIM_armature_bonecoll_assign(bcoll, bone);
}
bool ANIM_armature_bonecoll_assign_and_move_editbone(struct BoneCollection *bcoll,
struct EditBone *ebone)
{
ANIM_armature_bonecoll_unassign_all_editbone(ebone);
return ANIM_armature_bonecoll_assign_editbone(bcoll, ebone);
}
bool ANIM_armature_bonecoll_unassign(BoneCollection *bcoll, Bone *bone)
{
bool was_found = false;
@ -377,6 +384,13 @@ void ANIM_armature_bonecoll_unassign_all(Bone *bone)
}
}
void ANIM_armature_bonecoll_unassign_all_editbone(struct EditBone *ebone)
{
LISTBASE_FOREACH_MUTABLE (BoneCollectionReference *, ref, &ebone->bone_collections) {
ANIM_armature_bonecoll_unassign_editbone(ref->bcoll, ebone);
}
}
bool ANIM_armature_bonecoll_unassign_editbone(BoneCollection *bcoll, EditBone *ebone)
{
bool was_found = false;

View File

@ -879,26 +879,24 @@ static bool blf_glyph_set_variation_float(FontBLF *font, FT_Fixed coords[], uint
* \{ */
/**
* Adjust the glyphs weight by a factor.
* Adjust the glyph's weight by a factor. Used for fonts without "wght" variable axis.
*
* \param factor: -1 (min stroke width) <= 0 (normal) => 1 (max boldness).
*/
static bool blf_glyph_transform_weight(FT_GlyphSlot glyph, float factor, bool monospaced)
{
if (glyph->format == FT_GLYPH_FORMAT_OUTLINE) {
/* Fake bold if the font does not have this variable axis. */
const FontBLF *font = (FontBLF *)glyph->face->generic.data;
const FT_Pos average_width = font->ft_size->metrics.height;
FT_Pos change = (FT_Pos)(float(average_width) * factor * 0.1f);
FT_Outline_EmboldenXY(&glyph->outline, change, change / 2);
FT_Pos change = (FT_Pos)(float(average_width) * factor * 0.12f);
FT_Outline_EmboldenXY(&glyph->outline, change, 0);
if (monospaced) {
/* Widened fixed-pitch font needs a nudge left. */
FT_Outline_Translate(&glyph->outline, change / -2, 0);
}
else {
/* Need to increase advance. */
glyph->advance.x += change;
glyph->advance.y += change / 2;
/* Need to increase horizontal advance. */
glyph->advance.x += change / 2;
}
return true;
}
@ -906,7 +904,7 @@ static bool blf_glyph_transform_weight(FT_GlyphSlot glyph, float factor, bool mo
}
/**
* Adjust the glyphs slant by a factor (making it oblique).
* Adjust the glyph's slant by a factor. Used for fonts without "slnt" variable axis.
*
* \param factor: -1 (max right-leaning) <= 0 (no slant) => 1 (max left-leaning).
*
@ -924,7 +922,7 @@ static bool blf_glyph_transform_slant(FT_GlyphSlot glyph, float factor)
}
/**
* Adjust the glyph width by factor.
* Adjust the glyph width by factor. Used for fonts without "wdth" variable axis.
*
* \param factor: -1 (min width) <= 0 (normal) => 1 (max width).
*/
@ -941,7 +939,7 @@ static bool blf_glyph_transform_width(FT_GlyphSlot glyph, float factor)
}
/**
* Change glyph advance to alter letter-spacing (tracking).
* Adjust the glyph spacing by factor. Used for fonts without "spac" variable axis.
*
* \param factor: -1 (min tightness) <= 0 (normal) => 1 (max looseness).
*/
@ -957,7 +955,9 @@ static bool blf_glyph_transform_spacing(FT_GlyphSlot glyph, float factor)
}
/**
* Transform glyph to fit nicely within a fixed column width.
* Transform glyph to fit nicely within a fixed column width. This conversion of
* a proportional font glyph into a monospaced glyph only occurs when a mono font
* does not contain a needed character and must get one from the fallback stack.
*/
static bool blf_glyph_transform_monospace(FT_GlyphSlot glyph, int width)
{
@ -1010,10 +1010,8 @@ static FT_GlyphSlot blf_glyph_render(FontBLF *settings_font,
bool width_done = false;
bool spacing_done = false;
/* 70% of maximum weight results in the same amount of boldness and horizontal
* expansion as the bold version `DejaVuSans-Bold.ttf` of our default font.
* Worth reevaluating if we change default font. */
float weight = (settings_font->flags & BLF_BOLD) ? 0.7f : settings_font->char_weight;
/* Treat bold as 75% of maximum weight. */
float weight = (settings_font->flags & BLF_BOLD) ? 0.75f : settings_font->char_weight;
/* Treat italics as 75% of maximum rightward slant. Note that slant angle is in
* counter-clockwise degrees per OTF spec, so negative. */

View File

@ -413,8 +413,6 @@ bool CTX_data_editable_gpencil_layers(const bContext *C, ListBase *list);
bool CTX_data_editable_gpencil_strokes(const bContext *C, ListBase *list);
const struct AssetLibraryReference *CTX_wm_asset_library_ref(const bContext *C);
struct AssetHandle CTX_wm_asset_handle(const bContext *C, bool *r_is_valid);
#ifdef __cplusplus
class blender::asset_system::AssetRepresentation *CTX_wm_asset(const bContext *C);
#endif

View File

@ -24,6 +24,12 @@ struct Mesh;
struct PointCloud;
struct Volume;
struct GreasePencil;
namespace blender::bke {
class ComponentAttributeProviders;
class CurvesEditHints;
class Instances;
class GeometryComponent;
} // namespace blender::bke
namespace blender::bke {
@ -38,11 +44,6 @@ enum class GeometryOwnershipType {
ReadOnly = 2,
};
class ComponentAttributeProviders;
class CurvesEditHints;
class Instances;
class GeometryComponent;
using GeometryComponentPtr = ImplicitSharingPtr<GeometryComponent>;
/**

View File

@ -203,17 +203,16 @@ enum {
* assigned to ID datablocks */
G_DEBUG_DEPSGRAPH = (G_DEBUG_DEPSGRAPH_BUILD | G_DEBUG_DEPSGRAPH_EVAL | G_DEBUG_DEPSGRAPH_TAG |
G_DEBUG_DEPSGRAPH_TIME | G_DEBUG_DEPSGRAPH_UUID),
G_DEBUG_SIMDATA = (1 << 15), /* sim debug data display */
G_DEBUG_GPU = (1 << 16), /* gpu debug */
G_DEBUG_IO = (1 << 17), /* IO Debugging (for Collada, ...). */
G_DEBUG_GPU_FORCE_WORKAROUNDS = (1 << 18), /* force gpu workarounds bypassing detections. */
G_DEBUG_GPU_FORCE_DISABLE_SSBO = (1 << 19), /* force disabling usage of SSBO's */
G_DEBUG_GPU_RENDERDOC = (1 << 20), /* Enable RenderDoc integration. */
G_DEBUG_XR = (1 << 21), /* XR/OpenXR messages */
G_DEBUG_XR_TIME = (1 << 22), /* XR/OpenXR timing messages */
G_DEBUG_SIMDATA = (1 << 15), /* sim debug data display */
G_DEBUG_GPU = (1 << 16), /* gpu debug */
G_DEBUG_IO = (1 << 17), /* IO Debugging (for Collada, ...). */
G_DEBUG_GPU_FORCE_WORKAROUNDS = (1 << 18), /* force gpu workarounds bypassing detections. */
G_DEBUG_GPU_RENDERDOC = (1 << 19), /* Enable RenderDoc integration. */
G_DEBUG_XR = (1 << 20), /* XR/OpenXR messages */
G_DEBUG_XR_TIME = (1 << 21), /* XR/OpenXR timing messages */
G_DEBUG_GHOST = (1 << 23), /* Debug GHOST module. */
G_DEBUG_WINTAB = (1 << 24), /* Debug Wintab. */
G_DEBUG_GHOST = (1 << 22), /* Debug GHOST module. */
G_DEBUG_WINTAB = (1 << 23), /* Debug Wintab. */
};
#define G_DEBUG_ALL \

View File

@ -704,6 +704,16 @@ inline blender::Span<bNodeLink> bNode::internal_links() const
return this->runtime->internal_links;
}
inline bool bNode::is_socket_drawn(const bNodeSocket &socket) const
{
return socket.is_visible();
}
inline bool bNode::is_socket_icon_drawn(const bNodeSocket &socket) const
{
return socket.is_visible() && (this->flag & NODE_HIDDEN || !socket.is_panel_collapsed());
}
inline blender::Span<bNode *> bNode::direct_children_in_frame() const
{
BLI_assert(blender::bke::node_tree_runtime::topology_cache_is_available(*this));
@ -794,14 +804,9 @@ inline bool bNodeSocket::is_panel_collapsed() const
return (this->flag & SOCK_PANEL_COLLAPSED) != 0;
}
inline bool bNodeSocket::is_visible_or_panel_collapsed() const
{
return !this->is_hidden() && this->is_available();
}
inline bool bNodeSocket::is_visible() const
{
return this->is_visible_or_panel_collapsed() && !this->is_panel_collapsed();
return !this->is_hidden() && this->is_available();
}
inline bNode &bNodeSocket::owner_node()

View File

@ -56,7 +56,7 @@ void BKE_text_write(struct Text *text, const char *str, int str_len) ATTR_NONNUL
* - 2 if filepath on disk has been deleted.
* - -1 is returned if an error occurs.
*/
int BKE_text_file_modified_check(struct Text *text);
int BKE_text_file_modified_check(const struct Text *text);
void BKE_text_file_modified_ignore(struct Text *text);
char *txt_to_buf(struct Text *text, size_t *r_buf_strlen)

View File

@ -1484,10 +1484,10 @@ bool CTX_data_editable_gpencil_strokes(const bContext *C, ListBase *list)
const AssetLibraryReference *CTX_wm_asset_library_ref(const bContext *C)
{
return static_cast<AssetLibraryReference *>(ctx_data_pointer_get(C, "asset_library_ref"));
return static_cast<AssetLibraryReference *>(ctx_data_pointer_get(C, "asset_library_reference"));
}
AssetHandle CTX_wm_asset_handle(const bContext *C, bool *r_is_valid)
static AssetHandle ctx_wm_asset_handle(const bContext *C, bool *r_is_valid)
{
AssetHandle *asset_handle_p =
(AssetHandle *)CTX_data_pointer_get_type(C, "asset_handle", &RNA_AssetHandle).data;
@ -1514,8 +1514,20 @@ AssetHandle CTX_wm_asset_handle(const bContext *C, bool *r_is_valid)
blender::asset_system::AssetRepresentation *CTX_wm_asset(const bContext *C)
{
return static_cast<blender::asset_system::AssetRepresentation *>(
ctx_data_pointer_get(C, "asset"));
if (auto *asset = static_cast<blender::asset_system::AssetRepresentation *>(
ctx_data_pointer_get(C, "asset")))
{
return asset;
}
/* Expose the asset representation from the asset-handle.
* TODO(Julian): #AssetHandle should be properly replaced by #AssetRepresentation. */
bool is_valid;
if (AssetHandle handle = ctx_wm_asset_handle(C, &is_valid); is_valid) {
return handle.file_data->asset;
}
return nullptr;
}
Depsgraph *CTX_data_depsgraph_pointer(const bContext *C)

View File

@ -2588,8 +2588,9 @@ static void *socket_value_storage(bNodeSocket &socket)
return &socket.default_value_typed<bNodeSocketValueObject>()->value;
case SOCK_MATERIAL:
return &socket.default_value_typed<bNodeSocketValueMaterial>()->value;
case SOCK_STRING:
case SOCK_ROTATION:
return &socket.default_value_typed<bNodeSocketValueRotation>()->value_euler;
case SOCK_STRING:
/* We don't want do this now! */
return nullptr;
case SOCK_CUSTOM:
@ -2756,8 +2757,7 @@ void nodeRemSocketLinks(bNodeTree *ntree, bNodeSocket *sock)
bool nodeLinkIsHidden(const bNodeLink *link)
{
return !(link->fromsock->is_visible_or_panel_collapsed() &&
link->tosock->is_visible_or_panel_collapsed());
return !(link->fromsock->is_visible() && link->tosock->is_visible());
}
namespace blender::bke {

View File

@ -525,7 +525,7 @@ void BKE_text_write(Text *text, const char *str, int str_len) /* called directly
txt_make_dirty(text);
}
int BKE_text_file_modified_check(Text *text)
int BKE_text_file_modified_check(const Text *text)
{
BLI_stat_t st;
int result;

View File

@ -245,7 +245,7 @@ static void polyedge_beauty_cost_update(const float (*coords)[2],
}
}
static void polyedge_rotate(struct HalfEdge *edges, struct HalfEdge *e)
static void polyedge_rotate(struct HalfEdge *edges, const struct HalfEdge *e)
{
/** CCW winding, rotate internal edge to new vertical state.
*

View File

@ -196,7 +196,8 @@ static void eevee_init_util_texture()
texels_layer[y * 64 + x][0] = blender::eevee::lut::bsdf_ggx[j][y][x][0];
texels_layer[y * 64 + x][1] = blender::eevee::lut::bsdf_ggx[j][y][x][1];
texels_layer[y * 64 + x][2] = blender::eevee::lut::bsdf_ggx[j][y][x][2];
/* BTDF LUT for `IOR > 1`, parametrized differently as above. See `eevee_lut_comp.glsl`. */
/* BTDF LUT for `IOR > 1`, parameterized differently as above.
* See `eevee_lut_comp.glsl`. */
texels_layer[y * 64 + x][3] = blender::eevee::lut::btdf_ggx[j][y][x][0];
}
}

View File

@ -45,6 +45,7 @@ GPU_SHADER_CREATE_INFO(eevee_legacy_material_volumetric_vert)
#ifdef WITH_METAL_BACKEND
GPU_SHADER_CREATE_INFO(eevee_legacy_material_volumetric_vert_no_geom)
.additional_info("eevee_legacy_material_empty_base_volume")
.builtins(BuiltinBits::LAYER)
.vertex_out(legacy_volume_vert_geom_iface)
.vertex_out(legacy_volume_geom_frag_iface)
.additional_info("draw_resource_id_varying");

View File

@ -125,7 +125,7 @@ vec4 ggx_bsdf_split_sum(vec3 lut_coord)
/* Generate BTDF LUT for `IOR > 1` using Schlick's approximation. Only the transmittance is needed
* because the scale and bias does not depend on the IOR and can be obtained from the BRDF LUT.
*
* Parametrize with `x = sqrt((ior - 1) / (ior + 1))` for higher precision in 1 < IOR < 2,
* Parameterize with `x = sqrt((ior - 1) / (ior + 1))` for higher precision in 1 < IOR < 2,
* and `y = sqrt(1.0 - cos(theta))`, `z = roughness` similar to BRDF LUT.
*
* The result is interpreted as:

View File

@ -135,7 +135,7 @@ struct GlobalsUboStorage {
float size_checker;
float size_vertex_gpencil;
float fresnel_mix_edit;
float _pad[3];
float _pad1, _pad2, _pad3;
};
BLI_STATIC_ASSERT_ALIGN(GlobalsUboStorage, 16)

View File

@ -71,8 +71,6 @@ void ARMATURE_OT_autoside_names(struct wmOperatorType *ot);
void ARMATURE_OT_flip_names(struct wmOperatorType *ot);
void ARMATURE_OT_layers_show_all(struct wmOperatorType *ot);
void ARMATURE_OT_armature_layers(struct wmOperatorType *ot);
void ARMATURE_OT_bone_layers(struct wmOperatorType *ot);
void ARMATURE_OT_collection_add(struct wmOperatorType *ot);
void ARMATURE_OT_collection_remove(struct wmOperatorType *ot);

View File

@ -60,8 +60,6 @@ void ED_operatortypes_armature()
WM_operatortype_append(ARMATURE_OT_flip_names);
WM_operatortype_append(ARMATURE_OT_layers_show_all);
WM_operatortype_append(ARMATURE_OT_armature_layers);
WM_operatortype_append(ARMATURE_OT_bone_layers);
WM_operatortype_append(ARMATURE_OT_collection_add);
WM_operatortype_append(ARMATURE_OT_collection_remove);

View File

@ -16,6 +16,7 @@
#include "BKE_context.h"
#include "BKE_layer.h"
#include "BKE_report.h"
#include "DEG_depsgraph.h"
@ -631,18 +632,13 @@ void ARMATURE_OT_collection_deselect(wmOperatorType *ot)
/* -------------------------- */
using assign_func = bool (*)(BoneCollection *, Bone *);
static int add_or_move_to_collection_exec(bContext *C,
wmOperator *op,
const assign_func assign_func)
static BoneCollection *add_or_move_to_collection_bcoll(wmOperator *op, bArmature *arm)
{
Object *obpose = ED_pose_object_from_context(C);
bArmature *arm = static_cast<bArmature *>(obpose->data);
const int collection_index = RNA_enum_get(op->ptr, "collection");
BoneCollection *target_bcoll;
if (collection_index < 0) {
/* TODO: check this with linked, non-overridden armatures. */
char new_collection_name[MAX_NAME];
RNA_string_get(op->ptr, "new_collection_name", new_collection_name);
target_bcoll = ANIM_armature_bonecoll_new(arm, new_collection_name);
@ -654,41 +650,85 @@ static int add_or_move_to_collection_exec(bContext *C,
target_bcoll = static_cast<BoneCollection *>(
BLI_findlink(&arm->collections, collection_index));
if (target_bcoll == nullptr) {
WM_reportf(RPT_ERROR,
"Bone collection with index %d not found on Armature %s",
collection_index,
arm->id.name + 2);
return OPERATOR_CANCELLED;
BKE_reportf(op->reports,
RPT_ERROR,
"Bone collection with index %d not found on Armature %s",
collection_index,
arm->id.name + 2);
return nullptr;
}
}
if (!ANIM_armature_bonecoll_is_editable(arm, target_bcoll)) {
WM_reportf(RPT_ERROR,
"Bone collection %s is not editable, maybe add an override on the armature?",
target_bcoll->name);
BKE_reportf(op->reports,
RPT_ERROR,
"Bone collection %s is not editable, maybe add an override on the armature?",
target_bcoll->name);
return nullptr;
}
return target_bcoll;
}
static int add_or_move_to_collection_exec(bContext *C,
wmOperator *op,
const assign_bone_func assign_func_bone,
const assign_ebone_func assign_func_ebone)
{
Object *ob = ED_object_context(C);
if (ob->mode == OB_MODE_POSE) {
ob = ED_pose_object_from_context(C);
}
if (!ob) {
BKE_reportf(op->reports, RPT_ERROR, "No object found to operate on");
return OPERATOR_CANCELLED;
}
FOREACH_PCHAN_SELECTED_IN_OBJECT_BEGIN (obpose, pchan) {
assign_func(target_bcoll, pchan->bone);
bArmature *arm = static_cast<bArmature *>(ob->data);
BoneCollection *target_bcoll = add_or_move_to_collection_bcoll(op, arm);
bool made_any_changes = false;
bool had_bones_to_assign = false;
const bool mode_is_supported = bone_collection_assign_mode_specific(C,
ob,
target_bcoll,
assign_func_bone,
assign_func_ebone,
&made_any_changes,
&had_bones_to_assign);
if (!mode_is_supported) {
WM_report(RPT_ERROR, "This operator only works in pose mode and armature edit mode");
return OPERATOR_CANCELLED;
}
if (!had_bones_to_assign) {
WM_report(RPT_WARNING, "No bones selected, nothing to assign to bone collection");
return OPERATOR_CANCELLED;
}
if (!made_any_changes) {
WM_report(RPT_WARNING, "All selected bones were already part of this collection");
return OPERATOR_CANCELLED;
}
FOREACH_PCHAN_SELECTED_IN_OBJECT_END;
DEG_id_tag_update(&arm->id, ID_RECALC_SELECT); /* Recreate the draw buffers. */
WM_event_add_notifier(C, NC_OBJECT | ND_DATA, obpose);
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, obpose);
WM_event_add_notifier(C, NC_OBJECT | ND_DATA, ob);
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
return OPERATOR_FINISHED;
}
static int move_to_collection_exec(bContext *C, wmOperator *op)
{
return add_or_move_to_collection_exec(C, op, ANIM_armature_bonecoll_assign_and_move);
return add_or_move_to_collection_exec(C,
op,
ANIM_armature_bonecoll_assign_and_move,
ANIM_armature_bonecoll_assign_and_move_editbone);
}
static int assign_to_collection_exec(bContext *C, wmOperator *op)
{
return add_or_move_to_collection_exec(C, op, ANIM_armature_bonecoll_assign);
return add_or_move_to_collection_exec(
C, op, ANIM_armature_bonecoll_assign, ANIM_armature_bonecoll_assign_editbone);
}
static bool move_to_collection_poll(bContext *C)
@ -714,37 +754,67 @@ static bool move_to_collection_poll(bContext *C)
return true;
}
static bool bone_collection_enum_itemf_for_object(Object *ob,
EnumPropertyItem **item,
int *totitem)
{
EnumPropertyItem item_tmp = {0};
bArmature *arm = static_cast<bArmature *>(ob->data);
int bcoll_index = 0;
LISTBASE_FOREACH_INDEX (BoneCollection *, bcoll, &arm->collections, bcoll_index) {
if (!ANIM_armature_bonecoll_is_editable(arm, bcoll)) {
/* Skip bone collections that cannot be assigned to because they're
* linked and thus uneditable. If there is a way to still show these, but in a disabled
* state, that would be preferred. */
continue;
}
item_tmp.identifier = bcoll->name;
item_tmp.name = bcoll->name;
item_tmp.value = bcoll_index;
RNA_enum_item_add(item, totitem, &item_tmp);
}
return true;
}
static const EnumPropertyItem *bone_collection_enum_itemf(bContext *C,
PointerRNA * /*ptr*/,
PropertyRNA * /*prop*/,
bool *r_free)
{
EnumPropertyItem *item = nullptr, item_tmp = {0};
*r_free = false;
if (!C) {
/* This happens when operators are being tested, and not during normal invocation. */
return rna_enum_dummy_NULL_items;
}
Object *ob = ED_object_context(C);
if (!ob || ob->type != OB_ARMATURE) {
return rna_enum_dummy_NULL_items;
}
EnumPropertyItem *item = nullptr;
int totitem = 0;
if (C) {
if (Object *obpose = ED_pose_object_from_context(C)) {
bArmature *arm = static_cast<bArmature *>(obpose->data);
int bcoll_index = 0;
LISTBASE_FOREACH_INDEX (BoneCollection *, bcoll, &arm->collections, bcoll_index) {
if (!ANIM_armature_bonecoll_is_editable(arm, bcoll)) {
/* Skip bone collections that cannot be assigned to because they're
* linked and thus uneditable. If there is a way to still show these, but in a disabled
* state, that would be preferred. */
continue;
}
item_tmp.identifier = bcoll->name;
item_tmp.name = bcoll->name;
item_tmp.value = bcoll_index;
RNA_enum_item_add(&item, &totitem, &item_tmp);
switch (ob->mode) {
case OB_MODE_POSE: {
Object *obpose = ED_pose_object_from_context(C);
if (!obpose) {
return nullptr;
}
RNA_enum_item_add_separator(&item, &totitem);
bone_collection_enum_itemf_for_object(obpose, &item, &totitem);
break;
}
case OB_MODE_EDIT:
bone_collection_enum_itemf_for_object(ob, &item, &totitem);
break;
default:
return rna_enum_dummy_NULL_items;
}
/* New Collection. */
EnumPropertyItem item_tmp = {0};
item_tmp.identifier = "__NEW__";
item_tmp.name = "New Collection";
item_tmp.value = -1;

View File

@ -748,77 +748,6 @@ void ARMATURE_OT_layers_show_all(wmOperatorType *ot)
/* ------------------- */
/* Present a popup to get the layers that should be used */
static int armature_layers_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
Object *ob = CTX_data_active_object(C);
bArmature *arm = armature_layers_get_data(&ob);
/* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
bool layers[32];
/* sanity checking */
if (arm == nullptr) {
return OPERATOR_CANCELLED;
}
/* Get RNA pointer to armature data to use that to retrieve the layers as ints
* to init the operator. */
PointerRNA ptr = RNA_id_pointer_create((ID *)arm);
RNA_boolean_get_array(&ptr, "layers", layers);
RNA_boolean_set_array(op->ptr, "layers", layers);
/* part to sync with other similar operators... */
return WM_operator_props_popup(C, op, event);
}
/* Set the visible layers for the active armature (edit and pose modes) */
static int armature_layers_exec(bContext *C, wmOperator *op)
{
Object *ob = CTX_data_active_object(C);
bArmature *arm = armature_layers_get_data(&ob);
/* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
bool layers[32];
if (arm == nullptr) {
return OPERATOR_CANCELLED;
}
/* get the values set in the operator properties */
RNA_boolean_get_array(op->ptr, "layers", layers);
/* get pointer for armature, and write data there... */
PointerRNA ptr = RNA_id_pointer_create((ID *)arm);
RNA_boolean_set_array(&ptr, "layers", layers);
/* NOTE: notifier might evolve. */
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
DEG_id_tag_update(&arm->id, ID_RECALC_COPY_ON_WRITE);
return OPERATOR_FINISHED;
}
void ARMATURE_OT_armature_layers(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Change Armature Layers";
ot->idname = "ARMATURE_OT_armature_layers";
ot->description = "Change the visible armature layers";
/* callbacks */
ot->invoke = armature_layers_invoke;
ot->exec = armature_layers_exec;
ot->poll = armature_layers_poll;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
RNA_def_boolean_layer_member(
ot->srna, "layers", 32, nullptr, "Layer", "Armature layers to make visible");
}
/* ------------------- */
/* Present a popup to get the layers that should be used */
static int pose_bone_layers_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
@ -906,64 +835,6 @@ void POSE_OT_bone_layers(wmOperatorType *ot)
ot->srna, "layers", 32, nullptr, "Layer", "Armature layers that bone belongs to");
}
/* ------------------- */
/* Present a popup to get the layers that should be used */
static int armature_bone_layers_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
/* hardcoded for now - we can only have 32 armature layers, so this should be fine... */
bool layers[32] = {false};
/* get layers that are active already */
CTX_DATA_BEGIN (C, EditBone *, ebone, selected_editable_bones) {
short bit;
/* loop over the bits for this pchan's layers, adding layers where they're needed */
for (bit = 0; bit < 32; bit++) {
if (ebone->layer & (1u << bit)) {
layers[bit] = true;
}
}
}
CTX_DATA_END;
/* copy layers to operator */
RNA_boolean_set_array(op->ptr, "layers", layers);
/* part to sync with other similar operators... */
return WM_operator_props_popup(C, op, event);
}
/* Set the visible layers for the active armature (edit and pose modes) */
static int armature_bone_layers_exec(bContext * /*C*/, wmOperator * /*op*/)
{
// TODO: remove this entire operator, replacing it with a similar one for bone collections.
WM_report(
RPT_ERROR,
"Bone Layers have been converted to Bone Collections. This operator will be removed soon.");
return OPERATOR_CANCELLED;
}
void ARMATURE_OT_bone_layers(wmOperatorType *ot)
{
/* identifiers */
ot->name = "Change Bone Layers";
ot->idname = "ARMATURE_OT_bone_layers";
ot->description = "Change the layers that the selected bones belong to";
/* callbacks */
ot->invoke = armature_bone_layers_invoke;
ot->exec = armature_bone_layers_exec;
ot->poll = ED_operator_editarmature;
/* flags */
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* properties */
RNA_def_boolean_layer_member(
ot->srna, "layers", 32, nullptr, "Layer", "Armature layers that bone belongs to");
}
/* ********************************************** */
/* Show/Hide Bones */

View File

@ -9,6 +9,8 @@
#include <cmath>
#include <cstring>
#include "AS_asset_representation.hh"
#include "MEM_guardedalloc.h"
#include "BLI_string.h"
@ -285,14 +287,11 @@ static void poselib_tempload_exit(PoseBlendData *pbd)
static bAction *poselib_blend_init_get_action(bContext *C, wmOperator *op)
{
bool asset_handle_valid;
const AssetHandle asset_handle = CTX_wm_asset_handle(C, &asset_handle_valid);
/* Poll callback should check. */
BLI_assert(asset_handle_valid);
const AssetRepresentationHandle *asset = CTX_wm_asset(C);
PoseBlendData *pbd = static_cast<PoseBlendData *>(op->customdata);
pbd->temp_id_consumer = ED_asset_temp_id_consumer_create(&asset_handle);
pbd->temp_id_consumer = ED_asset_temp_id_consumer_create(asset);
return (bAction *)ED_asset_temp_id_consumer_ensure_local_id(
pbd->temp_id_consumer, ID_AC, CTX_data_main(C), op->reports);
}
@ -551,11 +550,9 @@ static int poselib_blend_exec(bContext *C, wmOperator *op)
static bool poselib_asset_in_context(bContext *C)
{
bool asset_handle_valid;
/* Check whether the context provides the asset data needed to add a pose. */
const AssetHandle asset_handle = CTX_wm_asset_handle(C, &asset_handle_valid);
return asset_handle_valid && (ED_asset_handle_get_id_type(&asset_handle) == ID_AC);
const AssetRepresentationHandle *asset = CTX_wm_asset(C);
return asset && (asset->get_id_type() == ID_AC);
}
/* Poll callback for operators that require existing PoseLib data (with poses) to work. */

View File

@ -15,17 +15,25 @@
#include "DNA_ID_enums.h"
#ifdef __cplusplus
namespace blender::asset_system {
class AssetRepresentation;
}
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef struct AssetTempIDConsumer AssetTempIDConsumer;
struct AssetHandle;
struct Main;
struct ReportList;
AssetTempIDConsumer *ED_asset_temp_id_consumer_create(const struct AssetHandle *handle);
#ifdef __cplusplus
extern "C++" AssetTempIDConsumer *ED_asset_temp_id_consumer_create(
const blender::asset_system::AssetRepresentation *asset);
#endif
void ED_asset_temp_id_consumer_free(AssetTempIDConsumer **consumer);
struct ID *ED_asset_temp_id_consumer_ensure_local_id(AssetTempIDConsumer *consumer,
ID_Type id_type,

View File

@ -287,12 +287,9 @@ void AssetClearHelper::operator()(PointerRNAVec &ids)
void AssetClearHelper::reportResults(const bContext *C, ReportList &reports) const
{
if (!wasSuccessful()) {
bool is_valid;
/* Dedicated error message for when there is an active asset detected, but it's not an ID local
* to this file. Helps users better understanding what's going on. */
if (AssetHandle active_asset = CTX_wm_asset_handle(C, &is_valid);
is_valid && !ED_asset_handle_get_representation(&active_asset)->local_id())
{
if (AssetRepresentationHandle *active_asset = CTX_wm_asset(C); !active_asset->is_local_id()) {
BKE_report(&reports,
RPT_ERROR,
"No asset data-blocks from the current file selected (assets must be stored in "
@ -820,7 +817,7 @@ static void ASSET_OT_bundle_install(wmOperatorType *ot)
ot->invoke = asset_bundle_install_invoke;
ot->poll = asset_bundle_install_poll;
ot->prop = RNA_def_property(ot->srna, "asset_library_ref", PROP_ENUM, PROP_NONE);
ot->prop = RNA_def_property(ot->srna, "asset_library_reference", PROP_ENUM, PROP_NONE);
RNA_def_property_flag(ot->prop, PROP_HIDDEN);
RNA_def_enum_funcs(ot->prop, rna_asset_library_reference_itemf);
@ -843,7 +840,7 @@ static bool could_be_asset_bundle(const Main *bmain)
static const bUserAssetLibrary *selected_asset_library(wmOperator *op)
{
const int enum_value = RNA_enum_get(op->ptr, "asset_library_ref");
const int enum_value = RNA_enum_get(op->ptr, "asset_library_reference");
const AssetLibraryReference lib_ref = ED_asset_library_reference_from_enum_value(enum_value);
const bUserAssetLibrary *lib = BKE_preferences_asset_library_find_index(
&U, lib_ref.custom_library_index);
@ -860,7 +857,7 @@ static bool is_contained_in_selected_asset_library(wmOperator *op, const char *f
}
/**
* Set the "filepath" RNA property based on selected "asset_library_ref".
* Set the "filepath" RNA property based on selected "asset_library_reference".
* \return true if ok, false if error.
*/
static bool set_filepath_for_asset_lib(const Main *bmain, wmOperator *op)

View File

@ -508,7 +508,7 @@ int ED_asset_shelf_context(const bContext *C, const char *member, bContextDataRe
{
static const char *context_dir[] = {
"asset_shelf",
"asset_library_ref",
"asset_library_reference",
"active_file", /* XXX yuk... */
nullptr,
};
@ -544,7 +544,7 @@ int ED_asset_shelf_context(const bContext *C, const char *member, bContextDataRe
return CTX_RESULT_OK;
}
if (CTX_data_equals(member, "asset_library_ref")) {
if (CTX_data_equals(member, "asset_library_reference")) {
CTX_data_pointer_set(result,
&screen->id,
&RNA_AssetLibraryReference,

View File

@ -14,10 +14,6 @@
#include "AS_asset_representation.hh"
#include "DNA_space_types.h"
#include "ED_asset.hh"
#include "BKE_report.h"
#include "BLI_utility_mixins.hh"
@ -69,14 +65,14 @@ class AssetTemporaryIDConsumer : NonCopyable, NonMovable {
}
};
AssetTempIDConsumer *ED_asset_temp_id_consumer_create(const AssetHandle *handle)
AssetTempIDConsumer *ED_asset_temp_id_consumer_create(
const asset_system::AssetRepresentation *asset)
{
if (!handle) {
if (!asset) {
return nullptr;
}
BLI_assert(handle->file_data->asset != nullptr);
return reinterpret_cast<AssetTempIDConsumer *>(
MEM_new<AssetTemporaryIDConsumer>(__func__, ED_asset_handle_get_representation(handle)));
MEM_new<AssetTemporaryIDConsumer>(__func__, asset));
}
void ED_asset_temp_id_consumer_free(AssetTempIDConsumer **consumer)

View File

@ -2383,13 +2383,16 @@ static void UI_OT_list_start_filter(wmOperatorType *ot)
static bool ui_view_focused_poll(bContext *C)
{
const wmWindow *win = CTX_wm_window(C);
if (!(win && win->eventstate)) {
return false;
}
const ARegion *region = CTX_wm_region(C);
if (!region) {
return false;
}
const wmWindow *win = CTX_wm_window(C);
const uiViewHandle *view = UI_region_view_find_at(region, win->eventstate->xy, 0);
return view != nullptr;
}
@ -2426,6 +2429,9 @@ static void UI_OT_view_start_filter(wmOperatorType *ot)
static bool ui_view_drop_poll(bContext *C)
{
const wmWindow *win = CTX_wm_window(C);
if (!(win && win->eventstate)) {
return false;
}
const ARegion *region = CTX_wm_region(C);
if (region == nullptr) {
return false;

View File

@ -407,6 +407,11 @@ static uiTooltipData *ui_tooltip_data_from_tool(bContext *C, uiBut *but, bool is
if (but->optype == nullptr) {
return nullptr;
}
/* While this should always be set for buttons as they are shown in the UI,
* the operator search popup can create a button that has no properties, see: #112541. */
if (but->opptr == nullptr) {
return nullptr;
}
if (!STREQ(but->optype->idname, "WM_OT_tool_set_by_id")) {
return nullptr;

View File

@ -1868,17 +1868,17 @@ static short mouse_in_scroller_handle(int mouse, int sc_min, int sc_max, int sh_
static bool scroller_activate_poll(bContext *C)
{
const wmWindow *win = CTX_wm_window(C);
if (!(win && win->eventstate)) {
return false;
}
if (!view2d_poll(C)) {
return false;
}
wmWindow *win = CTX_wm_window(C);
ARegion *region = CTX_wm_region(C);
View2D *v2d = &region->v2d;
wmEvent *event = win->eventstate;
/* Check if mouse in scroll-bars, if they're enabled. */
return (UI_view2d_mouse_in_scrollers(region, v2d, event->xy) != 0);
return (UI_view2d_mouse_in_scrollers(region, v2d, win->eventstate->xy) != 0);
}
/* Initialize #wmOperator.customdata for scroller manipulation operator. */

View File

@ -52,32 +52,33 @@ static const EnumPropertyItem prop_similar_compare_types[] = {
};
static const EnumPropertyItem prop_similar_types[] = {
{SIMVERT_NORMAL, "NORMAL", 0, "Normal", ""},
{SIMVERT_FACE, "FACE", 0, "Amount of Adjacent Faces", ""},
{SIMVERT_VGROUP, "VGROUP", 0, "Vertex Groups", ""},
{SIMVERT_EDGE, "EDGE", 0, "Amount of Connecting Edges", ""},
{SIMVERT_CREASE, "VCREASE", 0, "Vertex Crease", ""},
{SIMEDGE_LENGTH, "LENGTH", 0, "Length", ""},
{SIMEDGE_DIR, "DIR", 0, "Direction", ""},
{SIMEDGE_FACE, "FACE", 0, "Amount of Faces Around an Edge", ""},
{SIMEDGE_FACE_ANGLE, "FACE_ANGLE", 0, "Face Angles", ""},
{SIMEDGE_CREASE, "CREASE", 0, "Crease", ""},
{SIMEDGE_BEVEL, "BEVEL", 0, "Bevel", ""},
{SIMEDGE_SEAM, "SEAM", 0, "Seam", ""},
{SIMEDGE_SHARP, "SHARP", 0, "Sharpness", ""},
{SIMVERT_NORMAL, "VERT_NORMAL", 0, "Normal", ""},
{SIMVERT_FACE, "VERT_FACES", 0, "Amount of Adjacent Faces", ""},
{SIMVERT_VGROUP, "VERT_GROUPS", 0, "Vertex Groups", ""},
{SIMVERT_EDGE, "VERT_EDGES", 0, "Amount of Connecting Edges", ""},
{SIMVERT_CREASE, "VERT_CREASE", 0, "Vertex Crease", ""},
{SIMEDGE_LENGTH, "EDGE_LENGTH", 0, "Length", ""},
{SIMEDGE_DIR, "EDGE_DIR", 0, "Direction", ""},
{SIMEDGE_FACE, "EDGE_FACES", 0, "Amount of Faces Around an Edge", ""},
{SIMEDGE_FACE_ANGLE, "EDGE_FACE_ANGLE", 0, "Face Angles", ""},
{SIMEDGE_CREASE, "EDGE_CREASE", 0, "Crease", ""},
{SIMEDGE_BEVEL, "EDGE_BEVEL", 0, "Bevel", ""},
{SIMEDGE_SEAM, "EDGE_SEAM", 0, "Seam", ""},
{SIMEDGE_SHARP, "EDGE_SHARP", 0, "Sharpness", ""},
#ifdef WITH_FREESTYLE
{SIMEDGE_FREESTYLE, "FREESTYLE_EDGE", 0, "Freestyle Edge Marks", ""},
{SIMEDGE_FREESTYLE, "EDGE_FREESTYLE", 0, "Freestyle Edge Marks", ""},
#endif
{SIMFACE_MATERIAL, "MATERIAL", 0, "Material", ""},
{SIMFACE_AREA, "AREA", 0, "Area", ""},
{SIMFACE_SIDES, "SIDES", 0, "Polygon Sides", ""},
{SIMFACE_PERIMETER, "PERIMETER", 0, "Perimeter", ""},
{SIMFACE_NORMAL, "NORMAL", 0, "Normal", ""},
{SIMFACE_COPLANAR, "COPLANAR", 0, "Coplanar", ""},
{SIMFACE_SMOOTH, "SMOOTH", 0, "Flat/Smooth", ""},
{SIMFACE_MATERIAL, "FACE_MATERIAL", 0, "Material", ""},
{SIMFACE_AREA, "FACE_AREA", 0, "Area", ""},
{SIMFACE_SIDES, "FACE_SIDES", 0, "Polygon Sides", ""},
{SIMFACE_PERIMETER, "FACE_PERIMETER", 0, "Perimeter", ""},
{SIMFACE_NORMAL, "FACE_NORMAL", 0, "Normal", ""},
{SIMFACE_COPLANAR, "FACE_COPLANAR", 0, "Coplanar", ""},
{SIMFACE_SMOOTH, "FACE_SMOOTH", 0, "Flat/Smooth", ""},
#ifdef WITH_FREESTYLE
{SIMFACE_FREESTYLE, "FREESTYLE_FACE", 0, "Freestyle Face Marks", ""},
{SIMFACE_FREESTYLE, "FACE_FREESTYLE", 0, "Freestyle Face Marks", ""},
#endif
{0, nullptr, 0, nullptr, nullptr},

View File

@ -114,7 +114,7 @@ const char *screen_context_dir[] = {
"selected_editable_keyframes",
"ui_list",
"property",
"asset_library_ref",
"asset_library_reference",
nullptr,
};
@ -1380,7 +1380,7 @@ static void ensure_ed_screen_context_functions()
register_context_function("selected_visible_fcurves", screen_ctx_selected_visible_fcurves);
register_context_function("active_editable_fcurve", screen_ctx_active_editable_fcurve);
register_context_function("selected_editable_keyframes", screen_ctx_selected_editable_keyframes);
register_context_function("asset_library_ref", screen_ctx_asset_library);
register_context_function("asset_library_reference", screen_ctx_asset_library);
register_context_function("ui_list", screen_ctx_ui_list);
register_context_function("property", screen_ctx_property);
}

View File

@ -19,8 +19,8 @@
const char *file_context_dir[] = {
"active_file",
"selected_files",
"asset_library_ref",
"selected_asset_files",
"asset_library_reference",
"selected_assets",
"id",
"selected_ids",
nullptr,
@ -69,7 +69,7 @@ int /*eContextResult*/ file_context(const bContext *C,
return CTX_RESULT_OK;
}
if (CTX_data_equals(member, "asset_library_ref")) {
if (CTX_data_equals(member, "asset_library_reference")) {
FileAssetSelectParams *asset_params = ED_fileselect_get_asset_params(sfile);
if (!asset_params) {
return CTX_RESULT_NO_DATA;
@ -79,17 +79,14 @@ int /*eContextResult*/ file_context(const bContext *C,
result, &screen->id, &RNA_AssetLibraryReference, &asset_params->asset_library_ref);
return CTX_RESULT_OK;
}
/** TODO temporary AssetHandle design: For now this returns the file entry. Would be better if it
* was `"selected_assets"` and returned the assets (e.g. as `AssetHandle`) directly. See comment
* for #AssetHandle for more info. */
if (CTX_data_equals(member, "selected_asset_files")) {
if (CTX_data_equals(member, "selected_assets")) {
const int num_files_filtered = filelist_files_ensure(sfile->files);
for (int file_index = 0; file_index < num_files_filtered; file_index++) {
if (filelist_entry_is_selected(sfile->files, file_index)) {
FileDirEntry *entry = filelist_file(sfile->files, file_index);
if (entry->asset) {
CTX_data_list_add(result, &screen->id, &RNA_FileSelectEntry, entry);
CTX_data_list_add(result, nullptr, &RNA_AssetRepresentation, entry->asset);
}
}
}

View File

@ -234,7 +234,7 @@ static void file_panel_asset_catalog_buttons_draw(const bContext *C, Panel *pane
PointerRNA params_ptr = RNA_pointer_create(&screen->id, &RNA_FileAssetSelectParams, params);
uiItemR(row, &params_ptr, "asset_library_ref", UI_ITEM_NONE, "", ICON_NONE);
uiItemR(row, &params_ptr, "asset_library_reference", UI_ITEM_NONE, "", ICON_NONE);
if (params->asset_library_ref.type == ASSET_LIBRARY_LOCAL) {
bContext *mutable_ctx = CTX_copy(C);
if (WM_operator_name_poll(mutable_ctx, "asset.bundle_install")) {
@ -242,7 +242,7 @@ static void file_panel_asset_catalog_buttons_draw(const bContext *C, Panel *pane
uiItemMenuEnumO(col,
C,
"asset.bundle_install",
"asset_library_ref",
"asset_library_reference",
"Copy Bundle to Asset Library...",
ICON_IMPORT);
}

View File

@ -407,8 +407,8 @@ static bool node_update_basis_socket(const bContext &C,
const int &locx,
int &locy)
{
if ((!input_socket || !input_socket->is_visible_or_panel_collapsed()) &&
(!output_socket || !output_socket->is_visible_or_panel_collapsed()))
if ((!input_socket || !input_socket->is_visible()) &&
(!output_socket || !output_socket->is_visible()))
{
return false;
}
@ -701,7 +701,7 @@ static void node_update_basis_from_declaration(
}
else {
/* Space between items. */
if (!is_first && item.input->is_visible_or_panel_collapsed()) {
if (!is_first && item.input->is_visible()) {
locy -= NODE_SOCKDY;
}
}
@ -714,7 +714,7 @@ static void node_update_basis_from_declaration(
}
else {
/* Space between items. */
if (!is_first && item.output->is_visible_or_panel_collapsed()) {
if (!is_first && item.output->is_visible()) {
locy -= NODE_SOCKDY;
}
}
@ -865,12 +865,12 @@ static void node_update_hidden(bNode &node, uiBlock &block)
/* Calculate minimal radius. */
for (const bNodeSocket *socket : node.input_sockets()) {
if (socket->is_visible_or_panel_collapsed()) {
if (socket->is_visible()) {
totin++;
}
}
for (const bNodeSocket *socket : node.output_sockets()) {
if (socket->is_visible_or_panel_collapsed()) {
if (socket->is_visible()) {
totout++;
}
}
@ -891,7 +891,7 @@ static void node_update_hidden(bNode &node, uiBlock &block)
float drad = rad;
for (bNodeSocket *socket : node.output_sockets()) {
if (socket->is_visible_or_panel_collapsed()) {
if (socket->is_visible()) {
/* Round the socket location to stop it from jiggling. */
socket->runtime->location = {
round(node.runtime->totr.xmax - hiddenrad + sinf(rad) * hiddenrad),
@ -904,7 +904,7 @@ static void node_update_hidden(bNode &node, uiBlock &block)
rad = drad = -float(M_PI) / (1.0f + float(totin));
for (bNodeSocket *socket : node.input_sockets()) {
if (socket->is_visible_or_panel_collapsed()) {
if (socket->is_visible()) {
/* Round the socket location to stop it from jiggling. */
socket->runtime->location = {
round(node.runtime->totr.xmin + hiddenrad + sinf(rad) * hiddenrad),
@ -1751,7 +1751,8 @@ static void node_draw_sockets(const View2D &v2d,
/* Socket inputs. */
int selected_input_len = 0;
for (const bNodeSocket *sock : node.input_sockets()) {
if (!sock->is_visible()) {
/* In "hidden" nodes: draw sockets even when panels are collapsed. */
if (!node.is_socket_icon_drawn(*sock)) {
continue;
}
if (select_all || (sock->flag & SELECT)) {
@ -1774,7 +1775,8 @@ static void node_draw_sockets(const View2D &v2d,
int selected_output_len = 0;
if (draw_outputs) {
for (const bNodeSocket *sock : node.output_sockets()) {
if (!sock->is_visible()) {
/* In "hidden" nodes: draw sockets even when panels are collapsed. */
if (!node.is_socket_icon_drawn(*sock)) {
continue;
}
if (select_all || (sock->flag & SELECT)) {
@ -1802,7 +1804,7 @@ static void node_draw_sockets(const View2D &v2d,
if (selected_input_len) {
/* Socket inputs. */
for (const bNodeSocket *sock : node.input_sockets()) {
if (!sock->is_visible()) {
if (!node.is_socket_icon_drawn(*sock)) {
continue;
}
/* Don't draw multi-input sockets here since they are drawn in a different batch. */
@ -1831,7 +1833,7 @@ static void node_draw_sockets(const View2D &v2d,
if (selected_output_len) {
/* Socket outputs. */
for (const bNodeSocket *sock : node.output_sockets()) {
if (!sock->is_visible()) {
if (!node.is_socket_icon_drawn(*sock)) {
continue;
}
if (select_all || (sock->flag & SELECT)) {
@ -1864,7 +1866,7 @@ static void node_draw_sockets(const View2D &v2d,
/* Draw multi-input sockets after the others because they are drawn with `UI_draw_roundbox`
* rather than with `GL_POINT`. */
for (const bNodeSocket *socket : node.input_sockets()) {
if (!socket->is_visible()) {
if (!node.is_socket_icon_drawn(*socket)) {
continue;
}
if (!(socket->flag & SOCK_MULTI_INPUT)) {

View File

@ -1191,7 +1191,7 @@ bNodeSocket *node_find_indicated_socket(SpaceNode &snode,
if (in_out & SOCK_IN) {
for (bNodeSocket *sock : node.input_sockets()) {
if (sock->is_visible()) {
if (node.is_socket_icon_drawn(*sock)) {
const float2 location = sock->runtime->location;
if (sock->flag & SOCK_MULTI_INPUT && !(node.flag & NODE_HIDDEN)) {
if (cursor_isect_multi_input_socket(cursor, *sock)) {
@ -1210,7 +1210,7 @@ bNodeSocket *node_find_indicated_socket(SpaceNode &snode,
}
if (in_out & SOCK_OUT) {
for (bNodeSocket *sock : node.output_sockets()) {
if (sock->is_visible()) {
if (node.is_socket_icon_drawn(*sock)) {
const float2 location = sock->runtime->location;
if (BLI_rctf_isect_pt(&rect, location.x, location.y)) {
if (!socket_is_occluded(location, node, snode)) {

View File

@ -170,7 +170,7 @@ static void pick_input_link_by_link_intersect(const bContext &C,
static bool socket_is_available(bNodeTree * /*ntree*/, bNodeSocket *sock, const bool allow_used)
{
if (!sock->is_visible_or_panel_collapsed()) {
if (!sock->is_visible()) {
return false;
}
@ -414,9 +414,9 @@ namespace viewer_linking {
* \{ */
/* Depending on the node tree type, different socket types are supported by viewer nodes. */
static bool socket_can_be_viewed(const bNodeSocket &socket)
static bool socket_can_be_viewed(const bNode &node, const bNodeSocket &socket)
{
if (!socket.is_visible()) {
if (!node.is_socket_icon_drawn(socket)) {
return false;
}
if (STREQ(socket.idname, "NodeSocketVirtual")) {
@ -530,7 +530,7 @@ static bNodeSocket *determine_socket_to_view(bNode &node_to_view)
int last_linked_data_socket_index = -1;
bool has_linked_geometry_socket = false;
for (bNodeSocket *socket : node_to_view.output_sockets()) {
if (!socket_can_be_viewed(*socket)) {
if (!socket_can_be_viewed(node_to_view, *socket)) {
continue;
}
for (bNodeLink *link : socket->directly_linked_links()) {
@ -554,7 +554,7 @@ static bNodeSocket *determine_socket_to_view(bNode &node_to_view)
if (last_linked_data_socket_index == -1 && !has_linked_geometry_socket) {
/* Return the first socket that can be viewed. */
for (bNodeSocket *socket : node_to_view.output_sockets()) {
if (socket_can_be_viewed(*socket)) {
if (socket_can_be_viewed(node_to_view, *socket)) {
return socket;
}
}
@ -566,7 +566,7 @@ static bNodeSocket *determine_socket_to_view(bNode &node_to_view)
for (const int offset : IndexRange(1, tot_outputs)) {
const int index = (last_linked_data_socket_index + offset) % tot_outputs;
bNodeSocket &output_socket = node_to_view.output_socket(index);
if (!socket_can_be_viewed(output_socket)) {
if (!socket_can_be_viewed(node_to_view, output_socket)) {
continue;
}
if (has_linked_geometry_socket && output_socket.type == SOCK_GEOMETRY) {
@ -2264,7 +2264,7 @@ bNodeSocket *get_main_socket(bNodeTree &ntree, bNode &node, eNodeSocketInOut in_
int index;
LISTBASE_FOREACH_INDEX (bNodeSocket *, socket, sockets, index) {
const nodes::SocketDeclaration &socket_decl = *socket_decls[index];
if (!socket->is_visible_or_panel_collapsed()) {
if (!socket->is_visible()) {
continue;
}
if (socket_decl.is_default_link_socket) {
@ -2285,7 +2285,7 @@ bNodeSocket *get_main_socket(bNodeTree &ntree, bNode &node, eNodeSocketInOut in_
/* Try all priorities, starting from 'highest'. */
for (int priority = maxpriority; priority >= 0; priority--) {
LISTBASE_FOREACH (bNodeSocket *, sock, sockets) {
if (!!sock->is_visible_or_panel_collapsed() && priority == get_main_socket_priority(sock)) {
if (!!sock->is_visible() && priority == get_main_socket_priority(sock)) {
return sock;
}
}

View File

@ -49,19 +49,23 @@ static int strip_modifier_add_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
static const EnumPropertyItem *filter_modifiers_by_sequence_type(bContext *C,
PointerRNA * /* ptr */,
PropertyRNA * /* prop */,
bool * /* r_free */)
static const EnumPropertyItem *filter_modifiers_by_sequence_type_itemf(bContext *C,
PointerRNA * /*ptr*/,
PropertyRNA * /*prop*/,
bool * /*r_free*/)
{
if (C == nullptr) {
return rna_enum_sequence_modifier_type_items;
}
Scene *scene = CTX_data_scene(C);
Sequence *seq = SEQ_select_active_get(scene);
if (ELEM(seq->type, SEQ_TYPE_SOUND_RAM)) {
return rna_enum_sequence_sound_modifier_type_items;
}
else {
return rna_enum_sequence_video_modifier_type_items;
if (seq) {
if (ELEM(seq->type, SEQ_TYPE_SOUND_RAM)) {
return rna_enum_sequence_sound_modifier_type_items;
}
}
return rna_enum_sequence_video_modifier_type_items;
}
void SEQUENCER_OT_strip_modifier_add(wmOperatorType *ot)
@ -85,7 +89,7 @@ void SEQUENCER_OT_strip_modifier_add(wmOperatorType *ot)
/* properties */
prop = RNA_def_enum(ot->srna, "type", rna_enum_dummy_NULL_items, 0, "Type", "");
RNA_def_enum_funcs(prop, filter_modifiers_by_sequence_type);
RNA_def_enum_funcs(prop, filter_modifiers_by_sequence_type_itemf);
ot->prop = prop;
}

View File

@ -319,10 +319,10 @@ ImBuf *make_sep_waveform_view_from_ibuf(ImBuf *ibuf)
return make_sep_waveform_view_from_ibuf_byte(ibuf);
}
static void draw_zebra_byte(ImBuf *src, ImBuf *ibuf, float perc)
static void draw_zebra_byte(const ImBuf *src, ImBuf *ibuf, float perc)
{
uint limit = 255.0f * perc / 100.0f;
uchar *p = src->byte_buffer.data;
const uchar *p = src->byte_buffer.data;
uchar *o = ibuf->byte_buffer.data;
int x;
int y;

View File

@ -13,6 +13,7 @@ set(INC
../editors/include
../makesrna
../render
../render/intern
../windowmanager
../../../intern/eigen

View File

@ -52,6 +52,9 @@
#include "DNA_scene_types.h"
#include "MEM_guardedalloc.h"
#include "RE_pipeline.h"
#include "render_types.h"
#include "lineart_intern.h"
struct LineartIsecSingle {
@ -4991,34 +4994,42 @@ bool MOD_lineart_compute_feature_lines(Depsgraph *depsgraph,
LineartData *ld;
Scene *scene = DEG_get_evaluated_scene(depsgraph);
int intersections_only = 0; /* Not used right now, but preserve for future. */
Object *use_camera;
Object *lineart_camera = nullptr;
double t_start;
if (G.debug_value == 4000) {
t_start = PIL_check_seconds_timer();
}
bool use_render_camera_override = false;
if (lmd->calculation_flags & LRT_USE_CUSTOM_CAMERA) {
if (!lmd->source_camera ||
(use_camera = DEG_get_evaluated_object(depsgraph, lmd->source_camera))->type != OB_CAMERA)
(lineart_camera = DEG_get_evaluated_object(depsgraph, lmd->source_camera))->type !=
OB_CAMERA)
{
return false;
}
}
else {
BKE_scene_camera_switch_update(scene);
if (!scene->camera) {
return false;
Render *render = RE_GetSceneRender(scene);
if (render && render->camera_override) {
lineart_camera = DEG_get_evaluated_object(depsgraph, render->camera_override);
use_render_camera_override = true;
}
if (!lineart_camera) {
BKE_scene_camera_switch_update(scene);
if (!scene->camera) {
return false;
}
lineart_camera = scene->camera;
}
use_camera = scene->camera;
}
LineartCache *lc = lineart_init_cache();
*cached_result = lc;
ld = lineart_create_render_buffer(scene, lmd, use_camera, scene->camera, lc);
ld = lineart_create_render_buffer(
scene, lmd, lineart_camera, use_render_camera_override ? lineart_camera : scene->camera, lc);
/* Triangle thread testing data size varies depending on the thread count.
* See definition of LineartTriangleThread for details. */
@ -5042,7 +5053,7 @@ bool MOD_lineart_compute_feature_lines(Depsgraph *depsgraph,
lineart_main_load_geometries(depsgraph,
scene,
use_camera,
lineart_camera,
ld,
lmd->calculation_flags & LRT_ALLOW_DUPLI_OBJECTS,
false,

View File

@ -457,13 +457,6 @@ static void detect_workarounds()
/* Minimum Per-Vertex stride is 1 byte for OpenGL. */
GCaps.minimum_per_vertex_stride = 1;
/* Force disable per feature. */
if (G.debug & G_DEBUG_GPU_FORCE_DISABLE_SSBO) {
printf("\n");
printf("GL: Force disabling SSBO support from commandline arguments.\n");
GCaps.shader_storage_buffer_objects_support = false;
}
} // namespace blender::gpu
/** Internal capabilities. */

View File

@ -112,4 +112,15 @@ TEST(std140, gpu_shader_2D_widget_base)
EXPECT_EQ(offset, 272);
}
TEST(std430, overlay_grid)
{
uint32_t offset = 0;
def_attr<Std430>(shader::Type::VEC3, 0, 0, 12, &offset);
def_attr<Std430>(shader::Type::INT, 0, 12, 16, &offset);
align_end_of_struct<Std430>(&offset);
EXPECT_EQ(offset, 16);
}
} // namespace blender::gpu

View File

@ -60,6 +60,7 @@ uint32_t Std430::element_components_len(const shader::Type type)
case shader::Type::VEC3:
case shader::Type::UVEC3:
case shader::Type::IVEC3:
return 3;
case shader::Type::VEC4:
case shader::Type::UVEC4:
case shader::Type::IVEC4:
@ -76,7 +77,31 @@ uint32_t Std430::element_components_len(const shader::Type type)
uint32_t Std430::array_components_len(const shader::Type type)
{
return Std430::element_components_len(type);
switch (type) {
case shader::Type::FLOAT:
case shader::Type::UINT:
case shader::Type::INT:
case shader::Type::BOOL:
return 1;
case shader::Type::VEC2:
case shader::Type::UVEC2:
case shader::Type::IVEC2:
return 2;
case shader::Type::VEC3:
case shader::Type::UVEC3:
case shader::Type::IVEC3:
case shader::Type::VEC4:
case shader::Type::UVEC4:
case shader::Type::IVEC4:
return 4;
case shader::Type::MAT3:
return 12;
case shader::Type::MAT4:
return 16;
default:
BLI_assert_msg(false, "Type not supported in dynamic structs.");
}
return 0;
}
uint32_t Std140::component_mem_size(const shader::Type /*type*/)

View File

@ -1006,7 +1006,7 @@ std::string VKShader::resources_declare(const shader::ShaderCreateInfo &info) co
if (push_constants_storage != VKPushConstants::StorageType::NONE) {
ss << "\n/* Push Constants. */\n";
if (push_constants_storage == VKPushConstants::StorageType::PUSH_CONSTANTS) {
ss << "layout(push_constant) uniform constants\n";
ss << "layout(push_constant, std430) uniform constants\n";
}
else if (push_constants_storage == VKPushConstants::StorageType::UNIFORM_BUFFER) {
ss << "layout(binding = " << push_constants_layout.descriptor_set_location_get()

View File

@ -51,7 +51,7 @@ static IKPlugin ikplugin_tab[] = {
{nullptr}};
static IKPlugin *get_plugin(bPose *pose)
static IKPlugin *get_plugin(const bPose *pose)
{
if (!pose || pose->iksolver < 0 || pose->iksolver >= (ARRAY_SIZE(ikplugin_tab) - 1)) {
return nullptr;

View File

@ -45,7 +45,7 @@ int logimage_fseek(LogImageFile *logFile, intptr_t offset, int origin)
return 0;
}
int logimage_fwrite(void *buffer, size_t size, uint count, LogImageFile *logFile)
int logimage_fwrite(const void *buffer, size_t size, uint count, LogImageFile *logFile)
{
if (logFile->file) {
return fwrite(buffer, size, count, logFile->file);

View File

@ -15,7 +15,7 @@
#include <stdlib.h>
int logimage_fseek(LogImageFile *logFile, intptr_t offset, int origin);
int logimage_fwrite(void *buffer, size_t size, unsigned int count, LogImageFile *logFile);
int logimage_fwrite(const void *buffer, size_t size, unsigned int count, LogImageFile *logFile);
int logimage_fread(void *buffer, size_t size, unsigned int count, LogImageFile *logFile);
int logimage_read_uchar(unsigned char *x, LogImageFile *logFile);
int logimage_read_ushort(unsigned short *x, LogImageFile *logFile);

View File

@ -1252,7 +1252,7 @@ struct FallbackIndexBuilderContext {
};
static AviMovie *alloc_proxy_output_avi(
anim *anim, char *filepath, int width, int height, int quality)
anim *anim, const char *filepath, int width, int height, int quality)
{
int x, y;
AviFormat format;

View File

@ -105,7 +105,7 @@ bool ABC_import(struct bContext *C,
const struct AlembicImportParams *params,
bool as_background_job);
struct CacheArchiveHandle *ABC_create_handle(struct Main *bmain,
struct CacheArchiveHandle *ABC_create_handle(const struct Main *bmain,
const char *filepath,
const struct CacheFileLayer *layers,
struct ListBase *object_paths);

View File

@ -63,7 +63,7 @@ static IArchive open_archive(const std::string &filename,
return IArchive();
}
ArchiveReader *ArchiveReader::get(Main *bmain, const std::vector<const char *> &filenames)
ArchiveReader *ArchiveReader::get(const Main *bmain, const std::vector<const char *> &filenames)
{
std::vector<ArchiveReader *> readers;
@ -103,7 +103,7 @@ ArchiveReader::ArchiveReader(const std::vector<ArchiveReader *> &readers) : m_re
m_archive = IArchive(arPtr, kWrapExisting, ErrorHandler::kThrowPolicy);
}
ArchiveReader::ArchiveReader(Main *bmain, const char *filename)
ArchiveReader::ArchiveReader(const Main *bmain, const char *filename)
{
char abs_filepath[FILE_MAX];
STRNCPY(abs_filepath, filename);

View File

@ -30,10 +30,10 @@ class ArchiveReader {
ArchiveReader(const std::vector<ArchiveReader *> &readers);
ArchiveReader(struct Main *bmain, const char *filename);
ArchiveReader(const struct Main *bmain, const char *filename);
public:
static ArchiveReader *get(struct Main *bmain, const std::vector<const char *> &filenames);
static ArchiveReader *get(const struct Main *bmain, const std::vector<const char *> &filenames);
~ArchiveReader();

View File

@ -154,7 +154,7 @@ static bool gather_objects_paths(const IObject &object, ListBase *object_paths)
return parent_is_part_of_this_object;
}
CacheArchiveHandle *ABC_create_handle(Main *bmain,
CacheArchiveHandle *ABC_create_handle(const Main *bmain,
const char *filepath,
const CacheFileLayer *layers,
ListBase *object_paths)

View File

@ -227,7 +227,7 @@ bool AVI_is_avi(const char *filepath);
/**
* Open a compressed file, decompress it into memory.
*/
AviError AVI_open_compress(char *filepath, AviMovie *movie, int streams, ...);
AviError AVI_open_compress(const char *filepath, AviMovie *movie, int streams, ...);
/**
* Finalize a compressed output stream.

View File

@ -701,7 +701,7 @@ AviError AVI_close(AviMovie *movie)
return AVI_ERROR_NONE;
}
AviError AVI_open_compress(char *filepath, AviMovie *movie, int streams, ...)
AviError AVI_open_compress(const char *filepath, AviMovie *movie, int streams, ...)
{
va_list ap;
AviList list;

View File

@ -131,7 +131,7 @@ static void Iindexe(AviIndexEntry *indexe)
}
#endif /* __BIG_ENDIAN__ */
void awrite(AviMovie *movie, void *datain, int block, int size, FILE *fp, int type)
void awrite(AviMovie *movie, const void *datain, int block, int size, FILE *fp, int type)
{
#ifdef __BIG_ENDIAN__
void *data;

View File

@ -23,7 +23,7 @@ extern "C" {
#define AVI_INDEXE 6
#define AVI_MJPEGU 7
void awrite(AviMovie *movie, void *datain, int block, int size, FILE *fp, int type);
void awrite(AviMovie *movie, const void *datain, int block, int size, FILE *fp, int type);
#ifdef __cplusplus
}

View File

@ -189,7 +189,6 @@ typedef struct bNodeSocket {
bool is_hidden() const;
bool is_available() const;
bool is_panel_collapsed() const;
bool is_visible_or_panel_collapsed() const;
bool is_visible() const;
bool is_multi_input() const;
bool is_input() const;
@ -428,6 +427,11 @@ typedef struct bNode {
/** A span containing all internal links when the node is muted. */
blender::Span<bNodeLink> internal_links() const;
/* True if the socket is visible and has a valid location. The icon may not be visible. */
bool is_socket_drawn(const bNodeSocket &socket) const;
/* True if the socket is drawn and the icon is visible. */
bool is_socket_icon_drawn(const bNodeSocket &socket) const;
/* The following methods are only available when #bNodeTree.ensure_topology_cache has been
* called. */

View File

@ -44,6 +44,8 @@ const EnumPropertyItem rna_enum_aset_library_type_items[] = {
# include "RNA_access.hh"
using namespace blender::asset_system;
static char *rna_AssetMetaData_path(const PointerRNA * /*ptr*/)
{
return BLI_strdup("asset_data");
@ -339,7 +341,7 @@ void rna_AssetMetaData_catalog_id_update(bContext *C, PointerRNA *ptr)
return;
}
AssetLibrary *asset_library = ED_fileselect_active_asset_library_get(sfile);
::AssetLibrary *asset_library = ED_fileselect_active_asset_library_get(sfile);
if (asset_library == nullptr) {
/* The SpaceFile may not be an asset browser but a regular file browser. */
return;
@ -365,31 +367,64 @@ static void rna_AssetHandle_file_data_set(PointerRNA *ptr,
asset_handle->file_data = static_cast<const FileDirEntry *>(value.data);
}
static void rna_AssetHandle_get_full_library_path(
// AssetHandle *asset,
FileDirEntry *asset_file,
char r_result[/*FILE_MAX_LIBEXTRA*/])
static void rna_AssetRepresentation_name_get(PointerRNA *ptr, char *value)
{
AssetHandle asset{};
asset.file_data = asset_file;
ED_asset_handle_get_full_library_path(&asset, r_result);
const AssetRepresentation *asset = static_cast<const AssetRepresentation *>(ptr->data);
const blender::StringRefNull name = asset->get_name();
BLI_strncpy(value, name.c_str(), name.size() + 1);
}
static PointerRNA rna_AssetHandle_local_id_get(PointerRNA *ptr)
static int rna_AssetRepresentation_name_length(PointerRNA *ptr)
{
const AssetHandle *asset = static_cast<const AssetHandle *>(ptr->data);
ID *id = ED_asset_handle_get_representation(asset)->local_id();
return rna_pointer_inherit_refine(ptr, &RNA_ID, id);
const AssetRepresentation *asset = static_cast<const AssetRepresentation *>(ptr->data);
const blender::StringRefNull name = asset->get_name();
return name.size();
}
static PointerRNA rna_AssetRepresentation_metadata_get(PointerRNA *ptr)
{
const AssetRepresentation *asset = static_cast<const AssetRepresentation *>(ptr->data);
AssetMetaData &asset_data = asset->get_metadata();
/* Note that for local ID assets, the asset metadata is owned by the ID. Let the pointer inherit
* accordingly, so that the #PointerRNA.owner_id is set to the ID, and the metadata can be
* recognized as editable. */
if (asset->is_local_id()) {
PointerRNA id_ptr = RNA_id_pointer_create(asset->local_id());
return rna_pointer_inherit_refine(&id_ptr, &RNA_AssetMetaData, &asset_data);
}
return rna_pointer_inherit_refine(ptr, &RNA_AssetMetaData, &asset_data);
}
static int rna_AssetRepresentation_id_type_get(PointerRNA *ptr)
{
using namespace blender::asset_system;
const AssetRepresentation *asset = static_cast<const AssetRepresentation *>(ptr->data);
return asset->get_id_type();
}
static PointerRNA rna_AssetRepresentation_local_id_get(PointerRNA *ptr)
{
const AssetRepresentation *asset = static_cast<const AssetRepresentation *>(ptr->data);
return rna_pointer_inherit_refine(ptr, &RNA_ID, asset->local_id());
}
static void rna_AssetRepresentation_full_library_path_get(PointerRNA *ptr, char *value)
{
const AssetRepresentation *asset = static_cast<const AssetRepresentation *>(ptr->data);
const std::string full_library_path = asset->get_identifier().full_library_path();
BLI_strncpy(value, full_library_path.c_str(), full_library_path.size() + 1);
}
static int rna_AssetRepresentation_full_library_path_length(PointerRNA *ptr)
{
const AssetRepresentation *asset = static_cast<const AssetRepresentation *>(ptr->data);
const std::string full_library_path = asset->get_identifier().full_library_path();
return full_library_path.size();
}
const EnumPropertyItem *rna_asset_library_reference_itemf(bContext * /*C*/,
PointerRNA * /*ptr*/,
PropertyRNA * /*prop*/,
@ -545,22 +580,6 @@ static void rna_def_asset_data(BlenderRNA *brna)
"data recovery purposes");
}
static void rna_def_asset_handle_api(StructRNA *srna)
{
FunctionRNA *func;
PropertyRNA *parm;
func = RNA_def_function(srna, "get_full_library_path", "rna_AssetHandle_get_full_library_path");
/* TODO temporarily static function, for until .py can receive the asset handle from context
* properly. `asset_file_handle` should go away too then. */
RNA_def_function_flag(func, FUNC_NO_SELF);
parm = RNA_def_pointer(func, "asset_file_handle", "FileSelectEntry", "", "");
RNA_def_parameter_flags(parm, PropertyFlag(0), PARM_REQUIRED);
parm = RNA_def_string(func, "result", nullptr, FILE_MAX_LIBEXTRA, "result", "");
RNA_def_parameter_flags(parm, PROP_THICK_WRAP, ParameterFlag(0));
RNA_def_function_output(func, parm);
}
static void rna_def_asset_handle(BlenderRNA *brna)
{
StructRNA *srna;
@ -579,17 +598,6 @@ static void rna_def_asset_handle(BlenderRNA *brna)
prop, "rna_AssetHandle_file_data_get", "rna_AssetHandle_file_data_set", nullptr, nullptr);
RNA_def_property_ui_text(
prop, "File Entry", "TEMPORARY, DO NOT USE - File data used to refer to the asset");
prop = RNA_def_property(srna, "local_id", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "ID");
RNA_def_property_pointer_funcs(prop, "rna_AssetHandle_local_id_get", nullptr, nullptr, nullptr);
RNA_def_property_ui_text(prop,
"",
"The local data-block this asset represents; only valid if that is a "
"data-block in this file");
RNA_def_property_flag(prop, PROP_HIDDEN);
rna_def_asset_handle_api(srna);
}
static void rna_def_asset_representation(BlenderRNA *brna)
@ -603,6 +611,19 @@ static void rna_def_asset_representation(BlenderRNA *brna)
"Information about an entity that makes it possible for the asset system "
"to deal with the entity as asset");
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_FILENAME);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_string_funcs(
prop, "rna_AssetRepresentation_name_get", "rna_AssetRepresentation_name_length", nullptr);
RNA_def_property_ui_text(prop, "Name", "");
RNA_def_struct_name_property(srna, prop);
prop = RNA_def_property(srna, "metadata", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "AssetMetaData");
RNA_def_property_pointer_funcs(
prop, "rna_AssetRepresentation_metadata_get", nullptr, nullptr, nullptr);
RNA_def_property_ui_text(prop, "Asset Metadata", "Additional information about the asset");
prop = RNA_def_property(srna, "id_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, rna_enum_id_type_items);
RNA_def_property_enum_funcs(prop, "rna_AssetRepresentation_id_type_get", nullptr, nullptr);
@ -614,6 +635,27 @@ static void rna_def_asset_representation(BlenderRNA *brna)
* assets are supported. */
"The type of the data-block, if the asset represents one ('NONE' otherwise)");
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_ID);
prop = RNA_def_property(srna, "local_id", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "ID");
RNA_def_property_pointer_funcs(
prop, "rna_AssetRepresentation_local_id_get", nullptr, nullptr, nullptr);
RNA_def_property_ui_text(prop,
"",
"The local data-block this asset represents; only valid if that is a "
"data-block in this file");
prop = RNA_def_property(srna, "full_library_path", PROP_STRING, PROP_FILENAME);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_string_funcs(prop,
"rna_AssetRepresentation_full_library_path_get",
"rna_AssetRepresentation_full_library_path_length",
nullptr);
RNA_def_property_ui_text(
prop,
"Full Library Path",
"Absolute path to the .blend file containing this asset extended with the path "
"of the asset inside the file");
}
static void rna_def_asset_catalog_path(BlenderRNA *brna)
@ -633,7 +675,7 @@ PropertyRNA *rna_def_asset_library_reference_common(StructRNA *srna,
const char *get,
const char *set)
{
PropertyRNA *prop = RNA_def_property(srna, "asset_library_ref", PROP_ENUM, PROP_NONE);
PropertyRNA *prop = RNA_def_property(srna, "asset_library_reference", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, rna_enum_dummy_NULL_items);
RNA_def_property_enum_funcs(prop, get, set, "rna_asset_library_reference_itemf");

View File

@ -125,19 +125,10 @@ static PointerRNA rna_Context_gizmo_group_get(PointerRNA *ptr)
return newptr;
}
static PointerRNA rna_Context_asset_file_handle_get(PointerRNA *ptr)
static PointerRNA rna_Context_asset_get(PointerRNA *ptr)
{
bContext *C = (bContext *)ptr->data;
bool is_handle_valid;
AssetHandle asset_handle = CTX_wm_asset_handle(C, &is_handle_valid);
if (!is_handle_valid) {
return PointerRNA_NULL;
}
/* Have to cast away const, but the file entry API doesn't allow modifications anyway. */
PointerRNA newptr = RNA_pointer_create(
nullptr, &RNA_FileSelectEntry, (FileDirEntry *)asset_handle.file_data);
return newptr;
return RNA_pointer_create(nullptr, &RNA_AssetRepresentation, CTX_wm_asset(C));
}
static PointerRNA rna_Context_main_get(PointerRNA *ptr)
@ -290,17 +281,10 @@ void RNA_def_context(BlenderRNA *brna)
RNA_def_property_struct_type(prop, "GizmoGroup");
RNA_def_property_pointer_funcs(prop, "rna_Context_gizmo_group_get", nullptr, nullptr, nullptr);
/* TODO can't expose AssetHandle, since there is no permanent storage to it (so we can't
* return a pointer). Instead provide the FileDirEntry pointer it wraps. */
prop = RNA_def_property(srna, "asset_file_handle", PROP_POINTER, PROP_NONE);
prop = RNA_def_property(srna, "asset", PROP_POINTER, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_struct_type(prop, "FileSelectEntry");
RNA_def_property_pointer_funcs(
prop, "rna_Context_asset_file_handle_get", nullptr, nullptr, nullptr);
RNA_def_property_ui_text(prop,
"",
"The file of an active asset. Avoid using this, it will be replaced by "
"a proper AssetHandle design");
RNA_def_property_struct_type(prop, "AssetRepresentation");
RNA_def_property_pointer_funcs(prop, "rna_Context_asset_get", nullptr, nullptr, nullptr);
/* Data */
prop = RNA_def_property(srna, "blend_data", PROP_POINTER, PROP_NONE);

View File

@ -64,31 +64,34 @@ struct EffectInfo {
int inputs;
};
/* These wrap strangely, disable formatting for fixed indentation and wrapping. */
/* clang-format off */
#define RNA_ENUM_SEQUENCER_VIDEO_MODIFIER_TYPE_ITEMS \
{seqModifierType_BrightContrast, "BRIGHT_CONTRAST", ICON_NONE, "Bright/Contrast", ""}, \
{seqModifierType_ColorBalance, "COLOR_BALANCE", ICON_NONE, "Color Balance", ""}, \
{seqModifierType_Curves, "CURVES", ICON_NONE, "Curves", ""}, \
{seqModifierType_HueCorrect, "HUE_CORRECT", ICON_NONE, "Hue Correct", ""}, \
{seqModifierType_Mask, "MASK", ICON_NONE, "Mask", ""}, \
{seqModifierType_Tonemap, "TONEMAP", ICON_NONE, "Tone Map", ""}, \
{seqModifierType_WhiteBalance, "WHITE_BALANCE", ICON_NONE, "White Balance", ""}
#define RNA_ENUM_SEQUENCER_AUDIO_MODIFIER_TYPE_ITEMS \
{seqModifierType_SoundEqualizer, "SOUND_EQUALIZER", ICON_NONE, "Equalizer", ""}
/* clang-format on */
const EnumPropertyItem rna_enum_sequence_modifier_type_items[] = {
{seqModifierType_BrightContrast, "BRIGHT_CONTRAST", ICON_NONE, "Brightness/Contrast", ""},
{seqModifierType_ColorBalance, "COLOR_BALANCE", ICON_NONE, "Color Balance", ""},
{seqModifierType_Curves, "CURVES", ICON_NONE, "Curves", ""},
{seqModifierType_HueCorrect, "HUE_CORRECT", ICON_NONE, "Hue Correct", ""},
{seqModifierType_Mask, "MASK", ICON_NONE, "Mask", ""},
{seqModifierType_Tonemap, "TONEMAP", ICON_NONE, "Tone Map", ""},
{seqModifierType_WhiteBalance, "WHITE_BALANCE", ICON_NONE, "White Balance", ""},
{seqModifierType_SoundEqualizer, "SOUND_EQUALIZER", ICON_NONE, "Sound Equalizer", ""},
RNA_ENUM_SEQUENCER_VIDEO_MODIFIER_TYPE_ITEMS,
RNA_ENUM_SEQUENCER_AUDIO_MODIFIER_TYPE_ITEMS,
{0, nullptr, 0, nullptr, nullptr},
};
const EnumPropertyItem rna_enum_sequence_video_modifier_type_items[] = {
{seqModifierType_BrightContrast, "BRIGHT_CONTRAST", ICON_NONE, "Bright/Contrast", ""},
{seqModifierType_ColorBalance, "COLOR_BALANCE", ICON_NONE, "Color Balance", ""},
{seqModifierType_Curves, "CURVES", ICON_NONE, "Curves", ""},
{seqModifierType_HueCorrect, "HUE_CORRECT", ICON_NONE, "Hue Correct", ""},
{seqModifierType_Mask, "MASK", ICON_NONE, "Mask", ""},
{seqModifierType_Tonemap, "TONEMAP", ICON_NONE, "Tone Map", ""},
{seqModifierType_WhiteBalance, "WHITE_BALANCE", ICON_NONE, "White Balance", ""},
RNA_ENUM_SEQUENCER_VIDEO_MODIFIER_TYPE_ITEMS,
{0, nullptr, 0, nullptr, nullptr},
};
const EnumPropertyItem rna_enum_sequence_sound_modifier_type_items[] = {
{seqModifierType_SoundEqualizer, "SOUND_EQUALIZER", ICON_NONE, "Equalizer", ""},
RNA_ENUM_SEQUENCER_AUDIO_MODIFIER_TYPE_ITEMS,
{0, nullptr, 0, nullptr, nullptr},
};

View File

@ -2838,32 +2838,6 @@ static int rna_FileBrowser_FileSelectEntry_relative_path_length(PointerRNA *ptr)
return int(strlen(entry->relpath));
}
static const EnumPropertyItem *rna_FileBrowser_FileSelectEntry_id_type_itemf(
bContext * /*C*/, PointerRNA *ptr, PropertyRNA * /*prop*/, bool * /*r_free*/)
{
const FileDirEntry *entry = static_cast<const FileDirEntry *>(ptr->data);
if (entry->blentype == 0) {
static const EnumPropertyItem none_items[] = {
{0, "NONE", 0, "None", ""},
};
return none_items;
}
return rna_enum_id_type_items;
}
static int rna_FileBrowser_FileSelectEntry_id_type_get(PointerRNA *ptr)
{
const FileDirEntry *entry = static_cast<const FileDirEntry *>(ptr->data);
return entry->blentype;
}
static PointerRNA rna_FileBrowser_FileSelectEntry_local_id_get(PointerRNA *ptr)
{
const FileDirEntry *entry = static_cast<const FileDirEntry *>(ptr->data);
return rna_pointer_inherit_refine(ptr, &RNA_ID, entry->id);
}
static int rna_FileBrowser_FileSelectEntry_preview_icon_id_get(PointerRNA *ptr)
{
const FileDirEntry *entry = static_cast<const FileDirEntry *>(ptr->data);
@ -6674,29 +6648,6 @@ static void rna_def_fileselect_entry(BlenderRNA *brna)
"Browser (includes the file name)");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
prop = RNA_def_property(srna, "id_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, rna_enum_id_type_items);
RNA_def_property_enum_funcs(prop,
"rna_FileBrowser_FileSelectEntry_id_type_get",
nullptr,
"rna_FileBrowser_FileSelectEntry_id_type_itemf");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(
prop,
"Data-block Type",
"The type of the data-block, if the file represents one ('NONE' otherwise)");
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_ID);
prop = RNA_def_property(srna, "local_id", PROP_POINTER, PROP_NONE);
RNA_def_property_struct_type(prop, "ID");
RNA_def_property_pointer_funcs(
prop, "rna_FileBrowser_FileSelectEntry_local_id_get", nullptr, nullptr, nullptr);
RNA_def_property_ui_text(prop,
"",
"The local data-block this file represents; only valid if that is a "
"data-block in this file");
RNA_def_property_flag(prop, PROP_HIDDEN);
prop = RNA_def_int(
srna,
"preview_icon_id",

View File

@ -29,7 +29,7 @@
static void rna_Text_filepath_get(PointerRNA *ptr, char *value)
{
Text *text = (Text *)ptr->data;
const Text *text = (const Text *)ptr->data;
if (text->filepath) {
strcpy(value, text->filepath);
@ -41,7 +41,7 @@ static void rna_Text_filepath_get(PointerRNA *ptr, char *value)
static int rna_Text_filepath_length(PointerRNA *ptr)
{
Text *text = (Text *)ptr->data;
const Text *text = (const Text *)ptr->data;
return (text->filepath) ? strlen(text->filepath) : 0;
}
@ -63,13 +63,13 @@ static void rna_Text_filepath_set(PointerRNA *ptr, const char *value)
static bool rna_Text_modified_get(PointerRNA *ptr)
{
Text *text = (Text *)ptr->data;
const Text *text = (const Text *)ptr->data;
return BKE_text_file_modified_check(text) != 0;
}
static int rna_Text_current_line_index_get(PointerRNA *ptr)
{
Text *text = (Text *)ptr->data;
const Text *text = (const Text *)ptr->data;
return BLI_findindex(&text->lines, text->curl);
}
@ -86,7 +86,7 @@ static void rna_Text_current_line_index_set(PointerRNA *ptr, int value)
static int rna_Text_select_end_line_index_get(PointerRNA *ptr)
{
Text *text = static_cast<Text *>(ptr->data);
const Text *text = static_cast<Text *>(ptr->data);
return BLI_findindex(&text->lines, text->sell);
}
@ -103,7 +103,7 @@ static void rna_Text_select_end_line_index_set(PointerRNA *ptr, int value)
static int rna_Text_current_character_get(PointerRNA *ptr)
{
Text *text = static_cast<Text *>(ptr->data);
const Text *text = static_cast<const Text *>(ptr->data);
const TextLine *line = text->curl;
return BLI_str_utf8_offset_to_index(line->line, line->len, text->curc);
}
@ -135,7 +135,7 @@ static void rna_Text_select_end_character_set(PointerRNA *ptr, int index)
static void rna_TextLine_body_get(PointerRNA *ptr, char *value)
{
TextLine *line = (TextLine *)ptr->data;
const TextLine *line = (const TextLine *)ptr->data;
if (line->line) {
strcpy(value, line->line);
@ -147,7 +147,7 @@ static void rna_TextLine_body_get(PointerRNA *ptr, char *value)
static int rna_TextLine_body_length(PointerRNA *ptr)
{
TextLine *line = (TextLine *)ptr->data;
const TextLine *line = (const TextLine *)ptr->data;
return line->len;
}

View File

@ -124,7 +124,7 @@ static void node_gather_link_searches(GatherLinkSearchOpParams &params)
/* If the source node has a geometry socket, connect it to the new viewer node as well. */
LISTBASE_FOREACH (bNodeSocket *, socket, &params.node.outputs) {
if (socket->type == SOCK_GEOMETRY && socket->is_visible_or_panel_collapsed()) {
if (socket->type == SOCK_GEOMETRY && socket->is_visible()) {
nodeAddLink(&params.node_tree,
&params.node,
socket,

View File

@ -23,7 +23,7 @@ extern "C" {
/** Call #BPY_context_set first. */
void BPY_python_start(struct bContext *C, int argc, const char **argv);
void BPY_python_end(void);
void BPY_python_end(bool do_python_exit);
void BPY_python_reset(struct bContext *C);
void BPY_python_use_system_env(void);
void BPY_python_backtrace(FILE *fp);

View File

@ -836,6 +836,22 @@ void PyC_Err_PrintWithFunc(PyObject *py_func)
/** \name Exception Buffer Access
* \{ */
/**
* When a script calls `sys.exit(..)` it is expected that Blender quits,
* internally this raises as `SystemExit` exception which this function detects.
*
* Historically Blender would call `PyErr_Print` when encountering an error.
* In some cases `PyErr_Print` is still called, but not all.
* When only #PyC_ExceptionBuffer is used to access the error, it's not desirable
* that `sys.exit()` fails to exit, causing `sys.exit(..)` to arbitrarily work depending
* on the internals of Blender's error handling.
* To avoid this discrepancy, detect when `PyErr_Print` *would* exit and call it in that case.
* It's important to call `PyErr_Print` (instead of simply exiting), because the exception
* may contain a message which the user should see.
*
* \note No need to handle freeing resources here, Python's `atexit` is used to cleanup
* Blender's state when Python requests an exit (via `bpy_atexit` callback).
*/
static void pyc_exception_buffer_handle_system_exit()
{
if (!PyErr_ExceptionMatches(PyExc_SystemExit)) {
@ -847,10 +863,9 @@ static void pyc_exception_buffer_handle_system_exit()
}
/* NOTE(@ideasman42): A `SystemExit` exception will exit immediately (unless inspecting).
* So print the error and exit now. This is necessary as the call to #PyErr_Print exits,
* the temporary `sys.stderr` assignment causes the output to be suppressed, failing silently.
* Instead, restore the error and print it. If Python changes it's behavior and doesn't exit in
* the future - continue to create the exception buffer, see: #99966.
* So print the error and exit now. Without this #PyErr_Display shows the error stack-trace
* as a regular exception (as if something went wrong) and fail to exit.
* see: #99966 for additional context.
*
* Arguably accessing a `SystemExit` exception as a buffer should be supported without exiting.
* (by temporarily enabling inspection for example) however - it's not obvious exactly when this
@ -875,6 +890,10 @@ PyObject *PyC_ExceptionBuffer()
PyObject *error_type, *error_value, *error_traceback;
PyErr_Fetch(&error_type, &error_value, &error_traceback);
/* Normalizing is needed because it's possible the error value is a string which
* #PyErr_Display will fail to print. */
PyErr_NormalizeException(&error_type, &error_value, &error_traceback);
/* `io.StringIO()`. */
PyObject *string_io = nullptr;
PyObject *string_io_mod = nullptr;

View File

@ -30,12 +30,19 @@ void PyC_StackSpit(void);
/**
* Return a string containing the full stack trace.
*
* - Only call when `PyErr_Occurred() != 0` .
* - The always returns a Python string.
* - The exception is left in place without being manipulated,
* although they will be normalized in order to display them (`PyErr_Print` also does this).
* - `SystemExit` exceptions will exit (so `sys.exit(..)` works, matching `PyErr_Print` behavior).
* - The always returns a Python string (unless exiting where the function doesn't return).
*/
PyObject *PyC_ExceptionBuffer(void) ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL;
/**
* A version of #PyC_ExceptionBuffer that returns the last exception only.
*
* Useful for error messages from evaluating numeric expressions for e.g.
* where a full multi-line stack-trace isn't needed and doesn't format well in the status-bar.
*/
PyObject *PyC_ExceptionBuffer_Simple(void) ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL;

View File

@ -45,7 +45,7 @@
#include "BKE_appdir.h"
#include "BKE_context.h"
#include "BKE_global.h" /* only for script checking */
#include "BKE_global.h" /* Only for script checking. */
#include "BKE_main.h"
#include "BKE_text.h"
@ -59,7 +59,7 @@
#include "../generic/py_capi_utils.h"
/* inittab initialization functions */
/* `inittab` initialization functions. */
#include "../bmesh/bmesh_py_api.h"
#include "../generic/bgl.h"
#include "../generic/bl_math_py_api.h"
@ -75,36 +75,41 @@ CLG_LOGREF_DECLARE_GLOBAL(BPY_LOG_CONTEXT, "bpy.context");
CLG_LOGREF_DECLARE_GLOBAL(BPY_LOG_INTERFACE, "bpy.interface");
CLG_LOGREF_DECLARE_GLOBAL(BPY_LOG_RNA, "bpy.rna");
/* for internal use, when starting and ending python scripts */
/* For internal use, when starting and ending Python scripts. */
/* In case a python script triggers another python call,
* stop bpy_context_clear from invalidating. */
/* In case a Python script triggers another Python call,
* stop #bpy_context_clear from invalidating. */
static int py_call_level = 0;
/* Set by command line arguments before Python starts. */
static bool py_use_system_env = false;
// #define TIME_PY_RUN /* simple python tests. prints on exit. */
// #define TIME_PY_RUN /* Simple python tests. prints on exit. */
#ifdef TIME_PY_RUN
# include "PIL_time.h"
static int bpy_timer_count = 0;
static double bpy_timer; /* time since python starts */
static double bpy_timer_run; /* time for each python script run */
static double bpy_timer_run_tot; /* accumulate python runs */
/** Time since python starts. */
static double bpy_timer;
/** Time for each Python script run. */
static double bpy_timer_run;
/** Accumulate Python runs. */
static double bpy_timer_run_tot;
#endif
void BPY_context_update(bContext *C)
{
/* don't do this from a non-main (e.g. render) thread, it can cause a race
* condition on C->data.recursion. ideal solution would be to disable
* context entirely from non-main threads, but that's more complicated */
/* Don't do this from a non-main (e.g. render) thread, it can cause a race
* condition on `C->data.recursion`. Ideal solution would be to disable
* context entirely from non-main threads, but that's more complicated. */
if (!BLI_thread_is_main()) {
return;
}
BPY_context_set(C);
BPY_modules_update(); /* can give really bad results if this isn't here */
/* Can give really bad results if this isn't here. */
BPY_modules_update();
}
void bpy_context_set(bContext *C, PyGILState_STATE *gilstate)
@ -120,7 +125,7 @@ void bpy_context_set(bContext *C, PyGILState_STATE *gilstate)
#ifdef TIME_PY_RUN
if (bpy_timer_count == 0) {
/* record time from the beginning */
/* Record time from the beginning. */
bpy_timer = PIL_check_seconds_timer();
bpy_timer_run = bpy_timer_run_tot = 0.0;
}
@ -143,8 +148,8 @@ void bpy_context_clear(bContext * /*C*/, const PyGILState_STATE *gilstate)
fprintf(stderr, "ERROR: Python context internal state bug. this should not happen!\n");
}
else if (py_call_level == 0) {
/* XXX: Calling classes currently won't store the context :\,
* can't set nullptr because of this. but this is very flaky still. */
/* NOTE: Unfortunately calling classes currently won't store the context.
* Can't set nullptr because of this - but this is very flaky still. */
#if 0
BPY_context_set(nullptr);
#endif
@ -219,13 +224,15 @@ void BPY_text_free_code(Text *text)
void BPY_modules_update()
{
#if 0 /* slow, this runs all the time poll, draw etc 100's of time a sec. */
/* Correct but slow, this runs all the time operator poll, panel draw etc
* (100's of time a second). */
#if 0
PyObject *mod = PyImport_ImportModuleLevel("bpy", nullptr, nullptr, nullptr, 0);
PyModule_AddObject(mod, "data", BPY_rna_module());
PyModule_AddObject(mod, "types", BPY_rna_types()); /* This does not need updating. */
#endif
/* refreshes the main struct */
/* Refreshes the main struct. */
BPY_update_rna_module();
}
@ -240,17 +247,17 @@ void BPY_context_set(bContext *C)
}
#ifdef WITH_FLUID
/* defined in manta module */
/* Defined in `manta` module. */
extern "C" PyObject *Manta_initPython(void);
#endif
#ifdef WITH_AUDASPACE_PY
/* defined in AUD_C-API.cpp */
/* Defined in `AUD_C-API.cpp`. */
extern "C" PyObject *AUD_initPython(void);
#endif
#ifdef WITH_CYCLES
/* defined in cycles module */
/* Defined in `cycles` module. */
static PyObject *CCL_initPython()
{
return (PyObject *)CCL_python_module_init();
@ -258,7 +265,7 @@ static PyObject *CCL_initPython()
#endif
#ifdef WITH_HYDRA
/* defined in render_hydra module */
/* Defined in `render_hydra` module. */
PyObject *BPyInit_hydra();
#endif
@ -499,7 +506,7 @@ void BPY_python_start(bContext *C, int argc, const char **argv)
PyErr_Print();
PyErr_Clear();
}
// Py_DECREF(mod); /* ideally would decref, but in this case we never want to free */
// Py_DECREF(mod); /* Ideally would decref, but in this case we never want to free. */
}
}
#endif
@ -513,8 +520,8 @@ void BPY_python_start(bContext *C, int argc, const char **argv)
pyrna_alloc_types();
#ifndef WITH_PYTHON_MODULE
/* py module runs atexit when bpy is freed */
BPY_atexit_register(); /* this can init any time */
/* Python module runs `atexit` when `bpy` is freed. */
BPY_atexit_register(); /* This can initialize any time. */
/* Free the lock acquired (implicitly) when Python is initialized. */
PyEval_ReleaseThread(PyGILState_GetThisThreadState());
@ -528,15 +535,14 @@ void BPY_python_start(bContext *C, int argc, const char **argv)
#endif
}
void BPY_python_end()
void BPY_python_end(const bool do_python_exit)
{
// fprintf(stderr, "Ending Python!\n");
PyGILState_STATE gilstate;
/* finalizing, no need to grab the state, except when we are a module */
/* Finalizing, no need to grab the state, except when we are a module. */
gilstate = PyGILState_Ensure();
/* Frees the python-driver name-space & cached data. */
/* Frees the Python-driver name-space & cached data. */
BPY_driver_exit();
/* Clear Python values in the context so freeing the context after Python exits doesn't crash. */
@ -545,30 +551,33 @@ void BPY_python_end()
/* Decrement user counts of all callback functions. */
BPY_rna_props_clear_all();
/* free other python data. */
/* Free other Python data. */
pyrna_free_types();
BPY_rna_exit();
/* clear all python data from structs */
/* Clear all Python data from structs. */
bpy_intern_string_exit();
/* bpy.app modules that need cleanup */
/* `bpy.app` modules that need cleanup. */
BPY_app_translations_end();
#ifndef WITH_PYTHON_MODULE
BPY_atexit_unregister(); /* without this we get recursive calls to WM_exit */
Py_Finalize();
/* Without this we get recursive calls to #WM_exit_ex. */
BPY_atexit_unregister();
if (do_python_exit) {
Py_Finalize();
}
(void)gilstate;
#else
PyGILState_Release(gilstate);
(void)do_python_exit;
#endif
#ifdef TIME_PY_RUN
/* measure time since py started */
/* Measure time since Python started. */
bpy_timer = PIL_check_seconds_timer() - bpy_timer;
printf("*bpy stats* - ");
@ -583,15 +592,12 @@ void BPY_python_end()
}
printf("\n");
// fprintf(stderr, "Ending Python Done!\n");
#endif
}
void BPY_python_reset(bContext *C)
{
/* unrelated security stuff */
/* Unrelated security stuff. */
G.f &= ~(G_FLAG_SCRIPT_AUTOEXEC_FAIL | G_FLAG_SCRIPT_AUTOEXEC_FAIL_QUIET);
G.autoexec_fail[0] = '\0';
@ -614,8 +620,8 @@ void BPY_python_backtrace(FILE *fp)
if (!_PyThreadState_UncheckedGet()) {
return;
}
PyFrameObject *frame;
if (!(frame = PyEval_GetFrame())) {
PyFrameObject *frame = PyEval_GetFrame();
if (frame == nullptr) {
return;
}
do {
@ -651,13 +657,12 @@ void BPY_modules_load_user(bContext *C)
Main *bmain = CTX_data_main(C);
Text *text;
/* can happen on file load */
/* Can happen on file load. */
if (bmain == nullptr) {
return;
}
/* update pointers since this can run from a nested script
* on file load */
/* Update pointers since this can run from a nested script on file load. */
if (py_call_level) {
BPY_context_update(C);
}
@ -709,7 +714,7 @@ int BPY_context_member_get(bContext *C, const char *member, bContextDataResult *
item = PyDict_GetItemString(pyctx, member);
if (item == nullptr) {
/* pass */
/* Pass. */
}
else if (item == Py_None) {
done = true;
@ -806,16 +811,17 @@ struct dealloc_obj {
PyObject *mod;
};
/* call once __file__ is set */
/* Call once `__file__` is set. */
static void bpy_module_delay_init(PyObject *bpy_proxy)
{
const int argc = 1;
const char *argv[2];
/* updating the module dict below will lose the reference to __file__ */
/* Updating the module dict below will lose the reference to `__file__`. */
PyObject *filepath_obj = PyModule_GetFilenameObject(bpy_proxy);
const char *filepath_rel = PyUnicode_AsUTF8(filepath_obj); /* can be relative */
/* The file can be a relative path. */
const char *filepath_rel = PyUnicode_AsUTF8(filepath_obj);
char filepath_abs[1024];
STRNCPY(filepath_abs, filepath_rel);
@ -825,11 +831,9 @@ static void bpy_module_delay_init(PyObject *bpy_proxy)
argv[0] = filepath_abs;
argv[1] = nullptr;
// printf("module found %s\n", argv[0]);
main_python_enter(argc, argv);
/* initialized in BPy_init_modules() */
/* Initialized in #BPy_init_modules(). */
PyDict_Update(PyModule_GetDict(bpy_proxy), PyModule_GetDict(bpy_package_py));
}
@ -882,12 +886,13 @@ static void dealloc_obj_dealloc(PyObject *self);
static PyTypeObject dealloc_obj_Type;
/* use our own dealloc so we can free a property if we use one */
/* Use our own `dealloc` so we can free a property if we use one. */
static void dealloc_obj_dealloc(PyObject *self)
{
bpy_module_delay_init(((dealloc_obj *)self)->mod);
/* NOTE: for subclassed PyObjects we can't just call PyObject_DEL() directly or it will crash. */
/* NOTE: for sub-classed `PyObject` objects
* we can't call #PyObject_DEL() directly or it will crash. */
dealloc_obj_Type.tp_free(self);
}
@ -902,23 +907,23 @@ PyMODINIT_FUNC PyInit_bpy()
PyObject *bpy_proxy = PyModule_Create(&bpy_proxy_def);
/* Problem:
* 1) this init function is expected to have a private member defined - `md_def`
* but this is only set for C defined modules (not py packages)
* so we can't return 'bpy_package_py' as is.
* 1) This initializing function is expected to have a private member defined - `md_def`
* but this is only set for CAPI defined modules (not Python packages)
* so we can't return `bpy_package_py` as is.
*
* 2) there is a 'bpy' C module for python to load which is basically all of blender,
* 2) There is a `bpy` CAPI module for python to load which is basically all of blender,
* and there is `scripts/bpy/__init__.py`,
* we may end up having to rename this module so there is no naming conflict here eg:
* 'from blender import bpy'
* `from blender import bpy`
*
* 3) we don't know the filepath at this point, workaround by assigning a dummy value
* 3) We don't know the file-path at this point, workaround by assigning a dummy value
* which calls back when its freed so the real loading can take place.
*/
/* assign an object which is freed after __file__ is assigned */
/* Assign an object which is freed after `__file__` is assigned. */
dealloc_obj *dob;
/* assign dummy type */
/* Assign dummy type. */
dealloc_obj_Type.tp_name = "dealloc_obj";
dealloc_obj_Type.tp_basicsize = sizeof(dealloc_obj);
dealloc_obj_Type.tp_dealloc = dealloc_obj_dealloc;
@ -944,9 +949,7 @@ static void bpy_module_free(void * /*mod*/)
bool BPY_string_is_keyword(const char *str)
{
/* list is from...
* ", ".join(['"%s"' % kw for kw in __import__("keyword").kwlist])
*/
/* List is from: `", ".join(['"%s"' % kw for kw in __import__("keyword").kwlist])`. */
const char *kwlist[] = {
"False", "None", "True", "and", "as", "assert", "async", "await", "break",
"class", "continue", "def", "del", "elif", "else", "except", "finally", "for",

View File

@ -21,10 +21,26 @@
static PyObject *bpy_atexit(PyObject * /*self*/, PyObject * /*args*/, PyObject * /*kw*/)
{
/* close down enough of blender at least not to crash */
bContext *C = BPY_context_get();
/* NOTE(@ideasman42): This doesn't have to match Blender shutting down exactly,
* leaks reported by memory checking tools may be reported but are harmless
* and don't have to be *fixed* unless doing so is trivial.
*
* Just handle the basics:
* - Free resources avoiding crashes and errors on exit.
* - Remove Blender's temporary directory.
*
* Anything else that prevents `sys.exit(..)` from exiting gracefully should be handled here too.
*/
WM_exit_ex(C, false, false);
bContext *C = BPY_context_get();
/* As Python requested the exit, it handles shutting it's self down. */
const bool do_python_exit = false;
/* User actions such as saving the session, preferences, recent-files for e.g.
* should be skipped because an explicit call to exit is more likely to be used as part of
* automated processes shouldn't impact the users session in the future. */
const bool do_user_exit_actions = false;
WM_exit_ex(C, do_python_exit, do_user_exit_actions);
Py_RETURN_NONE;
}

View File

@ -8747,7 +8747,19 @@ static int bpy_class_call(bContext *C, PointerRNA *ptr, FunctionRNA *func, Param
reports = CTX_wm_reports(C);
}
BPy_errors_to_report(reports);
/* Typically null reports are sent to the output,
* in this case however PyErr_Print is responsible for that,
* so only run this if reports are non-null. */
if (reports) {
/* Create a temporary report list so none of the reports are printed (only stored).
* Only do this when reports is non-null because the error is printed to the `stderr`
* #PyErr_Print below. */
ReportList reports_temp = {0};
BKE_reports_init(&reports_temp, reports->flag | RPT_PRINT_HANDLED_BY_OWNER);
reports_temp.storelevel = reports->storelevel;
BPy_errors_to_report(&reports_temp);
BLI_movelisttolist(&reports->list, &reports_temp.list);
}
/* Also print in the console for Python. */
PyErr_Print();

View File

@ -252,7 +252,7 @@ bool seq_disk_cache_enforce_limits(SeqDiskCache *disk_cache)
}
static DiskCacheFile *seq_disk_cache_get_file_entry_by_path(SeqDiskCache *disk_cache,
char *filepath)
const char *filepath)
{
DiskCacheFile *cache_file = static_cast<DiskCacheFile *>(disk_cache->files.first);
@ -266,7 +266,7 @@ static DiskCacheFile *seq_disk_cache_get_file_entry_by_path(SeqDiskCache *disk_c
}
/* Update file size and timestamp. */
static void seq_disk_cache_update_file(SeqDiskCache *disk_cache, char *filepath)
static void seq_disk_cache_update_file(SeqDiskCache *disk_cache, const char *filepath)
{
DiskCacheFile *cache_file;
int64_t size_before;

View File

@ -109,15 +109,14 @@ void WM_init(bContext *C, int argc, const char **argv);
*
* \param C: The context or null, a null context implies `do_user_exit_actions == false` &
* prevents some editor-exit operations from running.
* \param do_python: Free all data associated with Blender's Python integration.
* Also exit the Python interpreter (unless `WITH_PYTHON_MODULE` is enabled).
* \param do_python_exit: Exit the Python interpreter (unless `WITH_PYTHON_MODULE` is enabled).
* \param do_user_exit_actions: When enabled perform actions associated with a user
* having been using Blender then exiting. Actions such as writing the auto-save
* and writing any changes to preferences.
* Set to false in background mode or when exiting because of failed command line argument parsing.
* In general automated actions where the user isn't making changes should pass in false too.
*/
void WM_exit_ex(bContext *C, bool do_python, bool do_user_exit_actions);
void WM_exit_ex(bContext *C, bool do_python_exit, bool do_user_exit_actions);
/**
* Main exit function to close Blender ordinarily.

View File

@ -211,13 +211,13 @@ wmDrag *WM_drag_data_create(
/* The asset-list case is special: We get multiple assets from context and attach them to the
* drag item. */
case WM_DRAG_ASSET_LIST: {
ListBase asset_file_links = CTX_data_collection_get(C, "selected_asset_files");
LISTBASE_FOREACH (const CollectionPointerLink *, link, &asset_file_links) {
const FileDirEntry *asset_file = static_cast<const FileDirEntry *>(link->ptr.data);
const AssetHandle asset_handle = {asset_file};
WM_drag_add_asset_list_item(drag, ED_asset_handle_get_representation(&asset_handle));
ListBase asset_links = CTX_data_collection_get(C, "selected_assets");
LISTBASE_FOREACH (const CollectionPointerLink *, link, &asset_links) {
const AssetRepresentationHandle *asset = static_cast<const AssetRepresentationHandle *>(
link->ptr.data);
WM_drag_add_asset_list_item(drag, asset);
}
BLI_freelistN(&asset_file_links);
BLI_freelistN(&asset_links);
break;
}
default:

View File

@ -490,7 +490,7 @@ void wm_exit_schedule_delayed(const bContext *C)
void UV_clipboard_free();
void WM_exit_ex(bContext *C, const bool do_python, const bool do_user_exit_actions)
void WM_exit_ex(bContext *C, const bool do_python_exit, const bool do_user_exit_actions)
{
wmWindowManager *wm = C ? CTX_wm_manager(C) : nullptr;
@ -663,8 +663,8 @@ void WM_exit_ex(bContext *C, const bool do_python, const bool do_user_exit_actio
// free_txt_data();
#ifdef WITH_PYTHON
/* option not to close python so we can use 'atexit' */
if (do_python && ((C == nullptr) || CTX_py_init_get(C))) {
/* Option not to exit Python so this function can be called from 'atexit'. */
if ((C == nullptr) || CTX_py_init_get(C)) {
/* NOTE: (old note)
* before BKE_blender_free so Python's garbage-collection happens while library still exists.
* Needed at least for a rare crash that can happen in python-drivers.
@ -672,10 +672,10 @@ void WM_exit_ex(bContext *C, const bool do_python, const bool do_user_exit_actio
* Update for Blender 2.5, move after #BKE_blender_free because Blender now holds references
* to #PyObject's so #Py_DECREF'ing them after Python ends causes bad problems every time
* the python-driver bug can be fixed if it happens again we can deal with it then. */
BPY_python_end();
BPY_python_end(do_python_exit);
}
#else
(void)do_python;
(void)do_python_exit;
#endif
ED_file_exit(); /* For file-selector menu data. */

View File

@ -46,7 +46,7 @@ static bool wm_platform_support_check_approval(const char *platform_support_key,
BLI_path_join(filepath, sizeof(filepath), cfgdir, BLENDER_PLATFORM_SUPPORT_FILE);
LinkNode *lines = BLI_file_read_as_lines(filepath);
for (LinkNode *line_node = lines; line_node; line_node = line_node->next) {
char *line = static_cast<char *>(line_node->link);
const char *line = static_cast<char *>(line_node->link);
if (STREQ(line, platform_support_key)) {
result = true;
break;

View File

@ -748,11 +748,11 @@ static const char *toolsystem_default_tool(const bToolKey *tkey)
case SPACE_SEQ: {
switch (tkey->mode) {
case SEQ_VIEW_SEQUENCE:
return "builtin.select";
return "builtin.select_box";
case SEQ_VIEW_PREVIEW:
return "builtin.sample";
case SEQ_VIEW_SEQUENCE_PREVIEW:
return "builtin.select";
return "builtin.select_box";
}
return "builtin.select_box";
}

View File

@ -663,7 +663,6 @@ static void print_help(bArgs *ba, bool all)
BLI_args_print_arg_doc(ba, "--debug-wintab");
BLI_args_print_arg_doc(ba, "--debug-gpu");
BLI_args_print_arg_doc(ba, "--debug-gpu-force-workarounds");
BLI_args_print_arg_doc(ba, "--debug-gpu-disable-ssbo");
if (defs.with_renderdoc) {
BLI_args_print_arg_doc(ba, "--debug-gpu-renderdoc");
}
@ -1113,9 +1112,6 @@ static const char arg_handle_debug_mode_generic_set_doc_depsgraph_uuid[] =
static const char arg_handle_debug_mode_generic_set_doc_gpu_force_workarounds[] =
"\n\t"
"Enable workarounds for typical GPU issues and disable all GPU extensions.";
static const char arg_handle_debug_mode_generic_set_doc_gpu_disable_ssbo[] =
"\n\t"
"Disable usage of shader storage buffer objects.";
static int arg_handle_debug_mode_generic_set(int /*argc*/, const char ** /*argv*/, void *data)
{
@ -2480,11 +2476,6 @@ void main_args_setup(bContext *C, bArgs *ba, bool all)
"--debug-gpu-force-workarounds",
CB_EX(arg_handle_debug_mode_generic_set, gpu_force_workarounds),
(void *)G_DEBUG_GPU_FORCE_WORKAROUNDS);
BLI_args_add(ba,
nullptr,
"--debug-gpu-disable-ssbo",
CB_EX(arg_handle_debug_mode_generic_set, gpu_disable_ssbo),
(void *)G_DEBUG_GPU_FORCE_DISABLE_SSBO);
BLI_args_add(ba, nullptr, "--debug-exit-on-error", CB(arg_handle_debug_exit_on_error), nullptr);
BLI_args_add(ba, nullptr, "--verbose", CB(arg_handle_verbosity_set), nullptr);