diff options
286 files changed, 2210 insertions, 1891 deletions
diff --git a/build_files/build_environment/install_deps.sh b/build_files/build_environment/install_deps.sh index 03a75468400..75c0b3c0009 100755 --- a/build_files/build_environment/install_deps.sh +++ b/build_files/build_environment/install_deps.sh @@ -4036,14 +4036,14 @@ install_DEB() { INFO "Forced Python building, as requested..." _do_compile_python=true else - check_package_version_ge_lt_DEB python3-dev $PYTHON_VERSION_MIN $PYTHON_VERSION_MEX + check_package_version_ge_lt_DEB python${PYTHON_VERSION_SHORT}-dev $PYTHON_VERSION_MIN $PYTHON_VERSION_MEX if [ $? -eq 0 ]; then - PYTHON_VERSION_INSTALLED=$(echo `get_package_version_DEB python3-dev` | sed -r 's/^([0-9]+\.[0-9]+).*/\1/') - - install_packages_DEB python3-dev + install_packages_DEB python${PYTHON_VERSION_SHORT}-dev clean_Python PRINT "" + PYTHON_VERSION_INSTALLED=$(echo `get_package_version_DEB python${PYTHON_VERSION_SHORT}-dev` | sed -r 's/^([0-9]+\.[0-9]+).*/\1/') + for module in "${PYTHON_MODULES_PACKAGES[@]}" do module=($module) @@ -4681,11 +4681,11 @@ install_RPM() { else check_package_version_ge_lt_RPM python3-devel $PYTHON_VERSION_MIN $PYTHON_VERSION_MEX if [ $? -eq 0 ]; then - PYTHON_VERSION_INSTALLED=$(echo `get_package_version_RPM python3-devel` | sed -r 's/^([0-9]+\.[0-9]+).*/\1/') - install_packages_RPM python3-devel clean_Python + PYTHON_VERSION_INSTALLED=$(echo `get_package_version_RPM python3-devel` | sed -r 's/^([0-9]+\.[0-9]+).*/\1/') + for module in "${PYTHON_MODULES_PACKAGES[@]}" do module=($module) @@ -5224,12 +5224,12 @@ install_ARCH() { else check_package_version_ge_lt_ARCH python $PYTHON_VERSION_MIN $PYTHON_VERSION_MEX if [ $? -eq 0 ]; then - PYTHON_VERSION_INSTALLED=$(echo `get_package_version_ARCH python` | sed -r 's/^([0-9]+\.[0-9]+).*/\1/') - install_packages_ARCH python clean_Python PRINT "" + PYTHON_VERSION_INSTALLED=$(echo `get_package_version_ARCH python` | sed -r 's/^([0-9]+\.[0-9]+).*/\1/') + for module in "${PYTHON_MODULES_PACKAGES[@]}" do module=($module) diff --git a/build_files/config/pipeline_config.yaml b/build_files/config/pipeline_config.yaml index 5f85d232dce..8222f2ff0b9 100644 --- a/build_files/config/pipeline_config.yaml +++ b/build_files/config/pipeline_config.yaml @@ -5,38 +5,38 @@ update-code: git: submodules: - - branch: blender-v3.1-release + - branch: master commit_id: HEAD path: release/scripts/addons - - branch: blender-v3.1-release + - branch: master commit_id: HEAD path: release/scripts/addons_contrib - - branch: blender-v3.1-release + - branch: master commit_id: HEAD path: release/datafiles/locale - - branch: blender-v3.1-release + - branch: master commit_id: HEAD path: source/tools svn: libraries: darwin-arm64: - branch: tags/blender-3.1-release + branch: trunk commit_id: HEAD path: lib/darwin_arm64 darwin-x86_64: - branch: tags/blender-3.1-release + branch: trunk commit_id: HEAD path: lib/darwin linux-x86_64: - branch: tags/blender-3.1-release + branch: trunk commit_id: HEAD path: lib/linux_centos7_x86_64 windows-amd64: - branch: tags/blender-3.1-release + branch: trunk commit_id: HEAD path: lib/win64_vc15 tests: - branch: tags/blender-3.1-release + branch: trunk commit_id: HEAD path: lib/tests benchmarks: diff --git a/doc/doxygen/Doxyfile b/doc/doxygen/Doxyfile index 89954d8a155..2f004491c89 100644 --- a/doc/doxygen/Doxyfile +++ b/doc/doxygen/Doxyfile @@ -38,7 +38,7 @@ PROJECT_NAME = Blender # could be handy for archiving the generated documentation or if some version # control system is used. -PROJECT_NUMBER = V3.1 +PROJECT_NUMBER = V3.2 # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer a diff --git a/intern/cycles/device/hip/device_impl.cpp b/intern/cycles/device/hip/device_impl.cpp index 4f1cbabc89b..85ed3dc5b55 100644 --- a/intern/cycles/device/hip/device_impl.cpp +++ b/intern/cycles/device/hip/device_impl.cpp @@ -905,8 +905,8 @@ void HIPDevice::tex_alloc(device_texture &mem) address_mode = hipAddressModeClamp; break; case EXTENSION_CLIP: - // TODO : (Arya) setting this to Mode Clamp instead of Mode Border because it's unsupported - // in hip + /* TODO(@arya): setting this to Mode Clamp instead of Mode Border + * because it's unsupported in HIP. */ address_mode = hipAddressModeClamp; break; default: diff --git a/intern/cycles/integrator/shader_eval.cpp b/intern/cycles/integrator/shader_eval.cpp index 95a1adeb016..0edd3810c39 100644 --- a/intern/cycles/integrator/shader_eval.cpp +++ b/intern/cycles/integrator/shader_eval.cpp @@ -157,7 +157,7 @@ bool ShaderEval::eval_gpu(Device *device, queue->init_execution(); /* Execute work on GPU in chunk, so we can cancel. - * TODO : query appropriate size from device.*/ + * TODO: query appropriate size from device. */ const int32_t chunk_size = 65536; device_ptr d_input = input.device_pointer; diff --git a/intern/ghost/intern/GHOST_ImeWin32.cpp b/intern/ghost/intern/GHOST_ImeWin32.cpp index d1fc80adf56..2a1bfb633b3 100644 --- a/intern/ghost/intern/GHOST_ImeWin32.cpp +++ b/intern/ghost/intern/GHOST_ImeWin32.cpp @@ -96,7 +96,7 @@ bool GHOST_ImeWin32::IsEnglishMode() !(conversion_modes_ & (IME_CMODE_NATIVE | IME_CMODE_FULLSHAPE)); } -bool GHOST_ImeWin32::IsImeKeyEvent(char ascii) +bool GHOST_ImeWin32::IsImeKeyEvent(char ascii, GHOST_TKey key) { if (!(IsEnglishMode())) { /* In Chinese, Japanese, Korean, all alpha keys are processed by IME. */ @@ -106,7 +106,8 @@ bool GHOST_ImeWin32::IsImeKeyEvent(char ascii) if (IsLanguage(IMELANG_JAPANESE) && (ascii >= ' ' && ascii <= '~')) { return true; } - else if (IsLanguage(IMELANG_CHINESE) && ascii && strchr("!\"$'(),.:;<>?[\\]^_`/", ascii)) { + else if (IsLanguage(IMELANG_CHINESE) && ascii && strchr("!\"$'(),.:;<>?[\\]^_`/", ascii) && + !(key == GHOST_kKeyNumpadPeriod)) { return true; } } diff --git a/intern/ghost/intern/GHOST_ImeWin32.h b/intern/ghost/intern/GHOST_ImeWin32.h index ce0e4d64d53..d17a6d79503 100644 --- a/intern/ghost/intern/GHOST_ImeWin32.h +++ b/intern/ghost/intern/GHOST_ImeWin32.h @@ -161,7 +161,7 @@ class GHOST_ImeWin32 { bool IsEnglishMode(); /* Checks a key whether IME has to do handling. */ - bool IsImeKeyEvent(char ascii); + bool IsImeKeyEvent(char ascii, GHOST_TKey key); /** * Create the IME windows, and allocate required resources for them. diff --git a/intern/ghost/intern/GHOST_SystemCocoa.mm b/intern/ghost/intern/GHOST_SystemCocoa.mm index b92c3e73a88..756c4f876ed 100644 --- a/intern/ghost/intern/GHOST_SystemCocoa.mm +++ b/intern/ghost/intern/GHOST_SystemCocoa.mm @@ -890,7 +890,7 @@ bool GHOST_SystemCocoa::processEvents(bool waitForEvent) bool anyProcessed = false; NSEvent *event; - // TODO : implement timer ?? + /* TODO: implement timer? */ #if 0 do { GHOST_TimerManager* timerMgr = getTimerManager(); diff --git a/intern/ghost/intern/GHOST_SystemWin32.cpp b/intern/ghost/intern/GHOST_SystemWin32.cpp index 5251dd01b29..64e1ac3b9b3 100644 --- a/intern/ghost/intern/GHOST_SystemWin32.cpp +++ b/intern/ghost/intern/GHOST_SystemWin32.cpp @@ -1220,7 +1220,7 @@ GHOST_EventKey *GHOST_SystemWin32::processKeyEvent(GHOST_WindowWin32 *window, RA } #ifdef WITH_INPUT_IME - if (window->getImeInput()->IsImeKeyEvent(ascii)) { + if (window->getImeInput()->IsImeKeyEvent(ascii, key)) { return NULL; } #endif /* WITH_INPUT_IME */ diff --git a/intern/ghost/intern/GHOST_WindowWin32.cpp b/intern/ghost/intern/GHOST_WindowWin32.cpp index b5d0fd8e6db..47d4ff77d17 100644 --- a/intern/ghost/intern/GHOST_WindowWin32.cpp +++ b/intern/ghost/intern/GHOST_WindowWin32.cpp @@ -71,6 +71,8 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system, m_mousePresent(false), m_inLiveResize(false), m_system(system), + m_dropTarget(NULL), + m_hWnd(0), m_hDC(0), m_isDialog(dialog), m_hasMouseCaptured(false), @@ -78,6 +80,7 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system, m_nPressedButtons(0), m_customCursor(0), m_wantAlphaBackground(alphaBackground), + m_Bar(NULL), m_wintab(NULL), m_lastPointerTabletData(GHOST_TABLET_DATA_NONE), m_normal_state(GHOST_kWindowStateNormal), @@ -129,8 +132,24 @@ GHOST_WindowWin32::GHOST_WindowWin32(GHOST_SystemWin32 *system, m_hDC = ::GetDC(m_hWnd); if (!setDrawingContextType(type)) { + const char *title = "Blender - Unsupported Graphics Card Configuration"; + const char *text = + "A graphics card and driver with support for OpenGL 3.3 or higher is " + "required.\n\nInstalling the latest driver for your graphics card might resolve the " + "issue."; + if (GetSystemMetrics(SM_CMONITORS) > 1) { + text = + "A graphics card and driver with support for OpenGL 3.3 or higher is " + "required.\n\nPlugging all monitors into your primary graphics card might resolve " + "this issue. Installing the latest driver for your graphics card could also help."; + } + MessageBox(m_hWnd, text, title, MB_OK | MB_ICONERROR); + ::ReleaseDC(m_hWnd, m_hDC); ::DestroyWindow(m_hWnd); m_hWnd = NULL; + if (!parentwindow) { + exit(0); + } return; } @@ -564,20 +583,13 @@ GHOST_Context *GHOST_WindowWin32::newDrawingContext(GHOST_TDrawingContextType ty (m_debug_context ? WGL_CONTEXT_DEBUG_BIT_ARB : 0), GHOST_OPENGL_WGL_RESET_NOTIFICATION_STRATEGY); - if (context->initializeDrawingContext()) { - return context; - } - else { - MessageBox(m_hWnd, - "A graphics card and driver with support for OpenGL 3.3 or higher is required.\n" - "Installing the latest driver for your graphics card may resolve the issue.\n\n" - "The program will now close.", - "Blender - Unsupported Graphics Card or Driver", - MB_OK | MB_ICONERROR); + if (context && !context->initializeDrawingContext()) { delete context; - exit(0); + context = nullptr; } + return context; + #elif defined(WITH_GL_PROFILE_COMPAT) // ask for 2.1 context, driver gives any GL version >= 2.1 // (hopefully the latest compatibility profile) diff --git a/intern/ghost/intern/GHOST_XrContext.cpp b/intern/ghost/intern/GHOST_XrContext.cpp index 15b40690d83..9fa93f0c4b4 100644 --- a/intern/ghost/intern/GHOST_XrContext.cpp +++ b/intern/ghost/intern/GHOST_XrContext.cpp @@ -86,6 +86,7 @@ void GHOST_XrContext::initialize(const GHOST_XrContextCreateInfo *create_info) initApiLayers(); initExtensions(); if (isDebugMode()) { + printSDKVersion(); printAvailableAPILayersAndExtensionsInfo(); } @@ -156,6 +157,16 @@ void GHOST_XrContext::storeInstanceProperties() /** \name Debug Printing * \{ */ +void GHOST_XrContext::printSDKVersion() +{ + const XrVersion sdk_version = XR_CURRENT_API_VERSION; + + printf("OpenXR SDK Version: %u.%u.%u\n", + XR_VERSION_MAJOR(sdk_version), + XR_VERSION_MINOR(sdk_version), + XR_VERSION_PATCH(sdk_version)); +} + void GHOST_XrContext::printInstanceInfo() { assert(m_oxr->instance != XR_NULL_HANDLE); diff --git a/intern/ghost/intern/GHOST_XrContext.h b/intern/ghost/intern/GHOST_XrContext.h index 479b50e1537..b00f017ff59 100644 --- a/intern/ghost/intern/GHOST_XrContext.h +++ b/intern/ghost/intern/GHOST_XrContext.h @@ -126,6 +126,7 @@ class GHOST_XrContext : public GHOST_IXrContext { void storeInstanceProperties(); void initDebugMessenger(); + void printSDKVersion(); void printInstanceInfo(); void printAvailableAPILayersAndExtensionsInfo(); void printExtensionsAndAPILayersToEnable(); diff --git a/intern/guardedalloc/MEM_guardedalloc.h b/intern/guardedalloc/MEM_guardedalloc.h index 8a20323dcfc..d071def2ca4 100644 --- a/intern/guardedalloc/MEM_guardedalloc.h +++ b/intern/guardedalloc/MEM_guardedalloc.h @@ -39,8 +39,8 @@ * second intern/ module with MEM_ prefix, for use in c++. * * \subsection memdependencies Dependencies - * - stdlib - * - stdio + * - `stdlib` + * - `stdio` * * \subsection memdocs API Documentation * See \ref MEM_guardedalloc.h diff --git a/intern/locale/CMakeLists.txt b/intern/locale/CMakeLists.txt index 732fa1e4d11..3e467302d8e 100644 --- a/intern/locale/CMakeLists.txt +++ b/intern/locale/CMakeLists.txt @@ -56,7 +56,6 @@ if(WITH_INTERNATIONAL) list(APPEND LIB ${BOOST_LIBRARIES} ) - add_definitions(-DWITH_INTERNATIONAL) add_definitions(${BOOST_DEFINITIONS}) endif() diff --git a/release/datafiles/splash.png b/release/datafiles/splash.png Binary files differindex 4e9d58f2ac9..eb1250cf5a5 100644 --- a/release/datafiles/splash.png +++ b/release/datafiles/splash.png diff --git a/release/scripts/startup/bl_operators/wm.py b/release/scripts/startup/bl_operators/wm.py index ce8bfa3b058..bb85ad8ca50 100644 --- a/release/scripts/startup/bl_operators/wm.py +++ b/release/scripts/startup/bl_operators/wm.py @@ -2961,93 +2961,75 @@ class WM_MT_splash_quick_setup(Menu): bl_label = "Quick Setup" def draw(self, context): - wm = context.window_manager - # prefs = context.preferences - layout = self.layout - layout.operator_context = 'EXEC_DEFAULT' layout.label(text="Quick Setup") - split = layout.split(factor=0.25) + split = layout.split(factor=0.14) # Left margin. split.label() - split = split.split(factor=2.0 / 3.0) + split = split.split(factor=0.73) # Content width. col = split.column() + col.use_property_split = True + col.use_property_decorate = False + + # Languages. if bpy.app.build_options.international: - sub = col.split(factor=0.35) - row = sub.row() - row.alignment = 'RIGHT' - row.label(text="Language") prefs = context.preferences - sub.prop(prefs.view, "language", text="") + col.prop(prefs.view, "language") + col.separator() - col.separator() + # Shortcuts. + wm = context.window_manager + kc = wm.keyconfigs.active + kc_prefs = kc.preferences - sub = col.split(factor=0.35) - row = sub.row() - row.alignment = 'RIGHT' - row.label(text="Shortcuts") - text = bpy.path.display_name(wm.keyconfigs.active.name) + sub = col.column(heading="Shortcuts") + text = bpy.path.display_name(kc.name) if not text: text = "Blender" sub.menu("USERPREF_MT_keyconfigs", text=text) - kc = wm.keyconfigs.active - kc_prefs = kc.preferences has_select_mouse = hasattr(kc_prefs, "select_mouse") if has_select_mouse: - sub = col.split(factor=0.35) - row = sub.row() - row.alignment = 'RIGHT' - row.label(text="Select With") - sub.row().prop(kc_prefs, "select_mouse", expand=True) - has_select_mouse = True + col.row().prop(kc_prefs, "select_mouse", text="Select With", expand=True) has_spacebar_action = hasattr(kc_prefs, "spacebar_action") if has_spacebar_action: - sub = col.split(factor=0.35) - row = sub.row() - row.alignment = 'RIGHT' - row.label(text="Spacebar") - sub.row().prop(kc_prefs, "spacebar_action", expand=True) - has_select_mouse = True + col.row().prop(kc_prefs, "spacebar_action", text="Spacebar") col.separator() - sub = col.split(factor=0.35) - row = sub.row() - row.alignment = 'RIGHT' - row.label(text="Theme") + # Themes. + sub = col.column(heading="Theme") label = bpy.types.USERPREF_MT_interface_theme_presets.bl_label if label == "Presets": label = "Blender Dark" sub.menu("USERPREF_MT_interface_theme_presets", text=label) - # Keep height constant + # Keep height constant. if not has_select_mouse: col.label() if not has_spacebar_action: col.label() - layout.label() + layout.separator(factor=2.0) - row = layout.row() + # Save settings buttons. + sub = layout.row() - sub = row.row() old_version = bpy.types.PREFERENCES_OT_copy_prev.previous_version() if bpy.types.PREFERENCES_OT_copy_prev.poll(context) and old_version: - sub.operator("preferences.copy_prev", text=iface_("Load %d.%d Settings", "Operator") % old_version) + sub.operator("preferences.copy_prev", text="Load %d.%d Settings" % old_version) sub.operator("wm.save_userpref", text="Save New Settings") else: sub.label() sub.label() sub.operator("wm.save_userpref", text="Next") - layout.separator() - layout.separator() + layout.separator(factor=2.4) class WM_MT_splash(Menu): diff --git a/release/scripts/startup/bl_ui/space_userpref.py b/release/scripts/startup/bl_ui/space_userpref.py index 0548486c786..78ef68e0bab 100644 --- a/release/scripts/startup/bl_ui/space_userpref.py +++ b/release/scripts/startup/bl_ui/space_userpref.py @@ -2316,7 +2316,6 @@ class USERPREF_PT_experimental_debugging(ExperimentalPanel, Panel): context, ( ({"property": "use_undo_legacy"}, "T60695"), ({"property": "override_auto_resync"}, "T83811"), - ({"property": "proxy_to_override_auto_conversion"}, "T91671"), ({"property": "use_cycles_debug"}, None), ({"property": "use_geometry_nodes_legacy"}, "T91274"), ({"property": "show_asset_debug_info"}, None), diff --git a/release/scripts/startup/nodeitems_builtins.py b/release/scripts/startup/nodeitems_builtins.py index b841cb5dd13..4b48f5f0680 100644 --- a/release/scripts/startup/nodeitems_builtins.py +++ b/release/scripts/startup/nodeitems_builtins.py @@ -547,6 +547,8 @@ compositor_node_categories = [ NodeItem("CompositorNodeCombYUVA"), NodeItem("CompositorNodeSepYCCA"), NodeItem("CompositorNodeCombYCCA"), + NodeItem("CompositorNodeSeparateXYZ"), + NodeItem("CompositorNodeCombineXYZ"), NodeItem("CompositorNodeSwitchView"), NodeItem("CompositorNodeConvertColorSpace"), ]), diff --git a/source/blender/blenfont/CMakeLists.txt b/source/blender/blenfont/CMakeLists.txt index dd22bc2e7e0..5d04823cd0a 100644 --- a/source/blender/blenfont/CMakeLists.txt +++ b/source/blender/blenfont/CMakeLists.txt @@ -63,10 +63,6 @@ if(WIN32) ) endif() -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() - if(WITH_PYTHON) add_definitions(-DWITH_PYTHON) list(APPEND INC diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h index 1801c1ee1c9..ef9711c360c 100644 --- a/source/blender/blenkernel/BKE_DerivedMesh.h +++ b/source/blender/blenkernel/BKE_DerivedMesh.h @@ -104,14 +104,6 @@ typedef enum DerivedMeshType { DM_TYPE_CCGDM, } DerivedMeshType; -typedef enum DMDirtyFlag { - /* dm has valid tessellated faces, but tessellated CDDATA need to be updated. */ - DM_DIRTY_TESS_CDLAYERS = 1 << 0, - - /* check this with modifier dependsOnNormals callback to see if normals need recalculation */ - DM_DIRTY_NORMALS = 1 << 1, -} DMDirtyFlag; - typedef struct DerivedMesh DerivedMesh; struct DerivedMesh { /** Private DerivedMesh data, only for internal DerivedMesh use */ @@ -120,7 +112,6 @@ struct DerivedMesh { int needsFree; /* checked on ->release, is set to 0 for cached results */ int deformedOnly; /* set by modifier stack if only deformed from original */ DerivedMeshType type; - DMDirtyFlag dirty; /** * \warning Typical access is done via #getLoopTriArray, #getNumLoopTri. @@ -139,9 +130,6 @@ struct DerivedMesh { short tangent_mask; /* which tangent layers are calculated */ - /** Calculate vert and face normals */ - void (*calcNormals)(DerivedMesh *dm); - /** Loop tessellation cache (WARNING! Only call inside threading-protected code!) */ void (*recalcLoopTri)(DerivedMesh *dm); /** accessor functions */ @@ -164,7 +152,6 @@ struct DerivedMesh { */ struct MVert *(*getVertArray)(DerivedMesh *dm); struct MEdge *(*getEdgeArray)(DerivedMesh *dm); - struct MFace *(*getTessFaceArray)(DerivedMesh *dm); struct MLoop *(*getLoopArray)(DerivedMesh *dm); struct MPoly *(*getPolyArray)(DerivedMesh *dm); @@ -173,7 +160,6 @@ struct DerivedMesh { */ void (*copyVertArray)(DerivedMesh *dm, struct MVert *r_vert); void (*copyEdgeArray)(DerivedMesh *dm, struct MEdge *r_edge); - void (*copyTessFaceArray)(DerivedMesh *dm, struct MFace *r_face); void (*copyLoopArray)(DerivedMesh *dm, struct MLoop *r_loop); void (*copyPolyArray)(DerivedMesh *dm, struct MPoly *r_poly); @@ -182,37 +168,18 @@ struct DerivedMesh { */ struct MVert *(*dupVertArray)(DerivedMesh *dm); struct MEdge *(*dupEdgeArray)(DerivedMesh *dm); - struct MFace *(*dupTessFaceArray)(DerivedMesh *dm); struct MLoop *(*dupLoopArray)(DerivedMesh *dm); struct MPoly *(*dupPolyArray)(DerivedMesh *dm); - /** Return a pointer to a single element of vert/edge/face custom data - * from the derived mesh (this gives a pointer to the actual data, not - * a copy) - */ - void *(*getVertData)(DerivedMesh *dm, int index, int type); - void *(*getEdgeData)(DerivedMesh *dm, int index, int type); - void *(*getTessFaceData)(DerivedMesh *dm, int index, int type); - void *(*getPolyData)(DerivedMesh *dm, int index, int type); - /** Return a pointer to the entire array of vert/edge/face custom data * from the derived mesh (this gives a pointer to the actual data, not * a copy) */ void *(*getVertDataArray)(DerivedMesh *dm, int type); void *(*getEdgeDataArray)(DerivedMesh *dm, int type); - void *(*getTessFaceDataArray)(DerivedMesh *dm, int type); void *(*getLoopDataArray)(DerivedMesh *dm, int type); void *(*getPolyDataArray)(DerivedMesh *dm, int type); - /** Retrieves the base CustomData structures for - * verts/edges/tessfaces/loops/faces. */ - CustomData *(*getVertDataLayout)(DerivedMesh *dm); - CustomData *(*getEdgeDataLayout)(DerivedMesh *dm); - CustomData *(*getTessFaceDataLayout)(DerivedMesh *dm); - CustomData *(*getLoopDataLayout)(DerivedMesh *dm); - CustomData *(*getPolyDataLayout)(DerivedMesh *dm); - /** Optional grid access for subsurf */ int (*getNumGrids)(DerivedMesh *dm); int (*getGridSize)(DerivedMesh *dm); @@ -231,11 +198,6 @@ struct DerivedMesh { /** Get smooth vertex normal, undefined if index is not valid */ void (*getVertNo)(DerivedMesh *dm, int index, float r_no[3]); - void (*getPolyNo)(DerivedMesh *dm, int index, float r_no[3]); - - /** Get a map of vertices to faces - */ - const struct MeshElemMap *(*getPolyMap)(struct Object *ob, DerivedMesh *dm); /** Release reference to the DerivedMesh. This function decides internally * if the DerivedMesh will be freed, or cached for later use. */ @@ -265,15 +227,6 @@ void DM_init(DerivedMesh *dm, * Utility function to initialize a DerivedMesh for the desired number * of vertices, edges and faces, with a layer setup copied from source */ -void DM_from_template_ex(DerivedMesh *dm, - DerivedMesh *source, - DerivedMeshType type, - int numVerts, - int numEdges, - int numTessFaces, - int numLoops, - int numPolys, - const struct CustomData_MeshMasks *mask); void DM_from_template(DerivedMesh *dm, DerivedMesh *source, DerivedMeshType type, @@ -303,26 +256,9 @@ void DM_set_only_copy(DerivedMesh *dm, const struct CustomData_MeshMasks *mask); void DM_add_vert_layer(struct DerivedMesh *dm, int type, eCDAllocType alloctype, void *layer); void DM_add_edge_layer(struct DerivedMesh *dm, int type, eCDAllocType alloctype, void *layer); -void DM_add_tessface_layer(struct DerivedMesh *dm, int type, eCDAllocType alloctype, void *layer); -void DM_add_loop_layer(DerivedMesh *dm, int type, eCDAllocType alloctype, void *layer); void DM_add_poly_layer(struct DerivedMesh *dm, int type, eCDAllocType alloctype, void *layer); /* -------------------------------------------------------------------- */ -/** \name Custom Data Access Functions - * - * \return pointer to data from first layer which matches type - * if they return NULL for valid indices, data doesn't exist. - * \note these return pointers - any change modifies the internals of the mesh. - * \{ */ - -void *DM_get_vert_data(struct DerivedMesh *dm, int index, int type); -void *DM_get_edge_data(struct DerivedMesh *dm, int index, int type); -void *DM_get_tessface_data(struct DerivedMesh *dm, int index, int type); -void *DM_get_poly_data(struct DerivedMesh *dm, int index, int type); - -/** \} */ - -/* -------------------------------------------------------------------- */ /** \name Custom Data Layer Access Functions * * \return pointer to first data layer which matches type (a flat array) @@ -332,7 +268,6 @@ void *DM_get_poly_data(struct DerivedMesh *dm, int index, int type); void *DM_get_vert_data_layer(struct DerivedMesh *dm, int type); void *DM_get_edge_data_layer(struct DerivedMesh *dm, int type); -void *DM_get_tessface_data_layer(struct DerivedMesh *dm, int type); void *DM_get_poly_data_layer(struct DerivedMesh *dm, int type); void *DM_get_loop_data_layer(struct DerivedMesh *dm, int type); @@ -354,8 +289,6 @@ void DM_copy_vert_data(struct DerivedMesh *source, */ void DM_DupPolys(DerivedMesh *source, DerivedMesh *target); -void DM_ensure_normals(DerivedMesh *dm); - /** * Ensure the array is large enough. * diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h index d1f31e0d2f5..645d049fe71 100644 --- a/source/blender/blenkernel/BKE_blender_version.h +++ b/source/blender/blenkernel/BKE_blender_version.h @@ -31,15 +31,15 @@ extern "C" { */ /* Blender major and minor version. */ -#define BLENDER_VERSION 301 +#define BLENDER_VERSION 302 /* Blender patch version for bugfix releases. */ #define BLENDER_VERSION_PATCH 0 /** Blender release cycle stage: alpha/beta/rc/release. */ -#define BLENDER_VERSION_CYCLE beta +#define BLENDER_VERSION_CYCLE alpha /* Blender file format version. */ #define BLENDER_FILE_VERSION BLENDER_VERSION -#define BLENDER_FILE_SUBVERSION 6 +#define BLENDER_FILE_SUBVERSION 1 /* Minimum Blender version that supports reading file written with the current * version. Older Blender versions will test this and show a warning if the file diff --git a/source/blender/blenkernel/BKE_image_partial_update.hh b/source/blender/blenkernel/BKE_image_partial_update.hh index ca7c4f40593..0fc05809bbd 100644 --- a/source/blender/blenkernel/BKE_image_partial_update.hh +++ b/source/blender/blenkernel/BKE_image_partial_update.hh @@ -23,8 +23,8 @@ * image that are changed. These areas are organized in chunks. Changes that happen over time are * organized in changesets. * - * A common usecase is to update GPUTexture for drawing where only that part is uploaded that only - * changed. + * A common use case is to update #GPUTexture for drawing where only that part is uploaded that + * only changed. */ #pragma once diff --git a/source/blender/blenkernel/BKE_lib_override.h b/source/blender/blenkernel/BKE_lib_override.h index 30e75259967..e8065566c97 100644 --- a/source/blender/blenkernel/BKE_lib_override.h +++ b/source/blender/blenkernel/BKE_lib_override.h @@ -100,6 +100,9 @@ struct ID *BKE_lib_override_library_create_from_id(struct Main *bmain, * main. You can add more local IDs to be remapped to use new overriding ones by setting their * LIB_TAG_DOIT tag. * + * \param owner_library: the library in which the overrides should be created. Besides versioning + * and resync code path, this should always be NULL (i.e. the local .blend file). + * * \param reference_library: the library from which the linked data being overridden come from * (i.e. the library of the linked reference ID). * @@ -109,6 +112,7 @@ struct ID *BKE_lib_override_library_create_from_id(struct Main *bmain, * \return \a true on success, \a false otherwise. */ bool BKE_lib_override_library_create_from_tag(struct Main *bmain, + struct Library *owner_library, const struct Library *reference_library, bool do_no_main); /** @@ -122,16 +126,24 @@ bool BKE_lib_override_library_create_from_tag(struct Main *bmain, * * \param view_layer: the active view layer to search instantiated collections in, can be NULL (in * which case \a scene's master collection children hierarchy is used instead). + * + * \param owner_library: the library in which the overrides should be created. Besides versioning + * and resync code path, this should always be NULL (i.e. the local .blend file). + * * \param id_root: The root ID to create an override from. + * * \param id_reference: Some reference ID used to do some post-processing after overrides have been * created, may be NULL. Typically, the Empty object instantiating the linked collection we * override, currently. + * * \param r_id_root_override: if not NULL, the override generated for the given \a id_root. + * * \return true if override was successfully created. */ bool BKE_lib_override_library_create(struct Main *bmain, struct Scene *scene, struct ViewLayer *view_layer, + struct Library *owner_library, struct ID *id_root, struct ID *id_reference, struct ID **r_id_root_override); diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h index 80889813b34..14305323db9 100644 --- a/source/blender/blenkernel/BKE_modifier.h +++ b/source/blender/blenkernel/BKE_modifier.h @@ -245,10 +245,6 @@ typedef struct ModifierTypeInfo { const struct ModifierEvalContext *ctx, struct Mesh *mesh); - struct Hair *(*modifyHair)(struct ModifierData *md, - const struct ModifierEvalContext *ctx, - struct Hair *hair); - /** * The modifier has to change the geometry set in-place. The geometry set can contain zero or * more geometry components. This callback can be used by modifiers that don't work on any diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h index 16d8ba2e6dd..d583b5f0648 100644 --- a/source/blender/blenkernel/BKE_node.h +++ b/source/blender/blenkernel/BKE_node.h @@ -1291,6 +1291,8 @@ void BKE_nodetree_remove_layer_n(struct bNodeTree *ntree, struct Scene *scene, i #define CMP_NODE_POSTERIZE 327 #define CMP_NODE_CONVERT_COLOR_SPACE 328 #define CMP_NODE_SCENE_TIME 329 +#define CMP_NODE_SEPARATE_XYZ 330 +#define CMP_NODE_COMBINE_XYZ 331 /* channel toggles */ #define CMP_CHAN_RGB 1 diff --git a/source/blender/blenkernel/CMakeLists.txt b/source/blender/blenkernel/CMakeLists.txt index 220d4673075..05902e94552 100644 --- a/source/blender/blenkernel/CMakeLists.txt +++ b/source/blender/blenkernel/CMakeLists.txt @@ -719,10 +719,6 @@ if(WITH_FFTW3) add_definitions(-DFFTW3=1) endif() -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() - if(WITH_FREESTYLE) add_definitions(-DWITH_FREESTYLE) endif() diff --git a/source/blender/blenkernel/intern/DerivedMesh.cc b/source/blender/blenkernel/intern/DerivedMesh.cc index d0d19ff199d..32f14249aab 100644 --- a/source/blender/blenkernel/intern/DerivedMesh.cc +++ b/source/blender/blenkernel/intern/DerivedMesh.cc @@ -127,30 +127,6 @@ static MEdge *dm_getEdgeArray(DerivedMesh *dm) return medge; } -static MFace *dm_getTessFaceArray(DerivedMesh *dm) -{ - MFace *mface = (MFace *)CustomData_get_layer(&dm->faceData, CD_MFACE); - - if (!mface) { - int numTessFaces = dm->getNumTessFaces(dm); - - if (!numTessFaces) { - /* Do not add layer if there's no elements in it, this leads to issues later when - * this layer is needed with non-zero size, but currently CD stuff does not check - * for requested layer size on creation and just returns layer which was previously - * added (sergey) */ - return nullptr; - } - - mface = (MFace *)CustomData_add_layer( - &dm->faceData, CD_MFACE, CD_CALLOC, nullptr, numTessFaces); - CustomData_set_layer_flag(&dm->faceData, CD_MFACE, CD_FLAG_TEMPORARY); - dm->copyTessFaceArray(dm, mface); - } - - return mface; -} - static MLoop *dm_getLoopArray(DerivedMesh *dm) { MLoop *mloop = (MLoop *)CustomData_get_layer(&dm->loopData, CD_MLOOP); @@ -203,18 +179,6 @@ static MEdge *dm_dupEdgeArray(DerivedMesh *dm) return tmp; } -static MFace *dm_dupFaceArray(DerivedMesh *dm) -{ - MFace *tmp = (MFace *)MEM_malloc_arrayN( - dm->getNumTessFaces(dm), sizeof(*tmp), "dm_dupFaceArray tmp"); - - if (tmp) { - dm->copyTessFaceArray(dm, tmp); - } - - return tmp; -} - static MLoop *dm_dupLoopArray(DerivedMesh *dm) { MLoop *tmp = (MLoop *)MEM_malloc_arrayN( @@ -270,42 +234,15 @@ static const MLoopTri *dm_getLoopTriArray(DerivedMesh *dm) return looptri; } -static CustomData *dm_getVertCData(DerivedMesh *dm) -{ - return &dm->vertData; -} - -static CustomData *dm_getEdgeCData(DerivedMesh *dm) -{ - return &dm->edgeData; -} - -static CustomData *dm_getTessFaceCData(DerivedMesh *dm) -{ - return &dm->faceData; -} - -static CustomData *dm_getLoopCData(DerivedMesh *dm) -{ - return &dm->loopData; -} - -static CustomData *dm_getPolyCData(DerivedMesh *dm) -{ - return &dm->polyData; -} - void DM_init_funcs(DerivedMesh *dm) { /* default function implementations */ dm->getVertArray = dm_getVertArray; dm->getEdgeArray = dm_getEdgeArray; - dm->getTessFaceArray = dm_getTessFaceArray; dm->getLoopArray = dm_getLoopArray; dm->getPolyArray = dm_getPolyArray; dm->dupVertArray = dm_dupVertArray; dm->dupEdgeArray = dm_dupEdgeArray; - dm->dupTessFaceArray = dm_dupFaceArray; dm->dupLoopArray = dm_dupLoopArray; dm->dupPolyArray = dm_dupPolyArray; @@ -314,19 +251,8 @@ void DM_init_funcs(DerivedMesh *dm) /* subtypes handle getting actual data */ dm->getNumLoopTri = dm_getNumLoopTri; - dm->getVertDataLayout = dm_getVertCData; - dm->getEdgeDataLayout = dm_getEdgeCData; - dm->getTessFaceDataLayout = dm_getTessFaceCData; - dm->getLoopDataLayout = dm_getLoopCData; - dm->getPolyDataLayout = dm_getPolyCData; - - dm->getVertData = DM_get_vert_data; - dm->getEdgeData = DM_get_edge_data; - dm->getTessFaceData = DM_get_tessface_data; - dm->getPolyData = DM_get_poly_data; dm->getVertDataArray = DM_get_vert_data_layer; dm->getEdgeDataArray = DM_get_edge_data_layer; - dm->getTessFaceDataArray = DM_get_tessface_data_layer; dm->getPolyDataArray = DM_get_poly_data_layer; dm->getLoopDataArray = DM_get_loop_data_layer; } @@ -349,7 +275,6 @@ void DM_init(DerivedMesh *dm, DM_init_funcs(dm); dm->needsFree = 1; - dm->dirty = (DMDirtyFlag)0; /* Don't use #CustomData_reset because we don't want to touch custom-data. */ copy_vn_i(dm->vertData.typemap, CD_NUMTYPES, -1); @@ -359,16 +284,16 @@ void DM_init(DerivedMesh *dm, copy_vn_i(dm->polyData.typemap, CD_NUMTYPES, -1); } -void DM_from_template_ex(DerivedMesh *dm, - DerivedMesh *source, - DerivedMeshType type, - int numVerts, - int numEdges, - int numTessFaces, - int numLoops, - int numPolys, - const CustomData_MeshMasks *mask) +void DM_from_template(DerivedMesh *dm, + DerivedMesh *source, + DerivedMeshType type, + int numVerts, + int numEdges, + int numTessFaces, + int numLoops, + int numPolys) { + const CustomData_MeshMasks *mask = &CD_MASK_DERIVEDMESH; CustomData_copy(&source->vertData, &dm->vertData, mask->vmask, CD_CALLOC, numVerts); CustomData_copy(&source->edgeData, &dm->edgeData, mask->emask, CD_CALLOC, numEdges); CustomData_copy(&source->faceData, &dm->faceData, mask->fmask, CD_CALLOC, numTessFaces); @@ -387,26 +312,6 @@ void DM_from_template_ex(DerivedMesh *dm, DM_init_funcs(dm); dm->needsFree = 1; - dm->dirty = (DMDirtyFlag)0; -} -void DM_from_template(DerivedMesh *dm, - DerivedMesh *source, - DerivedMeshType type, - int numVerts, - int numEdges, - int numTessFaces, - int numLoops, - int numPolys) -{ - DM_from_template_ex(dm, - source, - type, - numVerts, - numEdges, - numTessFaces, - numLoops, - numPolys, - &CD_MASK_DERIVEDMESH); } bool DM_release(DerivedMesh *dm) @@ -464,14 +369,6 @@ void DM_DupPolys(DerivedMesh *source, DerivedMesh *target) } } -void DM_ensure_normals(DerivedMesh *dm) -{ - if (dm->dirty & DM_DIRTY_NORMALS) { - dm->calcNormals(dm); - } - BLI_assert((dm->dirty & DM_DIRTY_NORMALS) == 0); -} - void DM_ensure_looptri_data(DerivedMesh *dm) { const unsigned int totpoly = dm->numPolyData; @@ -524,7 +421,7 @@ void DM_set_only_copy(DerivedMesh *dm, const CustomData_MeshMasks *mask) * see replies to r50969, Campbell */ #if 0 CustomData_set_only_copy(&dm->loopData, mask->lmask); - CustomData_set_only_copy(&dm->polyData, mask->pmask); + Custom(&dm->polyData, mask->pmask); #endif } @@ -552,45 +449,11 @@ void DM_add_edge_layer(DerivedMesh *dm, int type, eCDAllocType alloctype, void * CustomData_add_layer(&dm->edgeData, type, alloctype, layer, dm->numEdgeData); } -void DM_add_tessface_layer(DerivedMesh *dm, int type, eCDAllocType alloctype, void *layer) -{ - CustomData_add_layer(&dm->faceData, type, alloctype, layer, dm->numTessFaceData); -} - -void DM_add_loop_layer(DerivedMesh *dm, int type, eCDAllocType alloctype, void *layer) -{ - CustomData_add_layer(&dm->loopData, type, alloctype, layer, dm->numLoopData); -} - void DM_add_poly_layer(DerivedMesh *dm, int type, eCDAllocType alloctype, void *layer) { CustomData_add_layer(&dm->polyData, type, alloctype, layer, dm->numPolyData); } -void *DM_get_vert_data(DerivedMesh *dm, int index, int type) -{ - BLI_assert(index >= 0 && index < dm->getNumVerts(dm)); - return CustomData_get(&dm->vertData, index, type); -} - -void *DM_get_edge_data(DerivedMesh *dm, int index, int type) -{ - BLI_assert(index >= 0 && index < dm->getNumEdges(dm)); - return CustomData_get(&dm->edgeData, index, type); -} - -void *DM_get_tessface_data(DerivedMesh *dm, int index, int type) -{ - BLI_assert(index >= 0 && index < dm->getNumTessFaces(dm)); - return CustomData_get(&dm->faceData, index, type); -} - -void *DM_get_poly_data(DerivedMesh *dm, int index, int type) -{ - BLI_assert(index >= 0 && index < dm->getNumPolys(dm)); - return CustomData_get(&dm->polyData, index, type); -} - void *DM_get_vert_data_layer(DerivedMesh *dm, int type) { if (type == CD_MVERT) { @@ -609,15 +472,6 @@ void *DM_get_edge_data_layer(DerivedMesh *dm, int type) return CustomData_get_layer(&dm->edgeData, type); } -void *DM_get_tessface_data_layer(DerivedMesh *dm, int type) -{ - if (type == CD_MFACE) { - return dm->getTessFaceArray(dm); - } - - return CustomData_get_layer(&dm->faceData, type); -} - void *DM_get_poly_data_layer(DerivedMesh *dm, int type) { return CustomData_get_layer(&dm->polyData, type); diff --git a/source/blender/blenkernel/intern/blendfile.c b/source/blender/blenkernel/intern/blendfile.c index 6ae19c8036f..819f786a2d0 100644 --- a/source/blender/blenkernel/intern/blendfile.c +++ b/source/blender/blenkernel/intern/blendfile.c @@ -78,6 +78,23 @@ /** \name High Level `.blend` file read/write. * \{ */ +static bool blendfile_or_libraries_versions_atleast(Main *bmain, + const short versionfile, + const short subversionfile) +{ + if (!MAIN_VERSION_ATLEAST(bmain, versionfile, subversionfile)) { + return false; + } + + LISTBASE_FOREACH (Library *, library, &bmain->libraries) { + if (!MAIN_VERSION_ATLEAST(library, versionfile, subversionfile)) { + return false; + } + } + + return true; +} + static bool foreach_path_clean_cb(BPathForeachPathData *UNUSED(bpath_data), char *path_dst, const char *path_src) @@ -349,10 +366,11 @@ static void setup_app_data(bContext *C, do_versions_ipos_to_animato(bmain); } - /* FIXME: Same as above, readfile's `do_version` do not allow to create new IDs. */ - /* TODO: Once this is definitively validated for 3.0 and option to not do it is removed, add a - * version bump and check here. */ - if (mode != LOAD_UNDO && !USER_EXPERIMENTAL_TEST(&U, no_proxy_to_override_conversion)) { + /* NOTE: readfile's `do_version` does not allow to create new IDs, and only operates on a single + * library at a time. This code needs to operate on the whole Main at once. */ + /* NOTE: Check bmain version (i.e. current blend file version), AND the versions of all the + * linked libraries. */ + if (mode != LOAD_UNDO && !blendfile_or_libraries_versions_atleast(bmain, 302, 1)) { BKE_lib_override_library_main_proxy_convert(bmain, reports); } diff --git a/source/blender/blenkernel/intern/blendfile_link_append.c b/source/blender/blenkernel/intern/blendfile_link_append.c index 9b3f4c2fae8..94d14b63437 100644 --- a/source/blender/blenkernel/intern/blendfile_link_append.c +++ b/source/blender/blenkernel/intern/blendfile_link_append.c @@ -993,6 +993,27 @@ static int foreach_libblock_link_append_callback(LibraryIDLinkCallbackData *cb_d /** \name Library link/append code. * \{ */ +static void blendfile_link_append_proxies_convert(Main *bmain, ReportList *reports) +{ + /* NOTE: Do not bother checking file versions here, if there are no proxies to convert this code + * is quite fast anyway. */ + + BlendFileReadReport bf_reports = {.reports = reports}; + BKE_lib_override_library_main_proxy_convert(bmain, &bf_reports); + + if (bf_reports.count.proxies_to_lib_overrides_success != 0 || + bf_reports.count.proxies_to_lib_overrides_failures != 0) { + BKE_reportf( + bf_reports.reports, + RPT_WARNING, + "Proxies have been removed from Blender (%d proxies were automatically converted " + "to library overrides, %d proxies could not be converted and were cleared). " + "Please consider re-saving any library .blend file with the newest Blender version.", + bf_reports.count.proxies_to_lib_overrides_success, + bf_reports.count.proxies_to_lib_overrides_failures); + } +} + void BKE_blendfile_append(BlendfileLinkAppendContext *lapp_context, ReportList *reports) { if (lapp_context->num_items == 0) { @@ -1259,6 +1280,8 @@ void BKE_blendfile_append(BlendfileLinkAppendContext *lapp_context, ReportList * } BKE_main_id_newptr_and_tag_clear(bmain); + + blendfile_link_append_proxies_convert(bmain, reports); } void BKE_blendfile_link(BlendfileLinkAppendContext *lapp_context, ReportList *reports) @@ -1361,6 +1384,10 @@ void BKE_blendfile_link(BlendfileLinkAppendContext *lapp_context, ReportList *re .active_collection = NULL}; loose_data_instantiate(&instantiate_context); } + + if ((lapp_context->params->flag & FILE_LINK) != 0) { + blendfile_link_append_proxies_convert(lapp_context->params->bmain, reports); + } } /** \} */ diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c index a4f3e84a2bf..275500ba2f6 100644 --- a/source/blender/blenkernel/intern/cdderivedmesh.c +++ b/source/blender/blenkernel/intern/cdderivedmesh.c @@ -116,12 +116,6 @@ static void cdDM_copyEdgeArray(DerivedMesh *dm, MEdge *r_edge) memcpy(r_edge, cddm->medge, sizeof(*r_edge) * dm->numEdgeData); } -static void cdDM_copyTessFaceArray(DerivedMesh *dm, MFace *r_face) -{ - CDDerivedMesh *cddm = (CDDerivedMesh *)dm; - memcpy(r_face, cddm->mface, sizeof(*r_face) * dm->numTessFaceData); -} - static void cdDM_copyLoopArray(DerivedMesh *dm, MLoop *r_loop) { CDDerivedMesh *cddm = (CDDerivedMesh *)dm; @@ -147,20 +141,6 @@ static void cdDM_getVertNo(DerivedMesh *dm, int index, float r_no[3]) copy_v3_v3(r_no, cddm->vert_normals[index]); } -static const MeshElemMap *cdDM_getPolyMap(Object *ob, DerivedMesh *dm) -{ - CDDerivedMesh *cddm = (CDDerivedMesh *)dm; - - if (!cddm->pmap && ob->type == OB_MESH) { - Mesh *me = ob->data; - - BKE_mesh_vert_poly_map_create( - &cddm->pmap, &cddm->pmap_mem, me->mpoly, me->mloop, me->totvert, me->totpoly, me->totloop); - } - - return cddm->pmap; -} - static void cdDM_recalc_looptri(DerivedMesh *dm) { CDDerivedMesh *cddm = (CDDerivedMesh *)dm; @@ -216,24 +196,17 @@ static CDDerivedMesh *cdDM_create(const char *desc) dm->copyVertArray = cdDM_copyVertArray; dm->copyEdgeArray = cdDM_copyEdgeArray; - dm->copyTessFaceArray = cdDM_copyTessFaceArray; dm->copyLoopArray = cdDM_copyLoopArray; dm->copyPolyArray = cdDM_copyPolyArray; - dm->getVertData = DM_get_vert_data; - dm->getEdgeData = DM_get_edge_data; - dm->getTessFaceData = DM_get_tessface_data; dm->getVertDataArray = DM_get_vert_data_layer; dm->getEdgeDataArray = DM_get_edge_data_layer; - dm->getTessFaceDataArray = DM_get_tessface_data_layer; dm->recalcLoopTri = cdDM_recalc_looptri; dm->getVertCo = cdDM_getVertCo; dm->getVertNo = cdDM_getVertNo; - dm->getPolyMap = cdDM_getPolyMap; - dm->release = cdDM_release; return cddm; @@ -265,12 +238,6 @@ static DerivedMesh *cdDM_from_mesh_ex(Mesh *mesh, dm->deformedOnly = 1; dm->cd_flag = mesh->cd_flag; - if (mesh->runtime.cd_dirty_vert & CD_MASK_NORMAL) { - dm->dirty |= DM_DIRTY_NORMALS; - } - /* TODO: DM_DIRTY_TESS_CDLAYERS ? Maybe not though, - * since we probably want to switch to looptris? */ - CustomData_merge(&mesh->vdata, &dm->vertData, cddata_masks.vmask, alloctype, mesh->totvert); CustomData_merge(&mesh->edata, &dm->edgeData, cddata_masks.emask, alloctype, mesh->totedge); CustomData_merge(&mesh->fdata, @@ -282,7 +249,9 @@ static DerivedMesh *cdDM_from_mesh_ex(Mesh *mesh, CustomData_merge(&mesh->pdata, &dm->polyData, cddata_masks.pmask, alloctype, mesh->totpoly); cddm->mvert = CustomData_get_layer(&dm->vertData, CD_MVERT); - cddm->vert_normals = CustomData_get_layer(&dm->vertData, CD_NORMAL); + /* Though this may be an unnecessary calculation, simply retrieving the layer may return nothing + * or dirty normals. */ + cddm->vert_normals = BKE_mesh_vertex_normals_ensure(mesh); cddm->medge = CustomData_get_layer(&dm->edgeData, CD_MEDGE); cddm->mloop = CustomData_get_layer(&dm->loopData, CD_MLOOP); cddm->mpoly = CustomData_get_layer(&dm->polyData, CD_MPOLY); @@ -327,12 +296,6 @@ DerivedMesh *CDDM_copy(DerivedMesh *source) DM_from_template(dm, source, DM_TYPE_CDDM, numVerts, numEdges, numTessFaces, numLoops, numPolys); dm->deformedOnly = source->deformedOnly; dm->cd_flag = source->cd_flag; - dm->dirty = source->dirty; - - /* Tessellation data is never copied, so tag it here. - * Only tag dirty layers if we really ignored tessellation faces. - */ - dm->dirty |= DM_DIRTY_TESS_CDLAYERS; CustomData_copy_data(&source->vertData, &dm->vertData, 0, 0, numVerts); CustomData_copy_data(&source->edgeData, &dm->edgeData, 0, 0, numEdges); diff --git a/source/blender/blenkernel/intern/crazyspace.c b/source/blender/blenkernel/intern/crazyspace.c index 573595b6f90..0bf83ed5036 100644 --- a/source/blender/blenkernel/intern/crazyspace.c +++ b/source/blender/blenkernel/intern/crazyspace.c @@ -194,13 +194,10 @@ void BKE_crazyspace_set_quats_mesh(Mesh *me, float (*mappedcos)[3], float (*quats)[4]) { - MVert *mvert = me->mvert; - for (int i = 0; i < me->totvert; i++, mvert++) { - mvert->flag &= ~ME_VERT_TMP_TAG; - } + BLI_bitmap *vert_tag = BLI_BITMAP_NEW(me->totvert, __func__); /* first store two sets of tangent vectors in vertices, we derive it just from the face-edges */ - mvert = me->mvert; + MVert *mvert = me->mvert; MPoly *mp = me->mpoly; MLoop *mloop = me->mloop; @@ -210,7 +207,7 @@ void BKE_crazyspace_set_quats_mesh(Mesh *me, MLoop *ml_prev = &ml_next[mp->totloop - 2]; for (int j = 0; j < mp->totloop; j++) { - if ((mvert[ml_curr->v].flag & ME_VERT_TMP_TAG) == 0) { + if (!BLI_BITMAP_TEST(vert_tag, ml_curr->v)) { const float *co_prev, *co_curr, *co_next; /* orig */ const float *vd_prev, *vd_curr, *vd_next; /* deform */ @@ -233,7 +230,7 @@ void BKE_crazyspace_set_quats_mesh(Mesh *me, set_crazy_vertex_quat( quats[ml_curr->v], co_curr, co_next, co_prev, vd_curr, vd_next, vd_prev); - mvert[ml_curr->v].flag |= ME_VERT_TMP_TAG; + BLI_BITMAP_ENABLE(vert_tag, ml_curr->v); } ml_prev = ml_curr; @@ -241,6 +238,8 @@ void BKE_crazyspace_set_quats_mesh(Mesh *me, ml_next++; } } + + MEM_freeN(vert_tag); } int BKE_crazyspace_get_first_deform_matrices_editbmesh(struct Depsgraph *depsgraph, diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c index ef789d3e39b..bc5a0ed1538 100644 --- a/source/blender/blenkernel/intern/dynamicpaint.c +++ b/source/blender/blenkernel/intern/dynamicpaint.c @@ -1985,9 +1985,6 @@ static Mesh *dynamicPaint_Modifier_apply(DynamicPaintModifierData *pmd, Object * } MEM_freeN(fcolor); - - /* Mark tessellated CD layers as dirty. */ - // result->dirty |= DM_DIRTY_TESS_CDLAYERS; } /* vertex group paint */ else if (surface->type == MOD_DPAINT_SURFACE_T_WEIGHT) { diff --git a/source/blender/blenkernel/intern/hair.cc b/source/blender/blenkernel/intern/hair.cc index b7ba159f631..5e8b81c03a4 100644 --- a/source/blender/blenkernel/intern/hair.cc +++ b/source/blender/blenkernel/intern/hair.cc @@ -31,7 +31,7 @@ #include "BLI_listbase.h" #include "BLI_math_base.h" #include "BLI_math_vec_types.hh" -#include "BLI_rand.h" +#include "BLI_rand.hh" #include "BLI_string.h" #include "BLI_utildefines.h" @@ -54,6 +54,7 @@ #include "BLO_read_write.h" using blender::float3; +using blender::RandomNumberGenerator; static const char *HAIR_ATTR_POSITION = "position"; static const char *HAIR_ATTR_RADIUS = "radius"; @@ -220,38 +221,32 @@ static void hair_random(Hair *hair) CustomData_realloc(&hair->cdata, hair->totcurve); BKE_hair_update_customdata_pointers(hair); - RNG *rng = BLI_rng_new(0); + RandomNumberGenerator rng; for (int i = 0; i < hair->totcurve; i++) { HairCurve *curve = &hair->curves[i]; curve->firstpoint = i * numpoints; curve->numpoints = numpoints; - float theta = 2.0f * M_PI * BLI_rng_get_float(rng); - float phi = saacosf(2.0f * BLI_rng_get_float(rng) - 1.0f); + const float theta = 2.0f * M_PI * rng.get_float(); + const float phi = saacosf(2.0f * rng.get_float() - 1.0f); - float no[3] = {sinf(theta) * sinf(phi), cosf(theta) * sinf(phi), cosf(phi)}; - normalize_v3(no); + float3 no = {std::sin(theta) * std::sin(phi), std::cos(theta) * std::sin(phi), std::cos(phi)}; + blender::math::normalize(no); - float co[3]; - copy_v3_v3(co, no); - - float(*curve_co)[3] = hair->co + curve->firstpoint; - float *curve_radius = hair->radius + curve->firstpoint; + float(*curve_positions)[3] = hair->co + curve->firstpoint; + float *curve_radii = hair->radius + curve->firstpoint; + float3 co = no; for (int key = 0; key < numpoints; key++) { float t = key / (float)(numpoints - 1); - copy_v3_v3(curve_co[key], co); - curve_radius[key] = 0.02f * (1.0f - t); - - float offset[3] = {2.0f * BLI_rng_get_float(rng) - 1.0f, - 2.0f * BLI_rng_get_float(rng) - 1.0f, - 2.0f * BLI_rng_get_float(rng) - 1.0f}; - add_v3_v3(offset, no); - madd_v3_v3fl(co, offset, 1.0f / numpoints); + copy_v3_v3(curve_positions[key], co); + curve_radii[key] = 0.02f * (1.0f - t); + + float3 offset = float3(rng.get_float(), rng.get_float(), rng.get_float()) * 2.0f - 1.0f; + + co += (offset + no) / numpoints; } } - - BLI_rng_free(rng); } void *BKE_hair_add(Main *bmain, const char *name) @@ -380,22 +375,6 @@ static Hair *hair_evaluate_modifiers(struct Depsgraph *depsgraph, /* Created deformed coordinates array on demand. */ mti->deformVerts(md, &mectx, nullptr, hair->co, hair->totpoint); } - else if (mti->modifyHair) { - /* Ensure we are not modifying the input. */ - if (hair == hair_input) { - hair = BKE_hair_copy_for_eval(hair, true); - } - - Hair *hair_next = mti->modifyHair(md, &mectx, hair); - - if (hair_next && hair_next != hair) { - /* If the modifier returned a new hair, release the old one. */ - if (hair != hair_input) { - BKE_id_free(nullptr, hair); - } - hair = hair_next; - } - } } return hair; diff --git a/source/blender/blenkernel/intern/image_partial_update.cc b/source/blender/blenkernel/intern/image_partial_update.cc index 7e187c2014e..876e5276e5a 100644 --- a/source/blender/blenkernel/intern/image_partial_update.cc +++ b/source/blender/blenkernel/intern/image_partial_update.cc @@ -23,8 +23,8 @@ * image that are changed. These areas are organized in chunks. Changes that happen over time are * organized in changesets. * - * A common usecase is to update GPUTexture for drawing where only that part is uploaded that only - * changed. + * A common use case is to update #GPUTexture for drawing where only that part is uploaded that + * only changed. * * Usage: * @@ -273,7 +273,8 @@ struct TileChangeset { const int previous_chunk_len = chunk_dirty_flags_.size(); chunk_dirty_flags_.resize(chunk_len); - /* Fast exit. When the changeset was already empty no need to re-init the chunk_validity. */ + /* Fast exit. When the changeset was already empty no need to + * re-initialize the chunk_validity. */ if (!has_dirty_chunks()) { return; } diff --git a/source/blender/blenkernel/intern/image_partial_update_test.cc b/source/blender/blenkernel/intern/image_partial_update_test.cc index 70aa51f7c98..bf12c27241e 100644 --- a/source/blender/blenkernel/intern/image_partial_update_test.cc +++ b/source/blender/blenkernel/intern/image_partial_update_test.cc @@ -70,7 +70,7 @@ class ImagePartialUpdateTest : public testing::Test { IMB_init(); bmain = BKE_main_new(); - /* Creating an image generates a mem-leak during tests. */ + /* Creating an image generates a memory-leak during tests. */ image = create_test_image(1024, 1024); image_tile = BKE_image_get_tile(image, 0); image_buffer = BKE_image_acquire_ibuf(image, nullptr, nullptr); diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c index d1375b1e5b5..5abe0f5e6be 100644 --- a/source/blender/blenkernel/intern/lib_override.c +++ b/source/blender/blenkernel/intern/lib_override.c @@ -211,6 +211,7 @@ void BKE_lib_override_library_free(struct IDOverrideLibrary **override, const bo } static ID *lib_override_library_create_from(Main *bmain, + Library *owner_library, ID *reference_id, const int lib_id_copy_flags) { @@ -227,6 +228,12 @@ static ID *lib_override_library_create_from(Main *bmain, } id_us_min(local_id); + /* TODO: Handle this properly in LIB_NO_MAIN case as well (i.e. resync case). Or offload to + * generic ID copy code? */ + if ((lib_id_copy_flags & LIB_ID_CREATE_NO_MAIN) == 0) { + local_id->lib = owner_library; + } + BKE_lib_override_library_init(local_id, reference_id); /* NOTE: From liboverride perspective (and RNA one), shape keys are considered as local embedded @@ -281,7 +288,7 @@ ID *BKE_lib_override_library_create_from_id(Main *bmain, BLI_assert(reference_id != NULL); BLI_assert(ID_IS_LINKED(reference_id)); - ID *local_id = lib_override_library_create_from(bmain, reference_id, 0); + ID *local_id = lib_override_library_create_from(bmain, NULL, reference_id, 0); /* We cannot allow automatic hierarchy resync on this ID, it is highly likely to generate a giant * mess in case there are a lot of hidden, non-instantiated, non-properly organized dependencies. * Ref T94650. */ @@ -320,6 +327,7 @@ ID *BKE_lib_override_library_create_from_id(Main *bmain, } bool BKE_lib_override_library_create_from_tag(Main *bmain, + Library *owner_library, const Library *reference_library, const bool do_no_main) { @@ -351,7 +359,7 @@ bool BKE_lib_override_library_create_from_tag(Main *bmain, * This requires extra care further down the resync process, * see: #BKE_lib_override_library_resync. */ reference_id->newid = lib_override_library_create_from( - bmain, reference_id, do_no_main ? LIB_ID_CREATE_NO_MAIN : 0); + bmain, owner_library, reference_id, do_no_main ? LIB_ID_CREATE_NO_MAIN : 0); if (reference_id->newid == NULL) { success = false; break; @@ -813,7 +821,10 @@ static void lib_override_overrides_group_tag(LibOverrideGroupTagData *data) lib_override_overrides_group_tag_recursive(data); } -static bool lib_override_library_create_do(Main *bmain, Scene *scene, ID *id_root) +static bool lib_override_library_create_do(Main *bmain, + Scene *scene, + Library *owner_library, + ID *id_root) { BKE_main_relations_create(bmain, 0); LibOverrideGroupTagData data = {.bmain = bmain, @@ -832,12 +843,13 @@ static bool lib_override_library_create_do(Main *bmain, Scene *scene, ID *id_roo BKE_main_relations_free(bmain); lib_override_group_tag_data_clear(&data); - return BKE_lib_override_library_create_from_tag(bmain, id_root->lib, false); + return BKE_lib_override_library_create_from_tag(bmain, owner_library, id_root->lib, false); } static void lib_override_library_create_post_process(Main *bmain, Scene *scene, ViewLayer *view_layer, + const Library *owner_library, ID *id_root, ID *id_reference, Collection *residual_storage, @@ -859,7 +871,8 @@ static void lib_override_library_create_post_process(Main *bmain, /* Instantiating the root collection or object should never be needed in resync case, since the * old override would be remapped to the new one. */ - if (!is_resync && id_root != NULL && id_root->newid != NULL && !ID_IS_LINKED(id_root->newid)) { + if (!is_resync && id_root != NULL && id_root->newid != NULL && + (!ID_IS_LINKED(id_root->newid) || id_root->newid->lib == owner_library)) { switch (GS(id_root->name)) { case ID_GR: { Object *ob_reference = id_reference != NULL && GS(id_reference->name) == ID_OB ? @@ -904,7 +917,7 @@ static void lib_override_library_create_post_process(Main *bmain, Collection *default_instantiating_collection = residual_storage; LISTBASE_FOREACH (Object *, ob, &bmain->objects) { Object *ob_new = (Object *)ob->id.newid; - if (ob_new == NULL || ID_IS_LINKED(ob_new)) { + if (ob_new == NULL || (ID_IS_LINKED(ob_new) && ob_new->id.lib != owner_library)) { continue; } @@ -967,6 +980,7 @@ static void lib_override_library_create_post_process(Main *bmain, bool BKE_lib_override_library_create(Main *bmain, Scene *scene, ViewLayer *view_layer, + Library *owner_library, ID *id_root, ID *id_reference, ID **r_id_root_override) @@ -975,7 +989,7 @@ bool BKE_lib_override_library_create(Main *bmain, *r_id_root_override = NULL; } - const bool success = lib_override_library_create_do(bmain, scene, id_root); + const bool success = lib_override_library_create_do(bmain, scene, owner_library, id_root); if (!success) { return success; @@ -986,7 +1000,7 @@ bool BKE_lib_override_library_create(Main *bmain, } lib_override_library_create_post_process( - bmain, scene, view_layer, id_root, id_reference, NULL, false); + bmain, scene, view_layer, owner_library, id_root, id_reference, NULL, false); /* Cleanup. */ BKE_main_id_newptr_and_tag_clear(bmain); @@ -1026,7 +1040,12 @@ bool BKE_lib_override_library_proxy_convert(Main *bmain, /* In some cases the instance collection of a proxy object may be local (see e.g. T83875). Not * sure this is a valid state, but for now just abort the overriding process. */ - if (!ID_IS_OVERRIDABLE_LIBRARY(id_root)) { + if (!ID_IS_OVERRIDABLE_LIBRARY_HIERARCHY(id_root)) { + if (ob_proxy->proxy != NULL) { + ob_proxy->proxy->proxy_from = NULL; + } + id_us_min((ID *)ob_proxy->proxy); + ob_proxy->proxy = ob_proxy->proxy_group = NULL; return false; } @@ -1044,18 +1063,19 @@ bool BKE_lib_override_library_proxy_convert(Main *bmain, DEG_id_tag_update(&ob_proxy->id, ID_RECALC_COPY_ON_WRITE); /* In case of proxy conversion, remap all local ID usages to linked IDs to their newly created - * overrides. + * overrides. Also do that for the IDs from the same lib as the proxy in case it is linked. * While this might not be 100% the desired behavior, it is likely to be the case most of the * time. Ref: T91711. */ ID *id_iter; FOREACH_MAIN_ID_BEGIN (bmain, id_iter) { - if (!ID_IS_LINKED(id_iter)) { + if (!ID_IS_LINKED(id_iter) || id_iter->lib == ob_proxy->id.lib) { id_iter->tag |= LIB_TAG_DOIT; } } FOREACH_MAIN_ID_END; - return BKE_lib_override_library_create(bmain, scene, view_layer, id_root, id_reference, NULL); + return BKE_lib_override_library_create( + bmain, scene, view_layer, ob_proxy->id.lib, id_root, id_reference, NULL); } static void lib_override_library_proxy_convert_do(Main *bmain, @@ -1105,18 +1125,24 @@ void BKE_lib_override_library_main_proxy_convert(Main *bmain, BlendFileReadRepor } LISTBASE_FOREACH (Object *, object, &bmain->objects) { - if (ID_IS_LINKED(object)) { - if (object->proxy != NULL) { - CLOG_WARN(&LOG, "Did not try to convert linked proxy object '%s'", object->id.name); - reports->count.linked_proxies++; - } - continue; - } - if (object->proxy_group != NULL || object->proxy != NULL) { - CLOG_WARN( - &LOG, "Proxy object '%s' failed to be converted to library override", object->id.name); + if (ID_IS_LINKED(object)) { + CLOG_WARN(&LOG, + "Linked proxy object '%s' from '%s' failed to be converted to library override", + object->id.name + 2, + object->id.lib->filepath); + } + else { + CLOG_WARN(&LOG, + "Proxy object '%s' failed to be converted to library override", + object->id.name + 2); + } reports->count.proxies_to_lib_overrides_failures++; + if (object->proxy != NULL) { + object->proxy->proxy_from = NULL; + } + id_us_min((ID *)object->proxy); + object->proxy = object->proxy_group = NULL; } } } @@ -1288,7 +1314,7 @@ static bool lib_override_library_resync(Main *bmain, * override IDs (including within the old overrides themselves, since those are tagged too * above). */ const bool success = BKE_lib_override_library_create_from_tag( - bmain, id_root_reference->lib, true); + bmain, NULL, id_root_reference->lib, true); if (!success) { return success; @@ -1502,6 +1528,7 @@ static bool lib_override_library_resync(Main *bmain, lib_override_library_create_post_process(bmain, scene, view_layer, + NULL, id_root_reference, id_root, override_resync_residual_storage, @@ -1926,7 +1953,7 @@ void BKE_lib_override_library_main_resync(Main *bmain, /* Essentially ensures that potentially new overrides of new objects will be instantiated. */ lib_override_library_create_post_process( - bmain, scene, view_layer, NULL, NULL, override_resync_residual_storage, true); + bmain, scene, view_layer, NULL, NULL, NULL, override_resync_residual_storage, true); if (BKE_collection_is_empty(override_resync_residual_storage)) { BKE_collection_delete(bmain, override_resync_residual_storage, true); diff --git a/source/blender/blenkernel/intern/mesh_merge.c b/source/blender/blenkernel/intern/mesh_merge.c index 134a1344f83..3c01d5a4a50 100644 --- a/source/blender/blenkernel/intern/mesh_merge.c +++ b/source/blender/blenkernel/intern/mesh_merge.c @@ -27,6 +27,7 @@ #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" +#include "BLI_bitmap.h" #include "BLI_edgehash.h" #include "BLI_ghash.h" #include "BLI_utildefines.h" @@ -351,6 +352,8 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh, &poly_map, &poly_map_mem, mesh->mpoly, mesh->mloop, totvert, totpoly, totloop); } /* done preparing for fast poly compare */ + BLI_bitmap *vert_tag = BLI_BITMAP_NEW(mesh->totvert, __func__); + mp = mesh->mpoly; mv = mesh->mvert; for (i = 0; i < totpoly; i++, mp++) { @@ -365,11 +368,11 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh, if (vtargetmap[ml->v] == -1) { all_vertices_merged = false; /* This will be used to check for poly using several time the same vert. */ - mv[ml->v].flag &= ~ME_VERT_TMP_TAG; + BLI_BITMAP_DISABLE(vert_tag, ml->v); } else { /* This will be used to check for poly using several time the same vert. */ - mv[vtargetmap[ml->v]].flag &= ~ME_VERT_TMP_TAG; + BLI_BITMAP_DISABLE(vert_tag, vtargetmap[ml->v]); } } @@ -457,8 +460,8 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh, #endif /* A loop is only valid if its matching edge is, * and it's not reusing a vertex already used by this poly. */ - if (LIKELY((newe[ml->e] != -1) && ((mv[mlv].flag & ME_VERT_TMP_TAG) == 0))) { - mv[mlv].flag |= ME_VERT_TMP_TAG; + if (LIKELY((newe[ml->e] != -1) && !BLI_BITMAP_TEST(vert_tag, mlv))) { + BLI_BITMAP_ENABLE(vert_tag, mlv); if (UNLIKELY(last_valid_ml != NULL && need_edge_from_last_valid_ml)) { /* We need to create a new edge between last valid loop and this one! */ @@ -644,6 +647,8 @@ Mesh *BKE_mesh_merge_verts(Mesh *mesh, MEM_freeN(oldl); MEM_freeN(oldp); + MEM_freeN(vert_tag); + BLI_edgehash_free(ehash, NULL); if (poly_map != NULL) { diff --git a/source/blender/blenkernel/intern/mesh_validate.c b/source/blender/blenkernel/intern/mesh_validate.c index 005c916b4e0..a5ba2767301 100644 --- a/source/blender/blenkernel/intern/mesh_validate.c +++ b/source/blender/blenkernel/intern/mesh_validate.c @@ -28,6 +28,7 @@ #include "CLG_log.h" +#include "BLI_bitmap.h" #include "DNA_mesh_types.h" #include "DNA_meshdata_types.h" #include "DNA_object_types.h" @@ -560,6 +561,8 @@ bool BKE_mesh_validate_arrays(Mesh *mesh, * so be sure to leave at most one poly per loop! */ { + BLI_bitmap *vert_tag = BLI_BITMAP_NEW(mesh->totvert, __func__); + SortPoly *sort_polys = MEM_callocN(sizeof(SortPoly) * totpoly, "mesh validate's sort_polys"); SortPoly *prev_sp, *sp = sort_polys; int prev_end; @@ -608,7 +611,7 @@ bool BKE_mesh_validate_arrays(Mesh *mesh, * so we have to ensure here all verts of current poly are cleared. */ for (j = 0, ml = &mloops[sp->loopstart]; j < mp->totloop; j++, ml++) { if (ml->v < totvert) { - mverts[ml->v].flag &= ~ME_VERT_TMP_TAG; + BLI_BITMAP_DISABLE(vert_tag, ml->v); } } @@ -619,12 +622,12 @@ bool BKE_mesh_validate_arrays(Mesh *mesh, PRINT_ERR("\tLoop %u has invalid vert reference (%u)", sp->loopstart + j, ml->v); sp->invalid = true; } - else if (mverts[ml->v].flag & ME_VERT_TMP_TAG) { + else if (BLI_BITMAP_TEST(vert_tag, ml->v)) { PRINT_ERR("\tPoly %u has duplicated vert reference at corner (%u)", i, j); sp->invalid = true; } else { - mverts[ml->v].flag |= ME_VERT_TMP_TAG; + BLI_BITMAP_ENABLE(vert_tag, ml->v); } *v = ml->v; } @@ -698,6 +701,8 @@ bool BKE_mesh_validate_arrays(Mesh *mesh, } } + MEM_freeN(vert_tag); + /* Second check pass, testing polys using the same verts. */ qsort(sort_polys, totpoly, sizeof(SortPoly), search_poly_cmp); sp = prev_sp = sort_polys; diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c index e1fd8ff45d1..bdf2568287b 100644 --- a/source/blender/blenkernel/intern/modifier.c +++ b/source/blender/blenkernel/intern/modifier.c @@ -1182,8 +1182,8 @@ void BKE_modifier_blend_write(BlendWriter *writer, ListBase *modbase) #if 0 CollisionModifierData *collmd = (CollisionModifierData *)md; - // TODO: CollisionModifier should use pointcache - // + have proper reset events before enabling this + /* TODO: CollisionModifier should use pointcache + * + have proper reset events before enabling this. */ writestruct(wd, DATA, MVert, collmd->numverts, collmd->x); writestruct(wd, DATA, MVert, collmd->numverts, collmd->xnew); writestruct(wd, DATA, MFace, collmd->numfaces, collmd->mfaces); diff --git a/source/blender/blenkernel/intern/node.cc b/source/blender/blenkernel/intern/node.cc index 40d0c24c9af..0677b1adb6d 100644 --- a/source/blender/blenkernel/intern/node.cc +++ b/source/blender/blenkernel/intern/node.cc @@ -4503,6 +4503,8 @@ static void registerCompositNodes() register_node_type_cmp_sepycca(); register_node_type_cmp_combycca(); register_node_type_cmp_premulkey(); + register_node_type_cmp_separate_xyz(); + register_node_type_cmp_combine_xyz(); register_node_type_cmp_diff_matte(); register_node_type_cmp_distance_matte(); diff --git a/source/blender/blenkernel/intern/object.cc b/source/blender/blenkernel/intern/object.cc index f9484205ef6..41221c0e444 100644 --- a/source/blender/blenkernel/intern/object.cc +++ b/source/blender/blenkernel/intern/object.cc @@ -1486,10 +1486,7 @@ bool BKE_object_support_modifier_type_check(const Object *ob, int modifier_type) } /* Only geometry objects should be able to get modifiers T25291. */ - if (ob->type == OB_HAIR) { - return (mti->modifyHair != nullptr) || (mti->flags & eModifierTypeFlag_AcceptsVertexCosOnly); - } - if (ELEM(ob->type, OB_POINTCLOUD, OB_VOLUME)) { + if (ELEM(ob->type, OB_POINTCLOUD, OB_VOLUME, OB_HAIR)) { return (mti->modifyGeometrySet != nullptr); } if (ELEM(ob->type, OB_MESH, OB_CURVE, OB_SURF, OB_FONT, OB_LATTICE)) { diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index 4dba13ce4c2..aa08a6494d1 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -4640,7 +4640,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, * account when subdividing for instance. */ pind.mesh = psys_in_edit_mode(sim->depsgraph, psys) ? NULL : - psys->hair_out_mesh; /* XXX(@sybren) EEK. */ + psys->hair_out_mesh; /* XXX(@sybren): EEK. */ init_particle_interpolation(sim->ob, psys, pa, &pind); do_particle_interpolation(psys, p, pa, t, &pind, state); diff --git a/source/blender/blenkernel/intern/subsurf_ccg.c b/source/blender/blenkernel/intern/subsurf_ccg.c index 9d66c354b54..2f63edebb67 100644 --- a/source/blender/blenkernel/intern/subsurf_ccg.c +++ b/source/blender/blenkernel/intern/subsurf_ccg.c @@ -580,7 +580,6 @@ static void ss_sync_ccg_from_derivedmesh(CCGSubSurf *ss, #endif MVert *mvert = dm->getVertArray(dm); MEdge *medge = dm->getEdgeArray(dm); - // MFace *mface = dm->getTessFaceArray(dm); /* UNUSED */ MVert *mv; MEdge *me; MLoop *mloop = dm->getLoopArray(dm), *ml; @@ -1129,44 +1128,6 @@ static void ccgDM_copyFinalEdgeArray(DerivedMesh *dm, MEdge *medge) } } -static void ccgDM_copyFinalFaceArray(DerivedMesh *dm, MFace *mface) -{ - CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm; - CCGSubSurf *ss = ccgdm->ss; - int index; - int totface; - int gridSize = ccgSubSurf_getGridSize(ss); - int edgeSize = ccgSubSurf_getEdgeSize(ss); - int i = 0; - DMFlagMat *faceFlags = ccgdm->faceFlags; - - totface = dm->getNumTessFaces(dm); - for (index = 0; index < totface; index++) { - CCGFace *f = ccgdm->faceMap[index].face; - int x, y, S, numVerts = ccgSubSurf_getFaceNumVerts(f); - /* keep types in sync with MFace, avoid many conversions */ - char flag = (faceFlags) ? faceFlags[index].flag : ME_SMOOTH; - short mat_nr = (faceFlags) ? faceFlags[index].mat_nr : 0; - - for (S = 0; S < numVerts; S++) { - for (y = 0; y < gridSize - 1; y++) { - for (x = 0; x < gridSize - 1; x++) { - MFace *mf = &mface[i]; - mf->v1 = getFaceIndex(ss, f, S, x + 0, y + 0, edgeSize, gridSize); - mf->v2 = getFaceIndex(ss, f, S, x + 0, y + 1, edgeSize, gridSize); - mf->v3 = getFaceIndex(ss, f, S, x + 1, y + 1, edgeSize, gridSize); - mf->v4 = getFaceIndex(ss, f, S, x + 1, y + 0, edgeSize, gridSize); - mf->mat_nr = mat_nr; - mf->flag = flag; - mf->edcode = 0; - - i++; - } - } - } - } -} - typedef struct CopyFinalLoopArrayData { CCGDerivedMesh *ccgdm; MLoop *mloop; @@ -1457,63 +1418,6 @@ static void *ccgDM_get_edge_data_layer(DerivedMesh *dm, int type) return DM_get_edge_data_layer(dm, type); } -static void *ccgDM_get_tessface_data_layer(DerivedMesh *dm, int type) -{ - if (type == CD_ORIGINDEX) { - /* create origindex on demand to save memory */ - int *origindex; - - /* Avoid re-creation if the layer exists already */ - origindex = DM_get_tessface_data_layer(dm, CD_ORIGINDEX); - if (origindex) { - return origindex; - } - - DM_add_tessface_layer(dm, CD_ORIGINDEX, CD_CALLOC, NULL); - origindex = DM_get_tessface_data_layer(dm, CD_ORIGINDEX); - - /* silly loop counting up */ - range_vn_i(origindex, dm->getNumTessFaces(dm), 0); - - return origindex; - } - - if (type == CD_TESSLOOPNORMAL) { - /* Create tessloopnormal on demand to save memory. */ - /* Note that since tessellated face corners are the same a loops in CCGDM, - * and since all faces have four loops/corners, we can simplify the code - * here by converting tessloopnormals from 'short (*)[4][3]' to 'short (*)[3]'. */ - short(*tlnors)[3]; - - /* Avoid re-creation if the layer exists already */ - tlnors = DM_get_tessface_data_layer(dm, CD_TESSLOOPNORMAL); - if (!tlnors) { - float(*lnors)[3]; - short(*tlnors_it)[3]; - const int numLoops = ccgDM_getNumLoops(dm); - int i; - - lnors = dm->getLoopDataArray(dm, CD_NORMAL); - if (!lnors) { - return NULL; - } - - DM_add_tessface_layer(dm, CD_TESSLOOPNORMAL, CD_CALLOC, NULL); - tlnors = tlnors_it = (short(*)[3])DM_get_tessface_data_layer(dm, CD_TESSLOOPNORMAL); - - /* With ccgdm, we have a simple one to one mapping between loops - * and tessellated face corners. */ - for (i = 0; i < numLoops; i++, tlnors_it++, lnors++) { - normal_float_to_short_v3(*tlnors_it, *lnors); - } - } - - return tlnors; - } - - return DM_get_tessface_data_layer(dm, type); -} - static void *ccgDM_get_poly_data_layer(DerivedMesh *dm, int type) { if (type == CD_ORIGINDEX) { @@ -1551,46 +1455,6 @@ static void *ccgDM_get_poly_data_layer(DerivedMesh *dm, int type) return DM_get_poly_data_layer(dm, type); } -static void *ccgDM_get_vert_data(DerivedMesh *dm, int index, int type) -{ - if (type == CD_ORIGINDEX) { - /* ensure creation of CD_ORIGINDEX layer */ - ccgDM_get_vert_data_layer(dm, type); - } - - return DM_get_vert_data(dm, index, type); -} - -static void *ccgDM_get_edge_data(DerivedMesh *dm, int index, int type) -{ - if (type == CD_ORIGINDEX) { - /* ensure creation of CD_ORIGINDEX layer */ - ccgDM_get_edge_data_layer(dm, type); - } - - return DM_get_edge_data(dm, index, type); -} - -static void *ccgDM_get_tessface_data(DerivedMesh *dm, int index, int type) -{ - if (ELEM(type, CD_ORIGINDEX, CD_TESSLOOPNORMAL)) { - /* ensure creation of CD_ORIGINDEX/CD_TESSLOOPNORMAL layers */ - ccgDM_get_tessface_data_layer(dm, type); - } - - return DM_get_tessface_data(dm, index, type); -} - -static void *ccgDM_get_poly_data(DerivedMesh *dm, int index, int type) -{ - if (type == CD_ORIGINDEX) { - /* ensure creation of CD_ORIGINDEX layer */ - ccgDM_get_tessface_data_layer(dm, type); - } - - return DM_get_poly_data(dm, index, type); -} - static int ccgDM_getNumGrids(DerivedMesh *dm) { CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm; @@ -1705,25 +1569,6 @@ static BLI_bitmap **ccgDM_getGridHidden(DerivedMesh *dm) return ccgdm->gridHidden; } -static const MeshElemMap *ccgDM_getPolyMap(Object *ob, DerivedMesh *dm) -{ - CCGDerivedMesh *ccgdm = (CCGDerivedMesh *)dm; - - if (!ccgdm->multires.mmd && !ccgdm->pmap && ob->type == OB_MESH) { - Mesh *me = ob->data; - - BKE_mesh_vert_poly_map_create(&ccgdm->pmap, - &ccgdm->pmap_mem, - me->mpoly, - me->mloop, - me->totvert, - me->totpoly, - me->totloop); - } - - return ccgdm->pmap; -} - /* WARNING! *MUST* be called in an 'loops_cache_rwlock' protected thread context! */ static void ccgDM_recalcLoopTri(DerivedMesh *dm) { @@ -1773,17 +1618,11 @@ static void set_default_ccgdm_callbacks(CCGDerivedMesh *ccgdm) ccgdm->dm.copyVertArray = ccgDM_copyFinalVertArray; ccgdm->dm.copyEdgeArray = ccgDM_copyFinalEdgeArray; - ccgdm->dm.copyTessFaceArray = ccgDM_copyFinalFaceArray; ccgdm->dm.copyLoopArray = ccgDM_copyFinalLoopArray; ccgdm->dm.copyPolyArray = ccgDM_copyFinalPolyArray; - ccgdm->dm.getVertData = ccgDM_get_vert_data; - ccgdm->dm.getEdgeData = ccgDM_get_edge_data; - ccgdm->dm.getTessFaceData = ccgDM_get_tessface_data; - ccgdm->dm.getPolyData = ccgDM_get_poly_data; ccgdm->dm.getVertDataArray = ccgDM_get_vert_data_layer; ccgdm->dm.getEdgeDataArray = ccgDM_get_edge_data_layer; - ccgdm->dm.getTessFaceDataArray = ccgDM_get_tessface_data_layer; ccgdm->dm.getPolyDataArray = ccgDM_get_poly_data_layer; ccgdm->dm.getNumGrids = ccgDM_getNumGrids; ccgdm->dm.getGridSize = ccgDM_getGridSize; @@ -1792,7 +1631,6 @@ static void set_default_ccgdm_callbacks(CCGDerivedMesh *ccgdm) ccgdm->dm.getGridKey = ccgDM_getGridKey; ccgdm->dm.getGridFlagMats = ccgDM_getGridFlagMats; ccgdm->dm.getGridHidden = ccgDM_getGridHidden; - ccgdm->dm.getPolyMap = ccgDM_getPolyMap; ccgdm->dm.recalcLoopTri = ccgDM_recalcLoopTri; @@ -1848,7 +1686,7 @@ static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm, int index; int i; int vertNum = 0, edgeNum = 0, faceNum = 0; - int *vertOrigIndex, *faceOrigIndex, *polyOrigIndex, *base_polyOrigIndex, *edgeOrigIndex; + int *vertOrigIndex, *polyOrigIndex, *base_polyOrigIndex, *edgeOrigIndex; short *edgeFlags = ccgdm->edgeFlags; DMFlagMat *faceFlags = ccgdm->faceFlags; int *polyidx = NULL; @@ -1884,7 +1722,6 @@ static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm, vertOrigIndex = DM_get_vert_data_layer(&ccgdm->dm, CD_ORIGINDEX); edgeOrigIndex = DM_get_edge_data_layer(&ccgdm->dm, CD_ORIGINDEX); - faceOrigIndex = DM_get_tessface_data_layer(&ccgdm->dm, CD_ORIGINDEX); polyOrigIndex = DM_get_poly_data_layer(&ccgdm->dm, CD_ORIGINDEX); has_edge_cd = ((ccgdm->dm.edgeData.totlayer - (edgeOrigIndex ? 1 : 0)) != 0); @@ -2006,12 +1843,6 @@ static void set_ccgdm_all_geometry(CCGDerivedMesh *ccgdm, /* Copy over poly data, e.g. #CD_FACEMAP. */ CustomData_copy_data(&dm->polyData, &ccgdm->dm.polyData, origIndex, faceNum, 1); - /* Set original index data. */ - if (faceOrigIndex) { - /* reference the index in 'polyOrigIndex' */ - *faceOrigIndex = faceNum; - faceOrigIndex++; - } if (polyOrigIndex) { *polyOrigIndex = base_polyOrigIndex ? base_polyOrigIndex[origIndex] : origIndex; polyOrigIndex++; diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c index 3800fc58a5b..d61c6c015f6 100644 --- a/source/blender/blenlib/intern/math_geom.c +++ b/source/blender/blenlib/intern/math_geom.c @@ -3299,8 +3299,8 @@ static bool point_in_slice(const float p[3], return (h >= 0.0f && h <= 1.0f); } -/* adult sister defining the slice planes by the origin and the normal - * NOTE |normal| may not be 1 but defining the thickness of the slice */ +/* Adult sister defining the slice planes by the origin and the normal. + * NOTE: |normal| may not be 1 but defining the thickness of the slice. */ static bool point_in_slice_as(const float p[3], const float origin[3], const float normal[3]) { float h, rp[3]; diff --git a/source/blender/blenlib/intern/math_interp.c b/source/blender/blenlib/intern/math_interp.c index 7225ca5fc94..fed330aa2f0 100644 --- a/source/blender/blenlib/intern/math_interp.c +++ b/source/blender/blenlib/intern/math_interp.c @@ -706,9 +706,9 @@ void BLI_ewa_filter(const int width, } } - /* d should hopefully never be zero anymore */ + /* `d` should hopefully never be zero anymore. */ d = 1.0f / d; mul_v3_fl(result, d); - /* clipping can be ignored if alpha used, texr->trgba[3] already includes filtered edge */ + /* Clipping can be ignored if alpha used, `texr->trgba[3]` already includes filtered edge. */ result[3] = use_alpha ? result[3] * d : 1.0f; } diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h index c4c3b42cb63..066b180dcc9 100644 --- a/source/blender/blenloader/BLO_readfile.h +++ b/source/blender/blenloader/BLO_readfile.h @@ -117,8 +117,6 @@ typedef struct BlendFileReadReport { /* Number of root override IDs that were resynced. */ int resynced_lib_overrides; - /* Number of (non-converted) linked proxies. */ - int linked_proxies; /* Number of proxies converted to library overrides. */ int proxies_to_lib_overrides_success; /* Number of proxies that failed to convert to library overrides. */ diff --git a/source/blender/blenloader/CMakeLists.txt b/source/blender/blenloader/CMakeLists.txt index 245514d4977..1ff713160df 100644 --- a/source/blender/blenloader/CMakeLists.txt +++ b/source/blender/blenloader/CMakeLists.txt @@ -86,10 +86,6 @@ if(WITH_BUILDINFO) add_definitions(-DWITH_BUILDINFO) endif() -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() - if(WITH_CODEC_FFMPEG) add_definitions(-DWITH_FFMPEG) endif() diff --git a/source/blender/blentranslation/BLT_translation.h b/source/blender/blentranslation/BLT_translation.h index 21296143226..8785eadf5f1 100644 --- a/source/blender/blentranslation/BLT_translation.h +++ b/source/blender/blentranslation/BLT_translation.h @@ -55,24 +55,14 @@ bool BLT_lang_is_ime_supported(void); #define N_(msgid) msgid #define CTX_N_(context, msgid) msgid -/* Those macros should be used everywhere in UI code. */ -#ifdef WITH_INTERNATIONAL +/* These macros should be used everywhere in UI code. */ /*# define _(msgid) BLT_gettext(msgid) */ -# define IFACE_(msgid) BLT_translate_do_iface(NULL, msgid) -# define TIP_(msgid) BLT_translate_do_tooltip(NULL, msgid) -# define DATA_(msgid) BLT_translate_do_new_dataname(NULL, msgid) -# define CTX_IFACE_(context, msgid) BLT_translate_do_iface(context, msgid) -# define CTX_TIP_(context, msgid) BLT_translate_do_tooltip(context, msgid) -# define CTX_DATA_(context, msgid) BLT_translate_do_new_dataname(context, msgid) -#else -/*# define _(msgid) msgid */ -# define IFACE_(msgid) msgid -# define TIP_(msgid) msgid -# define DATA_(msgid) msgid -# define CTX_IFACE_(context, msgid) ((void)(0 ? (context) : 0), msgid) -# define CTX_TIP_(context, msgid) ((void)(0 ? (context) : 0), msgid) -# define CTX_DATA_(context, msgid) ((void)(0 ? (context) : 0), msgid) -#endif +#define IFACE_(msgid) BLT_translate_do_iface(NULL, msgid) +#define TIP_(msgid) BLT_translate_do_tooltip(NULL, msgid) +#define DATA_(msgid) BLT_translate_do_new_dataname(NULL, msgid) +#define CTX_IFACE_(context, msgid) BLT_translate_do_iface(context, msgid) +#define CTX_TIP_(context, msgid) BLT_translate_do_tooltip(context, msgid) +#define CTX_DATA_(context, msgid) BLT_translate_do_new_dataname(context, msgid) /* Helper macro, when we want to define a same msgid for multiple msgctxt... * Does nothing in C, but is "parsed" by our i18n py tools. diff --git a/source/blender/bmesh/CMakeLists.txt b/source/blender/bmesh/CMakeLists.txt index e2ed005cf9e..a61327238fe 100644 --- a/source/blender/bmesh/CMakeLists.txt +++ b/source/blender/bmesh/CMakeLists.txt @@ -207,10 +207,6 @@ if(WITH_BULLET) add_definitions(-DWITH_BULLET) endif() -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() - if(WITH_FREESTYLE) add_definitions(-DWITH_FREESTYLE) endif() diff --git a/source/blender/compositor/CMakeLists.txt b/source/blender/compositor/CMakeLists.txt index b9b365a3175..2f473ef2945 100644 --- a/source/blender/compositor/CMakeLists.txt +++ b/source/blender/compositor/CMakeLists.txt @@ -274,10 +274,14 @@ set(SRC # converter nodes nodes/COM_CombineColorNode.cc nodes/COM_CombineColorNode.h + nodes/COM_CombineXYZNode.cc + nodes/COM_CombineXYZNode.h nodes/COM_IDMaskNode.cc nodes/COM_IDMaskNode.h nodes/COM_SeparateColorNode.cc nodes/COM_SeparateColorNode.h + nodes/COM_SeparateXYZNode.cc + nodes/COM_SeparateXYZNode.h nodes/COM_MapRangeNode.cc nodes/COM_MapRangeNode.h @@ -631,10 +635,6 @@ list(APPEND SRC unset(GENSRC) unset(GENSRC_DIR) -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() - if(WITH_OPENIMAGEDENOISE) add_definitions(-DWITH_OPENIMAGEDENOISE) add_definitions(-DOIDN_STATIC_LIB) diff --git a/source/blender/compositor/intern/COM_Converter.cc b/source/blender/compositor/intern/COM_Converter.cc index 6cf6c698a2f..d0b3ae74446 100644 --- a/source/blender/compositor/intern/COM_Converter.cc +++ b/source/blender/compositor/intern/COM_Converter.cc @@ -44,6 +44,7 @@ #include "COM_ColorSpillNode.h" #include "COM_ColorToBWNode.h" #include "COM_CombineColorNode.h" +#include "COM_CombineXYZNode.h" #include "COM_CompositorNode.h" #include "COM_ConvertAlphaNode.h" #include "COM_ConvertColorSpaceNode.h" @@ -96,6 +97,7 @@ #include "COM_ScaleOperation.h" #include "COM_SceneTimeNode.h" #include "COM_SeparateColorNode.h" +#include "COM_SeparateXYZNode.h" #include "COM_SetAlphaNode.h" #include "COM_SetValueOperation.h" #include "COM_SplitViewerNode.h" @@ -434,6 +436,12 @@ Node *COM_convert_bnode(bNode *b_node) case CMP_NODE_CONVERT_COLOR_SPACE: node = new ConvertColorSpaceNode(b_node); break; + case CMP_NODE_SEPARATE_XYZ: + node = new SeparateXYZNode(b_node); + break; + case CMP_NODE_COMBINE_XYZ: + node = new CombineXYZNode(b_node); + break; } return node; } diff --git a/source/blender/compositor/nodes/COM_CombineXYZNode.cc b/source/blender/compositor/nodes/COM_CombineXYZNode.cc new file mode 100644 index 00000000000..2b71b94e192 --- /dev/null +++ b/source/blender/compositor/nodes/COM_CombineXYZNode.cc @@ -0,0 +1,55 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright 2021, Blender Foundation. + */ + +#include "COM_CombineXYZNode.h" + +#include "COM_ConvertOperation.h" + +namespace blender::compositor { + +CombineXYZNode::CombineXYZNode(bNode *editor_node) : Node(editor_node) +{ +} + +void CombineXYZNode::convert_to_operations(NodeConverter &converter, + const CompositorContext &UNUSED(context)) const +{ + NodeInput *input_x_socket = this->get_input_socket(0); + NodeInput *input_y_socket = this->get_input_socket(1); + NodeInput *input_z_socket = this->get_input_socket(2); + NodeOutput *output_socket = this->get_output_socket(0); + + CombineChannelsOperation *operation = new CombineChannelsOperation(); + if (input_x_socket->is_linked()) { + operation->set_canvas_input_index(0); + } + else if (input_y_socket->is_linked()) { + operation->set_canvas_input_index(1); + } + else { + operation->set_canvas_input_index(2); + } + converter.add_operation(operation); + + converter.map_input_socket(input_x_socket, operation->get_input_socket(0)); + converter.map_input_socket(input_y_socket, operation->get_input_socket(1)); + converter.map_input_socket(input_z_socket, operation->get_input_socket(2)); + converter.map_output_socket(output_socket, operation->get_output_socket()); +} + +} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_CombineXYZNode.h b/source/blender/compositor/nodes/COM_CombineXYZNode.h new file mode 100644 index 00000000000..c3bb69b03ed --- /dev/null +++ b/source/blender/compositor/nodes/COM_CombineXYZNode.h @@ -0,0 +1,36 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright 2021, Blender Foundation. + */ + +#pragma once + +#include "COM_Node.h" + +namespace blender::compositor { + +/** + * \brief SeparateXYZNode + * \ingroup Node + */ +class CombineXYZNode : public Node { + public: + CombineXYZNode(bNode *editor_node); + void convert_to_operations(NodeConverter &converter, + const CompositorContext &context) const override; +}; + +} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_SeparateXYZNode.cc b/source/blender/compositor/nodes/COM_SeparateXYZNode.cc new file mode 100644 index 00000000000..749116d6217 --- /dev/null +++ b/source/blender/compositor/nodes/COM_SeparateXYZNode.cc @@ -0,0 +1,63 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright 2021, Blender Foundation. + */ + +#include "COM_SeparateXYZNode.h" + +#include "COM_ConvertOperation.h" + +namespace blender::compositor { + +SeparateXYZNode::SeparateXYZNode(bNode *editor_node) : Node(editor_node) +{ + /* pass */ +} + +void SeparateXYZNode::convert_to_operations(NodeConverter &converter, + const CompositorContext &UNUSED(context)) const +{ + NodeInput *vector_socket = this->get_input_socket(0); + NodeOutput *output_x_socket = this->get_output_socket(0); + NodeOutput *output_y_socket = this->get_output_socket(1); + NodeOutput *output_z_socket = this->get_output_socket(2); + + { + SeparateChannelOperation *operation = new SeparateChannelOperation(); + operation->set_channel(0); + converter.add_operation(operation); + converter.map_input_socket(vector_socket, operation->get_input_socket(0)); + converter.map_output_socket(output_x_socket, operation->get_output_socket(0)); + } + + { + SeparateChannelOperation *operation = new SeparateChannelOperation(); + operation->set_channel(1); + converter.add_operation(operation); + converter.map_input_socket(vector_socket, operation->get_input_socket(0)); + converter.map_output_socket(output_y_socket, operation->get_output_socket(0)); + } + + { + SeparateChannelOperation *operation = new SeparateChannelOperation(); + operation->set_channel(2); + converter.add_operation(operation); + converter.map_input_socket(vector_socket, operation->get_input_socket(0)); + converter.map_output_socket(output_z_socket, operation->get_output_socket(0)); + } +} + +} // namespace blender::compositor diff --git a/source/blender/compositor/nodes/COM_SeparateXYZNode.h b/source/blender/compositor/nodes/COM_SeparateXYZNode.h new file mode 100644 index 00000000000..1efa017d9e3 --- /dev/null +++ b/source/blender/compositor/nodes/COM_SeparateXYZNode.h @@ -0,0 +1,36 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * Copyright 2021, Blender Foundation. + */ + +#pragma once + +#include "COM_Node.h" + +namespace blender::compositor { + +/** + * \brief SeparateXYZNode + * \ingroup Node + */ +class SeparateXYZNode : public Node { + public: + SeparateXYZNode(bNode *editor_node); + void convert_to_operations(NodeConverter &converter, + const CompositorContext &context) const override; +}; + +} // namespace blender::compositor diff --git a/source/blender/draw/engines/eevee/eevee_depth_of_field.c b/source/blender/draw/engines/eevee/eevee_depth_of_field.c index 4748323d6a7..d0c0635a1fb 100644 --- a/source/blender/draw/engines/eevee/eevee_depth_of_field.c +++ b/source/blender/draw/engines/eevee/eevee_depth_of_field.c @@ -251,7 +251,7 @@ int EEVEE_depth_of_field_init(EEVEE_ViewLayerData *UNUSED(sldata), effects->dof_coc_params[1] = -aperture * fabsf(focal_len_scaled / (focus_dist - focal_len_scaled)); - /* FIXME(fclem) This is broken for vertically fit sensor. */ + /* FIXME(@fclem): This is broken for vertically fit sensor. */ effects->dof_coc_params[1] *= viewport_size[0] / sensor_scaled; if ((scene_eval->eevee.flag & SCE_EEVEE_DOF_JITTER) != 0) { @@ -625,7 +625,7 @@ static void dof_reduce_pass_init(EEVEE_FramebufferList *fbl, } if (txl->dof_reduced_color) { - /* TODO(fclem) In the future, we need to check if mip_count did not change. + /* TODO(@fclem): In the future, we need to check if mip_count did not change. * For now it's ok as we always define all mip level. */ if (res[0] != GPU_texture_width(txl->dof_reduced_color) || res[1] != GPU_texture_width(txl->dof_reduced_color)) { @@ -642,7 +642,8 @@ static void dof_reduce_pass_init(EEVEE_FramebufferList *fbl, txl->dof_reduced_coc = GPU_texture_create_2d( "dof_reduced_coc", UNPACK2(res), mip_count, GPU_R16F, NULL); - /* TODO(fclem) Remove once we have immutable storage or when mips are generated on creation. */ + /* TODO(@fclem): Remove once we have immutable storage or when mips are generated on creation. + */ GPU_texture_generate_mipmap(txl->dof_reduced_color); GPU_texture_generate_mipmap(txl->dof_reduced_coc); } diff --git a/source/blender/draw/engines/eevee/eevee_lightprobes.c b/source/blender/draw/engines/eevee/eevee_lightprobes.c index c51fc18a406..c7a8d2cc001 100644 --- a/source/blender/draw/engines/eevee/eevee_lightprobes.c +++ b/source/blender/draw/engines/eevee/eevee_lightprobes.c @@ -1077,8 +1077,8 @@ void EEVEE_lightbake_filter_diffuse(EEVEE_ViewLayerData *sldata, pinfo->intensity_fac = intensity; - /* find cell position on the virtual 3D texture */ - /* NOTE : Keep in sync with load_irradiance_cell() */ + /* Find cell position on the virtual 3D texture. */ + /* NOTE: Keep in sync with `load_irradiance_cell()`. */ #if defined(IRRADIANCE_SH_L2) int size[2] = {3, 3}; #elif defined(IRRADIANCE_HL2) diff --git a/source/blender/draw/engines/eevee/eevee_render.c b/source/blender/draw/engines/eevee/eevee_render.c index 9e7a67060da..e4e7f6fa4e3 100644 --- a/source/blender/draw/engines/eevee/eevee_render.c +++ b/source/blender/draw/engines/eevee/eevee_render.c @@ -517,8 +517,7 @@ static void eevee_render_draw_background(EEVEE_Data *vedata) EEVEE_PassList *psl = vedata->psl; /* Prevent background to write to data buffers. - * NOTE : This also make sure the textures are bound - * to the right double buffer. */ + * NOTE: This also make sure the textures are bound to the right double buffer. */ GPU_framebuffer_ensure_config(&fbl->main_fb, {GPU_ATTACHMENT_LEAVE, GPU_ATTACHMENT_LEAVE, diff --git a/source/blender/draw/engines/eevee/eevee_subsurface.c b/source/blender/draw/engines/eevee/eevee_subsurface.c index 48c24d138e6..81d9d560320 100644 --- a/source/blender/draw/engines/eevee/eevee_subsurface.c +++ b/source/blender/draw/engines/eevee/eevee_subsurface.c @@ -49,7 +49,7 @@ void EEVEE_subsurface_draw_init(EEVEE_ViewLayerData *sldata, EEVEE_Data *vedata) const int fs_size[2] = {(int)viewport_size[0], (int)viewport_size[1]}; if (effects->enabled_effects & EFFECT_SSS) { - /* NOTE : we need another stencil because the stencil buffer is on the same texture + /* NOTE: we need another stencil because the stencil buffer is on the same texture * as the depth buffer we are sampling from. This could be avoided if the stencil is * a separate texture but that needs OpenGL 4.4 or ARB_texture_stencil8. * OR OpenGL 4.3 / ARB_ES3_compatibility if using a render-buffer instead. */ diff --git a/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl b/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl index 1061b2f91a2..1c7ef775ac2 100644 --- a/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/ambient_occlusion_lib.glsl @@ -56,7 +56,7 @@ vec2 get_ao_noise(void) { vec2 noise = texelfetch_noise_tex(gl_FragCoord.xy).xy; /* Decorrelate noise from AA. */ - /* TODO(fclem) we should use a more general approach for more random number dimensions. */ + /* TODO(@fclem): we should use a more general approach for more random number dimensions. */ noise = fract(noise * 6.1803402007); return noise; } diff --git a/source/blender/draw/engines/eevee/shaders/closure_eval_diffuse_lib.glsl b/source/blender/draw/engines/eevee/shaders/closure_eval_diffuse_lib.glsl index 4f9791ac95f..5bf20fe6979 100644 --- a/source/blender/draw/engines/eevee/shaders/closure_eval_diffuse_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/closure_eval_diffuse_lib.glsl @@ -43,7 +43,7 @@ void closure_Diffuse_light_eval(ClosureInputDiffuse cl_in, inout ClosureOutputDiffuse cl_out) { float radiance = light_diffuse(light.data, cl_in.N, cl_common.V, light.L); - /* TODO(fclem) We could try to shadow lights that are shadowless with the ambient_occlusion + /* TODO(@fclem): We could try to shadow lights that are shadowless with the ambient_occlusion * factor here. */ cl_out.radiance += light.data.l_color * (light.data.l_diff * light.vis * light.contact_shadow * radiance); diff --git a/source/blender/draw/engines/eevee/shaders/closure_eval_glossy_lib.glsl b/source/blender/draw/engines/eevee/shaders/closure_eval_glossy_lib.glsl index 00d265a48b0..584aacc9e19 100644 --- a/source/blender/draw/engines/eevee/shaders/closure_eval_glossy_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/closure_eval_glossy_lib.glsl @@ -63,7 +63,7 @@ ClosureEvalGlossy closure_Glossy_eval_init(inout ClosureInputGlossy cl_in, /* The brdf split sum LUT is applied after the radiance accumulation. * Correct the LTC so that its energy is constant. */ - /* TODO(fclem) Optimize this so that only one scale factor is stored. */ + /* TODO(@fclem): Optimize this so that only one scale factor is stored. */ vec4 ltc_brdf = texture(utilTex, vec3(lut_uv, LTC_BRDF_LAYER)).barg; vec2 split_sum_brdf = ltc_brdf.zw; cl_eval.ltc_brdf_scale = (ltc_brdf.x + ltc_brdf.y) / (split_sum_brdf.x + split_sum_brdf.y); diff --git a/source/blender/draw/engines/eevee/shaders/effect_dof_gather_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_dof_gather_frag.glsl index db9ae0f7034..f5c45d147e6 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_dof_gather_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_dof_gather_frag.glsl @@ -52,7 +52,7 @@ const float unit_ring_radius = 1.0 / float(gather_ring_count); const float unit_sample_radius = 1.0 / float(gather_ring_count + 0.5); const float large_kernel_radius = 0.5 + float(gather_ring_count); const float smaller_kernel_radius = 0.5 + float(gather_ring_count - gather_density_change_ring); -/* NOTE(fclem) the bias is reducing issues with density change visible transition. */ +/* NOTE(@fclem): the bias is reducing issues with density change visible transition. */ const float radius_downscale_factor = smaller_kernel_radius / large_kernel_radius; const int change_density_at_ring = (gather_ring_count - gather_density_change_ring + 1); const float coc_radius_error = 2.0; @@ -83,7 +83,7 @@ void dof_gather_init(float base_radius, #endif center_co = gl_FragCoord.xy + jitter_ofs * base_radius * unit_sample_radius; - /* TODO(fclem) Seems like the default lod selection is too big. Bias to avoid blocky moving + /* TODO(@fclem): Seems like the default lod selection is too big. Bias to avoid blocky moving * out of focus shapes. */ const float lod_bias = -2.0; lod = max(floor(log2(base_radius * unit_sample_radius) + 0.5) + lod_bias, 0.0); @@ -111,7 +111,7 @@ void dof_gather_accumulator(float base_radius, * a ring. So we need to compensate for fast gather that does not check CoC intersection. */ base_radius += (0.5 - noise.x) * 1.5 * unit_ring_radius * base_radius; } - /* TODO(fclem) another seed? For now Cranly-Partterson rotation with golden ratio. */ + /* TODO(@fclem): another seed? For now Cranly-Partterson rotation with golden ratio. */ noise.x = fract(noise.x + 0.61803398875); float lod, isect_mul; @@ -172,7 +172,7 @@ void dof_gather_accumulator(float base_radius, } #ifdef DOF_FOREGROUND_PASS /* Reduce issue with closer foreground over distant foreground. */ - /* TODO(fclem) this seems to not be completely correct as the issue remains. */ + /* TODO(@fclem): This seems to not be completely correct as the issue remains. */ float ring_area = (sqr(float(ring) + 0.5 + coc_radius_error) - sqr(float(ring) - 0.5 + coc_radius_error)) * sqr(base_radius * unit_sample_radius); diff --git a/source/blender/draw/engines/eevee/shaders/effect_dof_lib.glsl b/source/blender/draw/engines/eevee/shaders/effect_dof_lib.glsl index e5b68637563..e288e1a55ea 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_dof_lib.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_dof_lib.glsl @@ -66,7 +66,7 @@ float dof_hdr_color_weight(vec4 color) { /* From UE4. Very fast "luma" weighting. */ float luma = (color.g * 2.0) + (color.r + color.b); - /* TODO(fclem) Pass correct exposure. */ + /* TODO(@fclem): Pass correct exposure. */ const float exposure = 1.0; return 1.0 / (luma * exposure + 4.0); } @@ -92,7 +92,7 @@ vec4 dof_downsample_bilateral_coc_weights(vec4 cocs) { float chosen_coc = dof_coc_select(cocs); - const float scale = 4.0; /* TODO(fclem) revisit. */ + const float scale = 4.0; /* TODO(@fclem): revisit. */ /* NOTE: The difference between the cocs should be inside a abs() function, * but we follow UE4 implementation to improve how dithered transparency looks (see slide 19). */ return saturate(1.0 - (chosen_coc - cocs) * scale); @@ -373,7 +373,7 @@ void dof_gather_accumulate_sample_pair(DofGatherData pair_data[2], #if 0 const float mirroring_threshold = -layer_threshold - layer_offset; - /* TODO(fclem) Promote to parameter? dither with Noise? */ + /* TODO(@fclem): Promote to parameter? dither with Noise? */ const float mirroring_min_distance = 15.0; if (pair_data[0].coc < mirroring_threshold && (pair_data[1].coc - mirroring_min_distance) > pair_data[0].coc) { @@ -487,7 +487,8 @@ void dof_gather_accumulate_sample_ring(DofGatherData ring_data, } } -/* FIXME(fclem) Seems to be wrong since it needs ringcount+1 as input for slightfocus gather. */ +/* FIXME(@fclem): Seems to be wrong since it needs `ringcount + 1` as input for slightfocus gather. + */ int dof_gather_total_sample_count(const int ring_count, const int ring_density) { return (ring_count * ring_count - ring_count) * ring_density + 1; diff --git a/source/blender/draw/engines/eevee/shaders/effect_dof_scatter_vert.glsl b/source/blender/draw/engines/eevee/shaders/effect_dof_scatter_vert.glsl index f349806d37e..59564890d7e 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_dof_scatter_vert.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_dof_scatter_vert.glsl @@ -25,7 +25,8 @@ flat out float spritesize; /* Load 4 Circle of confusion values. texel_co is centered around the 4 taps. */ vec4 fetch_cocs(vec2 texel_co) { - /* TODO(fclem) The textureGather(sampler, co, comp) variant isn't here on some implementations. + /* TODO(@fclem): The `textureGather(sampler, co, comp)` variant isn't here on some + * implementations. */ #if 0 // GPU_ARB_texture_gather vec2 uvs = texel_co / vec2(textureSize(cocBuffer, 0)); diff --git a/source/blender/draw/engines/eevee/shaders/effect_gtao_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_gtao_frag.glsl index 70f1e9f1e66..85f8a12aa88 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_gtao_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_gtao_frag.glsl @@ -45,7 +45,7 @@ vec3 view_position_derivative_from_depth(vec2 uvs, vec2 ofs, vec3 vP, float dept } } -/* TODO(fclem) port to a common place for other effects to use. */ +/* TODO(@fclem): port to a common place for other effects to use. */ bool reconstruct_view_position_and_normal_from_depth(vec2 uvs, out vec3 vP, out vec3 vNg) { vec2 texel_size = vec2(abs(dFdx(uvs.x)), abs(dFdy(uvs.y))); diff --git a/source/blender/draw/engines/eevee/shaders/effect_reflection_trace_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_reflection_trace_frag.glsl index 2f1efd588f7..f4ff28eaee4 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_reflection_trace_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_reflection_trace_frag.glsl @@ -31,7 +31,7 @@ void main() { vec4 rand = texelfetch_noise_tex(gl_FragCoord.xy); /* Decorrelate from AA. */ - /* TODO(fclem) we should use a more general approach for more random number dimensions. */ + /* TODO(@fclem): we should use a more general approach for more random number dimensions. */ vec2 random_px = floor(fract(rand.xy * 2.2074408460575947536) * 1.99999) - 0.5; rand.xy = fract(rand.xy * 3.2471795724474602596); diff --git a/source/blender/draw/engines/eevee/shaders/effect_translucency_frag.glsl b/source/blender/draw/engines/eevee/shaders/effect_translucency_frag.glsl index ee48c468630..ba90f5ae531 100644 --- a/source/blender/draw/engines/eevee/shaders/effect_translucency_frag.glsl +++ b/source/blender/draw/engines/eevee/shaders/effect_translucency_frag.glsl @@ -212,7 +212,7 @@ vec3 view_position_derivative_from_depth(vec2 uvs, vec2 ofs, vec3 vP, float dept } } -/* TODO(fclem) port to a common place for other effects to use. */ +/* TODO(@fclem): port to a common place for other effects to use. */ bool reconstruct_view_position_and_normal_from_depth(vec2 uvs, out vec3 vP, out vec3 vNg) { vec2 texel_size = vec2(abs(dFdx(uvs.x)), abs(dFdy(uvs.y))); diff --git a/source/blender/draw/engines/gpencil/gpencil_draw_data.c b/source/blender/draw/engines/gpencil/gpencil_draw_data.c index 8aba1090b58..5a79dfc2663 100644 --- a/source/blender/draw/engines/gpencil/gpencil_draw_data.c +++ b/source/blender/draw/engines/gpencil/gpencil_draw_data.c @@ -472,7 +472,7 @@ GPENCIL_ViewLayerData *GPENCIL_view_layer_data_ensure(void) GPENCIL_ViewLayerData **vldata = (GPENCIL_ViewLayerData **)DRW_view_layer_engine_data_ensure( &draw_engine_gpencil_type, gpencil_view_layer_data_free); - /* NOTE(fclem) Putting this stuff in viewlayer means it is shared by all viewports. + /* NOTE(&fclem): Putting this stuff in viewlayer means it is shared by all viewports. * For now it is ok, but in the future, it could become a problem if we implement * the caching system. */ if (*vldata == NULL) { diff --git a/source/blender/draw/engines/gpencil/gpencil_engine.c b/source/blender/draw/engines/gpencil/gpencil_engine.c index 9bc340a2786..dfa0d350485 100644 --- a/source/blender/draw/engines/gpencil/gpencil_engine.c +++ b/source/blender/draw/engines/gpencil/gpencil_engine.c @@ -788,7 +788,7 @@ static void gpencil_draw_mask(GPENCIL_Data *vedata, GPENCIL_tObject *ob, GPENCIL const float clear_col[4] = {1.0f, 1.0f, 1.0f, 1.0f}; float clear_depth = ob->is_drawmode3d ? 1.0f : 0.0f; bool inverted = false; - /* OPTI(fclem) we could optimize by only clearing if the new mask_bits does not contain all + /* OPTI(@fclem): we could optimize by only clearing if the new mask_bits does not contain all * the masks already rendered in the buffer, and drawing only the layers not already drawn. */ bool cleared = false; diff --git a/source/blender/draw/engines/image/image_drawing_mode.hh b/source/blender/draw/engines/image/image_drawing_mode.hh index 4cb0023ccb9..3be34ef6acb 100644 --- a/source/blender/draw/engines/image/image_drawing_mode.hh +++ b/source/blender/draw/engines/image/image_drawing_mode.hh @@ -207,7 +207,7 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD IMAGE_InstanceData &instance_data) const { while (iterator.get_next_change() == ePartialUpdateIterResult::ChangeAvailable) { - /* Quick exit when tile_buffer isn't availble. */ + /* Quick exit when tile_buffer isn't available. */ if (iterator.tile_data.tile_buffer == nullptr) { continue; } @@ -227,8 +227,7 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD GPUTexture *texture = info.texture; const float texture_width = GPU_texture_width(texture); const float texture_height = GPU_texture_height(texture); - // TODO - // early bound check. + /* TODO: early bound check. */ ImageTileWrapper tile_accessor(iterator.tile_data.tile); float tile_offset_x = static_cast<float>(tile_accessor.get_tile_x_offset()); float tile_offset_y = static_cast<float>(tile_accessor.get_tile_y_offset()); @@ -253,9 +252,9 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD if (!region_overlap) { continue; } - // convert the overlapping region to texel space and to ss_pixel space... - // TODO: first convert to ss_pixel space as integer based. and from there go back to texel - // space. But perhaps this isn't needed and we could use an extraction offset somehow. + /* Convert the overlapping region to texel space and to ss_pixel space... + * TODO: first convert to ss_pixel space as integer based. and from there go back to texel + * space. But perhaps this isn't needed and we could use an extraction offset somehow. */ rcti gpu_texture_region_to_update; BLI_rcti_init(&gpu_texture_region_to_update, floor((changed_overlapping_region_in_uv_space.xmin - info.uv_bounds.xmin) * @@ -275,8 +274,8 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD ceil((changed_overlapping_region_in_uv_space.ymin - tile_offset_y) * tile_height), ceil((changed_overlapping_region_in_uv_space.ymax - tile_offset_y) * tile_height)); - // Create an image buffer with a size - // extract and scale into an imbuf + /* Create an image buffer with a size. + * Extract and scale into an imbuf. */ const int texture_region_width = BLI_rcti_size_x(&gpu_texture_region_to_update); const int texture_region_height = BLI_rcti_size_y(&gpu_texture_region_to_update); @@ -437,17 +436,17 @@ template<typename TextureMethod> class ScreenSpaceDrawingMode : public AbstractD instance_data->partial_update.ensure_image(image); instance_data->clear_dirty_flag(); - // Step: Find out which screen space textures are needed to draw on the screen. Remove the - // screen space textures that aren't needed. + /* Step: Find out which screen space textures are needed to draw on the screen. Remove the + * screen space textures that aren't needed. */ const ARegion *region = draw_ctx->region; method.update_screen_space_bounds(region); method.update_uv_bounds(region); - // Step: Update the GPU textures based on the changes in the image. + /* Step: Update the GPU textures based on the changes in the image. */ instance_data->update_gpu_texture_allocations(); update_textures(*instance_data, image, iuser); - // Step: Add the GPU textures to the shgroup. + /* Step: Add the GPU textures to the shgroup. */ instance_data->update_batches(); add_depth_shgroups(*instance_data, image, iuser); add_shgroups(instance_data); diff --git a/source/blender/draw/engines/image/image_texture_info.hh b/source/blender/draw/engines/image/image_texture_info.hh index 3ab4f6be864..571328cca9f 100644 --- a/source/blender/draw/engines/image/image_texture_info.hh +++ b/source/blender/draw/engines/image/image_texture_info.hh @@ -48,9 +48,9 @@ struct TextureInfo { rctf uv_bounds; /** - * \brief Batch to draw the associated texton the screen. + * \brief Batch to draw the associated text on the screen. * - * contans a VBO with `pos` and 'uv'. + * Contains a VBO with `pos` and `uv`. * `pos` (2xF32) is relative to the origin of the space. * `uv` (2xF32) reflect the uv bounds. */ diff --git a/source/blender/draw/engines/overlay/overlay_armature.c b/source/blender/draw/engines/overlay/overlay_armature.c index 4029f1237e8..2b80ccc57d5 100644 --- a/source/blender/draw/engines/overlay/overlay_armature.c +++ b/source/blender/draw/engines/overlay/overlay_armature.c @@ -2084,7 +2084,9 @@ static void draw_armature_edit(ArmatureDrawContext *ctx) boneflag &= ~BONE_DRAW_LOCKED_WEIGHT; - draw_bone_relations(ctx, eBone, NULL, arm, boneflag, constflag); + if (!is_select) { + draw_bone_relations(ctx, eBone, NULL, arm, boneflag, constflag); + } if (arm->drawtype == ARM_ENVELOPE) { draw_bone_update_disp_matrix_default(eBone, NULL); @@ -2107,12 +2109,14 @@ static void draw_armature_edit(ArmatureDrawContext *ctx) draw_bone_octahedral(ctx, eBone, NULL, arm, boneflag, constflag, select_id); } - if (show_text && (arm->flag & ARM_DRAWNAMES)) { - draw_bone_name(ctx, eBone, NULL, arm, boneflag); - } + if (!is_select) { + if (show_text && (arm->flag & ARM_DRAWNAMES)) { + draw_bone_name(ctx, eBone, NULL, arm, boneflag); + } - if (arm->flag & ARM_DRAWAXES) { - draw_axes(ctx, eBone, NULL, arm); + if (arm->flag & ARM_DRAWAXES) { + draw_axes(ctx, eBone, NULL, arm); + } } } } @@ -2221,7 +2225,9 @@ static void draw_armature_pose(ArmatureDrawContext *ctx) boneflag &= ~BONE_DRAW_LOCKED_WEIGHT; } - draw_bone_relations(ctx, NULL, pchan, arm, boneflag, constflag); + if (!is_pose_select) { + draw_bone_relations(ctx, NULL, pchan, arm, boneflag, constflag); + } if ((pchan->custom) && !(arm->flag & ARM_NO_CUSTOM)) { draw_bone_update_disp_matrix_custom(pchan); @@ -2248,16 +2254,19 @@ static void draw_armature_pose(ArmatureDrawContext *ctx) draw_bone_octahedral(ctx, NULL, pchan, arm, boneflag, constflag, select_id); } - if (draw_dofs) { - draw_bone_degrees_of_freedom(ctx, pchan); - } + /* These aren't included in the selection. */ + if (!is_pose_select) { + if (draw_dofs) { + draw_bone_degrees_of_freedom(ctx, pchan); + } - if (show_text && (arm->flag & ARM_DRAWNAMES)) { - draw_bone_name(ctx, NULL, pchan, arm, boneflag); - } + if (show_text && (arm->flag & ARM_DRAWNAMES)) { + draw_bone_name(ctx, NULL, pchan, arm, boneflag); + } - if (arm->flag & ARM_DRAWAXES) { - draw_axes(ctx, NULL, pchan, arm); + if (arm->flag & ARM_DRAWAXES) { + draw_axes(ctx, NULL, pchan, arm); + } } } } diff --git a/source/blender/draw/intern/DRW_gpu_wrapper.hh b/source/blender/draw/intern/DRW_gpu_wrapper.hh index af262272577..2809661c8c8 100644 --- a/source/blender/draw/intern/DRW_gpu_wrapper.hh +++ b/source/blender/draw/intern/DRW_gpu_wrapper.hh @@ -286,13 +286,13 @@ template< /** The number of values that can be stored in this uniform buffer. */ int64_t len /** True if the buffer only resides on GPU memory and cannot be accessed. */ - /* TODO(fclem): Currently unsupported. */ + /* TODO(@fclem): Currently unsupported. */ /* bool device_only = false */> class UniformArrayBuffer : public detail::UniformCommon<T, len, false> { public: UniformArrayBuffer() { - /* TODO(fclem) We should map memory instead. */ + /* TODO(@fclem): We should map memory instead. */ this->data_ = (T *)MEM_mallocN_aligned(len * sizeof(T), 16, this->name_); } }; @@ -301,13 +301,13 @@ template< /** Type of the values stored in this uniform buffer. */ typename T /** True if the buffer only resides on GPU memory and cannot be accessed. */ - /* TODO(fclem): Currently unsupported. */ + /* TODO(@fclem): Currently unsupported. */ /* bool device_only = false */> class UniformBuffer : public T, public detail::UniformCommon<T, 1, false> { public: UniformBuffer() { - /* TODO(fclem) How could we map this? */ + /* TODO(@fclem): How could we map this? */ this->data_ = static_cast<T *>(this); } @@ -641,7 +641,7 @@ class Texture : NonCopyable { bool cubemap = false) { - /* TODO(fclem) In the future, we need to check if mip_count did not change. + /* TODO(@fclem): In the future, we need to check if mip_count did not change. * For now it's ok as we always define all MIP level. */ if (tx_) { int3 size = this->size(); @@ -653,7 +653,7 @@ class Texture : NonCopyable { if (tx_ == nullptr) { tx_ = create(w, h, d, mips, format, data, layered, cubemap); if (mips > 1) { - /* TODO(fclem) Remove once we have immutable storage or when mips are + /* TODO(@fclem): Remove once we have immutable storage or when mips are * generated on creation. */ GPU_texture_generate_mipmap(tx_); } diff --git a/source/blender/draw/intern/draw_cache_impl_subdivision.cc b/source/blender/draw/intern/draw_cache_impl_subdivision.cc index a24a3a5a3a7..4a8670a9ee2 100644 --- a/source/blender/draw/intern/draw_cache_impl_subdivision.cc +++ b/source/blender/draw/intern/draw_cache_impl_subdivision.cc @@ -999,7 +999,7 @@ static bool draw_subdiv_build_cache(DRWSubdivCache *cache, cache->face_ptex_offset = BKE_subdiv_face_ptex_offset_get(subdiv); - // Build patch coordinates for all the face dots + /* Build patch coordinates for all the face dots. */ cache->fdots_patch_coords = gpu_vertbuf_create_from_format(get_blender_patch_coords_format(), mesh_eval->totpoly); CompressedPatchCoord *blender_fdots_patch_coords = (CompressedPatchCoord *)GPU_vertbuf_get_data( @@ -1760,7 +1760,7 @@ static void draw_subdiv_cache_ensure_mat_offsets(DRWSubdivCache *cache, int *mat_start = static_cast<int *>(MEM_callocN(sizeof(int) * mat_len, "subdiv mat_start")); int *subdiv_polygon_offset = cache->subdiv_polygon_offset; - // TODO: parallel_reduce? + /* TODO: parallel_reduce? */ for (int i = 0; i < mesh_eval->totpoly; i++) { const MPoly *mpoly = &mesh_eval->mpoly[i]; const int next_offset = (i == mesh_eval->totpoly - 1) ? number_of_quads : diff --git a/source/blender/draw/intern/draw_manager.h b/source/blender/draw/intern/draw_manager.h index d27eb8be9e0..38cd3ecb9b6 100644 --- a/source/blender/draw/intern/draw_manager.h +++ b/source/blender/draw/intern/draw_manager.h @@ -300,7 +300,7 @@ struct DRWCallBuffer { }; /** Used by #DRWUniform.type */ -/* TODO(jbakker): rename to DRW_RESOURCE/DRWResourceType. */ +/* TODO(@jbakker): rename to DRW_RESOURCE/DRWResourceType. */ typedef enum { DRW_UNIFORM_INT = 0, DRW_UNIFORM_INT_COPY, @@ -529,7 +529,7 @@ typedef struct DRWData { struct GHash *obattrs_ubo_pool; uint ubo_len; /** Texture pool to reuse temp texture across engines. */ - /* TODO(fclem) the pool could be shared even between viewports. */ + /* TODO(@fclem): The pool could be shared even between view-ports. */ struct DRWTexturePool *texture_pool; /** Per stereo view data. Contains engine data and default framebuffers. */ struct DRWViewData *view_data[2]; @@ -549,7 +549,7 @@ typedef struct DupliKey { typedef struct DRWManager { /* TODO: clean up this struct a bit. */ /* Cache generation */ - /* TODO(fclem) Rename to data. */ + /* TODO(@fclem): Rename to data. */ DRWData *vmempool; /** Active view data structure for one of the 2 stereo view. Not related to DRWView. */ struct DRWViewData *view_data_active; @@ -572,7 +572,7 @@ typedef struct DRWManager { struct ID *dupli_origin_data; /** Hash-map: #DupliKey -> void pointer for each enabled engine. */ struct GHash *dupli_ghash; - /** TODO(fclem): try to remove usage of this. */ + /** TODO(@fclem): try to remove usage of this. */ DRWInstanceData *object_instance_data[MAX_INSTANCE_DATA_SIZE]; /* Dupli data for the current dupli for each enabled engine. */ void **dupli_datas; @@ -615,7 +615,7 @@ typedef struct DRWManager { DRWView *view_active; DRWView *view_previous; uint primary_view_ct; - /** TODO(fclem): Remove this. Only here to support + /** TODO(@fclem): Remove this. Only here to support * shaders without common_view_lib.glsl */ DRWViewUboStorage view_storage_cpy; @@ -640,7 +640,7 @@ typedef struct DRWManager { GPUDrawList *draw_list; struct { - /* TODO(fclem): optimize: use chunks. */ + /* TODO(@fclem): optimize: use chunks. */ DRWDebugLine *lines; DRWDebugSphere *spheres; } debug; diff --git a/source/blender/draw/intern/draw_manager_data.c b/source/blender/draw/intern/draw_manager_data.c index a4d5d6f3c31..f07fc94f5d1 100644 --- a/source/blender/draw/intern/draw_manager_data.c +++ b/source/blender/draw/intern/draw_manager_data.c @@ -816,7 +816,7 @@ void DRW_shgroup_call_ex(DRWShadingGroup *shgroup, culling->user_data = user_data; } if (bypass_culling) { - /* NOTE this will disable culling for the whole object. */ + /* NOTE: this will disable culling for the whole object. */ culling->bsphere.radius = -1.0f; } } @@ -1248,7 +1248,7 @@ static void drw_shgroup_init(DRWShadingGroup *shgroup, GPUShader *shader) int chunkid_location = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_RESOURCE_CHUNK); int resourceid_location = GPU_shader_get_builtin_uniform(shader, GPU_UNIFORM_RESOURCE_ID); - /* TODO(fclem) Will take the place of the above after the GPUShaderCreateInfo port. */ + /* TODO(@fclem): Will take the place of the above after the GPUShaderCreateInfo port. */ if (view_ubo_location == -1) { view_ubo_location = GPU_shader_get_builtin_block(shader, GPU_UNIFORM_BLOCK_DRW_VIEW); } diff --git a/source/blender/draw/intern/draw_shader_shared.h b/source/blender/draw/intern/draw_shader_shared.h index 35350417ca8..133ffdbd636 100644 --- a/source/blender/draw/intern/draw_shader_shared.h +++ b/source/blender/draw/intern/draw_shader_shared.h @@ -23,7 +23,7 @@ struct ViewInfos { }; BLI_STATIC_ASSERT_ALIGN(ViewInfos, 16) -/* TODO(fclem) Mass rename. */ +/* TODO(@fclem): Mass rename. */ #define ViewProjectionMatrix drw_view.persmat #define ViewProjectionMatrixInverse drw_view.persinv #define ViewMatrix drw_view.viewmat diff --git a/source/blender/draw/intern/draw_view_data.h b/source/blender/draw/intern/draw_view_data.h index b37e48c11e8..98ada5a59cb 100644 --- a/source/blender/draw/intern/draw_view_data.h +++ b/source/blender/draw/intern/draw_view_data.h @@ -35,7 +35,7 @@ struct DRWRegisteredDrawEngine; struct DrawEngineType; struct GPUViewport; -/* NOTE these structs are only here for reading the actual lists from the engine. +/* NOTE: these structs are only here for reading the actual lists from the engine. * The actual length of them is stored in a ViewportEngineData_Info. * The length of 1 is just here to avoid compiler warning. */ typedef struct FramebufferList { diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc index b846da3f016..4dcd821e607 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_attributes.cc @@ -101,7 +101,7 @@ static uint gpu_component_size_for_attribute_type(CustomDataType type) case CD_PROP_BOOL: case CD_PROP_INT32: case CD_PROP_FLOAT: { - /* TODO(kevindietrich) : should be 1 when scalar attributes conversion is handled by us. See + /* TODO(@kevindietrich): should be 1 when scalar attributes conversion is handled by us. See * comment #extract_attr_init. */ return 3; } @@ -317,7 +317,7 @@ static void extract_attr_init(const MeshRenderData *mr, init_vbo_for_attribute(mr, vbo, request, false, static_cast<uint32_t>(mr->loop_len)); - /* TODO(kevindietrich) : float3 is used for scalar attributes as the implicit conversion done by + /* TODO(@kevindietrich): float3 is used for scalar attributes as the implicit conversion done by * OpenGL to vec4 for a scalar `s` will produce a `vec4(s, 0, 0, 1)`. However, following the * Blender convention, it should be `vec4(s, s, s, 1)`. This could be resolved using a similar * texture as for volume attribute, so we can control the conversion ourselves. */ diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edge_fac.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edge_fac.cc index 8470a71059f..4185f2f84a2 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edge_fac.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_edge_fac.cc @@ -78,7 +78,7 @@ static void extract_edge_fac_init(const MeshRenderData *mr, data->edge_loop_count = static_cast<uchar *>( MEM_callocN(sizeof(uint32_t) * mr->edge_len, __func__)); - /* HACK(fclem) Detecting the need for edge render. + /* HACK(@fclem): Detecting the need for edge render. * We could have a flag in the mesh instead or check the modifier stack. */ const MEdge *med = mr->medge; for (int e_index = 0; e_index < mr->edge_len; e_index++, med++) { diff --git a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc index 5d2ea923658..11f1515275c 100644 --- a/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc +++ b/source/blender/draw/intern/mesh_extractors/extract_mesh_vbo_pos_nor.cc @@ -270,7 +270,7 @@ static void extract_pos_nor_loose_geom_subdiv(const DRWSubdivCache *subdiv_cache const MVert *coarse_verts = coarse_mesh->mvert; uint offset = subdiv_cache->num_subdiv_loops; - /* TODO(kevindietrich) : replace this when compressed normals are supported. */ + /* TODO(@kevindietrich): replace this when compressed normals are supported. */ struct SubdivPosNorLoop { float pos[3]; float nor[3]; diff --git a/source/blender/draw/intern/shaders/common_fxaa_lib.glsl b/source/blender/draw/intern/shaders/common_fxaa_lib.glsl index bf59972fbaa..599d875c500 100644 --- a/source/blender/draw/intern/shaders/common_fxaa_lib.glsl +++ b/source/blender/draw/intern/shaders/common_fxaa_lib.glsl @@ -51,7 +51,7 @@ /*============================================================================ FXAA QUALITY - TUNING KNOBS ------------------------------------------------------------------------------ -NOTE the other tuning knobs are now in the shader function inputs! +NOTE: the other tuning knobs are now in the shader function inputs! ============================================================================*/ #ifndef FXAA_QUALITY__PRESET /* diff --git a/source/blender/draw/intern/shaders/common_subdiv_lib.glsl b/source/blender/draw/intern/shaders/common_subdiv_lib.glsl index 9dd86c35ee4..e6538d80111 100644 --- a/source/blender/draw/intern/shaders/common_subdiv_lib.glsl +++ b/source/blender/draw/intern/shaders/common_subdiv_lib.glsl @@ -101,7 +101,7 @@ uint get_index(uint i) * the format. */ struct PosNorLoop { float x, y, z; - /* TODO(kevindietrich) : figure how to compress properly as GLSL does not have char/short types, + /* TODO(@kevindietrich): figure how to compress properly as GLSL does not have char/short types, * bit operations get tricky. */ float nx, ny, nz; float flag; diff --git a/source/blender/draw/intern/shaders/draw_hair_refine_info.hh b/source/blender/draw/intern/shaders/draw_hair_refine_info.hh index b41be7d8605..bdfc26b7dcd 100644 --- a/source/blender/draw/intern/shaders/draw_hair_refine_info.hh +++ b/source/blender/draw/intern/shaders/draw_hair_refine_info.hh @@ -25,7 +25,7 @@ GPU_SHADER_CREATE_INFO(draw_hair_refine_compute) .local_group_size(1, 1) - .storage_buf(0, Qualifier::WRITE_ONLY, "vec4", "posTime[]") + .storage_buf(0, Qualifier::WRITE, "vec4", "posTime[]") .sampler(0, ImageType::FLOAT_BUFFER, "hairPointBuffer") .sampler(1, ImageType::UINT_BUFFER, "hairStrandBuffer") .sampler(2, ImageType::UINT_BUFFER, "hairStrandSegBuffer") diff --git a/source/blender/draw/intern/shaders/draw_view_info.hh b/source/blender/draw/intern/shaders/draw_view_info.hh index 0a25059ffed..479527379cf 100644 --- a/source/blender/draw/intern/shaders/draw_view_info.hh +++ b/source/blender/draw/intern/shaders/draw_view_info.hh @@ -83,7 +83,7 @@ GPU_SHADER_CREATE_INFO(draw_hair) .sampler(15, ImageType::FLOAT_BUFFER, "hairPointBuffer") .sampler(14, ImageType::UINT_BUFFER, "hairStrandBuffer") .sampler(13, ImageType::UINT_BUFFER, "hairStrandSegBuffer") - /* TODO(fclem) Pack thoses into one UBO. */ + /* TODO(@fclem): Pack these into one UBO. */ .push_constant(Type::INT, "hairStrandsRes") .push_constant(Type::INT, "hairThicknessRes") .push_constant(Type::FLOAT, "hairRadRoot") diff --git a/source/blender/editors/animation/CMakeLists.txt b/source/blender/editors/animation/CMakeLists.txt index 6fa4d94df3a..0baac40660d 100644 --- a/source/blender/editors/animation/CMakeLists.txt +++ b/source/blender/editors/animation/CMakeLists.txt @@ -60,10 +60,6 @@ set(LIB bf_blenlib ) -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() - if(WITH_PYTHON) add_definitions(-DWITH_PYTHON) endif() diff --git a/source/blender/editors/armature/CMakeLists.txt b/source/blender/editors/armature/CMakeLists.txt index aff5803f037..c8ca27c64a3 100644 --- a/source/blender/editors/armature/CMakeLists.txt +++ b/source/blender/editors/armature/CMakeLists.txt @@ -63,9 +63,5 @@ set(LIB bf_blenlib ) -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() - blender_add_lib(bf_editor_armature "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/editors/armature/armature_intern.h b/source/blender/editors/armature/armature_intern.h index 252cf806e34..aaeac29b7d0 100644 --- a/source/blender/editors/armature/armature_intern.h +++ b/source/blender/editors/armature/armature_intern.h @@ -27,6 +27,7 @@ struct wmOperatorType; struct Base; +struct GPUSelectResult; struct Object; struct Scene; struct bContext; @@ -323,21 +324,21 @@ struct Bone *ED_armature_pick_bone(struct bContext *C, struct EditBone *ED_armature_pick_ebone_from_selectbuffer(struct Base **bases, uint bases_len, - const uint *buffer, + const struct GPUSelectResult *buffer, short hits, bool findunsel, bool do_nearest, struct Base **r_base); struct bPoseChannel *ED_armature_pick_pchan_from_selectbuffer(struct Base **bases, uint bases_len, - const uint *buffer, + const struct GPUSelectResult *buffer, short hits, bool findunsel, bool do_nearest, struct Base **r_base); struct Bone *ED_armature_pick_bone_from_selectbuffer(struct Base **bases, uint bases_len, - const uint *buffer, + const struct GPUSelectResult *buffer, short hits, bool findunsel, bool do_nearest, diff --git a/source/blender/editors/armature/armature_select.c b/source/blender/editors/armature/armature_select.c index 5e4cb813064..f9b52eb53ed 100644 --- a/source/blender/editors/armature/armature_select.c +++ b/source/blender/editors/armature/armature_select.c @@ -55,6 +55,8 @@ #include "DEG_depsgraph.h" +#include "GPU_select.h" + #include "armature_intern.h" /* utility macros for storing a temp int in the bone (selection flag) */ @@ -67,10 +69,10 @@ Base *ED_armature_base_and_ebone_from_select_buffer(Base **bases, uint bases_len, - int hit, + const uint select_id, EditBone **r_ebone) { - const uint hit_object = hit & 0xFFFF; + const uint hit_object = select_id & 0xFFFF; Base *base = NULL; EditBone *ebone = NULL; /* TODO(campbell): optimize, eg: sort & binary search. */ @@ -81,7 +83,7 @@ Base *ED_armature_base_and_ebone_from_select_buffer(Base **bases, } } if (base != NULL) { - const uint hit_bone = (hit & ~BONESEL_ANY) >> 16; + const uint hit_bone = (select_id & ~BONESEL_ANY) >> 16; bArmature *arm = base->object->data; ebone = BLI_findlink(arm->edbo, hit_bone); } @@ -91,10 +93,10 @@ Base *ED_armature_base_and_ebone_from_select_buffer(Base **bases, Object *ED_armature_object_and_ebone_from_select_buffer(Object **objects, uint objects_len, - int hit, + const uint select_id, EditBone **r_ebone) { - const uint hit_object = hit & 0xFFFF; + const uint hit_object = select_id & 0xFFFF; Object *ob = NULL; EditBone *ebone = NULL; /* TODO(campbell): optimize, eg: sort & binary search. */ @@ -105,7 +107,7 @@ Object *ED_armature_object_and_ebone_from_select_buffer(Object **objects, } } if (ob != NULL) { - const uint hit_bone = (hit & ~BONESEL_ANY) >> 16; + const uint hit_bone = (select_id & ~BONESEL_ANY) >> 16; bArmature *arm = ob->data; ebone = BLI_findlink(arm->edbo, hit_bone); } @@ -115,10 +117,10 @@ Object *ED_armature_object_and_ebone_from_select_buffer(Object **objects, Base *ED_armature_base_and_pchan_from_select_buffer(Base **bases, uint bases_len, - int hit, + const uint select_id, bPoseChannel **r_pchan) { - const uint hit_object = hit & 0xFFFF; + const uint hit_object = select_id & 0xFFFF; Base *base = NULL; bPoseChannel *pchan = NULL; /* TODO(campbell): optimize, eg: sort & binary search. */ @@ -130,7 +132,7 @@ Base *ED_armature_base_and_pchan_from_select_buffer(Base **bases, } if (base != NULL) { if (base->object->pose != NULL) { - const uint hit_bone = (hit & ~BONESEL_ANY) >> 16; + const uint hit_bone = (select_id & ~BONESEL_ANY) >> 16; /* pchan may be NULL. */ pchan = BLI_findlink(&base->object->pose->chanbase, hit_bone); } @@ -141,11 +143,11 @@ Base *ED_armature_base_and_pchan_from_select_buffer(Base **bases, Base *ED_armature_base_and_bone_from_select_buffer(Base **bases, uint bases_len, - int hit, + const uint select_id, Bone **r_bone) { bPoseChannel *pchan = NULL; - Base *base = ED_armature_base_and_pchan_from_select_buffer(bases, bases_len, hit, &pchan); + Base *base = ED_armature_base_and_pchan_from_select_buffer(bases, bases_len, select_id, &pchan); *r_bone = pchan ? pchan->bone : NULL; return base; } @@ -166,8 +168,8 @@ Base *ED_armature_base_and_bone_from_select_buffer(Base **bases, static void *ed_armature_pick_bone_from_selectbuffer_impl(const bool is_editmode, Base **bases, uint bases_len, - const uint *buffer, - short hits, + const GPUSelectResult *buffer, + const short hits, bool findunsel, bool do_nearest, Base **r_base) @@ -181,7 +183,7 @@ static void *ed_armature_pick_bone_from_selectbuffer_impl(const bool is_editmode int minsel = 0xffffffff, minunsel = 0xffffffff; for (short i = 0; i < hits; i++) { - hitresult = buffer[3 + (i * 4)]; + hitresult = buffer[i].id; if (hitresult & BONESEL_ANY) { /* to avoid including objects in selection */ Base *base = NULL; @@ -221,10 +223,10 @@ static void *ed_armature_pick_bone_from_selectbuffer_impl(const bool is_editmode if (data) { if (sel) { if (do_nearest) { - if (minsel > buffer[4 * i + 1]) { + if (minsel > buffer[i].depth) { firstSel = data; firstSel_base = base; - minsel = buffer[4 * i + 1]; + minsel = buffer[i].depth; } } else { @@ -237,10 +239,10 @@ static void *ed_armature_pick_bone_from_selectbuffer_impl(const bool is_editmode } else { if (do_nearest) { - if (minunsel > buffer[4 * i + 1]) { + if (minunsel > buffer[i].depth) { firstunSel = data; firstunSel_base = base; - minunsel = buffer[4 * i + 1]; + minunsel = buffer[i].depth; } } else { @@ -268,8 +270,8 @@ static void *ed_armature_pick_bone_from_selectbuffer_impl(const bool is_editmode EditBone *ED_armature_pick_ebone_from_selectbuffer(Base **bases, uint bases_len, - const uint *buffer, - short hits, + const GPUSelectResult *buffer, + const short hits, bool findunsel, bool do_nearest, Base **r_base) @@ -281,8 +283,8 @@ EditBone *ED_armature_pick_ebone_from_selectbuffer(Base **bases, bPoseChannel *ED_armature_pick_pchan_from_selectbuffer(Base **bases, uint bases_len, - const uint *buffer, - short hits, + const GPUSelectResult *buffer, + const short hits, bool findunsel, bool do_nearest, Base **r_base) @@ -294,8 +296,8 @@ bPoseChannel *ED_armature_pick_pchan_from_selectbuffer(Base **bases, Bone *ED_armature_pick_bone_from_selectbuffer(Base **bases, uint bases_len, - const uint *buffer, - short hits, + const GPUSelectResult *buffer, + const short hits, bool findunsel, bool do_nearest, Base **r_base) @@ -327,7 +329,7 @@ static void *ed_armature_pick_bone_impl( Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); ViewContext vc; rcti rect; - uint buffer[MAXPICKBUF]; + GPUSelectResult buffer[MAXPICKELEMS]; short hits; ED_view3d_viewcontext_init(C, &vc, depsgraph); @@ -340,7 +342,7 @@ static void *ed_armature_pick_bone_impl( hits = view3d_opengl_select_with_id_filter(&vc, buffer, - MAXPICKBUF, + ARRAY_SIZE(buffer), &rect, VIEW3D_SELECT_PICK_NEAREST, VIEW3D_SELECT_FILTER_NOP, @@ -636,15 +638,15 @@ void ARMATURE_OT_select_linked_pick(wmOperatorType *ot) * \{ */ /* utility function for get_nearest_editbonepoint */ -static int selectbuffer_ret_hits_12(uint *UNUSED(buffer), const int hits12) +static int selectbuffer_ret_hits_12(GPUSelectResult *UNUSED(buffer), const int hits12) { return hits12; } -static int selectbuffer_ret_hits_5(uint *buffer, const int hits12, const int hits5) +static int selectbuffer_ret_hits_5(GPUSelectResult *buffer, const int hits12, const int hits5) { - const int ofs = 4 * hits12; - memcpy(buffer, buffer + ofs, 4 * hits5 * sizeof(uint)); + const int ofs = hits12; + memcpy(buffer, buffer + ofs, hits5 * sizeof(*buffer)); return hits5; } @@ -653,7 +655,7 @@ static int selectbuffer_ret_hits_5(uint *buffer, const int hits12, const int hit static EditBone *get_nearest_editbonepoint( ViewContext *vc, bool findunsel, bool use_cycle, Base **r_base, int *r_selmask) { - uint buffer[MAXPICKBUF]; + GPUSelectResult buffer[MAXPICKELEMS]; struct { uint hitresult; Base *base; @@ -692,7 +694,7 @@ static EditBone *get_nearest_editbonepoint( rcti rect; BLI_rcti_init_pt_radius(&rect, vc->mval, 12); const int hits12 = view3d_opengl_select_with_id_filter( - vc, buffer, MAXPICKBUF, &rect, select_mode, select_filter, select_id_ignore); + vc, buffer, ARRAY_SIZE(buffer), &rect, select_mode, select_filter, select_id_ignore); if (hits12 == 1) { hits = selectbuffer_ret_hits_12(buffer, hits12); @@ -701,10 +703,15 @@ static EditBone *get_nearest_editbonepoint( else if (hits12 > 0) { int ofs; - ofs = 4 * hits12; + ofs = hits12; BLI_rcti_init_pt_radius(&rect, vc->mval, 5); - const int hits5 = view3d_opengl_select_with_id_filter( - vc, buffer + ofs, MAXPICKBUF - ofs, &rect, select_mode, select_filter, select_id_ignore); + const int hits5 = view3d_opengl_select_with_id_filter(vc, + buffer + ofs, + ARRAY_SIZE(buffer) - ofs, + &rect, + select_mode, + select_filter, + select_id_ignore); if (hits5 == 1) { hits = selectbuffer_ret_hits_5(buffer, hits12, hits5); @@ -732,7 +739,7 @@ cache_end: /* See if there are any selected bones in this group */ if (hits > 0) { if (hits == 1) { - result_bias.hitresult = buffer[3]; + result_bias.hitresult = buffer->id; result_bias.base = ED_armature_base_and_ebone_from_select_buffer( bases, bases_len, result_bias.hitresult, &result_bias.ebone); } @@ -771,7 +778,7 @@ cache_end: } for (int i = 0; i < hits; i++) { - const uint hitresult = buffer[3 + (i * 4)]; + const uint hitresult = buffer[i].id; Base *base = NULL; EditBone *ebone; diff --git a/source/blender/editors/armature/pose_select.c b/source/blender/editors/armature/pose_select.c index 0b889149f9d..f41c3657431 100644 --- a/source/blender/editors/armature/pose_select.c +++ b/source/blender/editors/armature/pose_select.c @@ -240,8 +240,8 @@ void ED_armature_pose_select_pick_bone(ViewLayer *view_layer, bool ED_armature_pose_select_pick_with_buffer(ViewLayer *view_layer, View3D *v3d, Base *base, - const uint *buffer, - short hits, + const struct GPUSelectResult *buffer, + const short hits, bool extend, bool deselect, bool toggle, diff --git a/source/blender/editors/curve/CMakeLists.txt b/source/blender/editors/curve/CMakeLists.txt index 877c2d99102..0ac572c0422 100644 --- a/source/blender/editors/curve/CMakeLists.txt +++ b/source/blender/editors/curve/CMakeLists.txt @@ -51,9 +51,5 @@ set(LIB extern_curve_fit_nd ) -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() - blender_add_lib(bf_editor_curve "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/editors/gpencil/CMakeLists.txt b/source/blender/editors/gpencil/CMakeLists.txt index bff7310e9f7..93d17598181 100644 --- a/source/blender/editors/gpencil/CMakeLists.txt +++ b/source/blender/editors/gpencil/CMakeLists.txt @@ -86,9 +86,5 @@ if(WITH_POTRACE) add_definitions(-DWITH_POTRACE) endif() -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() - blender_add_lib(bf_editor_gpencil "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c index afb786da8c6..c910162415d 100644 --- a/source/blender/editors/gpencil/gpencil_edit.c +++ b/source/blender/editors/gpencil/gpencil_edit.c @@ -4635,7 +4635,7 @@ static int gpencil_stroke_separate_exec(bContext *C, wmOperator *op) } } - /* Separate the entrie stroke. */ + /* Separate the entire stroke. */ if (all_points_selected) { /* deselect old stroke */ gps->flag &= ~GP_STROKE_SELECT; diff --git a/source/blender/editors/include/ED_armature.h b/source/blender/editors/include/ED_armature.h index 7631bd35e79..afba3c7b96a 100644 --- a/source/blender/editors/include/ED_armature.h +++ b/source/blender/editors/include/ED_armature.h @@ -35,6 +35,7 @@ struct Base; struct Bone; struct Depsgraph; struct EditBone; +struct GPUSelectResult; struct ListBase; struct Main; struct Mesh; @@ -157,22 +158,22 @@ int ED_armature_join_objects_exec(struct bContext *C, struct wmOperator *op); struct Base *ED_armature_base_and_ebone_from_select_buffer(struct Base **bases, uint bases_len, - int hit, + unsigned int select_id, struct EditBone **r_ebone); struct Object *ED_armature_object_and_ebone_from_select_buffer(struct Object **objects, uint objects_len, - int hit, + unsigned int select_id, struct EditBone **r_ebone); struct Base *ED_armature_base_and_pchan_from_select_buffer(struct Base **bases, uint bases_len, - int hit, + unsigned int select_id, struct bPoseChannel **r_pchan); /** * For callers that don't need the pose channel. */ struct Base *ED_armature_base_and_bone_from_select_buffer(struct Base **bases, uint bases_len, - int hit, + unsigned int select_id, struct Bone **r_bone); bool ED_armature_edit_deselect_all(struct Object *obedit); bool ED_armature_edit_deselect_all_visible(struct Object *obedit); @@ -334,7 +335,7 @@ void ED_armature_pose_select_pick_bone(struct ViewLayer *view_layer, bool ED_armature_pose_select_pick_with_buffer(struct ViewLayer *view_layer, struct View3D *v3d, struct Base *base, - const unsigned int *buffer, + const struct GPUSelectResult *buffer, short hits, bool extend, bool deselect, diff --git a/source/blender/editors/include/ED_util.h b/source/blender/editors/include/ED_util.h index 4e794838b2f..6d9691d96f4 100644 --- a/source/blender/editors/include/ED_util.h +++ b/source/blender/editors/include/ED_util.h @@ -62,9 +62,9 @@ bool ED_editors_flush_edits(struct Main *bmain); * \param new_id: may be NULL to unlink \a old_id. */ void ED_spacedata_id_remap_single(struct ScrArea *area, - struct SpaceLink *sl, - struct ID *old_id, - struct ID *new_id); + struct SpaceLink *sl, + struct ID *old_id, + struct ID *new_id); void ED_spacedata_id_remap(struct ScrArea *area, struct SpaceLink *sl, const struct IDRemapper *mappings); diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h index 0398c209c68..3bbffc3b7c9 100644 --- a/source/blender/editors/include/ED_view3d.h +++ b/source/blender/editors/include/ED_view3d.h @@ -41,6 +41,7 @@ struct Camera; struct CustomData_MeshMasks; struct Depsgraph; struct EditBone; +struct GPUSelectResult; struct ID; struct MVert; struct Main; @@ -871,9 +872,14 @@ bool ED_view3d_autodist_simple(struct ARegion *region, bool ED_view3d_depth_read_cached_seg( const ViewDepths *vd, const int mval_sta[2], const int mval_end[2], int margin, float *depth); -/* select */ +/** + * The default value for the maximum number of elements that can be selected at once + * using view-port selection. + * + * \note in many cases this defines the size of fixed-size stack buffers, + * so take care increasing this value. + */ #define MAXPICKELEMS 2500 -#define MAXPICKBUF (4 * MAXPICKELEMS) typedef enum { /* all elements in the region, ignore depth */ @@ -912,21 +918,21 @@ void view3d_opengl_select_cache_end(void); * \note (vc->obedit == NULL) can be set to explicitly skip edit-object selection. */ int view3d_opengl_select_ex(struct ViewContext *vc, - unsigned int *buffer, - unsigned int bufsize, + struct GPUSelectResult *buffer, + unsigned int buffer_len, const struct rcti *input, eV3DSelectMode select_mode, eV3DSelectObjectFilter select_filter, bool do_material_slot_selection); int view3d_opengl_select(struct ViewContext *vc, - unsigned int *buffer, - unsigned int bufsize, + struct GPUSelectResult *buffer, + unsigned int buffer_len, const struct rcti *input, eV3DSelectMode select_mode, eV3DSelectObjectFilter select_filter); int view3d_opengl_select_with_id_filter(struct ViewContext *vc, - unsigned int *buffer, - unsigned int bufsize, + struct GPUSelectResult *buffer, + unsigned int buffer_len, const struct rcti *input, eV3DSelectMode select_mode, eV3DSelectObjectFilter select_filter, diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h index 3796fa51499..ae4c2ff16fd 100644 --- a/source/blender/editors/include/UI_interface.h +++ b/source/blender/editors/include/UI_interface.h @@ -1370,6 +1370,8 @@ uiBut *uiDefIconTextButO_ptr(uiBlock *block, /* for passing inputs to ButO buttons */ struct PointerRNA *UI_but_operator_ptr_get(uiBut *but); +struct bContextStore *UI_but_context_get(const uiBut *but); + void UI_but_unit_type_set(uiBut *but, int unit_type); int UI_but_unit_type_get(const uiBut *but); diff --git a/source/blender/editors/include/UI_interface_icons.h b/source/blender/editors/include/UI_interface_icons.h index 1009ae5cd3f..ec80338b4c0 100644 --- a/source/blender/editors/include/UI_interface_icons.h +++ b/source/blender/editors/include/UI_interface_icons.h @@ -102,7 +102,6 @@ void UI_icon_render_id_ex(const struct bContext *C, const bool use_job, struct PreviewImage *r_preview_image); - /** * Render size for preview images and icons */ diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c index 636281ba373..2292bf759b7 100644 --- a/source/blender/editors/interface/interface.c +++ b/source/blender/editors/interface/interface.c @@ -5928,6 +5928,11 @@ PointerRNA *UI_but_operator_ptr_get(uiBut *but) return but->opptr; } +bContextStore *UI_but_context_get(const uiBut *but) +{ + return but->context; +} + void UI_but_unit_type_set(uiBut *but, const int unit_type) { but->unit_type = (uchar)(RNA_SUBTYPE_UNIT_VALUE(unit_type)); diff --git a/source/blender/editors/interface/interface_eyedropper.c b/source/blender/editors/interface/interface_eyedropper.c index fd03cc5e12c..6fa94730365 100644 --- a/source/blender/editors/interface/interface_eyedropper.c +++ b/source/blender/editors/interface/interface_eyedropper.c @@ -25,6 +25,7 @@ #include "DNA_space_types.h" #include "BLI_math_color.h" +#include "BLI_math_vector.h" #include "BKE_context.h" #include "BKE_screen.h" @@ -107,7 +108,7 @@ wmKeyMap *eyedropper_colorband_modal_keymap(wmKeyConfig *keyconf) /** \name Generic Shared Functions * \{ */ -static void eyedropper_draw_cursor_text_ex(const int x, const int y, const char *name) +static void eyedropper_draw_cursor_text_ex(const int xy[2], const char *name) { const uiFontStyle *fstyle = UI_FSTYLE_WIDGET; @@ -119,7 +120,7 @@ static void eyedropper_draw_cursor_text_ex(const int x, const int y, const char rgba_uchar_to_float(col_fg, wcol->text); rgba_uchar_to_float(col_bg, wcol->inner); - UI_fontstyle_draw_simple_backdrop(fstyle, x, y + U.widget_unit, name, col_fg, col_bg); + UI_fontstyle_draw_simple_backdrop(fstyle, xy[0], xy[1] + U.widget_unit, name, col_fg, col_bg); } void eyedropper_draw_cursor_text_window(const struct wmWindow *window, const char *name) @@ -128,19 +129,16 @@ void eyedropper_draw_cursor_text_window(const struct wmWindow *window, const cha return; } - const int x = window->eventstate->xy[0]; - const int y = window->eventstate->xy[1]; - - eyedropper_draw_cursor_text_ex(x, y, name); + eyedropper_draw_cursor_text_ex(window->eventstate->xy, name); } -void eyedropper_draw_cursor_text_region(const int x, const int y, const char *name) +void eyedropper_draw_cursor_text_region(const int xy[2], const char *name) { if (name[0] == '\0') { return; } - eyedropper_draw_cursor_text_ex(x, y, name); + eyedropper_draw_cursor_text_ex(xy, name); } uiBut *eyedropper_get_property_button_under_mouse(bContext *C, const wmEvent *event) @@ -173,8 +171,7 @@ void datadropper_win_area_find( } } else if (mval != r_mval) { - r_mval[0] = mval[0]; - r_mval[1] = mval[1]; + copy_v2_v2_int(r_mval, mval); } } diff --git a/source/blender/editors/interface/interface_eyedropper_color.c b/source/blender/editors/interface/interface_eyedropper_color.c index 05840175fab..b5eed2534a3 100644 --- a/source/blender/editors/interface/interface_eyedropper_color.c +++ b/source/blender/editors/interface/interface_eyedropper_color.c @@ -254,8 +254,10 @@ static bool eyedropper_cryptomatte_sample_image_fl(const bNode *node, return success; } -static bool eyedropper_cryptomatte_sample_fl( - bContext *C, Eyedropper *eye, int mx, int my, float r_col[3]) +static bool eyedropper_cryptomatte_sample_fl(bContext *C, + Eyedropper *eye, + const int m_xy[2], + float r_col[3]) { bNode *node = eye->crypto_node; NodeCryptomatte *crypto = node ? ((NodeCryptomatte *)node->storage) : NULL; @@ -265,17 +267,17 @@ static bool eyedropper_cryptomatte_sample_fl( } bScreen *screen = CTX_wm_screen(C); - ScrArea *area = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, (const int[2]){mx, my}); + ScrArea *area = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, m_xy); if (!area || !ELEM(area->spacetype, SPACE_IMAGE, SPACE_NODE, SPACE_CLIP)) { return false; } - ARegion *region = BKE_area_find_region_xy(area, RGN_TYPE_WINDOW, (const int[2]){mx, my}); + ARegion *region = BKE_area_find_region_xy(area, RGN_TYPE_WINDOW, m_xy); if (!region) { return false; } - int mval[2] = {mx - region->winrct.xmin, my - region->winrct.ymin}; + int mval[2] = {m_xy[0] - region->winrct.xmin, m_xy[1] - region->winrct.ymin}; float fpos[2] = {-1.0f, -1.0}; switch (area->spacetype) { case SPACE_IMAGE: { @@ -324,7 +326,7 @@ static bool eyedropper_cryptomatte_sample_fl( return false; } -void eyedropper_color_sample_fl(bContext *C, int mx, int my, float r_col[3]) +void eyedropper_color_sample_fl(bContext *C, const int m_xy[2], float r_col[3]) { /* we could use some clever */ Main *bmain = CTX_data_main(C); @@ -332,10 +334,10 @@ void eyedropper_color_sample_fl(bContext *C, int mx, int my, float r_col[3]) const char *display_device = CTX_data_scene(C)->display_settings.display_device; struct ColorManagedDisplay *display = IMB_colormanagement_display_get_named(display_device); + int mval[2]; wmWindow *win; ScrArea *area; - int mval[2] = {mx, my}; - datadropper_win_area_find(C, mval, mval, &win, &area); + datadropper_win_area_find(C, m_xy, mval, &win, &area); if (area) { if (area->spacetype == SPACE_IMAGE) { @@ -406,17 +408,17 @@ static void eyedropper_color_set(bContext *C, Eyedropper *eye, const float col[3 RNA_property_update(C, &eye->ptr, eye->prop); } -static void eyedropper_color_sample(bContext *C, Eyedropper *eye, int mx, int my) +static void eyedropper_color_sample(bContext *C, Eyedropper *eye, const int m_xy[2]) { /* Accumulate color. */ float col[3]; if (eye->crypto_node) { - if (!eyedropper_cryptomatte_sample_fl(C, eye, mx, my, col)) { + if (!eyedropper_cryptomatte_sample_fl(C, eye, m_xy, col)) { return; } } else { - eyedropper_color_sample_fl(C, mx, my, col); + eyedropper_color_sample_fl(C, m_xy, col); } if (!eye->crypto_node) { @@ -439,13 +441,13 @@ static void eyedropper_color_sample(bContext *C, Eyedropper *eye, int mx, int my eyedropper_color_set(C, eye, accum_col); } -static void eyedropper_color_sample_text_update(bContext *C, Eyedropper *eye, int mx, int my) +static void eyedropper_color_sample_text_update(bContext *C, Eyedropper *eye, const int m_xy[2]) { float col[3]; eye->sample_text[0] = '\0'; if (eye->cryptomatte_session) { - if (eyedropper_cryptomatte_sample_fl(C, eye, mx, my, col)) { + if (eyedropper_cryptomatte_sample_fl(C, eye, m_xy, col)) { BKE_cryptomatte_find_name( eye->cryptomatte_session, col[0], eye->sample_text, sizeof(eye->sample_text)); eye->sample_text[sizeof(eye->sample_text) - 1] = '\0'; @@ -476,7 +478,7 @@ static int eyedropper_modal(bContext *C, wmOperator *op, const wmEvent *event) case EYE_MODAL_SAMPLE_CONFIRM: { const bool is_undo = eye->is_undo; if (eye->accum_tot == 0) { - eyedropper_color_sample(C, eye, event->xy[0], event->xy[1]); + eyedropper_color_sample(C, eye, event->xy); } eyedropper_exit(C, op); /* Could support finished & undo-skip. */ @@ -485,23 +487,23 @@ static int eyedropper_modal(bContext *C, wmOperator *op, const wmEvent *event) case EYE_MODAL_SAMPLE_BEGIN: /* enable accum and make first sample */ eye->accum_start = true; - eyedropper_color_sample(C, eye, event->xy[0], event->xy[1]); + eyedropper_color_sample(C, eye, event->xy); break; case EYE_MODAL_SAMPLE_RESET: eye->accum_tot = 0; zero_v3(eye->accum_col); - eyedropper_color_sample(C, eye, event->xy[0], event->xy[1]); + eyedropper_color_sample(C, eye, event->xy); break; } } else if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) { if (eye->accum_start) { /* button is pressed so keep sampling */ - eyedropper_color_sample(C, eye, event->xy[0], event->xy[1]); + eyedropper_color_sample(C, eye, event->xy); } if (eye->draw_handle_sample_text) { - eyedropper_color_sample_text_update(C, eye, event->xy[0], event->xy[1]); + eyedropper_color_sample_text_update(C, eye, event->xy); ED_region_tag_redraw(CTX_wm_region(C)); } } diff --git a/source/blender/editors/interface/interface_eyedropper_colorband.c b/source/blender/editors/interface/interface_eyedropper_colorband.c index 22320282766..05ed4ecf601 100644 --- a/source/blender/editors/interface/interface_eyedropper_colorband.c +++ b/source/blender/editors/interface/interface_eyedropper_colorband.c @@ -58,7 +58,7 @@ typedef struct Colorband_RNAUpdateCb { } Colorband_RNAUpdateCb; typedef struct EyedropperColorband { - int last_x, last_y; + int event_xy_last[2]; /* Alpha is currently fixed at 1.0, may support in future. */ float (*color_buffer)[4]; int color_buffer_alloc; @@ -142,13 +142,12 @@ static bool eyedropper_colorband_init(bContext *C, wmOperator *op) static void eyedropper_colorband_sample_point(bContext *C, EyedropperColorband *eye, - int mx, - int my) + const int m_xy[2]) { - if (eye->last_x != mx || eye->last_y != my) { + if (eye->event_xy_last[0] != m_xy[0] || eye->event_xy_last[1] != m_xy[1]) { float col[4]; col[3] = 1.0f; /* TODO: sample alpha */ - eyedropper_color_sample_fl(C, mx, my, col); + eyedropper_color_sample_fl(C, m_xy, col); if (eye->color_buffer_len + 1 == eye->color_buffer_alloc) { eye->color_buffer_alloc *= 2; eye->color_buffer = MEM_reallocN(eye->color_buffer, @@ -156,8 +155,7 @@ static void eyedropper_colorband_sample_point(bContext *C, } copy_v4_v4(eye->color_buffer[eye->color_buffer_len], col); eye->color_buffer_len += 1; - eye->last_x = mx; - eye->last_y = my; + copy_v2_v2_int(eye->event_xy_last, m_xy); eye->is_set = true; } } @@ -167,21 +165,20 @@ static bool eyedropper_colorband_sample_callback(int mx, int my, void *userdata) struct EyedropperColorband_Context *data = userdata; bContext *C = data->context; EyedropperColorband *eye = data->eye; - eyedropper_colorband_sample_point(C, eye, mx, my); + const int cursor[2] = {mx, my}; + eyedropper_colorband_sample_point(C, eye, cursor); return true; } static void eyedropper_colorband_sample_segment(bContext *C, EyedropperColorband *eye, - int mx, - int my) + const int m_xy[2]) { /* Since the mouse tends to move rather rapidly we use #BLI_bitmap_draw_2d_line_v2v2i * to interpolate between the reported coordinates */ struct EyedropperColorband_Context userdata = {C, eye}; - const int p1[2] = {eye->last_x, eye->last_y}; - const int p2[2] = {mx, my}; - BLI_bitmap_draw_2d_line_v2v2i(p1, p2, eyedropper_colorband_sample_callback, &userdata); + BLI_bitmap_draw_2d_line_v2v2i( + eye->event_xy_last, m_xy, eyedropper_colorband_sample_callback, &userdata); } static void eyedropper_colorband_exit(bContext *C, wmOperator *op) @@ -233,7 +230,7 @@ static int eyedropper_colorband_modal(bContext *C, wmOperator *op, const wmEvent return OPERATOR_CANCELLED; case EYE_MODAL_SAMPLE_CONFIRM: { const bool is_undo = eye->is_undo; - eyedropper_colorband_sample_segment(C, eye, event->xy[0], event->xy[1]); + eyedropper_colorband_sample_segment(C, eye, event->xy); eyedropper_colorband_apply(C, op); eyedropper_colorband_exit(C, op); /* Could support finished & undo-skip. */ @@ -242,10 +239,9 @@ static int eyedropper_colorband_modal(bContext *C, wmOperator *op, const wmEvent case EYE_MODAL_SAMPLE_BEGIN: /* enable accum and make first sample */ eye->sample_start = true; - eyedropper_colorband_sample_point(C, eye, event->xy[0], event->xy[1]); + eyedropper_colorband_sample_point(C, eye, event->xy); eyedropper_colorband_apply(C, op); - eye->last_x = event->xy[0]; - eye->last_y = event->xy[1]; + copy_v2_v2_int(eye->event_xy_last, event->xy); break; case EYE_MODAL_SAMPLE_RESET: break; @@ -253,7 +249,7 @@ static int eyedropper_colorband_modal(bContext *C, wmOperator *op, const wmEvent } else if (event->type == MOUSEMOVE) { if (eye->sample_start) { - eyedropper_colorband_sample_segment(C, eye, event->xy[0], event->xy[1]); + eyedropper_colorband_sample_segment(C, eye, event->xy); eyedropper_colorband_apply(C, op); } } @@ -280,7 +276,7 @@ static int eyedropper_colorband_point_modal(bContext *C, wmOperator *op, const w } break; case EYE_MODAL_POINT_SAMPLE: - eyedropper_colorband_sample_point(C, eye, event->xy[0], event->xy[1]); + eyedropper_colorband_sample_point(C, eye, event->xy); eyedropper_colorband_apply(C, op); if (eye->color_buffer_len == MAXCOLORBAND) { eyedropper_colorband_exit(C, op); diff --git a/source/blender/editors/interface/interface_eyedropper_datablock.c b/source/blender/editors/interface/interface_eyedropper_datablock.c index cf53ef0ec75..812011101e8 100644 --- a/source/blender/editors/interface/interface_eyedropper_datablock.c +++ b/source/blender/editors/interface/interface_eyedropper_datablock.c @@ -32,6 +32,7 @@ #include "DNA_screen_types.h" #include "DNA_space_types.h" +#include "BLI_math_vector.h" #include "BLI_string.h" #include "BLT_translation.h" @@ -80,7 +81,7 @@ static void datadropper_draw_cb(const struct bContext *UNUSED(C), void *arg) { DataDropper *ddr = arg; - eyedropper_draw_cursor_text_region(UNPACK2(ddr->name_pos), ddr->name); + eyedropper_draw_cursor_text_region(ddr->name_pos, ddr->name); } static int datadropper_init(bContext *C, wmOperator *op) @@ -152,7 +153,7 @@ static void datadropper_exit(bContext *C, wmOperator *op) * \brief get the ID from the 3D view or outliner. */ static void datadropper_id_sample_pt( - bContext *C, wmWindow *win, ScrArea *area, DataDropper *ddr, int mx, int my, ID **r_id) + bContext *C, wmWindow *win, ScrArea *area, DataDropper *ddr, const int m_xy[2], ID **r_id) { wmWindow *win_prev = CTX_wm_window(C); ScrArea *area_prev = CTX_wm_area(C); @@ -162,9 +163,9 @@ static void datadropper_id_sample_pt( if (area) { if (ELEM(area->spacetype, SPACE_VIEW3D, SPACE_OUTLINER)) { - ARegion *region = BKE_area_find_region_xy(area, RGN_TYPE_WINDOW, (const int[2]){mx, my}); + ARegion *region = BKE_area_find_region_xy(area, RGN_TYPE_WINDOW, m_xy); if (region) { - const int mval[2] = {mx - region->winrct.xmin, my - region->winrct.ymin}; + const int mval[2] = {m_xy[0] - region->winrct.xmin, m_xy[1] - region->winrct.ymin}; Base *base; CTX_wm_window_set(C, win); @@ -205,8 +206,7 @@ static void datadropper_id_sample_pt( *r_id = id; } - ddr->name_pos[0] = mval[0]; - ddr->name_pos[1] = mval[1]; + copy_v2_v2_int(ddr->name_pos, mval); } } } @@ -234,17 +234,16 @@ static bool datadropper_id_set(bContext *C, DataDropper *ddr, ID *id) } /* single point sample & set */ -static bool datadropper_id_sample(bContext *C, DataDropper *ddr, int mx, int my) +static bool datadropper_id_sample(bContext *C, DataDropper *ddr, const int m_xy[2]) { ID *id = NULL; + int mval[2]; wmWindow *win; ScrArea *area; + datadropper_win_area_find(C, m_xy, mval, &win, &area); - int mval[] = {mx, my}; - datadropper_win_area_find(C, mval, mval, &win, &area); - - datadropper_id_sample_pt(C, win, area, ddr, mval[0], mval[1], &id); + datadropper_id_sample_pt(C, win, area, ddr, mval, &id); return datadropper_id_set(C, ddr, id); } @@ -292,7 +291,7 @@ static int datadropper_modal(bContext *C, wmOperator *op, const wmEvent *event) return OPERATOR_CANCELLED; case EYE_MODAL_SAMPLE_CONFIRM: { const bool is_undo = ddr->is_undo; - const bool success = datadropper_id_sample(C, ddr, event->xy[0], event->xy[1]); + const bool success = datadropper_id_sample(C, ddr, event->xy); datadropper_exit(C, op); if (success) { /* Could support finished & undo-skip. */ @@ -306,16 +305,15 @@ static int datadropper_modal(bContext *C, wmOperator *op, const wmEvent *event) else if (event->type == MOUSEMOVE) { ID *id = NULL; + int mval[2]; wmWindow *win; ScrArea *area; - - int mval[] = {event->xy[0], event->xy[1]}; - datadropper_win_area_find(C, mval, mval, &win, &area); + datadropper_win_area_find(C, event->xy, mval, &win, &area); /* Set the region for eyedropper cursor text drawing */ datadropper_set_draw_callback_region(area, ddr); - datadropper_id_sample_pt(C, win, area, ddr, mval[0], mval[1], &id); + datadropper_id_sample_pt(C, win, area, ddr, mval, &id); } return OPERATOR_RUNNING_MODAL; diff --git a/source/blender/editors/interface/interface_eyedropper_depth.c b/source/blender/editors/interface/interface_eyedropper_depth.c index 8c6b0ac9cfe..b11001c4bf2 100644 --- a/source/blender/editors/interface/interface_eyedropper_depth.c +++ b/source/blender/editors/interface/interface_eyedropper_depth.c @@ -81,7 +81,7 @@ static void depthdropper_draw_cb(const struct bContext *UNUSED(C), void *arg) { DepthDropper *ddr = arg; - eyedropper_draw_cursor_text_region(UNPACK2(ddr->name_pos), ddr->name); + eyedropper_draw_cursor_text_region(ddr->name_pos, ddr->name); } static int depthdropper_init(bContext *C, wmOperator *op) @@ -152,12 +152,14 @@ static void depthdropper_exit(bContext *C, wmOperator *op) /** * \brief get the ID from the screen. */ -static void depthdropper_depth_sample_pt( - bContext *C, DepthDropper *ddr, int mx, int my, float *r_depth) +static void depthdropper_depth_sample_pt(bContext *C, + DepthDropper *ddr, + const int m_xy[2], + float *r_depth) { /* we could use some clever */ bScreen *screen = CTX_wm_screen(C); - ScrArea *area = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, (const int[2]){mx, my}); + ScrArea *area = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, m_xy); Scene *scene = CTX_data_scene(C); ScrArea *area_prev = CTX_wm_area(C); @@ -167,14 +169,14 @@ static void depthdropper_depth_sample_pt( if (area) { if (area->spacetype == SPACE_VIEW3D) { - ARegion *region = BKE_area_find_region_xy(area, RGN_TYPE_WINDOW, (const int[2]){mx, my}); + ARegion *region = BKE_area_find_region_xy(area, RGN_TYPE_WINDOW, m_xy); if (region) { struct Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); View3D *v3d = area->spacedata.first; RegionView3D *rv3d = region->regiondata; /* weak, we could pass in some reference point */ const float *view_co = v3d->camera ? v3d->camera->obmat[3] : rv3d->viewinv[3]; - const int mval[2] = {mx - region->winrct.xmin, my - region->winrct.ymin}; + const int mval[2] = {m_xy[0] - region->winrct.xmin, m_xy[1] - region->winrct.ymin}; copy_v2_v2_int(ddr->name_pos, mval); float co[3]; @@ -234,19 +236,19 @@ static void depthdropper_depth_set_accum(bContext *C, DepthDropper *ddr) } /* single point sample & set */ -static void depthdropper_depth_sample(bContext *C, DepthDropper *ddr, int mx, int my) +static void depthdropper_depth_sample(bContext *C, DepthDropper *ddr, const int m_xy[2]) { float depth = -1.0f; if (depth != -1.0f) { - depthdropper_depth_sample_pt(C, ddr, mx, my, &depth); + depthdropper_depth_sample_pt(C, ddr, m_xy, &depth); depthdropper_depth_set(C, ddr, depth); } } -static void depthdropper_depth_sample_accum(bContext *C, DepthDropper *ddr, int mx, int my) +static void depthdropper_depth_sample_accum(bContext *C, DepthDropper *ddr, const int m_xy[2]) { float depth = -1.0f; - depthdropper_depth_sample_pt(C, ddr, mx, my, &depth); + depthdropper_depth_sample_pt(C, ddr, m_xy, &depth); if (depth != -1.0f) { ddr->accum_depth += depth; ddr->accum_tot++; @@ -276,7 +278,7 @@ static int depthdropper_modal(bContext *C, wmOperator *op, const wmEvent *event) case EYE_MODAL_SAMPLE_CONFIRM: { const bool is_undo = ddr->is_undo; if (ddr->accum_tot == 0) { - depthdropper_depth_sample(C, ddr, event->xy[0], event->xy[1]); + depthdropper_depth_sample(C, ddr, event->xy); } else { depthdropper_depth_set_accum(C, ddr); @@ -288,12 +290,12 @@ static int depthdropper_modal(bContext *C, wmOperator *op, const wmEvent *event) case EYE_MODAL_SAMPLE_BEGIN: /* enable accum and make first sample */ ddr->accum_start = true; - depthdropper_depth_sample_accum(C, ddr, event->xy[0], event->xy[1]); + depthdropper_depth_sample_accum(C, ddr, event->xy); break; case EYE_MODAL_SAMPLE_RESET: ddr->accum_tot = 0; ddr->accum_depth = 0.0f; - depthdropper_depth_sample_accum(C, ddr, event->xy[0], event->xy[1]); + depthdropper_depth_sample_accum(C, ddr, event->xy); depthdropper_depth_set_accum(C, ddr); break; } @@ -301,7 +303,7 @@ static int depthdropper_modal(bContext *C, wmOperator *op, const wmEvent *event) else if (event->type == MOUSEMOVE) { if (ddr->accum_start) { /* button is pressed so keep sampling */ - depthdropper_depth_sample_accum(C, ddr, event->xy[0], event->xy[1]); + depthdropper_depth_sample_accum(C, ddr, event->xy); depthdropper_depth_set_accum(C, ddr); } } diff --git a/source/blender/editors/interface/interface_eyedropper_gpencil_color.c b/source/blender/editors/interface/interface_eyedropper_gpencil_color.c index d76ff84bcad..c1d49406818 100644 --- a/source/blender/editors/interface/interface_eyedropper_gpencil_color.c +++ b/source/blender/editors/interface/interface_eyedropper_gpencil_color.c @@ -265,9 +265,9 @@ static void eyedropper_gpencil_color_set(bContext *C, const wmEvent *event, Eyed } /* Sample the color below cursor. */ -static void eyedropper_gpencil_color_sample(bContext *C, EyedropperGPencil *eye, int mx, int my) +static void eyedropper_gpencil_color_sample(bContext *C, EyedropperGPencil *eye, const int m_xy[2]) { - eyedropper_color_sample_fl(C, mx, my, eye->color); + eyedropper_color_sample_fl(C, m_xy, eye->color); } /* Cancel operator. */ @@ -292,7 +292,7 @@ static int eyedropper_gpencil_modal(bContext *C, wmOperator *op, const wmEvent * return OPERATOR_CANCELLED; } case EYE_MODAL_SAMPLE_CONFIRM: { - eyedropper_gpencil_color_sample(C, eye, event->xy[0], event->xy[1]); + eyedropper_gpencil_color_sample(C, eye, event->xy); /* Create material. */ eyedropper_gpencil_color_set(C, event, eye); @@ -309,7 +309,7 @@ static int eyedropper_gpencil_modal(bContext *C, wmOperator *op, const wmEvent * } case MOUSEMOVE: case INBETWEEN_MOUSEMOVE: { - eyedropper_gpencil_color_sample(C, eye, event->xy[0], event->xy[1]); + eyedropper_gpencil_color_sample(C, eye, event->xy); break; } default: { diff --git a/source/blender/editors/interface/interface_eyedropper_intern.h b/source/blender/editors/interface/interface_eyedropper_intern.h index ec448ef9b9f..335ee520791 100644 --- a/source/blender/editors/interface/interface_eyedropper_intern.h +++ b/source/blender/editors/interface/interface_eyedropper_intern.h @@ -25,7 +25,7 @@ /* interface_eyedropper.c */ void eyedropper_draw_cursor_text_window(const struct wmWindow *window, const char *name); -void eyedropper_draw_cursor_text_region(int x, int y, const char *name); +void eyedropper_draw_cursor_text_region(const int xy[2], const char *name); /** * Utility to retrieve a button representing a RNA property that is currently under the cursor. * @@ -51,7 +51,7 @@ void datadropper_win_area_find(const struct bContext *C, * * \note Exposed by 'interface_eyedropper_intern.h' for use with color band picking. */ -void eyedropper_color_sample_fl(bContext *C, int mx, int my, float r_col[3]); +void eyedropper_color_sample_fl(bContext *C, const int m_xy[2], float r_col[3]); /* Used for most eye-dropper operators. */ enum { diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c index 905fd452b6c..a171160d020 100644 --- a/source/blender/editors/interface/interface_handlers.c +++ b/source/blender/editors/interface/interface_handlers.c @@ -3957,7 +3957,14 @@ static void ui_do_but_textedit( ui_textedit_delete_selection(but, data); } if (event->type == WM_IME_COMPOSITE_EVENT && ime_data->result_len) { - ui_textedit_insert_buf(but, data, ime_data->str_result, ime_data->result_len); + if (ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER) && + strcmp(ime_data->str_result, "\xE3\x80\x82") == 0) { + /* Convert Ideographic Full Stop (U+3002) to decimal point when entering numbers. */ + ui_textedit_insert_ascii(but, data, '.'); + } + else { + ui_textedit_insert_buf(but, data, ime_data->str_result, ime_data->result_len); + } } } else if (event->type == WM_IME_COMPOSITE_END) { diff --git a/source/blender/editors/interface/interface_style.c b/source/blender/editors/interface/interface_style.c index 44942d508ca..1fe538eca5d 100644 --- a/source/blender/editors/interface/interface_style.c +++ b/source/blender/editors/interface/interface_style.c @@ -39,9 +39,8 @@ #include "BKE_global.h" #include "BLF_api.h" -#ifdef WITH_INTERNATIONAL -# include "BLT_translation.h" -#endif + +#include "BLT_translation.h" #include "UI_interface.h" diff --git a/source/blender/editors/io/CMakeLists.txt b/source/blender/editors/io/CMakeLists.txt index cb1c3cedf8e..5db16354124 100644 --- a/source/blender/editors/io/CMakeLists.txt +++ b/source/blender/editors/io/CMakeLists.txt @@ -84,10 +84,6 @@ if(WITH_USD) add_definitions(-DWITH_USD) endif() -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() - if(WITH_PUGIXML) add_definitions(-DWITH_PUGIXML) endif() diff --git a/source/blender/editors/mesh/CMakeLists.txt b/source/blender/editors/mesh/CMakeLists.txt index 4ad2e57d266..0fb64c8a46b 100644 --- a/source/blender/editors/mesh/CMakeLists.txt +++ b/source/blender/editors/mesh/CMakeLists.txt @@ -78,10 +78,6 @@ set(LIB bf_windowmanager ) -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() - if(WITH_FREESTYLE) add_definitions(-DWITH_FREESTYLE) endif() diff --git a/source/blender/editors/metaball/CMakeLists.txt b/source/blender/editors/metaball/CMakeLists.txt index 4e600dc0277..a247920c305 100644 --- a/source/blender/editors/metaball/CMakeLists.txt +++ b/source/blender/editors/metaball/CMakeLists.txt @@ -20,6 +20,7 @@ set(INC ../../blenkernel ../../blenlib ../../depsgraph + ../../gpu ../../makesdna ../../makesrna ../../render diff --git a/source/blender/editors/metaball/mball_edit.c b/source/blender/editors/metaball/mball_edit.c index bedb9d4f4f4..51cfc920d1d 100644 --- a/source/blender/editors/metaball/mball_edit.c +++ b/source/blender/editors/metaball/mball_edit.c @@ -47,6 +47,8 @@ #include "DEG_depsgraph.h" +#include "GPU_select.h" + #include "ED_mball.h" #include "ED_object.h" #include "ED_screen.h" @@ -756,15 +758,19 @@ bool ED_mball_select_pick(bContext *C, const int mval[2], bool extend, bool dese static MetaElem *startelem = NULL; ViewContext vc; int a, hits; - uint buffer[MAXPICKBUF]; + GPUSelectResult buffer[MAXPICKELEMS]; rcti rect; ED_view3d_viewcontext_init(C, &vc, depsgraph); BLI_rcti_init_pt_radius(&rect, mval, 12); - hits = view3d_opengl_select( - &vc, buffer, MAXPICKBUF, &rect, VIEW3D_SELECT_PICK_NEAREST, VIEW3D_SELECT_FILTER_NOP); + hits = view3d_opengl_select(&vc, + buffer, + ARRAY_SIZE(buffer), + &rect, + VIEW3D_SELECT_PICK_NEAREST, + VIEW3D_SELECT_FILTER_NOP); FOREACH_BASE_IN_EDIT_MODE_BEGIN (vc.view_layer, vc.v3d, base) { ED_view3d_viewcontext_init_object(&vc, base->object); @@ -789,7 +795,7 @@ bool ED_mball_select_pick(bContext *C, const int mval[2], bool extend, bool dese ml = startelem; while (ml) { for (a = 0; a < hits; a++) { - int hitresult = buffer[(4 * a) + 3]; + const int hitresult = buffer[a].id; if (hitresult == -1) { continue; } diff --git a/source/blender/editors/object/CMakeLists.txt b/source/blender/editors/object/CMakeLists.txt index 040b5cd5066..a953c7d7f89 100644 --- a/source/blender/editors/object/CMakeLists.txt +++ b/source/blender/editors/object/CMakeLists.txt @@ -85,10 +85,6 @@ if(WITH_PYTHON) add_definitions(-DWITH_PYTHON) endif() -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() - if(WITH_EXPERIMENTAL_FEATURES) add_definitions(-DWITH_SIMULATION_DATABLOCK) add_definitions(-DWITH_POINT_CLOUD) diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c index a6eb35d49b9..ee594398f4a 100644 --- a/source/blender/editors/object/object_relations.c +++ b/source/blender/editors/object/object_relations.c @@ -2334,7 +2334,7 @@ static int make_override_library_exec(bContext *C, wmOperator *op) BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false); const bool success = BKE_lib_override_library_create( - bmain, scene, view_layer, id_root, &obact->id, NULL); + bmain, scene, view_layer, NULL, id_root, &obact->id, NULL); /* Remove the instance empty from this scene, the items now have an overridden collection * instead. */ diff --git a/source/blender/editors/object/object_vgroup.c b/source/blender/editors/object/object_vgroup.c index 3e74aaeeb10..e21e815b56f 100644 --- a/source/blender/editors/object/object_vgroup.c +++ b/source/blender/editors/object/object_vgroup.c @@ -39,6 +39,7 @@ #include "BLI_alloca.h" #include "BLI_array.h" +#include "BLI_bitmap.h" #include "BLI_blenlib.h" #include "BLI_listbase.h" #include "BLI_math.h" @@ -2464,17 +2465,14 @@ void ED_vgroup_mirror(Object *ob, sel = sel_mirr = true; } - /* tag verts we have used */ - for (vidx = 0, mv = me->mvert; vidx < me->totvert; vidx++, mv++) { - mv->flag &= ~ME_VERT_TMP_TAG; - } + BLI_bitmap *vert_tag = BLI_BITMAP_NEW(me->totvert, __func__); for (vidx = 0, mv = me->mvert; vidx < me->totvert; vidx++, mv++) { - if ((mv->flag & ME_VERT_TMP_TAG) == 0) { + if (!BLI_BITMAP_TEST(vert_tag, vidx)) { if ((vidx_mirr = mesh_get_x_mirror_vert(ob, NULL, vidx, use_topology)) != -1) { if (vidx != vidx_mirr) { mv_mirr = &me->mvert[vidx_mirr]; - if ((mv_mirr->flag & ME_VERT_TMP_TAG) == 0) { + if (!BLI_BITMAP_TEST(vert_tag, vidx_mirr)) { if (use_vert_sel) { sel = mv->flag & SELECT; @@ -2489,8 +2487,8 @@ void ED_vgroup_mirror(Object *ob, totmirr++; } - mv->flag |= ME_VERT_TMP_TAG; - mv_mirr->flag |= ME_VERT_TMP_TAG; + BLI_BITMAP_ENABLE(vert_tag, vidx); + BLI_BITMAP_ENABLE(vert_tag, vidx_mirr); } } } @@ -2499,6 +2497,8 @@ void ED_vgroup_mirror(Object *ob, } } } + + MEM_freeN(vert_tag); } } else if (ob->type == OB_LATTICE) { diff --git a/source/blender/editors/physics/CMakeLists.txt b/source/blender/editors/physics/CMakeLists.txt index a607663763e..7c32a2dcf1d 100644 --- a/source/blender/editors/physics/CMakeLists.txt +++ b/source/blender/editors/physics/CMakeLists.txt @@ -60,10 +60,6 @@ if(WITH_MOD_FLUID) add_definitions(-DWITH_FLUID) endif() -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() - if(WITH_BULLET) list(APPEND INC ../../../../intern/rigidbody diff --git a/source/blender/editors/render/CMakeLists.txt b/source/blender/editors/render/CMakeLists.txt index 1f867c6f1f7..934badd3b6f 100644 --- a/source/blender/editors/render/CMakeLists.txt +++ b/source/blender/editors/render/CMakeLists.txt @@ -67,8 +67,4 @@ if(WITH_FREESTYLE) add_definitions(-DWITH_FREESTYLE) endif() -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() - blender_add_lib(bf_editor_render "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/editors/scene/CMakeLists.txt b/source/blender/editors/scene/CMakeLists.txt index cd59f06c6e3..ce0c2062766 100644 --- a/source/blender/editors/scene/CMakeLists.txt +++ b/source/blender/editors/scene/CMakeLists.txt @@ -39,8 +39,5 @@ set(LIB bf_blenlib ) -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() blender_add_lib(bf_editor_scene "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/editors/screen/CMakeLists.txt b/source/blender/editors/screen/CMakeLists.txt index d194d0cdbb6..7c5ae4dcd5e 100644 --- a/source/blender/editors/screen/CMakeLists.txt +++ b/source/blender/editors/screen/CMakeLists.txt @@ -57,9 +57,5 @@ set(LIB bf_editor_space_sequencer ) -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() - blender_add_lib(bf_editor_screen "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c index 6581bffb6bd..8b6e6b4ef9b 100644 --- a/source/blender/editors/screen/screen_ops.c +++ b/source/blender/editors/screen/screen_ops.c @@ -2608,7 +2608,7 @@ typedef struct RegionMoveData { ARegion *region; ScrArea *area; int bigger, smaller, origval; - int origx, origy; + int orig_xy[2]; int maxsize; AZEdge edge; @@ -2716,8 +2716,7 @@ static int region_scale_invoke(bContext *C, wmOperator *op, const wmEvent *event } rmd->area = sad->sa1; rmd->edge = az->edge; - rmd->origx = event->xy[0]; - rmd->origy = event->xy[1]; + copy_v2_v2_int(rmd->orig_xy, event->xy); rmd->maxsize = area_max_regionsize(rmd->area, rmd->region, rmd->edge); /* if not set we do now, otherwise it uses type */ @@ -2804,7 +2803,7 @@ static int region_scale_modal(bContext *C, wmOperator *op, const wmEvent *event) (BLI_rcti_size_x(&rmd->region->v2d.mask) + 1); const int snap_size_threshold = (U.widget_unit * 2) / aspect; if (ELEM(rmd->edge, AE_LEFT_TO_TOPRIGHT, AE_RIGHT_TO_TOPLEFT)) { - delta = event->xy[0] - rmd->origx; + delta = event->xy[0] - rmd->orig_xy[0]; if (rmd->edge == AE_LEFT_TO_TOPRIGHT) { delta = -delta; } @@ -2837,7 +2836,7 @@ static int region_scale_modal(bContext *C, wmOperator *op, const wmEvent *event) } } else { - delta = event->xy[1] - rmd->origy; + delta = event->xy[1] - rmd->orig_xy[1]; if (rmd->edge == AE_BOTTOM_TO_TOPLEFT) { delta = -delta; } @@ -2879,7 +2878,7 @@ static int region_scale_modal(bContext *C, wmOperator *op, const wmEvent *event) } case LEFTMOUSE: if (event->val == KM_RELEASE) { - if (len_manhattan_v2v2_int(event->xy, &rmd->origx) <= WM_EVENT_CURSOR_MOTION_THRESHOLD) { + if (len_manhattan_v2v2_int(event->xy, rmd->orig_xy) <= WM_EVENT_CURSOR_MOTION_THRESHOLD) { if (rmd->region->flag & RGN_FLAG_HIDDEN) { region_scale_toggle_hidden(C, rmd); } diff --git a/source/blender/editors/sculpt_paint/CMakeLists.txt b/source/blender/editors/sculpt_paint/CMakeLists.txt index b15b6784d34..907080626e0 100644 --- a/source/blender/editors/sculpt_paint/CMakeLists.txt +++ b/source/blender/editors/sculpt_paint/CMakeLists.txt @@ -90,9 +90,5 @@ set(LIB bf_blenlib ) -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() - blender_add_lib(bf_editor_sculpt_paint "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c index ca012f20f01..f05cd4c3d5f 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.c +++ b/source/blender/editors/sculpt_paint/paint_image_proj.c @@ -1730,17 +1730,12 @@ static float project_paint_uvpixel_mask(const ProjPaintState *ps, normalize_v3(no); } else { -#if 1 /* In case the normalizing per pixel isn't optimal, * we could cache or access from evaluated mesh. */ normal_tri_v3(no, ps->mvert_eval[lt_vtri[0]].co, ps->mvert_eval[lt_vtri[1]].co, ps->mvert_eval[lt_vtri[2]].co); -#else - /* Don't use because some modifiers don't have normal data (subsurf for eg). */ - copy_v3_v3(no, (float *)ps->dm->getTessFaceData(ps->dm, tri_index, CD_NORMAL)); -#endif } if (UNLIKELY(ps->is_flip_object)) { diff --git a/source/blender/editors/space_buttons/CMakeLists.txt b/source/blender/editors/space_buttons/CMakeLists.txt index b5f6874fcfc..e2b2579c256 100644 --- a/source/blender/editors/space_buttons/CMakeLists.txt +++ b/source/blender/editors/space_buttons/CMakeLists.txt @@ -40,10 +40,6 @@ set(SRC set(LIB ) -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() - if(WITH_FREESTYLE) add_definitions(-DWITH_FREESTYLE) diff --git a/source/blender/editors/space_clip/CMakeLists.txt b/source/blender/editors/space_clip/CMakeLists.txt index db881dafa6b..8f1a2c3c81e 100644 --- a/source/blender/editors/space_clip/CMakeLists.txt +++ b/source/blender/editors/space_clip/CMakeLists.txt @@ -68,11 +68,6 @@ set(LIB ) -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() - - blender_add_lib(bf_editor_space_clip "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") # Needed so we can use dna_type_offsets.h for defaults initialization. diff --git a/source/blender/editors/space_file/CMakeLists.txt b/source/blender/editors/space_file/CMakeLists.txt index cbeb2e6f529..1df0c9c4409 100644 --- a/source/blender/editors/space_file/CMakeLists.txt +++ b/source/blender/editors/space_file/CMakeLists.txt @@ -92,10 +92,6 @@ if(WITH_IMAGE_HDR) add_definitions(-DWITH_HDR) endif() -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() - if(WITH_FREESTYLE) add_definitions(-DWITH_FREESTYLE) diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index 2d31e8030a4..044d7aba88f 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -524,7 +524,7 @@ static int compare_apply_inverted(int val, const struct FileSortData *sort_data) * 2) If not possible (file names match) and both represent local IDs, sort by ID-type. * 3) If not possible and only one is a local ID, place files representing local IDs first. * - * TODO (not actually implemented, but should be): + * TODO: (not actually implemented, but should be): * 4) If no file represents a local ID, sort by file path, so that files higher up the file system * hierarchy are placed first. */ diff --git a/source/blender/editors/space_file/fsmenu.c b/source/blender/editors/space_file/fsmenu.c index 14f596ae7bf..0a69d0f9b39 100644 --- a/source/blender/editors/space_file/fsmenu.c +++ b/source/blender/editors/space_file/fsmenu.c @@ -745,14 +745,17 @@ void fsmenu_read_system(struct FSMenu *fsmenu, int read_bookmarks) N_("Fonts"), ICON_FILE_FONT, FS_INSERT_LAST); + fsmenu_add_windows_folder(fsmenu, + FS_CATEGORY_SYSTEM_BOOKMARKS, + &FOLDERID_SkyDrive, + N_("OneDrive"), + ICON_URL, + FS_INSERT_LAST); /* These items are just put in path cache for thumbnail views and if bookmarked. */ fsmenu_add_windows_folder( fsmenu, FS_CATEGORY_OTHER, &FOLDERID_UserProfiles, NULL, ICON_COMMUNITY, FS_INSERT_LAST); - - fsmenu_add_windows_folder( - fsmenu, FS_CATEGORY_OTHER, &FOLDERID_SkyDrive, NULL, ICON_URL, FS_INSERT_LAST); } } #elif defined(__APPLE__) diff --git a/source/blender/editors/space_graph/CMakeLists.txt b/source/blender/editors/space_graph/CMakeLists.txt index 2a795dd954c..2e6e6971ce9 100644 --- a/source/blender/editors/space_graph/CMakeLists.txt +++ b/source/blender/editors/space_graph/CMakeLists.txt @@ -61,9 +61,5 @@ if(WITH_AUDASPACE) add_definitions(-DWITH_AUDASPACE) endif() -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() - blender_add_lib(bf_editor_space_graph "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/editors/space_image/CMakeLists.txt b/source/blender/editors/space_image/CMakeLists.txt index 7a1bab0ef14..25d0e02ecc0 100644 --- a/source/blender/editors/space_image/CMakeLists.txt +++ b/source/blender/editors/space_image/CMakeLists.txt @@ -53,10 +53,6 @@ set(LIB bf_editor_uvedit ) -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() - if(WITH_OPENIMAGEIO) add_definitions(-DWITH_OPENIMAGEIO) endif() diff --git a/source/blender/editors/space_image/image_undo.c b/source/blender/editors/space_image/image_undo.c index e81f3b6a490..73993606a14 100644 --- a/source/blender/editors/space_image/image_undo.c +++ b/source/blender/editors/space_image/image_undo.c @@ -1000,7 +1000,7 @@ void ED_image_undosys_type(UndoType *ut) ut->step_foreach_ID_ref = image_undosys_foreach_ID_ref; - /* NOTE this is actually a confusing case, since it expects a valid context, but only in a + /* NOTE: this is actually a confusing case, since it expects a valid context, but only in a * specific case, see `image_undosys_step_encode` code. We cannot specify * `UNDOTYPE_FLAG_NEED_CONTEXT_FOR_ENCODE` though, as it can be called with a NULL context by * current code. */ diff --git a/source/blender/editors/space_info/CMakeLists.txt b/source/blender/editors/space_info/CMakeLists.txt index 144b21fb9b8..fb17a6c9709 100644 --- a/source/blender/editors/space_info/CMakeLists.txt +++ b/source/blender/editors/space_info/CMakeLists.txt @@ -48,9 +48,5 @@ set(SRC set(LIB ) -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() - blender_add_lib(bf_editor_space_info "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/editors/space_nla/CMakeLists.txt b/source/blender/editors/space_nla/CMakeLists.txt index 9a94d28c604..5326f1cce2b 100644 --- a/source/blender/editors/space_nla/CMakeLists.txt +++ b/source/blender/editors/space_nla/CMakeLists.txt @@ -47,9 +47,5 @@ set(LIB bf_blenlib ) -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() - blender_add_lib(bf_editor_space_nla "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/editors/space_node/CMakeLists.txt b/source/blender/editors/space_node/CMakeLists.txt index 41d6388c947..15e0d04c8fa 100644 --- a/source/blender/editors/space_node/CMakeLists.txt +++ b/source/blender/editors/space_node/CMakeLists.txt @@ -63,10 +63,6 @@ set(LIB bf_editor_screen ) -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() - if(WITH_COMPOSITOR) add_definitions(-DWITH_COMPOSITOR) endif() diff --git a/source/blender/editors/space_outliner/CMakeLists.txt b/source/blender/editors/space_outliner/CMakeLists.txt index bc6db978a4f..d97f48bcb68 100644 --- a/source/blender/editors/space_outliner/CMakeLists.txt +++ b/source/blender/editors/space_outliner/CMakeLists.txt @@ -95,9 +95,5 @@ set(LIB bf_editor_undo ) -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() - blender_add_lib(bf_editor_space_outliner "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/editors/space_outliner/outliner_intern.hh b/source/blender/editors/space_outliner/outliner_intern.hh index 9db1d73dc76..bd288241a63 100644 --- a/source/blender/editors/space_outliner/outliner_intern.hh +++ b/source/blender/editors/space_outliner/outliner_intern.hh @@ -57,10 +57,12 @@ class AbstractTreeDisplay; class AbstractTreeElement; } // namespace blender::ed::outliner +namespace outliner = blender::ed::outliner; + struct SpaceOutliner_Runtime { /** Object to create and manage the tree for a specific display type (View Layers, Scenes, * Blender File, etc.). */ - std::unique_ptr<blender::ed::outliner::AbstractTreeDisplay> tree_display; + std::unique_ptr<outliner::AbstractTreeDisplay> tree_display; /** Pointers to tree-store elements, grouped by `(id, type, nr)` * in hash-table for faster searching. */ @@ -93,11 +95,12 @@ typedef struct TreeElement { struct TreeElement *next, *prev, *parent; /** - * Handle to the new C++ object (a derived type of base #AbstractTreeElement) that should replace - * #TreeElement. Step by step, data should be moved to it and operations based on the type should - * become virtual methods of the class hierarchy. + * The new inheritance based representation of the element (a derived type of base + * #AbstractTreeElement) that should eventually replace #TreeElement. Step by step, data should + * be moved to it and operations based on the type should become virtual methods of the class + * hierarchy. */ - std::unique_ptr<blender::ed::outliner::AbstractTreeElement> type; + std::unique_ptr<outliner::AbstractTreeElement> abstract_element; ListBase subtree; int xs, ys; /* Do selection. */ @@ -700,7 +703,7 @@ template<typename TreeElementT> TreeElementT *tree_element_cast(const TreeElemen { static_assert(std::is_base_of_v<AbstractTreeElement, TreeElementT>, "Requested tree-element type must be an AbstractTreeElement"); - return dynamic_cast<TreeElementT *>(te->type.get()); + return dynamic_cast<TreeElementT *>(te->abstract_element.get()); } } // namespace blender::ed::outliner diff --git a/source/blender/editors/space_outliner/outliner_tools.cc b/source/blender/editors/space_outliner/outliner_tools.cc index 03fc4c20fe5..02e8ab2f128 100644 --- a/source/blender/editors/space_outliner/outliner_tools.cc +++ b/source/blender/editors/space_outliner/outliner_tools.cc @@ -875,7 +875,7 @@ static void id_override_library_create_fn(bContext *C, } success = BKE_lib_override_library_create( - bmain, CTX_data_scene(C), CTX_data_view_layer(C), id_root, id_reference, nullptr); + bmain, CTX_data_scene(C), CTX_data_view_layer(C), NULL, id_root, id_reference, nullptr); } else if (ID_IS_OVERRIDABLE_LIBRARY(id_root)) { success = BKE_lib_override_library_create_from_id(bmain, id_root, true) != nullptr; diff --git a/source/blender/editors/space_outliner/outliner_tree.cc b/source/blender/editors/space_outliner/outliner_tree.cc index eb885eba20d..d8fe17a570f 100644 --- a/source/blender/editors/space_outliner/outliner_tree.cc +++ b/source/blender/editors/space_outliner/outliner_tree.cc @@ -217,7 +217,7 @@ void outliner_free_tree_element(TreeElement *element, ListBase *parent_subtree) if (element->flag & TE_FREE_NAME) { MEM_freeN((void *)element->name); } - element->type = nullptr; + element->abstract_element = nullptr; MEM_delete(element); } @@ -860,10 +860,10 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner, te->parent = parent; te->index = index; /* For data arrays. */ - /* New C++ based type handle. Only some support this, eventually this should replace - * `TreeElement` entirely. */ - te->type = AbstractTreeElement::createFromType(type, *te, idv); - if (te->type) { + /* New inheritance based element representation. Not all element types support this yet, + * eventually it should replace #TreeElement entirely. */ + te->abstract_element = AbstractTreeElement::createFromType(type, *te, idv); + if (te->abstract_element) { /* Element types ported to the new design are expected to have their name set at this point! */ BLI_assert(te->name != nullptr); } @@ -887,12 +887,12 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner, /* pass */ } else if (type == TSE_SOME_ID) { - if (!te->type) { + if (!te->abstract_element) { BLI_assert_msg(0, "Expected this ID type to be ported to new Outliner tree-element design"); } } else if (ELEM(type, TSE_LIBRARY_OVERRIDE_BASE, TSE_LIBRARY_OVERRIDE)) { - if (!te->type) { + if (!te->abstract_element) { BLI_assert_msg(0, "Expected override types to be ported to new Outliner tree-element design"); } @@ -903,20 +903,20 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner, /* The new type design sets the name already, don't override that here. We need to figure out * how to deal with the idcode for non-TSE_SOME_ID types still. Some rely on it... */ - if (!te->type) { + if (!te->abstract_element) { te->name = id->name + 2; /* Default, can be overridden by Library or non-ID data. */ } te->idcode = GS(id->name); } - if (te->type && te->type->isExpandValid()) { - tree_element_expand(*te->type, *space_outliner); + if (te->abstract_element && te->abstract_element->isExpandValid()) { + tree_element_expand(*te->abstract_element, *space_outliner); } else if (type == TSE_SOME_ID) { /* ID types not (fully) ported to new design yet. */ - if (te->type->expandPoll(*space_outliner)) { + if (te->abstract_element->expandPoll(*space_outliner)) { outliner_add_id_contents(space_outliner, te, tselem, id); - te->type->postExpand(*space_outliner); + te->abstract_element->postExpand(*space_outliner); } } else if (ELEM(type, diff --git a/source/blender/editors/space_sequencer/CMakeLists.txt b/source/blender/editors/space_sequencer/CMakeLists.txt index bf8cf89699d..d93dc0ac0c0 100644 --- a/source/blender/editors/space_sequencer/CMakeLists.txt +++ b/source/blender/editors/space_sequencer/CMakeLists.txt @@ -70,9 +70,5 @@ if(WITH_AUDASPACE) ) endif() -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() - blender_add_lib(bf_editor_space_sequencer "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/editors/space_text/CMakeLists.txt b/source/blender/editors/space_text/CMakeLists.txt index abd7620ea2b..a85c69caa50 100644 --- a/source/blender/editors/space_text/CMakeLists.txt +++ b/source/blender/editors/space_text/CMakeLists.txt @@ -61,8 +61,5 @@ if(WITH_PYTHON) add_definitions(-DWITH_PYTHON) endif() -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() blender_add_lib(bf_editor_space_text "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/editors/space_userpref/userpref_ops.c b/source/blender/editors/space_userpref/userpref_ops.c index d40229332fd..e4c11bc8668 100644 --- a/source/blender/editors/space_userpref/userpref_ops.c +++ b/source/blender/editors/space_userpref/userpref_ops.c @@ -30,6 +30,7 @@ #ifdef WIN32 # include "BLI_winstuff.h" #endif +#include "BLI_path_util.h" #include "BKE_context.h" #include "BKE_main.h" @@ -142,16 +143,20 @@ static void PREFERENCES_OT_autoexec_path_remove(wmOperatorType *ot) static int preferences_asset_library_add_exec(bContext *UNUSED(C), wmOperator *op) { - char *directory = RNA_string_get_alloc(op->ptr, "directory", NULL, 0, NULL); + char *path = RNA_string_get_alloc(op->ptr, "directory", NULL, 0, NULL); + char dirname[FILE_MAXFILE]; + + BLI_path_slash_rstrip(path); + BLI_split_file_part(path, dirname, sizeof(dirname)); /* NULL is a valid directory path here. A library without path will be created then. */ - BKE_preferences_asset_library_add(&U, NULL, directory); + BKE_preferences_asset_library_add(&U, dirname, path); U.runtime.is_dirty = true; /* There's no dedicated notifier for the Preferences. */ WM_main_add_notifier(NC_WINDOW, NULL); - MEM_freeN(directory); + MEM_freeN(path); return OPERATOR_FINISHED; } diff --git a/source/blender/editors/space_view3d/CMakeLists.txt b/source/blender/editors/space_view3d/CMakeLists.txt index 19f869ed50b..768c2d3e3a6 100644 --- a/source/blender/editors/space_view3d/CMakeLists.txt +++ b/source/blender/editors/space_view3d/CMakeLists.txt @@ -83,11 +83,6 @@ if(WITH_PYTHON) add_definitions(-DWITH_PYTHON) endif() - -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() - if(WITH_FREESTYLE) add_definitions(-DWITH_FREESTYLE) endif() diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c index b1f19581543..6bcb456a945 100644 --- a/source/blender/editors/space_view3d/view3d_draw.c +++ b/source/blender/editors/space_view3d/view3d_draw.c @@ -1258,11 +1258,7 @@ static void draw_viewport_name(ARegion *region, View3D *v3d, int xoffset, int *y /* 6 is the maximum size of the axis roll text. */ /* increase size for unicode languages (Chinese in utf-8...) */ -#ifdef WITH_INTERNATIONAL char tmpstr[96 + 6]; -#else - char tmpstr[32 + 6]; -#endif BLF_enable(font_id, BLF_SHADOW); BLF_shadow(font_id, 5, (const float[4]){0.0f, 0.0f, 0.0f, 1.0f}); @@ -1689,9 +1685,9 @@ void ED_view3d_draw_offscreen(Depsgraph *depsgraph, G.f |= G_FLAG_RENDER_VIEWPORT; { - /* free images which can have changed on frame-change - * warning! can be slow so only free animated images - campbell */ - BKE_image_free_anim_gputextures(G.main); /* XXX :((( */ + /* Free images which can have changed on frame-change. + * WARNING(@campbellbarton): can be slow so only free animated images. */ + BKE_image_free_anim_gputextures(G.main); } GPU_matrix_push_projection(); diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h index 6a1a09df316..1ef737bc84b 100644 --- a/source/blender/editors/space_view3d/view3d_intern.h +++ b/source/blender/editors/space_view3d/view3d_intern.h @@ -40,13 +40,6 @@ struct wmKeyConfig; struct wmOperatorType; struct wmWindowManager; -/* drawing flags: */ -enum { - DRAW_PICKING = (1 << 0), - DRAW_CONSTCOLOR = (1 << 1), - DRAW_SCENESET = (1 << 2), -}; - /* view3d_header.c */ void VIEW3D_OT_toggle_matcap_flip(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_view3d/view3d_select.c b/source/blender/editors/space_view3d/view3d_select.c index 45899880b41..34aa24a1eef 100644 --- a/source/blender/editors/space_view3d/view3d_select.c +++ b/source/blender/editors/space_view3d/view3d_select.c @@ -99,6 +99,7 @@ #include "UI_resources.h" #include "GPU_matrix.h" +#include "GPU_select.h" #include "DEG_depsgraph.h" #include "DEG_depsgraph_query.h" @@ -1566,8 +1567,8 @@ void VIEW3D_OT_select_menu(wmOperatorType *ot) static Base *object_mouse_select_menu(bContext *C, ViewContext *vc, - const uint *buffer, - int hits, + const GPUSelectResult *buffer, + const int hits, const int mval[2], bool extend, bool deselect, @@ -1585,7 +1586,7 @@ static Base *object_mouse_select_menu(bContext *C, if (buffer) { for (int a = 0; a < hits; a++) { /* index was converted */ - if (base->object->runtime.select_id == (buffer[(4 * a) + 3] & ~0xFFFF0000)) { + if (base->object->runtime.select_id == (buffer[a].id & ~0xFFFF0000)) { ok = true; break; } @@ -1742,7 +1743,7 @@ void VIEW3D_OT_bone_select_menu(wmOperatorType *ot) RNA_def_property_flag(prop, PROP_SKIP_SAVE); } static bool bone_mouse_select_menu(bContext *C, - const uint *buffer, + const GPUSelectResult *buffer, const int hits, const bool is_editmode, const bool extend, @@ -1760,7 +1761,7 @@ static bool bone_mouse_select_menu(bContext *C, for (int a = 0; a < hits; a++) { void *bone_ptr = NULL; Base *bone_base = NULL; - uint hitresult = buffer[3 + (a * 4)]; + uint hitresult = buffer[a].id; if (!(hitresult & BONESEL_ANY)) { /* To avoid including objects in selection. */ @@ -1874,10 +1875,10 @@ static bool bone_mouse_select_menu(bContext *C, return true; } -static bool selectbuffer_has_bones(const uint *buffer, const uint hits) +static bool selectbuffer_has_bones(const GPUSelectResult *buffer, const uint hits) { for (uint i = 0; i < hits; i++) { - if (buffer[(4 * i) + 3] & 0xFFFF0000) { + if (buffer[i].id & 0xFFFF0000) { return true; } } @@ -1885,25 +1886,25 @@ static bool selectbuffer_has_bones(const uint *buffer, const uint hits) } /* utility function for mixed_bones_object_selectbuffer */ -static int selectbuffer_ret_hits_15(uint *UNUSED(buffer), const int hits15) +static int selectbuffer_ret_hits_15(GPUSelectResult *UNUSED(buffer), const int hits15) { return hits15; } -static int selectbuffer_ret_hits_9(uint *buffer, const int hits15, const int hits9) +static int selectbuffer_ret_hits_9(GPUSelectResult *buffer, const int hits15, const int hits9) { - const int ofs = 4 * hits15; - memcpy(buffer, buffer + ofs, 4 * hits9 * sizeof(uint)); + const int ofs = hits15; + memcpy(buffer, buffer + ofs, hits9 * sizeof(GPUSelectResult)); return hits9; } -static int selectbuffer_ret_hits_5(uint *buffer, +static int selectbuffer_ret_hits_5(GPUSelectResult *buffer, const int hits15, const int hits9, const int hits5) { - const int ofs = 4 * hits15 + 4 * hits9; - memcpy(buffer, buffer + ofs, 4 * hits5 * sizeof(uint)); + const int ofs = hits15 + hits9; + memcpy(buffer, buffer + ofs, hits5 * sizeof(GPUSelectResult)); return hits5; } @@ -1916,7 +1917,8 @@ static int selectbuffer_ret_hits_5(uint *buffer, * Needed so we can step to the next, non-active object when it's already selected, see: T76445. */ static int mixed_bones_object_selectbuffer(ViewContext *vc, - uint *buffer, + GPUSelectResult *buffer, + const int buffer_len, const int mval[2], eV3DSelectObjectFilter select_filter, bool do_nearest, @@ -1941,7 +1943,7 @@ static int mixed_bones_object_selectbuffer(ViewContext *vc, BLI_rcti_init_pt_radius(&rect, mval, 14); hits15 = view3d_opengl_select_ex( - vc, buffer, MAXPICKBUF, &rect, select_mode, select_filter, do_material_slot_selection); + vc, buffer, buffer_len, &rect, select_mode, select_filter, do_material_slot_selection); if (hits15 == 1) { hits = selectbuffer_ret_hits_15(buffer, hits15); goto finally; @@ -1950,10 +1952,10 @@ static int mixed_bones_object_selectbuffer(ViewContext *vc, int ofs; has_bones15 = selectbuffer_has_bones(buffer, hits15); - ofs = 4 * hits15; + ofs = hits15; BLI_rcti_init_pt_radius(&rect, mval, 9); hits9 = view3d_opengl_select( - vc, buffer + ofs, MAXPICKBUF - ofs, &rect, select_mode, select_filter); + vc, buffer + ofs, buffer_len - ofs, &rect, select_mode, select_filter); if (hits9 == 1) { hits = selectbuffer_ret_hits_9(buffer, hits15, hits9); goto finally; @@ -1961,10 +1963,10 @@ static int mixed_bones_object_selectbuffer(ViewContext *vc, else if (hits9 > 0) { has_bones9 = selectbuffer_has_bones(buffer + ofs, hits9); - ofs += 4 * hits9; + ofs += hits9; BLI_rcti_init_pt_radius(&rect, mval, 5); hits5 = view3d_opengl_select( - vc, buffer + ofs, MAXPICKBUF - ofs, &rect, select_mode, select_filter); + vc, buffer + ofs, buffer_len - ofs, &rect, select_mode, select_filter); if (hits5 == 1) { hits = selectbuffer_ret_hits_5(buffer, hits15, hits9, hits5); goto finally; @@ -2007,7 +2009,8 @@ finally: } static int mixed_bones_object_selectbuffer_extended(ViewContext *vc, - uint *buffer, + GPUSelectResult *buffer, + const int buffer_len, const int mval[2], eV3DSelectObjectFilter select_filter, bool use_cycle, @@ -2038,7 +2041,7 @@ static int mixed_bones_object_selectbuffer_extended(ViewContext *vc, do_nearest = do_nearest && !enumerate; int hits = mixed_bones_object_selectbuffer( - vc, buffer, mval, select_filter, do_nearest, true, false); + vc, buffer, buffer_len, mval, select_filter, do_nearest, true, false); return hits; } @@ -2051,7 +2054,7 @@ static int mixed_bones_object_selectbuffer_extended(ViewContext *vc, * \return the active base or NULL. */ static Base *mouse_select_eval_buffer(ViewContext *vc, - const uint *buffer, + const GPUSelectResult *buffer, int hits, Base *startbase, bool has_bones, @@ -2071,10 +2074,10 @@ static Base *mouse_select_eval_buffer(ViewContext *vc, if (has_bones) { /* we skip non-bone hits */ for (a = 0; a < hits; a++) { - if (min > buffer[4 * a + 1] && (buffer[4 * a + 3] & 0xFFFF0000)) { - min = buffer[4 * a + 1]; - selcol = buffer[4 * a + 3] & 0xFFFF; - sub_selection_id = (buffer[4 * a + 3] & 0xFFFF0000) >> 16; + if (min > buffer[a].depth && (buffer[a].id & 0xFFFF0000)) { + min = buffer[a].depth; + selcol = buffer[a].id & 0xFFFF; + sub_selection_id = (buffer[a].id & 0xFFFF0000) >> 16; } } } @@ -2085,10 +2088,10 @@ static Base *mouse_select_eval_buffer(ViewContext *vc, } for (a = 0; a < hits; a++) { - if (min > buffer[4 * a + 1] && notcol != (buffer[4 * a + 3] & 0xFFFF)) { - min = buffer[4 * a + 1]; - selcol = buffer[4 * a + 3] & 0xFFFF; - sub_selection_id = (buffer[4 * a + 3] & 0xFFFF0000) >> 16; + if (min > buffer[a].depth && notcol != (buffer[a].id & 0xFFFF)) { + min = buffer[a].depth; + selcol = buffer[a].id & 0xFFFF; + sub_selection_id = (buffer[a].id & 0xFFFF0000) >> 16; } } } @@ -2127,14 +2130,14 @@ static Base *mouse_select_eval_buffer(ViewContext *vc, for (a = 0; a < hits; a++) { if (has_bones) { /* skip non-bone objects */ - if (buffer[4 * a + 3] & 0xFFFF0000) { - if (base->object->runtime.select_id == (buffer[(4 * a) + 3] & 0xFFFF)) { + if (buffer[a].id & 0xFFFF0000) { + if (base->object->runtime.select_id == (buffer[a].id & 0xFFFF)) { basact = base; } } } else { - if (base->object->runtime.select_id == (buffer[(4 * a) + 3] & 0xFFFF)) { + if (base->object->runtime.select_id == (buffer[a].id & 0xFFFF)) { basact = base; } } @@ -2169,7 +2172,7 @@ static Base *ed_view3d_give_base_under_cursor_ex(bContext *C, Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C); ViewContext vc; Base *basact = NULL; - uint buffer[MAXPICKBUF]; + GPUSelectResult buffer[MAXPICKELEMS]; /* setup view context for argument to callbacks */ view3d_operator_needs_opengl(C); @@ -2179,8 +2182,14 @@ static Base *ed_view3d_give_base_under_cursor_ex(bContext *C, const bool do_nearest = !XRAY_ACTIVE(vc.v3d); const bool do_material_slot_selection = r_material_slot != NULL; - const int hits = mixed_bones_object_selectbuffer( - &vc, buffer, mval, VIEW3D_SELECT_FILTER_NOP, do_nearest, false, do_material_slot_selection); + const int hits = mixed_bones_object_selectbuffer(&vc, + buffer, + ARRAY_SIZE(buffer), + mval, + VIEW3D_SELECT_FILTER_NOP, + do_nearest, + false, + do_material_slot_selection); if (hits > 0) { const bool has_bones = (r_material_slot == NULL) && selectbuffer_has_bones(buffer, hits); @@ -2342,7 +2351,7 @@ static bool ed_object_select_pick(bContext *C, } } else { - uint buffer[MAXPICKBUF]; + GPUSelectResult buffer[MAXPICKELEMS]; bool do_nearest; // TIMEIT_START(select_time); @@ -2353,7 +2362,7 @@ static bool ed_object_select_pick(bContext *C, vc.obact) : VIEW3D_SELECT_FILTER_NOP); hits = mixed_bones_object_selectbuffer_extended( - &vc, buffer, mval, select_filter, true, enumerate, &do_nearest); + &vc, buffer, ARRAY_SIZE(buffer), mval, select_filter, true, enumerate, &do_nearest); // TIMEIT_END(select_time); @@ -2383,7 +2392,7 @@ static bool ed_object_select_pick(bContext *C, bool changed = false; for (int i = 0; i < hits; i++) { - int hitresult = buffer[3 + (i * 4)]; + const int hitresult = buffer[i].id; /* if there's bundles in buffer select bundles first, * so non-camera elements should be ignored in buffer */ @@ -2394,7 +2403,7 @@ static bool ed_object_select_pick(bContext *C, /* index of bundle is 1<<16-based. if there's no "bone" index * in height word, this buffer value belongs to camera. not to bundle */ - if (buffer[4 * i + 3] & 0xFFFF0000) { + if (hitresult & 0xFFFF0000) { MovieTracking *tracking = &clip->tracking; ListBase *tracksbase; MovieTrackingTrack *track; @@ -2674,9 +2683,15 @@ static int view3d_select_exec(bContext *C, wmOperator *op) ViewContext vc; ED_view3d_viewcontext_init(C, &vc, depsgraph); - uint buffer[MAXPICKBUF]; - const int hits = mixed_bones_object_selectbuffer( - &vc, buffer, location, VIEW3D_SELECT_FILTER_NOP, false, true, false); + GPUSelectResult buffer[MAXPICKELEMS]; + const int hits = mixed_bones_object_selectbuffer(&vc, + buffer, + ARRAY_SIZE(buffer), + location, + VIEW3D_SELECT_FILTER_NOP, + false, + true, + false); retval = bone_mouse_select_menu(C, buffer, hits, true, extend, deselect, toggle); } if (!retval) { @@ -3256,11 +3271,11 @@ static bool do_meta_box_select(ViewContext *vc, const rcti *rect, const eSelectO int a; bool changed = false; - uint buffer[MAXPICKBUF]; + GPUSelectResult buffer[MAXPICKELEMS]; int hits; hits = view3d_opengl_select( - vc, buffer, MAXPICKBUF, rect, VIEW3D_SELECT_ALL, VIEW3D_SELECT_FILTER_NOP); + vc, buffer, MAXPICKELEMS, rect, VIEW3D_SELECT_ALL, VIEW3D_SELECT_FILTER_NOP); if (SEL_OP_USE_PRE_DESELECT(sel_op)) { changed |= BKE_mball_deselect_all(mb); @@ -3272,7 +3287,7 @@ static bool do_meta_box_select(ViewContext *vc, const rcti *rect, const eSelectO bool is_inside_stiff = false; for (a = 0; a < hits; a++) { - int hitresult = buffer[(4 * a) + 3]; + const int hitresult = buffer[a].id; if (hitresult == -1) { continue; @@ -3323,11 +3338,11 @@ static bool do_armature_box_select(ViewContext *vc, const rcti *rect, const eSel bool changed = false; int a; - uint buffer[MAXPICKBUF]; + GPUSelectResult buffer[MAXPICKELEMS]; int hits; hits = view3d_opengl_select( - vc, buffer, MAXPICKBUF, rect, VIEW3D_SELECT_ALL, VIEW3D_SELECT_FILTER_NOP); + vc, buffer, MAXPICKELEMS, rect, VIEW3D_SELECT_ALL, VIEW3D_SELECT_FILTER_NOP); uint bases_len = 0; Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data( @@ -3347,7 +3362,7 @@ static bool do_armature_box_select(ViewContext *vc, const rcti *rect, const eSel /* first we only check points inside the border */ for (a = 0; a < hits; a++) { - int select_id = buffer[(4 * a) + 3]; + const int select_id = buffer[a].id; if (select_id != -1) { if ((select_id & 0xFFFF0000) == 0) { continue; @@ -3375,14 +3390,13 @@ static bool do_armature_box_select(ViewContext *vc, const rcti *rect, const eSel } /** - * Compare result of 'GPU_select': 'uint[4]', + * Compare result of 'GPU_select': 'GPUSelectResult', * needed for when we need to align with object draw-order. */ static int opengl_bone_select_buffer_cmp(const void *sel_a_p, const void *sel_b_p) { - /* 4th element is select id */ - uint sel_a = ((uint *)sel_a_p)[3]; - uint sel_b = ((uint *)sel_b_p)[3]; + uint sel_a = ((GPUSelectResult *)sel_a_p)->id; + uint sel_b = ((GPUSelectResult *)sel_b_p)->id; #ifdef __BIG_ENDIAN__ BLI_endian_switch_uint32(&sel_a); @@ -3401,14 +3415,15 @@ static int opengl_bone_select_buffer_cmp(const void *sel_a_p, const void *sel_b_ static bool do_object_box_select(bContext *C, ViewContext *vc, rcti *rect, const eSelectOp sel_op) { View3D *v3d = vc->v3d; - int totobj = MAXPICKBUF; /* XXX solve later */ + int totobj = MAXPICKELEMS; /* XXX solve later */ - /* selection buffer now has bones potentially too, so we add MAXPICKBUF */ - uint *vbuffer = MEM_mallocN(4 * (totobj + MAXPICKELEMS) * sizeof(uint[4]), "selection buffer"); + /* Selection buffer has bones potentially too, so we add #MAXPICKELEMS. */ + GPUSelectResult *buffer = MEM_mallocN((totobj + MAXPICKELEMS) * sizeof(GPUSelectResult), + "selection buffer"); const eV3DSelectObjectFilter select_filter = ED_view3d_select_filter_from_mode(vc->scene, vc->obact); const int hits = view3d_opengl_select( - vc, vbuffer, 4 * (totobj + MAXPICKELEMS), rect, VIEW3D_SELECT_ALL, select_filter); + vc, buffer, (totobj + MAXPICKELEMS), rect, VIEW3D_SELECT_ALL, select_filter); LISTBASE_FOREACH (Base *, base, &vc->view_layer->object_bases) { base->object->id.tag &= ~LIB_TAG_DOIT; @@ -3435,12 +3450,13 @@ static bool do_object_box_select(bContext *C, ViewContext *vc, rcti *rect, const } /* The draw order doesn't always match the order we populate the engine, see: T51695. */ - qsort(vbuffer, hits, sizeof(uint[4]), opengl_bone_select_buffer_cmp); + qsort(buffer, hits, sizeof(GPUSelectResult), opengl_bone_select_buffer_cmp); - for (const uint *col = vbuffer + 3, *col_end = col + (hits * 4); col < col_end; col += 4) { + for (const GPUSelectResult *buf_iter = buffer, *buf_end = buf_iter + hits; buf_iter < buf_end; + buf_iter++) { bPoseChannel *pchan_dummy; Base *base = ED_armature_base_and_pchan_from_select_buffer( - bases, BLI_array_len(bases), *col, &pchan_dummy); + bases, BLI_array_len(bases), buf_iter->id, &pchan_dummy); if (base != NULL) { base->object->id.tag |= LIB_TAG_DOIT; } @@ -3463,7 +3479,7 @@ finally: MEM_freeN(bases); } - MEM_freeN(vbuffer); + MEM_freeN(buffer); if (changed) { DEG_id_tag_update(&vc->scene->id, ID_RECALC_SELECT); @@ -3477,14 +3493,15 @@ static bool do_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, const e uint bases_len; Base **bases = do_pose_tag_select_op_prepare(vc, &bases_len); - int totobj = MAXPICKBUF; /* XXX solve later */ + int totobj = MAXPICKELEMS; /* XXX solve later */ - /* selection buffer now has bones potentially too, so we add MAXPICKBUF */ - uint *vbuffer = MEM_mallocN((totobj + MAXPICKELEMS) * sizeof(uint[4]), "selection buffer"); + /* Selection buffer has bones potentially too, so add #MAXPICKELEMS. */ + GPUSelectResult *buffer = MEM_mallocN((totobj + MAXPICKELEMS) * sizeof(GPUSelectResult), + "selection buffer"); const eV3DSelectObjectFilter select_filter = ED_view3d_select_filter_from_mode(vc->scene, vc->obact); const int hits = view3d_opengl_select( - vc, vbuffer, 4 * (totobj + MAXPICKELEMS), rect, VIEW3D_SELECT_ALL, select_filter); + vc, buffer, (totobj + MAXPICKELEMS), rect, VIEW3D_SELECT_ALL, select_filter); /* * LOGIC NOTES (theeth): * The buffer and ListBase have the same relative order, which makes the selection @@ -3498,18 +3515,20 @@ static bool do_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, const e /* no need to loop if there's no hit */ /* The draw order doesn't always match the order we populate the engine, see: T51695. */ - qsort(vbuffer, hits, sizeof(uint[4]), opengl_bone_select_buffer_cmp); + qsort(buffer, hits, sizeof(GPUSelectResult), opengl_bone_select_buffer_cmp); - for (const uint *col = vbuffer + 3, *col_end = col + (hits * 4); col < col_end; col += 4) { + for (const GPUSelectResult *buf_iter = buffer, *buf_end = buf_iter + hits; buf_iter < buf_end; + buf_iter++) { Bone *bone; - Base *base = ED_armature_base_and_bone_from_select_buffer(bases, bases_len, *col, &bone); + Base *base = ED_armature_base_and_bone_from_select_buffer( + bases, bases_len, buf_iter->id, &bone); if (base == NULL) { continue; } /* Loop over contiguous bone hits for 'base'. */ - for (; col != col_end; col += 4) { + for (; buf_iter != buf_end; buf_iter++) { /* should never fail */ if (bone != NULL) { base->object->id.tag |= LIB_TAG_DOIT; @@ -3517,12 +3536,13 @@ static bool do_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, const e } /* Select the next bone if we're not switching bases. */ - if (col + 4 != col_end) { - if ((base->object->runtime.select_id & 0x0000FFFF) != (col[4] & 0x0000FFFF)) { + if (buf_iter + 1 != buf_end) { + const GPUSelectResult *col_next = buf_iter + 1; + if ((base->object->runtime.select_id & 0x0000FFFF) != (col_next->id & 0x0000FFFF)) { break; } if (base->object->pose != NULL) { - const uint hit_bone = (col[4] & ~BONESEL_ANY) >> 16; + const uint hit_bone = (col_next->id & ~BONESEL_ANY) >> 16; bPoseChannel *pchan = BLI_findlink(&base->object->pose->chanbase, hit_bone); bone = pchan ? pchan->bone : NULL; } @@ -3543,7 +3563,7 @@ static bool do_pose_box_select(bContext *C, ViewContext *vc, rcti *rect, const e if (bases != NULL) { MEM_freeN(bases); } - MEM_freeN(vbuffer); + MEM_freeN(buffer); return changed_multi; } diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c index 165f931394d..d6b928c6fa7 100644 --- a/source/blender/editors/space_view3d/view3d_view.c +++ b/source/blender/editors/space_view3d/view3d_view.c @@ -863,10 +863,10 @@ void view3d_opengl_select_cache_end(void) struct DrawSelectLoopUserData { uint pass; uint hits; - uint *buffer; + GPUSelectResult *buffer; uint buffer_len; const rcti *rect; - char gpu_select_mode; + eGPUSelectMode gpu_select_mode; }; static bool drw_select_loop_pass(eDRWSelectStage stage, void *user_data) @@ -927,8 +927,8 @@ static bool drw_select_filter_object_mode_lock_for_weight_paint(Object *ob, void } int view3d_opengl_select_ex(ViewContext *vc, - uint *buffer, - uint bufsize, + GPUSelectResult *buffer, + uint buffer_len, const rcti *input, eV3DSelectMode select_mode, eV3DSelectObjectFilter select_filter, @@ -950,7 +950,7 @@ int view3d_opengl_select_ex(ViewContext *vc, const bool use_nearest = (is_pick_select && select_mode == VIEW3D_SELECT_PICK_NEAREST); bool draw_surface = true; - char gpu_select_mode; + eGPUSelectMode gpu_select_mode; /* case not a box select */ if (input->xmin == input->xmax) { @@ -981,6 +981,15 @@ int view3d_opengl_select_ex(ViewContext *vc, } } + /* Re-use cache (rect must be smaller than the cached) + * other context is assumed to be unchanged */ + if (GPU_select_is_cached()) { + GPU_select_begin(buffer, buffer_len, &rect, gpu_select_mode, 0); + GPU_select_cache_load_id(); + hits = GPU_select_end(); + goto finally; + } + /* Important to use 'vc->obact', not 'OBACT(vc->view_layer)' below, * so it will be NULL when hidden. */ struct { @@ -1040,15 +1049,6 @@ int view3d_opengl_select_ex(ViewContext *vc, UI_Theme_Store(&theme_state); UI_SetTheme(SPACE_VIEW3D, RGN_TYPE_WINDOW); - /* Re-use cache (rect must be smaller than the cached) - * other context is assumed to be unchanged */ - if (GPU_select_is_cached()) { - GPU_select_begin(buffer, bufsize, &rect, gpu_select_mode, 0); - GPU_select_cache_load_id(); - hits = GPU_select_end(); - goto finally; - } - /* All of the queries need to be perform on the drawing context. */ DRW_opengl_context_enable(); @@ -1071,7 +1071,7 @@ int view3d_opengl_select_ex(ViewContext *vc, .pass = 0, .hits = 0, .buffer = buffer, - .buffer_len = bufsize, + .buffer_len = buffer_len, .rect = &rect, .gpu_select_mode = gpu_select_mode, }; @@ -1101,7 +1101,7 @@ int view3d_opengl_select_ex(ViewContext *vc, .pass = 0, .hits = 0, .buffer = buffer, - .buffer_len = bufsize, + .buffer_len = buffer_len, .rect = &rect, .gpu_select_mode = gpu_select_mode, }; @@ -1132,36 +1132,36 @@ int view3d_opengl_select_ex(ViewContext *vc, DRW_opengl_context_disable(); + UI_Theme_Restore(&theme_state); + finally: if (hits < 0) { printf("Too many objects in select buffer\n"); /* XXX make error message */ } - UI_Theme_Restore(&theme_state); - return hits; } int view3d_opengl_select(ViewContext *vc, - uint *buffer, - uint bufsize, + GPUSelectResult *buffer, + uint buffer_len, const rcti *input, eV3DSelectMode select_mode, eV3DSelectObjectFilter select_filter) { - return view3d_opengl_select_ex(vc, buffer, bufsize, input, select_mode, select_filter, false); + return view3d_opengl_select_ex(vc, buffer, buffer_len, input, select_mode, select_filter, false); } int view3d_opengl_select_with_id_filter(ViewContext *vc, - uint *buffer, - uint bufsize, + GPUSelectResult *buffer, + const uint buffer_len, const rcti *input, eV3DSelectMode select_mode, eV3DSelectObjectFilter select_filter, uint select_id) { - int hits = view3d_opengl_select(vc, buffer, bufsize, input, select_mode, select_filter); + int hits = view3d_opengl_select(vc, buffer, buffer_len, input, select_mode, select_filter); /* Selection sometimes uses -1 for an invalid selection ID, remove these as they * interfere with detection of actual number of hits in the selection. */ diff --git a/source/blender/editors/transform/CMakeLists.txt b/source/blender/editors/transform/CMakeLists.txt index 64a720322c1..09c53d7196c 100644 --- a/source/blender/editors/transform/CMakeLists.txt +++ b/source/blender/editors/transform/CMakeLists.txt @@ -125,9 +125,5 @@ set(LIB bf_gpu ) -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() - blender_add_lib(bf_editor_transform "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/editors/transform/transform_convert.h b/source/blender/editors/transform/transform_convert.h index c40f3c28a79..90f78d4abf1 100644 --- a/source/blender/editors/transform/transform_convert.h +++ b/source/blender/editors/transform/transform_convert.h @@ -124,10 +124,8 @@ void special_aftertrans_update__actedit(bContext *C, TransInfo *t); * Sets transform flags in the bones. * Returns total number of bones with #BONE_TRANSFORM. */ -int transform_convert_pose_transflags_update(Object *ob, - int mode, - short around, - bool has_translate_rotate[2]); +void transform_convert_pose_transflags_update(Object *ob, int mode, short around); + /** * When objects array is NULL, use 't->data_container' as is. */ diff --git a/source/blender/editors/transform/transform_convert_armature.c b/source/blender/editors/transform/transform_convert_armature.c index 5d0a3bd9dd1..04a8d462924 100644 --- a/source/blender/editors/transform/transform_convert_armature.c +++ b/source/blender/editors/transform/transform_convert_armature.c @@ -739,9 +739,43 @@ void createTransPose(TransInfo *t) const bool mirror = ((pose->flag & POSE_MIRROR_EDIT) != 0); - /* set flags and count total */ - tc->data_len = transform_convert_pose_transflags_update( - ob, t->mode, t->around, has_translate_rotate); + /* Set flags. */ + transform_convert_pose_transflags_update(ob, t->mode, t->around); + + /* Now count, and check if we have autoIK or have to switch from translate to rotate. */ + LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) { + Bone *bone = pchan->bone; + if (!(bone->flag & BONE_TRANSFORM)) { + continue; + } + + tc->data_len++; + + if (has_translate_rotate != NULL) { + if (has_translate_rotate[0] && has_translate_rotate[1]) { + continue; + } + + if (has_targetless_ik(pchan) == NULL) { + if (pchan->parent && (bone->flag & BONE_CONNECTED)) { + if (bone->flag & BONE_HINGE_CHILD_TRANSFORM) { + has_translate_rotate[0] = true; + } + } + else { + if ((pchan->protectflag & OB_LOCK_LOC) != OB_LOCK_LOC) { + has_translate_rotate[0] = true; + } + } + if ((pchan->protectflag & OB_LOCK_ROT) != OB_LOCK_ROT) { + has_translate_rotate[1] = true; + } + } + else { + has_translate_rotate[0] = true; + } + } + } if (tc->data_len == 0) { continue; @@ -1499,15 +1533,11 @@ static void bone_children_clear_transflag(int mode, short around, ListBase *lb) } } -int transform_convert_pose_transflags_update(Object *ob, - const int mode, - const short around, - bool has_translate_rotate[2]) +void transform_convert_pose_transflags_update(Object *ob, const int mode, const short around) { bArmature *arm = ob->data; bPoseChannel *pchan; Bone *bone; - int total = 0; for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { bone = pchan->bone; @@ -1537,36 +1567,6 @@ int transform_convert_pose_transflags_update(Object *ob, } } } - /* now count, and check if we have autoIK or have to switch from translate to rotate */ - for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) { - bone = pchan->bone; - if (bone->flag & BONE_TRANSFORM) { - total++; - - if (has_translate_rotate != NULL) { - if (has_targetless_ik(pchan) == NULL) { - if (pchan->parent && (pchan->bone->flag & BONE_CONNECTED)) { - if (pchan->bone->flag & BONE_HINGE_CHILD_TRANSFORM) { - has_translate_rotate[0] = true; - } - } - else { - if ((pchan->protectflag & OB_LOCK_LOC) != OB_LOCK_LOC) { - has_translate_rotate[0] = true; - } - } - if ((pchan->protectflag & OB_LOCK_ROT) != OB_LOCK_ROT) { - has_translate_rotate[1] = true; - } - } - else { - has_translate_rotate[0] = true; - } - } - } - } - - return total; } static short apply_targetless_ik(Object *ob) @@ -1733,7 +1733,7 @@ void special_aftertrans_update__pose(bContext *C, TransInfo *t) /* Set BONE_TRANSFORM flags for auto-key, gizmo draw might have changed them. */ if (!canceled && (t->mode != TFM_DUMMY)) { - transform_convert_pose_transflags_update(ob, t->mode, t->around, NULL); + transform_convert_pose_transflags_update(ob, t->mode, t->around); } /* if target-less IK grabbing, we calculate the pchan transforms and clear flag */ diff --git a/source/blender/editors/transform/transform_gizmo_3d.c b/source/blender/editors/transform/transform_gizmo_3d.c index 9bd55d78039..c0572478481 100644 --- a/source/blender/editors/transform/transform_gizmo_3d.c +++ b/source/blender/editors/transform/transform_gizmo_3d.c @@ -953,32 +953,25 @@ int ED_transform_calc_gizmo_stats(const bContext *C, for (uint ob_index = 0; ob_index < objects_len; ob_index++) { Object *ob_iter = objects[ob_index]; - const bool use_mat_local = (ob_iter != ob); - bPoseChannel *pchan; - + const bool use_mat_local = params->use_local_axis && (ob_iter != ob); /* mislead counting bones... bah. We don't know the gizmo mode, could be mixed */ const int mode = TFM_ROTATION; - const int totsel_iter = transform_convert_pose_transflags_update( - ob_iter, mode, V3D_AROUND_CENTER_BOUNDS, NULL); + transform_convert_pose_transflags_update(ob_iter, mode, V3D_AROUND_CENTER_BOUNDS); - if (totsel_iter) { - float mat_local[4][4]; - if (params->use_local_axis) { - if (use_mat_local) { - mul_m4_m4m4(mat_local, ob->imat, ob_iter->obmat); - } - } + float mat_local[4][4]; + if (use_mat_local) { + mul_m4_m4m4(mat_local, ob->imat, ob_iter->obmat); + } - /* use channels to get stats */ - for (pchan = ob_iter->pose->chanbase.first; pchan; pchan = pchan->next) { - Bone *bone = pchan->bone; - if (bone && (bone->flag & BONE_TRANSFORM)) { - calc_tw_center_with_matrix(tbounds, pchan->pose_head, use_mat_local, mat_local); - protectflag_to_drawflags_pchan(rv3d, pchan, orient_index); - } + /* Use channels to get stats. */ + LISTBASE_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) { + if (!(pchan->bone->flag & BONE_TRANSFORM)) { + continue; } - totsel += totsel_iter; + calc_tw_center_with_matrix(tbounds, pchan->pose_head, use_mat_local, mat_local); + protectflag_to_drawflags_pchan(rv3d, pchan, orient_index); + totsel++; } } MEM_freeN(objects); diff --git a/source/blender/editors/undo/CMakeLists.txt b/source/blender/editors/undo/CMakeLists.txt index 0f4152c9128..6f659e383fe 100644 --- a/source/blender/editors/undo/CMakeLists.txt +++ b/source/blender/editors/undo/CMakeLists.txt @@ -46,8 +46,4 @@ set(LIB bf_editor_physics ) -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() - blender_add_lib(bf_editor_undo "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/editors/util/CMakeLists.txt b/source/blender/editors/util/CMakeLists.txt index 90a09c87cc6..66cda0fc3f8 100644 --- a/source/blender/editors/util/CMakeLists.txt +++ b/source/blender/editors/util/CMakeLists.txt @@ -115,10 +115,6 @@ set(LIB ) -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() - if(WITH_PYTHON) add_definitions(-DWITH_PYTHON) list(APPEND INC diff --git a/source/blender/editors/uvedit/CMakeLists.txt b/source/blender/editors/uvedit/CMakeLists.txt index 1c8a56e0608..a3b29f29354 100644 --- a/source/blender/editors/uvedit/CMakeLists.txt +++ b/source/blender/editors/uvedit/CMakeLists.txt @@ -52,9 +52,5 @@ set(LIB bf_bmesh ) -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() - blender_add_lib(bf_editor_uvedit "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/freestyle/CMakeLists.txt b/source/blender/freestyle/CMakeLists.txt index d16787714c9..948e68e52da 100644 --- a/source/blender/freestyle/CMakeLists.txt +++ b/source/blender/freestyle/CMakeLists.txt @@ -583,10 +583,6 @@ if(WITH_PYTHON_SAFETY) add_definitions(-DWITH_PYTHON_SAFETY) endif() -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() - if(WIN32) list(APPEND INC_SYS ${PTHREADS_INC} diff --git a/source/blender/gpencil_modifiers/CMakeLists.txt b/source/blender/gpencil_modifiers/CMakeLists.txt index 5ee75619259..a3f468a20dc 100644 --- a/source/blender/gpencil_modifiers/CMakeLists.txt +++ b/source/blender/gpencil_modifiers/CMakeLists.txt @@ -92,10 +92,6 @@ set(SRC set(LIB ) -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() - add_definitions(${GL_DEFINITIONS}) blender_add_lib(bf_gpencil_modifiers "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/gpu/GPU_select.h b/source/blender/gpu/GPU_select.h index c02af763311..3076058c075 100644 --- a/source/blender/gpu/GPU_select.h +++ b/source/blender/gpu/GPU_select.h @@ -32,7 +32,7 @@ extern "C" { struct rcti; /** Flags for mode of operation. */ -enum { +typedef enum eGPUSelectMode { GPU_SELECT_ALL = 1, /* gpu_select_query */ GPU_SELECT_NEAREST_FIRST_PASS = 2, @@ -40,13 +40,32 @@ enum { /* gpu_select_pick */ GPU_SELECT_PICK_ALL = 4, GPU_SELECT_PICK_NEAREST = 5, -}; +} eGPUSelectMode; + +/** + * The result of calling #GPU_select_begin & #GPU_select_end. + */ +typedef struct GPUSelectResult { + /** The selection identifier matching the value passed in by #GPU_select_load_id. */ + unsigned int id; + /** + * The nearest depth. + * - Only supported by picking modes (#GPU_SELECT_PICK_ALL and #GPU_SELECT_PICK_NEAREST) + * since occlusion quires don't provide a convenient way of accessing the depth-buffer. + * - OpenGL's `GL_SELECT` supported both near and far depths, + * this has not been included as Blender doesn't need this however support could be added. + */ + unsigned int depth; +} GPUSelectResult; /** * Initialize and provide buffer for results. */ -void GPU_select_begin( - unsigned int *buffer, unsigned int bufsize, const struct rcti *input, char mode, int oldhits); +void GPU_select_begin(GPUSelectResult *buffer, + unsigned int buffer_len, + const struct rcti *input, + eGPUSelectMode mode, + int oldhits); /** * Loads a new selection id and ends previous query, if any. * In second pass of selection it also returns @@ -79,8 +98,8 @@ void GPU_select_cache_end(void); * * Note that comparing depth as uint is fine. */ -const uint *GPU_select_buffer_near(const uint *buffer, int hits); -uint GPU_select_buffer_remove_by_id(uint *buffer, int hits, uint select_id); +const GPUSelectResult *GPU_select_buffer_near(const GPUSelectResult *buffer, int hits); +uint GPU_select_buffer_remove_by_id(GPUSelectResult *buffer, int hits, uint select_id); /** * Part of the solution copied from `rect_subregion_stride_calc`. */ diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h index 972758febd4..05c992274eb 100644 --- a/source/blender/gpu/GPU_shader.h +++ b/source/blender/gpu/GPU_shader.h @@ -71,6 +71,8 @@ GPUShader *GPU_shader_create_ex(const char *vertcode, GPUShader *GPU_shader_create_from_info(const GPUShaderCreateInfo *_info); GPUShader *GPU_shader_create_from_info_name(const char *info_name); +const GPUShaderCreateInfo *GPU_shader_create_info_get(const char *info_name); + struct GPU_ShaderCreateFromArray_Params { const char **vert, **geom, **frag, **defs; }; diff --git a/source/blender/gpu/GPU_texture.h b/source/blender/gpu/GPU_texture.h index 6fae4a13918..7812c7a7257 100644 --- a/source/blender/gpu/GPU_texture.h +++ b/source/blender/gpu/GPU_texture.h @@ -272,7 +272,8 @@ void *GPU_texture_read(GPUTexture *tex, eGPUDataFormat data_format, int miplvl); * Fills the whole texture with the same data for all pixels. * \warning Only work for 2D texture for now. * \warning Only clears the mip 0 of the texture. - * \param data_format: data format of the pixel data. \note The format is float for unorm textures. + * \param data_format: data format of the pixel data. + * \note The format is float for unorm textures. * \param data: 1 pixel worth of data to fill the texture with. */ void GPU_texture_clear(GPUTexture *tex, eGPUDataFormat data_format, const void *data); diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c index 568462ec2a6..e1c6901470a 100644 --- a/source/blender/gpu/intern/gpu_codegen.c +++ b/source/blender/gpu/intern/gpu_codegen.c @@ -711,10 +711,10 @@ static char *code_generate_vertex(GPUNodeGraph *graph, LISTBASE_FOREACH (GPUMaterialAttribute *, attr, &graph->attributes) { const char *type_str = gpu_data_type_to_string(attr->gputype); const char *prefix = attr_prefix_get(attr->type); - /* XXX FIXME : see notes in mesh_render_data_create() */ - /* NOTE : Replicate changes to mesh_render_data_create() in draw_cache_impl_mesh.c */ + /* XXX FIXME: see notes in mesh_render_data_create() */ + /* NOTE: Replicate changes to mesh_render_data_create() in draw_cache_impl_mesh.c */ if (attr->type == CD_ORCO) { - /* OPTI : orco is computed from local positions, but only if no modifier is present. */ + /* OPTI: orco is computed from local positions, but only if no modifier is present. */ BLI_dynstr_append(ds, datatoc_gpu_shader_common_obinfos_lib_glsl); BLI_dynstr_append(ds, "DEFINE_ATTR(vec4, orco);\n"); } diff --git a/source/blender/gpu/intern/gpu_framebuffer.cc b/source/blender/gpu/intern/gpu_framebuffer.cc index 5b1eac2e82f..28f5b8b02b0 100644 --- a/source/blender/gpu/intern/gpu_framebuffer.cc +++ b/source/blender/gpu/intern/gpu_framebuffer.cc @@ -437,7 +437,7 @@ void GPU_framebuffer_blit(GPUFrameBuffer *gpufb_read, fb_read->blit_to(blit_buffers, read_slot, fb_write, write_slot, 0, 0); - /* FIXME(fclem) sRGB is not saved. */ + /* FIXME(@fclem): sRGB is not saved. */ prev_fb->bind(true); } diff --git a/source/blender/gpu/intern/gpu_select.c b/source/blender/gpu/intern/gpu_select.c index 958aab65b57..afef0e70ccc 100644 --- a/source/blender/gpu/intern/gpu_select.c +++ b/source/blender/gpu/intern/gpu_select.c @@ -43,22 +43,22 @@ * \{ */ /* Internal algorithm used */ -enum { +typedef enum eGPUSelectAlgo { /** glBegin/EndQuery(GL_SAMPLES_PASSED... ), `gpu_select_query.c` * Only sets 4th component (ID) correctly. */ ALGO_GL_QUERY = 1, /** Read depth buffer for every drawing pass and extract depths, `gpu_select_pick.c` * Only sets 4th component (ID) correctly. */ ALGO_GL_PICK = 2, -}; +} eGPUSelectAlgo; typedef struct GPUSelectState { /* To ignore selection id calls when not initialized */ bool select_is_active; /* mode of operation */ - char mode; + eGPUSelectMode mode; /* internal algorithm for selection */ - char algorithm; + eGPUSelectAlgo algorithm; /* allow GPU_select_begin/end without drawing */ bool use_cache; /** @@ -80,7 +80,11 @@ static GPUSelectState g_select_state = {0}; /** \name Public API * \{ */ -void GPU_select_begin(uint *buffer, uint bufsize, const rcti *input, char mode, int oldhits) +void GPU_select_begin(GPUSelectResult *buffer, + const uint buffer_len, + const rcti *input, + eGPUSelectMode mode, + int oldhits) { if (mode == GPU_SELECT_NEAREST_SECOND_PASS) { /* In the case hits was '-1', @@ -119,12 +123,12 @@ void GPU_select_begin(uint *buffer, uint bufsize, const rcti *input, char mode, switch (g_select_state.algorithm) { case ALGO_GL_QUERY: { - gpu_select_query_begin((uint(*)[4])buffer, bufsize / 4, input, mode, oldhits); + gpu_select_query_begin(buffer, buffer_len, input, mode, oldhits); break; } default: /* ALGO_GL_PICK */ { - gpu_select_pick_begin((uint(*)[4])buffer, bufsize / 4, input, mode); + gpu_select_pick_begin(buffer, buffer_len, input, mode); break; } } @@ -219,35 +223,35 @@ bool GPU_select_is_cached(void) /** \name Utilities * \{ */ -const uint *GPU_select_buffer_near(const uint *buffer, int hits) +const GPUSelectResult *GPU_select_buffer_near(const GPUSelectResult *buffer, int hits) { - const uint *buffer_near = NULL; + const GPUSelectResult *buffer_near = NULL; uint depth_min = (uint)-1; for (int i = 0; i < hits; i++) { - if (buffer[1] < depth_min) { - BLI_assert(buffer[3] != -1); - depth_min = buffer[1]; + if (buffer->depth < depth_min) { + BLI_assert(buffer->id != -1); + depth_min = buffer->depth; buffer_near = buffer; } - buffer += 4; + buffer++; } return buffer_near; } -uint GPU_select_buffer_remove_by_id(uint *buffer, int hits, uint select_id) +uint GPU_select_buffer_remove_by_id(GPUSelectResult *buffer, int hits, uint select_id) { - uint *buffer_src = buffer; - uint *buffer_dst = buffer; + GPUSelectResult *buffer_src = buffer; + GPUSelectResult *buffer_dst = buffer; int hits_final = 0; for (int i = 0; i < hits; i++) { - if (buffer_src[3] != select_id) { + if (buffer_src->id != select_id) { if (buffer_dst != buffer_src) { - memcpy(buffer_dst, buffer_src, sizeof(int[4])); + memcpy(buffer_dst, buffer_src, sizeof(GPUSelectResult)); } - buffer_dst += 4; + buffer_dst++; hits_final += 1; } - buffer_src += 4; + buffer_src++; } return hits_final; } diff --git a/source/blender/gpu/intern/gpu_select_pick.c b/source/blender/gpu/intern/gpu_select_pick.c index ddd3dfc6879..a5c0b2b1a14 100644 --- a/source/blender/gpu/intern/gpu_select_pick.c +++ b/source/blender/gpu/intern/gpu_select_pick.c @@ -55,15 +55,19 @@ /** \name #SubRectStride * \{ */ -/* For looping over a sub-region of a rect, could be moved into 'rct.c'. */ +/** For looping over a sub-region of a #rcti, could be moved into 'rct.c'. */ typedef struct SubRectStride { - uint start; /* start here */ - uint span; /* read these */ - uint span_len; /* len times (read span 'len' times). */ - uint skip; /* skip those */ + /** Start here. */ + uint start; + /** Read these. */ + uint span; + /** `len` times (read span 'len' times). */ + uint span_len; + /** Skip those. */ + uint skip; } SubRectStride; -/* we may want to change back to float if uint isn't well supported */ +/** We may want to change back to float if `uint` isn't well supported. */ typedef uint depth_t; /** @@ -104,11 +108,11 @@ BLI_INLINE bool depth_is_filled(const depth_t *prev, const depth_t *curr) /* -------------------------------------------------------------------- */ /** \name #DepthBufCache * - * Result of reading #glReadPixels, + * Result of reading #GPU_framebuffer_read_depth, * use for both cache and non-cached storage. * \{ */ -/** Store result of #glReadPixels. */ +/** Store result of #GPU_framebuffer_read_depth. */ typedef struct DepthBufCache { struct DepthBufCache *next, *prev; uint id; @@ -174,7 +178,7 @@ static bool depth_buf_subrect_depth_any_filled(const DepthBufCache *rect_src, const DepthBufCache *rect_dst, const SubRectStride *sub_rect) { - /* same as above but different rect sizes */ + /* Same as above but different rectangle sizes. */ const depth_t *prev = rect_src->buf + sub_rect->start; const depth_t *curr = rect_dst->buf + sub_rect->start; for (uint i = 0; i < sub_rect->span_len; i++) { @@ -235,66 +239,68 @@ static int depth_cmp(const void *v1, const void *v2) /** \name Main Selection Begin/End/Load API * \{ */ -/* depth sorting */ +/** Depth sorting. */ typedef struct GPUPickState { - /* cache on initialization */ - uint (*buffer)[4]; + /** Cache on initialization. */ + GPUSelectResult *buffer; + uint buffer_len; + /** Mode of this operation. */ + eGPUSelectMode mode; - /* Buffer size (stores number of integers, for actual size multiply by sizeof integer). */ - uint bufsize; - /* mode of operation */ - char mode; - - /* OpenGL drawing, never use when (is_cached == true). */ + /** GPU drawing, never use when `is_cached == true`. */ struct { - /* The current depth, accumulated as we draw */ + /** The current depth, accumulated while drawing. */ DepthBufCache *rect_depth; - /* Scratch buffer, avoid allocs every time (when not caching) */ + /** Scratch buffer, avoid allocations every time (when not caching). */ DepthBufCache *rect_depth_test; - /* Pass to glReadPixels (x, y, w, h) */ + /** Pass to `GPU_framebuffer_read_depth(x, y, w, h)`. */ int clip_readpixels[4]; - /* Set after first draw */ + /** Set after first draw. */ bool is_init; uint prev_id; - } gl; + } gpu; - /* src: data stored in 'cache' and 'gl', - * dst: use when cached region is smaller (where src -> dst isn't 1:1) */ + /** + * `src`: data stored in 'cache' and 'gpu', + * `dst`: use when cached region is smaller (where `src` -> `dst` isn't 1:1). + */ struct { rcti clip_rect; uint rect_len; } src, dst; - /* Store cache between `GPU_select_cache_begin/end` */ + /** Store cache between `GPU_select_cache_begin/end` */ bool use_cache; bool is_cached; struct { - /* Cleanup used for iterating over both source and destination buffers: - * src.clip_rect -> dst.clip_rect */ + /** + * Cleanup used for iterating over both source and destination buffers: + * `src.clip_rect` -> `dst.clip_rect`. + */ SubRectStride sub_rect; - /* List of DepthBufCache, sized of 'src.clip_rect' */ + /** List of #DepthBufCache, sized of 'src.clip_rect'. */ ListBase bufs; } cache; - /* Picking methods. */ + /** Picking methods. */ union { - /* GPU_SELECT_PICK_ALL */ + /** #GPU_SELECT_PICK_ALL */ struct { DepthID *hits; uint hits_len; uint hits_len_alloc; } all; - /* GPU_SELECT_PICK_NEAREST */ + /** #GPU_SELECT_PICK_NEAREST */ struct { uint *rect_id; } nearest; }; - /* Previous state to restore after drawing. */ + /** Previous state to restore after drawing. */ int viewport[4]; int scissor[4]; eGPUWriteMask write_mask; @@ -303,37 +309,44 @@ typedef struct GPUPickState { static GPUPickState g_pick_state = {0}; -void gpu_select_pick_begin(uint (*buffer)[4], uint bufsize, const rcti *input, char mode) +void gpu_select_pick_begin(GPUSelectResult *buffer, + const uint buffer_len, + const rcti *input, + eGPUSelectMode mode) { GPUPickState *ps = &g_pick_state; #ifdef DEBUG_PRINT - printf("%s: mode=%d, use_cache=%d, is_cache=%d\n", __func__, mode, ps->use_cache, ps->is_cached); + printf("%s: mode=%d, use_cache=%d, is_cache=%d\n", + __func__, + (int)mode, + ps->use_cache, + ps->is_cached); #endif GPU_debug_group_begin("Selection Pick"); - ps->bufsize = bufsize; ps->buffer = buffer; + ps->buffer_len = buffer_len; ps->mode = mode; const uint rect_len = (uint)(BLI_rcti_size_x(input) * BLI_rcti_size_y(input)); ps->dst.clip_rect = *input; ps->dst.rect_len = rect_len; - /* Restrict OpenGL operations for when we don't have cache */ + /* Avoids unnecessary GPU operations when cache is available and they are unnecessary. */ if (ps->is_cached == false) { ps->write_mask = GPU_write_mask_get(); ps->depth_test = GPU_depth_test_get(); GPU_scissor_get(ps->scissor); - /* disable writing to the framebuffer */ + /* Disable writing to the frame-buffer. */ GPU_color_mask(false, false, false, false); GPU_depth_mask(true); - /* Always use #GL_LEQUAL even though GPU_SELECT_PICK_ALL always clears the buffer. This is - * because individual objects themselves might have sections that overlap and we need these - * to have the correct distance information. */ + /* Always use #GPU_DEPTH_LESS_EQUAL even though #GPU_SELECT_PICK_ALL always clears the buffer. + * This is because individual objects themselves might have sections that overlap and we need + * these to have the correct distance information. */ GPU_depth_test(GPU_DEPTH_LESS_EQUAL); float viewport[4]; @@ -342,35 +355,35 @@ void gpu_select_pick_begin(uint (*buffer)[4], uint bufsize, const rcti *input, c ps->src.clip_rect = *input; ps->src.rect_len = rect_len; - ps->gl.clip_readpixels[0] = (int)viewport[0]; - ps->gl.clip_readpixels[1] = (int)viewport[1]; - ps->gl.clip_readpixels[2] = BLI_rcti_size_x(&ps->src.clip_rect); - ps->gl.clip_readpixels[3] = BLI_rcti_size_y(&ps->src.clip_rect); + ps->gpu.clip_readpixels[0] = (int)viewport[0]; + ps->gpu.clip_readpixels[1] = (int)viewport[1]; + ps->gpu.clip_readpixels[2] = BLI_rcti_size_x(&ps->src.clip_rect); + ps->gpu.clip_readpixels[3] = BLI_rcti_size_y(&ps->src.clip_rect); - GPU_viewport(UNPACK4(ps->gl.clip_readpixels)); + GPU_viewport(UNPACK4(ps->gpu.clip_readpixels)); /* It's possible we don't want to clear depth buffer, * so existing elements are masked by current z-buffer. */ GPU_clear_depth(1.0f); /* scratch buffer (read new values here) */ - ps->gl.rect_depth_test = depth_buf_malloc(rect_len); - ps->gl.rect_depth = depth_buf_malloc(rect_len); + ps->gpu.rect_depth_test = depth_buf_malloc(rect_len); + ps->gpu.rect_depth = depth_buf_malloc(rect_len); - /* set initial 'far' value */ + /* Set initial 'far' value. */ for (uint i = 0; i < rect_len; i++) { - ps->gl.rect_depth->buf[i] = DEPTH_MAX; + ps->gpu.rect_depth->buf[i] = DEPTH_MAX; } - ps->gl.is_init = false; - ps->gl.prev_id = 0; + ps->gpu.is_init = false; + ps->gpu.prev_id = 0; } else { - /* Using cache (ps->is_cached == true) */ - /* src.clip_rect -> dst.clip_rect */ + /* Using cache `ps->is_cached == true`. */ + /* `src.clip_rect` -> `dst.clip_rect`. */ rect_subregion_stride_calc(&ps->src.clip_rect, &ps->dst.clip_rect, &ps->cache.sub_rect); - BLI_assert(ps->gl.rect_depth == NULL); - BLI_assert(ps->gl.rect_depth_test == NULL); + BLI_assert(ps->gpu.rect_depth == NULL); + BLI_assert(ps->gpu.rect_depth_test == NULL); } if (mode == GPU_SELECT_PICK_ALL) { @@ -379,7 +392,7 @@ void gpu_select_pick_begin(uint (*buffer)[4], uint bufsize, const rcti *input, c ps->all.hits_len_alloc = ALLOC_DEPTHS; } else { - /* Set to 0xff for SELECT_ID_NONE */ + /* Set to 0xff for #SELECT_ID_NONE. */ ps->nearest.rect_id = MEM_mallocN(sizeof(uint) * ps->dst.rect_len, __func__); memset(ps->nearest.rect_id, 0xff, sizeof(uint) * ps->dst.rect_len); } @@ -411,7 +424,7 @@ static void gpu_select_load_id_pass_all(const DepthBufCache *rect_curr) } } else { - /* same as above but different rect sizes */ + /* Same as above but different rectangle sizes. */ const depth_t *curr = rect_curr->buf + ps->cache.sub_rect.start; for (uint i = 0; i < ps->cache.sub_rect.span_len; i++) { const depth_t *curr_end = curr + ps->cache.sub_rect.span; @@ -424,7 +437,7 @@ static void gpu_select_load_id_pass_all(const DepthBufCache *rect_curr) #undef EVAL_TEST - /* ensure enough space */ + /* Ensure enough space. */ if (UNLIKELY(ps->all.hits_len == ps->all.hits_len_alloc)) { ps->all.hits_len_alloc += ALLOC_DEPTHS; ps->all.hits = MEM_reallocN(ps->all.hits, ps->all.hits_len_alloc * sizeof(*ps->all.hits)); @@ -439,7 +452,7 @@ static void gpu_select_load_id_pass_nearest(const DepthBufCache *rect_prev, { GPUPickState *ps = &g_pick_state; const uint id = rect_curr->id; - /* keep track each pixels ID in 'nearest.rect_id' */ + /* Keep track each pixels ID in `nearest.rect_id`. */ if (id != SELECT_ID_NONE) { uint *id_ptr = ps->nearest.rect_id; @@ -483,8 +496,8 @@ bool gpu_select_pick_load_id(uint id, bool end) { GPUPickState *ps = &g_pick_state; - if (ps->gl.is_init) { - if (id == ps->gl.prev_id && !end) { + if (ps->gpu.is_init) { + if (id == ps->gpu.prev_id && !end) { /* No need to read if we are still drawing for the same id since * all these depths will be merged / de-duplicated in the end. */ return true; @@ -493,21 +506,21 @@ bool gpu_select_pick_load_id(uint id, bool end) const uint rect_len = ps->src.rect_len; GPUFrameBuffer *fb = GPU_framebuffer_active_get(); GPU_framebuffer_read_depth( - fb, UNPACK4(ps->gl.clip_readpixels), GPU_DATA_UINT, ps->gl.rect_depth_test->buf); + fb, UNPACK4(ps->gpu.clip_readpixels), GPU_DATA_UINT, ps->gpu.rect_depth_test->buf); /* Perform initial check since most cases the array remains unchanged. */ bool do_pass = false; if (g_pick_state.mode == GPU_SELECT_PICK_ALL) { - if (depth_buf_rect_depth_any(ps->gl.rect_depth_test, rect_len)) { - ps->gl.rect_depth_test->id = ps->gl.prev_id; - gpu_select_load_id_pass_all(ps->gl.rect_depth_test); + if (depth_buf_rect_depth_any(ps->gpu.rect_depth_test, rect_len)) { + ps->gpu.rect_depth_test->id = ps->gpu.prev_id; + gpu_select_load_id_pass_all(ps->gpu.rect_depth_test); do_pass = true; } } else { - if (depth_buf_rect_depth_any_filled(ps->gl.rect_depth, ps->gl.rect_depth_test, rect_len)) { - ps->gl.rect_depth_test->id = ps->gl.prev_id; - gpu_select_load_id_pass_nearest(ps->gl.rect_depth, ps->gl.rect_depth_test); + if (depth_buf_rect_depth_any_filled(ps->gpu.rect_depth, ps->gpu.rect_depth_test, rect_len)) { + ps->gpu.rect_depth_test->id = ps->gpu.prev_id; + gpu_select_load_id_pass_nearest(ps->gpu.rect_depth, ps->gpu.rect_depth_test); do_pass = true; } } @@ -515,11 +528,11 @@ bool gpu_select_pick_load_id(uint id, bool end) if (do_pass) { /* Store depth in cache */ if (ps->use_cache) { - BLI_addtail(&ps->cache.bufs, ps->gl.rect_depth); - ps->gl.rect_depth = depth_buf_malloc(ps->src.rect_len); + BLI_addtail(&ps->cache.bufs, ps->gpu.rect_depth); + ps->gpu.rect_depth = depth_buf_malloc(ps->src.rect_len); } - SWAP(DepthBufCache *, ps->gl.rect_depth, ps->gl.rect_depth_test); + SWAP(DepthBufCache *, ps->gpu.rect_depth, ps->gpu.rect_depth_test); if (g_pick_state.mode == GPU_SELECT_PICK_ALL) { /* (fclem) This is to be on the safe side. I don't know if this is required. */ @@ -533,8 +546,8 @@ bool gpu_select_pick_load_id(uint id, bool end) } } - ps->gl.is_init = true; - ps->gl.prev_id = id; + ps->gpu.is_init = true; + ps->gpu.prev_id = id; return true; } @@ -548,9 +561,9 @@ uint gpu_select_pick_end(void) #endif if (ps->is_cached == false) { - if (ps->gl.is_init) { + if (ps->gpu.is_init) { /* force finishing last pass */ - gpu_select_pick_load_id(ps->gl.prev_id, true); + gpu_select_pick_load_id(ps->gpu.prev_id, true); } GPU_write_mask(ps->write_mask); GPU_depth_test(ps->depth_test); @@ -559,39 +572,39 @@ uint gpu_select_pick_end(void) GPU_debug_group_end(); - /* assign but never free directly since it may be in cache */ + /* Assign but never free directly since it may be in cache. */ DepthBufCache *rect_depth_final; /* Store depth in cache */ if (ps->use_cache && !ps->is_cached) { - BLI_addtail(&ps->cache.bufs, ps->gl.rect_depth); - ps->gl.rect_depth = NULL; + BLI_addtail(&ps->cache.bufs, ps->gpu.rect_depth); + ps->gpu.rect_depth = NULL; rect_depth_final = ps->cache.bufs.last; } else if (ps->is_cached) { rect_depth_final = ps->cache.bufs.last; } else { - /* common case, no cache */ - rect_depth_final = ps->gl.rect_depth; + /* Common case, no cache. */ + rect_depth_final = ps->gpu.rect_depth; } - uint maxhits = g_pick_state.bufsize; + uint maxhits = g_pick_state.buffer_len; DepthID *depth_data; uint depth_data_len = 0; if (g_pick_state.mode == GPU_SELECT_PICK_ALL) { depth_data = ps->all.hits; depth_data_len = ps->all.hits_len; - /* move ownership */ + /* Move ownership. */ ps->all.hits = NULL; ps->all.hits_len = 0; ps->all.hits_len_alloc = 0; } else { - /* GPU_SELECT_PICK_NEAREST */ + /* #GPU_SELECT_PICK_NEAREST */ - /* Over alloc (unlikely we have as many depths as pixels) */ + /* Over allocate (unlikely we have as many depths as pixels). */ uint depth_data_len_first_pass = 0; depth_data = MEM_mallocN(ps->dst.rect_len * sizeof(*depth_data), __func__); @@ -624,7 +637,7 @@ uint gpu_select_pick_end(void) } } else { - /* same as above but different rect sizes */ + /* Same as above but different rectangle sizes. */ uint i_src = ps->cache.sub_rect.start, i_dst = 0; for (uint j = 0; j < ps->cache.sub_rect.span_len; j++) { const uint i_src_end = i_src + ps->cache.sub_rect.span; @@ -640,7 +653,7 @@ uint gpu_select_pick_end(void) qsort(depth_data, depth_data_len_first_pass, sizeof(DepthID), depth_id_cmp); - /* Sort by ID's then keep the best depth for each ID */ + /* Sort by ID's then keep the best depth for each ID. */ depth_data_len = 0; { DepthID *depth_last = NULL; @@ -657,25 +670,22 @@ uint gpu_select_pick_end(void) } /* Finally sort each unique (id, depth) pair by depth - * so the final hit-list is sorted by depth (nearest first) */ + * so the final hit-list is sorted by depth (nearest first). */ uint hits = 0; if (depth_data_len > maxhits) { hits = (uint)-1; } else { - /* leave sorting up to the caller */ + /* Leave sorting up to the caller. */ qsort(depth_data, depth_data_len, sizeof(DepthID), depth_cmp); for (uint i = 0; i < depth_data_len; i++) { #ifdef DEBUG_PRINT printf(" hit: %u: depth %u\n", depth_data[i].id, depth_data[i].depth); #endif - /* first 3 are dummy values */ - g_pick_state.buffer[hits][0] = 1; - g_pick_state.buffer[hits][1] = depth_data[i].depth; - g_pick_state.buffer[hits][2] = 0x0; /* z-far is currently never used. */ - g_pick_state.buffer[hits][3] = depth_data[i].id; + g_pick_state.buffer[hits].depth = depth_data[i].depth; + g_pick_state.buffer[hits].id = depth_data[i].id; hits++; } BLI_assert(hits < maxhits); @@ -683,8 +693,8 @@ uint gpu_select_pick_end(void) MEM_freeN(depth_data); - MEM_SAFE_FREE(ps->gl.rect_depth); - MEM_SAFE_FREE(ps->gl.rect_depth_test); + MEM_SAFE_FREE(ps->gpu.rect_depth); + MEM_SAFE_FREE(ps->gpu.rect_depth_test); if (g_pick_state.mode == GPU_SELECT_PICK_ALL) { /* 'hits' already freed as 'depth_data' */ @@ -744,8 +754,8 @@ void gpu_select_pick_cache_load_id(void) #endif LISTBASE_FOREACH (DepthBufCache *, rect_depth, &ps->cache.bufs) { if (rect_depth->next != NULL) { - /* we know the buffers differ, but this sub-region may not. - * double check before adding an id-pass */ + /* We know the buffers differ, but this sub-region may not. + * Double check before adding an id-pass. */ if (g_pick_state.mode == GPU_SELECT_PICK_ALL) { if (depth_buf_subrect_depth_any(rect_depth->next, &ps->cache.sub_rect)) { gpu_select_load_id_pass_all(rect_depth->next); diff --git a/source/blender/gpu/intern/gpu_select_private.h b/source/blender/gpu/intern/gpu_select_private.h index e5a84a037a6..0ec9f083c07 100644 --- a/source/blender/gpu/intern/gpu_select_private.h +++ b/source/blender/gpu/intern/gpu_select_private.h @@ -31,7 +31,10 @@ extern "C" { /* gpu_select_pick */ -void gpu_select_pick_begin(uint (*buffer)[4], uint bufsize, const rcti *input, char mode); +void gpu_select_pick_begin(GPUSelectResult *buffer, + uint buffer_len, + const rcti *input, + eGPUSelectMode mode); bool gpu_select_pick_load_id(uint id, bool end); uint gpu_select_pick_end(void); @@ -46,7 +49,7 @@ void gpu_select_pick_cache_load_id(void); /* gpu_select_sample_query */ void gpu_select_query_begin( - uint (*buffer)[4], uint bufsize, const rcti *input, char mode, int oldhits); + GPUSelectResult *buffer, uint buffer_len, const rcti *input, eGPUSelectMode mode, int oldhits); bool gpu_select_query_load_id(uint id); uint gpu_select_query_end(void); diff --git a/source/blender/gpu/intern/gpu_select_sample_query.cc b/source/blender/gpu/intern/gpu_select_sample_query.cc index a430d4a9d62..7559358aaca 100644 --- a/source/blender/gpu/intern/gpu_select_sample_query.cc +++ b/source/blender/gpu/intern/gpu_select_sample_query.cc @@ -48,22 +48,22 @@ using namespace blender; using namespace blender::gpu; struct GPUSelectQueryState { - /* Tracks whether a query has been issued so that gpu_load_id can end the previous one. */ + /** Tracks whether a query has been issued so that gpu_load_id can end the previous one. */ bool query_issued; - /* GPU queries abstraction. Contains an array of queries. */ + /** GPU queries abstraction. Contains an array of queries. */ QueryPool *queries; - /* Array holding the id corresponding id to each query. */ + /** Array holding the id corresponding id to each query. */ Vector<uint> *ids; - /* Cache on initialization. */ - uint (*buffer)[4]; - /* Buffer size (stores number of integers, for actual size multiply by `sizeof(int)`). */ - uint bufsize; - /* Mode of operation. */ - char mode; + /** Cache on initialization. */ + GPUSelectResult *buffer; + /** The capacity of the `buffer` array. */ + uint buffer_len; + /** Mode of operation. */ + eGPUSelectMode mode; uint index; int oldhits; - /* Previous state to restore after drawing. */ + /** Previous state to restore after drawing. */ int viewport[4]; int scissor[4]; eGPUWriteMask write_mask; @@ -72,14 +72,17 @@ struct GPUSelectQueryState { static GPUSelectQueryState g_query_state = {false}; -void gpu_select_query_begin( - uint (*buffer)[4], uint bufsize, const rcti *input, char mode, int oldhits) +void gpu_select_query_begin(GPUSelectResult *buffer, + uint buffer_len, + const rcti *input, + const eGPUSelectMode mode, + int oldhits) { GPU_debug_group_begin("Selection Queries"); g_query_state.query_issued = false; - g_query_state.bufsize = bufsize; g_query_state.buffer = buffer; + g_query_state.buffer_len = buffer_len; g_query_state.mode = mode; g_query_state.index = 0; g_query_state.oldhits = oldhits; @@ -111,7 +114,7 @@ void gpu_select_query_begin( /* occlusion queries operates on fragments that pass tests and since we are interested on all * objects in the view frustum independently of their order, we need to disable the depth test */ if (mode == GPU_SELECT_ALL) { - /* glQueries on Windows+Intel drivers only works with depth testing turned on. + /* #glQueries on Windows+Intel drivers only works with depth testing turned on. * See T62947 for details */ GPU_depth_test(GPU_DEPTH_ALWAYS); GPU_depth_mask(true); @@ -138,10 +141,11 @@ bool gpu_select_query_load_id(uint id) g_query_state.query_issued = true; if (g_query_state.mode == GPU_SELECT_NEAREST_SECOND_PASS) { - /* Second pass should never run if first pass fails, can read past 'bufsize' in this case. */ + /* Second pass should never run if first pass fails, + * can read past `buffer_len` in this case. */ BLI_assert(g_query_state.oldhits != -1); if (g_query_state.index < g_query_state.oldhits) { - if (g_query_state.buffer[g_query_state.index][3] == id) { + if (g_query_state.buffer[g_query_state.index].id == id) { g_query_state.index++; return true; } @@ -154,7 +158,7 @@ bool gpu_select_query_load_id(uint id) uint gpu_select_query_end() { uint hits = 0; - const uint maxhits = g_query_state.bufsize; + const uint maxhits = g_query_state.buffer_len; if (g_query_state.query_issued) { g_query_state.queries->end_query(); @@ -168,10 +172,8 @@ uint gpu_select_query_end() if (result[i] != 0) { if (g_query_state.mode != GPU_SELECT_NEAREST_SECOND_PASS) { if (hits < maxhits) { - g_query_state.buffer[hits][0] = 1; - g_query_state.buffer[hits][1] = 0xFFFF; - g_query_state.buffer[hits][2] = 0xFFFF; - g_query_state.buffer[hits][3] = ids[i]; + g_query_state.buffer[hits].depth = 0xFFFF; + g_query_state.buffer[hits].id = ids[i]; hits++; } else { @@ -183,9 +185,8 @@ uint gpu_select_query_end() int j; /* search in buffer and make selected object first */ for (j = 0; j < g_query_state.oldhits; j++) { - if (g_query_state.buffer[j][3] == ids[i]) { - g_query_state.buffer[j][1] = 0; - g_query_state.buffer[j][2] = 0; + if (g_query_state.buffer[j].id == ids[i]) { + g_query_state.buffer[j].depth = 0; } } break; diff --git a/source/blender/gpu/intern/gpu_shader.cc b/source/blender/gpu/intern/gpu_shader.cc index ef800abc3c9..2e924925ab8 100644 --- a/source/blender/gpu/intern/gpu_shader.cc +++ b/source/blender/gpu/intern/gpu_shader.cc @@ -249,6 +249,11 @@ GPUShader *GPU_shader_create_compute(const char *computecode, shname); } +const GPUShaderCreateInfo *GPU_shader_create_info_get(const char *info_name) +{ + return gpu_shader_create_info_get(info_name); +} + GPUShader *GPU_shader_create_from_info_name(const char *info_name) { using namespace blender::gpu::shader; @@ -309,9 +314,8 @@ GPUShader *GPU_shader_create_from_info(const GPUShaderCreateInfo *_info) } if (!info.vertex_source_.is_empty()) { - uint32_t builtins = 0; + char *code = gpu_shader_dependency_get_resolved_source(info.vertex_source_.c_str()); std::string interface = shader->vertex_interface_declare(info); - char *code = gpu_shader_dependency_get_resolved_source(info.vertex_source_.c_str(), &builtins); Vector<const char *> sources; standard_defines(sources); @@ -336,10 +340,8 @@ GPUShader *GPU_shader_create_from_info(const GPUShaderCreateInfo *_info) } if (!info.fragment_source_.is_empty()) { - uint32_t builtins = 0; + char *code = gpu_shader_dependency_get_resolved_source(info.fragment_source_.c_str()); std::string interface = shader->fragment_interface_declare(info); - char *code = gpu_shader_dependency_get_resolved_source(info.fragment_source_.c_str(), - &builtins); Vector<const char *> sources; standard_defines(sources); @@ -364,11 +366,9 @@ GPUShader *GPU_shader_create_from_info(const GPUShaderCreateInfo *_info) } if (!info.geometry_source_.is_empty()) { - uint32_t builtins = 0; - std::string interface = shader->geometry_interface_declare(info); + char *code = gpu_shader_dependency_get_resolved_source(info.geometry_source_.c_str()); std::string layout = shader->geometry_layout_declare(info); - char *code = gpu_shader_dependency_get_resolved_source(info.geometry_source_.c_str(), - &builtins); + std::string interface = shader->geometry_interface_declare(info); Vector<const char *> sources; standard_defines(sources); @@ -391,9 +391,7 @@ GPUShader *GPU_shader_create_from_info(const GPUShaderCreateInfo *_info) } if (!info.compute_source_.is_empty()) { - uint32_t builtins = 0; - char *code = gpu_shader_dependency_get_resolved_source(info.compute_source_.c_str(), - &builtins); + char *code = gpu_shader_dependency_get_resolved_source(info.compute_source_.c_str()); std::string layout = shader->compute_layout_declare(info); Vector<const char *> sources; diff --git a/source/blender/gpu/intern/gpu_shader_create_info.cc b/source/blender/gpu/intern/gpu_shader_create_info.cc index 492b247e192..1464a7ade24 100644 --- a/source/blender/gpu/intern/gpu_shader_create_info.cc +++ b/source/blender/gpu/intern/gpu_shader_create_info.cc @@ -34,6 +34,7 @@ #include "gpu_shader_create_info.hh" #include "gpu_shader_create_info_private.hh" +#include "gpu_shader_dependency_private.h" #include "gpu_shader_private.hh" #undef GPU_SHADER_INTERFACE_INFO @@ -167,7 +168,7 @@ void ShaderCreateInfo::validate(const ShaderCreateInfo &other_info) } } { - /* TODO(fclem) Push constant validation. */ + /* TODO(@fclem): Push constant validation. */ } } @@ -209,6 +210,19 @@ void gpu_shader_create_info_init() draw_modelmat = draw_modelmat_legacy; } + for (ShaderCreateInfo *info : g_create_infos->values()) { + if (info->do_static_compilation_) { + info->builtins_ |= static_cast<BuiltinBits>( + gpu_shader_dependency_get_builtins(info->vertex_source_.c_str())); + info->builtins_ |= static_cast<BuiltinBits>( + gpu_shader_dependency_get_builtins(info->fragment_source_.c_str())); + info->builtins_ |= static_cast<BuiltinBits>( + gpu_shader_dependency_get_builtins(info->geometry_source_.c_str())); + info->builtins_ |= static_cast<BuiltinBits>( + gpu_shader_dependency_get_builtins(info->compute_source_.c_str())); + } + } + /* TEST */ // gpu_shader_create_info_compile_all(); } @@ -302,6 +316,7 @@ const GPUShaderCreateInfo *gpu_shader_create_info_get(const char *info_name) { if (g_create_infos->contains(info_name) == false) { printf("Error: Cannot find shader create info named \"%s\"\n", info_name); + return nullptr; } ShaderCreateInfo *info = g_create_infos->lookup(info_name); return reinterpret_cast<const GPUShaderCreateInfo *>(info); diff --git a/source/blender/gpu/intern/gpu_shader_create_info.hh b/source/blender/gpu/intern/gpu_shader_create_info.hh index 63c6e94f4c8..736a8ed0590 100644 --- a/source/blender/gpu/intern/gpu_shader_create_info.hh +++ b/source/blender/gpu/intern/gpu_shader_create_info.hh @@ -63,6 +63,7 @@ enum class Type { }; enum class BuiltinBits { + NONE = 0, /** * Allow getting barycentric coordinates inside the fragment shader. * \note Emulated on OpenGL. @@ -72,6 +73,10 @@ enum class BuiltinBits { FRONT_FACING = (1 << 4), GLOBAL_INVOCATION_ID = (1 << 5), INSTANCE_ID = (1 << 6), + /** + * Allow setting the target layer when the output is a layered framebuffer. + * \note Emulated through geometry shader on older hardware. + */ LAYER = (1 << 7), LOCAL_INVOCATION_ID = (1 << 8), LOCAL_INVOCATION_INDEX = (1 << 9), @@ -125,10 +130,13 @@ enum class ImageType { /* Storage qualifiers. */ enum class Qualifier { - RESTRICT = (1 << 0), - READ_ONLY = (1 << 1), - WRITE_ONLY = (1 << 2), - QUALIFIER_MAX = (WRITE_ONLY << 1) - 1, + /** Restrict flag is set by default. Unless specified otherwise. */ + NO_RESTRICT = (1 << 0), + READ = (1 << 1), + WRITE = (1 << 2), + /** Shorthand version of combined flags. */ + READ_WRITE = READ | WRITE, + QUALIFIER_MAX = (WRITE << 1) - 1, }; ENUM_OPERATORS(Qualifier, Qualifier::QUALIFIER_MAX); @@ -226,6 +234,8 @@ struct ShaderCreateInfo { * Only for names used by gpu::ShaderInterface. */ size_t interface_names_size_ = 0; + /** Manually set builtins. */ + BuiltinBits builtins_ = BuiltinBits::NONE; struct VertIn { int index; @@ -538,6 +548,12 @@ struct ShaderCreateInfo { return *(Self *)this; } + Self &builtins(BuiltinBits builtin) + { + builtins_ |= builtin; + return *(Self *)this; + } + /** \} */ /* -------------------------------------------------------------------- */ diff --git a/source/blender/gpu/intern/gpu_shader_dependency.cc b/source/blender/gpu/intern/gpu_shader_dependency.cc index 5e03f7d0767..0db03c2b636 100644 --- a/source/blender/gpu/intern/gpu_shader_dependency.cc +++ b/source/blender/gpu/intern/gpu_shader_dependency.cc @@ -59,7 +59,6 @@ struct GPUSource { /* Scan for builtins. */ /* FIXME: This can trigger false positive caused by disabled #if blocks. */ /* TODO(fclem): Could be made faster by scanning once. */ - /* TODO(fclem): BARYCENTRIC_COORD. */ if (source.find("gl_FragCoord", 0)) { builtins |= shader::BuiltinBits::FRAG_COORD; } @@ -72,9 +71,6 @@ struct GPUSource { if (source.find("gl_InstanceID", 0)) { builtins |= shader::BuiltinBits::INSTANCE_ID; } - if (source.find("gl_Layer", 0)) { - builtins |= shader::BuiltinBits::LAYER; - } if (source.find("gl_LocalInvocationID", 0)) { builtins |= shader::BuiltinBits::LOCAL_INVOCATION_ID; } @@ -336,13 +332,23 @@ struct GPUSource { } /* Returns the final string with all includes done. */ - void build(std::string &str, shader::BuiltinBits &out_builtins) + std::string build() const { + std::string str; for (auto *dep : dependencies) { - out_builtins |= builtins; str += dep->source; } str += source; + return str; + } + + shader::BuiltinBits builtins_get() const + { + shader::BuiltinBits out_builtins = shader::BuiltinBits::NONE; + for (auto *dep : dependencies) { + out_builtins |= dep->builtins; + } + return out_builtins; } }; @@ -377,14 +383,19 @@ void gpu_shader_dependency_exit() delete g_sources; } -char *gpu_shader_dependency_get_resolved_source(const char *shader_source_name, uint32_t *builtins) +uint32_t gpu_shader_dependency_get_builtins(const char *shader_source_name) +{ + if (shader_source_name[0] == '\0') { + return 0; + } + GPUSource *source = g_sources->lookup(shader_source_name); + return static_cast<uint32_t>(source->builtins_get()); +} + +char *gpu_shader_dependency_get_resolved_source(const char *shader_source_name) { GPUSource *source = g_sources->lookup(shader_source_name); - std::string str; - shader::BuiltinBits out_builtins; - source->build(str, out_builtins); - *builtins |= (uint32_t)out_builtins; - return strdup(str.c_str()); + return strdup(source->build().c_str()); } char *gpu_shader_dependency_get_source(const char *shader_source_name) diff --git a/source/blender/gpu/intern/gpu_shader_dependency_private.h b/source/blender/gpu/intern/gpu_shader_dependency_private.h index b129ca74a48..083c38897ce 100644 --- a/source/blender/gpu/intern/gpu_shader_dependency_private.h +++ b/source/blender/gpu/intern/gpu_shader_dependency_private.h @@ -35,10 +35,11 @@ void gpu_shader_dependency_init(void); void gpu_shader_dependency_exit(void); /* User must free the resulting string using free. */ -char *gpu_shader_dependency_get_resolved_source(const char *shader_source_name, - uint32_t *builtins); +char *gpu_shader_dependency_get_resolved_source(const char *shader_source_name); char *gpu_shader_dependency_get_source(const char *shader_source_name); +uint32_t gpu_shader_dependency_get_builtins(const char *shader_source_name); + #ifdef __cplusplus } #endif diff --git a/source/blender/gpu/intern/gpu_shader_log.cc b/source/blender/gpu/intern/gpu_shader_log.cc index 12459b4b721..21973cf976a 100644 --- a/source/blender/gpu/intern/gpu_shader_log.cc +++ b/source/blender/gpu/intern/gpu_shader_log.cc @@ -102,7 +102,7 @@ void Shader::print_log(Span<const char *> sources, found_line_id = true; break; } -/* TODO(fclem) Make this an option to display N lines before error. */ +/* TODO(@fclem): Make this an option to display N lines before error. */ #if 0 /* Uncomment to print shader file up to the error line to have more context. */ BLI_dynstr_appendf(dynstr, "%5d | ", src_line_index); BLI_dynstr_nappend(dynstr, src_line, (src_line_end + 1) - src_line); diff --git a/source/blender/gpu/opengl/gl_backend.cc b/source/blender/gpu/opengl/gl_backend.cc index 92d180f1140..2ee7c0503f4 100644 --- a/source/blender/gpu/opengl/gl_backend.cc +++ b/source/blender/gpu/opengl/gl_backend.cc @@ -248,6 +248,8 @@ static void detect_workarounds() GLContext::direct_state_access_support = false; GLContext::fixed_restart_index_support = false; GLContext::geometry_shader_invocations = false; + GLContext::layered_rendering_support = false; + GLContext::native_barycentric_support = false; GLContext::multi_bind_support = false; GLContext::multi_draw_indirect_support = false; GLContext::shader_draw_parameters_support = false; @@ -445,6 +447,8 @@ bool GLContext::direct_state_access_support = false; bool GLContext::explicit_location_support = false; bool GLContext::geometry_shader_invocations = false; bool GLContext::fixed_restart_index_support = false; +bool GLContext::layered_rendering_support = false; +bool GLContext::native_barycentric_support = false; bool GLContext::multi_bind_support = false; bool GLContext::multi_draw_indirect_support = false; bool GLContext::shader_draw_parameters_support = false; @@ -505,6 +509,8 @@ void GLBackend::capabilities_init() GLContext::explicit_location_support = GLEW_VERSION_4_3; GLContext::geometry_shader_invocations = GLEW_ARB_gpu_shader5; GLContext::fixed_restart_index_support = GLEW_ARB_ES3_compatibility; + GLContext::layered_rendering_support = GLEW_AMD_vertex_shader_layer; + GLContext::native_barycentric_support = GLEW_AMD_shader_explicit_vertex_parameter; GLContext::multi_bind_support = GLEW_ARB_multi_bind; GLContext::multi_draw_indirect_support = GLEW_ARB_multi_draw_indirect; GLContext::shader_draw_parameters_support = GLEW_ARB_shader_draw_parameters; diff --git a/source/blender/gpu/opengl/gl_context.hh b/source/blender/gpu/opengl/gl_context.hh index dd22418972b..b7a74863ac4 100644 --- a/source/blender/gpu/opengl/gl_context.hh +++ b/source/blender/gpu/opengl/gl_context.hh @@ -72,6 +72,8 @@ class GLContext : public Context { static bool explicit_location_support; static bool geometry_shader_invocations; static bool fixed_restart_index_support; + static bool layered_rendering_support; + static bool native_barycentric_support; static bool multi_bind_support; static bool multi_draw_indirect_support; static bool shader_draw_parameters_support; diff --git a/source/blender/gpu/opengl/gl_shader.cc b/source/blender/gpu/opengl/gl_shader.cc index e031047f844..3ab3b11d1f4 100644 --- a/source/blender/gpu/opengl/gl_shader.cc +++ b/source/blender/gpu/opengl/gl_shader.cc @@ -277,15 +277,15 @@ static void print_image_type(std::ostream &os, static std::ostream &print_qualifier(std::ostream &os, const Qualifier &qualifiers) { - if ((qualifiers & Qualifier::RESTRICT) == Qualifier::RESTRICT) { + if (bool(qualifiers & Qualifier::NO_RESTRICT) == false) { os << "restrict "; } - if ((qualifiers & Qualifier::READ_ONLY) == Qualifier::READ_ONLY) { - os << "readonly "; - } - if ((qualifiers & Qualifier::WRITE_ONLY) == Qualifier::WRITE_ONLY) { + if (bool(qualifiers & Qualifier::READ) == false) { os << "writeonly "; } + if (bool(qualifiers & Qualifier::WRITE) == false) { + os << "readonly "; + } return os; } @@ -370,7 +370,7 @@ static void print_interface(std::ostream &os, const StageInterfaceInfo &iface, const StringRefNull &suffix = "") { - /* TODO(fclem) Move that to interface check. */ + /* TODO(@fclem): Move that to interface check. */ // if (iface.instance_name.is_empty()) { // BLI_assert_msg(0, "Interfaces require an instance name for geometry shader."); // std::cout << iface.name << ": Interfaces require an instance name for geometry shader.\n"; @@ -426,9 +426,28 @@ std::string GLShader::resources_declare(const ShaderCreateInfo &info) const return ss.str(); } +static std::string main_function_wrapper(std::string &pre_main, std::string &post_main) +{ + std::stringstream ss; + /* Prototype for the original main. */ + ss << "\n"; + ss << "void main_function_();\n"; + /* Wrapper to the main function in order to inject code processing on globals. */ + ss << "void main() {\n"; + ss << pre_main; + ss << " main_function_();\n"; + ss << post_main; + ss << "}\n"; + /* Rename the original main. */ + ss << "#define main main_function_\n"; + ss << "\n"; + return ss.str(); +} + std::string GLShader::vertex_interface_declare(const ShaderCreateInfo &info) const { std::stringstream ss; + std::string post_main = ""; ss << "\n/* Inputs. */\n"; for (const ShaderCreateInfo::VertIn &attr : info.vertex_inputs_) { @@ -441,13 +460,35 @@ std::string GLShader::vertex_interface_declare(const ShaderCreateInfo &info) con for (const StageInterfaceInfo *iface : info.vertex_out_interfaces_) { print_interface(ss, "out", *iface); } + if (!GLContext::layered_rendering_support && bool(info.builtins_ & BuiltinBits::LAYER)) { + ss << "out int gpu_Layer;\n"; + } + if (bool(info.builtins_ & BuiltinBits::BARYCENTRIC_COORD)) { + if (!GLContext::native_barycentric_support) { + /* Disabled or unsupported. */ + } + else if (GLEW_AMD_shader_explicit_vertex_parameter) { + /* Need this for stable barycentric. */ + ss << "flat out vec4 gpu_pos_flat;\n"; + ss << "out vec4 gpu_pos;\n"; + + post_main += " gpu_pos = gpu_pos_flat = gl_Position;\n"; + } + } ss << "\n"; + + if (post_main.empty() == false) { + std::string pre_main = ""; + ss << main_function_wrapper(pre_main, post_main); + } return ss.str(); } std::string GLShader::fragment_interface_declare(const ShaderCreateInfo &info) const { std::stringstream ss; + std::string pre_main = ""; + ss << "\n/* Interfaces. */\n"; const Vector<StageInterfaceInfo *> &in_interfaces = (info.geometry_source_.is_empty()) ? info.vertex_out_interfaces_ : @@ -455,6 +496,32 @@ std::string GLShader::fragment_interface_declare(const ShaderCreateInfo &info) c for (const StageInterfaceInfo *iface : in_interfaces) { print_interface(ss, "in", *iface); } + if (bool(info.builtins_ & BuiltinBits::BARYCENTRIC_COORD)) { + if (!GLContext::native_barycentric_support) { + ss << "smooth in vec3 gpu_BaryCoord;\n"; + ss << "noperspective in vec3 gpu_BaryCoordNoPersp;\n"; + } + else if (GLEW_AMD_shader_explicit_vertex_parameter) { + /* NOTE(fclem): This won't work with geometry shader. Hopefully, we don't need geometry + * shader workaround if this extension/feature is detected. */ + ss << "\n/* Stable Barycentric Coordinates. */\n"; + ss << "flat in vec4 gpu_pos_flat;\n"; + ss << "__explicitInterpAMD in vec4 gpu_pos;\n"; + /* Globals. */ + ss << "vec3 gpu_BaryCoord;\n"; + ss << "vec3 gpu_BaryCoordNoPersp;\n"; + ss << "\n"; + ss << "vec2 stable_bary_(vec2 in_bary) {\n"; + ss << " vec3 bary = vec3(in_bary, 1.0 - in_bary.x - in_bary.y);\n"; + ss << " if (interpolateAtVertexAMD(gpu_pos, 0) == gpu_pos_flat) { return bary.zxy; }\n"; + ss << " if (interpolateAtVertexAMD(gpu_pos, 2) == gpu_pos_flat) { return bary.yzx; }\n"; + ss << " return bary.xyz;\n"; + ss << "}\n"; + + pre_main += " gpu_BaryCoord = stable_bary_(gl_BaryCoordSmoothAMD);\n"; + pre_main += " gpu_BaryCoordNoPersp = stable_bary_(gl_BaryCoordNoPerspAMD);\n"; + } + } ss << "\n/* Outputs. */\n"; for (const ShaderCreateInfo::FragOut &output : info.fragment_outputs_) { ss << "layout(location = " << output.index; @@ -472,6 +539,11 @@ std::string GLShader::fragment_interface_declare(const ShaderCreateInfo &info) c ss << "out " << to_string(output.type) << " " << output.name << ";\n"; } ss << "\n"; + + if (pre_main.empty() == false) { + std::string post_main = ""; + ss << main_function_wrapper(pre_main, post_main); + } return ss.str(); } @@ -503,7 +575,7 @@ static StageInterfaceInfo *find_interface_by_name(const Vector<StageInterfaceInf const StringRefNull &name) { for (auto *iface : ifaces) { - if (iface->name == name) { + if (iface->instance_name == name) { return iface; } } @@ -512,8 +584,8 @@ static StageInterfaceInfo *find_interface_by_name(const Vector<StageInterfaceInf std::string GLShader::geometry_interface_declare(const ShaderCreateInfo &info) const { - std::stringstream ss; + ss << "\n/* Interfaces. */\n"; for (const StageInterfaceInfo *iface : info.vertex_out_interfaces_) { bool has_matching_output_iface = find_interface_by_name(info.geometry_out_interfaces_, @@ -547,6 +619,76 @@ std::string GLShader::compute_layout_declare(const ShaderCreateInfo &info) const ss << "\n"; return ss.str(); } +/** \} */ + +/* -------------------------------------------------------------------- */ +/** \name Passthrough geometry shader emulation + * + * \{ */ + +std::string GLShader::workaround_geometry_shader_source_create( + const shader::ShaderCreateInfo &info) +{ + std::stringstream ss; + + const bool do_layer_workaround = !GLContext::layered_rendering_support && + bool(info.builtins_ & BuiltinBits::LAYER); + const bool do_barycentric_workaround = !GLContext::native_barycentric_support && + bool(info.builtins_ & BuiltinBits::BARYCENTRIC_COORD); + + shader::ShaderCreateInfo info_modified = info; + info_modified.geometry_out_interfaces_ = info_modified.vertex_out_interfaces_; + /** + * NOTE(@fclem): Assuming we will render TRIANGLES. This will not work with other primitive + * types. In this case, it might not trigger an error on some implementations. + */ + info_modified.geometry_layout(PrimitiveIn::TRIANGLES, PrimitiveOut::TRIANGLE_STRIP, 3); + + ss << geometry_layout_declare(info_modified); + ss << geometry_interface_declare(info_modified); + if (do_layer_workaround) { + ss << "in int gpu_Layer[];\n"; + } + if (do_barycentric_workaround) { + ss << "smooth out vec3 gpu_BaryCoord;\n"; + ss << "noperspective out vec3 gpu_BaryCoordNoPersp;\n"; + } + ss << "\n"; + + ss << "void main()\n"; + ss << "{\n"; + if (do_layer_workaround) { + ss << " gl_Layer = gpu_Layer[0];\n"; + } + for (auto i : IndexRange(3)) { + for (auto iface : info_modified.vertex_out_interfaces_) { + for (auto &inout : iface->inouts) { + ss << " " << iface->instance_name << "_out." << inout.name; + ss << " = " << iface->instance_name << "_in[" << i << "]." << inout.name << ";\n"; + } + } + if (do_barycentric_workaround) { + ss << " gpu_BaryCoordNoPersp = gpu_BaryCoord ="; + ss << " vec3(" << int(i == 0) << ", " << int(i == 1) << ", " << int(i == 2) << ");\n"; + } + ss << " gl_Position = gl_in[" << i << "].gl_Position;\n"; + ss << " EmitVertex();\n"; + } + ss << "}\n"; + return ss.str(); +} + +bool GLShader::do_geometry_shader_injection(const shader::ShaderCreateInfo *info) +{ + BuiltinBits builtins = info->builtins_; + if (!GLContext::native_barycentric_support && bool(builtins & BuiltinBits::BARYCENTRIC_COORD)) { + return true; + } + if (!GLContext::layered_rendering_support && bool(builtins & BuiltinBits::LAYER)) { + return true; + } + return false; +} /** \} */ @@ -557,7 +699,7 @@ std::string GLShader::compute_layout_declare(const ShaderCreateInfo &info) const static char *glsl_patch_default_get() { /** Used for shader patching. Init once. */ - static char patch[700] = "\0"; + static char patch[1024] = "\0"; if (patch[0] != '\0') { return patch; } @@ -601,6 +743,13 @@ static char *glsl_patch_default_get() STR_CONCAT(patch, slen, "#extension GL_ARB_shader_image_load_store: enable\n"); STR_CONCAT(patch, slen, "#extension GL_ARB_shading_language_420pack: enable\n"); } + if (GLContext::layered_rendering_support) { + STR_CONCAT(patch, slen, "#extension GL_AMD_vertex_shader_layer: enable\n"); + STR_CONCAT(patch, slen, "#define gpu_Layer gl_Layer\n"); + } + if (GLContext::native_barycentric_support) { + STR_CONCAT(patch, slen, "#extension GL_AMD_shader_explicit_vertex_parameter: enable\n"); + } /* Fallbacks. */ if (!GLContext::shader_draw_parameters_support) { @@ -717,6 +866,14 @@ bool GLShader::finalize(const shader::ShaderCreateInfo *info) return false; } + if (info && do_geometry_shader_injection(info)) { + std::string source = workaround_geometry_shader_source_create(*info); + Vector<const char *> sources; + sources.append("version"); + sources.append(source.c_str()); + geometry_shader_from_glsl(sources); + } + glLinkProgram(shader_program_); GLint status; diff --git a/source/blender/gpu/opengl/gl_shader.hh b/source/blender/gpu/opengl/gl_shader.hh index a82ab026c16..cc1c93142f8 100644 --- a/source/blender/gpu/opengl/gl_shader.hh +++ b/source/blender/gpu/opengl/gl_shader.hh @@ -94,6 +94,14 @@ class GLShader : public Shader { /** Create, compile and attach the shader stage to the shader program. */ GLuint create_shader_stage(GLenum gl_stage, MutableSpan<const char *> sources); + /** + * \brief features available on newer implementation such as native barycentric coordinates + * and layered rendering, necessitate a geometry shader to work on older hardware. + */ + std::string workaround_geometry_shader_source_create(const shader::ShaderCreateInfo &info); + + bool do_geometry_shader_injection(const shader::ShaderCreateInfo *info); + MEM_CXX_CLASS_ALLOC_FUNCS("GLShader"); }; diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_diffuse.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_diffuse.glsl index 01a16e194ca..ab6024b073d 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_diffuse.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_diffuse.glsl @@ -18,7 +18,7 @@ void node_bsdf_diffuse(vec4 color, float roughness, vec3 N, out Closure result) result.radiance = out_Diffuse_0.radiance; - /* TODO(fclem) Try to not use this. */ + /* TODO(@fclem): Try to not use this. */ closure_load_ssr_data(vec3(0.0), 0.0, in_Diffuse_0.N, -1.0, result); } diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl index bba84c2be52..c97fc090fe2 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_principled.glsl @@ -166,7 +166,7 @@ void node_bsdf_principled(vec4 base_color, float btdf = (do_multiscatter != 0.0) ? 1.0 : btdf_lut(NV, in_Refraction_3.roughness, in_Refraction_3.ior).x; - /* TODO(fclem) This could be going to a transmission render pass instead. */ + /* TODO(@fclem): This could be going to a transmission render pass instead. */ out_Refraction_3.radiance *= btdf; out_Refraction_3.radiance = render_pass_glossy_mask(vec3(1), out_Refraction_3.radiance); out_Refraction_3.radiance *= base_color.rgb; diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_refraction.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_refraction.glsl index 7cbc7218f5c..8a42a131f43 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_refraction.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_refraction.glsl @@ -21,7 +21,7 @@ void node_bsdf_refraction(vec4 color, float roughness, float ior, vec3 N, out Cl result.radiance = out_Refraction_0.radiance; - /* TODO(fclem) Try to not use this. */ + /* TODO(@fclem): Try to not use this. */ result.ssr_normal = normal_encode(mat3(ViewMatrix) * in_Refraction_0.N, viewCameraVec(viewPosition)); } diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_subsurface_scattering.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_subsurface_scattering.glsl index d0c159cdf37..20b634aa801 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_subsurface_scattering.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_subsurface_scattering.glsl @@ -22,7 +22,7 @@ void node_subsurface_scattering(vec4 color, closure_load_sss_data(scale, out_Diffuse_0.radiance, color.rgb, int(sss_id), result); - /* TODO(fclem) Try to not use this. */ + /* TODO(@fclem): Try to not use this. */ closure_load_ssr_data(vec3(0.0), 0.0, in_Diffuse_0.N, -1.0, result); } diff --git a/source/blender/io/collada/CMakeLists.txt b/source/blender/io/collada/CMakeLists.txt index e1645083116..9ce3389257d 100644 --- a/source/blender/io/collada/CMakeLists.txt +++ b/source/blender/io/collada/CMakeLists.txt @@ -135,10 +135,6 @@ if(WITH_BUILDINFO) add_definitions(-DWITH_BUILDINFO) endif() -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() - if(CMAKE_COMPILER_IS_GNUCXX) # COLLADAFWArray.h gives error with gcc 4.5 string(APPEND CMAKE_CXX_FLAGS " -fpermissive") diff --git a/source/blender/io/usd/intern/usd_reader_camera.cc b/source/blender/io/usd/intern/usd_reader_camera.cc index 2732ed5770d..1d001e19140 100644 --- a/source/blender/io/usd/intern/usd_reader_camera.cc +++ b/source/blender/io/usd/intern/usd_reader_camera.cc @@ -72,7 +72,7 @@ void USDCameraReader::read_object_data(Main *bmain, const double motionSampleTim cam_prim.GetHorizontalApertureAttr().Get(&horAp, motionSampleTime); bcam->lens = val.Get<float>(); - /* TODO(makowalski) */ + /* TODO(@makowalski): support sensor size. */ #if 0 bcam->sensor_x = 0.0f; bcam->sensor_y = 0.0f; diff --git a/source/blender/io/wavefront_obj/CMakeLists.txt b/source/blender/io/wavefront_obj/CMakeLists.txt index 296dd70b5a2..0b1be7946cf 100644 --- a/source/blender/io/wavefront_obj/CMakeLists.txt +++ b/source/blender/io/wavefront_obj/CMakeLists.txt @@ -56,6 +56,12 @@ set(LIB bf_blenkernel ) +if(WITH_TBB) + add_definitions(-DWITH_TBB) + list(APPEND INC_SYS ${TBB_INCLUDE_DIRS}) + list(APPEND LIB ${TBB_LIBRARIES}) +endif() + blender_add_lib(bf_wavefront_obj "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") if(WITH_GTESTS) diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc index d31353c4a76..4f5321019d5 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc +++ b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.cc @@ -52,68 +52,75 @@ const char *DEFORM_GROUP_DISABLED = "off"; * So an empty material name is written. */ const char *MATERIAL_GROUP_DISABLED = ""; -void OBJWriter::write_vert_uv_normal_indices(Span<int> vert_indices, +void OBJWriter::write_vert_uv_normal_indices(FormatHandler<eFileType::OBJ> &fh, + const IndexOffsets &offsets, + Span<int> vert_indices, Span<int> uv_indices, Span<int> normal_indices) const { BLI_assert(vert_indices.size() == uv_indices.size() && vert_indices.size() == normal_indices.size()); - file_handler_->write<eOBJSyntaxElement::poly_element_begin>(); + fh.write<eOBJSyntaxElement::poly_element_begin>(); for (int j = 0; j < vert_indices.size(); j++) { - file_handler_->write<eOBJSyntaxElement::vertex_uv_normal_indices>( - vert_indices[j] + index_offsets_.vertex_offset + 1, - uv_indices[j] + index_offsets_.uv_vertex_offset + 1, - normal_indices[j] + index_offsets_.normal_offset + 1); + fh.write<eOBJSyntaxElement::vertex_uv_normal_indices>( + vert_indices[j] + offsets.vertex_offset + 1, + uv_indices[j] + offsets.uv_vertex_offset + 1, + normal_indices[j] + offsets.normal_offset + 1); } - file_handler_->write<eOBJSyntaxElement::poly_element_end>(); + fh.write<eOBJSyntaxElement::poly_element_end>(); } -void OBJWriter::write_vert_normal_indices(Span<int> vert_indices, +void OBJWriter::write_vert_normal_indices(FormatHandler<eFileType::OBJ> &fh, + const IndexOffsets &offsets, + Span<int> vert_indices, Span<int> /*uv_indices*/, Span<int> normal_indices) const { BLI_assert(vert_indices.size() == normal_indices.size()); - file_handler_->write<eOBJSyntaxElement::poly_element_begin>(); + fh.write<eOBJSyntaxElement::poly_element_begin>(); for (int j = 0; j < vert_indices.size(); j++) { - file_handler_->write<eOBJSyntaxElement::vertex_normal_indices>( - vert_indices[j] + index_offsets_.vertex_offset + 1, - normal_indices[j] + index_offsets_.normal_offset + 1); + fh.write<eOBJSyntaxElement::vertex_normal_indices>(vert_indices[j] + offsets.vertex_offset + 1, + normal_indices[j] + offsets.normal_offset + + 1); } - file_handler_->write<eOBJSyntaxElement::poly_element_end>(); + fh.write<eOBJSyntaxElement::poly_element_end>(); } -void OBJWriter::write_vert_uv_indices(Span<int> vert_indices, +void OBJWriter::write_vert_uv_indices(FormatHandler<eFileType::OBJ> &fh, + const IndexOffsets &offsets, + Span<int> vert_indices, Span<int> uv_indices, Span<int> /*normal_indices*/) const { BLI_assert(vert_indices.size() == uv_indices.size()); - file_handler_->write<eOBJSyntaxElement::poly_element_begin>(); + fh.write<eOBJSyntaxElement::poly_element_begin>(); for (int j = 0; j < vert_indices.size(); j++) { - file_handler_->write<eOBJSyntaxElement::vertex_uv_indices>( - vert_indices[j] + index_offsets_.vertex_offset + 1, - uv_indices[j] + index_offsets_.uv_vertex_offset + 1); + fh.write<eOBJSyntaxElement::vertex_uv_indices>(vert_indices[j] + offsets.vertex_offset + 1, + uv_indices[j] + offsets.uv_vertex_offset + 1); } - file_handler_->write<eOBJSyntaxElement::poly_element_end>(); + fh.write<eOBJSyntaxElement::poly_element_end>(); } -void OBJWriter::write_vert_indices(Span<int> vert_indices, +void OBJWriter::write_vert_indices(FormatHandler<eFileType::OBJ> &fh, + const IndexOffsets &offsets, + Span<int> vert_indices, Span<int> /*uv_indices*/, Span<int> /*normal_indices*/) const { - file_handler_->write<eOBJSyntaxElement::poly_element_begin>(); + fh.write<eOBJSyntaxElement::poly_element_begin>(); for (const int vert_index : vert_indices) { - file_handler_->write<eOBJSyntaxElement::vertex_indices>(vert_index + - index_offsets_.vertex_offset + 1); + fh.write<eOBJSyntaxElement::vertex_indices>(vert_index + offsets.vertex_offset + 1); } - file_handler_->write<eOBJSyntaxElement::poly_element_end>(); + fh.write<eOBJSyntaxElement::poly_element_end>(); } void OBJWriter::write_header() const { using namespace std::string_literals; - file_handler_->write<eOBJSyntaxElement::string>("# Blender "s + BKE_blender_version_string() + - "\n"); - file_handler_->write<eOBJSyntaxElement::string>("# www.blender.org\n"); + FormatHandler<eFileType::OBJ> fh; + fh.write<eOBJSyntaxElement::string>("# Blender "s + BKE_blender_version_string() + "\n"); + fh.write<eOBJSyntaxElement::string>("# www.blender.org\n"); + fh.write_to_file(outfile_); } void OBJWriter::write_mtllib_name(const StringRefNull mtl_filepath) const @@ -122,10 +129,13 @@ void OBJWriter::write_mtllib_name(const StringRefNull mtl_filepath) const char mtl_file_name[FILE_MAXFILE]; char mtl_dir_name[FILE_MAXDIR]; BLI_split_dirfile(mtl_filepath.data(), mtl_dir_name, mtl_file_name, FILE_MAXDIR, FILE_MAXFILE); - file_handler_->write<eOBJSyntaxElement::mtllib>(mtl_file_name); + FormatHandler<eFileType::OBJ> fh; + fh.write<eOBJSyntaxElement::mtllib>(mtl_file_name); + fh.write_to_file(outfile_); } -void OBJWriter::write_object_group(const OBJMesh &obj_mesh_data) const +void OBJWriter::write_object_group(FormatHandler<eFileType::OBJ> &fh, + const OBJMesh &obj_mesh_data) const { /* "o object_name" is not mandatory. A valid .OBJ file may contain neither * "o name" nor "g group_name". */ @@ -138,54 +148,52 @@ void OBJWriter::write_object_group(const OBJMesh &obj_mesh_data) const const char *object_material_name = obj_mesh_data.get_object_material_name(0); if (export_params_.export_materials && export_params_.export_material_groups && object_material_name) { - file_handler_->write<eOBJSyntaxElement::object_group>(object_name + "_" + object_mesh_name + - "_" + object_material_name); - return; + fh.write<eOBJSyntaxElement::object_group>(object_name + "_" + object_mesh_name + "_" + + object_material_name); + } + else { + fh.write<eOBJSyntaxElement::object_group>(object_name + "_" + object_mesh_name); } - file_handler_->write<eOBJSyntaxElement::object_group>(object_name + "_" + object_mesh_name); } -void OBJWriter::write_object_name(const OBJMesh &obj_mesh_data) const +void OBJWriter::write_object_name(FormatHandler<eFileType::OBJ> &fh, + const OBJMesh &obj_mesh_data) const { const char *object_name = obj_mesh_data.get_object_name(); if (export_params_.export_object_groups) { - write_object_group(obj_mesh_data); + write_object_group(fh, obj_mesh_data); return; } - file_handler_->write<eOBJSyntaxElement::object_name>(object_name); + fh.write<eOBJSyntaxElement::object_name>(object_name); } -void OBJWriter::write_vertex_coords(const OBJMesh &obj_mesh_data) const +void OBJWriter::write_vertex_coords(FormatHandler<eFileType::OBJ> &fh, + const OBJMesh &obj_mesh_data) const { const int tot_vertices = obj_mesh_data.tot_vertices(); for (int i = 0; i < tot_vertices; i++) { float3 vertex = obj_mesh_data.calc_vertex_coords(i, export_params_.scaling_factor); - file_handler_->write<eOBJSyntaxElement::vertex_coords>(vertex[0], vertex[1], vertex[2]); + fh.write<eOBJSyntaxElement::vertex_coords>(vertex[0], vertex[1], vertex[2]); } } -void OBJWriter::write_uv_coords(OBJMesh &r_obj_mesh_data) const +void OBJWriter::write_uv_coords(FormatHandler<eFileType::OBJ> &fh, OBJMesh &r_obj_mesh_data) const { - Vector<std::array<float, 2>> uv_coords; - /* UV indices are calculated and stored in an OBJMesh member here. */ - r_obj_mesh_data.store_uv_coords_and_indices(uv_coords); - - for (const std::array<float, 2> &uv_vertex : uv_coords) { - file_handler_->write<eOBJSyntaxElement::uv_vertex_coords>(uv_vertex[0], uv_vertex[1]); + for (const float2 &uv_vertex : r_obj_mesh_data.get_uv_coords()) { + fh.write<eOBJSyntaxElement::uv_vertex_coords>(uv_vertex[0], uv_vertex[1]); } } -void OBJWriter::write_poly_normals(OBJMesh &obj_mesh_data) +void OBJWriter::write_poly_normals(FormatHandler<eFileType::OBJ> &fh, OBJMesh &obj_mesh_data) { - obj_mesh_data.ensure_mesh_normals(); - Vector<float3> normals; - obj_mesh_data.store_normal_coords_and_indices(normals); - for (const float3 &normal : normals) { - file_handler_->write<eOBJSyntaxElement::normal>(normal[0], normal[1], normal[2]); + /* Poly normals should be calculated earlier via store_normal_coords_and_indices. */ + for (const float3 &normal : obj_mesh_data.get_normal_coords()) { + fh.write<eOBJSyntaxElement::normal>(normal[0], normal[1], normal[2]); } } -int OBJWriter::write_smooth_group(const OBJMesh &obj_mesh_data, +int OBJWriter::write_smooth_group(FormatHandler<eFileType::OBJ> &fh, + const OBJMesh &obj_mesh_data, const int poly_index, const int last_poly_smooth_group) const { @@ -203,11 +211,12 @@ int OBJWriter::write_smooth_group(const OBJMesh &obj_mesh_data, /* Group has already been written, even if it is "s 0". */ return current_group; } - file_handler_->write<eOBJSyntaxElement::smooth_group>(current_group); + fh.write<eOBJSyntaxElement::smooth_group>(current_group); return current_group; } -int16_t OBJWriter::write_poly_material(const OBJMesh &obj_mesh_data, +int16_t OBJWriter::write_poly_material(FormatHandler<eFileType::OBJ> &fh, + const OBJMesh &obj_mesh_data, const int poly_index, const int16_t last_poly_mat_nr, std::function<const char *(int)> matname_fn) const @@ -221,23 +230,25 @@ int16_t OBJWriter::write_poly_material(const OBJMesh &obj_mesh_data, if (last_poly_mat_nr == current_mat_nr) { return current_mat_nr; } + if (current_mat_nr == NOT_FOUND) { - file_handler_->write<eOBJSyntaxElement::poly_usemtl>(MATERIAL_GROUP_DISABLED); + fh.write<eOBJSyntaxElement::poly_usemtl>(MATERIAL_GROUP_DISABLED); return current_mat_nr; } if (export_params_.export_object_groups) { - write_object_group(obj_mesh_data); + write_object_group(fh, obj_mesh_data); } const char *mat_name = matname_fn(current_mat_nr); if (!mat_name) { mat_name = MATERIAL_GROUP_DISABLED; } - file_handler_->write<eOBJSyntaxElement::poly_usemtl>(mat_name); + fh.write<eOBJSyntaxElement::poly_usemtl>(mat_name); return current_mat_nr; } -int16_t OBJWriter::write_vertex_group(const OBJMesh &obj_mesh_data, +int16_t OBJWriter::write_vertex_group(FormatHandler<eFileType::OBJ> &fh, + const OBJMesh &obj_mesh_data, const int poly_index, const int16_t last_poly_vertex_group) const { @@ -251,11 +262,12 @@ int16_t OBJWriter::write_vertex_group(const OBJMesh &obj_mesh_data, return current_group; } if (current_group == NOT_FOUND) { - file_handler_->write<eOBJSyntaxElement::object_group>(DEFORM_GROUP_DISABLED); - return current_group; + fh.write<eOBJSyntaxElement::object_group>(DEFORM_GROUP_DISABLED); + } + else { + fh.write<eOBJSyntaxElement::object_group>( + obj_mesh_data.get_poly_deform_group_name(current_group)); } - file_handler_->write<eOBJSyntaxElement::object_group>( - obj_mesh_data.get_poly_deform_group_name(current_group)); return current_group; } @@ -278,7 +290,9 @@ OBJWriter::func_vert_uv_normal_indices OBJWriter::get_poly_element_writer( return &OBJWriter::write_vert_indices; } -void OBJWriter::write_poly_elements(const OBJMesh &obj_mesh_data, +void OBJWriter::write_poly_elements(FormatHandler<eFileType::OBJ> &fh, + const IndexOffsets &offsets, + const OBJMesh &obj_mesh_data, std::function<const char *(int)> matname_fn) { int last_poly_smooth_group = NEGATIVE_INIT; @@ -294,16 +308,19 @@ void OBJWriter::write_poly_elements(const OBJMesh &obj_mesh_data, Span<int> poly_uv_indices = obj_mesh_data.calc_poly_uv_indices(i); Vector<int> poly_normal_indices = obj_mesh_data.calc_poly_normal_indices(i); - last_poly_smooth_group = write_smooth_group(obj_mesh_data, i, last_poly_smooth_group); - last_poly_vertex_group = write_vertex_group(obj_mesh_data, i, last_poly_vertex_group); - last_poly_mat_nr = write_poly_material(obj_mesh_data, i, last_poly_mat_nr, matname_fn); - (this->*poly_element_writer)(poly_vertex_indices, poly_uv_indices, poly_normal_indices); + last_poly_smooth_group = write_smooth_group(fh, obj_mesh_data, i, last_poly_smooth_group); + last_poly_vertex_group = write_vertex_group(fh, obj_mesh_data, i, last_poly_vertex_group); + last_poly_mat_nr = write_poly_material(fh, obj_mesh_data, i, last_poly_mat_nr, matname_fn); + (this->*poly_element_writer)( + fh, offsets, poly_vertex_indices, poly_uv_indices, poly_normal_indices); } } -void OBJWriter::write_edges_indices(const OBJMesh &obj_mesh_data) const +void OBJWriter::write_edges_indices(FormatHandler<eFileType::OBJ> &fh, + const IndexOffsets &offsets, + const OBJMesh &obj_mesh_data) const { - obj_mesh_data.ensure_mesh_edges(); + /* Note: ensure_mesh_edges should be called before. */ const int tot_edges = obj_mesh_data.tot_edges(); for (int edge_index = 0; edge_index < tot_edges; edge_index++) { const std::optional<std::array<int, 2>> vertex_indices = @@ -311,13 +328,13 @@ void OBJWriter::write_edges_indices(const OBJMesh &obj_mesh_data) const if (!vertex_indices) { continue; } - file_handler_->write<eOBJSyntaxElement::edge>( - (*vertex_indices)[0] + index_offsets_.vertex_offset + 1, - (*vertex_indices)[1] + index_offsets_.vertex_offset + 1); + fh.write<eOBJSyntaxElement::edge>((*vertex_indices)[0] + offsets.vertex_offset + 1, + (*vertex_indices)[1] + offsets.vertex_offset + 1); } } -void OBJWriter::write_nurbs_curve(const OBJCurve &obj_nurbs_data) const +void OBJWriter::write_nurbs_curve(FormatHandler<eFileType::OBJ> &fh, + const OBJCurve &obj_nurbs_data) const { const int total_splines = obj_nurbs_data.total_splines(); for (int spline_idx = 0; spline_idx < total_splines; spline_idx++) { @@ -325,15 +342,15 @@ void OBJWriter::write_nurbs_curve(const OBJCurve &obj_nurbs_data) const for (int vertex_idx = 0; vertex_idx < total_vertices; vertex_idx++) { const float3 vertex_coords = obj_nurbs_data.vertex_coordinates( spline_idx, vertex_idx, export_params_.scaling_factor); - file_handler_->write<eOBJSyntaxElement::vertex_coords>( + fh.write<eOBJSyntaxElement::vertex_coords>( vertex_coords[0], vertex_coords[1], vertex_coords[2]); } const char *nurbs_name = obj_nurbs_data.get_curve_name(); const int nurbs_degree = obj_nurbs_data.get_nurbs_degree(spline_idx); - file_handler_->write<eOBJSyntaxElement::object_group>(nurbs_name); - file_handler_->write<eOBJSyntaxElement::cstype>(); - file_handler_->write<eOBJSyntaxElement::nurbs_degree>(nurbs_degree); + fh.write<eOBJSyntaxElement::object_group>(nurbs_name); + fh.write<eOBJSyntaxElement::cstype>(); + fh.write<eOBJSyntaxElement::nurbs_degree>(nurbs_degree); /** * The numbers written here are indices into the vertex coordinates written * earlier, relative to the line that is going to be written. @@ -342,36 +359,28 @@ void OBJWriter::write_nurbs_curve(const OBJCurve &obj_nurbs_data) const * 0.0 1.0 -1 -2 -3 -4 -1 -2 -3 for a cyclic curve with 4 vertices. */ const int total_control_points = obj_nurbs_data.total_spline_control_points(spline_idx); - file_handler_->write<eOBJSyntaxElement::curve_element_begin>(); + fh.write<eOBJSyntaxElement::curve_element_begin>(); for (int i = 0; i < total_control_points; i++) { /* "+1" to keep indices one-based, even if they're negative: i.e., -1 refers to the * last vertex coordinate, -2 second last. */ - file_handler_->write<eOBJSyntaxElement::vertex_indices>(-((i % total_vertices) + 1)); + fh.write<eOBJSyntaxElement::vertex_indices>(-((i % total_vertices) + 1)); } - file_handler_->write<eOBJSyntaxElement::curve_element_end>(); + fh.write<eOBJSyntaxElement::curve_element_end>(); /** * In `parm u 0 0.1 ..` line:, (total control points + 2) equidistant numbers in the * parameter range are inserted. */ - file_handler_->write<eOBJSyntaxElement::nurbs_parameter_begin>(); + fh.write<eOBJSyntaxElement::nurbs_parameter_begin>(); for (int i = 1; i <= total_control_points + 2; i++) { - file_handler_->write<eOBJSyntaxElement::nurbs_parameters>(1.0f * i / - (total_control_points + 2 + 1)); + fh.write<eOBJSyntaxElement::nurbs_parameters>(1.0f * i / (total_control_points + 2 + 1)); } - file_handler_->write<eOBJSyntaxElement::nurbs_parameter_end>(); + fh.write<eOBJSyntaxElement::nurbs_parameter_end>(); - file_handler_->write<eOBJSyntaxElement::nurbs_group_end>(); + fh.write<eOBJSyntaxElement::nurbs_group_end>(); } } -void OBJWriter::update_index_offsets(const OBJMesh &obj_mesh_data) -{ - index_offsets_.vertex_offset += obj_mesh_data.tot_vertices(); - index_offsets_.uv_vertex_offset += obj_mesh_data.tot_uv_vertices(); - index_offsets_.normal_offset += obj_mesh_data.tot_normal_indices(); -} - /* -------------------------------------------------------------------- */ /** \name .MTL writers. * \{ */ @@ -394,18 +403,31 @@ MTLWriter::MTLWriter(const char *obj_filepath) noexcept(false) if (!ok) { throw std::system_error(ENAMETOOLONG, std::system_category(), ""); } - file_handler_ = std::make_unique<FormattedFileHandler<eFileType::MTL>>(mtl_filepath_); + outfile_ = BLI_fopen(mtl_filepath_.c_str(), "wb"); + if (!outfile_) { + throw std::system_error(errno, std::system_category(), "Cannot open file " + mtl_filepath_); + } +} +MTLWriter::~MTLWriter() +{ + if (outfile_) { + fmt_handler_.write_to_file(outfile_); + if (std::fclose(outfile_)) { + std::cerr << "Error: could not close the file '" << mtl_filepath_ + << "' properly, it may be corrupted." << std::endl; + } + } } -void MTLWriter::write_header(const char *blen_filepath) const +void MTLWriter::write_header(const char *blen_filepath) { using namespace std::string_literals; const char *blen_basename = (blen_filepath && blen_filepath[0] != '\0') ? BLI_path_basename(blen_filepath) : "None"; - file_handler_->write<eMTLSyntaxElement::string>("# Blender "s + BKE_blender_version_string() + - " MTL File: '" + blen_basename + "'\n"); - file_handler_->write<eMTLSyntaxElement::string>("# www.blender.org\n"); + fmt_handler_.write<eMTLSyntaxElement::string>("# Blender "s + BKE_blender_version_string() + + " MTL File: '" + blen_basename + "'\n"); + fmt_handler_.write<eMTLSyntaxElement::string>("# www.blender.org\n"); } StringRefNull MTLWriter::mtl_file_path() const @@ -415,18 +437,18 @@ StringRefNull MTLWriter::mtl_file_path() const void MTLWriter::write_bsdf_properties(const MTLMaterial &mtl_material) { - file_handler_->write<eMTLSyntaxElement::Ns>(mtl_material.Ns); - file_handler_->write<eMTLSyntaxElement::Ka>( + fmt_handler_.write<eMTLSyntaxElement::Ns>(mtl_material.Ns); + fmt_handler_.write<eMTLSyntaxElement::Ka>( mtl_material.Ka.x, mtl_material.Ka.y, mtl_material.Ka.z); - file_handler_->write<eMTLSyntaxElement::Kd>( + fmt_handler_.write<eMTLSyntaxElement::Kd>( mtl_material.Kd.x, mtl_material.Kd.y, mtl_material.Kd.z); - file_handler_->write<eMTLSyntaxElement::Ks>( + fmt_handler_.write<eMTLSyntaxElement::Ks>( mtl_material.Ks.x, mtl_material.Ks.y, mtl_material.Ks.z); - file_handler_->write<eMTLSyntaxElement::Ke>( + fmt_handler_.write<eMTLSyntaxElement::Ke>( mtl_material.Ke.x, mtl_material.Ke.y, mtl_material.Ke.z); - file_handler_->write<eMTLSyntaxElement::Ni>(mtl_material.Ni); - file_handler_->write<eMTLSyntaxElement::d>(mtl_material.d); - file_handler_->write<eMTLSyntaxElement::illum>(mtl_material.illum); + fmt_handler_.write<eMTLSyntaxElement::Ni>(mtl_material.Ni); + fmt_handler_.write<eMTLSyntaxElement::d>(mtl_material.d); + fmt_handler_.write<eMTLSyntaxElement::illum>(mtl_material.illum); } void MTLWriter::write_texture_map( @@ -449,8 +471,8 @@ void MTLWriter::write_texture_map( #define SYNTAX_DISPATCH(eMTLSyntaxElement) \ if (texture_map.key == eMTLSyntaxElement) { \ - file_handler_->write<eMTLSyntaxElement>(translation + scale + map_bump_strength, \ - texture_map.value.image_path); \ + fmt_handler_.write<eMTLSyntaxElement>(translation + scale + map_bump_strength, \ + texture_map.value.image_path); \ return; \ } @@ -474,8 +496,8 @@ void MTLWriter::write_materials() mtlmaterials_.end(), [](const MTLMaterial &a, const MTLMaterial &b) { return a.name < b.name; }); for (const MTLMaterial &mtlmat : mtlmaterials_) { - file_handler_->write<eMTLSyntaxElement::string>("\n"); - file_handler_->write<eMTLSyntaxElement::newmtl>(mtlmat.name); + fmt_handler_.write<eMTLSyntaxElement::string>("\n"); + fmt_handler_.write<eMTLSyntaxElement::newmtl>(mtlmat.name); write_bsdf_properties(mtlmat); for (const Map<const eMTLSyntaxElement, tex_map_XX>::Item &texture_map : mtlmat.texture_maps.items()) { diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.hh b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.hh index 7385d9fabe2..2620d65f28c 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.hh +++ b/source/blender/io/wavefront_obj/exporter/obj_export_file_writer.hh @@ -49,14 +49,29 @@ struct IndexOffsets { class OBJWriter : NonMovable, NonCopyable { private: const OBJExportParams &export_params_; - std::unique_ptr<FormattedFileHandler<eFileType::OBJ>> file_handler_ = nullptr; - IndexOffsets index_offsets_{0, 0, 0}; + std::string outfile_path_; + FILE *outfile_; public: OBJWriter(const char *filepath, const OBJExportParams &export_params) noexcept(false) - : export_params_(export_params) + : export_params_(export_params), outfile_path_(filepath), outfile_(nullptr) { - file_handler_ = std::make_unique<FormattedFileHandler<eFileType::OBJ>>(filepath); + outfile_ = BLI_fopen(filepath, "wb"); + if (!outfile_) { + throw std::system_error(errno, std::system_category(), "Cannot open file " + outfile_path_); + } + } + ~OBJWriter() + { + if (outfile_ && std::fclose(outfile_)) { + std::cerr << "Error: could not close the file '" << outfile_path_ + << "' properly, it may be corrupted." << std::endl; + } + } + + FILE *get_outfile() const + { + return outfile_; } void write_header() const; @@ -64,11 +79,11 @@ class OBJWriter : NonMovable, NonCopyable { /** * Write object's name or group. */ - void write_object_name(const OBJMesh &obj_mesh_data) const; + void write_object_name(FormatHandler<eFileType::OBJ> &fh, const OBJMesh &obj_mesh_data) const; /** * Write an object's group with mesh and/or material name appended conditionally. */ - void write_object_group(const OBJMesh &obj_mesh_data) const; + void write_object_group(FormatHandler<eFileType::OBJ> &fh, const OBJMesh &obj_mesh_data) const; /** * Write file name of Material Library in .OBJ file. */ @@ -76,21 +91,22 @@ class OBJWriter : NonMovable, NonCopyable { /** * Write vertex coordinates for all vertices as "v x y z". */ - void write_vertex_coords(const OBJMesh &obj_mesh_data) const; + void write_vertex_coords(FormatHandler<eFileType::OBJ> &fh, const OBJMesh &obj_mesh_data) const; /** * Write UV vertex coordinates for all vertices as `vt u v`. * \note UV indices are stored here, but written with polygons later. */ - void write_uv_coords(OBJMesh &obj_mesh_data) const; + void write_uv_coords(FormatHandler<eFileType::OBJ> &fh, OBJMesh &obj_mesh_data) const; /** * Write loop normals for smooth-shaded polygons, and polygon normals otherwise, as "vn x y z". * \note Normal indices ares stored here, but written with polygons later. */ - void write_poly_normals(OBJMesh &obj_mesh_data); + void write_poly_normals(FormatHandler<eFileType::OBJ> &fh, OBJMesh &obj_mesh_data); /** * Write smooth group if polygon at the given index is shaded smooth else "s 0" */ - int write_smooth_group(const OBJMesh &obj_mesh_data, + int write_smooth_group(FormatHandler<eFileType::OBJ> &fh, + const OBJMesh &obj_mesh_data, int poly_index, int last_poly_smooth_group) const; /** @@ -98,14 +114,16 @@ class OBJWriter : NonMovable, NonCopyable { * \return #mat_nr of the polygon at the given index. * \note It doesn't write to the material library. */ - int16_t write_poly_material(const OBJMesh &obj_mesh_data, + int16_t write_poly_material(FormatHandler<eFileType::OBJ> &fh, + const OBJMesh &obj_mesh_data, int poly_index, int16_t last_poly_mat_nr, std::function<const char *(int)> matname_fn) const; /** * Write the name of the deform group of a polygon. */ - int16_t write_vertex_group(const OBJMesh &obj_mesh_data, + int16_t write_vertex_group(FormatHandler<eFileType::OBJ> &fh, + const OBJMesh &obj_mesh_data, int poly_index, int16_t last_poly_vertex_group) const; /** @@ -115,25 +133,25 @@ class OBJWriter : NonMovable, NonCopyable { * name used in the .obj file. * \note UV indices were stored while writing UV vertices. */ - void write_poly_elements(const OBJMesh &obj_mesh_data, + void write_poly_elements(FormatHandler<eFileType::OBJ> &fh, + const IndexOffsets &offsets, + const OBJMesh &obj_mesh_data, std::function<const char *(int)> matname_fn); /** * Write loose edges of a mesh as "l v1 v2". */ - void write_edges_indices(const OBJMesh &obj_mesh_data) const; + void write_edges_indices(FormatHandler<eFileType::OBJ> &fh, + const IndexOffsets &offsets, + const OBJMesh &obj_mesh_data) const; /** * Write a NURBS curve to the .OBJ file in parameter form. */ - void write_nurbs_curve(const OBJCurve &obj_nurbs_data) const; - - /** - * When there are multiple objects in a frame, the indices of previous objects' coordinates or - * normals add up. - */ - void update_index_offsets(const OBJMesh &obj_mesh_data); + void write_nurbs_curve(FormatHandler<eFileType::OBJ> &fh, const OBJCurve &obj_nurbs_data) const; private: - using func_vert_uv_normal_indices = void (OBJWriter::*)(Span<int> vert_indices, + using func_vert_uv_normal_indices = void (OBJWriter::*)(FormatHandler<eFileType::OBJ> &fh, + const IndexOffsets &offsets, + Span<int> vert_indices, Span<int> uv_indices, Span<int> normal_indices) const; /** @@ -144,25 +162,33 @@ class OBJWriter : NonMovable, NonCopyable { /** * Write one line of polygon indices as "f v1/vt1/vn1 v2/vt2/vn2 ...". */ - void write_vert_uv_normal_indices(Span<int> vert_indices, + void write_vert_uv_normal_indices(FormatHandler<eFileType::OBJ> &fh, + const IndexOffsets &offsets, + Span<int> vert_indices, Span<int> uv_indices, Span<int> normal_indices) const; /** * Write one line of polygon indices as "f v1//vn1 v2//vn2 ...". */ - void write_vert_normal_indices(Span<int> vert_indices, + void write_vert_normal_indices(FormatHandler<eFileType::OBJ> &fh, + const IndexOffsets &offsets, + Span<int> vert_indices, Span<int> /*uv_indices*/, Span<int> normal_indices) const; /** * Write one line of polygon indices as "f v1/vt1 v2/vt2 ...". */ - void write_vert_uv_indices(Span<int> vert_indices, + void write_vert_uv_indices(FormatHandler<eFileType::OBJ> &fh, + const IndexOffsets &offsets, + Span<int> vert_indices, Span<int> uv_indices, Span<int> /*normal_indices*/) const; /** * Write one line of polygon indices as "f v1 v2 ...". */ - void write_vert_indices(Span<int> vert_indices, + void write_vert_indices(FormatHandler<eFileType::OBJ> &fh, + const IndexOffsets &offsets, + Span<int> vert_indices, Span<int> /*uv_indices*/, Span<int> /*normal_indices*/) const; }; @@ -172,7 +198,8 @@ class OBJWriter : NonMovable, NonCopyable { */ class MTLWriter : NonMovable, NonCopyable { private: - std::unique_ptr<FormattedFileHandler<eFileType::MTL>> file_handler_ = nullptr; + FormatHandler<eFileType::MTL> fmt_handler_; + FILE *outfile_; std::string mtl_filepath_; Vector<MTLMaterial> mtlmaterials_; /* Map from a Material* to an index into mtlmaterials_. */ @@ -183,8 +210,9 @@ class MTLWriter : NonMovable, NonCopyable { * Create the .MTL file. */ MTLWriter(const char *obj_filepath) noexcept(false); + ~MTLWriter(); - void write_header(const char *blen_filepath) const; + void write_header(const char *blen_filepath); /** * Write all of the material specifications to the MTL file. * For consistency of output from run to run (useful for testing), diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_io.hh b/source/blender/io/wavefront_obj/exporter/obj_export_io.hh index 1bbefaee75f..692eb7f5db5 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_io.hh +++ b/source/blender/io/wavefront_obj/exporter/obj_export_io.hh @@ -24,6 +24,7 @@ #include <string> #include <system_error> #include <type_traits> +#include <vector> #include "BLI_compiler_attrs.h" #include "BLI_fileops.h" @@ -124,6 +125,14 @@ constexpr bool is_type_integral = (... && std::is_integral_v<std::decay_t<T>>); template<typename... T> constexpr bool is_type_string_related = (... && std::is_constructible_v<std::string, T>); +/* GCC (at least 9.3) while compiling the obj_exporter_tests.cc with optimizations on, + * results in "obj_export_io.hh:205:18: warning: ‘%s’ directive output truncated writing 34 bytes + * into a region of size 6" and similar warnings. Yes the output is truncated, and that is covered + * as an edge case by tests on purpose. */ +#if defined __GNUC__ +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Wformat-truncation" +#endif template<typename... T> constexpr FormattingSyntax syntax_elem_to_formatting(const eOBJSyntaxElement key) { @@ -264,31 +273,44 @@ constexpr FormattingSyntax syntax_elem_to_formatting(const eMTLSyntaxElement key } } } +#if defined __GNUC__ +# pragma GCC diagnostic pop +#endif /** - * File format and syntax agnostic file writer. + * File format and syntax agnostic file buffer writer. + * All writes are done into an internal chunked memory buffer + * (list of default 64 kilobyte blocks). + * Call write_fo_file once in a while to write the memory buffer(s) + * into the given file. */ -template<eFileType filetype> class FormattedFileHandler : NonCopyable, NonMovable { +template<eFileType filetype, + size_t buffer_chunk_size = 64 * 1024, + size_t write_local_buffer_size = 1024> +class FormatHandler : NonCopyable, NonMovable { private: - std::FILE *outfile_ = nullptr; - std::string outfile_path_; + typedef std::vector<char> VectorChar; + std::vector<VectorChar> blocks_; public: - FormattedFileHandler(std::string outfile_path) noexcept(false) - : outfile_path_(std::move(outfile_path)) + /* Write contents to the buffer(s) into a file, and clear the buffers. */ + void write_to_file(FILE *f) { - outfile_ = BLI_fopen(outfile_path_.c_str(), "w"); - if (!outfile_) { - throw std::system_error(errno, std::system_category(), "Cannot open file " + outfile_path_); - } + for (const auto &b : blocks_) + fwrite(b.data(), 1, b.size(), f); + blocks_.clear(); } - ~FormattedFileHandler() + std::string get_as_string() const { - if (outfile_ && std::fclose(outfile_)) { - std::cerr << "Error: could not close the file '" << outfile_path_ - << "' properly, it may be corrupted." << std::endl; - } + std::string s; + for (const auto &b : blocks_) + s.append(b.data(), b.size()); + return s; + } + size_t get_block_count() const + { + return blocks_.size(); } /** @@ -298,7 +320,7 @@ template<eFileType filetype> class FormattedFileHandler : NonCopyable, NonMovabl * `eFileType::MTL`. */ template<typename FileTypeTraits<filetype>::SyntaxType key, typename... T> - constexpr void write(T &&...args) const + constexpr void write(T &&...args) { /* Get format syntax, number of arguments expected and whether types of given arguments are * valid. @@ -339,13 +361,47 @@ template<eFileType filetype> class FormattedFileHandler : NonCopyable, NonMovabl } } - template<typename... T> constexpr void write_impl(const char *fmt, T &&...args) const + /* Ensure the last block contains at least this amount of free space. + * If not, add a new block with max of block size & the amount of space needed. */ + void ensure_space(size_t at_least) + { + if (blocks_.empty() || (blocks_.back().capacity() - blocks_.back().size() < at_least)) { + VectorChar &b = blocks_.emplace_back(VectorChar()); + b.reserve(std::max(at_least, buffer_chunk_size)); + } + } + + template<typename... T> constexpr void write_impl(const char *fmt, T &&...args) { if constexpr (sizeof...(T) == 0) { - std::fputs(fmt, outfile_); + /* No arguments: just emit the format string. */ + size_t len = strlen(fmt); + ensure_space(len); + VectorChar &bb = blocks_.back(); + bb.insert(bb.end(), fmt, fmt + len); } else { - std::fprintf(outfile_, fmt, convert_to_primitive(std::forward<T>(args))...); + /* Format into a local buffer. */ + char buf[write_local_buffer_size]; + int needed = std::snprintf( + buf, write_local_buffer_size, fmt, convert_to_primitive(std::forward<T>(args))...); + if (needed < 0) + throw std::system_error( + errno, std::system_category(), "Failed to format obj export string into a buffer"); + ensure_space(needed + 1); /* Ensure space for zero terminator. */ + VectorChar &bb = blocks_.back(); + if (needed < write_local_buffer_size) { + /* String formatted successfully into the local buffer, copy it. */ + bb.insert(bb.end(), buf, buf + needed); + } + else { + /* Would need more space than the local buffer: insert said space and format again into + * that. */ + size_t bbEnd = bb.size(); + bb.insert(bb.end(), needed, ' '); + std::snprintf( + bb.data() + bbEnd, needed + 1, fmt, convert_to_primitive(std::forward<T>(args))...); + } } } }; diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc index 14e50d726c0..468631cdd82 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc +++ b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.cc @@ -69,16 +69,28 @@ OBJMesh::OBJMesh(Depsgraph *depsgraph, const OBJExportParams &export_params, Obj */ OBJMesh::~OBJMesh() { - free_mesh_if_needed(); - if (poly_smooth_groups_) { - MEM_freeN(poly_smooth_groups_); - } + clear(); } void OBJMesh::free_mesh_if_needed() { if (mesh_eval_needs_free_ && export_mesh_eval_) { BKE_id_free(nullptr, export_mesh_eval_); + export_mesh_eval_ = nullptr; + mesh_eval_needs_free_ = false; + } +} + +void OBJMesh::clear() +{ + free_mesh_if_needed(); + uv_indices_.clear_and_make_inline(); + uv_coords_.clear_and_make_inline(); + loop_to_normal_index_.clear_and_make_inline(); + normal_coords_.clear_and_make_inline(); + if (poly_smooth_groups_) { + MEM_freeN(poly_smooth_groups_); + poly_smooth_groups_ = nullptr; } } @@ -256,7 +268,7 @@ Vector<int> OBJMesh::calc_poly_vertex_indices(const int poly_index) const return r_poly_vertex_indices; } -void OBJMesh::store_uv_coords_and_indices(Vector<std::array<float, 2>> &r_uv_coords) +void OBJMesh::store_uv_coords_and_indices() { const MPoly *mpoly = export_mesh_eval_->mpoly; const MLoop *mloop = export_mesh_eval_->mloop; @@ -276,7 +288,7 @@ void OBJMesh::store_uv_coords_and_indices(Vector<std::array<float, 2>> &r_uv_coo uv_indices_.resize(totpoly); /* At least total vertices of a mesh will be present in its texture map. So * reserve minimum space early. */ - r_uv_coords.reserve(totvert); + uv_coords_.reserve(totvert); tot_uv_vertices_ = 0; for (int vertex_index = 0; vertex_index < totvert; vertex_index++) { @@ -288,11 +300,10 @@ void OBJMesh::store_uv_coords_and_indices(Vector<std::array<float, 2>> &r_uv_coo const int vertices_in_poly = mpoly[uv_vert->poly_index].totloop; /* Store UV vertex coordinates. */ - r_uv_coords.resize(tot_uv_vertices_); + uv_coords_.resize(tot_uv_vertices_); const int loopstart = mpoly[uv_vert->poly_index].loopstart; Span<float> vert_uv_coords(mloopuv[loopstart + uv_vert->loop_of_poly_index].uv, 2); - r_uv_coords[tot_uv_vertices_ - 1][0] = vert_uv_coords[0]; - r_uv_coords[tot_uv_vertices_ - 1][1] = vert_uv_coords[1]; + uv_coords_[tot_uv_vertices_ - 1] = float2(vert_uv_coords[0], vert_uv_coords[1]); /* Store UV vertex indices. */ uv_indices_[uv_vert->poly_index].resize(vertices_in_poly); @@ -340,7 +351,7 @@ static float3 round_float3_to_n_digits(const float3 &v, int round_digits) return ans; } -void OBJMesh::store_normal_coords_and_indices(Vector<float3> &r_normal_coords) +void OBJMesh::store_normal_coords_and_indices() { /* We'll round normal components to 4 digits. * This will cover up some minor differences @@ -371,7 +382,7 @@ void OBJMesh::store_normal_coords_and_indices(Vector<float3> &r_normal_coords) if (loop_norm_index == -1) { loop_norm_index = cur_normal_index++; normal_to_index.add(rounded_loop_normal, loop_norm_index); - r_normal_coords.append(rounded_loop_normal); + normal_coords_.append(rounded_loop_normal); } loop_to_normal_index_[loop_index] = loop_norm_index; } @@ -383,7 +394,7 @@ void OBJMesh::store_normal_coords_and_indices(Vector<float3> &r_normal_coords) if (poly_norm_index == -1) { poly_norm_index = cur_normal_index++; normal_to_index.add(rounded_poly_normal, poly_norm_index); - r_normal_coords.append(rounded_poly_normal); + normal_coords_.append(rounded_poly_normal); } for (int i = 0; i < mpoly.totloop; ++i) { int loop_index = mpoly.loopstart + i; diff --git a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.hh b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.hh index f3ace140006..4cfbffdcebc 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_export_mesh.hh +++ b/source/blender/io/wavefront_obj/exporter/obj_export_mesh.hh @@ -82,11 +82,19 @@ class OBJMesh : NonCopyable { * Per-polygon-per-vertex UV vertex indices. */ Vector<Vector<int>> uv_indices_; + /* + * UV vertices. + */ + Vector<float2> uv_coords_; /** * Per-loop normal index. */ Vector<int> loop_to_normal_index_; /* + * Normal coords. + */ + Vector<float3> normal_coords_; + /* * Total number of normal indices (maximum entry, plus 1, in * the loop_to_norm_index_ vector). */ @@ -108,6 +116,9 @@ class OBJMesh : NonCopyable { OBJMesh(Depsgraph *depsgraph, const OBJExportParams &export_params, Object *mesh_object); ~OBJMesh(); + /* Clear various arrays to release potentially large memory allocations. */ + void clear(); + int tot_vertices() const; int tot_polygons() const; int tot_uv_vertices() const; @@ -165,10 +176,14 @@ class OBJMesh : NonCopyable { Vector<int> calc_poly_vertex_indices(int poly_index) const; /** * Calculate UV vertex coordinates of an Object. - * - * \note Also store the UV vertex indices in the member variable. + * Stores the coordinates and UV vertex indices in the member variables. */ - void store_uv_coords_and_indices(Vector<std::array<float, 2>> &r_uv_coords); + void store_uv_coords_and_indices(); + /* Get UV coordinates computed by store_uv_coords_and_indices. */ + const Vector<float2> &get_uv_coords() const + { + return uv_coords_; + } Span<int> calc_poly_uv_indices(int poly_index) const; /** * Calculate polygon normal of a polygon at given index. @@ -177,10 +192,15 @@ class OBJMesh : NonCopyable { */ float3 calc_poly_normal(int poly_index) const; /** - * Find the unique normals of the mesh and return them in \a r_normal_coords. - * Store the indices into that vector with for each loop in this #OBJMesh. + * Find the unique normals of the mesh and stores them in a member variable. + * Also stores the indices into that vector with for each loop. */ - void store_normal_coords_and_indices(Vector<float3> &r_normal_coords); + void store_normal_coords_and_indices(); + /* Get normals calculate by store_normal_coords_and_indices. */ + const Vector<float3> &get_normal_coords() const + { + return normal_coords_; + } /** * Calculate a polygon's polygon/loop normal indices. * \param poly_index Index of the polygon to calculate indices for. diff --git a/source/blender/io/wavefront_obj/exporter/obj_exporter.cc b/source/blender/io/wavefront_obj/exporter/obj_exporter.cc index 0c753ccdcac..187f50277f1 100644 --- a/source/blender/io/wavefront_obj/exporter/obj_exporter.cc +++ b/source/blender/io/wavefront_obj/exporter/obj_exporter.cc @@ -25,6 +25,7 @@ #include "BKE_scene.h" #include "BLI_path_util.h" +#include "BLI_task.hh" #include "BLI_vector.hh" #include "DEG_depsgraph_query.h" @@ -155,44 +156,97 @@ static void write_mesh_objects(Vector<std::unique_ptr<OBJMesh>> exportable_as_me MTLWriter *mtl_writer, const OBJExportParams &export_params) { + /* Parallelization is over meshes/objects, which means + * we have to have the output text buffer for each object, + * and write them all into the file at the end. */ + size_t count = exportable_as_mesh.size(); + std::vector<FormatHandler<eFileType::OBJ>> buffers(count); + + /* Serial: gather material indices, ensure normals & edges. */ + Vector<Vector<int>> mtlindices; if (mtl_writer) { obj_writer.write_mtllib_name(mtl_writer->mtl_file_path()); + mtlindices.reserve(count); } - - /* Smooth groups and UV vertex indices may make huge memory allocations, so they should be freed - * right after they're written, instead of waiting for #blender::Vector to clean them up after - * all the objects are exported. */ for (auto &obj_mesh : exportable_as_mesh) { - obj_writer.write_object_name(*obj_mesh); - obj_writer.write_vertex_coords(*obj_mesh); - Vector<int> obj_mtlindices; + OBJMesh &obj = *obj_mesh; + if (mtl_writer) { + mtlindices.append(mtl_writer->add_materials(obj)); + } + if (export_params.export_normals) { + obj.ensure_mesh_normals(); + } + obj.ensure_mesh_edges(); + } - if (obj_mesh->tot_polygons() > 0) { - if (export_params.export_smooth_groups) { - obj_mesh->calc_smooth_groups(export_params.smooth_groups_bitflags); - } + /* Parallel over meshes: store normal coords & indices, uv coords and indices. */ + blender::threading::parallel_for(IndexRange(count), 1, [&](IndexRange range) { + for (const int i : range) { + OBJMesh &obj = *exportable_as_mesh[i]; if (export_params.export_normals) { - obj_writer.write_poly_normals(*obj_mesh); + obj.store_normal_coords_and_indices(); } if (export_params.export_uv) { - obj_writer.write_uv_coords(*obj_mesh); - } - if (mtl_writer) { - obj_mtlindices = mtl_writer->add_materials(*obj_mesh); + obj.store_uv_coords_and_indices(); } - /* This function takes a 0-indexed slot index for the obj_mesh object and - * returns the material name that we are using in the .obj file for it. */ - std::function<const char *(int)> matname_fn = [&](int s) -> const char * { - if (!mtl_writer || s < 0 || s >= obj_mtlindices.size()) { - return nullptr; + } + }); + + /* Serial: calculate index offsets; these are sequentially added + * over all meshes, and requite normal/uv indices to be calculated. */ + Vector<IndexOffsets> index_offsets; + index_offsets.reserve(count); + IndexOffsets offsets{0, 0, 0}; + for (auto &obj_mesh : exportable_as_mesh) { + OBJMesh &obj = *obj_mesh; + index_offsets.append(offsets); + offsets.vertex_offset += obj.tot_vertices(); + offsets.uv_vertex_offset += obj.tot_uv_vertices(); + offsets.normal_offset += obj.tot_normal_indices(); + } + + /* Parallel over meshes: main result writing. */ + blender::threading::parallel_for(IndexRange(count), 1, [&](IndexRange range) { + for (const int i : range) { + OBJMesh &obj = *exportable_as_mesh[i]; + auto &fh = buffers[i]; + + obj_writer.write_object_name(fh, obj); + obj_writer.write_vertex_coords(fh, obj); + + if (obj.tot_polygons() > 0) { + if (export_params.export_smooth_groups) { + obj.calc_smooth_groups(export_params.smooth_groups_bitflags); + } + if (export_params.export_normals) { + obj_writer.write_poly_normals(fh, obj); } - return mtl_writer->mtlmaterial_name(obj_mtlindices[s]); - }; - obj_writer.write_poly_elements(*obj_mesh, matname_fn); + if (export_params.export_uv) { + obj_writer.write_uv_coords(fh, obj); + } + /* This function takes a 0-indexed slot index for the obj_mesh object and + * returns the material name that we are using in the .obj file for it. */ + const auto *obj_mtlindices = mtlindices.is_empty() ? nullptr : &mtlindices[i]; + std::function<const char *(int)> matname_fn = [&](int s) -> const char * { + if (!obj_mtlindices || s < 0 || s >= obj_mtlindices->size()) { + return nullptr; + } + return mtl_writer->mtlmaterial_name((*obj_mtlindices)[s]); + }; + obj_writer.write_poly_elements(fh, index_offsets[i], obj, matname_fn); + } + obj_writer.write_edges_indices(fh, index_offsets[i], obj); + + /* Nothing will need this object's data after this point, release + * various arrays here. */ + obj.clear(); } - obj_writer.write_edges_indices(*obj_mesh); + }); - obj_writer.update_index_offsets(*obj_mesh); + /* Write all the object text buffers into the output file. */ + FILE *f = obj_writer.get_outfile(); + for (auto &b : buffers) { + b.write_to_file(f); } } @@ -202,11 +256,13 @@ static void write_mesh_objects(Vector<std::unique_ptr<OBJMesh>> exportable_as_me static void write_nurbs_curve_objects(const Vector<std::unique_ptr<OBJCurve>> &exportable_as_nurbs, const OBJWriter &obj_writer) { + FormatHandler<eFileType::OBJ> fh; /* #OBJCurve doesn't have any dynamically allocated memory, so it's fine * to wait for #blender::Vector to clean the objects up. */ for (const std::unique_ptr<OBJCurve> &obj_curve : exportable_as_nurbs) { - obj_writer.write_nurbs_curve(*obj_curve); + obj_writer.write_nurbs_curve(fh, *obj_curve); } + fh.write_to_file(obj_writer.get_outfile()); } void export_frame(Depsgraph *depsgraph, const OBJExportParams &export_params, const char *filepath) diff --git a/source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc b/source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc index f97e2575aa2..ac2ee8d566b 100644 --- a/source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc +++ b/source/blender/io/wavefront_obj/tests/obj_exporter_tests.cc @@ -238,6 +238,38 @@ TEST(obj_exporter_writer, mtllib) BLI_delete(out_file_path.c_str(), false, false); } +TEST(obj_exporter_writer, format_handler_buffer_chunking) +{ + /* Use a tiny buffer chunk size, so that the test below ends up creating several blocks. */ + FormatHandler<eFileType::OBJ, 16, 8> h; + h.write<eOBJSyntaxElement::object_name>("abc"); + h.write<eOBJSyntaxElement::object_name>("abcd"); + h.write<eOBJSyntaxElement::object_name>("abcde"); + h.write<eOBJSyntaxElement::object_name>("abcdef"); + h.write<eOBJSyntaxElement::object_name>("012345678901234567890123456789abcd"); + h.write<eOBJSyntaxElement::object_name>("123"); + h.write<eOBJSyntaxElement::curve_element_begin>(); + h.write<eOBJSyntaxElement::new_line>(); + h.write<eOBJSyntaxElement::nurbs_parameter_begin>(); + h.write<eOBJSyntaxElement::new_line>(); + + size_t got_blocks = h.get_block_count(); + ASSERT_EQ(got_blocks, 7); + + std::string got_string = h.get_as_string(); + using namespace std::string_literals; + const char *expected = R"(o abc +o abcd +o abcde +o abcdef +o 012345678901234567890123456789abcd +o 123 +curv 0.0 1.0 +parm 0.0 +)"; + ASSERT_EQ(got_string, expected); +} + /* Return true if string #a and string #b are equal after their first newline. */ static bool strings_equal_after_first_lines(const std::string &a, const std::string &b) { diff --git a/source/blender/makesdna/DNA_armature_types.h b/source/blender/makesdna/DNA_armature_types.h index 566ffd19669..1005b5186aa 100644 --- a/source/blender/makesdna/DNA_armature_types.h +++ b/source/blender/makesdna/DNA_armature_types.h @@ -77,7 +77,7 @@ typedef struct Bone { /** dist, weight: for non-deformgroup deforms. */ float dist, weight; /** - * The width for block bones. + * The width for block bones. The final X/Z bone widths are double these values. * * \note keep in this order for transform code which stores a pointer to `xwidth`, * accessing length and `zwidth` as offsets. diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h index 22c523901c0..b0276d010a4 100644 --- a/source/blender/makesdna/DNA_meshdata_types.h +++ b/source/blender/makesdna/DNA_meshdata_types.h @@ -48,7 +48,6 @@ typedef struct MVert { /** #MVert.flag */ enum { /* SELECT = (1 << 0), */ - ME_VERT_TMP_TAG = (1 << 2), ME_HIDE = (1 << 4), ME_VERT_FACEDOT = (1 << 5), /* ME_VERT_MERGED = (1 << 6), */ diff --git a/source/blender/makesdna/DNA_userdef_types.h b/source/blender/makesdna/DNA_userdef_types.h index 15bb1ef920d..637dd216935 100644 --- a/source/blender/makesdna/DNA_userdef_types.h +++ b/source/blender/makesdna/DNA_userdef_types.h @@ -651,7 +651,6 @@ typedef struct UserDef_Experimental { /* Debug options, always available. */ char use_undo_legacy; char no_override_auto_resync; - char no_proxy_to_override_conversion; char use_cycles_debug; char use_geometry_nodes_legacy; char show_asset_debug_info; @@ -666,7 +665,7 @@ typedef struct UserDef_Experimental { char use_sculpt_tools_tilt; char use_extended_asset_browser; char use_override_templates; - char _pad[1]; + char _pad[2]; /** `makesdna` does not allow empty structs. */ } UserDef_Experimental; diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h index 1ade964854d..130402a31db 100644 --- a/source/blender/makesrna/RNA_access.h +++ b/source/blender/makesrna/RNA_access.h @@ -143,6 +143,7 @@ extern StructRNA RNA_CompositorNodeCombHSVA; extern StructRNA RNA_CompositorNodeCombRGBA; extern StructRNA RNA_CompositorNodeCombYCCA; extern StructRNA RNA_CompositorNodeCombYUVA; +extern StructRNA RNA_CompositorNodeCombineXYZ; extern StructRNA RNA_CompositorNodeComposite; extern StructRNA RNA_CompositorNodeCornerPin; extern StructRNA RNA_CompositorNodeCrop; @@ -187,6 +188,7 @@ extern StructRNA RNA_CompositorNodeRLayers; extern StructRNA RNA_CompositorNodeRotate; extern StructRNA RNA_CompositorNodeScale; extern StructRNA RNA_CompositorNodeSceneTime; +extern StructRNA RNA_CompositorNodeSeparateXYZ; extern StructRNA RNA_CompositorNodeSepHSVA; extern StructRNA RNA_CompositorNodeSepRGBA; extern StructRNA RNA_CompositorNodeSepYCCA; @@ -1512,10 +1514,21 @@ void RNA_collection_clear(PointerRNA *ptr, const char *name); /** * Check if the #IDproperty exists, for operators. + * + * \param use_ghost: Internally an #IDProperty may exist, + * without the RNA considering it to be "set", see #IDP_FLAG_GHOST. + * This is used for operators, where executing an operator that has run previously + * will re-use the last value (unless #PROP_SKIP_SAVE property is set). + * In this case, the presence of the an existing value shouldn't prevent it being initialized + * from the context. Even though the this value will be returned if it's requested, + * it's not considered to be set (as it would if the menu item or key-map defined it's value). + * Set `use_ghost` to true for default behavior, otherwise false to check if there is a value + * exists internally and would be returned on request. */ bool RNA_property_is_set_ex(PointerRNA *ptr, PropertyRNA *prop, bool use_ghost); bool RNA_property_is_set(PointerRNA *ptr, PropertyRNA *prop); void RNA_property_unset(PointerRNA *ptr, PropertyRNA *prop); +/** See #RNA_property_is_set_ex documentation. */ bool RNA_struct_property_is_set_ex(PointerRNA *ptr, const char *identifier, bool use_ghost); bool RNA_struct_property_is_set(PointerRNA *ptr, const char *identifier); bool RNA_property_is_idprop(const PropertyRNA *prop); diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c index 1ae036a254e..1f3dd34a0a7 100644 --- a/source/blender/makesrna/intern/rna_ID.c +++ b/source/blender/makesrna/intern/rna_ID.c @@ -719,7 +719,8 @@ static ID *rna_ID_override_hierarchy_create( BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false); ID *id_root_override = NULL; - BKE_lib_override_library_create(bmain, scene, view_layer, id, id_reference, &id_root_override); + BKE_lib_override_library_create( + bmain, scene, view_layer, NULL, id, id_reference, &id_root_override); WM_main_add_notifier(NC_ID | NA_ADDED, NULL); WM_main_add_notifier(NC_WM | ND_LIB_OVERRIDE_CHANGED, NULL); diff --git a/source/blender/makesrna/intern/rna_asset.c b/source/blender/makesrna/intern/rna_asset.c index e79cbc838d4..e80c8559020 100644 --- a/source/blender/makesrna/intern/rna_asset.c +++ b/source/blender/makesrna/intern/rna_asset.c @@ -237,7 +237,7 @@ static void rna_AssetMetaData_catalog_id_set(PointerRNA *ptr, const char *value) } if (!BLI_uuid_parse_string(&new_uuid, value)) { - // TODO(Sybren): raise ValueError exception once that's possible from an RNA setter. + /* TODO(@sybren): raise ValueError exception once that's possible from an RNA setter. */ printf("UUID %s not formatted correctly, ignoring new value\n", value); return; } diff --git a/source/blender/makesrna/intern/rna_gpencil.c b/source/blender/makesrna/intern/rna_gpencil.c index 3f380cd1830..7ef2f757cd8 100644 --- a/source/blender/makesrna/intern/rna_gpencil.c +++ b/source/blender/makesrna/intern/rna_gpencil.c @@ -2228,7 +2228,7 @@ static void rna_def_gpencil_layer(BlenderRNA *brna) prop = RNA_def_property(srna, "use_solo_mode", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "flag", GP_LAYER_SOLO_MODE); RNA_def_property_ui_text( - prop, "Solo Mode", "In Paint mode display only layers with keyframe in current frame"); + prop, "Solo Mode", "In Draw Mode only display layers with keyframe in current frame"); RNA_def_property_update(prop, NC_GPENCIL | ND_DATA, "rna_GPencil_update"); /* Layer is used as Ruler. */ diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c index 0d86572357f..af13baad5a2 100644 --- a/source/blender/makesrna/intern/rna_image.c +++ b/source/blender/makesrna/intern/rna_image.c @@ -1107,7 +1107,7 @@ static void rna_def_image(BlenderRNA *brna) prop, "Duration", "Duration (in frames) of the image (1 when not a video/sequence)"); RNA_def_property_clear_flag(prop, PROP_EDITABLE); - /* NOTE about pixels/channels/is_float: + /* NOTE: About pixels/channels/is_float: * These properties describe how the image is stored internally (inside of ImBuf), * not how it was saved to disk or how it'll be saved on disk. */ diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index d4de20b5328..0e0391197ea 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -369,9 +369,10 @@ void rna_ViewLayer_active_aov_index_range( PointerRNA *ptr, int *min, int *max, int *softmin, int *softmax); int rna_ViewLayer_active_aov_index_get(PointerRNA *ptr); void rna_ViewLayer_active_aov_index_set(PointerRNA *ptr, int value); -/** Set `r_rna_path` with the base viewlayer path. +/** + * Set `r_rna_path` with the base view-layer path. * `rna_path_buffer_size` should be at least `sizeof(ViewLayer.name) * 3`. - * \return actual length of the generayted RNA path. + * \return actual length of the generated RNA path. */ size_t rna_ViewLayer_path_buffer_get(struct ViewLayer *view_layer, char *r_rna_path, diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c index 38a447a9657..13c8444de1d 100644 --- a/source/blender/makesrna/intern/rna_nodetree.c +++ b/source/blender/makesrna/intern/rna_nodetree.c @@ -10524,7 +10524,7 @@ static void def_geo_object_info(StructRNA *srna) RNA_def_property_enum_items(prop, rna_node_geometry_object_info_transform_space_items); RNA_def_property_ui_text( prop, "Transform Space", "The transformation of the vector and geometry outputs"); - RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update_relations"); } static void def_geo_legacy_points_to_volume(StructRNA *srna) @@ -10608,7 +10608,7 @@ static void def_geo_collection_info(StructRNA *srna) prop = RNA_def_property(srna, "transform_space", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, rna_node_geometry_collection_info_transform_space_items); RNA_def_property_ui_text(prop, "Transform Space", "The transformation of the geometry output"); - RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update"); + RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update_relations"); } static void def_geo_legacy_attribute_proximity(StructRNA *srna) diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c index 4379b4ebe1d..aef219c4236 100644 --- a/source/blender/makesrna/intern/rna_userdef.c +++ b/source/blender/makesrna/intern/rna_userdef.c @@ -6386,13 +6386,6 @@ static void rna_def_userdef_experimental(BlenderRNA *brna) "Enable library overrides automatic resync detection and process on file load. Disable when " "dealing with older .blend files that need manual Resync (Enforce) handling"); - prop = RNA_def_property(srna, "proxy_to_override_auto_conversion", PROP_BOOLEAN, PROP_NONE); - RNA_def_property_boolean_negative_sdna(prop, NULL, "no_proxy_to_override_conversion", 1); - RNA_def_property_ui_text( - prop, - "Proxy to Override Auto Conversion", - "Enable automatic conversion of proxies to library overrides on file load"); - prop = RNA_def_property(srna, "use_new_point_cloud_type", PROP_BOOLEAN, PROP_NONE); RNA_def_property_boolean_sdna(prop, NULL, "use_new_point_cloud_type", 1); RNA_def_property_ui_text( diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c index c64a47fc2ab..178a50c4d29 100644 --- a/source/blender/makesrna/intern/rna_wm.c +++ b/source/blender/makesrna/intern/rna_wm.c @@ -2175,7 +2175,8 @@ static void rna_def_event(BlenderRNA *brna) RNA_def_property_ui_text( prop, "Mouse Previous Y Position", "The window relative vertical location of the mouse"); - prop = RNA_def_property(srna, "pressure", PROP_FLOAT, PROP_NONE); + prop = RNA_def_property(srna, "pressure", PROP_FLOAT, PROP_FACTOR); + RNA_def_property_float_default(prop, 1.0f); RNA_def_property_clear_flag(prop, PROP_EDITABLE); RNA_def_property_float_funcs(prop, "rna_Event_pressure_get", NULL, NULL); RNA_def_property_ui_text( diff --git a/source/blender/modifiers/CMakeLists.txt b/source/blender/modifiers/CMakeLists.txt index bb933ba97a5..5065a23ee1b 100644 --- a/source/blender/modifiers/CMakeLists.txt +++ b/source/blender/modifiers/CMakeLists.txt @@ -183,10 +183,6 @@ if(WITH_BULLET) add_definitions(-DWITH_BULLET) endif() -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() - # To disable adaptive subdivision test in subsurf UI without cycles if(WITH_CYCLES) add_definitions(-DWITH_CYCLES) diff --git a/source/blender/modifiers/intern/MOD_armature.c b/source/blender/modifiers/intern/MOD_armature.c index 828b8b79664..a86a667974e 100644 --- a/source/blender/modifiers/intern/MOD_armature.c +++ b/source/blender/modifiers/intern/MOD_armature.c @@ -296,7 +296,6 @@ ModifierTypeInfo modifierType_Armature = { /* deformVertsEM */ deformVertsEM, /* deformMatricesEM */ deformMatricesEM, /* modifyMesh */ NULL, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c index 56db68b163c..c2b1478c1b2 100644 --- a/source/blender/modifiers/intern/MOD_array.c +++ b/source/blender/modifiers/intern/MOD_array.c @@ -1037,7 +1037,6 @@ ModifierTypeInfo modifierType_Array = { /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, /* modifyMesh */ modifyMesh, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_bevel.c b/source/blender/modifiers/intern/MOD_bevel.c index add95a0d248..984e85f58ef 100644 --- a/source/blender/modifiers/intern/MOD_bevel.c +++ b/source/blender/modifiers/intern/MOD_bevel.c @@ -446,7 +446,6 @@ ModifierTypeInfo modifierType_Bevel = { /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, /* modifyMesh */ modifyMesh, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, /* requiredDataMask */ requiredDataMask, diff --git a/source/blender/modifiers/intern/MOD_boolean.cc b/source/blender/modifiers/intern/MOD_boolean.cc index bb05ae3e1b3..7b084d608fb 100644 --- a/source/blender/modifiers/intern/MOD_boolean.cc +++ b/source/blender/modifiers/intern/MOD_boolean.cc @@ -641,7 +641,6 @@ ModifierTypeInfo modifierType_Boolean = { /* deformVertsEM */ nullptr, /* deformMatricesEM */ nullptr, /* modifyMesh */ modifyMesh, - /* modifyHair */ nullptr, /* modifyGeometrySet */ nullptr, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_build.c b/source/blender/modifiers/intern/MOD_build.c index 86f0df1418b..867c1e9b5bb 100644 --- a/source/blender/modifiers/intern/MOD_build.c +++ b/source/blender/modifiers/intern/MOD_build.c @@ -345,7 +345,6 @@ ModifierTypeInfo modifierType_Build = { /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, /* modifyMesh */ modifyMesh, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_cast.c b/source/blender/modifiers/intern/MOD_cast.c index 715bc26e5d3..defc7df31dc 100644 --- a/source/blender/modifiers/intern/MOD_cast.c +++ b/source/blender/modifiers/intern/MOD_cast.c @@ -589,7 +589,6 @@ ModifierTypeInfo modifierType_Cast = { /* deformVertsEM */ deformVertsEM, /* deformMatricesEM */ NULL, /* modifyMesh */ NULL, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_cloth.c b/source/blender/modifiers/intern/MOD_cloth.c index 8aff29dc17d..4b8928009fe 100644 --- a/source/blender/modifiers/intern/MOD_cloth.c +++ b/source/blender/modifiers/intern/MOD_cloth.c @@ -308,7 +308,6 @@ ModifierTypeInfo modifierType_Cloth = { /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, /* modifyMesh */ NULL, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_collision.c b/source/blender/modifiers/intern/MOD_collision.c index 02e1f61b824..658a569627b 100644 --- a/source/blender/modifiers/intern/MOD_collision.c +++ b/source/blender/modifiers/intern/MOD_collision.c @@ -317,7 +317,6 @@ ModifierTypeInfo modifierType_Collision = { /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, /* modifyMesh */ NULL, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_correctivesmooth.c b/source/blender/modifiers/intern/MOD_correctivesmooth.c index 49ff4acb31f..fe331b2147f 100644 --- a/source/blender/modifiers/intern/MOD_correctivesmooth.c +++ b/source/blender/modifiers/intern/MOD_correctivesmooth.c @@ -850,7 +850,6 @@ ModifierTypeInfo modifierType_CorrectiveSmooth = { /* deformVertsEM */ deformVertsEM, /* deformMatricesEM */ NULL, /* modifyMesh */ NULL, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_curve.c b/source/blender/modifiers/intern/MOD_curve.c index 20dbb299767..b01b70000b8 100644 --- a/source/blender/modifiers/intern/MOD_curve.c +++ b/source/blender/modifiers/intern/MOD_curve.c @@ -234,7 +234,6 @@ ModifierTypeInfo modifierType_Curve = { /* deformVertsEM */ deformVertsEM, /* deformMatricesEM */ NULL, /* modifyMesh */ NULL, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_datatransfer.c b/source/blender/modifiers/intern/MOD_datatransfer.c index 34bb93cbbbc..a289b9c918a 100644 --- a/source/blender/modifiers/intern/MOD_datatransfer.c +++ b/source/blender/modifiers/intern/MOD_datatransfer.c @@ -484,7 +484,6 @@ ModifierTypeInfo modifierType_DataTransfer = { /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, /* modifyMesh */ modifyMesh, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_decimate.c b/source/blender/modifiers/intern/MOD_decimate.c index 975f80a04f8..ad5391d2b6c 100644 --- a/source/blender/modifiers/intern/MOD_decimate.c +++ b/source/blender/modifiers/intern/MOD_decimate.c @@ -298,7 +298,6 @@ ModifierTypeInfo modifierType_Decimate = { /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, /* modifyMesh */ modifyMesh, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_displace.c b/source/blender/modifiers/intern/MOD_displace.c index c81e6cafa39..94cdcad3b6a 100644 --- a/source/blender/modifiers/intern/MOD_displace.c +++ b/source/blender/modifiers/intern/MOD_displace.c @@ -508,7 +508,6 @@ ModifierTypeInfo modifierType_Displace = { /* deformVertsEM */ deformVertsEM, /* deformMatricesEM */ NULL, /* modifyMesh */ NULL, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_dynamicpaint.c b/source/blender/modifiers/intern/MOD_dynamicpaint.c index a696ce216c7..676433b14b1 100644 --- a/source/blender/modifiers/intern/MOD_dynamicpaint.c +++ b/source/blender/modifiers/intern/MOD_dynamicpaint.c @@ -221,7 +221,6 @@ ModifierTypeInfo modifierType_DynamicPaint = { /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, /* modifyMesh */ modifyMesh, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_edgesplit.c b/source/blender/modifiers/intern/MOD_edgesplit.c index 1039bcb2b3b..55707435e52 100644 --- a/source/blender/modifiers/intern/MOD_edgesplit.c +++ b/source/blender/modifiers/intern/MOD_edgesplit.c @@ -185,7 +185,6 @@ ModifierTypeInfo modifierType_EdgeSplit = { /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, /* modifyMesh */ modifyMesh, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_explode.c b/source/blender/modifiers/intern/MOD_explode.c index 68d6b4a3626..c788633f978 100644 --- a/source/blender/modifiers/intern/MOD_explode.c +++ b/source/blender/modifiers/intern/MOD_explode.c @@ -1255,7 +1255,6 @@ ModifierTypeInfo modifierType_Explode = { /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, /* modifyMesh */ modifyMesh, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_fluid.c b/source/blender/modifiers/intern/MOD_fluid.c index a21eb603300..748633b78b3 100644 --- a/source/blender/modifiers/intern/MOD_fluid.c +++ b/source/blender/modifiers/intern/MOD_fluid.c @@ -273,7 +273,6 @@ ModifierTypeInfo modifierType_Fluid = { /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, /* modifyMesh */ modifyMesh, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_hook.c b/source/blender/modifiers/intern/MOD_hook.c index 18ce37c5d85..b4c081906ba 100644 --- a/source/blender/modifiers/intern/MOD_hook.c +++ b/source/blender/modifiers/intern/MOD_hook.c @@ -572,7 +572,6 @@ ModifierTypeInfo modifierType_Hook = { /* deformVertsEM */ deformVertsEM, /* deformMatricesEM */ NULL, /* modifyMesh */ NULL, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_laplaciandeform.c b/source/blender/modifiers/intern/MOD_laplaciandeform.c index 6efeec1970f..090973f12c0 100644 --- a/source/blender/modifiers/intern/MOD_laplaciandeform.c +++ b/source/blender/modifiers/intern/MOD_laplaciandeform.c @@ -887,7 +887,6 @@ ModifierTypeInfo modifierType_LaplacianDeform = { /* deformVertsEM */ deformVertsEM, /* deformMatricesEM */ NULL, /* modifyMesh */ NULL, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_laplaciansmooth.c b/source/blender/modifiers/intern/MOD_laplaciansmooth.c index a36a8c386b4..8cc34d43d82 100644 --- a/source/blender/modifiers/intern/MOD_laplaciansmooth.c +++ b/source/blender/modifiers/intern/MOD_laplaciansmooth.c @@ -633,7 +633,6 @@ ModifierTypeInfo modifierType_LaplacianSmooth = { /* deformVertsEM */ deformVertsEM, /* deformMatricesEM */ NULL, /* modifyMesh */ NULL, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ init_data, diff --git a/source/blender/modifiers/intern/MOD_lattice.c b/source/blender/modifiers/intern/MOD_lattice.c index 29d1ecf6050..709b617d3ec 100644 --- a/source/blender/modifiers/intern/MOD_lattice.c +++ b/source/blender/modifiers/intern/MOD_lattice.c @@ -191,7 +191,6 @@ ModifierTypeInfo modifierType_Lattice = { /* deformVertsEM */ deformVertsEM, /* deformMatricesEM */ NULL, /* modifyMesh */ NULL, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_mask.cc b/source/blender/modifiers/intern/MOD_mask.cc index 0de8b26a1b7..097f7241205 100644 --- a/source/blender/modifiers/intern/MOD_mask.cc +++ b/source/blender/modifiers/intern/MOD_mask.cc @@ -837,7 +837,6 @@ ModifierTypeInfo modifierType_Mask = { /* deformVertsEM */ nullptr, /* deformMatricesEM */ nullptr, /* modifyMesh */ modifyMesh, - /* modifyHair */ nullptr, /* modifyGeometrySet */ nullptr, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_mesh_to_volume.cc b/source/blender/modifiers/intern/MOD_mesh_to_volume.cc index 910b52dea67..a8e1c91dd20 100644 --- a/source/blender/modifiers/intern/MOD_mesh_to_volume.cc +++ b/source/blender/modifiers/intern/MOD_mesh_to_volume.cc @@ -308,7 +308,6 @@ ModifierTypeInfo modifierType_MeshToVolume = { /* deformVertsEM */ nullptr, /* deformMatricesEM */ nullptr, /* modifyMesh */ nullptr, - /* modifyHair */ nullptr, /* modifyGeometrySet */ modifyGeometrySet, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_meshcache.c b/source/blender/modifiers/intern/MOD_meshcache.c index 74f9887a973..48ff4f7d6af 100644 --- a/source/blender/modifiers/intern/MOD_meshcache.c +++ b/source/blender/modifiers/intern/MOD_meshcache.c @@ -446,7 +446,6 @@ ModifierTypeInfo modifierType_MeshCache = { /* deformVertsEM */ deformVertsEM, /* deformMatricesEM */ NULL, /* modifyMesh */ NULL, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c index cb043643dd9..3e751eeb239 100644 --- a/source/blender/modifiers/intern/MOD_meshdeform.c +++ b/source/blender/modifiers/intern/MOD_meshdeform.c @@ -642,7 +642,6 @@ ModifierTypeInfo modifierType_MeshDeform = { /* deformVertsEM */ deformVertsEM, /* deformMatricesEM */ NULL, /* modifyMesh */ NULL, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_meshsequencecache.c b/source/blender/modifiers/intern/MOD_meshsequencecache.c index b5dd0566215..8bde0cab3dc 100644 --- a/source/blender/modifiers/intern/MOD_meshsequencecache.c +++ b/source/blender/modifiers/intern/MOD_meshsequencecache.c @@ -456,7 +456,6 @@ ModifierTypeInfo modifierType_MeshSequenceCache = { /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, /* modifyMesh */ modifyMesh, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_mirror.c b/source/blender/modifiers/intern/MOD_mirror.c index 1bdc97f0a8b..721906a6a01 100644 --- a/source/blender/modifiers/intern/MOD_mirror.c +++ b/source/blender/modifiers/intern/MOD_mirror.c @@ -238,7 +238,6 @@ ModifierTypeInfo modifierType_Mirror = { /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, /* modifyMesh */ modifyMesh, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_multires.c b/source/blender/modifiers/intern/MOD_multires.c index c3b34f3cd23..205839774d8 100644 --- a/source/blender/modifiers/intern/MOD_multires.c +++ b/source/blender/modifiers/intern/MOD_multires.c @@ -518,7 +518,6 @@ ModifierTypeInfo modifierType_Multires = { /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, /* modifyMesh */ modifyMesh, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_nodes.cc b/source/blender/modifiers/intern/MOD_nodes.cc index 49528845197..ac72478782f 100644 --- a/source/blender/modifiers/intern/MOD_nodes.cc +++ b/source/blender/modifiers/intern/MOD_nodes.cc @@ -137,56 +137,85 @@ static void initData(ModifierData *md) MEMCPY_STRUCT_AFTER(nmd, DNA_struct_default_get(NodesModifierData), modifier); } -static void addIdsUsedBySocket(const ListBase *sockets, Set<ID *> &ids) +static void add_used_ids_from_sockets(const ListBase &sockets, Set<ID *> &ids) { - LISTBASE_FOREACH (const bNodeSocket *, socket, sockets) { - if (socket->type == SOCK_OBJECT) { - Object *object = ((bNodeSocketValueObject *)socket->default_value)->value; - if (object != nullptr) { - ids.add(&object->id); + LISTBASE_FOREACH (const bNodeSocket *, socket, &sockets) { + switch (socket->type) { + case SOCK_OBJECT: { + if (Object *object = ((bNodeSocketValueObject *)socket->default_value)->value) { + ids.add(&object->id); + } + break; } - } - else if (socket->type == SOCK_COLLECTION) { - Collection *collection = ((bNodeSocketValueCollection *)socket->default_value)->value; - if (collection != nullptr) { - ids.add(&collection->id); + case SOCK_COLLECTION: { + if (Collection *collection = + ((bNodeSocketValueCollection *)socket->default_value)->value) { + ids.add(&collection->id); + } + break; } - } - else if (socket->type == SOCK_MATERIAL) { - Material *material = ((bNodeSocketValueMaterial *)socket->default_value)->value; - if (material != nullptr) { - ids.add(&material->id); + case SOCK_MATERIAL: { + if (Material *material = ((bNodeSocketValueMaterial *)socket->default_value)->value) { + ids.add(&material->id); + } + break; } - } - else if (socket->type == SOCK_TEXTURE) { - Tex *texture = ((bNodeSocketValueTexture *)socket->default_value)->value; - if (texture != nullptr) { - ids.add(&texture->id); + case SOCK_TEXTURE: { + if (Tex *texture = ((bNodeSocketValueTexture *)socket->default_value)->value) { + ids.add(&texture->id); + } + break; } - } - else if (socket->type == SOCK_IMAGE) { - Image *image = ((bNodeSocketValueImage *)socket->default_value)->value; - if (image != nullptr) { - ids.add(&image->id); + case SOCK_IMAGE: { + if (Image *image = ((bNodeSocketValueImage *)socket->default_value)->value) { + ids.add(&image->id); + } + break; } } } } -static void find_used_ids_from_nodes(const bNodeTree &tree, Set<ID *> &ids) +/** + * \note We can only check properties here that cause the dependency graph to update relations when + * they are changed, otherwise there may be a missing relation after editing. So this could check + * more properties like whether the node is muted, but we would have to accept the cost of updating + * relations when those properties are changed. + */ +static bool node_needs_own_transform_relation(const bNode &node) +{ + if (node.type == GEO_NODE_COLLECTION_INFO) { + const NodeGeometryCollectionInfo &storage = *static_cast<const NodeGeometryCollectionInfo *>( + node.storage); + return storage.transform_space == GEO_NODE_TRANSFORM_SPACE_RELATIVE; + } + + if (node.type == GEO_NODE_OBJECT_INFO) { + const NodeGeometryObjectInfo &storage = *static_cast<const NodeGeometryObjectInfo *>( + node.storage); + return storage.transform_space == GEO_NODE_TRANSFORM_SPACE_RELATIVE; + } + + return false; +} + +static void process_nodes_for_depsgraph(const bNodeTree &tree, + Set<ID *> &ids, + bool &needs_own_transform_relation) { Set<const bNodeTree *> handled_groups; LISTBASE_FOREACH (const bNode *, node, &tree.nodes) { - addIdsUsedBySocket(&node->inputs, ids); - addIdsUsedBySocket(&node->outputs, ids); + add_used_ids_from_sockets(node->inputs, ids); + add_used_ids_from_sockets(node->outputs, ids); if (ELEM(node->type, NODE_GROUP, NODE_CUSTOM_GROUP)) { const bNodeTree *group = (bNodeTree *)node->id; if (group != nullptr && handled_groups.add(group)) { - find_used_ids_from_nodes(*group, ids); + process_nodes_for_depsgraph(*group, ids, needs_own_transform_relation); } } + needs_own_transform_relation |= node_needs_own_transform_relation(*node); } } @@ -236,37 +265,43 @@ static void add_object_relation(const ModifierUpdateDepsgraphContext *ctx, Objec static void updateDepsgraph(ModifierData *md, const ModifierUpdateDepsgraphContext *ctx) { NodesModifierData *nmd = reinterpret_cast<NodesModifierData *>(md); - DEG_add_modifier_to_transform_relation(ctx->node, "Nodes Modifier"); - if (nmd->node_group != nullptr) { - DEG_add_node_tree_output_relation(ctx->node, nmd->node_group, "Nodes Modifier"); - - Set<ID *> used_ids; - find_used_ids_from_settings(nmd->settings, used_ids); - find_used_ids_from_nodes(*nmd->node_group, used_ids); - for (ID *id : used_ids) { - switch ((ID_Type)GS(id->name)) { - case ID_OB: { - Object *object = reinterpret_cast<Object *>(id); - add_object_relation(ctx, *object); - break; - } - case ID_GR: { - Collection *collection = reinterpret_cast<Collection *>(id); - add_collection_relation(ctx, *collection); - break; - } - case ID_IM: - case ID_TE: { - DEG_add_generic_id_relation(ctx->node, id, "Nodes Modifier"); - } - default: { - /* Purposefully don't add relations for materials. While there are material sockets, - * the pointers are only passed around as handles rather than dereferenced. */ - break; - } + if (nmd->node_group == nullptr) { + return; + } + + DEG_add_node_tree_output_relation(ctx->node, nmd->node_group, "Nodes Modifier"); + + bool needs_own_transform_relation = false; + Set<ID *> used_ids; + find_used_ids_from_settings(nmd->settings, used_ids); + process_nodes_for_depsgraph(*nmd->node_group, used_ids, needs_own_transform_relation); + for (ID *id : used_ids) { + switch ((ID_Type)GS(id->name)) { + case ID_OB: { + Object *object = reinterpret_cast<Object *>(id); + add_object_relation(ctx, *object); + break; + } + case ID_GR: { + Collection *collection = reinterpret_cast<Collection *>(id); + add_collection_relation(ctx, *collection); + break; + } + case ID_IM: + case ID_TE: { + DEG_add_generic_id_relation(ctx->node, id, "Nodes Modifier"); + } + default: { + /* Purposefully don't add relations for materials. While there are material sockets, + * the pointers are only passed around as handles rather than dereferenced. */ + break; } } } + + if (needs_own_transform_relation) { + DEG_add_modifier_to_transform_relation(ctx->node, "Nodes Modifier"); + } } static bool check_tree_for_time_node(const bNodeTree &tree, @@ -1616,7 +1651,6 @@ ModifierTypeInfo modifierType_Nodes = { /* deformVertsEM */ nullptr, /* deformMatricesEM */ nullptr, /* modifyMesh */ modifyMesh, - /* modifyHair */ nullptr, /* modifyGeometrySet */ modifyGeometrySet, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_none.c b/source/blender/modifiers/intern/MOD_none.c index a01f63be791..cce3434f6e3 100644 --- a/source/blender/modifiers/intern/MOD_none.c +++ b/source/blender/modifiers/intern/MOD_none.c @@ -58,7 +58,6 @@ ModifierTypeInfo modifierType_None = { /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, /* modifyMesh */ NULL, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ NULL, diff --git a/source/blender/modifiers/intern/MOD_normal_edit.c b/source/blender/modifiers/intern/MOD_normal_edit.c index 61099fedf46..8b58b575d24 100644 --- a/source/blender/modifiers/intern/MOD_normal_edit.c +++ b/source/blender/modifiers/intern/MOD_normal_edit.c @@ -336,8 +336,6 @@ static void normalEditModifier_do_radial(NormalEditModifierData *enmd, if (do_polynors_fix && polygons_check_flip( mloop, nos, &mesh->ldata, mpoly, BKE_mesh_poly_normals_for_write(mesh), num_polys)) { - /* XXX TODO: is this still needed? */ - // mesh->dirty |= DM_DIRTY_TESS_CDLAYERS; /* We need to recompute vertex normals! */ BKE_mesh_normals_tag_dirty(mesh); } @@ -788,7 +786,6 @@ ModifierTypeInfo modifierType_NormalEdit = { /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, /* modifyMesh */ modifyMesh, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_ocean.c b/source/blender/modifiers/intern/MOD_ocean.c index d821caf25a7..0c00f807df3 100644 --- a/source/blender/modifiers/intern/MOD_ocean.c +++ b/source/blender/modifiers/intern/MOD_ocean.c @@ -741,7 +741,6 @@ ModifierTypeInfo modifierType_Ocean = { /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, /* modifyMesh */ modifyMesh, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_particleinstance.c b/source/blender/modifiers/intern/MOD_particleinstance.c index 4fffa7c93f3..67a492d4154 100644 --- a/source/blender/modifiers/intern/MOD_particleinstance.c +++ b/source/blender/modifiers/intern/MOD_particleinstance.c @@ -677,7 +677,6 @@ ModifierTypeInfo modifierType_ParticleInstance = { /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, /* modifyMesh */ modifyMesh, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_particlesystem.c b/source/blender/modifiers/intern/MOD_particlesystem.c index 2a4cc1c2747..6fb60fffcf4 100644 --- a/source/blender/modifiers/intern/MOD_particlesystem.c +++ b/source/blender/modifiers/intern/MOD_particlesystem.c @@ -334,7 +334,6 @@ ModifierTypeInfo modifierType_ParticleSystem = { /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, /* modifyMesh */ NULL, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_remesh.c b/source/blender/modifiers/intern/MOD_remesh.c index 937a73fddd9..67f83b17f3f 100644 --- a/source/blender/modifiers/intern/MOD_remesh.c +++ b/source/blender/modifiers/intern/MOD_remesh.c @@ -299,7 +299,6 @@ ModifierTypeInfo modifierType_Remesh = { /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, /* modifyMesh */ modifyMesh, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_screw.c b/source/blender/modifiers/intern/MOD_screw.c index f5db3bced7a..33c62197dbd 100644 --- a/source/blender/modifiers/intern/MOD_screw.c +++ b/source/blender/modifiers/intern/MOD_screw.c @@ -27,6 +27,7 @@ #include "BLI_utildefines.h" #include "BLI_alloca.h" +#include "BLI_bitmap.h" #include "BLI_math.h" #include "BLT_translation.h" @@ -134,6 +135,8 @@ static Mesh *mesh_remove_doubles_on_axis(Mesh *result, const float axis_offset[3], const float merge_threshold) { + BLI_bitmap *vert_tag = BLI_BITMAP_NEW(totvert, __func__); + const float merge_threshold_sq = square_f(merge_threshold); const bool use_offset = axis_offset != NULL; uint tot_doubles = 0; @@ -150,13 +153,10 @@ static Mesh *mesh_remove_doubles_on_axis(Mesh *result, } const float dist_sq = len_squared_v3v3(axis_co, mvert_new[i].co); if (dist_sq <= merge_threshold_sq) { - mvert_new[i].flag |= ME_VERT_TMP_TAG; + BLI_BITMAP_ENABLE(vert_tag, i); tot_doubles += 1; copy_v3_v3(mvert_new[i].co, axis_co); } - else { - mvert_new[i].flag &= ~ME_VERT_TMP_TAG & 0xFF; - } } if (tot_doubles != 0) { @@ -166,7 +166,7 @@ static Mesh *mesh_remove_doubles_on_axis(Mesh *result, uint tot_doubles_left = tot_doubles; for (uint i = 0; i < totvert; i += 1) { - if (mvert_new[i].flag & ME_VERT_TMP_TAG) { + if (BLI_BITMAP_TEST(vert_tag, i)) { int *doubles_map = &full_doubles_map[totvert + i]; for (uint step = 1; step < step_tot; step += 1) { *doubles_map = (int)i; @@ -184,6 +184,9 @@ static Mesh *mesh_remove_doubles_on_axis(Mesh *result, MESH_MERGE_VERTS_DUMP_IF_MAPPED); MEM_freeN(full_doubles_map); } + + MEM_freeN(vert_tag); + return result; } @@ -439,6 +442,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * mv_new = mvert_new; mv_orig = mvert_orig; + BLI_bitmap *vert_tag = BLI_BITMAP_NEW(totvert, __func__); + /* Copy the first set of edges */ med_orig = medge_orig; med_new = medge_new; @@ -447,10 +452,10 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * med_new->v2 = med_orig->v2; med_new->crease = med_orig->crease; med_new->flag = med_orig->flag & ~ME_LOOSEEDGE; - /* Tag mvert as not loose. - * NOTE: ME_VERT_TMP_TAG is given to be cleared by BKE_mesh_new_nomain_from_template. */ - mvert_new[med_orig->v1].flag |= ME_VERT_TMP_TAG; - mvert_new[med_orig->v2].flag |= ME_VERT_TMP_TAG; + + /* Tag mvert as not loose. */ + BLI_BITMAP_ENABLE(vert_tag, med_orig->v1); + BLI_BITMAP_ENABLE(vert_tag, med_orig->v1); } /* build polygon -> edge map */ @@ -910,7 +915,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * med_new->v1 = varray_stride + j; med_new->v2 = med_new->v1 - totvert; med_new->flag = ME_EDGEDRAW | ME_EDGERENDER; - if ((mv_new_base->flag & ME_VERT_TMP_TAG) == 0) { + if (!BLI_BITMAP_TEST(vert_tag, j)) { med_new->flag |= ME_LOOSEEDGE; } med_new++; @@ -931,7 +936,7 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * med_new->v1 = i; med_new->v2 = varray_stride + i; med_new->flag = ME_EDGEDRAW | ME_EDGERENDER; - if ((mvert_new[i].flag & ME_VERT_TMP_TAG) == 0) { + if (!BLI_BITMAP_TEST(vert_tag, i)) { med_new->flag |= ME_LOOSEEDGE; } med_new++; @@ -1119,6 +1124,8 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * } #endif + MEM_freeN(vert_tag); + if (edge_poly_map) { MEM_freeN(edge_poly_map); } @@ -1257,7 +1264,6 @@ ModifierTypeInfo modifierType_Screw = { /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, /* modifyMesh */ modifyMesh, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_shapekey.c b/source/blender/modifiers/intern/MOD_shapekey.c index b517bc102f8..8c5299a965d 100644 --- a/source/blender/modifiers/intern/MOD_shapekey.c +++ b/source/blender/modifiers/intern/MOD_shapekey.c @@ -139,7 +139,6 @@ ModifierTypeInfo modifierType_ShapeKey = { /* deformVertsEM */ deformVertsEM, /* deformMatricesEM */ deformMatricesEM, /* modifyMesh */ NULL, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ NULL, diff --git a/source/blender/modifiers/intern/MOD_shrinkwrap.c b/source/blender/modifiers/intern/MOD_shrinkwrap.c index a12724ec23c..4d10df91331 100644 --- a/source/blender/modifiers/intern/MOD_shrinkwrap.c +++ b/source/blender/modifiers/intern/MOD_shrinkwrap.c @@ -291,7 +291,6 @@ ModifierTypeInfo modifierType_Shrinkwrap = { /* deformVertsEM */ deformVertsEM, /* deformMatricesEM */ NULL, /* modifyMesh */ NULL, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_simpledeform.c b/source/blender/modifiers/intern/MOD_simpledeform.c index 39ebc415021..25c3acb0c4f 100644 --- a/source/blender/modifiers/intern/MOD_simpledeform.c +++ b/source/blender/modifiers/intern/MOD_simpledeform.c @@ -596,7 +596,6 @@ ModifierTypeInfo modifierType_SimpleDeform = { /* deformVertsEM */ deformVertsEM, /* deformMatricesEM */ NULL, /* modifyMesh */ NULL, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_skin.c b/source/blender/modifiers/intern/MOD_skin.c index 07ce819e91c..d1cb120132d 100644 --- a/source/blender/modifiers/intern/MOD_skin.c +++ b/source/blender/modifiers/intern/MOD_skin.c @@ -2101,7 +2101,6 @@ ModifierTypeInfo modifierType_Skin = { /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, /* modifyMesh */ modifyMesh, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_smooth.c b/source/blender/modifiers/intern/MOD_smooth.c index 97027e2ecff..3228a72d958 100644 --- a/source/blender/modifiers/intern/MOD_smooth.c +++ b/source/blender/modifiers/intern/MOD_smooth.c @@ -284,7 +284,6 @@ ModifierTypeInfo modifierType_Smooth = { /* deformVertsEM */ deformVertsEM, /* deformMatricesEM */ NULL, /* modifyMesh */ NULL, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_softbody.c b/source/blender/modifiers/intern/MOD_softbody.c index 46e960e10d4..f0178a817dc 100644 --- a/source/blender/modifiers/intern/MOD_softbody.c +++ b/source/blender/modifiers/intern/MOD_softbody.c @@ -120,7 +120,6 @@ ModifierTypeInfo modifierType_Softbody = { /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, /* modifyMesh */ NULL, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ NULL, diff --git a/source/blender/modifiers/intern/MOD_solidify.c b/source/blender/modifiers/intern/MOD_solidify.c index 736dd08a713..09933fef7ff 100644 --- a/source/blender/modifiers/intern/MOD_solidify.c +++ b/source/blender/modifiers/intern/MOD_solidify.c @@ -274,7 +274,6 @@ ModifierTypeInfo modifierType_Solidify = { /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, /* modifyMesh */ modifyMesh, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_subsurf.c b/source/blender/modifiers/intern/MOD_subsurf.c index a8c6687193b..65ad298cff1 100644 --- a/source/blender/modifiers/intern/MOD_subsurf.c +++ b/source/blender/modifiers/intern/MOD_subsurf.c @@ -500,7 +500,6 @@ ModifierTypeInfo modifierType_Subsurf = { /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, /* modifyMesh */ modifyMesh, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_surface.c b/source/blender/modifiers/intern/MOD_surface.c index c8be2bd2829..a54af766b2f 100644 --- a/source/blender/modifiers/intern/MOD_surface.c +++ b/source/blender/modifiers/intern/MOD_surface.c @@ -245,7 +245,6 @@ ModifierTypeInfo modifierType_Surface = { /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, /* modifyMesh */ NULL, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.c b/source/blender/modifiers/intern/MOD_surfacedeform.c index ec6de8f8387..fd41eedba80 100644 --- a/source/blender/modifiers/intern/MOD_surfacedeform.c +++ b/source/blender/modifiers/intern/MOD_surfacedeform.c @@ -1715,7 +1715,6 @@ ModifierTypeInfo modifierType_SurfaceDeform = { /* deformVertsEM */ deformVertsEM, /* deformMatricesEM */ NULL, /* modifyMesh */ NULL, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_triangulate.c b/source/blender/modifiers/intern/MOD_triangulate.c index b713df05b80..d4fcebb3216 100644 --- a/source/blender/modifiers/intern/MOD_triangulate.c +++ b/source/blender/modifiers/intern/MOD_triangulate.c @@ -170,7 +170,6 @@ ModifierTypeInfo modifierType_Triangulate = { /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, /* modifyMesh */ modifyMesh, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_uvproject.c b/source/blender/modifiers/intern/MOD_uvproject.c index 238952fde00..5721834c032 100644 --- a/source/blender/modifiers/intern/MOD_uvproject.c +++ b/source/blender/modifiers/intern/MOD_uvproject.c @@ -383,7 +383,6 @@ ModifierTypeInfo modifierType_UVProject = { /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, /* modifyMesh */ modifyMesh, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_uvwarp.c b/source/blender/modifiers/intern/MOD_uvwarp.c index 3f161d339c2..552cf1d5d3b 100644 --- a/source/blender/modifiers/intern/MOD_uvwarp.c +++ b/source/blender/modifiers/intern/MOD_uvwarp.c @@ -233,9 +233,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh * settings.use_threading = (numPolys > 1000); BLI_task_parallel_range(0, numPolys, &data, uv_warp_compute, &settings); - /* XXX TODO: is this still needed? */ - // me_eval->dirty |= DM_DIRTY_TESS_CDLAYERS; - mesh->runtime.is_original = false; return mesh; @@ -340,7 +337,6 @@ ModifierTypeInfo modifierType_UVWarp = { /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, /* modifyMesh */ modifyMesh, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_volume_displace.cc b/source/blender/modifiers/intern/MOD_volume_displace.cc index af3a502162d..2b9ee97ea09 100644 --- a/source/blender/modifiers/intern/MOD_volume_displace.cc +++ b/source/blender/modifiers/intern/MOD_volume_displace.cc @@ -339,7 +339,6 @@ ModifierTypeInfo modifierType_VolumeDisplace = { /* deformVertsEM */ nullptr, /* deformMatricesEM */ nullptr, /* modifyMesh */ nullptr, - /* modifyHair */ nullptr, /* modifyGeometrySet */ modifyGeometrySet, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_volume_to_mesh.cc b/source/blender/modifiers/intern/MOD_volume_to_mesh.cc index 72358844838..9557abf0a8a 100644 --- a/source/blender/modifiers/intern/MOD_volume_to_mesh.cc +++ b/source/blender/modifiers/intern/MOD_volume_to_mesh.cc @@ -221,7 +221,6 @@ ModifierTypeInfo modifierType_VolumeToMesh = { /* deformVertsEM */ nullptr, /* deformMatricesEM */ nullptr, /* modifyMesh */ modifyMesh, - /* modifyHair */ nullptr, /* modifyGeometrySet */ nullptr, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_warp.c b/source/blender/modifiers/intern/MOD_warp.c index 25e33b22bde..777ae4d9b10 100644 --- a/source/blender/modifiers/intern/MOD_warp.c +++ b/source/blender/modifiers/intern/MOD_warp.c @@ -539,7 +539,6 @@ ModifierTypeInfo modifierType_Warp = { /* deformVertsEM */ deformVertsEM, /* deformMatricesEM */ NULL, /* modifyMesh */ NULL, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_wave.c b/source/blender/modifiers/intern/MOD_wave.c index b7ab5dac388..5a56ec1d9e5 100644 --- a/source/blender/modifiers/intern/MOD_wave.c +++ b/source/blender/modifiers/intern/MOD_wave.c @@ -494,7 +494,6 @@ ModifierTypeInfo modifierType_Wave = { /* deformVertsEM */ deformVertsEM, /* deformMatricesEM */ NULL, /* modifyMesh */ NULL, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_weighted_normal.c b/source/blender/modifiers/intern/MOD_weighted_normal.c index bfe389eb080..21e6ed46908 100644 --- a/source/blender/modifiers/intern/MOD_weighted_normal.c +++ b/source/blender/modifiers/intern/MOD_weighted_normal.c @@ -757,7 +757,6 @@ ModifierTypeInfo modifierType_WeightedNormal = { /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, /* modifyMesh */ modifyMesh, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_weightvgedit.c b/source/blender/modifiers/intern/MOD_weightvgedit.c index a9d01c64ff1..6e4f8be8c50 100644 --- a/source/blender/modifiers/intern/MOD_weightvgedit.c +++ b/source/blender/modifiers/intern/MOD_weightvgedit.c @@ -428,7 +428,6 @@ ModifierTypeInfo modifierType_WeightVGEdit = { /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, /* modifyMesh */ modifyMesh, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_weightvgmix.c b/source/blender/modifiers/intern/MOD_weightvgmix.c index b369b82ebb7..1b2608afa12 100644 --- a/source/blender/modifiers/intern/MOD_weightvgmix.c +++ b/source/blender/modifiers/intern/MOD_weightvgmix.c @@ -514,7 +514,6 @@ ModifierTypeInfo modifierType_WeightVGMix = { /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, /* modifyMesh */ modifyMesh, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_weightvgproximity.c b/source/blender/modifiers/intern/MOD_weightvgproximity.c index 7ee19e1c537..27242b32432 100644 --- a/source/blender/modifiers/intern/MOD_weightvgproximity.c +++ b/source/blender/modifiers/intern/MOD_weightvgproximity.c @@ -767,7 +767,6 @@ ModifierTypeInfo modifierType_WeightVGProximity = { /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, /* modifyMesh */ modifyMesh, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_weld.cc b/source/blender/modifiers/intern/MOD_weld.cc index 64871acabea..e9d98429ff2 100644 --- a/source/blender/modifiers/intern/MOD_weld.cc +++ b/source/blender/modifiers/intern/MOD_weld.cc @@ -218,7 +218,6 @@ ModifierTypeInfo modifierType_Weld = { /* deformVertsEM */ nullptr, /* deformMatricesEM */ nullptr, /* modifyMesh */ modifyMesh, - /* modifyHair */ nullptr, /* modifyGeometrySet */ nullptr, /* initData */ initData, diff --git a/source/blender/modifiers/intern/MOD_wireframe.c b/source/blender/modifiers/intern/MOD_wireframe.c index 706960182cf..72bc4336eff 100644 --- a/source/blender/modifiers/intern/MOD_wireframe.c +++ b/source/blender/modifiers/intern/MOD_wireframe.c @@ -194,7 +194,6 @@ ModifierTypeInfo modifierType_Wireframe = { /* deformVertsEM */ NULL, /* deformMatricesEM */ NULL, /* modifyMesh */ modifyMesh, - /* modifyHair */ NULL, /* modifyGeometrySet */ NULL, /* initData */ initData, diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt index 402a71af27f..43fb90a52cd 100644 --- a/source/blender/nodes/CMakeLists.txt +++ b/source/blender/nodes/CMakeLists.txt @@ -133,10 +133,6 @@ if(WITH_PYTHON) add_definitions(-DWITH_PYTHON) endif() -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() - if(WITH_TBB) list(APPEND INC_SYS ${TBB_INCLUDE_DIRS} diff --git a/source/blender/nodes/NOD_composite.h b/source/blender/nodes/NOD_composite.h index 82faccc2c2d..71acc738472 100644 --- a/source/blender/nodes/NOD_composite.h +++ b/source/blender/nodes/NOD_composite.h @@ -140,6 +140,8 @@ void register_node_type_cmp_pixelate(void); void register_node_type_cmp_trackpos(void); void register_node_type_cmp_planetrackdeform(void); void register_node_type_cmp_cornerpin(void); +void register_node_type_cmp_separate_xyz(void); +void register_node_type_cmp_combine_xyz(void); void node_cmp_rlayers_outputs(struct bNodeTree *ntree, struct bNode *node); void node_cmp_rlayers_register_pass(struct bNodeTree *ntree, diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h index 8cbde6adcad..8fd71a978e3 100644 --- a/source/blender/nodes/NOD_static_types.h +++ b/source/blender/nodes/NOD_static_types.h @@ -230,6 +230,8 @@ DefNode(CompositorNode, CMP_NODE_ANTIALIASING, def_cmp_antialiasing, "ANTIAL DefNode(CompositorNode, CMP_NODE_POSTERIZE, 0, "POSTERIZE", Posterize, "Posterize", "" ) DefNode(CompositorNode, CMP_NODE_CONVERT_COLOR_SPACE,def_cmp_convert_color_space, "CONVERT_COLORSPACE", ConvertColorSpace, "Color Space","" ) DefNode(CompositorNode, CMP_NODE_SCENE_TIME, 0, "SCENE_TIME", SceneTime, "Scene Time", "" ) +DefNode(CompositorNode, CMP_NODE_COMBINE_XYZ, 0, "COMBINE_XYZ", CombineXYZ, "Combine XYZ", "" ) +DefNode(CompositorNode, CMP_NODE_SEPARATE_XYZ, 0, "SEPARATE_XYZ", SeparateXYZ, "Separate XYZ", "" ) DefNode(TextureNode, TEX_NODE_OUTPUT, def_tex_output, "OUTPUT", Output, "Output", "" ) DefNode(TextureNode, TEX_NODE_CHECKER, 0, "CHECKER", Checker, "Checker", "" ) diff --git a/source/blender/nodes/composite/CMakeLists.txt b/source/blender/nodes/composite/CMakeLists.txt index 8d2b2befd1a..8581ab7f82f 100644 --- a/source/blender/nodes/composite/CMakeLists.txt +++ b/source/blender/nodes/composite/CMakeLists.txt @@ -110,6 +110,7 @@ set(SRC nodes/node_composite_sepcomb_rgba.cc nodes/node_composite_sepcomb_ycca.cc nodes/node_composite_sepcomb_yuva.cc + nodes/node_composite_sepcomb_xyz.cc nodes/node_composite_setalpha.cc nodes/node_composite_split_viewer.cc nodes/node_composite_stabilize2d.cc @@ -133,10 +134,6 @@ set(SRC node_composite_util.hh ) -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() - if(WITH_IMAGE_OPENEXR) add_definitions(-DWITH_OPENEXR) endif() diff --git a/source/blender/nodes/composite/nodes/node_composite_sepcomb_xyz.cc b/source/blender/nodes/composite/nodes/node_composite_sepcomb_xyz.cc new file mode 100644 index 00000000000..5dfcf5dca1e --- /dev/null +++ b/source/blender/nodes/composite/nodes/node_composite_sepcomb_xyz.cc @@ -0,0 +1,71 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * The Original Code is Copyright (C) 2021 Blender Foundation. + * All rights reserved. + */ + +/** \file + * \ingroup cmpnodes + */ + +#include "node_composite_util.hh" + +/* **************** SEPARATE XYZ ******************** */ +namespace blender::nodes { + +static void cmp_node_separate_xyz_declare(NodeDeclarationBuilder &b) +{ + b.add_input<decl::Vector>("Vector").min(-10000.0f).max(10000.0f); + b.add_output<decl::Float>("X"); + b.add_output<decl::Float>("Y"); + b.add_output<decl::Float>("Z"); +} + +} // namespace blender::nodes + +void register_node_type_cmp_separate_xyz() +{ + static bNodeType ntype; + + cmp_node_type_base(&ntype, CMP_NODE_SEPARATE_XYZ, "Separate XYZ", NODE_CLASS_CONVERTER); + ntype.declare = blender::nodes::cmp_node_separate_xyz_declare; + + nodeRegisterType(&ntype); +} + +/* **************** COMBINE XYZ ******************** */ + +namespace blender::nodes { + +static void cmp_node_combine_xyz_declare(NodeDeclarationBuilder &b) +{ + b.add_input<decl::Float>("X").min(-10000.0f).max(10000.0f); + b.add_input<decl::Float>("Y").min(-10000.0f).max(10000.0f); + b.add_input<decl::Float>("Z").min(-10000.0f).max(10000.0f); + b.add_output<decl::Vector>("Vector"); +} + +} // namespace blender::nodes + +void register_node_type_cmp_combine_xyz() +{ + static bNodeType ntype; + + cmp_node_type_base(&ntype, CMP_NODE_COMBINE_XYZ, "Combine XYZ", NODE_CLASS_CONVERTER); + ntype.declare = blender::nodes::cmp_node_combine_xyz_declare; + + nodeRegisterType(&ntype); +} diff --git a/source/blender/nodes/function/CMakeLists.txt b/source/blender/nodes/function/CMakeLists.txt index 0c3c6a34995..6418c525776 100644 --- a/source/blender/nodes/function/CMakeLists.txt +++ b/source/blender/nodes/function/CMakeLists.txt @@ -63,10 +63,6 @@ set(LIB bf_functions ) -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() - blender_add_lib(bf_nodes_function "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") if(WITH_UNITY_BUILD) diff --git a/source/blender/nodes/geometry/CMakeLists.txt b/source/blender/nodes/geometry/CMakeLists.txt index b4add633b0c..2a8faf65a6d 100644 --- a/source/blender/nodes/geometry/CMakeLists.txt +++ b/source/blender/nodes/geometry/CMakeLists.txt @@ -239,10 +239,6 @@ if(WITH_PYTHON) add_definitions(-DWITH_PYTHON) endif() -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() - if(WITH_TBB) list(APPEND INC_SYS ${TBB_INCLUDE_DIRS} diff --git a/source/blender/nodes/shader/CMakeLists.txt b/source/blender/nodes/shader/CMakeLists.txt index c8eb0b8d570..598b0c81b51 100644 --- a/source/blender/nodes/shader/CMakeLists.txt +++ b/source/blender/nodes/shader/CMakeLists.txt @@ -158,10 +158,6 @@ if(WITH_PYTHON) add_definitions(-DWITH_PYTHON) endif() -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() - if(WITH_FREESTYLE) add_definitions(-DWITH_FREESTYLE) endif() diff --git a/source/blender/nodes/texture/CMakeLists.txt b/source/blender/nodes/texture/CMakeLists.txt index 053b17e4e57..e595343b7d2 100644 --- a/source/blender/nodes/texture/CMakeLists.txt +++ b/source/blender/nodes/texture/CMakeLists.txt @@ -82,8 +82,5 @@ if(WITH_PYTHON) add_definitions(-DWITH_PYTHON) endif() -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() blender_add_lib(bf_nodes_texture "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/render/CMakeLists.txt b/source/blender/render/CMakeLists.txt index a7c1b12982c..a49fc21d7ff 100644 --- a/source/blender/render/CMakeLists.txt +++ b/source/blender/render/CMakeLists.txt @@ -95,9 +95,5 @@ if(WITH_FREESTYLE) add_definitions(-DWITH_FREESTYLE) endif() -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() - blender_add_lib_nolist(bf_render "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/render/RE_texture.h b/source/blender/render/RE_texture.h index c6ccc547ff4..4d58d866e9f 100644 --- a/source/blender/render/RE_texture.h +++ b/source/blender/render/RE_texture.h @@ -103,7 +103,7 @@ void RE_point_density_fix_linking(void); typedef struct TexResult { float tin; float trgba[4]; - /* Is acually a bool true->use alpha, false->set alpha to 1.0. */ + /* Is actually a boolean: When true -> use alpha, false -> set alpha to 1.0. */ int talpha; float *nor; } TexResult; diff --git a/source/blender/render/intern/texture_margin.cc b/source/blender/render/intern/texture_margin.cc index 5a9d9db5367..b864aa64709 100644 --- a/source/blender/render/intern/texture_margin.cc +++ b/source/blender/render/intern/texture_margin.cc @@ -48,16 +48,17 @@ namespace blender::render::texturemargin { -/* The map class contains both a pixel map which maps out polygon indices for all UV-polygons and +/** + * The map class contains both a pixel map which maps out polygon indices for all UV-polygons and * adjacency tables. */ class TextureMarginMap { static const int directions[8][2]; static const int distances[8]; - /* Maps UV-edges to their corresponding UV-edge. */ + /** Maps UV-edges to their corresponding UV-edge. */ Vector<int> loop_adjacency_map_; - /* Maps UV-edges to their corresponding polygon. */ + /** Maps UV-edges to their corresponding polygon. */ Vector<int> loop_to_poly_map_; int w_, h_; @@ -132,9 +133,7 @@ class TextureMarginMap { static void zscan_store_pixel( void *map, int x, int y, [[maybe_unused]] float u, [[maybe_unused]] float v) { - /* NOTE: Not thread safe, see comment above. - * - */ + /* NOTE: Not thread safe, see comment above. */ TextureMarginMap *m = static_cast<TextureMarginMap *>(map); m->set_pixel(x, y, m->value_to_store_); if (m->mask_) { @@ -153,7 +152,8 @@ class TextureMarginMap { #define IsDijkstraPixel(dp) ((dp)&0x80000000) #define DijkstraPixelIsUnset(dp) ((dp) == 0xFFFFFFFF) - /* Use dijkstra's algorithm to 'grow' a border around the polygons marked in the map. + /** + * Use dijkstra's algorithm to 'grow' a border around the polygons marked in the map. * For each pixel mark which direction is the shortest way to a polygon. */ void grow_dijkstra(int margin) @@ -188,8 +188,10 @@ class TextureMarginMap { } } - // std::make_heap(active_pixels.begin(), active_pixels.end(), cmp_dijkstrapixel_fun); - // Not strictly needed because at this point it already is a heap. + /* Not strictly needed because at this point it already is a heap. */ +#if 0 + std::make_heap(active_pixels.begin(), active_pixels.end(), cmp_dijkstrapixel_fun); +#endif while (active_pixels.size()) { std::pop_heap(active_pixels.begin(), active_pixels.end(), cmp_dijkstrapixel_fun); @@ -215,7 +217,8 @@ class TextureMarginMap { } } - /* Walk over the map and for margin pixels follow the direction stored in the bottom 3 + /** + * Walk over the map and for margin pixels follow the direction stored in the bottom 3 * bits back to the polygon. * Then look up the pixel from the next polygon. */ @@ -324,10 +327,12 @@ class TextureMarginMap { } } - /* Call lookup_pixel for the start_poly. If that fails, try the adjacent polygons as well. - * Because the Dijkstra is not vey exact in determining which polygon is the closest, the + /** + * Call lookup_pixel for the start_poly. If that fails, try the adjacent polygons as well. + * Because the Dijkstra is not very exact in determining which polygon is the closest, the * polygon we need can be the one next to the one the Dijkstra map provides. To prevent missing - * pixels also check the neighbouring polygons. */ + * pixels also check the neighboring polygons. + */ bool lookup_pixel_polygon_neighbourhood( float x, float y, uint32_t *r_start_poly, float *r_destx, float *r_desty, int *r_other_poly) { @@ -344,8 +349,8 @@ class TextureMarginMap { float mindist = -1.f; - /* Loop over all adjacent polyons and determine which edge is closest. - * This could be optimized by only inspecting neigbours which are on the edge of an island. + /* Loop over all adjacent polygons and determine which edge is closest. + * This could be optimized by only inspecting neighbors which are on the edge of an island. * But it seems fast enough for now and that would add a lot of complexity. */ for (int i = 0; i < totloop; i++) { int otherloop = loop_adjacency_map_[i + loopstart]; @@ -370,10 +375,12 @@ class TextureMarginMap { return mindist >= 0.f; } - /* Find which edge of the src_poly is closest to x,y. Look up it's adjacent UV-edge and polygon. + /** + * Find which edge of the src_poly is closest to x,y. Look up it's adjacent UV-edge and polygon. * Then return the location of the equivalent pixel in the other polygon. * Returns true if a new pixel location was found, false if it wasn't, which can happen if the - * margin pixel is on a corner, or the UV-edge doesn't have an adjacent polygon. */ + * margin pixel is on a corner, or the UV-edge doesn't have an adjacent polygon. + */ bool lookup_pixel(float x, float y, int src_poly, @@ -568,7 +575,9 @@ static void generate_margin(ImBuf *ibuf, vec[a][1] = uv[1] * (float)ibuf->y - (0.5f + 0.002f); } - BLI_assert(lt->poly < 0x80000000); // NOTE: we need the top bit for the dijkstra distance map + /* NOTE: we need the top bit for the dijkstra distance map. */ + BLI_assert(lt->poly < 0x80000000); + map.rasterize_tri(vec[0], vec[1], vec[2], lt->poly, draw_new_mask ? mask : nullptr); } diff --git a/source/blender/sequencer/intern/strip_add.c b/source/blender/sequencer/intern/strip_add.c index be29dcfcd0c..dd8966acfd8 100644 --- a/source/blender/sequencer/intern/strip_add.c +++ b/source/blender/sequencer/intern/strip_add.c @@ -297,7 +297,7 @@ static void seq_add_sound_av_sync(Main *bmain, Scene *scene, Sequence *seq, SeqL const double av_stream_offset = sound_stream.start - load_data->r_video_stream_start; const int frame_offset = av_stream_offset * FPS; - /* Set subframe offset. */ + /* Set sub-frame offset. */ seq->sound->offset_time = ((double)frame_offset / FPS) - av_stream_offset; SEQ_transform_translate_sequence(scene, seq, frame_offset); } diff --git a/source/blender/shader_fx/CMakeLists.txt b/source/blender/shader_fx/CMakeLists.txt index 0167591c3ba..ae78d9964e5 100644 --- a/source/blender/shader_fx/CMakeLists.txt +++ b/source/blender/shader_fx/CMakeLists.txt @@ -63,9 +63,5 @@ set(SRC set(LIB ) -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() - blender_add_lib(bf_shader_fx "${SRC}" "${INC}" "${INC_SYS}" "${LIB}") diff --git a/source/blender/windowmanager/CMakeLists.txt b/source/blender/windowmanager/CMakeLists.txt index 03b2fb49085..37b233d85d2 100644 --- a/source/blender/windowmanager/CMakeLists.txt +++ b/source/blender/windowmanager/CMakeLists.txt @@ -135,10 +135,6 @@ if(WITH_CYCLES) add_definitions(-DWITH_CYCLES) endif() -if(WITH_INTERNATIONAL) - add_definitions(-DWITH_INTERNATIONAL) -endif() - if(WITH_OPENCOLLADA) add_definitions(-DWITH_COLLADA) endif() diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index d1f790ce3e2..929b39715b9 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -1048,6 +1048,10 @@ typedef struct wmDragActiveDropState { * it as needed. */ struct ARegion *region_from; + /** If `active_dropbox` is set, additional context provided by the active (i.e. hovered) button. + * Activated before context sensitive operations (polling, drawing, dropping). */ + struct bContextStore *ui_context; + /** Text to show when a dropbox poll succeeds (so the dropbox itself is available) but the * operator poll fails. Typically the message the operator set with * CTX_wm_operator_poll_msg_set(). */ diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c index 6f10e4f3f0d..2a93e279576 100644 --- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c +++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_group.c @@ -706,7 +706,7 @@ wmKeyMap *WM_gizmogroup_setup_keymap_generic_maybe_drag(const wmGizmoGroupType * /** * Variation of #WM_gizmogroup_keymap_common but with keymap items for selection * - * TODO(campbell): move to Python. + * TODO(@campbellbarton): move to Python. * * \param name: Typically #wmGizmoGroupType.name * \param params: Typically #wmGizmoGroupType.gzmap_params @@ -719,7 +719,7 @@ static wmKeyMap *WM_gizmogroup_keymap_template_select_ex( wmKeyMap *km = WM_keymap_ensure(kc, name, params->spaceid, params->regionid); const bool do_init = BLI_listbase_is_empty(&km->items); - /* FIXME(campbell) */ + /* FIXME(@campbellbarton): Currently hard coded. */ #if 0 const int select_mouse = (U.flag & USER_LMOUSESELECT) ? LEFTMOUSE : RIGHTMOUSE; const int select_tweak = (U.flag & USER_LMOUSESELECT) ? EVT_TWEAK_L : EVT_TWEAK_R; diff --git a/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c b/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c index e61de28d0a4..ed38b4a154c 100644 --- a/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c +++ b/source/blender/windowmanager/gizmo/intern/wm_gizmo_map.c @@ -572,7 +572,7 @@ static int gizmo_find_intersected_3d_intern(wmGizmo **visible_gizmos, Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C); rcti rect; /* Almost certainly overkill, but allow for many custom gizmos. */ - uint buffer[MAXPICKBUF]; + GPUSelectResult buffer[MAXPICKELEMS]; short hits; BLI_rcti_init_pt_radius(&rect, co, hotspot); @@ -582,19 +582,19 @@ static int gizmo_find_intersected_3d_intern(wmGizmo **visible_gizmos, * - #GPU_SELECT_ALL: Use it to check if there is anything at the cursor location * (only ever runs once). * - #GPU_SELECT_PICK_NEAREST: Use if there are more than 1 item at the cursor location, - * select the best one. + * pick the nearest one. * - #GPU_SELECT_PICK_ALL: Use for the same purpose as #GPU_SELECT_PICK_NEAREST * when the selection depths need to re-ordered based on a bias. * */ - const int gpu_select_mode = (use_depth_test ? - (has_3d_select_bias ? - /* Using select bias means the depths need to be - * re-calculated based on the bias to pick the best. */ - GPU_SELECT_PICK_ALL : - /* No bias, just pick the closest. */ - GPU_SELECT_PICK_NEAREST) : - /* Fast-path (occlusion queries). */ - GPU_SELECT_ALL); + const eGPUSelectMode gpu_select_mode = + (use_depth_test ? (has_3d_select_bias ? + /* Using select bias means the depths need to be + * re-calculated based on the bias to pick the best. */ + GPU_SELECT_PICK_ALL : + /* No bias, just pick the closest. */ + GPU_SELECT_PICK_NEAREST) : + /* Fast-path (occlusion queries). */ + GPU_SELECT_ALL); if (GPU_select_is_cached()) { GPU_select_begin(buffer, ARRAY_SIZE(buffer), &rect, gpu_select_mode, 0); @@ -650,14 +650,14 @@ static int gizmo_find_intersected_3d_intern(wmGizmo **visible_gizmos, GPU_matrix_unproject_3fv(co_screen, rv3d->viewinv, rv3d->winmat, viewport, co_3d_origin); - uint *buf_iter = buffer; + GPUSelectResult *buf_iter = buffer; float dot_best = FLT_MAX; - for (int i = 0; i < hits; i++, buf_iter += 4) { - BLI_assert(buf_iter[3] != -1); - wmGizmo *gz = visible_gizmos[buf_iter[3] >> 8]; + for (int i = 0; i < hits; i++, buf_iter++) { + BLI_assert(buf_iter->id != -1); + wmGizmo *gz = visible_gizmos[buf_iter->id >> 8]; float co_3d[3]; - co_screen[2] = int_as_float(buf_iter[1]); + co_screen[2] = int_as_float(buf_iter->depth); GPU_matrix_unproject_3fv(co_screen, rv3d->viewinv, rv3d->winmat, viewport, co_3d); float select_bias = gz->select_bias; if ((gz->flag & WM_GIZMO_DRAW_NO_SCALE) == 0) { @@ -667,14 +667,14 @@ static int gizmo_find_intersected_3d_intern(wmGizmo **visible_gizmos, const float dot_test = dot_v3v3(co_3d, co_direction) - select_bias; if (dot_best > dot_test) { dot_best = dot_test; - hit_found = buf_iter[3]; + hit_found = buf_iter->id; } } } else { - const uint *hit_near = GPU_select_buffer_near(buffer, hits); + const GPUSelectResult *hit_near = GPU_select_buffer_near(buffer, hits); if (hit_near) { - hit_found = hit_near[3]; + hit_found = hit_near->id; } } diff --git a/source/blender/windowmanager/intern/wm_dragdrop.c b/source/blender/windowmanager/intern/wm_dragdrop.c index 96cb66b44ea..3bc77db45ca 100644 --- a/source/blender/windowmanager/intern/wm_dragdrop.c +++ b/source/blender/windowmanager/intern/wm_dragdrop.c @@ -226,6 +226,30 @@ void wm_drags_exit(wmWindowManager *wm, wmWindow *win) } } +static bContextStore *wm_drop_ui_context_create(const bContext *C) +{ + uiBut *active_but = UI_region_active_but_get(CTX_wm_region(C)); + if (!active_but) { + return NULL; + } + + bContextStore *but_context = UI_but_context_get(active_but); + if (!but_context) { + return NULL; + } + + return CTX_store_copy(but_context); +} + +static void wm_drop_ui_context_free(bContextStore **context_store) +{ + if (!*context_store) { + return; + } + CTX_store_free(*context_store); + *context_store = NULL; +} + void WM_event_drag_image(wmDrag *drag, ImBuf *imb, float scale, int sx, int sy) { drag->imb = imb; @@ -259,6 +283,7 @@ void WM_drag_free(wmDrag *drag) if (drag->flags & WM_DRAG_FREE_DATA) { WM_drag_data_free(drag->type, drag->poin); } + wm_drop_ui_context_free(&drag->drop_state.ui_context); if (drag->drop_state.free_disabled_info) { MEM_SAFE_FREE(drag->drop_state.disabled_info); } @@ -317,6 +342,10 @@ static wmDropBox *dropbox_active(bContext *C, } const wmOperatorCallContext opcontext = wm_drop_operator_context_get(drop); + if (drag->drop_state.ui_context) { + CTX_store_set(C, drag->drop_state.ui_context); + } + if (WM_operator_poll_context(C, drop->ot, opcontext)) { return drop; } @@ -367,6 +396,10 @@ static void wm_drop_update_active(bContext *C, wmDrag *drag, const wmEvent *even return; } + /* Update UI context, before polling so polls can query this context. */ + wm_drop_ui_context_free(&drag->drop_state.ui_context); + drag->drop_state.ui_context = wm_drop_ui_context_create(C); + wmDropBox *drop_prev = drag->drop_state.active_dropbox; wmDropBox *drop = wm_dropbox_active(C, drag, event); if (drop != drop_prev) { @@ -381,11 +414,20 @@ static void wm_drop_update_active(bContext *C, wmDrag *drag, const wmEvent *even drag->drop_state.area_from = drop ? CTX_wm_area(C) : NULL; drag->drop_state.region_from = drop ? CTX_wm_region(C) : NULL; } + + if (!drag->drop_state.active_dropbox) { + wm_drop_ui_context_free(&drag->drop_state.ui_context); + } } void wm_drop_prepare(bContext *C, wmDrag *drag, wmDropBox *drop) { const wmOperatorCallContext opcontext = wm_drop_operator_context_get(drop); + + if (drag->drop_state.ui_context) { + CTX_store_set(C, drag->drop_state.ui_context); + } + /* Optionally copy drag information to operator properties. Don't call it if the * operator fails anyway, it might do more than just set properties (e.g. * typically import an asset). */ @@ -396,6 +438,11 @@ void wm_drop_prepare(bContext *C, wmDrag *drag, wmDropBox *drop) wm_drags_exit(CTX_wm_manager(C), CTX_wm_window(C)); } +void wm_drop_end(bContext *C, wmDrag *UNUSED(drag), wmDropBox *UNUSED(drop)) +{ + CTX_store_set(C, NULL); +} + void wm_drags_check_ops(bContext *C, const wmEvent *event) { wmWindowManager *wm = CTX_wm_manager(C); @@ -897,6 +944,7 @@ void wm_drags_draw(bContext *C, wmWindow *win) if (drag->drop_state.active_dropbox) { CTX_wm_area_set(C, drag->drop_state.area_from); CTX_wm_region_set(C, drag->drop_state.region_from); + CTX_store_set(C, drag->drop_state.ui_context); /* Drawing should be allowed to assume the context from handling and polling (that's why we * restore it above). */ @@ -915,4 +963,5 @@ void wm_drags_draw(bContext *C, wmWindow *win) GPU_blend(GPU_BLEND_NONE); CTX_wm_area_set(C, NULL); CTX_wm_region_set(C, NULL); + CTX_store_set(C, NULL); } diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 9d2c97e151f..88920432f66 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -1081,7 +1081,7 @@ static int wm_operator_exec(bContext *C, wmOperator *op, const bool repeat, cons } } - /* XXX(mont29) Disabled the repeat check to address part 2 of T31840. + /* XXX(@mont29): Disabled the repeat check to address part 2 of T31840. * Carefully checked all calls to wm_operator_exec and WM_operator_repeat, don't see any reason * why this was needed, but worth to note it in case something turns bad. */ if (retval & (OPERATOR_FINISHED | OPERATOR_CANCELLED) /* && repeat == 0 */) { @@ -3076,6 +3076,8 @@ static int wm_handlers_do_intern(bContext *C, wmWindow *win, wmEvent *event, Lis event->customdata = NULL; event->custom = 0; + wm_drop_end(C, drag, drop); + /* XXX fileread case. */ if (CTX_wm_window(C) == NULL) { return action; diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 1478712c3cd..723c572c4da 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -874,18 +874,16 @@ static void file_read_reports_finalize(BlendFileReadReport *bf_reports) duration_lib_override_recursive_resync_seconds); } - if (bf_reports->count.linked_proxies != 0 || - bf_reports->count.proxies_to_lib_overrides_success != 0 || + if (bf_reports->count.proxies_to_lib_overrides_success != 0 || bf_reports->count.proxies_to_lib_overrides_failures != 0) { - BKE_reportf(bf_reports->reports, - RPT_WARNING, - "Proxies are deprecated (%d proxies were automatically converted to library " - "overrides, %d proxies could not be converted and %d linked proxies were kept " - "untouched). If you need to keep proxies for the time being, please disable the " - "`Proxy to Override Auto Conversion` in Experimental user preferences", - bf_reports->count.proxies_to_lib_overrides_success, - bf_reports->count.proxies_to_lib_overrides_failures, - bf_reports->count.linked_proxies); + BKE_reportf( + bf_reports->reports, + RPT_WARNING, + "Proxies have been removed from Blender (%d proxies were automatically converted " + "to library overrides, %d proxies could not be converted and were cleared). " + "Please also consider re-saving any library .blend file with the newest Blender version.", + bf_reports->count.proxies_to_lib_overrides_success, + bf_reports->count.proxies_to_lib_overrides_failures); } if (bf_reports->count.sequence_strips_skipped != 0) { diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index 6caac79c4d5..1d26c58bcf9 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -594,9 +594,7 @@ void WM_exit_ex(bContext *C, const bool do_python) DRW_opengl_context_destroy(); } -#ifdef WITH_INTERNATIONAL BLT_lang_free(); -#endif ANIM_keyingset_infos_exit(); diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index a1854a8ed86..a7b5b9bddda 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -1483,7 +1483,11 @@ static bool wm_window_timer(const bContext *C) wt->delta = time - wt->ltime; wt->duration += wt->delta; wt->ltime = time; - wt->ntime = wt->stime + wt->timestep * ceil(wt->duration / wt->timestep); + + wt->ntime = wt->stime; + if (wt->timestep != 0.0f) { + wt->ntime += wt->timestep * ceil(wt->duration / wt->timestep); + } if (wt->event_type == TIMERJOBS) { wm_jobs_timer(wm, wt); @@ -1596,6 +1600,7 @@ void WM_event_timer_sleep(wmWindowManager *wm, wmTimer *WM_event_add_timer(wmWindowManager *wm, wmWindow *win, int event_type, double timestep) { wmTimer *wt = MEM_callocN(sizeof(wmTimer), "window timer"); + BLI_assert(timestep >= 0.0f); wt->event_type = event_type; wt->ltime = PIL_check_seconds_timer(); @@ -1615,6 +1620,7 @@ wmTimer *WM_event_add_timer_notifier(wmWindowManager *wm, double timestep) { wmTimer *wt = MEM_callocN(sizeof(wmTimer), "window timer"); + BLI_assert(timestep >= 0.0f); wt->event_type = TIMERNOTIFIER; wt->ltime = PIL_check_seconds_timer(); diff --git a/source/blender/windowmanager/wm_event_system.h b/source/blender/windowmanager/wm_event_system.h index 925be8ab183..252ff228bc1 100644 --- a/source/blender/windowmanager/wm_event_system.h +++ b/source/blender/windowmanager/wm_event_system.h @@ -199,6 +199,7 @@ void wm_dropbox_free(void); */ void wm_drags_exit(wmWindowManager *wm, wmWindow *win); void wm_drop_prepare(bContext *C, wmDrag *drag, wmDropBox *drop); +void wm_drop_end(bContext *C, wmDrag *drag, wmDropBox *drop); /** * Called in inner handler loop, region context. */ diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h index a6685e97c4f..6fcaad92661 100644 --- a/source/blender/windowmanager/wm_event_types.h +++ b/source/blender/windowmanager/wm_event_types.h @@ -60,7 +60,7 @@ enum { /* ********** Start of Input devices. ********** */ - /* MOUSE : 0x000x, 0x001x */ + /* MOUSE: 0x000x, 0x001x */ LEFTMOUSE = 0x0001, MIDDLEMOUSE = 0x0002, RIGHTMOUSE = 0x0003, @@ -71,7 +71,7 @@ enum { /* More mouse buttons - can't use 9 and 10 here (wheel) */ BUTTON6MOUSE = 0x0012, BUTTON7MOUSE = 0x0013, - /* Extra trackpad gestures */ + /* Extra track-pad gestures. */ MOUSEPAN = 0x000e, MOUSEZOOM = 0x000f, MOUSEROTATE = 0x0010, diff --git a/tests/python/bl_keymap_validate.py b/tests/python/bl_keymap_validate.py index ebc35c1178c..705a026e441 100644 --- a/tests/python/bl_keymap_validate.py +++ b/tests/python/bl_keymap_validate.py @@ -162,7 +162,7 @@ def keymap_data_clean(keyconfig_data: typing.List, *, relaxed: bool) -> None: item_prop.pop("properties") # Needed so: `{"properties": ()}` matches `None` as there is no meaningful difference. - # Wruting `None` makes the most sense when explicitly written, however generated properties + # Writing `None` makes the most sense when explicitly written, however generated properties # might be empty and it's not worth adding checks in the generation logic to use `None` # just to satisfy this check. if not item_prop: |