BLF: Subpixel Positioning, Anti-aliasing, Hinting #105441
|
@ -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),
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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:
|
||||
/**
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)) &&
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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"),
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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://")):
|
||||
|
|
|
@ -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():
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>;
|
||||
|
||||
/**
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
*
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 = ®ion->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. */
|
||||
|
|
|
@ -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},
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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, ¶ms_ptr, "asset_library_ref", UI_ITEM_NONE, "", ICON_NONE);
|
||||
uiItemR(row, ¶ms_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);
|
||||
}
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -13,6 +13,7 @@ set(INC
|
|||
../editors/include
|
||||
../makesrna
|
||||
../render
|
||||
../render/intern
|
||||
../windowmanager
|
||||
../../../intern/eigen
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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*/)
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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. */
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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},
|
||||
};
|
||||
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -124,7 +124,7 @@ static void node_gather_link_searches(GatherLinkSearchOpParams ¶ms)
|
|||
|
||||
/* If the source node has a geometry socket, connect it to the new viewer node as well. */
|
||||
LISTBASE_FOREACH (bNodeSocket *, socket, ¶ms.node.outputs) {
|
||||
if (socket->type == SOCK_GEOMETRY && socket->is_visible_or_panel_collapsed()) {
|
||||
if (socket->type == SOCK_GEOMETRY && socket->is_visible()) {
|
||||
nodeAddLink(¶ms.node_tree,
|
||||
¶ms.node,
|
||||
socket,
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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";
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue