Geometry Nodes: new Bake node #115466
@ -53,15 +53,11 @@ endif()
|
||||
# quiet output for Makefiles, 'make -s' helps too
|
||||
# set_property(GLOBAL PROPERTY RULE_MESSAGES OFF)
|
||||
|
||||
# global compile definitions since add_definitions() adds for all.
|
||||
# Global compile definitions since add_definitions() adds for all.
|
||||
# _DEBUG is a Visual Studio define, enabled for all platforms.
|
||||
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS
|
||||
$<$<CONFIG:Debug>:DEBUG;_DEBUG>
|
||||
$<$<CONFIG:Release>:NDEBUG>
|
||||
$<$<CONFIG:MinSizeRel>:NDEBUG>
|
||||
$<$<CONFIG:RelWithDebInfo>:NDEBUG>
|
||||
$<$<CONFIG:Debug>:_DEBUG>
|
||||
)
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Set policy
|
||||
|
||||
@ -99,7 +95,6 @@ endif()
|
||||
|
||||
include(build_files/cmake/macros.cmake)
|
||||
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
# Initialize Project
|
||||
|
||||
@ -733,6 +728,9 @@ mark_as_advanced(WITH_CXX_GUARDEDALLOC)
|
||||
option(WITH_ASSERT_ABORT "Call abort() when raising an assertion through BLI_assert()" ON)
|
||||
mark_as_advanced(WITH_ASSERT_ABORT)
|
||||
|
||||
option(WITH_ASSERT_RELEASE "Build with asserts enabled even for non-debug configurations" OFF)
|
||||
mark_as_advanced(WITH_ASSERT_RELEASE)
|
||||
|
||||
if((UNIX AND NOT APPLE) OR (CMAKE_GENERATOR MATCHES "^Visual Studio.+"))
|
||||
option(WITH_CLANG_TIDY "\
|
||||
Use Clang Tidy to analyze the source code \
|
||||
@ -2165,6 +2163,20 @@ if(WITH_ASSERT_ABORT)
|
||||
add_definitions(-DWITH_ASSERT_ABORT)
|
||||
endif()
|
||||
|
||||
# NDEBUG is the standard C define to disable asserts.
|
||||
if(WITH_ASSERT_RELEASE)
|
||||
# CMake seemingly be setting the NDEBUG flag on its own already on some configurations
|
||||
# therefore we need to remove the flags if they happen to be set.
|
||||
remove_cc_flag("-DNDEBUG") # GCC/CLang
|
||||
remove_cc_flag("/DNDEBUG") # MSVC
|
||||
else()
|
||||
set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS
|
||||
$<$<CONFIG:Release>:NDEBUG>
|
||||
$<$<CONFIG:MinSizeRel>:NDEBUG>
|
||||
$<$<CONFIG:RelWithDebInfo>:NDEBUG>
|
||||
)
|
||||
endif()
|
||||
|
||||
# message(STATUS "Using CFLAGS: ${CMAKE_C_FLAGS}")
|
||||
# message(STATUS "Using CXXFLAGS: ${CMAKE_CXX_FLAGS}")
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
#
|
||||
|
||||
set(WITH_ASSERT_ABORT ON CACHE BOOL "" FORCE)
|
||||
set(WITH_ASSERT_RELEASE ON CACHE BOOL "" FORCE)
|
||||
set(WITH_BUILDINFO OFF CACHE BOOL "" FORCE)
|
||||
# Sadly ASAN is more often broken than working with MSVC do not enable it in the
|
||||
# developer profile for now.
|
||||
|
@ -1311,7 +1311,7 @@ int curve_fit_cubic_to_points_refit_db(
|
||||
#ifdef USE_CORNER_DETECT
|
||||
if (use_corner) {
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifndef NDEBUG
|
||||
for (uint i = 0; i < knots_len; i++) {
|
||||
assert(knots[i].heap_node == NULL);
|
||||
}
|
||||
|
10
extern/rangetree/intern/range_tree.c
vendored
10
extern/rangetree/intern/range_tree.c
vendored
@ -206,7 +206,7 @@ static void rt_node_free(RangeTreeUInt *rt, Node *node);
|
||||
|
||||
#ifdef USE_BTREE
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifndef NDEBUG
|
||||
static bool rb_is_balanced_root(const Node *root);
|
||||
#endif
|
||||
|
||||
@ -238,7 +238,7 @@ static int key_cmp(uint key1, uint key2)
|
||||
/* removed from the tree */
|
||||
static void rb_node_invalidate(Node *node)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
#ifndef NDEBUG
|
||||
node->left = NULL;
|
||||
node->right = NULL;
|
||||
node->color = false;
|
||||
@ -481,7 +481,7 @@ static Node *rb_get_or_lower_recursive(Node *n, const uint key)
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifndef NDEBUG
|
||||
|
||||
static bool rb_is_balanced_recursive(const Node *node, int black)
|
||||
{
|
||||
@ -511,7 +511,7 @@ static bool rb_is_balanced_root(const Node *root)
|
||||
return rb_is_balanced_recursive(root, black);
|
||||
}
|
||||
|
||||
#endif // DEBUG
|
||||
#endif // NDEBUG
|
||||
|
||||
|
||||
/* End BTree API */
|
||||
@ -703,7 +703,7 @@ RangeTreeUInt *range_tree_uint_alloc(uint min, uint max)
|
||||
|
||||
void range_tree_uint_free(RangeTreeUInt *rt)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
#ifndef NDEBUG
|
||||
#ifdef USE_BTREE
|
||||
assert(rb_is_balanced_root(rt->root));
|
||||
#endif
|
||||
|
@ -259,7 +259,7 @@ string HIPDevice::compile_kernel(const uint kernel_features, const char *name, c
|
||||
# else
|
||||
options.append("Wno-parentheses-equality -Wno-unused-value --hipcc-func-supp -O3 -ffast-math");
|
||||
# endif
|
||||
# ifdef _DEBUG
|
||||
# ifndef NDEBUG
|
||||
options.append(" -save-temps");
|
||||
# endif
|
||||
options.append(" --amdgpu-target=").append(arch);
|
||||
|
@ -4,6 +4,10 @@
|
||||
|
||||
#ifdef WITH_ONEAPI
|
||||
|
||||
/* <algorithm> is needed until included upstream in sycl/detail/property_list_base.hpp */
|
||||
# include <algorithm>
|
||||
# include <sycl/sycl.hpp>
|
||||
|
||||
# include "device/oneapi/device_impl.h"
|
||||
|
||||
# include "util/debug.h"
|
||||
@ -25,6 +29,9 @@ extern "C" bool rtcIsSYCLDeviceSupported(const sycl::device sycl_device);
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
static std::vector<sycl::device> available_sycl_devices();
|
||||
static int parse_driver_build_version(const sycl::device &device);
|
||||
|
||||
static void queue_error_cb(const char *message, void *user_ptr)
|
||||
{
|
||||
if (user_ptr) {
|
||||
@ -545,7 +552,7 @@ void OneapiDevice::usm_free(void *usm_ptr)
|
||||
|
||||
void OneapiDevice::check_usm(SyclQueue *queue_, const void *usm_ptr, bool allow_host = false)
|
||||
{
|
||||
# ifdef _DEBUG
|
||||
# ifndef NDEBUG
|
||||
sycl::queue *queue = reinterpret_cast<sycl::queue *>(queue_);
|
||||
sycl::info::device_type device_type =
|
||||
queue->get_device().get_info<sycl::info::device::device_type>();
|
||||
@ -574,7 +581,7 @@ bool OneapiDevice::create_queue(SyclQueue *&external_queue,
|
||||
{
|
||||
bool finished_correct = true;
|
||||
try {
|
||||
std::vector<sycl::device> devices = OneapiDevice::available_devices();
|
||||
std::vector<sycl::device> devices = available_sycl_devices();
|
||||
if (device_index < 0 || device_index >= devices.size()) {
|
||||
return false;
|
||||
}
|
||||
@ -862,7 +869,7 @@ static const int lowest_supported_driver_version_neo = 26957;
|
||||
static const int lowest_supported_driver_version_neo = 26918;
|
||||
# endif
|
||||
|
||||
int OneapiDevice::parse_driver_build_version(const sycl::device &device)
|
||||
int parse_driver_build_version(const sycl::device &device)
|
||||
{
|
||||
const std::string &driver_version = device.get_info<sycl::info::device::driver_version>();
|
||||
int driver_build_version = 0;
|
||||
@ -901,7 +908,7 @@ int OneapiDevice::parse_driver_build_version(const sycl::device &device)
|
||||
return driver_build_version;
|
||||
}
|
||||
|
||||
std::vector<sycl::device> OneapiDevice::available_devices()
|
||||
std::vector<sycl::device> available_sycl_devices()
|
||||
{
|
||||
bool allow_all_devices = false;
|
||||
if (getenv("CYCLES_ONEAPI_ALL_DEVICES") != nullptr) {
|
||||
@ -971,7 +978,7 @@ char *OneapiDevice::device_capabilities()
|
||||
{
|
||||
std::stringstream capabilities;
|
||||
|
||||
const std::vector<sycl::device> &oneapi_devices = available_devices();
|
||||
const std::vector<sycl::device> &oneapi_devices = available_sycl_devices();
|
||||
for (const sycl::device &device : oneapi_devices) {
|
||||
# ifndef WITH_ONEAPI_SYCL_HOST_TASK
|
||||
const std::string &name = device.get_info<sycl::info::device::name>();
|
||||
@ -1080,7 +1087,7 @@ char *OneapiDevice::device_capabilities()
|
||||
void OneapiDevice::iterate_devices(OneAPIDeviceIteratorCallback cb, void *user_ptr)
|
||||
{
|
||||
int num = 0;
|
||||
std::vector<sycl::device> devices = OneapiDevice::available_devices();
|
||||
std::vector<sycl::device> devices = available_sycl_devices();
|
||||
for (sycl::device &device : devices) {
|
||||
const std::string &platform_name =
|
||||
device.get_platform().get_info<sycl::info::platform::name>();
|
||||
|
@ -3,11 +3,6 @@
|
||||
* SPDX-License-Identifier: Apache-2.0 */
|
||||
|
||||
#ifdef WITH_ONEAPI
|
||||
|
||||
/* <algorithm> is needed until included upstream in sycl/detail/property_list_base.hpp */
|
||||
# include <algorithm>
|
||||
# include <sycl/sycl.hpp>
|
||||
|
||||
# include "device/device.h"
|
||||
# include "device/oneapi/device.h"
|
||||
# include "device/oneapi/queue.h"
|
||||
@ -106,9 +101,7 @@ class OneapiDevice : public Device {
|
||||
void *usm_aligned_alloc_host(size_t memory_size, size_t alignment);
|
||||
void usm_free(void *usm_ptr);
|
||||
|
||||
static std::vector<sycl::device> available_devices();
|
||||
static char *device_capabilities();
|
||||
static int parse_driver_build_version(const sycl::device &device);
|
||||
static void iterate_devices(OneAPIDeviceIteratorCallback cb, void *user_ptr);
|
||||
|
||||
size_t get_memcapacity();
|
||||
|
@ -9,6 +9,7 @@
|
||||
# include <array>
|
||||
|
||||
# include "device/device.h"
|
||||
# include "device/oneapi/device_impl.h"
|
||||
# include "device/queue.h"
|
||||
# include "integrator/pass_accessor_cpu.h"
|
||||
# include "session/buffers.h"
|
||||
@ -27,13 +28,10 @@
|
||||
|
||||
CCL_NAMESPACE_BEGIN
|
||||
|
||||
/* Ideally, this would be dynamic and adaptively change when the runtime runs out of memory. */
|
||||
constexpr int prefilter_max_mem = 1024;
|
||||
|
||||
thread_mutex OIDNDenoiserGPU::mutex_;
|
||||
bool OIDNDenoiserGPU::is_device_type_supported(const DeviceType &type)
|
||||
bool OIDNDenoiserGPU::is_device_supported(const DeviceInfo &device)
|
||||
{
|
||||
switch (type) {
|
||||
/* Currently falls back to checking just the device type, can be improved. */
|
||||
switch (device.type) {
|
||||
# ifdef OIDN_DEVICE_SYCL
|
||||
/* Assume all devices with Cycles support are also supported by OIDN2. */
|
||||
case DEVICE_ONEAPI:
|
||||
@ -44,12 +42,6 @@ bool OIDNDenoiserGPU::is_device_type_supported(const DeviceType &type)
|
||||
}
|
||||
}
|
||||
|
||||
bool OIDNDenoiserGPU::is_device_supported(const DeviceInfo &device)
|
||||
{
|
||||
/* Currently falls back to checking just the device type, can be improved. */
|
||||
return is_device_type_supported(device.type);
|
||||
}
|
||||
|
||||
OIDNDenoiserGPU::OIDNDenoiserGPU(Device *path_trace_device, const DenoiseParams ¶ms)
|
||||
: DenoiserGPU(path_trace_device, params)
|
||||
{
|
||||
@ -123,9 +115,11 @@ bool OIDNDenoiserGPU::denoise_create_if_needed(DenoiseContext &context)
|
||||
}
|
||||
|
||||
switch (denoiser_device_->info.type) {
|
||||
# if defined(OIDN_DEVICE_SYCL)
|
||||
# if defined(OIDN_DEVICE_SYCL) && defined(WITH_ONEAPI)
|
||||
case DEVICE_ONEAPI:
|
||||
oidn_device_ = oidnNewDevice(OIDN_DEVICE_TYPE_SYCL);
|
||||
oidn_device_ = oidnNewSYCLDevice(
|
||||
(const sycl::queue *)reinterpret_cast<OneapiDevice *>(denoiser_device_)->sycl_queue(),
|
||||
1);
|
||||
denoiser_queue_->init_execution();
|
||||
break;
|
||||
# endif
|
||||
@ -156,7 +150,6 @@ bool OIDNDenoiserGPU::denoise_create_if_needed(DenoiseContext &context)
|
||||
if (context.use_pass_albedo) {
|
||||
albedo_filter_ = create_filter();
|
||||
if (albedo_filter_ == nullptr) {
|
||||
oidnSetFilterInt(oidn_filter_, "maxMemoryMB", prefilter_max_mem);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -164,7 +157,6 @@ bool OIDNDenoiserGPU::denoise_create_if_needed(DenoiseContext &context)
|
||||
if (context.use_pass_normal) {
|
||||
normal_filter_ = create_filter();
|
||||
if (normal_filter_ == nullptr) {
|
||||
oidnSetFilterInt(oidn_filter_, "maxMemoryMB", prefilter_max_mem);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -34,15 +34,10 @@ class OIDNDenoiserGPU : public DenoiserGPU {
|
||||
bool allow_inplace_modification) override;
|
||||
|
||||
static bool is_device_supported(const DeviceInfo &device);
|
||||
static bool is_device_type_supported(const DeviceType &type);
|
||||
|
||||
protected:
|
||||
virtual uint get_device_type_mask() const override;
|
||||
|
||||
/* We only perform one denoising at a time, since OpenImageDenoise itself is multithreaded.
|
||||
* Use this mutex whenever images are passed to the OIDN and needs to be denoised. */
|
||||
static thread_mutex mutex_;
|
||||
|
||||
/* Create OIDN denoiser descriptor if needed.
|
||||
* Will do nothing if the current OIDN descriptor is usable for the given parameters.
|
||||
* If the OIDN denoiser descriptor did re-allocate here it is left unconfigured. */
|
||||
|
@ -14,7 +14,8 @@
|
||||
# pragma GCC diagnostic ignored "-Wlogical-op"
|
||||
#endif
|
||||
|
||||
#ifdef __EIGEN3_MATRIX_C_API_CC__ /* quiet warning */
|
||||
#ifdef __EIGEN3_MATRIX_C_API_CC__
|
||||
/* Quiet warning. */
|
||||
#endif
|
||||
|
||||
#include <Eigen/Core>
|
||||
|
@ -14,7 +14,8 @@
|
||||
# pragma GCC diagnostic ignored "-Wlogical-op"
|
||||
#endif
|
||||
|
||||
#ifdef __EIGEN3_SVD_C_API_CC__ /* quiet warning */
|
||||
#ifdef __EIGEN3_SVD_C_API_CC__
|
||||
/* Quiet warning. */
|
||||
#endif
|
||||
|
||||
#include <Eigen/Core>
|
||||
|
@ -580,8 +580,8 @@ extern GHOST_ContextHandle GHOST_GetDrawingContext(GHOST_WindowHandle windowhand
|
||||
extern void GHOST_SetTitle(GHOST_WindowHandle windowhandle, const char *title);
|
||||
|
||||
/**
|
||||
* Returns the title displayed in the title bar. The title
|
||||
* should be free'd with free().
|
||||
* Returns the title displayed in the title bar.
|
||||
* The title must be freed with free().
|
||||
*
|
||||
* \param windowhandle: The handle to the window.
|
||||
* \return The title, free with free().
|
||||
|
@ -316,7 +316,7 @@ typedef enum {
|
||||
} GHOST_TEventType;
|
||||
|
||||
typedef enum {
|
||||
GHOST_kStandardCursorFirstCursor = 0,
|
||||
#define GHOST_kStandardCursorFirstCursor int(GHOST_kStandardCursorDefault)
|
||||
GHOST_kStandardCursorDefault = 0,
|
||||
GHOST_kStandardCursorRightArrow,
|
||||
GHOST_kStandardCursorLeftArrow,
|
||||
@ -357,7 +357,7 @@ typedef enum {
|
||||
GHOST_kStandardCursorCopy,
|
||||
GHOST_kStandardCursorCustom,
|
||||
|
||||
GHOST_kStandardCursorNumCursors
|
||||
#define GHOST_kStandardCursorNumCursors (int(GHOST_kStandardCursorCustom) + 1)
|
||||
} GHOST_TStandardCursor;
|
||||
|
||||
typedef enum {
|
||||
|
@ -10,7 +10,7 @@
|
||||
#pragma once
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# ifdef DEBUG
|
||||
# ifdef _DEBUG
|
||||
/* Suppress STL-MSVC debug info warning. */
|
||||
# pragma warning(disable : 4786)
|
||||
# endif
|
||||
|
@ -159,7 +159,7 @@ GHOST_TSuccess GHOST_DisplayManagerX11::setCurrentDisplaySetting(
|
||||
fprintf(stderr, "Error: XF86VidMode extension missing!\n");
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
# ifdef DEBUG
|
||||
# ifndef NDEBUG
|
||||
printf("Using XFree86-VidModeExtension Version %d.%d\n", majorVersion, minorVersion);
|
||||
# endif
|
||||
|
||||
@ -199,7 +199,7 @@ GHOST_TSuccess GHOST_DisplayManagerX11::setCurrentDisplaySetting(
|
||||
}
|
||||
|
||||
if (best_fit != -1) {
|
||||
# ifdef DEBUG
|
||||
# ifndef NDEBUG
|
||||
printf("Switching to video mode %dx%d %dx%d %d\n",
|
||||
vidmodes[best_fit]->hdisplay,
|
||||
vidmodes[best_fit]->vdisplay,
|
||||
|
@ -61,13 +61,6 @@ GHOST_TSuccess GHOST_System::putClipboardImage(uint * /*rgba*/,
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
|
||||
uint64_t GHOST_System::getMilliSeconds() const
|
||||
{
|
||||
return std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
std::chrono::steady_clock::now().time_since_epoch())
|
||||
.count();
|
||||
}
|
||||
|
||||
GHOST_ITimerTask *GHOST_System::installTimer(uint64_t delay,
|
||||
uint64_t interval,
|
||||
GHOST_TimerProcPtr timerProc,
|
||||
|
@ -54,14 +54,6 @@ class GHOST_System : public GHOST_ISystem {
|
||||
* Time(r) functionality
|
||||
***************************************************************************************/
|
||||
|
||||
/**
|
||||
* Returns the system time.
|
||||
* Returns the number of milliseconds since the start of the system process.
|
||||
* Based on ANSI clock() routine.
|
||||
* \return The number of milliseconds.
|
||||
*/
|
||||
virtual uint64_t getMilliSeconds() const;
|
||||
|
||||
/**
|
||||
* Installs a timer.
|
||||
*
|
||||
|
@ -454,7 +454,8 @@ void GHOST_SystemSDL::processEvent(SDL_Event *sdl_event)
|
||||
|
||||
switch (sdl_event->type) {
|
||||
case SDL_WINDOWEVENT: {
|
||||
SDL_WindowEvent &sdl_sub_evt = sdl_event->window;
|
||||
const SDL_WindowEvent &sdl_sub_evt = sdl_event->window;
|
||||
const uint64_t event_ms = sdl_sub_evt.timestamp;
|
||||
GHOST_WindowSDL *window = findGhostWindow(
|
||||
SDL_GetWindowFromID_fallback(sdl_sub_evt.windowID));
|
||||
/* Can be nullptr on close window. */
|
||||
@ -464,22 +465,22 @@ void GHOST_SystemSDL::processEvent(SDL_Event *sdl_event)
|
||||
|
||||
switch (sdl_sub_evt.event) {
|
||||
case SDL_WINDOWEVENT_EXPOSED:
|
||||
g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowUpdate, window);
|
||||
g_event = new GHOST_Event(event_ms, GHOST_kEventWindowUpdate, window);
|
||||
break;
|
||||
case SDL_WINDOWEVENT_RESIZED:
|
||||
g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window);
|
||||
g_event = new GHOST_Event(event_ms, GHOST_kEventWindowSize, window);
|
||||
break;
|
||||
case SDL_WINDOWEVENT_MOVED:
|
||||
g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowMove, window);
|
||||
g_event = new GHOST_Event(event_ms, GHOST_kEventWindowMove, window);
|
||||
break;
|
||||
case SDL_WINDOWEVENT_FOCUS_GAINED:
|
||||
g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowActivate, window);
|
||||
g_event = new GHOST_Event(event_ms, GHOST_kEventWindowActivate, window);
|
||||
break;
|
||||
case SDL_WINDOWEVENT_FOCUS_LOST:
|
||||
g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowDeactivate, window);
|
||||
g_event = new GHOST_Event(event_ms, GHOST_kEventWindowDeactivate, window);
|
||||
break;
|
||||
case SDL_WINDOWEVENT_CLOSE:
|
||||
g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowClose, window);
|
||||
g_event = new GHOST_Event(event_ms, GHOST_kEventWindowClose, window);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -487,13 +488,16 @@ void GHOST_SystemSDL::processEvent(SDL_Event *sdl_event)
|
||||
}
|
||||
|
||||
case SDL_QUIT: {
|
||||
const SDL_QuitEvent &sdl_sub_evt = sdl_event->quit;
|
||||
const uint64_t event_ms = sdl_sub_evt.timestamp;
|
||||
GHOST_IWindow *window = m_windowManager->getActiveWindow();
|
||||
g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventQuitRequest, window);
|
||||
g_event = new GHOST_Event(event_ms, GHOST_kEventQuitRequest, window);
|
||||
break;
|
||||
}
|
||||
|
||||
case SDL_MOUSEMOTION: {
|
||||
SDL_MouseMotionEvent &sdl_sub_evt = sdl_event->motion;
|
||||
const SDL_MouseMotionEvent &sdl_sub_evt = sdl_event->motion;
|
||||
const uint64_t event_ms = sdl_sub_evt.timestamp;
|
||||
SDL_Window *sdl_win = SDL_GetWindowFromID_fallback(sdl_sub_evt.windowID);
|
||||
GHOST_WindowSDL *window = findGhostWindow(sdl_win);
|
||||
assert(window != nullptr);
|
||||
@ -535,7 +539,7 @@ void GHOST_SystemSDL::processEvent(SDL_Event *sdl_event)
|
||||
SDL_WarpMouseInWindow(sdl_win, x_new - x_win, y_new - y_win);
|
||||
}
|
||||
|
||||
g_event = new GHOST_EventCursor(getMilliSeconds(),
|
||||
g_event = new GHOST_EventCursor(event_ms,
|
||||
GHOST_kEventCursorMove,
|
||||
window,
|
||||
x_new,
|
||||
@ -543,7 +547,7 @@ void GHOST_SystemSDL::processEvent(SDL_Event *sdl_event)
|
||||
GHOST_TABLET_DATA_NONE);
|
||||
}
|
||||
else {
|
||||
g_event = new GHOST_EventCursor(getMilliSeconds(),
|
||||
g_event = new GHOST_EventCursor(event_ms,
|
||||
GHOST_kEventCursorMove,
|
||||
window,
|
||||
x_root + x_accum,
|
||||
@ -554,18 +558,15 @@ void GHOST_SystemSDL::processEvent(SDL_Event *sdl_event)
|
||||
else
|
||||
#endif
|
||||
{
|
||||
g_event = new GHOST_EventCursor(getMilliSeconds(),
|
||||
GHOST_kEventCursorMove,
|
||||
window,
|
||||
x_root,
|
||||
y_root,
|
||||
GHOST_TABLET_DATA_NONE);
|
||||
g_event = new GHOST_EventCursor(
|
||||
event_ms, GHOST_kEventCursorMove, window, x_root, y_root, GHOST_TABLET_DATA_NONE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
case SDL_MOUSEBUTTONDOWN: {
|
||||
SDL_MouseButtonEvent &sdl_sub_evt = sdl_event->button;
|
||||
const SDL_MouseButtonEvent &sdl_sub_evt = sdl_event->button;
|
||||
const uint64_t event_ms = sdl_sub_evt.timestamp;
|
||||
GHOST_TButton gbmask = GHOST_kButtonMaskLeft;
|
||||
GHOST_TEventType type = (sdl_sub_evt.state == SDL_PRESSED) ? GHOST_kEventButtonDown :
|
||||
GHOST_kEventButtonUp;
|
||||
@ -595,21 +596,22 @@ void GHOST_SystemSDL::processEvent(SDL_Event *sdl_event)
|
||||
break;
|
||||
}
|
||||
|
||||
g_event = new GHOST_EventButton(
|
||||
getMilliSeconds(), type, window, gbmask, GHOST_TABLET_DATA_NONE);
|
||||
g_event = new GHOST_EventButton(event_ms, type, window, gbmask, GHOST_TABLET_DATA_NONE);
|
||||
break;
|
||||
}
|
||||
case SDL_MOUSEWHEEL: {
|
||||
SDL_MouseWheelEvent &sdl_sub_evt = sdl_event->wheel;
|
||||
const SDL_MouseWheelEvent &sdl_sub_evt = sdl_event->wheel;
|
||||
const uint64_t event_ms = sdl_sub_evt.timestamp;
|
||||
GHOST_WindowSDL *window = findGhostWindow(
|
||||
SDL_GetWindowFromID_fallback(sdl_sub_evt.windowID));
|
||||
assert(window != nullptr);
|
||||
g_event = new GHOST_EventWheel(getMilliSeconds(), window, sdl_sub_evt.y);
|
||||
g_event = new GHOST_EventWheel(event_ms, window, sdl_sub_evt.y);
|
||||
break;
|
||||
}
|
||||
case SDL_KEYDOWN:
|
||||
case SDL_KEYUP: {
|
||||
SDL_KeyboardEvent &sdl_sub_evt = sdl_event->key;
|
||||
const SDL_KeyboardEvent &sdl_sub_evt = sdl_event->key;
|
||||
const uint64_t event_ms = sdl_sub_evt.timestamp;
|
||||
GHOST_TEventType type = (sdl_sub_evt.state == SDL_PRESSED) ? GHOST_kEventKeyDown :
|
||||
GHOST_kEventKeyUp;
|
||||
const bool is_repeat = sdl_sub_evt.repeat != 0;
|
||||
@ -629,7 +631,7 @@ void GHOST_SystemSDL::processEvent(SDL_Event *sdl_event)
|
||||
utf8_buf[0] = convert_keyboard_event_to_ascii(sdl_sub_evt);
|
||||
}
|
||||
|
||||
g_event = new GHOST_EventKey(getMilliSeconds(), type, window, gkey, is_repeat, utf8_buf);
|
||||
g_event = new GHOST_EventKey(event_ms, type, window, gkey, is_repeat, utf8_buf);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -670,7 +672,9 @@ bool GHOST_SystemSDL::generateWindowExposeEvents()
|
||||
bool anyProcessed = false;
|
||||
|
||||
for (; w_start != w_end; ++w_start) {
|
||||
GHOST_Event *g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowUpdate, *w_start);
|
||||
/* The caller doesn't have a time-stamp. */
|
||||
const uint64_t event_ms = getMilliSeconds();
|
||||
GHOST_Event *g_event = new GHOST_Event(event_ms, GHOST_kEventWindowUpdate, *w_start);
|
||||
|
||||
(*w_start)->validate();
|
||||
|
||||
|
@ -394,7 +394,7 @@ struct GWL_Cursor {
|
||||
wl_cursor_image image = {0};
|
||||
wl_cursor_theme *theme = nullptr;
|
||||
/** Only set when the cursor is from the theme (it may be animated). */
|
||||
wl_cursor *theme_cursor = nullptr;
|
||||
const wl_cursor *theme_cursor = nullptr;
|
||||
/** Needed so changing the theme scale can reload 'theme_cursor' at a new scale. */
|
||||
const char *theme_cursor_name = nullptr;
|
||||
} wl;
|
||||
@ -1203,7 +1203,14 @@ struct GWL_RegistryEntry;
|
||||
* see: #GHOST_SystemWayland::milliseconds_from_input_time.
|
||||
*/
|
||||
struct GWL_DisplayTimeStamp {
|
||||
uint64_t last = 0;
|
||||
/**
|
||||
* When true, the GHOST & WAYLAND time-stamps are compatible,
|
||||
* in most cases this means they will be equal however for systems with long up-times
|
||||
* it may equal `uint32(GHOST_SystemWayland::getMilliSeconds())`,
|
||||
* the `offsets` member is set to account for this case.
|
||||
*/
|
||||
bool exact_match = false;
|
||||
uint32_t last = 0;
|
||||
uint64_t offset = 0;
|
||||
};
|
||||
|
||||
@ -1936,47 +1943,64 @@ static GHOST_TTabletMode tablet_tool_map_type(enum zwp_tablet_tool_v2_type wp_ta
|
||||
|
||||
static const int default_cursor_size = 24;
|
||||
|
||||
static const std::unordered_map<GHOST_TStandardCursor, const char *> ghost_wl_cursors = {
|
||||
{GHOST_kStandardCursorDefault, "left_ptr"},
|
||||
{GHOST_kStandardCursorRightArrow, "right_ptr"},
|
||||
{GHOST_kStandardCursorLeftArrow, "left_ptr"},
|
||||
{GHOST_kStandardCursorInfo, ""},
|
||||
{GHOST_kStandardCursorDestroy, "pirate"},
|
||||
{GHOST_kStandardCursorHelp, "question_arrow"},
|
||||
{GHOST_kStandardCursorWait, "watch"},
|
||||
{GHOST_kStandardCursorText, "xterm"},
|
||||
{GHOST_kStandardCursorCrosshair, "crosshair"},
|
||||
{GHOST_kStandardCursorCrosshairA, ""},
|
||||
{GHOST_kStandardCursorCrosshairB, ""},
|
||||
{GHOST_kStandardCursorCrosshairC, ""},
|
||||
{GHOST_kStandardCursorPencil, "pencil"},
|
||||
{GHOST_kStandardCursorUpArrow, "sb_up_arrow"},
|
||||
{GHOST_kStandardCursorDownArrow, "sb_down_arrow"},
|
||||
{GHOST_kStandardCursorVerticalSplit, "split_v"},
|
||||
{GHOST_kStandardCursorHorizontalSplit, "split_h"},
|
||||
{GHOST_kStandardCursorEraser, ""},
|
||||
{GHOST_kStandardCursorKnife, ""},
|
||||
{GHOST_kStandardCursorEyedropper, "color-picker"},
|
||||
{GHOST_kStandardCursorZoomIn, "zoom-in"},
|
||||
{GHOST_kStandardCursorZoomOut, "zoom-out"},
|
||||
{GHOST_kStandardCursorMove, "move"},
|
||||
{GHOST_kStandardCursorNSEWScroll, "size_all"}, /* Not an exact match. */
|
||||
{GHOST_kStandardCursorNSScroll, "size_ver"}, /* Not an exact match. */
|
||||
{GHOST_kStandardCursorEWScroll, "size_hor"}, /* Not an exact match. */
|
||||
{GHOST_kStandardCursorStop, "not-allowed"},
|
||||
{GHOST_kStandardCursorUpDown, "sb_v_double_arrow"},
|
||||
{GHOST_kStandardCursorLeftRight, "sb_h_double_arrow"},
|
||||
{GHOST_kStandardCursorTopSide, "top_side"},
|
||||
{GHOST_kStandardCursorBottomSide, "bottom_side"},
|
||||
{GHOST_kStandardCursorLeftSide, "left_side"},
|
||||
{GHOST_kStandardCursorRightSide, "right_side"},
|
||||
{GHOST_kStandardCursorTopLeftCorner, "top_left_corner"},
|
||||
{GHOST_kStandardCursorTopRightCorner, "top_right_corner"},
|
||||
{GHOST_kStandardCursorBottomRightCorner, "bottom_right_corner"},
|
||||
{GHOST_kStandardCursorBottomLeftCorner, "bottom_left_corner"},
|
||||
{GHOST_kStandardCursorCopy, "copy"},
|
||||
struct GWL_Cursor_ShapeInfo {
|
||||
const char *names[GHOST_kStandardCursorNumCursors] = {0};
|
||||
};
|
||||
|
||||
static const GWL_Cursor_ShapeInfo ghost_wl_cursors = []() -> GWL_Cursor_ShapeInfo {
|
||||
GWL_Cursor_ShapeInfo info{};
|
||||
|
||||
#define CASE_CURSOR(shape_id, shape_name_in_theme) \
|
||||
case shape_id: \
|
||||
info.names[int(shape_id)] = shape_name_in_theme;
|
||||
|
||||
/* Use a switch to ensure missing values show a compiler warning. */
|
||||
switch (GHOST_kStandardCursorDefault) {
|
||||
CASE_CURSOR(GHOST_kStandardCursorDefault, "left_ptr");
|
||||
CASE_CURSOR(GHOST_kStandardCursorRightArrow, "right_ptr");
|
||||
CASE_CURSOR(GHOST_kStandardCursorLeftArrow, "left_ptr");
|
||||
CASE_CURSOR(GHOST_kStandardCursorInfo, "left_ptr_help");
|
||||
CASE_CURSOR(GHOST_kStandardCursorDestroy, "pirate");
|
||||
CASE_CURSOR(GHOST_kStandardCursorHelp, "question_arrow");
|
||||
CASE_CURSOR(GHOST_kStandardCursorWait, "watch");
|
||||
CASE_CURSOR(GHOST_kStandardCursorText, "xterm");
|
||||
CASE_CURSOR(GHOST_kStandardCursorCrosshair, "crosshair");
|
||||
CASE_CURSOR(GHOST_kStandardCursorCrosshairA, "");
|
||||
CASE_CURSOR(GHOST_kStandardCursorCrosshairB, "");
|
||||
CASE_CURSOR(GHOST_kStandardCursorCrosshairC, "");
|
||||
CASE_CURSOR(GHOST_kStandardCursorPencil, "pencil");
|
||||
CASE_CURSOR(GHOST_kStandardCursorUpArrow, "sb_up_arrow");
|
||||
CASE_CURSOR(GHOST_kStandardCursorDownArrow, "sb_down_arrow");
|
||||
CASE_CURSOR(GHOST_kStandardCursorVerticalSplit, "split_v");
|
||||
CASE_CURSOR(GHOST_kStandardCursorHorizontalSplit, "split_h");
|
||||
CASE_CURSOR(GHOST_kStandardCursorEraser, "");
|
||||
CASE_CURSOR(GHOST_kStandardCursorKnife, "");
|
||||
CASE_CURSOR(GHOST_kStandardCursorEyedropper, "color-picker");
|
||||
CASE_CURSOR(GHOST_kStandardCursorZoomIn, "zoom-in");
|
||||
CASE_CURSOR(GHOST_kStandardCursorZoomOut, "zoom-out");
|
||||
CASE_CURSOR(GHOST_kStandardCursorMove, "move");
|
||||
CASE_CURSOR(GHOST_kStandardCursorNSEWScroll, "all-scroll");
|
||||
CASE_CURSOR(GHOST_kStandardCursorNSScroll, "size_ver");
|
||||
CASE_CURSOR(GHOST_kStandardCursorEWScroll, "size_hor");
|
||||
CASE_CURSOR(GHOST_kStandardCursorStop, "not-allowed");
|
||||
CASE_CURSOR(GHOST_kStandardCursorUpDown, "sb_v_double_arrow");
|
||||
CASE_CURSOR(GHOST_kStandardCursorLeftRight, "sb_h_double_arrow");
|
||||
CASE_CURSOR(GHOST_kStandardCursorTopSide, "top_side");
|
||||
CASE_CURSOR(GHOST_kStandardCursorBottomSide, "bottom_side");
|
||||
CASE_CURSOR(GHOST_kStandardCursorLeftSide, "left_side");
|
||||
CASE_CURSOR(GHOST_kStandardCursorRightSide, "right_side");
|
||||
CASE_CURSOR(GHOST_kStandardCursorTopLeftCorner, "top_left_corner");
|
||||
CASE_CURSOR(GHOST_kStandardCursorTopRightCorner, "top_right_corner");
|
||||
CASE_CURSOR(GHOST_kStandardCursorBottomRightCorner, "bottom_right_corner");
|
||||
CASE_CURSOR(GHOST_kStandardCursorBottomLeftCorner, "bottom_left_corner");
|
||||
CASE_CURSOR(GHOST_kStandardCursorCopy, "copy");
|
||||
CASE_CURSOR(GHOST_kStandardCursorCustom, "");
|
||||
}
|
||||
#undef CASE_CURSOR
|
||||
|
||||
return info;
|
||||
}();
|
||||
|
||||
static constexpr const char *ghost_wl_mime_text_plain = "text/plain";
|
||||
static constexpr const char *ghost_wl_mime_text_utf8 = "text/plain;charset=utf-8";
|
||||
static constexpr const char *ghost_wl_mime_text_uri = "text/uri-list";
|
||||
@ -6956,6 +6980,14 @@ uint8_t GHOST_SystemWayland::getNumDisplays() const
|
||||
return display_ ? uint8_t(display_->outputs.size()) : 0;
|
||||
}
|
||||
|
||||
uint64_t GHOST_SystemWayland::getMilliSeconds() const
|
||||
{
|
||||
/* Match the timing method used by LIBINPUT, so the result is closer to WAYLAND's time-stamps. */
|
||||
struct timespec ts = {0, 0};
|
||||
clock_gettime(CLOCK_MONOTONIC, &ts);
|
||||
return ((uint64_t(ts.tv_sec) * 1000) + (ts.tv_nsec / 1000000));
|
||||
}
|
||||
|
||||
static GHOST_TSuccess getCursorPositionClientRelative_impl(
|
||||
const GWL_SeatStatePointer *seat_state_pointer,
|
||||
const GHOST_WindowWayland *win,
|
||||
@ -7530,7 +7562,7 @@ static void cursor_anim_begin(GWL_Seat *seat)
|
||||
auto cursor_anim_frame_step_fn =
|
||||
[](GWL_Seat *seat, GWL_Cursor_AnimHandle *anim_handle, int delay) {
|
||||
/* It's possible the `wl_cursor` is reloaded while the cursor is animating.
|
||||
* Don't access outside the lock, tha's why the `delay` is passed in. */
|
||||
* Don't access outside the lock, that's why the `delay` is passed in. */
|
||||
std::mutex *server_mutex = seat->system->server_mutex;
|
||||
int frame = 0;
|
||||
while (!anim_handle->exit_pending.load()) {
|
||||
@ -7538,7 +7570,7 @@ static void cursor_anim_begin(GWL_Seat *seat)
|
||||
if (!anim_handle->exit_pending.load()) {
|
||||
std::lock_guard lock_server_guard{*server_mutex};
|
||||
if (!anim_handle->exit_pending.load()) {
|
||||
struct wl_cursor *wl_cursor = seat->cursor.wl.theme_cursor;
|
||||
const struct wl_cursor *wl_cursor = seat->cursor.wl.theme_cursor;
|
||||
frame = (frame + 1) % wl_cursor->image_count;
|
||||
wl_cursor_image *image = wl_cursor->images[frame];
|
||||
wl_buffer *buffer = wl_cursor_image_get_buffer(image);
|
||||
@ -7586,6 +7618,36 @@ static void cursor_anim_reset(GWL_Seat *seat)
|
||||
cursor_anim_begin_if_needed(seat);
|
||||
}
|
||||
|
||||
static const wl_cursor *cursor_find_from_shape(GWL_Seat *seat,
|
||||
const GHOST_TStandardCursor shape,
|
||||
const char **r_cursor_name)
|
||||
{
|
||||
/* Caller must lock `server_mutex`. */
|
||||
GWL_Cursor *cursor = &seat->cursor;
|
||||
wl_cursor *wl_cursor = nullptr;
|
||||
|
||||
const char *cursor_name = ghost_wl_cursors.names[shape];
|
||||
if (cursor_name[0] != '\0') {
|
||||
if (!cursor->wl.theme) {
|
||||
/* The cursor wl_surface hasn't entered an output yet. Initialize theme with scale 1. */
|
||||
cursor->wl.theme = wl_cursor_theme_load(
|
||||
cursor->theme_name.c_str(), cursor->theme_size, seat->system->wl_shm_get());
|
||||
}
|
||||
|
||||
if (cursor->wl.theme) {
|
||||
wl_cursor = wl_cursor_theme_get_cursor(cursor->wl.theme, cursor_name);
|
||||
if (!wl_cursor) {
|
||||
GHOST_PRINT("cursor '" << cursor_name << "' does not exist" << std::endl);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (r_cursor_name && wl_cursor) {
|
||||
*r_cursor_name = cursor_name;
|
||||
}
|
||||
return wl_cursor;
|
||||
}
|
||||
|
||||
GHOST_TSuccess GHOST_SystemWayland::cursor_shape_set(const GHOST_TStandardCursor shape)
|
||||
{
|
||||
/* Caller must lock `server_mutex`. */
|
||||
@ -7594,26 +7656,14 @@ GHOST_TSuccess GHOST_SystemWayland::cursor_shape_set(const GHOST_TStandardCursor
|
||||
if (UNLIKELY(!seat)) {
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
auto cursor_find = ghost_wl_cursors.find(shape);
|
||||
const char *cursor_name = (cursor_find == ghost_wl_cursors.end()) ?
|
||||
ghost_wl_cursors.at(GHOST_kStandardCursorDefault) :
|
||||
(*cursor_find).second;
|
||||
|
||||
GWL_Cursor *cursor = &seat->cursor;
|
||||
|
||||
if (!cursor->wl.theme) {
|
||||
/* The cursor wl_surface hasn't entered an output yet. Initialize theme with scale 1. */
|
||||
cursor->wl.theme = wl_cursor_theme_load(
|
||||
cursor->theme_name.c_str(), cursor->theme_size, wl_shm_get());
|
||||
}
|
||||
|
||||
wl_cursor *wl_cursor = wl_cursor_theme_get_cursor(cursor->wl.theme, cursor_name);
|
||||
|
||||
if (!wl_cursor) {
|
||||
GHOST_PRINT("cursor '" << cursor_name << "' does not exist" << std::endl);
|
||||
const char *cursor_name = nullptr;
|
||||
const wl_cursor *wl_cursor = cursor_find_from_shape(seat, shape, &cursor_name);
|
||||
if (wl_cursor == nullptr) {
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
|
||||
GWL_Cursor *cursor = &seat->cursor;
|
||||
wl_cursor_image *image = wl_cursor->images[0];
|
||||
wl_buffer *buffer = wl_cursor_image_get_buffer(image);
|
||||
if (!buffer) {
|
||||
@ -7635,12 +7685,9 @@ GHOST_TSuccess GHOST_SystemWayland::cursor_shape_set(const GHOST_TStandardCursor
|
||||
GHOST_TSuccess GHOST_SystemWayland::cursor_shape_check(const GHOST_TStandardCursor cursorShape)
|
||||
{
|
||||
/* No need to lock `server_mutex`. */
|
||||
auto cursor_find = ghost_wl_cursors.find(cursorShape);
|
||||
if (cursor_find == ghost_wl_cursors.end()) {
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
const char *value = (*cursor_find).second;
|
||||
if (*value == '\0') {
|
||||
GWL_Seat *seat = gwl_display_seat_active_get(display_);
|
||||
const wl_cursor *wl_cursor = cursor_find_from_shape(seat, cursorShape, nullptr);
|
||||
if (wl_cursor == nullptr) {
|
||||
return GHOST_kFailure;
|
||||
}
|
||||
return GHOST_kSuccess;
|
||||
@ -8147,15 +8194,28 @@ uint64_t GHOST_SystemWayland::ms_from_input_time(const uint32_t timestamp_as_uin
|
||||
* This is updated because time may have passed between generating the time-stamp and `now`.
|
||||
* The method here is used by SDL. */
|
||||
|
||||
const uint64_t now = getMilliSeconds();
|
||||
GWL_DisplayTimeStamp &input_timestamp = display_->input_timestamp;
|
||||
uint64_t timestamp = uint64_t(timestamp_as_uint);
|
||||
if (timestamp < input_timestamp.last) {
|
||||
if (timestamp_as_uint < input_timestamp.last) {
|
||||
/* 32-bit timer rollover, bump the offset. */
|
||||
input_timestamp.offset += uint64_t(std::numeric_limits<uint32_t>::max()) + 1;
|
||||
}
|
||||
input_timestamp.last = timestamp;
|
||||
input_timestamp.last = timestamp_as_uint;
|
||||
|
||||
uint64_t timestamp = uint64_t(timestamp_as_uint);
|
||||
if (input_timestamp.exact_match) {
|
||||
timestamp += input_timestamp.offset;
|
||||
}
|
||||
else {
|
||||
const uint64_t now = getMilliSeconds();
|
||||
const uint32_t now_as_uint32 = uint32_t(now);
|
||||
if (now_as_uint32 == timestamp_as_uint) {
|
||||
input_timestamp.exact_match = true;
|
||||
/* For systems with up times exceeding 47 days
|
||||
* it's possible we need to begin with an offset. */
|
||||
input_timestamp.offset = now - uint64_t(now_as_uint32);
|
||||
timestamp = now;
|
||||
}
|
||||
else {
|
||||
if (!input_timestamp.offset) {
|
||||
input_timestamp.offset = (now - timestamp);
|
||||
}
|
||||
@ -8165,6 +8225,8 @@ uint64_t GHOST_SystemWayland::ms_from_input_time(const uint32_t timestamp_as_uin
|
||||
input_timestamp.offset -= (timestamp - now);
|
||||
timestamp = now;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return timestamp;
|
||||
}
|
||||
|
@ -154,6 +154,8 @@ class GHOST_SystemWayland : public GHOST_System {
|
||||
|
||||
uint8_t getNumDisplays() const override;
|
||||
|
||||
uint64_t getMilliSeconds() const override;
|
||||
|
||||
GHOST_TSuccess getCursorPositionClientRelative(const GHOST_IWindow *window,
|
||||
int32_t &x,
|
||||
int32_t &y) const override;
|
||||
|
@ -107,6 +107,7 @@ GHOST_SystemX11::GHOST_SystemX11()
|
||||
: GHOST_System(),
|
||||
m_xkb_descr(nullptr),
|
||||
m_start_time(0),
|
||||
m_start_time_monotonic(0),
|
||||
m_keyboard_vector{0},
|
||||
m_keycode_last_repeat_key(uint(-1))
|
||||
{
|
||||
@ -172,14 +173,23 @@ GHOST_SystemX11::GHOST_SystemX11()
|
||||
m_last_release_keycode = 0;
|
||||
m_last_release_time = 0;
|
||||
|
||||
/* compute the initial time */
|
||||
/* Compute the initial times. */
|
||||
{
|
||||
timeval tv;
|
||||
if (gettimeofday(&tv, nullptr) == -1) {
|
||||
if (gettimeofday(&tv, nullptr) != 0) {
|
||||
GHOST_ASSERT(false, "Could not instantiate timer!");
|
||||
}
|
||||
|
||||
/* Taking care not to overflow the `tv.tv_sec * 1000`. */
|
||||
m_start_time = uint64_t(tv.tv_sec) * 1000 + tv.tv_usec / 1000;
|
||||
}
|
||||
|
||||
{
|
||||
struct timespec ts = {0, 0};
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
|
||||
GHOST_ASSERT(false, "Could not instantiate monotonic timer!");
|
||||
}
|
||||
m_start_time_monotonic = ((uint64_t(ts.tv_sec) * 1000) + (ts.tv_nsec / 1000000));
|
||||
}
|
||||
|
||||
/* Use detectable auto-repeat, mac and windows also do this. */
|
||||
int use_xkb;
|
||||
@ -203,7 +213,7 @@ GHOST_SystemX11::GHOST_SystemX11()
|
||||
#endif
|
||||
|
||||
#ifdef WITH_X11_XINPUT
|
||||
/* detect if we have xinput (for reuse) */
|
||||
/* Detect if we have XINPUT (for reuse). */
|
||||
{
|
||||
memset(&m_xinput_version, 0, sizeof(m_xinput_version));
|
||||
XExtensionVersion *version = XGetExtensionVersion(m_display, INAME);
|
||||
@ -271,7 +281,7 @@ GHOST_TSuccess GHOST_SystemX11::init()
|
||||
uint64_t GHOST_SystemX11::getMilliSeconds() const
|
||||
{
|
||||
timeval tv;
|
||||
if (gettimeofday(&tv, nullptr) == -1) {
|
||||
if (gettimeofday(&tv, nullptr) != 0) {
|
||||
GHOST_ASSERT(false, "Could not compute time!");
|
||||
}
|
||||
|
||||
@ -279,6 +289,17 @@ uint64_t GHOST_SystemX11::getMilliSeconds() const
|
||||
return uint64_t(tv.tv_sec) * 1000 + tv.tv_usec / 1000 - m_start_time;
|
||||
}
|
||||
|
||||
uint64_t GHOST_SystemX11::ms_from_input_time(const Time timestamp) const
|
||||
{
|
||||
GHOST_ASSERT(timestamp >= m_start_time_monotonic, "Invalid time-stemp");
|
||||
/* NOTE(@ideasman42): Return a time compatible with `getMilliSeconds()`,
|
||||
* this is needed as X11 time-stamps use monotonic time.
|
||||
* The X11 implementation *could* use any basis, in practice though we are supporting
|
||||
* XORG/LIBINPUT which uses time-stamps based on the monotonic time,
|
||||
* Needed to resolve failure to detect double-clicking, see: #40009. */
|
||||
return uint64_t(timestamp) - m_start_time_monotonic;
|
||||
}
|
||||
|
||||
uint8_t GHOST_SystemX11::getNumDisplays() const
|
||||
{
|
||||
return uint8_t(1);
|
||||
@ -637,6 +658,7 @@ bool GHOST_SystemX11::processEvents(bool waitForEvent)
|
||||
XPeekEvent(m_display, &xev_next);
|
||||
|
||||
if (ELEM(xev_next.type, KeyPress, KeyRelease)) {
|
||||
const uint64_t event_ms = ms_from_input_time(xev_next.xkey.time);
|
||||
/* XK_Hyper_L/R currently unused. */
|
||||
const static KeySym modifiers[] = {
|
||||
XK_Shift_L,
|
||||
@ -652,7 +674,7 @@ bool GHOST_SystemX11::processEvents(bool waitForEvent)
|
||||
for (int i = 0; i < int(ARRAY_SIZE(modifiers)); i++) {
|
||||
KeyCode kc = XKeysymToKeycode(m_display, modifiers[i]);
|
||||
if (kc != 0 && ((xevent.xkeymap.key_vector[kc >> 3] >> (kc & 7)) & 1) != 0) {
|
||||
pushEvent(new GHOST_EventKey(getMilliSeconds(),
|
||||
pushEvent(new GHOST_EventKey(event_ms,
|
||||
GHOST_kEventKeyDown,
|
||||
window,
|
||||
ghost_key_from_keysym(modifiers[i]),
|
||||
@ -850,16 +872,19 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
|
||||
const XExposeEvent &xee = xe->xexpose;
|
||||
|
||||
if (xee.count == 0) {
|
||||
/* Only generate a single expose event
|
||||
* per read of the event queue. */
|
||||
/* Only generate a single expose event per read of the event queue. */
|
||||
|
||||
g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowUpdate, window);
|
||||
/* Event has no timestamp. */
|
||||
const uint64_t event_ms = getMilliSeconds();
|
||||
|
||||
g_event = new GHOST_Event(event_ms, GHOST_kEventWindowUpdate, window);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case MotionNotify: {
|
||||
const XMotionEvent &xme = xe->xmotion;
|
||||
const uint64_t event_ms = ms_from_input_time(xme.time);
|
||||
|
||||
bool is_tablet = window->GetTabletData().Active != GHOST_kTabletModeNone;
|
||||
|
||||
@ -932,7 +957,7 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
|
||||
setCursorPosition(x_new, y_new); /* wrap */
|
||||
}
|
||||
else {
|
||||
g_event = new GHOST_EventCursor(getMilliSeconds(),
|
||||
g_event = new GHOST_EventCursor(event_ms,
|
||||
GHOST_kEventCursorMove,
|
||||
window,
|
||||
xme.x_root + x_accum,
|
||||
@ -941,7 +966,7 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
|
||||
}
|
||||
}
|
||||
else {
|
||||
g_event = new GHOST_EventCursor(getMilliSeconds(),
|
||||
g_event = new GHOST_EventCursor(event_ms,
|
||||
GHOST_kEventCursorMove,
|
||||
window,
|
||||
xme.x_root,
|
||||
@ -954,6 +979,7 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
|
||||
case KeyPress:
|
||||
case KeyRelease: {
|
||||
XKeyEvent *xke = &(xe->xkey);
|
||||
const uint64_t event_ms = ms_from_input_time(xke->time);
|
||||
KeySym key_sym;
|
||||
char *utf8_buf = nullptr;
|
||||
char ascii;
|
||||
@ -1146,7 +1172,7 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
|
||||
}
|
||||
}
|
||||
|
||||
g_event = new GHOST_EventKey(getMilliSeconds(), type, window, gkey, is_repeat, utf8_buf);
|
||||
g_event = new GHOST_EventKey(event_ms, type, window, gkey, is_repeat, utf8_buf);
|
||||
|
||||
#if defined(WITH_X11_XINPUT) && defined(X_HAVE_UTF8_STRING)
|
||||
/* when using IM for some languages such as Japanese,
|
||||
@ -1171,8 +1197,7 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
|
||||
/* Enqueue previous character. */
|
||||
pushEvent(g_event);
|
||||
|
||||
g_event = new GHOST_EventKey(
|
||||
getMilliSeconds(), type, window, gkey, is_repeat, &utf8_buf[i]);
|
||||
g_event = new GHOST_EventKey(event_ms, type, window, gkey, is_repeat, &utf8_buf[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1187,6 +1212,7 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
|
||||
case ButtonPress:
|
||||
case ButtonRelease: {
|
||||
const XButtonEvent &xbe = xe->xbutton;
|
||||
const uint64_t event_ms = ms_from_input_time(xbe.time);
|
||||
GHOST_TButton gbmask = GHOST_kButtonMaskLeft;
|
||||
GHOST_TEventType type = (xbe.type == ButtonPress) ? GHOST_kEventButtonDown :
|
||||
GHOST_kEventButtonUp;
|
||||
@ -1194,13 +1220,13 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
|
||||
/* process wheel mouse events and break, only pass on press events */
|
||||
if (xbe.button == Button4) {
|
||||
if (xbe.type == ButtonPress) {
|
||||
g_event = new GHOST_EventWheel(getMilliSeconds(), window, 1);
|
||||
g_event = new GHOST_EventWheel(event_ms, window, 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (xbe.button == Button5) {
|
||||
if (xbe.type == ButtonPress) {
|
||||
g_event = new GHOST_EventWheel(getMilliSeconds(), window, -1);
|
||||
g_event = new GHOST_EventWheel(event_ms, window, -1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -1234,15 +1260,17 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
|
||||
break;
|
||||
}
|
||||
|
||||
g_event = new GHOST_EventButton(
|
||||
getMilliSeconds(), type, window, gbmask, window->GetTabletData());
|
||||
g_event = new GHOST_EventButton(event_ms, type, window, gbmask, window->GetTabletData());
|
||||
break;
|
||||
}
|
||||
|
||||
/* change of size, border, layer etc. */
|
||||
case ConfigureNotify: {
|
||||
// const XConfigureEvent & xce = xe->xconfigure;
|
||||
g_event = new GHOST_Event(getMilliSeconds(), GHOST_kEventWindowSize, window);
|
||||
/* Event has no timestamp. */
|
||||
const uint64_t event_ms = getMilliSeconds();
|
||||
|
||||
g_event = new GHOST_Event(event_ms, GHOST_kEventWindowSize, window);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -1338,8 +1366,9 @@ void GHOST_SystemX11::processEvent(XEvent *xe)
|
||||
* also send grab/un-grab crossings for mouse-wheel events.
|
||||
*/
|
||||
const XCrossingEvent &xce = xe->xcrossing;
|
||||
const uint64_t event_ms = ms_from_input_time(xce.time);
|
||||
if (xce.mode == NotifyNormal) {
|
||||
g_event = new GHOST_EventCursor(getMilliSeconds(),
|
||||
g_event = new GHOST_EventCursor(event_ms,
|
||||
GHOST_kEventCursorMove,
|
||||
window,
|
||||
xce.x_root,
|
||||
@ -2538,8 +2567,12 @@ GHOST_TSuccess GHOST_SystemX11::pushDragDropEvent(GHOST_TEventType eventType,
|
||||
void *data)
|
||||
{
|
||||
GHOST_SystemX11 *system = ((GHOST_SystemX11 *)getSystem());
|
||||
|
||||
/* Caller has no timestamp. */
|
||||
const uint64_t event_ms = system->getMilliSeconds();
|
||||
|
||||
return system->pushEvent(new GHOST_EventDragnDrop(
|
||||
system->getMilliSeconds(), eventType, draggedObjectType, window, mouseX, mouseY, data));
|
||||
event_ms, eventType, draggedObjectType, window, mouseX, mouseY, data));
|
||||
}
|
||||
#endif
|
||||
/**
|
||||
|
@ -200,6 +200,13 @@ class GHOST_SystemX11 : public GHOST_System {
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Use this function instead of #GHOST_System::getMilliSeconds,
|
||||
* passing in the time-stamp from X to input to get the event
|
||||
* time-stamp with an offset applied to make it compatible with `getMilliSeconds`.
|
||||
*/
|
||||
uint64_t ms_from_input_time(const Time timestamp_as_uint) const;
|
||||
|
||||
/** Helped function for get data from the clipboard. */
|
||||
void getClipboard_xcout(const XEvent *evt,
|
||||
Atom sel,
|
||||
@ -343,6 +350,8 @@ class GHOST_SystemX11 : public GHOST_System {
|
||||
|
||||
/** Start time at initialization. */
|
||||
uint64_t m_start_time;
|
||||
/** Start time at initialization (using `CLOCK_MONOTONIC`). */
|
||||
uint64_t m_start_time_monotonic;
|
||||
|
||||
/** A vector of keyboard key masks. */
|
||||
char m_keyboard_vector[32];
|
||||
|
@ -1265,4 +1265,4 @@ void MEM_guarded_name_ptr_set(void *vmemh, const char *str)
|
||||
MEMNEXT(memh->prev)->nextname = str;
|
||||
}
|
||||
}
|
||||
#endif /* NDEBUG */
|
||||
#endif /* !NDEBUG */
|
||||
|
@ -440,4 +440,4 @@ const char *MEM_lockfree_name_ptr(void *vmemh)
|
||||
}
|
||||
|
||||
void MEM_lockfree_name_ptr_set(void *UNUSED(vmemh), const char *UNUSED(str)) {}
|
||||
#endif /* NDEBUG */
|
||||
#endif /* !NDEBUG */
|
||||
|
@ -32,7 +32,7 @@ def extend(obj, EXTEND_MODE, use_uv_selection):
|
||||
return STATUS_ERR_NOT_SELECTED # Active face is not selected.
|
||||
if len(f_act.verts) != 4:
|
||||
return STATUS_ERR_NOT_QUAD # Active face is not a quad
|
||||
if not me.uv_layers:
|
||||
if not bm.loops.layers.uv:
|
||||
return STATUS_ERR_MISSING_UV_LAYER # Object's mesh doesn't have any UV layers.
|
||||
|
||||
uv_act = bm.loops.layers.uv.active # Always use the active UV layer.
|
||||
@ -240,6 +240,10 @@ def main(context, operator):
|
||||
operator.report({'ERROR'}, "Active face must be a quad")
|
||||
elif status & STATUS_ERR_NOT_SELECTED:
|
||||
operator.report({'ERROR'}, "Active face not selected")
|
||||
elif status & STATUS_ERR_NO_FACES_SELECTED:
|
||||
operator.report({'ERROR'}, "No selected faces")
|
||||
elif status & STATUS_ERR_MISSING_UV_LAYER:
|
||||
operator.report({'ERROR'}, "No UV layers")
|
||||
else:
|
||||
assert status & STATUS_ERR_ACTIVE_FACE != 0
|
||||
operator.report({'ERROR'}, "No active face")
|
||||
|
@ -281,12 +281,13 @@ class GREASE_PENCIL_MT_layer_active(Menu):
|
||||
layout = self.layout
|
||||
layout.operator_context = 'INVOKE_REGION_WIN'
|
||||
obd = context.active_object.data
|
||||
if not obd.layers:
|
||||
return
|
||||
|
||||
nlop = layout.operator("grease_pencil.layer_add", text="New Layer", icon='ADD')
|
||||
nlop.new_layer_name = "Layer"
|
||||
|
||||
if not obd.layers:
|
||||
return
|
||||
|
||||
layout.separator()
|
||||
|
||||
for i in range(len(obd.layers) - 1, -1, -1):
|
||||
|
@ -1042,6 +1042,8 @@ class VIEW3D_HT_header(Header):
|
||||
sub.popover(panel="VIEW3D_PT_overlay_vertex_paint", text="", icon='VPAINT_HLT')
|
||||
elif obj is not None and obj.type == 'GPENCIL':
|
||||
sub.popover(panel="VIEW3D_PT_overlay_gpencil_options", text="", icon='OUTLINER_DATA_GREASEPENCIL')
|
||||
elif obj is not None and obj.type == 'GREASEPENCIL':
|
||||
sub.popover(panel="VIEW3D_PT_overlay_grease_pencil_options", text="", icon='OUTLINER_DATA_GREASEPENCIL')
|
||||
|
||||
# Separate from `elif` chain because it may coexist with weight-paint.
|
||||
if (
|
||||
@ -3565,7 +3567,7 @@ class VIEW3D_MT_sculpt(Menu):
|
||||
props.action = 'SHOW'
|
||||
props.area = 'ALL'
|
||||
|
||||
layout.operator("sculpt.face_set_invert_visibility", text="Invert Visible")
|
||||
layout.operator("paint.visibility_invert", text="Invert Visible")
|
||||
|
||||
props = layout.operator("paint.hide_show", text="Hide Masked")
|
||||
props.action = 'HIDE'
|
||||
@ -3786,14 +3788,6 @@ class VIEW3D_MT_face_sets(Menu):
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("sculpt.face_set_invert_visibility", text="Invert Visible Face Sets")
|
||||
|
||||
props = layout.operator("paint.hide_show", text="Show All Face Sets")
|
||||
props.action = "SHOW"
|
||||
props.area = "ALL"
|
||||
|
||||
layout.separator()
|
||||
|
||||
props = layout.operator("sculpt.face_sets_randomize_colors", text="Randomize Colors")
|
||||
|
||||
layout.template_node_operator_asset_menu_items(catalog_path=self.bl_label)
|
||||
@ -6142,7 +6136,7 @@ class VIEW3D_MT_sculpt_face_sets_edit_pie(Menu):
|
||||
props = pie.operator("sculpt.face_sets_create", text="Face Set from Visible")
|
||||
props.mode = 'VISIBLE'
|
||||
|
||||
pie.operator("sculpt.face_set_invert_visibility", text="Invert Visible")
|
||||
pie.operator("paint.visibility_invert", text="Invert Visible")
|
||||
|
||||
props = pie.operator("paint.hide_show", text="Show All")
|
||||
props.action = "SHOW"
|
||||
@ -7796,6 +7790,33 @@ class VIEW3D_PT_overlay_gpencil_options(Panel):
|
||||
row.prop(overlay, "gpencil_vertex_paint_opacity", text="Opacity", slider=True)
|
||||
|
||||
|
||||
class VIEW3D_PT_overlay_grease_pencil_options(Panel):
|
||||
bl_space_type = 'VIEW_3D'
|
||||
bl_region_type = 'HEADER'
|
||||
bl_label = ""
|
||||
bl_ui_units_x = 13
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
return context.object and context.object.type == 'GREASEPENCIL'
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
view = context.space_data
|
||||
overlay = view.overlay
|
||||
|
||||
layout.label(text={
|
||||
'PAINT_GREASE_PENCIL': iface_("Draw Grease Pencil"),
|
||||
'EDIT_GREASE_PENCIL': iface_("Edit Grease Pencil"),
|
||||
'OBJECT': iface_("Grease Pencil"),
|
||||
}[context.mode], translate=False)
|
||||
|
||||
if context.object.mode in {'EDIT'}:
|
||||
split = layout.split()
|
||||
col = split.column()
|
||||
col.prop(overlay, "use_gpencil_edit_lines", text="Edit Lines")
|
||||
|
||||
|
||||
class VIEW3D_PT_quad_view(Panel):
|
||||
bl_space_type = 'VIEW_3D'
|
||||
bl_region_type = 'UI'
|
||||
@ -8961,6 +8982,7 @@ classes = (
|
||||
VIEW3D_PT_gpencil_guide,
|
||||
VIEW3D_PT_transform_orientations,
|
||||
VIEW3D_PT_overlay_gpencil_options,
|
||||
VIEW3D_PT_overlay_grease_pencil_options,
|
||||
VIEW3D_PT_context_properties,
|
||||
VIEW3D_PT_paint_vertex_context_menu,
|
||||
VIEW3D_PT_paint_texture_context_menu,
|
||||
|
@ -61,7 +61,9 @@ int insert_bezt_fcurve(FCurve *fcu, const BezTriple *bezt, eInsertKeyFlags flag)
|
||||
* \param flag: Optional flags (#eInsertKeyFlags) for controlling how keys get added
|
||||
* and/or whether updates get done.
|
||||
*/
|
||||
int insert_vert_fcurve(
|
||||
FCurve *fcu, float x, float y, eBezTriple_KeyframeType keyframe_type, eInsertKeyFlags flag);
|
||||
int insert_vert_fcurve(FCurve *fcu,
|
||||
const float2 position,
|
||||
eBezTriple_KeyframeType keyframe_type,
|
||||
eInsertKeyFlags flag);
|
||||
|
||||
} // namespace blender::animrig
|
||||
|
@ -137,7 +137,7 @@ static void bonecoll_ensure_name_unique(bArmature *armature, BoneCollection *bco
|
||||
}
|
||||
|
||||
/**
|
||||
* Inserts bcoll into armature's array of bone collecions at index.
|
||||
* Inserts bcoll into armature's array of bone collections at index.
|
||||
*
|
||||
* Note: the specified index is where the given bone collection will end up.
|
||||
* This means, for example, that for a collection array of length N, you can
|
||||
|
@ -260,11 +260,13 @@ void initialize_bezt(BezTriple *beztr,
|
||||
beztr->period = 4.1f;
|
||||
}
|
||||
|
||||
int insert_vert_fcurve(
|
||||
FCurve *fcu, float x, float y, eBezTriple_KeyframeType keyframe_type, eInsertKeyFlags flag)
|
||||
int insert_vert_fcurve(FCurve *fcu,
|
||||
const float2 position,
|
||||
eBezTriple_KeyframeType keyframe_type,
|
||||
eInsertKeyFlags flag)
|
||||
{
|
||||
BezTriple beztr = {{{0}}};
|
||||
initialize_bezt(&beztr, {x, y}, keyframe_type, flag, eFCurve_Flags(fcu->flag));
|
||||
initialize_bezt(&beztr, position, keyframe_type, flag, eFCurve_Flags(fcu->flag));
|
||||
|
||||
uint oldTot = fcu->totvert;
|
||||
int a;
|
||||
|
@ -315,14 +315,14 @@ static bool insert_keyframe_value(
|
||||
return false;
|
||||
}
|
||||
|
||||
if (insert_vert_fcurve(fcu, cfra, curval, keytype, flag) < 0) {
|
||||
if (insert_vert_fcurve(fcu, {cfra, curval}, keytype, flag) < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return insert_vert_fcurve(fcu, cfra, curval, keytype, flag) >= 0;
|
||||
return insert_vert_fcurve(fcu, {cfra, curval}, keytype, flag) >= 0;
|
||||
}
|
||||
|
||||
bool insert_keyframe_direct(ReportList *reports,
|
||||
|
@ -345,7 +345,7 @@ int BLF_load_default(bool unique);
|
||||
int BLF_load_mono_default(bool unique);
|
||||
void BLF_load_font_stack(void);
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifndef NDEBUG
|
||||
void BLF_state_print(int fontid);
|
||||
#endif
|
||||
|
||||
|
@ -1017,7 +1017,7 @@ float BLF_character_to_curves(int fontid,
|
||||
return blf_character_to_curves(font, unicode, nurbsbase, scale);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifndef NDEBUG
|
||||
void BLF_state_print(int fontid)
|
||||
{
|
||||
FontBLF *font = blf_get(fontid);
|
||||
|
@ -765,7 +765,7 @@ static FT_UInt blf_glyph_index_from_charcode(FontBLF **font, const uint charcode
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifndef NDEBUG
|
||||
printf("Unicode character U+%04X not found in loaded fonts. \n", charcode);
|
||||
#endif
|
||||
|
||||
|
@ -349,7 +349,7 @@ typedef struct FontBLF {
|
||||
int char_weight; /* 100 - 900, 400 = normal. */
|
||||
float char_slant; /* Slant in clockwise degrees. 0.0 = upright. */
|
||||
float char_width; /* Factor of normal character width. 1.0 = normal. */
|
||||
float char_spacing; /* Factor of normal normal spacing. 0.0 = normal. */
|
||||
float char_spacing; /* Factor of normal character spacing. 0.0 = normal. */
|
||||
|
||||
/** Max texture size. */
|
||||
int tex_size_max;
|
||||
|
@ -43,7 +43,7 @@ using eCustomDataMask = uint64_t;
|
||||
|
||||
/**
|
||||
* UV map related customdata offsets into BMesh attribute blocks. See #BM_uv_map_get_offsets.
|
||||
* Defined in #BKE_customdata.hh to avoid including bmesh.h in many unrelated areas.
|
||||
* Defined in #BKE_customdata.hh to avoid including bmesh.hh in many unrelated areas.
|
||||
* An offset of -1 means that the corresponding layer does not exist.
|
||||
*/
|
||||
struct BMUVOffsets {
|
||||
@ -347,6 +347,11 @@ void CustomData_bmesh_copy_data(const CustomData *source,
|
||||
CustomData *dest,
|
||||
void *src_block,
|
||||
void **dest_block);
|
||||
/**
|
||||
* Copy all layers from the source to the destination block.
|
||||
* Allocate the result block if necessary, otherwise free its existing layer data.
|
||||
*/
|
||||
void CustomData_bmesh_copy_block(CustomData &data, void *src_block, void **dst_block);
|
||||
void CustomData_bmesh_copy_data_exclude_by_type(const CustomData *source,
|
||||
CustomData *dest,
|
||||
void *src_block,
|
||||
@ -509,11 +514,6 @@ const char *CustomData_get_render_layer_name(const CustomData *data, eCustomData
|
||||
|
||||
bool CustomData_layer_is_anonymous(const CustomData *data, eCustomDataType type, int n);
|
||||
|
||||
void CustomData_bmesh_set(const CustomData *data,
|
||||
void *block,
|
||||
eCustomDataType type,
|
||||
const void *source);
|
||||
|
||||
void CustomData_bmesh_set_n(
|
||||
CustomData *data, void *block, eCustomDataType type, int n, const void *source);
|
||||
|
||||
@ -757,7 +757,7 @@ size_t CustomData_get_elem_size(const CustomDataLayer *layer);
|
||||
struct DynStr;
|
||||
/** Use to inspect mesh data when debugging. */
|
||||
void CustomData_debug_info_from_layers(const CustomData *data, const char *indent, DynStr *dynstr);
|
||||
#endif /* NDEBUG */
|
||||
#endif /* !NDEBUG */
|
||||
|
||||
namespace blender::bke {
|
||||
const CPPType *custom_data_type_to_cpp_type(eCustomDataType type);
|
||||
|
@ -13,7 +13,7 @@
|
||||
*/
|
||||
|
||||
#include "DNA_customdata_types.h"
|
||||
#include "bmesh.h"
|
||||
#include "bmesh.hh"
|
||||
|
||||
struct BMLoop;
|
||||
struct BMPartialUpdate;
|
||||
|
@ -473,16 +473,6 @@ void BKE_mesh_merge_customdata_for_apply_modifier(struct Mesh *me);
|
||||
|
||||
/* Flush flags. */
|
||||
|
||||
/**
|
||||
* Update the hide flag for edges and faces from the corresponding flag in verts.
|
||||
*/
|
||||
void BKE_mesh_flush_hidden_from_verts(struct Mesh *me);
|
||||
void BKE_mesh_flush_hidden_from_faces(struct Mesh *me);
|
||||
|
||||
void BKE_mesh_flush_select_from_faces(struct Mesh *me);
|
||||
void BKE_mesh_flush_select_from_verts(struct Mesh *me);
|
||||
void BKE_mesh_flush_select_from_edges(struct Mesh *me);
|
||||
|
||||
/* spatial evaluation */
|
||||
/**
|
||||
* This function takes the difference between 2 vertex-coord-arrays
|
||||
|
@ -297,6 +297,18 @@ void mesh_vert_normals_assign(Mesh &mesh, Span<float3> vert_normals);
|
||||
/** Set mesh vertex normals to known-correct values, avoiding future lazy computation. */
|
||||
void mesh_vert_normals_assign(Mesh &mesh, Vector<float3> vert_normals);
|
||||
|
||||
/** Make edge and face visibility consistent with vertices. */
|
||||
void mesh_hide_vert_flush(Mesh &mesh);
|
||||
/** Make vertex and edge visibility consistent with faces. */
|
||||
void mesh_hide_face_flush(Mesh &mesh);
|
||||
|
||||
/** Make edge and face visibility consistent with vertices. */
|
||||
void mesh_select_vert_flush(Mesh &mesh);
|
||||
/** Make vertex and face visibility consistent with edges. */
|
||||
void mesh_select_edge_flush(Mesh &mesh);
|
||||
/** Make vertex and edge visibility consistent with faces. */
|
||||
void mesh_select_face_flush(Mesh &mesh);
|
||||
|
||||
} // namespace blender::bke
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
@ -81,4 +81,4 @@ void BKE_mesh_runtime_eval_to_meshkey(Mesh *me_deformed, Mesh *me, KeyBlock *kb)
|
||||
|
||||
#ifndef NDEBUG
|
||||
bool BKE_mesh_runtime_is_valid(Mesh *me_eval);
|
||||
#endif /* NDEBUG */
|
||||
#endif /* !NDEBUG */
|
||||
|
@ -140,7 +140,7 @@ struct MeshRuntime {
|
||||
CustomData_MeshMasks cd_mask_extra = {};
|
||||
|
||||
/**
|
||||
* Grids representation for multiresolution sculpting. When this is set, the mesh will be empty,
|
||||
* Grids representation for multi-resolution sculpting. When this is set, the mesh will be empty,
|
||||
* since it is conceptually replaced with the limited data stored in the grids.
|
||||
*/
|
||||
std::unique_ptr<SubdivCCG> subdiv_ccg;
|
||||
|
@ -100,7 +100,7 @@ class NodeDeclaration;
|
||||
class NodeDeclarationBuilder;
|
||||
class GatherAddNodeSearchParams;
|
||||
class GatherLinkSearchOpParams;
|
||||
class NodeExtraInfoParams;
|
||||
struct NodeExtraInfoParams;
|
||||
} // namespace nodes
|
||||
namespace realtime_compositor {
|
||||
class Context;
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include "BKE_attribute.h"
|
||||
#include "BKE_pbvh.hh"
|
||||
|
||||
#include "bmesh.h"
|
||||
#include "bmesh.hh"
|
||||
|
||||
struct BMFace;
|
||||
struct BMesh;
|
||||
@ -196,7 +196,6 @@ const Brush *BKE_paint_brush_for_read(const Paint *p);
|
||||
void BKE_paint_brush_set(Paint *paint, Brush *br);
|
||||
Palette *BKE_paint_palette(Paint *paint);
|
||||
void BKE_paint_palette_set(Paint *p, Palette *palette);
|
||||
void BKE_paint_curve_set(Brush *br, PaintCurve *pc);
|
||||
void BKE_paint_curve_clamp_endpoint_add_index(PaintCurve *pc, int add_index);
|
||||
|
||||
/**
|
||||
@ -607,12 +606,12 @@ struct SculptSession {
|
||||
* geometry (the trim tool, for example) to detect which geometry was just added, so it can be
|
||||
* assigned a valid Face Set after creation. Tools are not intended to run with Face Sets IDs set
|
||||
* to 0. */
|
||||
int *face_sets;
|
||||
const int *face_sets;
|
||||
/**
|
||||
* A reference to the ".hide_poly" attribute, to store whether (base) faces are hidden.
|
||||
* May be null.
|
||||
*/
|
||||
bool *hide_poly;
|
||||
const bool *hide_poly;
|
||||
|
||||
/* BMesh for dynamic topology sculpting */
|
||||
BMesh *bm;
|
||||
@ -775,11 +774,6 @@ SculptAttribute *BKE_sculpt_attribute_get(Object *ob,
|
||||
eCustomDataType proptype,
|
||||
const char *name);
|
||||
|
||||
bool BKE_sculpt_attribute_exists(Object *ob,
|
||||
eAttrDomain domain,
|
||||
eCustomDataType proptype,
|
||||
const char *name);
|
||||
|
||||
bool BKE_sculpt_attribute_destroy(Object *ob, SculptAttribute *attr);
|
||||
|
||||
/* Destroy all attributes and pseudo-attributes created by sculpt mode. */
|
||||
@ -848,13 +842,11 @@ void BKE_sculpt_update_object_after_eval(Depsgraph *depsgraph, Object *ob_eval);
|
||||
* it's the last modifier on the stack and it is not on the first level.
|
||||
*/
|
||||
MultiresModifierData *BKE_sculpt_multires_active(const Scene *scene, Object *ob);
|
||||
int *BKE_sculpt_face_sets_ensure(Object *ob);
|
||||
/**
|
||||
* Create the attribute used to store face visibility and retrieve its data.
|
||||
* Note that changes to the face visibility have to be propagated to other domains
|
||||
* (see #SCULPT_visibility_sync_all_from_faces).
|
||||
* Update the pointer to the ".hide_poly" attribute. This is necessary because it is dynamically
|
||||
* created, removed, and made mutable.
|
||||
*/
|
||||
bool *BKE_sculpt_hide_poly_ensure(Mesh *mesh);
|
||||
void BKE_sculpt_hide_poly_pointer_update(Object &object);
|
||||
|
||||
/**
|
||||
* Ensures a mask layer exists. If depsgraph and bmain are non-null,
|
||||
@ -874,7 +866,6 @@ PBVH *BKE_sculpt_object_pbvh_ensure(Depsgraph *depsgraph, Object *ob);
|
||||
|
||||
void BKE_sculpt_bvh_update_from_ccg(PBVH *pbvh, SubdivCCG *subdiv_ccg);
|
||||
|
||||
void BKE_sculpt_ensure_orig_mesh_data(Scene *scene, Object *object);
|
||||
void BKE_sculpt_sync_face_visibility_to_grids(Mesh *mesh, SubdivCCG *subdiv_ccg);
|
||||
|
||||
/**
|
||||
|
@ -29,7 +29,7 @@
|
||||
#include "BKE_ccg.h"
|
||||
#include "BKE_pbvh.hh"
|
||||
|
||||
#include "bmesh.h"
|
||||
#include "bmesh.hh"
|
||||
|
||||
struct BMLog;
|
||||
struct BMesh;
|
||||
@ -384,6 +384,10 @@ int BKE_pbvh_node_num_unique_verts(const PBVH &pbvh, const PBVHNode &node);
|
||||
blender::Span<int> BKE_pbvh_node_get_vert_indices(const PBVHNode *node);
|
||||
blender::Span<int> BKE_pbvh_node_get_unique_vert_indices(const PBVHNode *node);
|
||||
void BKE_pbvh_node_get_loops(const PBVHNode *node, const int **r_loop_indices);
|
||||
|
||||
void BKE_pbvh_node_calc_face_indices(const PBVH &pbvh,
|
||||
const PBVHNode &node,
|
||||
blender::Vector<int> &faces);
|
||||
blender::Vector<int> BKE_pbvh_node_calc_face_indices(const PBVH &pbvh, const PBVHNode &node);
|
||||
|
||||
/* Get number of faces in the mesh; for PBVH_GRIDS the
|
||||
|
@ -92,7 +92,7 @@ std::optional<int> BKE_previewimg_deferred_thumb_source_get(const PreviewImage *
|
||||
|
||||
/**
|
||||
* Create an #ImBuf holding a copy of the preview image buffer in \a prv.
|
||||
* \note The returned image buffer has to be free'd (#IMB_freeImBuf()).
|
||||
* \note The returned image buffer has to be freed (#IMB_freeImBuf()).
|
||||
*/
|
||||
ImBuf *BKE_previewimg_to_imbuf(PreviewImage *prv, int size);
|
||||
|
||||
|
@ -84,7 +84,7 @@ static bool is_appdir_init = false;
|
||||
# define ASSERT_IS_INIT() BLI_assert(is_appdir_init)
|
||||
#else
|
||||
# define ASSERT_IS_INIT() ((void)0)
|
||||
#endif
|
||||
#endif /* NDEBUG */
|
||||
|
||||
void BKE_appdir_init()
|
||||
{
|
||||
@ -882,7 +882,7 @@ static void where_am_i(char *program_filepath,
|
||||
/* Remove "/./" and "/../" so string comparisons can be used on the path. */
|
||||
BLI_path_normalize_native(program_filepath);
|
||||
|
||||
# if defined(DEBUG)
|
||||
# ifndef NDEBUG
|
||||
if (!STREQ(program_name, program_filepath)) {
|
||||
CLOG_INFO(&LOG, 2, "guessing '%s' == '%s'", program_name, program_filepath);
|
||||
}
|
||||
|
@ -807,20 +807,6 @@ CustomDataLayer *BKE_id_attribute_from_index(ID *id,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get list of domain types but with ATTR_DOMAIN_FACE and
|
||||
* ATTR_DOMAIN_CORNER swapped.
|
||||
*/
|
||||
static void get_domains_types(eAttrDomain domains[ATTR_DOMAIN_NUM])
|
||||
{
|
||||
for (const int i : IndexRange(ATTR_DOMAIN_NUM)) {
|
||||
domains[i] = static_cast<eAttrDomain>(i);
|
||||
}
|
||||
|
||||
/* Swap corner and face. */
|
||||
std::swap(domains[ATTR_DOMAIN_FACE], domains[ATTR_DOMAIN_CORNER]);
|
||||
}
|
||||
|
||||
int BKE_id_attribute_to_index(const ID *id,
|
||||
const CustomDataLayer *layer,
|
||||
eAttrDomainMask domain_mask,
|
||||
@ -831,21 +817,19 @@ int BKE_id_attribute_to_index(const ID *id,
|
||||
}
|
||||
|
||||
DomainInfo info[ATTR_DOMAIN_NUM];
|
||||
eAttrDomain domains[ATTR_DOMAIN_NUM];
|
||||
get_domains_types(domains);
|
||||
get_domains(id, info);
|
||||
|
||||
int index = 0;
|
||||
for (int i = 0; i < ATTR_DOMAIN_NUM; i++) {
|
||||
if (!(domain_mask & (1 << domains[i])) || !info[domains[i]].customdata) {
|
||||
for (const int domain : IndexRange(ATTR_DOMAIN_NUM)) {
|
||||
const CustomData *customdata = info[domain].customdata;
|
||||
|
||||
if (!customdata || !((1 << int(domain)) & domain_mask)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const CustomData *cdata = info[domains[i]].customdata;
|
||||
for (int j = 0; j < cdata->totlayer; j++) {
|
||||
const CustomDataLayer *layer_iter = cdata->layers + j;
|
||||
|
||||
if (!(CD_TYPE_AS_MASK(layer_iter->type) & layer_mask) ||
|
||||
for (int i = 0; i < customdata->totlayer; i++) {
|
||||
const CustomDataLayer *layer_iter = customdata->layers + i;
|
||||
if (!(layer_mask & CD_TYPE_AS_MASK(layer_iter->type)) ||
|
||||
(layer_iter->flag & CD_FLAG_TEMPORARY)) {
|
||||
continue;
|
||||
}
|
||||
|
@ -681,7 +681,7 @@ void MutableAttributeAccessor::remove_anonymous()
|
||||
/**
|
||||
* Debug utility that checks whether the #finish function of an #AttributeWriter has been called.
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
#ifndef NDEBUG
|
||||
struct FinishCallChecker {
|
||||
std::string name;
|
||||
bool finish_called = false;
|
||||
@ -700,7 +700,7 @@ GAttributeWriter MutableAttributeAccessor::lookup_for_write(const AttributeIDRef
|
||||
{
|
||||
GAttributeWriter attribute = fn_->lookup_for_write(owner_, attribute_id);
|
||||
/* Check that the #finish method is called in debug builds. */
|
||||
#ifdef DEBUG
|
||||
#ifndef NDEBUG
|
||||
if (attribute) {
|
||||
auto checker = std::make_shared<FinishCallChecker>();
|
||||
checker->name = attribute_id.name();
|
||||
|
@ -323,7 +323,8 @@ static void userdef_free_addons(UserDef *userdef)
|
||||
void BKE_blender_userdef_data_free(UserDef *userdef, bool clear_fonts)
|
||||
{
|
||||
#define U BLI_STATIC_ASSERT(false, "Global 'U' not allowed, only use arguments passed in!")
|
||||
#ifdef U /* quiet warning */
|
||||
#ifdef U
|
||||
/* Quiet warning. */
|
||||
#endif
|
||||
|
||||
userdef_free_keymaps(userdef);
|
||||
|
@ -1217,7 +1217,7 @@ BVHTree *BKE_bvhtree_from_mesh_get(BVHTreeFromMesh *data,
|
||||
bvhcache_insert(*bvh_cache_p, data->tree, bvh_cache_type);
|
||||
bvhcache_unlock(*bvh_cache_p, lock_started);
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifndef NDEBUG
|
||||
if (data->tree != nullptr) {
|
||||
if (BLI_bvhtree_get_tree_type(data->tree) != tree_type) {
|
||||
printf("tree_type %d obtained instead of %d\n",
|
||||
@ -1307,7 +1307,7 @@ BVHTree *BKE_bvhtree_from_editmesh_get(BVHTreeFromEditMesh *data,
|
||||
bvhcache_unlock(*bvh_cache_p, lock_started);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifndef NDEBUG
|
||||
if (data->tree != nullptr) {
|
||||
if (BLI_bvhtree_get_tree_type(data->tree) != tree_type) {
|
||||
printf("tree_type %d obtained instead of %d\n",
|
||||
|
@ -72,7 +72,7 @@ CurvesGeometry::CurvesGeometry(const int point_num, const int curve_num)
|
||||
MEM_malloc_arrayN(this->curve_num + 1, sizeof(int), __func__));
|
||||
this->runtime->curve_offsets_sharing_info = implicit_sharing::info_for_mem_free(
|
||||
this->curve_offsets);
|
||||
#ifdef DEBUG
|
||||
#ifndef NDEBUG
|
||||
this->offsets_for_write().fill(-1);
|
||||
#endif
|
||||
/* Set common values for convenience. */
|
||||
|
@ -54,7 +54,7 @@
|
||||
|
||||
#include "BLO_read_write.hh"
|
||||
|
||||
#include "bmesh.h"
|
||||
#include "bmesh.hh"
|
||||
|
||||
#include "CLG_log.h"
|
||||
|
||||
@ -65,6 +65,7 @@ using blender::BitVector;
|
||||
using blender::float2;
|
||||
using blender::ImplicitSharingInfo;
|
||||
using blender::IndexRange;
|
||||
using blender::MutableSpan;
|
||||
using blender::Set;
|
||||
using blender::Span;
|
||||
using blender::StringRef;
|
||||
@ -138,7 +139,7 @@ struct LayerTypeInfo {
|
||||
* size should be the size of one element of this layer's data (e.g.
|
||||
* LayerTypeInfo.size)
|
||||
*/
|
||||
void (*free)(void *data, int count, int size);
|
||||
void (*free)(void *data, int count);
|
||||
|
||||
/**
|
||||
* a function to interpolate between count source elements of this
|
||||
@ -224,15 +225,13 @@ static void layerCopy_mdeformvert(const void *source, void *dest, const int coun
|
||||
}
|
||||
}
|
||||
|
||||
static void layerFree_mdeformvert(void *data, const int count, const int size)
|
||||
static void layerFree_mdeformvert(void *data, const int count)
|
||||
{
|
||||
for (int i = 0; i < count; i++) {
|
||||
MDeformVert *dvert = static_cast<MDeformVert *>(POINTER_OFFSET(data, i * size));
|
||||
|
||||
if (dvert->dw) {
|
||||
MEM_freeN(dvert->dw);
|
||||
dvert->dw = nullptr;
|
||||
dvert->totweight = 0;
|
||||
for (MDeformVert &dvert : MutableSpan(static_cast<MDeformVert *>(data), count)) {
|
||||
if (dvert.dw) {
|
||||
MEM_freeN(dvert.dw);
|
||||
dvert.dw = nullptr;
|
||||
dvert.totweight = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -666,21 +665,13 @@ static void layerCopy_mdisps(const void *source, void *dest, const int count)
|
||||
}
|
||||
}
|
||||
|
||||
static void layerFree_mdisps(void *data, const int count, const int /*size*/)
|
||||
static void layerFree_mdisps(void *data, const int count)
|
||||
{
|
||||
MDisps *d = static_cast<MDisps *>(data);
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
if (d[i].disps) {
|
||||
MEM_freeN(d[i].disps);
|
||||
}
|
||||
if (d[i].hidden) {
|
||||
MEM_freeN(d[i].hidden);
|
||||
}
|
||||
d[i].disps = nullptr;
|
||||
d[i].hidden = nullptr;
|
||||
d[i].totdisp = 0;
|
||||
d[i].level = 0;
|
||||
for (MDisps &d : MutableSpan(static_cast<MDisps *>(data), count)) {
|
||||
MEM_SAFE_FREE(d.disps);
|
||||
MEM_SAFE_FREE(d.hidden);
|
||||
d.totdisp = 0;
|
||||
d.level = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -757,10 +748,10 @@ void bpy_bm_generic_invalidate(struct BPy_BMGeneric * /*self*/)
|
||||
}
|
||||
#endif
|
||||
|
||||
static void layerFree_bmesh_elem_py_ptr(void *data, const int count, const int size)
|
||||
static void layerFree_bmesh_elem_py_ptr(void *data, const int count)
|
||||
{
|
||||
for (int i = 0; i < count; i++) {
|
||||
void **ptr = (void **)POINTER_OFFSET(data, i * size);
|
||||
void **ptr = (void **)POINTER_OFFSET(data, i * sizeof(void *));
|
||||
if (*ptr) {
|
||||
bpy_bm_generic_invalidate(static_cast<BPy_BMGeneric *>(*ptr));
|
||||
}
|
||||
@ -790,13 +781,11 @@ static void layerCopy_grid_paint_mask(const void *source, void *dest, const int
|
||||
}
|
||||
}
|
||||
|
||||
static void layerFree_grid_paint_mask(void *data, const int count, const int /*size*/)
|
||||
static void layerFree_grid_paint_mask(void *data, const int count)
|
||||
{
|
||||
GridPaintMask *gpm = static_cast<GridPaintMask *>(data);
|
||||
|
||||
for (int i = 0; i < count; i++) {
|
||||
MEM_SAFE_FREE(gpm[i].data);
|
||||
gpm[i].level = 0;
|
||||
for (GridPaintMask &gpm : MutableSpan(static_cast<GridPaintMask *>(data), count)) {
|
||||
MEM_SAFE_FREE(gpm.data);
|
||||
gpm.level = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@ -2155,7 +2144,7 @@ static void free_layer_data(const eCustomDataType type, const void *data, const
|
||||
{
|
||||
const LayerTypeInfo &type_info = *layerType_getInfo(type);
|
||||
if (type_info.free) {
|
||||
type_info.free(const_cast<void *>(data), totelem, type_info.size);
|
||||
type_info.free(const_cast<void *>(data), totelem);
|
||||
}
|
||||
MEM_freeN(const_cast<void *>(data));
|
||||
}
|
||||
@ -3364,7 +3353,7 @@ void CustomData_free_elem(CustomData *data, const int index, const int count)
|
||||
size_t offset = size_t(index) * typeInfo->size;
|
||||
BLI_assert(layer_is_mutable(data->layers[i]));
|
||||
|
||||
typeInfo->free(POINTER_OFFSET(data->layers[i].data, offset), count, typeInfo->size);
|
||||
typeInfo->free(POINTER_OFFSET(data->layers[i].data, offset), count);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3756,7 +3745,7 @@ void CustomData_bmesh_free_block(CustomData *data, void **block)
|
||||
|
||||
if (typeInfo->free) {
|
||||
int offset = data->layers[i].offset;
|
||||
typeInfo->free(POINTER_OFFSET(*block, offset), 1, typeInfo->size);
|
||||
typeInfo->free(POINTER_OFFSET(*block, offset), 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3776,7 +3765,7 @@ void CustomData_bmesh_free_block_data(CustomData *data, void *block)
|
||||
const LayerTypeInfo *typeInfo = layerType_getInfo(eCustomDataType(data->layers[i].type));
|
||||
if (typeInfo->free) {
|
||||
const size_t offset = data->layers[i].offset;
|
||||
typeInfo->free(POINTER_OFFSET(block, offset), 1, typeInfo->size);
|
||||
typeInfo->free(POINTER_OFFSET(block, offset), 1);
|
||||
}
|
||||
}
|
||||
if (data->totsize) {
|
||||
@ -3810,7 +3799,7 @@ void CustomData_bmesh_free_block_data_exclude_by_type(CustomData *data,
|
||||
const LayerTypeInfo *typeInfo = layerType_getInfo(eCustomDataType(data->layers[i].type));
|
||||
const size_t offset = data->layers[i].offset;
|
||||
if (typeInfo->free) {
|
||||
typeInfo->free(POINTER_OFFSET(block, offset), 1, typeInfo->size);
|
||||
typeInfo->free(POINTER_OFFSET(block, offset), 1);
|
||||
}
|
||||
memset(POINTER_OFFSET(block, offset), 0, typeInfo->size);
|
||||
}
|
||||
@ -3910,6 +3899,35 @@ void CustomData_bmesh_copy_data(const CustomData *source,
|
||||
CustomData_bmesh_copy_data_exclude_by_type(source, dest, src_block, dest_block, 0);
|
||||
}
|
||||
|
||||
void CustomData_bmesh_copy_block(CustomData &data, void *src_block, void **dst_block)
|
||||
{
|
||||
if (*dst_block) {
|
||||
for (const CustomDataLayer &layer : Span(data.layers, data.totlayer)) {
|
||||
const LayerTypeInfo &info = *layerType_getInfo(eCustomDataType(layer.type));
|
||||
if (info.free) {
|
||||
info.free(POINTER_OFFSET(*dst_block, layer.offset), 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (data.totsize == 0) {
|
||||
return;
|
||||
}
|
||||
*dst_block = BLI_mempool_alloc(data.pool);
|
||||
}
|
||||
|
||||
for (const CustomDataLayer &layer : Span(data.layers, data.totlayer)) {
|
||||
const int offset = layer.offset;
|
||||
const LayerTypeInfo &info = *layerType_getInfo(eCustomDataType(layer.type));
|
||||
if (info.copy) {
|
||||
info.copy(POINTER_OFFSET(src_block, offset), POINTER_OFFSET(*dst_block, offset), 1);
|
||||
}
|
||||
else {
|
||||
memcpy(POINTER_OFFSET(*dst_block, offset), POINTER_OFFSET(src_block, offset), info.size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void *CustomData_bmesh_get(const CustomData *data, void *block, const eCustomDataType type)
|
||||
{
|
||||
int layer_index = CustomData_get_active_layer_index(data, type);
|
||||
@ -4085,26 +4103,6 @@ void CustomData_data_add(const eCustomDataType type, void *data1, const void *da
|
||||
}
|
||||
}
|
||||
|
||||
void CustomData_bmesh_set(const CustomData *data,
|
||||
void *block,
|
||||
const eCustomDataType type,
|
||||
const void *source)
|
||||
{
|
||||
void *dest = CustomData_bmesh_get(data, block, type);
|
||||
const LayerTypeInfo *typeInfo = layerType_getInfo(type);
|
||||
|
||||
if (!dest) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (typeInfo->copy) {
|
||||
typeInfo->copy(source, dest, 1);
|
||||
}
|
||||
else {
|
||||
memcpy(dest, source, typeInfo->size);
|
||||
}
|
||||
}
|
||||
|
||||
void CustomData_bmesh_set_n(
|
||||
CustomData *data, void *block, const eCustomDataType type, const int n, const void *source)
|
||||
{
|
||||
@ -4498,7 +4496,7 @@ void CustomData_external_reload(CustomData *data, ID * /*id*/, eCustomDataMask m
|
||||
}
|
||||
else if ((layer->flag & CD_FLAG_EXTERNAL) && (layer->flag & CD_FLAG_IN_MEMORY)) {
|
||||
if (typeInfo->free) {
|
||||
typeInfo->free(layer->data, totelem, typeInfo->size);
|
||||
typeInfo->free(layer->data, totelem);
|
||||
}
|
||||
layer->flag &= ~CD_FLAG_IN_MEMORY;
|
||||
}
|
||||
@ -4673,7 +4671,7 @@ void CustomData_external_write(
|
||||
if ((layer->flag & CD_FLAG_EXTERNAL) && typeInfo->write) {
|
||||
if (free) {
|
||||
if (typeInfo->free) {
|
||||
typeInfo->free(layer->data, totelem, typeInfo->size);
|
||||
typeInfo->free(layer->data, totelem);
|
||||
}
|
||||
layer->flag &= ~CD_FLAG_IN_MEMORY;
|
||||
}
|
||||
@ -5275,7 +5273,7 @@ void CustomData_debug_info_from_layers(const CustomData *data, const char *inden
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* NDEBUG */
|
||||
#endif /* !NDEBUG */
|
||||
|
||||
/** \} */
|
||||
|
||||
|
@ -32,9 +32,9 @@ TEST(evaluate_fcurve, OnKeys)
|
||||
{
|
||||
FCurve *fcu = BKE_fcurve_create();
|
||||
|
||||
insert_vert_fcurve(fcu, 1.0f, 7.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF);
|
||||
insert_vert_fcurve(fcu, 2.0f, 13.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF);
|
||||
insert_vert_fcurve(fcu, 3.0f, 19.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF);
|
||||
insert_vert_fcurve(fcu, {1.0f, 7.0f}, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF);
|
||||
insert_vert_fcurve(fcu, {2.0f, 13.0f}, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF);
|
||||
insert_vert_fcurve(fcu, {3.0f, 19.0f}, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF);
|
||||
|
||||
EXPECT_NEAR(evaluate_fcurve(fcu, 1.0f), 7.0f, EPSILON); /* hits 'on or before first' function */
|
||||
EXPECT_NEAR(evaluate_fcurve(fcu, 2.0f), 13.0f, EPSILON); /* hits 'between' function */
|
||||
@ -55,8 +55,10 @@ TEST(evaluate_fcurve, InterpolationConstant)
|
||||
{
|
||||
FCurve *fcu = BKE_fcurve_create();
|
||||
|
||||
EXPECT_EQ(insert_vert_fcurve(fcu, 1.0f, 7.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF), 0);
|
||||
EXPECT_EQ(insert_vert_fcurve(fcu, 2.0f, 13.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF), 1);
|
||||
EXPECT_EQ(insert_vert_fcurve(fcu, {1.0f, 7.0f}, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF),
|
||||
0);
|
||||
EXPECT_EQ(insert_vert_fcurve(fcu, {2.0f, 13.0f}, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF),
|
||||
1);
|
||||
|
||||
fcu->bezt[0].ipo = BEZT_IPO_CONST;
|
||||
fcu->bezt[1].ipo = BEZT_IPO_CONST;
|
||||
@ -71,8 +73,10 @@ TEST(evaluate_fcurve, InterpolationLinear)
|
||||
{
|
||||
FCurve *fcu = BKE_fcurve_create();
|
||||
|
||||
EXPECT_EQ(insert_vert_fcurve(fcu, 1.0f, 7.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF), 0);
|
||||
EXPECT_EQ(insert_vert_fcurve(fcu, 2.0f, 13.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF), 1);
|
||||
EXPECT_EQ(insert_vert_fcurve(fcu, {1.0f, 7.0f}, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF),
|
||||
0);
|
||||
EXPECT_EQ(insert_vert_fcurve(fcu, {2.0f, 13.0f}, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF),
|
||||
1);
|
||||
|
||||
fcu->bezt[0].ipo = BEZT_IPO_LIN;
|
||||
fcu->bezt[1].ipo = BEZT_IPO_LIN;
|
||||
@ -88,8 +92,10 @@ TEST(evaluate_fcurve, InterpolationBezier)
|
||||
{
|
||||
FCurve *fcu = BKE_fcurve_create();
|
||||
|
||||
EXPECT_EQ(insert_vert_fcurve(fcu, 1.0f, 7.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF), 0);
|
||||
EXPECT_EQ(insert_vert_fcurve(fcu, 2.0f, 13.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF), 1);
|
||||
EXPECT_EQ(insert_vert_fcurve(fcu, {1.0f, 7.0f}, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF),
|
||||
0);
|
||||
EXPECT_EQ(insert_vert_fcurve(fcu, {2.0f, 13.0f}, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF),
|
||||
1);
|
||||
|
||||
EXPECT_EQ(fcu->bezt[0].ipo, BEZT_IPO_BEZ);
|
||||
EXPECT_EQ(fcu->bezt[1].ipo, BEZT_IPO_BEZ);
|
||||
@ -121,8 +127,10 @@ TEST(evaluate_fcurve, InterpolationBounce)
|
||||
{
|
||||
FCurve *fcu = BKE_fcurve_create();
|
||||
|
||||
EXPECT_EQ(insert_vert_fcurve(fcu, 1.0f, 7.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF), 0);
|
||||
EXPECT_EQ(insert_vert_fcurve(fcu, 2.0f, 13.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF), 1);
|
||||
EXPECT_EQ(insert_vert_fcurve(fcu, {1.0f, 7.0f}, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF),
|
||||
0);
|
||||
EXPECT_EQ(insert_vert_fcurve(fcu, {2.0f, 13.0f}, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF),
|
||||
1);
|
||||
|
||||
fcu->bezt[0].ipo = BEZT_IPO_BOUNCE;
|
||||
fcu->bezt[1].ipo = BEZT_IPO_BOUNCE;
|
||||
@ -141,8 +149,10 @@ TEST(evaluate_fcurve, ExtrapolationLinearKeys)
|
||||
{
|
||||
FCurve *fcu = BKE_fcurve_create();
|
||||
|
||||
EXPECT_EQ(insert_vert_fcurve(fcu, 1.0f, 7.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF), 0);
|
||||
EXPECT_EQ(insert_vert_fcurve(fcu, 2.0f, 13.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF), 1);
|
||||
EXPECT_EQ(insert_vert_fcurve(fcu, {1.0f, 7.0f}, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF),
|
||||
0);
|
||||
EXPECT_EQ(insert_vert_fcurve(fcu, {2.0f, 13.0f}, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF),
|
||||
1);
|
||||
fcu->bezt[0].ipo = BEZT_IPO_LIN;
|
||||
fcu->bezt[1].ipo = BEZT_IPO_LIN;
|
||||
|
||||
@ -170,8 +180,10 @@ TEST(evaluate_fcurve, ExtrapolationBezierKeys)
|
||||
{
|
||||
FCurve *fcu = BKE_fcurve_create();
|
||||
|
||||
EXPECT_EQ(insert_vert_fcurve(fcu, 1.0f, 7.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF), 0);
|
||||
EXPECT_EQ(insert_vert_fcurve(fcu, 2.0f, 13.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF), 1);
|
||||
EXPECT_EQ(insert_vert_fcurve(fcu, {1.0f, 7.0f}, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF),
|
||||
0);
|
||||
EXPECT_EQ(insert_vert_fcurve(fcu, {2.0f, 13.0f}, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF),
|
||||
1);
|
||||
|
||||
fcu->bezt[0].vec[0][0] = 0.71855f; /* left handle X */
|
||||
fcu->bezt[0].vec[0][1] = 6.22482f; /* left handle Y */
|
||||
@ -207,8 +219,10 @@ TEST(fcurve_subdivide, BKE_fcurve_bezt_subdivide_handles)
|
||||
FCurve *fcu = BKE_fcurve_create();
|
||||
|
||||
/* Insert two keyframes and set handles to something non-default. */
|
||||
EXPECT_EQ(insert_vert_fcurve(fcu, 1.0f, 0.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF), 0);
|
||||
EXPECT_EQ(insert_vert_fcurve(fcu, 13.0f, 2.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF), 1);
|
||||
EXPECT_EQ(insert_vert_fcurve(fcu, {1.0f, 0.0f}, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF),
|
||||
0);
|
||||
EXPECT_EQ(insert_vert_fcurve(fcu, {13.0f, 2.0f}, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF),
|
||||
1);
|
||||
|
||||
fcu->bezt[0].h1 = fcu->bezt[0].h2 = HD_FREE;
|
||||
fcu->bezt[0].vec[0][0] = -5.0f;
|
||||
@ -273,11 +287,14 @@ TEST(fcurve_active_keyframe, ActiveKeyframe)
|
||||
EXPECT_EQ(BKE_fcurve_active_keyframe_index(fcu), FCURVE_ACTIVE_KEYFRAME_NONE);
|
||||
|
||||
/* Check that adding new points sets the active index. */
|
||||
EXPECT_EQ(insert_vert_fcurve(fcu, 1.0f, 7.5f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF), 0);
|
||||
EXPECT_EQ(insert_vert_fcurve(fcu, {1.0f, 7.5f}, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF),
|
||||
0);
|
||||
EXPECT_EQ(BKE_fcurve_active_keyframe_index(fcu), 0);
|
||||
EXPECT_EQ(insert_vert_fcurve(fcu, 8.0f, 15.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF), 1);
|
||||
EXPECT_EQ(insert_vert_fcurve(fcu, {8.0f, 15.0f}, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF),
|
||||
1);
|
||||
EXPECT_EQ(BKE_fcurve_active_keyframe_index(fcu), 1);
|
||||
EXPECT_EQ(insert_vert_fcurve(fcu, 14.0f, 8.2f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF), 2);
|
||||
EXPECT_EQ(insert_vert_fcurve(fcu, {14.0f, 8.2f}, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF),
|
||||
2);
|
||||
EXPECT_EQ(BKE_fcurve_active_keyframe_index(fcu), 2);
|
||||
|
||||
/* Check clearing the index. */
|
||||
@ -325,9 +342,9 @@ TEST(BKE_fcurve, BKE_fcurve_keyframe_move_value_with_handles)
|
||||
{
|
||||
FCurve *fcu = BKE_fcurve_create();
|
||||
|
||||
insert_vert_fcurve(fcu, 1.0f, 7.5f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF);
|
||||
insert_vert_fcurve(fcu, 8.0f, 15.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF);
|
||||
insert_vert_fcurve(fcu, 14.0f, 8.2f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF);
|
||||
insert_vert_fcurve(fcu, {1.0f, 7.5f}, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF);
|
||||
insert_vert_fcurve(fcu, {8.0f, 15.0f}, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF);
|
||||
insert_vert_fcurve(fcu, {14.0f, 8.2f}, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF);
|
||||
|
||||
EXPECT_FLOAT_EQ(fcu->bezt[1].vec[0][0], 5.2671194f);
|
||||
EXPECT_FLOAT_EQ(fcu->bezt[1].vec[0][1], 15.0f);
|
||||
@ -356,9 +373,9 @@ TEST(BKE_fcurve, BKE_fcurve_keyframe_move_time_with_handles)
|
||||
{
|
||||
FCurve *fcu = BKE_fcurve_create();
|
||||
|
||||
insert_vert_fcurve(fcu, 1.0f, 7.5f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF);
|
||||
insert_vert_fcurve(fcu, 8.0f, 15.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF);
|
||||
insert_vert_fcurve(fcu, 14.0f, 8.2f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF);
|
||||
insert_vert_fcurve(fcu, {1.0f, 7.5f}, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF);
|
||||
insert_vert_fcurve(fcu, {8.0f, 15.0f}, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF);
|
||||
insert_vert_fcurve(fcu, {14.0f, 8.2f}, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF);
|
||||
|
||||
EXPECT_FLOAT_EQ(fcu->bezt[1].vec[0][0], 5.2671194f);
|
||||
EXPECT_FLOAT_EQ(fcu->bezt[1].vec[0][1], 15.0f);
|
||||
@ -387,11 +404,11 @@ TEST(BKE_fcurve, BKE_fcurve_calc_range)
|
||||
{
|
||||
FCurve *fcu = BKE_fcurve_create();
|
||||
|
||||
insert_vert_fcurve(fcu, 1.0f, 7.5f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF);
|
||||
insert_vert_fcurve(fcu, 4.0f, -15.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF);
|
||||
insert_vert_fcurve(fcu, 8.0f, 15.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF);
|
||||
insert_vert_fcurve(fcu, 14.0f, 8.2f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF);
|
||||
insert_vert_fcurve(fcu, 18.2f, -20.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF);
|
||||
insert_vert_fcurve(fcu, {1.0f, 7.5f}, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF);
|
||||
insert_vert_fcurve(fcu, {4.0f, -15.0f}, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF);
|
||||
insert_vert_fcurve(fcu, {8.0f, 15.0f}, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF);
|
||||
insert_vert_fcurve(fcu, {14.0f, 8.2f}, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF);
|
||||
insert_vert_fcurve(fcu, {18.2f, -20.0f}, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF);
|
||||
|
||||
for (int i = 0; i < fcu->totvert; i++) {
|
||||
fcu->bezt[i].f1 &= ~SELECT;
|
||||
@ -439,11 +456,11 @@ TEST(BKE_fcurve, BKE_fcurve_calc_bounds)
|
||||
{
|
||||
FCurve *fcu = BKE_fcurve_create();
|
||||
|
||||
insert_vert_fcurve(fcu, 1.0f, 7.5f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF);
|
||||
insert_vert_fcurve(fcu, 4.0f, -15.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF);
|
||||
insert_vert_fcurve(fcu, 8.0f, 15.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF);
|
||||
insert_vert_fcurve(fcu, 14.0f, 8.2f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF);
|
||||
insert_vert_fcurve(fcu, 18.2f, -20.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF);
|
||||
insert_vert_fcurve(fcu, {1.0f, 7.5f}, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF);
|
||||
insert_vert_fcurve(fcu, {4.0f, -15.0f}, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF);
|
||||
insert_vert_fcurve(fcu, {8.0f, 15.0f}, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF);
|
||||
insert_vert_fcurve(fcu, {14.0f, 8.2f}, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF);
|
||||
insert_vert_fcurve(fcu, {18.2f, -20.0f}, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_NO_USERPREF);
|
||||
|
||||
for (int i = 0; i < fcu->totvert; i++) {
|
||||
fcu->bezt[i].f1 &= ~SELECT;
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "BLI_math_matrix.h"
|
||||
#include "BLI_math_rotation.h"
|
||||
#include "BLI_math_vector.h"
|
||||
#include "BLI_math_vector.hh"
|
||||
#include "BLI_math_vector_types.hh"
|
||||
#include "BLI_polyfill_2d.h"
|
||||
#include "BLI_span.hh"
|
||||
@ -115,10 +116,9 @@ std::optional<blender::Bounds<blender::float3>> BKE_gpencil_data_minmax(const bG
|
||||
|
||||
void BKE_gpencil_centroid_3d(bGPdata *gpd, float r_centroid[3])
|
||||
{
|
||||
const blender::Bounds<blender::float3> bounds = *BKE_gpencil_data_minmax(gpd);
|
||||
|
||||
const float3 tot = bounds.min + bounds.max;
|
||||
mul_v3_v3fl(r_centroid, tot, 0.5f);
|
||||
using namespace blender;
|
||||
const Bounds<float3> bounds = BKE_gpencil_data_minmax(gpd).value_or(Bounds(float3(0)));
|
||||
copy_v3_v3(r_centroid, math::midpoint(bounds.min, bounds.max));
|
||||
}
|
||||
|
||||
void BKE_gpencil_stroke_boundingbox_calc(bGPDstroke *gps)
|
||||
|
@ -440,7 +440,7 @@ TEST(lib_id_main_unique_name, name_number_suffix_assignment)
|
||||
|
||||
EXPECT_TRUE(BKE_main_namemap_validate(ctx.bmain));
|
||||
|
||||
/* Create objects again; they should get suffixes that were just free'd up. */
|
||||
/* Create objects again; they should get suffixes that were just freed up. */
|
||||
ID *id_010 = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo"));
|
||||
EXPECT_STREQ(id_010->name + 2, "Foo.010");
|
||||
ID *id_020 = static_cast<ID *>(BKE_id_new(ctx.bmain, ID_OB, "Foo.123"));
|
||||
|
@ -740,19 +740,77 @@ bool BKE_lib_override_library_create_from_tag(Main *bmain,
|
||||
struct LibOverrideGroupTagData {
|
||||
Main *bmain;
|
||||
Scene *scene;
|
||||
ID *id_root;
|
||||
ID *hierarchy_root_id;
|
||||
|
||||
/** The linked data used as reference for the liboverrides. */
|
||||
ID *id_root_reference;
|
||||
ID *hierarchy_root_id_reference;
|
||||
|
||||
/** The existing liboverrides, if any. */
|
||||
ID *id_root_override;
|
||||
ID *hierarchy_root_id_override;
|
||||
|
||||
/**
|
||||
* Whether we are looping on override data, or their references (linked) one.
|
||||
*
|
||||
* IMPORTANT: This value controls which of the `reference`/`override` ID pointers are accessed by
|
||||
* the `root`/`hierarchy_root` accessor functions below. */
|
||||
bool is_override;
|
||||
|
||||
ID *root_get()
|
||||
{
|
||||
return is_override ? id_root_override : id_root_reference;
|
||||
}
|
||||
void root_set(ID *id_root)
|
||||
{
|
||||
if (is_override) {
|
||||
id_root_override = id_root;
|
||||
}
|
||||
else {
|
||||
id_root_reference = id_root;
|
||||
}
|
||||
}
|
||||
ID *hierarchy_root_get()
|
||||
{
|
||||
return is_override ? hierarchy_root_id_override : hierarchy_root_id_reference;
|
||||
}
|
||||
void hierarchy_root_set(ID *hierarchy_root_id)
|
||||
{
|
||||
if (is_override) {
|
||||
hierarchy_root_id_override = hierarchy_root_id;
|
||||
}
|
||||
else {
|
||||
hierarchy_root_id_reference = hierarchy_root_id;
|
||||
}
|
||||
}
|
||||
|
||||
/** Whether we are creating new override, or resyncing existing one. */
|
||||
bool is_resync;
|
||||
|
||||
/** ID tag to use for IDs detected as being part of the liboverride hierarchy. */
|
||||
uint tag;
|
||||
uint missing_tag;
|
||||
/* Whether we are looping on override data, or their references (linked) one. */
|
||||
bool is_override;
|
||||
/* Whether we are creating new override, or resyncing existing one. */
|
||||
bool is_resync;
|
||||
|
||||
/* Mapping linked objects to all their instantiating collections (as a linked list).
|
||||
* Avoids calling #BKE_collection_object_find over and over, this function is very expansive. */
|
||||
GHash *linked_object_to_instantiating_collections;
|
||||
MemArena *mem_arena;
|
||||
|
||||
void clear(void)
|
||||
{
|
||||
BLI_ghash_free(linked_object_to_instantiating_collections, nullptr, nullptr);
|
||||
BLI_memarena_free(mem_arena);
|
||||
|
||||
bmain = nullptr;
|
||||
scene = nullptr;
|
||||
id_root_reference = nullptr;
|
||||
hierarchy_root_id_reference = nullptr;
|
||||
id_root_override = nullptr;
|
||||
hierarchy_root_id_override = nullptr;
|
||||
tag = 0;
|
||||
missing_tag = 0;
|
||||
is_override = false;
|
||||
is_resync = false;
|
||||
}
|
||||
};
|
||||
|
||||
static void lib_override_group_tag_data_object_to_collection_init_collection_process(
|
||||
@ -796,17 +854,10 @@ static void lib_override_group_tag_data_object_to_collection_init(LibOverrideGro
|
||||
}
|
||||
}
|
||||
|
||||
static void lib_override_group_tag_data_clear(LibOverrideGroupTagData *data)
|
||||
{
|
||||
BLI_ghash_free(data->linked_object_to_instantiating_collections, nullptr, nullptr);
|
||||
BLI_memarena_free(data->mem_arena);
|
||||
memset(data, 0, sizeof(*data));
|
||||
}
|
||||
|
||||
static void lib_override_hierarchy_dependencies_recursive_tag_from(LibOverrideGroupTagData *data)
|
||||
{
|
||||
Main *bmain = data->bmain;
|
||||
ID *id = data->id_root;
|
||||
ID *id = data->root_get();
|
||||
const bool is_override = data->is_override;
|
||||
|
||||
if ((*reinterpret_cast<uint *>(&id->tag) & data->tag) == 0) {
|
||||
@ -844,22 +895,22 @@ static void lib_override_hierarchy_dependencies_recursive_tag_from(LibOverrideGr
|
||||
continue;
|
||||
}
|
||||
from_id->tag |= data->tag;
|
||||
LibOverrideGroupTagData sub_data = *data;
|
||||
sub_data.id_root = from_id;
|
||||
lib_override_hierarchy_dependencies_recursive_tag_from(&sub_data);
|
||||
data->root_set(from_id);
|
||||
lib_override_hierarchy_dependencies_recursive_tag_from(data);
|
||||
}
|
||||
data->root_set(id);
|
||||
}
|
||||
|
||||
/* Tag all IDs in dependency relationships within an override hierarchy/group.
|
||||
*
|
||||
* Requires existing `Main.relations`.
|
||||
*
|
||||
* NOTE: This is typically called to complete `lib_override_linked_group_tag()`.
|
||||
* NOTE: This is typically called to complete #lib_override_linked_group_tag.
|
||||
*/
|
||||
static bool lib_override_hierarchy_dependencies_recursive_tag(LibOverrideGroupTagData *data)
|
||||
{
|
||||
Main *bmain = data->bmain;
|
||||
ID *id = data->id_root;
|
||||
ID *id = data->root_get();
|
||||
const bool is_override = data->is_override;
|
||||
const bool is_resync = data->is_resync;
|
||||
|
||||
@ -891,12 +942,12 @@ static bool lib_override_hierarchy_dependencies_recursive_tag(LibOverrideGroupTa
|
||||
* both barriers of dependency. */
|
||||
continue;
|
||||
}
|
||||
LibOverrideGroupTagData sub_data = *data;
|
||||
sub_data.id_root = to_id;
|
||||
if (lib_override_hierarchy_dependencies_recursive_tag(&sub_data)) {
|
||||
data->root_set(to_id);
|
||||
if (lib_override_hierarchy_dependencies_recursive_tag(data)) {
|
||||
id->tag |= data->tag;
|
||||
}
|
||||
}
|
||||
data->root_set(id);
|
||||
|
||||
/* If the current ID is/has been tagged for override above, then check its reversed dependencies
|
||||
* (i.e. IDs that depend on the current one).
|
||||
@ -913,7 +964,7 @@ static bool lib_override_hierarchy_dependencies_recursive_tag(LibOverrideGroupTa
|
||||
static void lib_override_linked_group_tag_recursive(LibOverrideGroupTagData *data)
|
||||
{
|
||||
Main *bmain = data->bmain;
|
||||
ID *id_owner = data->id_root;
|
||||
ID *id_owner = data->root_get();
|
||||
BLI_assert(ID_IS_LINKED(id_owner));
|
||||
BLI_assert(!data->is_override);
|
||||
const uint tag = data->tag;
|
||||
@ -962,10 +1013,10 @@ static void lib_override_linked_group_tag_recursive(LibOverrideGroupTagData *dat
|
||||
}
|
||||
|
||||
/* Recursively process the dependencies. */
|
||||
LibOverrideGroupTagData sub_data = *data;
|
||||
sub_data.id_root = to_id;
|
||||
lib_override_linked_group_tag_recursive(&sub_data);
|
||||
data->root_set(to_id);
|
||||
lib_override_linked_group_tag_recursive(data);
|
||||
}
|
||||
data->root_set(id_owner);
|
||||
}
|
||||
|
||||
static bool lib_override_linked_group_tag_collections_keep_tagged_check_recursive(
|
||||
@ -1007,11 +1058,14 @@ static bool lib_override_linked_group_tag_collections_keep_tagged_check_recursiv
|
||||
static void lib_override_linked_group_tag_clear_boneshapes_objects(LibOverrideGroupTagData *data)
|
||||
{
|
||||
Main *bmain = data->bmain;
|
||||
ID *id_root = data->id_root;
|
||||
ID *id_root = data->root_get();
|
||||
|
||||
/* Remove (untag) bone shape objects, they shall never need to be to directly/explicitly
|
||||
* overridden. */
|
||||
LISTBASE_FOREACH (Object *, ob, &bmain->objects) {
|
||||
if (ob->id.lib != id_root->lib) {
|
||||
continue;
|
||||
}
|
||||
if (ob->type == OB_ARMATURE && ob->pose != nullptr && (ob->id.tag & data->tag)) {
|
||||
for (bPoseChannel *pchan = static_cast<bPoseChannel *>(ob->pose->chanbase.first);
|
||||
pchan != nullptr;
|
||||
@ -1027,7 +1081,9 @@ static void lib_override_linked_group_tag_clear_boneshapes_objects(LibOverrideGr
|
||||
/* Remove (untag) collections if they do not own any tagged object (either themselves, or in
|
||||
* their children collections). */
|
||||
LISTBASE_FOREACH (Collection *, collection, &bmain->collections) {
|
||||
if ((collection->id.tag & data->tag) == 0 || &collection->id == id_root) {
|
||||
if ((collection->id.tag & data->tag) == 0 || &collection->id == id_root ||
|
||||
collection->id.lib != id_root->lib)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -1050,18 +1106,17 @@ static void lib_override_linked_group_tag_clear_boneshapes_objects(LibOverrideGr
|
||||
static void lib_override_linked_group_tag(LibOverrideGroupTagData *data)
|
||||
{
|
||||
Main *bmain = data->bmain;
|
||||
ID *id_root = data->id_root;
|
||||
ID *id_root = data->root_get();
|
||||
const bool is_resync = data->is_resync;
|
||||
BLI_assert(!data->is_override);
|
||||
|
||||
if (id_root->tag & LIB_TAG_MISSING) {
|
||||
id_root->tag |= data->missing_tag;
|
||||
}
|
||||
else {
|
||||
id_root->tag |= data->tag;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Tag all collections and objects recursively. */
|
||||
id_root->tag |= data->tag;
|
||||
lib_override_linked_group_tag_recursive(data);
|
||||
|
||||
/* Do not override objects used as bone shapes, nor their collections if possible. */
|
||||
@ -1133,11 +1188,11 @@ static void lib_override_linked_group_tag(LibOverrideGroupTagData *data)
|
||||
static void lib_override_overrides_group_tag_recursive(LibOverrideGroupTagData *data)
|
||||
{
|
||||
Main *bmain = data->bmain;
|
||||
ID *id_owner = data->id_root;
|
||||
ID *id_owner = data->root_get();
|
||||
BLI_assert(ID_IS_OVERRIDE_LIBRARY(id_owner));
|
||||
BLI_assert(data->is_override);
|
||||
|
||||
ID *id_hierarchy_root = data->hierarchy_root_id;
|
||||
ID *id_hierarchy_root = data->hierarchy_root_get();
|
||||
|
||||
if (ID_IS_OVERRIDE_LIBRARY_REAL(id_owner) &&
|
||||
(id_owner->override_library->flag & LIBOVERRIDE_FLAG_NO_HIERARCHY) != 0)
|
||||
@ -1200,20 +1255,20 @@ static void lib_override_overrides_group_tag_recursive(LibOverrideGroupTagData *
|
||||
}
|
||||
|
||||
/* Recursively process the dependencies. */
|
||||
LibOverrideGroupTagData sub_data = *data;
|
||||
sub_data.id_root = to_id;
|
||||
lib_override_overrides_group_tag_recursive(&sub_data);
|
||||
data->root_set(to_id);
|
||||
lib_override_overrides_group_tag_recursive(data);
|
||||
}
|
||||
data->root_set(id_owner);
|
||||
}
|
||||
|
||||
/* This will tag all override IDs of an override group defined by the given `id_root`. */
|
||||
static void lib_override_overrides_group_tag(LibOverrideGroupTagData *data)
|
||||
{
|
||||
ID *id_root = data->id_root;
|
||||
ID *id_root = data->root_get();
|
||||
BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id_root));
|
||||
BLI_assert(data->is_override);
|
||||
|
||||
ID *id_hierarchy_root = data->hierarchy_root_id;
|
||||
ID *id_hierarchy_root = data->hierarchy_root_get();
|
||||
BLI_assert(id_hierarchy_root != nullptr);
|
||||
BLI_assert(ID_IS_OVERRIDE_LIBRARY_REAL(id_hierarchy_root));
|
||||
UNUSED_VARS_NDEBUG(id_hierarchy_root);
|
||||
@ -1240,11 +1295,13 @@ static bool lib_override_library_create_do(Main *bmain,
|
||||
LibOverrideGroupTagData data{};
|
||||
data.bmain = bmain;
|
||||
data.scene = scene;
|
||||
data.id_root = id_root_reference;
|
||||
data.tag = LIB_TAG_DOIT;
|
||||
data.missing_tag = LIB_TAG_MISSING;
|
||||
data.is_override = false;
|
||||
data.is_resync = false;
|
||||
|
||||
data.root_set(id_root_reference);
|
||||
|
||||
lib_override_group_tag_data_object_to_collection_init(&data);
|
||||
lib_override_linked_group_tag(&data);
|
||||
|
||||
@ -1260,14 +1317,14 @@ static bool lib_override_library_create_do(Main *bmain,
|
||||
id_root_reference->lib);
|
||||
|
||||
BKE_main_relations_tag_set(bmain, MAINIDRELATIONS_ENTRY_TAGS_PROCESSED, false);
|
||||
data.hierarchy_root_id = id_hierarchy_root_reference;
|
||||
data.id_root = id_hierarchy_root_reference;
|
||||
data.is_override = true;
|
||||
data.root_set(id_hierarchy_root_reference);
|
||||
data.hierarchy_root_set(id_hierarchy_root_reference);
|
||||
lib_override_overrides_group_tag(&data);
|
||||
}
|
||||
|
||||
BKE_main_relations_free(bmain);
|
||||
lib_override_group_tag_data_clear(&data);
|
||||
data.clear();
|
||||
|
||||
bool success = false;
|
||||
if (id_hierarchy_root_reference->lib != id_root_reference->lib) {
|
||||
@ -1402,6 +1459,10 @@ static void lib_override_library_create_post_process(Main *bmain,
|
||||
ob_new->id.override_library->reference == &ob->id);
|
||||
|
||||
if (old_active_object == ob) {
|
||||
BLI_assert(view_layer);
|
||||
/* May have been tagged as dirty again in a previous iteration of this loop, e.g. if adding a
|
||||
* liboverride object to a collection. */
|
||||
BKE_view_layer_synced_ensure(scene, view_layer);
|
||||
Base *basact = BKE_view_layer_base_find(view_layer, ob_new);
|
||||
if (basact != nullptr) {
|
||||
view_layer->basact = basact;
|
||||
@ -1991,12 +2052,14 @@ static bool lib_override_library_resync(Main *bmain,
|
||||
LibOverrideGroupTagData data{};
|
||||
data.bmain = bmain;
|
||||
data.scene = scene;
|
||||
data.id_root = id_root;
|
||||
data.hierarchy_root_id = id_root->override_library->hierarchy_root;
|
||||
data.tag = LIB_TAG_DOIT;
|
||||
data.missing_tag = LIB_TAG_MISSING;
|
||||
data.is_override = true;
|
||||
data.is_resync = true;
|
||||
|
||||
data.root_set(id_root);
|
||||
data.hierarchy_root_set(id_root->override_library->hierarchy_root);
|
||||
|
||||
lib_override_group_tag_data_object_to_collection_init(&data);
|
||||
|
||||
/* Mapping 'linked reference IDs' -> 'Local override IDs' of existing overrides, populated from
|
||||
@ -2038,20 +2101,20 @@ static bool lib_override_library_resync(Main *bmain,
|
||||
id_root->name + 2);
|
||||
BLI_ghash_free(linkedref_to_old_override, nullptr, nullptr);
|
||||
BKE_main_relations_free(bmain);
|
||||
lib_override_group_tag_data_clear(&data);
|
||||
data.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Tag local overrides of the current resync sub-hierarchy. */
|
||||
BKE_main_relations_tag_set(bmain, MAINIDRELATIONS_ENTRY_TAGS_PROCESSED, false);
|
||||
data.id_root = id_resync_root;
|
||||
data.is_override = true;
|
||||
data.root_set(id_resync_root);
|
||||
lib_override_overrides_group_tag(&data);
|
||||
|
||||
/* Tag reference data matching the current resync sub-hierarchy. */
|
||||
BKE_main_relations_tag_set(bmain, MAINIDRELATIONS_ENTRY_TAGS_PROCESSED, false);
|
||||
data.id_root = id_resync_root->override_library->reference;
|
||||
data.is_override = false;
|
||||
data.root_set(id_resync_root->override_library->reference);
|
||||
lib_override_linked_group_tag(&data);
|
||||
|
||||
BKE_main_relations_tag_set(bmain, MAINIDRELATIONS_ENTRY_TAGS_PROCESSED, false);
|
||||
@ -2150,12 +2213,12 @@ static bool lib_override_library_resync(Main *bmain,
|
||||
|
||||
/* Tag all local overrides of the current hierarchy. */
|
||||
BKE_main_relations_tag_set(bmain, MAINIDRELATIONS_ENTRY_TAGS_PROCESSED, false);
|
||||
data.id_root = id_root;
|
||||
data.is_override = true;
|
||||
data.root_set(id_root);
|
||||
lib_override_overrides_group_tag(&data);
|
||||
|
||||
BKE_main_relations_free(bmain);
|
||||
lib_override_group_tag_data_clear(&data);
|
||||
data.clear();
|
||||
|
||||
/* Make new override from linked data. */
|
||||
/* Note that this call also remaps all pointers of tagged IDs from old override IDs to new
|
||||
@ -3080,7 +3143,6 @@ static bool lib_override_library_main_resync_on_library_indirect_level(
|
||||
LibOverrideGroupTagData data = {};
|
||||
data.bmain = bmain;
|
||||
data.scene = scene;
|
||||
data.id_root = nullptr;
|
||||
data.tag = LIB_TAG_DOIT;
|
||||
data.missing_tag = LIB_TAG_MISSING;
|
||||
data.is_override = false;
|
||||
@ -3097,14 +3159,14 @@ static bool lib_override_library_main_resync_on_library_indirect_level(
|
||||
continue;
|
||||
}
|
||||
|
||||
data.id_root = id->override_library->reference;
|
||||
data.root_set(id->override_library->reference);
|
||||
lib_override_linked_group_tag(&data);
|
||||
BKE_main_relations_tag_set(bmain, MAINIDRELATIONS_ENTRY_TAGS_PROCESSED, false);
|
||||
lib_override_hierarchy_dependencies_recursive_tag(&data);
|
||||
BKE_main_relations_tag_set(bmain, MAINIDRELATIONS_ENTRY_TAGS_PROCESSED, false);
|
||||
}
|
||||
FOREACH_MAIN_ID_END;
|
||||
lib_override_group_tag_data_clear(&data);
|
||||
data.clear();
|
||||
|
||||
GHash *id_roots = BLI_ghash_ptr_new(__func__);
|
||||
|
||||
@ -3569,17 +3631,19 @@ void BKE_lib_override_library_delete(Main *bmain, ID *id_root)
|
||||
LibOverrideGroupTagData data{};
|
||||
data.bmain = bmain;
|
||||
data.scene = nullptr;
|
||||
data.id_root = id_root;
|
||||
data.hierarchy_root_id = id_root->override_library->hierarchy_root;
|
||||
data.tag = LIB_TAG_DOIT;
|
||||
data.missing_tag = LIB_TAG_MISSING;
|
||||
data.is_override = true;
|
||||
data.is_resync = false;
|
||||
|
||||
data.root_set(id_root);
|
||||
data.hierarchy_root_set(id_root->override_library->hierarchy_root);
|
||||
|
||||
lib_override_group_tag_data_object_to_collection_init(&data);
|
||||
lib_override_overrides_group_tag(&data);
|
||||
|
||||
BKE_main_relations_free(bmain);
|
||||
lib_override_group_tag_data_clear(&data);
|
||||
data.clear();
|
||||
|
||||
ID *id;
|
||||
FOREACH_MAIN_ID_BEGIN (bmain, id) {
|
||||
|
@ -298,7 +298,7 @@ static void main_merge_add_id_to_move(Main *bmain_dst,
|
||||
void BKE_main_merge(Main *bmain_dst, Main **r_bmain_src, MainMergeReport &reports)
|
||||
{
|
||||
Main *bmain_src = *r_bmain_src;
|
||||
/* NOTE: Dedicated mapping type is needed here, to handle propoerly the library cases. */
|
||||
/* NOTE: Dedicated mapping type is needed here, to handle properly the library cases. */
|
||||
blender::Map<std::string, blender::Vector<ID *>> id_map_dst;
|
||||
ID *id_iter_dst, *id_iter_src;
|
||||
FOREACH_MAIN_ID_BEGIN (bmain_dst, id_iter_dst) {
|
||||
|
@ -212,7 +212,7 @@ TEST_F(BMainMergeTest, linked_data)
|
||||
|
||||
/* Use a relative library path. Since this is a different library, even though the object re-use
|
||||
* the same name, it should still be moved into `bmain_dst`. The library filepath should also be
|
||||
* updated and become relative the the path of bmain_dst too. */
|
||||
* updated and become relative the path of bmain_dst too. */
|
||||
bmain_src = BKE_main_new();
|
||||
BLI_strncpy(bmain_src->filepath, SRC_PATH, sizeof(bmain_dst->filepath));
|
||||
|
||||
|
@ -963,7 +963,7 @@ static void vnormal(PROCESS *process, const float point[3], float r_no[3])
|
||||
r_no[1] = metaball(process, point[0], point[1] + delta, point[2]) - f;
|
||||
r_no[2] = metaball(process, point[0], point[1], point[2] + delta) - f;
|
||||
}
|
||||
#endif /* USE_ACCUM_NORMAL */
|
||||
#endif /* !USE_ACCUM_NORMAL */
|
||||
|
||||
/**
|
||||
* \return the id of vertex between two corners.
|
||||
|
@ -535,7 +535,7 @@ void BKE_mesh_face_offsets_ensure_alloc(Mesh *mesh)
|
||||
mesh->runtime->face_offsets_sharing_info = blender::implicit_sharing::info_for_mem_free(
|
||||
mesh->face_offset_indices);
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifndef NDEBUG
|
||||
/* Fill offsets with obviously bad values to simplify finding missing initialization. */
|
||||
mesh->face_offsets_for_write().fill(-1);
|
||||
#endif
|
||||
@ -790,7 +790,7 @@ void BKE_mesh_texspace_calc(Mesh *me)
|
||||
using namespace blender;
|
||||
if (me->texspace_flag & ME_TEXSPACE_FLAG_AUTO) {
|
||||
const Bounds<float3> bounds = me->bounds_min_max().value_or(
|
||||
Bounds<float3>{float3(-1.0f), float3(1.0f)});
|
||||
Bounds(float3(-1.0f), float3(1.0f)));
|
||||
|
||||
float texspace_location[3], texspace_size[3];
|
||||
mid_v3_v3v3(texspace_location, bounds.min, bounds.max);
|
||||
|
@ -82,4 +82,4 @@ void BKE_mesh_debug_print(const Mesh *me)
|
||||
MEM_freeN(str);
|
||||
}
|
||||
|
||||
#endif /* NDEBUG */
|
||||
#endif /* !NDEBUG */
|
||||
|
@ -510,6 +510,8 @@ void BKE_mesh_mdisp_flip(MDisps *md, const bool use_loop_mdisp_flip)
|
||||
/** \name Visibility Interpolation
|
||||
* \{ */
|
||||
|
||||
namespace blender::bke {
|
||||
|
||||
/* Hide edges when either of their vertices are hidden. */
|
||||
static void edge_hide_from_vert(const Span<int2> edges,
|
||||
const Span<bool> hide_vert,
|
||||
@ -539,11 +541,9 @@ static void face_hide_from_vert(const OffsetIndices<int> faces,
|
||||
});
|
||||
}
|
||||
|
||||
void BKE_mesh_flush_hidden_from_verts(Mesh *me)
|
||||
void mesh_hide_vert_flush(Mesh &mesh)
|
||||
{
|
||||
using namespace blender;
|
||||
using namespace blender::bke;
|
||||
MutableAttributeAccessor attributes = me->attributes_for_write();
|
||||
MutableAttributeAccessor attributes = mesh.attributes_for_write();
|
||||
|
||||
const VArray<bool> hide_vert = *attributes.lookup_or_default<bool>(
|
||||
".hide_vert", ATTR_DOMAIN_POINT, false);
|
||||
@ -559,18 +559,16 @@ void BKE_mesh_flush_hidden_from_verts(Mesh *me)
|
||||
SpanAttributeWriter<bool> hide_poly = attributes.lookup_or_add_for_write_only_span<bool>(
|
||||
".hide_poly", ATTR_DOMAIN_FACE);
|
||||
|
||||
edge_hide_from_vert(me->edges(), hide_vert_span, hide_edge.span);
|
||||
face_hide_from_vert(me->faces(), me->corner_verts(), hide_vert_span, hide_poly.span);
|
||||
edge_hide_from_vert(mesh.edges(), hide_vert_span, hide_edge.span);
|
||||
face_hide_from_vert(mesh.faces(), mesh.corner_verts(), hide_vert_span, hide_poly.span);
|
||||
|
||||
hide_edge.finish();
|
||||
hide_poly.finish();
|
||||
}
|
||||
|
||||
void BKE_mesh_flush_hidden_from_faces(Mesh *me)
|
||||
void mesh_hide_face_flush(Mesh &mesh)
|
||||
{
|
||||
using namespace blender;
|
||||
using namespace blender::bke;
|
||||
MutableAttributeAccessor attributes = me->attributes_for_write();
|
||||
MutableAttributeAccessor attributes = mesh.attributes_for_write();
|
||||
|
||||
const VArray<bool> hide_poly = *attributes.lookup_or_default<bool>(
|
||||
".hide_poly", ATTR_DOMAIN_FACE, false);
|
||||
@ -580,9 +578,9 @@ void BKE_mesh_flush_hidden_from_faces(Mesh *me)
|
||||
return;
|
||||
}
|
||||
const VArraySpan<bool> hide_poly_span{hide_poly};
|
||||
const OffsetIndices faces = me->faces();
|
||||
const Span<int> corner_verts = me->corner_verts();
|
||||
const Span<int> corner_edges = me->corner_edges();
|
||||
const OffsetIndices faces = mesh.faces();
|
||||
const Span<int> corner_verts = mesh.corner_verts();
|
||||
const Span<int> corner_edges = mesh.corner_edges();
|
||||
SpanAttributeWriter<bool> hide_vert = attributes.lookup_or_add_for_write_only_span<bool>(
|
||||
".hide_vert", ATTR_DOMAIN_POINT);
|
||||
SpanAttributeWriter<bool> hide_edge = attributes.lookup_or_add_for_write_only_span<bool>(
|
||||
@ -617,11 +615,9 @@ void BKE_mesh_flush_hidden_from_faces(Mesh *me)
|
||||
/** \name Selection Interpolation
|
||||
* \{ */
|
||||
|
||||
void BKE_mesh_flush_select_from_faces(Mesh *me)
|
||||
void mesh_select_face_flush(Mesh &mesh)
|
||||
{
|
||||
using namespace blender;
|
||||
using namespace blender::bke;
|
||||
MutableAttributeAccessor attributes = me->attributes_for_write();
|
||||
MutableAttributeAccessor attributes = mesh.attributes_for_write();
|
||||
const VArray<bool> select_poly = *attributes.lookup_or_default<bool>(
|
||||
".select_poly", ATTR_DOMAIN_FACE, false);
|
||||
if (select_poly.is_single() && !select_poly.get_internal_single()) {
|
||||
@ -645,11 +641,9 @@ void BKE_mesh_flush_select_from_faces(Mesh *me)
|
||||
select_edge.finish();
|
||||
}
|
||||
|
||||
void BKE_mesh_flush_select_from_verts(Mesh *me)
|
||||
void mesh_select_vert_flush(Mesh &mesh)
|
||||
{
|
||||
using namespace blender;
|
||||
using namespace blender::bke;
|
||||
MutableAttributeAccessor attributes = me->attributes_for_write();
|
||||
MutableAttributeAccessor attributes = mesh.attributes_for_write();
|
||||
const VArray<bool> select_vert = *attributes.lookup_or_default<bool>(
|
||||
".select_vert", ATTR_DOMAIN_POINT, false);
|
||||
if (select_vert.is_single() && !select_vert.get_internal_single()) {
|
||||
@ -683,11 +677,9 @@ void BKE_mesh_flush_select_from_verts(Mesh *me)
|
||||
select_poly.finish();
|
||||
}
|
||||
|
||||
void BKE_mesh_flush_select_from_edges(Mesh *me)
|
||||
void mesh_select_edge_flush(Mesh &mesh)
|
||||
{
|
||||
using namespace blender;
|
||||
using namespace blender::bke;
|
||||
MutableAttributeAccessor attributes = me->attributes_for_write();
|
||||
MutableAttributeAccessor attributes = mesh.attributes_for_write();
|
||||
const VArray<bool> select_edge = *attributes.lookup_or_default<bool>(
|
||||
".select_edge", ATTR_DOMAIN_POINT, false);
|
||||
if (select_edge.is_single() && !select_edge.get_internal_single()) {
|
||||
@ -721,6 +713,8 @@ void BKE_mesh_flush_select_from_edges(Mesh *me)
|
||||
select_poly.finish();
|
||||
}
|
||||
|
||||
} // namespace blender::bke
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
@ -23,8 +23,8 @@
|
||||
#include "BKE_mesh_fair.hh"
|
||||
#include "BKE_mesh_mapping.hh"
|
||||
|
||||
#include "bmesh.h"
|
||||
#include "bmesh_tools.h"
|
||||
#include "bmesh.hh"
|
||||
#include "bmesh_tools.hh"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
#include "eigen_capi.h"
|
||||
@ -207,7 +207,7 @@ class MeshFairingContext : public FairingContext {
|
||||
vlmap_ = mesh->vert_to_corner_map();
|
||||
|
||||
/* Deformation coords. */
|
||||
co_.reserve(mesh->totvert);
|
||||
co_.resize(mesh->totvert);
|
||||
if (!deform_positions.is_empty()) {
|
||||
for (int i = 0; i < mesh->totvert; i++) {
|
||||
co_[i] = deform_positions[i];
|
||||
@ -261,7 +261,7 @@ class BMeshFairingContext : public FairingContext {
|
||||
BM_mesh_elem_index_ensure(bm, BM_LOOP);
|
||||
|
||||
/* Deformation coords. */
|
||||
co_.reserve(bm->totvert);
|
||||
co_.resize(bm->totvert);
|
||||
for (int i = 0; i < bm->totvert; i++) {
|
||||
BMVert *v = BM_vert_at_index(bm, i);
|
||||
co_[i] = v->co;
|
||||
@ -319,7 +319,7 @@ class UniformVertexWeight : public VertexWeight {
|
||||
UniformVertexWeight(FairingContext *fairing_context)
|
||||
{
|
||||
const int totvert = fairing_context->vertex_count_get();
|
||||
vertex_weights_.reserve(totvert);
|
||||
vertex_weights_.resize(totvert);
|
||||
for (int i = 0; i < totvert; i++) {
|
||||
const int tot_loop = fairing_context->vertex_loop_map_get(i).size();
|
||||
if (tot_loop != 0) {
|
||||
@ -347,7 +347,7 @@ class VoronoiVertexWeight : public VertexWeight {
|
||||
{
|
||||
|
||||
const int totvert = fairing_context->vertex_count_get();
|
||||
vertex_weights_.reserve(totvert);
|
||||
vertex_weights_.resize(totvert);
|
||||
for (int i = 0; i < totvert; i++) {
|
||||
|
||||
float area = 0.0f;
|
||||
|
@ -650,7 +650,7 @@ static bool check_matching_legacy_layer_counts(CustomData *fdata_legacy,
|
||||
* then there was nothing to do... */
|
||||
return a_num ? true : fallback;
|
||||
}
|
||||
#endif
|
||||
#endif /* !NDEBUG */
|
||||
|
||||
static void add_mface_layers(Mesh &mesh, CustomData *fdata_legacy, CustomData *ldata, int total)
|
||||
{
|
||||
|
@ -23,8 +23,8 @@
|
||||
#include "BKE_mesh_mirror.hh"
|
||||
#include "BKE_modifier.hh"
|
||||
|
||||
#include "bmesh.h"
|
||||
#include "bmesh_tools.h"
|
||||
#include "bmesh.hh"
|
||||
#include "bmesh_tools.hh"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
|
@ -39,7 +39,7 @@
|
||||
#include "BKE_mesh_runtime.hh"
|
||||
#include "BKE_mesh_sample.hh"
|
||||
|
||||
#include "bmesh_tools.h"
|
||||
#include "bmesh_tools.hh"
|
||||
|
||||
#ifdef WITH_OPENVDB
|
||||
# include <openvdb/openvdb.h>
|
||||
|
@ -473,6 +473,6 @@ bool BKE_mesh_runtime_is_valid(Mesh *me_eval)
|
||||
return is_valid;
|
||||
}
|
||||
|
||||
#endif /* NDEBUG */
|
||||
#endif /* !NDEBUG */
|
||||
|
||||
/** \} */
|
||||
|
@ -74,7 +74,7 @@ Mesh *BKE_mesh_wrapper_from_editmesh(BMEditMesh *em,
|
||||
me->edit_mesh->is_shallow_copy = true;
|
||||
|
||||
/* Make sure we crash if these are ever used. */
|
||||
#ifdef DEBUG
|
||||
#ifndef NDEBUG
|
||||
me->totvert = INT_MAX;
|
||||
me->totedge = INT_MAX;
|
||||
me->faces_num = INT_MAX;
|
||||
|
@ -29,7 +29,7 @@
|
||||
#include "BKE_subdiv.hh"
|
||||
#include "BKE_subsurf.hh"
|
||||
|
||||
#include "bmesh.h"
|
||||
#include "bmesh.hh"
|
||||
|
||||
#include "DEG_depsgraph_query.hh"
|
||||
|
||||
|
@ -3413,7 +3413,7 @@ static void free_localized_node_groups(bNodeTree *ntree)
|
||||
{
|
||||
/* Only localized node trees store a copy for each node group tree.
|
||||
* Each node group tree in a localized node tree can be freed,
|
||||
* since it is a localized copy itself (no risk of accessing free'd
|
||||
* since it is a localized copy itself (no risk of accessing freed
|
||||
* data in main, see #37939). */
|
||||
if (!(ntree->id.tag & LIB_TAG_LOCALIZED)) {
|
||||
return;
|
||||
|
@ -512,7 +512,7 @@ class NodeTreeMainUpdater {
|
||||
result.interface_changed = true;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifndef NDEBUG
|
||||
/* Check the uniqueness of node identifiers. */
|
||||
Set<int32_t> node_identifiers;
|
||||
const Span<const bNode *> nodes = ntree.all_nodes();
|
||||
|
@ -73,7 +73,7 @@
|
||||
|
||||
#include "BLO_read_write.hh"
|
||||
|
||||
#include "bmesh.h"
|
||||
#include "bmesh.hh"
|
||||
|
||||
using blender::float3;
|
||||
using blender::MutableSpan;
|
||||
@ -773,15 +773,6 @@ void BKE_paint_palette_set(Paint *p, Palette *palette)
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_paint_curve_set(Brush *br, PaintCurve *pc)
|
||||
{
|
||||
if (br) {
|
||||
id_us_min((ID *)br->paint_curve);
|
||||
br->paint_curve = pc;
|
||||
id_us_plus((ID *)br->paint_curve);
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_paint_curve_clamp_endpoint_add_index(PaintCurve *pc, const int add_index)
|
||||
{
|
||||
pc->add_index = (add_index || pc->tot_points == 1) ? (add_index + 1) : 0;
|
||||
@ -1121,7 +1112,7 @@ bool BKE_paint_ensure(ToolSettings *ts, Paint **r_paint)
|
||||
(Paint *)ts->uvsculpt,
|
||||
(Paint *)ts->curves_sculpt,
|
||||
(Paint *)&ts->imapaint));
|
||||
#ifdef DEBUG
|
||||
#ifndef NDEBUG
|
||||
Paint paint_test = **r_paint;
|
||||
BKE_paint_runtime_init(ts, *r_paint);
|
||||
/* Swap so debug doesn't hide errors when release fails. */
|
||||
@ -1736,15 +1727,14 @@ static void sculpt_update_object(Depsgraph *depsgraph,
|
||||
|
||||
/* Sculpt Face Sets. */
|
||||
if (use_face_sets) {
|
||||
ss->face_sets = static_cast<int *>(CustomData_get_layer_named_for_write(
|
||||
&me->face_data, CD_PROP_INT32, ".sculpt_face_set", me->faces_num));
|
||||
ss->face_sets = static_cast<const int *>(
|
||||
CustomData_get_layer_named(&me->face_data, CD_PROP_INT32, ".sculpt_face_set"));
|
||||
}
|
||||
else {
|
||||
ss->face_sets = nullptr;
|
||||
}
|
||||
|
||||
ss->hide_poly = (bool *)CustomData_get_layer_named_for_write(
|
||||
&me->face_data, CD_PROP_BOOL, ".hide_poly", me->faces_num);
|
||||
ss->hide_poly = (bool *)CustomData_get_layer_named(&me->face_data, CD_PROP_BOOL, ".hide_poly");
|
||||
|
||||
ss->subdiv_ccg = me_eval->runtime->subdiv_ccg.get();
|
||||
|
||||
@ -1940,63 +1930,11 @@ void BKE_sculpt_update_object_for_edit(Depsgraph *depsgraph, Object *ob_orig, bo
|
||||
sculpt_update_object(depsgraph, ob_orig, ob_eval, is_paint_tool);
|
||||
}
|
||||
|
||||
int *BKE_sculpt_face_sets_ensure(Object *ob)
|
||||
void BKE_sculpt_hide_poly_pointer_update(Object &object)
|
||||
{
|
||||
using namespace blender;
|
||||
using namespace blender::bke;
|
||||
Mesh *mesh = static_cast<Mesh *>(ob->data);
|
||||
SculptSession *ss = ob->sculpt;
|
||||
PBVH *pbvh = ss->pbvh;
|
||||
if (!pbvh) {
|
||||
BLI_assert_unreachable();
|
||||
return nullptr;
|
||||
}
|
||||
const StringRefNull name = ".sculpt_face_set";
|
||||
|
||||
switch (BKE_pbvh_type(pbvh)) {
|
||||
case PBVH_FACES:
|
||||
case PBVH_GRIDS: {
|
||||
MutableAttributeAccessor attributes = mesh->attributes_for_write();
|
||||
if (!attributes.contains(name)) {
|
||||
attributes.add<int>(name,
|
||||
ATTR_DOMAIN_FACE,
|
||||
AttributeInitVArray(VArray<int>::ForSingle(1, mesh->faces_num)));
|
||||
mesh->face_sets_color_default = 1;
|
||||
}
|
||||
return static_cast<int *>(CustomData_get_layer_named_for_write(
|
||||
&mesh->face_data, CD_PROP_INT32, name.c_str(), mesh->faces_num));
|
||||
}
|
||||
case PBVH_BMESH: {
|
||||
BMesh *bm = BKE_pbvh_get_bmesh(pbvh);
|
||||
if (!CustomData_has_layer_named(&bm->pdata, CD_PROP_INT32, name.c_str())) {
|
||||
BM_data_layer_add_named(bm, &bm->pdata, CD_PROP_INT32, name.c_str());
|
||||
const int offset = CustomData_get_offset_named(&bm->pdata, CD_PROP_INT32, name.c_str());
|
||||
if (offset == -1) {
|
||||
return nullptr;
|
||||
}
|
||||
BMIter iter;
|
||||
BMFace *face;
|
||||
BM_ITER_MESH (face, &iter, bm, BM_FACES_OF_MESH) {
|
||||
BM_ELEM_CD_SET_INT(face, offset, 1);
|
||||
}
|
||||
mesh->face_sets_color_default = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool *BKE_sculpt_hide_poly_ensure(Mesh *mesh)
|
||||
{
|
||||
bool *hide_poly = static_cast<bool *>(CustomData_get_layer_named_for_write(
|
||||
&mesh->face_data, CD_PROP_BOOL, ".hide_poly", mesh->faces_num));
|
||||
if (hide_poly != nullptr) {
|
||||
return hide_poly;
|
||||
}
|
||||
return static_cast<bool *>(CustomData_add_layer_named(
|
||||
&mesh->face_data, CD_PROP_BOOL, CD_SET_DEFAULT, mesh->faces_num, ".hide_poly"));
|
||||
const Mesh &mesh = *static_cast<const Mesh *>(object.data);
|
||||
object.sculpt->hide_poly = static_cast<const bool *>(
|
||||
CustomData_get_layer_named(&mesh.face_data, CD_PROP_BOOL, ".hide_poly"));
|
||||
}
|
||||
|
||||
void BKE_sculpt_mask_layers_ensure(Depsgraph *depsgraph,
|
||||
@ -2601,22 +2539,6 @@ static SculptAttribute *sculpt_get_cached_layer(SculptSession *ss,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool BKE_sculpt_attribute_exists(Object *ob,
|
||||
eAttrDomain domain,
|
||||
eCustomDataType proptype,
|
||||
const char *name)
|
||||
{
|
||||
SculptSession *ss = ob->sculpt;
|
||||
SculptAttribute *attr = sculpt_get_cached_layer(ss, domain, proptype, name);
|
||||
|
||||
if (attr) {
|
||||
return true;
|
||||
}
|
||||
|
||||
CustomData *cdata = sculpt_get_cdata(ob, domain);
|
||||
return CustomData_get_named_layer_index(cdata, proptype, name) != -1;
|
||||
}
|
||||
|
||||
static SculptAttribute *sculpt_alloc_attr(SculptSession *ss)
|
||||
{
|
||||
for (int i = 0; i < SCULPT_MAX_ATTRIBUTES; i++) {
|
||||
|
@ -41,7 +41,7 @@
|
||||
|
||||
#include "PIL_time.h"
|
||||
|
||||
#include "bmesh.h"
|
||||
#include "bmesh.hh"
|
||||
|
||||
#include "atomic_ops.h"
|
||||
|
||||
@ -1811,9 +1811,8 @@ blender::Span<int> BKE_pbvh_node_get_unique_vert_indices(const PBVHNode *node)
|
||||
return node->vert_indices.as_span().take_front(node->uniq_verts);
|
||||
}
|
||||
|
||||
blender::Vector<int> BKE_pbvh_node_calc_face_indices(const PBVH &pbvh, const PBVHNode &node)
|
||||
void BKE_pbvh_node_calc_face_indices(const PBVH &pbvh, const PBVHNode &node, Vector<int> &faces)
|
||||
{
|
||||
Vector<int> faces;
|
||||
switch (pbvh.header.type) {
|
||||
case PBVH_FACES: {
|
||||
const Span<int> looptri_faces = pbvh.looptri_faces;
|
||||
@ -1843,7 +1842,12 @@ blender::Vector<int> BKE_pbvh_node_calc_face_indices(const PBVH &pbvh, const PBV
|
||||
BLI_assert_unreachable();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
blender::Vector<int> BKE_pbvh_node_calc_face_indices(const PBVH &pbvh, const PBVHNode &node)
|
||||
{
|
||||
Vector<int> faces;
|
||||
BKE_pbvh_node_calc_face_indices(pbvh, node, faces);
|
||||
return faces;
|
||||
}
|
||||
|
||||
@ -2667,12 +2671,15 @@ static blender::draw::pbvh::PBVH_GPU_Args pbvh_draw_args_init(const Mesh &mesh,
|
||||
PBVH &pbvh,
|
||||
const PBVHNode &node)
|
||||
{
|
||||
/* TODO: Use an explicit argument for the original mesh to avoid relying on #PBVH::mesh. */
|
||||
blender::draw::pbvh::PBVH_GPU_Args args{};
|
||||
|
||||
args.pbvh_type = pbvh.header.type;
|
||||
|
||||
args.face_sets_color_default = mesh.face_sets_color_default;
|
||||
args.face_sets_color_seed = mesh.face_sets_color_seed;
|
||||
args.face_sets_color_default = pbvh.mesh ? pbvh.mesh->face_sets_color_default :
|
||||
mesh.face_sets_color_default;
|
||||
args.face_sets_color_seed = pbvh.mesh ? pbvh.mesh->face_sets_color_seed :
|
||||
mesh.face_sets_color_seed;
|
||||
|
||||
args.active_color = mesh.active_color_attribute;
|
||||
args.render_color = mesh.default_color_attribute;
|
||||
@ -3206,7 +3213,7 @@ void BKE_pbvh_sync_visibility_from_verts(PBVH *pbvh, Mesh *mesh)
|
||||
using namespace blender::bke;
|
||||
switch (pbvh->header.type) {
|
||||
case PBVH_FACES: {
|
||||
BKE_mesh_flush_hidden_from_verts(mesh);
|
||||
mesh_hide_vert_flush(*mesh);
|
||||
break;
|
||||
}
|
||||
case PBVH_BMESH: {
|
||||
@ -3269,7 +3276,7 @@ void BKE_pbvh_sync_visibility_from_verts(PBVH *pbvh, Mesh *mesh)
|
||||
hide_poly.finish();
|
||||
}
|
||||
|
||||
BKE_mesh_flush_hidden_from_faces(mesh);
|
||||
mesh_hide_face_flush(*mesh);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
#include "DRW_pbvh.hh"
|
||||
|
||||
#include "bmesh.h"
|
||||
#include "bmesh.hh"
|
||||
#include "pbvh_intern.hh"
|
||||
|
||||
#include "PIL_time.h"
|
||||
@ -1117,7 +1117,7 @@ static void short_edge_queue_create(EdgeQueueContext *eq_ctx,
|
||||
static void copy_edge_data(BMesh &bm, BMEdge &dst, /*const*/ BMEdge &src)
|
||||
{
|
||||
dst.head.hflag = src.head.hflag & ~BM_ELEM_TAG;
|
||||
CustomData_bmesh_copy_data(&bm.edata, &bm.edata, src.head.data, &dst.head.data);
|
||||
CustomData_bmesh_copy_block(bm.edata, src.head.data, &dst.head.data);
|
||||
}
|
||||
|
||||
/* Merge edge custom data from src to dst. */
|
||||
|
@ -32,7 +32,7 @@
|
||||
|
||||
#include "PIL_time.h"
|
||||
|
||||
#include "bmesh.h"
|
||||
#include "bmesh.hh"
|
||||
|
||||
#include "atomic_ops.h"
|
||||
|
||||
|
@ -67,7 +67,7 @@ struct rbCollisionShape;
|
||||
struct rbConstraint;
|
||||
struct rbDynamicsWorld;
|
||||
struct rbRigidBody;
|
||||
#endif
|
||||
#endif /* !WITH_BULLET */
|
||||
|
||||
/* ************************************** */
|
||||
/* Memory Management */
|
||||
|
@ -116,7 +116,7 @@
|
||||
|
||||
#include "DRW_engine.h"
|
||||
|
||||
#include "bmesh.h"
|
||||
#include "bmesh.hh"
|
||||
|
||||
CurveMapping *BKE_sculpt_default_cavity_curve()
|
||||
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include "opensubdiv_capi.h"
|
||||
#include "opensubdiv_converter_capi.h"
|
||||
|
||||
#include "bmesh_class.h"
|
||||
#include "bmesh_class.hh"
|
||||
|
||||
/* Enable work-around for non-working CPU evaluator when using bilinear scheme.
|
||||
* This forces Catmark scheme with all edges marked as infinitely sharp. */
|
||||
|
@ -2370,7 +2370,7 @@ int text_check_identifier_nodigit_unicode(const uint ch)
|
||||
{
|
||||
return (ch < 255 && text_check_identifier_nodigit(char(ch)));
|
||||
}
|
||||
#endif /* WITH_PYTHON */
|
||||
#endif /* !WITH_PYTHON */
|
||||
|
||||
bool text_check_whitespace(const char ch)
|
||||
{
|
||||
|
@ -379,7 +379,7 @@ WorkSpaceLayout *BKE_workspace_layout_add(Main *bmain,
|
||||
WorkSpaceLayout *layout = MEM_cnew<WorkSpaceLayout>(__func__);
|
||||
|
||||
BLI_assert(!workspaces_is_screen_used(bmain, screen));
|
||||
#ifndef DEBUG
|
||||
#ifdef NDEBUG
|
||||
UNUSED_VARS(bmain);
|
||||
#endif
|
||||
layout->screen = screen;
|
||||
|
@ -567,7 +567,7 @@ static const AVCodec *get_av1_encoder(
|
||||
break;
|
||||
}
|
||||
if (context->ffmpeg_crf >= 0) {
|
||||
/* `libsvtav1` does not support `crf` until FFmpeg builds since 2022-02-24,
|
||||
/* `libsvtav1` does not support CRF until FFMPEG builds since 2022-02-24,
|
||||
* use `qp` as fallback. */
|
||||
ffmpeg_dict_set_int(opts, "qp", context->ffmpeg_crf);
|
||||
}
|
||||
@ -762,9 +762,9 @@ static AVStream *alloc_video_stream(FFMpegContext *context,
|
||||
}
|
||||
else if (context->ffmpeg_crf >= 0) {
|
||||
/* As per https://trac.ffmpeg.org/wiki/Encode/VP9 we must set the bit rate to zero when
|
||||
* encoding with vp9 in crf mode.
|
||||
* encoding with VP9 in CRF mode.
|
||||
* Set this to always be zero for other codecs as well.
|
||||
* We don't care about bit rate in crf mode. */
|
||||
* We don't care about bit rate in CRF mode. */
|
||||
c->bit_rate = 0;
|
||||
ffmpeg_dict_set_int(&opts, "crf", context->ffmpeg_crf);
|
||||
}
|
||||
@ -776,11 +776,11 @@ static AVStream *alloc_video_stream(FFMpegContext *context,
|
||||
}
|
||||
|
||||
if (context->ffmpeg_preset) {
|
||||
/* 'preset' is used by h.264, 'deadline' is used by webm/vp9. I'm not
|
||||
/* 'preset' is used by h.264, 'deadline' is used by WEBM/VP9. I'm not
|
||||
* setting those properties conditionally based on the video codec,
|
||||
* as the FFmpeg encoder simply ignores unknown settings anyway. */
|
||||
char const *preset_name = nullptr; /* used by h.264 */
|
||||
char const *deadline_name = nullptr; /* used by webm/vp9 */
|
||||
char const *preset_name = nullptr; /* Used by h.264. */
|
||||
char const *deadline_name = nullptr; /* Used by WEBM/VP9. */
|
||||
switch (context->ffmpeg_preset) {
|
||||
case FFM_PRESET_GOOD:
|
||||
preset_name = "medium";
|
||||
@ -818,7 +818,7 @@ static AVStream *alloc_video_stream(FFMpegContext *context,
|
||||
}
|
||||
|
||||
if (context->ffmpeg_type == FFMPEG_XVID) {
|
||||
/* arghhhh ... */
|
||||
/* Alas! */
|
||||
c->pix_fmt = AV_PIX_FMT_YUV420P;
|
||||
c->codec_tag = (('D' << 24) + ('I' << 16) + ('V' << 8) + 'X');
|
||||
}
|
||||
@ -903,7 +903,7 @@ static AVStream *alloc_video_stream(FFMpegContext *context,
|
||||
}
|
||||
av_dict_free(&opts);
|
||||
|
||||
/* FFmpeg expects its data in the output pixel format. */
|
||||
/* FFMPEG expects its data in the output pixel format. */
|
||||
context->current_frame = alloc_picture(c->pix_fmt, c->width, c->height);
|
||||
|
||||
if (c->pix_fmt == AV_PIX_FMT_RGBA) {
|
||||
@ -1003,8 +1003,8 @@ static AVStream *alloc_audio_stream(FFMpegContext *context,
|
||||
|
||||
if (codec->sample_fmts) {
|
||||
/* Check if the preferred sample format for this codec is supported.
|
||||
* this is because, depending on the version of libav,
|
||||
* and with the whole ffmpeg/libav fork situation,
|
||||
* this is because, depending on the version of LIBAV,
|
||||
* and with the whole FFMPEG/LIBAV fork situation,
|
||||
* you have various implementations around.
|
||||
* Float samples in particular are not always supported. */
|
||||
const enum AVSampleFormat *p = codec->sample_fmts;
|
||||
@ -1051,14 +1051,14 @@ static AVStream *alloc_audio_stream(FFMpegContext *context,
|
||||
}
|
||||
|
||||
/* Need to prevent floating point exception when using VORBIS audio codec,
|
||||
* initialize this value in the same way as it's done in FFmpeg itself (sergey) */
|
||||
* initialize this value in the same way as it's done in FFMPEG itself (sergey) */
|
||||
c->time_base.num = 1;
|
||||
c->time_base.den = c->sample_rate;
|
||||
|
||||
if (c->frame_size == 0) {
|
||||
/* Used to be if ((c->codec_id >= CODEC_ID_PCM_S16LE) && (c->codec_id <= CODEC_ID_PCM_DVD))
|
||||
* not sure if that is needed anymore, so let's try out if there are any
|
||||
* complaints regarding some FFmpeg versions users might have. */
|
||||
* complaints regarding some FFMPEG versions users might have. */
|
||||
context->audio_input_samples = AV_INPUT_BUFFER_MIN_SIZE * 8 / c->bits_per_coded_sample /
|
||||
num_channels;
|
||||
}
|
||||
@ -1134,7 +1134,7 @@ static int start_ffmpeg_impl(FFMpegContext *context,
|
||||
/* Determine the correct filename */
|
||||
ffmpeg_filepath_get(context, filepath, rd, context->ffmpeg_preview, suffix);
|
||||
PRINT(
|
||||
"Starting output to %s(ffmpeg)...\n"
|
||||
"Starting output to %s(FFMPEG)...\n"
|
||||
" Using type=%d, codec=%d, audio_codec=%d,\n"
|
||||
" video_bitrate=%d, audio_bitrate=%d,\n"
|
||||
" gop_size=%d, autosplit=%d\n"
|
||||
@ -1165,7 +1165,7 @@ static int start_ffmpeg_impl(FFMpegContext *context,
|
||||
|
||||
of = avformat_alloc_context();
|
||||
if (!of) {
|
||||
BKE_report(reports, RPT_ERROR, "Can't allocate ffmpeg format context");
|
||||
BKE_report(reports, RPT_ERROR, "Can't allocate FFMPEG format context");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1236,7 +1236,7 @@ static int start_ffmpeg_impl(FFMpegContext *context,
|
||||
if (context->ffmpeg_audio_codec != AV_CODEC_ID_NONE &&
|
||||
rd->ffcodecdata.audio_mixrate != 48000 && rd->ffcodecdata.audio_channels != 2)
|
||||
{
|
||||
BKE_report(reports, RPT_ERROR, "FFmpeg only supports 48khz / stereo audio for DV!");
|
||||
BKE_report(reports, RPT_ERROR, "FFMPEG only supports 48khz / stereo audio for DV!");
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
@ -1571,7 +1571,7 @@ int BKE_ffmpeg_append(void *context_v,
|
||||
|
||||
static void end_ffmpeg_impl(FFMpegContext *context, int is_autosplit)
|
||||
{
|
||||
PRINT("Closing ffmpeg...\n");
|
||||
PRINT("Closing FFMPEG...\n");
|
||||
|
||||
# ifdef WITH_AUDASPACE
|
||||
if (is_autosplit == false) {
|
||||
@ -1825,9 +1825,9 @@ bool BKE_ffmpeg_alpha_channel_is_supported(const RenderData *rd)
|
||||
|
||||
void *BKE_ffmpeg_context_create()
|
||||
{
|
||||
/* new ffmpeg data struct */
|
||||
/* New FFMPEG data struct. */
|
||||
FFMpegContext *context = static_cast<FFMpegContext *>(
|
||||
MEM_callocN(sizeof(FFMpegContext), "new ffmpeg context"));
|
||||
MEM_callocN(sizeof(FFMpegContext), "new FFMPEG context"));
|
||||
|
||||
context->ffmpeg_codec = AV_CODEC_ID_MPEG4;
|
||||
context->ffmpeg_audio_codec = AV_CODEC_ID_NONE;
|
||||
|
@ -269,4 +269,15 @@ template<typename T> inline void fill_index_range(MutableSpan<T> span, const T s
|
||||
std::iota(span.begin(), span.end(), start);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool indexed_data_equal(const Span<T> all_values, const Span<int> indices, const Span<T> values)
|
||||
{
|
||||
for (const int i : indices.index_range()) {
|
||||
if (all_values[indices[i]] != values[i]) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace blender::array_utils
|
||||
|
@ -190,6 +190,11 @@ inline void foreach_1_index_expr(ExprFn &&expr,
|
||||
expr, handle, to_best_bit_span(first_arg), to_best_bit_span(args)...);
|
||||
}
|
||||
|
||||
template<typename BitSpanT> inline void invert(const BitSpanT &data)
|
||||
{
|
||||
mix_into_first_expr([](const BitInt x) { return ~x; }, data);
|
||||
}
|
||||
|
||||
template<typename FirstBitSpanT, typename... BitSpanT>
|
||||
inline void inplace_or(FirstBitSpanT &first_arg, const BitSpanT &...args)
|
||||
{
|
||||
|
@ -37,7 +37,7 @@ namespace enumerable_thread_specific_utils {
|
||||
inline std::atomic<int> next_id = 0;
|
||||
inline thread_local int thread_id = next_id.fetch_add(1, std::memory_order_relaxed);
|
||||
} // namespace enumerable_thread_specific_utils
|
||||
#endif
|
||||
#endif /* !WITH_TBB */
|
||||
|
||||
/**
|
||||
* This is mainly a wrapper for `tbb::enumerable_thread_specific`. The wrapper is needed because we
|
||||
|
@ -49,7 +49,7 @@ void BLI_memarena_merge(MemArena *ma_dst, MemArena *ma_src) ATTR_NONNULL(1, 2);
|
||||
|
||||
/**
|
||||
* Clear for reuse, avoids re-allocation when an arena may
|
||||
* otherwise be free'd and recreated.
|
||||
* otherwise be freed and recreated.
|
||||
*/
|
||||
void BLI_memarena_clear(MemArena *ma) ATTR_NONNULL(1);
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/* Use a define instead of `#pragma once` because of `bmesh_iterators_inline.h` */
|
||||
/* Use a define instead of `#pragma once` because of `bmesh_iterators_inline.hh` */
|
||||
#ifndef __BLI_TASK_H__
|
||||
#define __BLI_TASK_H__
|
||||
|
||||
|
@ -12,7 +12,7 @@
|
||||
*/
|
||||
|
||||
/* only validate array-bounds in debug mode */
|
||||
#ifdef DEBUG
|
||||
#ifndef NDEBUG
|
||||
# define STACK_DECLARE(stack) unsigned int _##stack##_index, _##stack##_num_alloc
|
||||
# define STACK_INIT(stack, stack_num) \
|
||||
((void)stack, \
|
||||
|
@ -49,7 +49,7 @@
|
||||
/* Setting zero so we can catch bugs in BLI_task/KDOPBVH.
|
||||
* TODO(sergey): Deduplicate the limits with PBVH from BKE.
|
||||
*/
|
||||
#ifdef DEBUG
|
||||
#ifndef NDEBUG
|
||||
# define KDOPBVH_THREAD_LEAF_THRESHOLD 0
|
||||
#else
|
||||
# define KDOPBVH_THREAD_LEAF_THRESHOLD 1024
|
||||
|
@ -528,7 +528,7 @@ void BLI_mempool_free(BLI_mempool *pool, void *addr)
|
||||
pool->totalloc = pool->pchunk;
|
||||
#endif
|
||||
|
||||
/* Temp alloc so valgrind doesn't complain when setting free'd blocks 'next'. */
|
||||
/* Temporary allocation so VALGRIND doesn't complain when setting freed blocks 'next'. */
|
||||
#ifdef WITH_MEM_VALGRIND
|
||||
VALGRIND_MEMPOOL_ALLOC(pool, CHUNK_DATA(first), pool->csize);
|
||||
#endif
|
||||
|
@ -1159,7 +1159,8 @@ static BChunkList *bchunk_list_from_data_merge(const BArrayInfo *info,
|
||||
/* Warning, from now on don't use len(data) since we want to ignore chunks already matched. */
|
||||
size_t data_len = data_len_original;
|
||||
#define data_len_original invalid_usage
|
||||
#ifdef data_len_original /* Quiet warning. */
|
||||
#ifdef data_len_original
|
||||
/* Quiet warning. */
|
||||
#endif
|
||||
|
||||
const BChunkRef *chunk_list_reference_last = NULL;
|
||||
|
@ -454,7 +454,7 @@ int BLI_rename(const char *from, const char *to)
|
||||
* Since this functionality isn't required at the moment, leave this as-is.
|
||||
* Noting it as a potential improvement. */
|
||||
|
||||
/* NOTE: To avoid the concurrency 'time of check/time of use' (TOC/TOU) issue, this code attemps
|
||||
/* NOTE: To avoid the concurrency 'time of check/time of use' (TOC/TOU) issue, this code attempts
|
||||
* to use available solutions for an 'atomic' (file-system wise) rename operation, instead of
|
||||
* first checking for an existing `to` target path, and then doing the rename operation if it
|
||||
* does not exists at the time of check.
|
||||
@ -476,9 +476,11 @@ int BLI_rename(const char *from, const char *to)
|
||||
return urename(from, to, false);
|
||||
#elif defined(__APPLE__)
|
||||
return renamex_np(from, to, RENAME_EXCL);
|
||||
#elif defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2, 28)
|
||||
#elif defined(__GLIBC_PREREQ)
|
||||
# if __GLIBC_PREREQ(2, 28)
|
||||
/* Most common Linux cases. */
|
||||
return renameat2(AT_FDCWD, from, AT_FDCWD, to, RENAME_NOREPLACE);
|
||||
# endif
|
||||
#else
|
||||
/* At least all BSD's currently. */
|
||||
if (BLI_exists(to)) {
|
||||
|
@ -22,7 +22,7 @@ namespace blender::index_mask {
|
||||
|
||||
template<typename T> void build_reverse_map(const IndexMask &mask, MutableSpan<T> r_map)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
#ifndef NDEBUG
|
||||
/* Catch errors with asserts in debug builds. */
|
||||
r_map.fill(-1);
|
||||
#endif
|
||||
|
@ -37,7 +37,7 @@ struct KDTree {
|
||||
uint nodes_len;
|
||||
uint root;
|
||||
int max_node_index;
|
||||
#ifdef DEBUG
|
||||
#ifndef NDEBUG
|
||||
bool is_balanced; /* ensure we call balance first */
|
||||
uint nodes_len_capacity; /* max size of the tree */
|
||||
#endif
|
||||
@ -97,7 +97,7 @@ KDTree *BLI_kdtree_nd_(new)(uint nodes_len_capacity)
|
||||
tree->root = KD_NODE_ROOT_IS_INIT;
|
||||
tree->max_node_index = -1;
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifndef NDEBUG
|
||||
tree->is_balanced = false;
|
||||
tree->nodes_len_capacity = nodes_len_capacity;
|
||||
#endif
|
||||
@ -120,7 +120,7 @@ void BLI_kdtree_nd_(insert)(KDTree *tree, int index, const float co[KD_DIMS])
|
||||
{
|
||||
KDTreeNode *node = &tree->nodes[tree->nodes_len++];
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifndef NDEBUG
|
||||
BLI_assert(tree->nodes_len <= tree->nodes_len_capacity);
|
||||
#endif
|
||||
|
||||
@ -133,7 +133,7 @@ void BLI_kdtree_nd_(insert)(KDTree *tree, int index, const float co[KD_DIMS])
|
||||
node->d = 0;
|
||||
tree->max_node_index = MAX2(tree->max_node_index, index);
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifndef NDEBUG
|
||||
tree->is_balanced = false;
|
||||
#endif
|
||||
}
|
||||
@ -205,7 +205,7 @@ void BLI_kdtree_nd_(balance)(KDTree *tree)
|
||||
|
||||
tree->root = kdtree_balance(tree->nodes, tree->nodes_len, 0, 0);
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifndef NDEBUG
|
||||
tree->is_balanced = true;
|
||||
#endif
|
||||
}
|
||||
@ -236,7 +236,7 @@ int BLI_kdtree_nd_(find_nearest)(const KDTree *tree,
|
||||
float min_dist, cur_dist;
|
||||
uint stack_len_capacity, cur = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifndef NDEBUG
|
||||
BLI_assert(tree->is_balanced == true);
|
||||
#endif
|
||||
|
||||
@ -346,7 +346,7 @@ int BLI_kdtree_nd_(find_nearest_cb)(
|
||||
float min_dist = FLT_MAX, cur_dist;
|
||||
uint stack_len_capacity, cur = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifndef NDEBUG
|
||||
BLI_assert(tree->is_balanced == true);
|
||||
#endif
|
||||
|
||||
@ -487,7 +487,7 @@ int BLI_kdtree_nd_(find_nearest_n_with_len_squared_cb)(
|
||||
uint stack_len_capacity, cur = 0;
|
||||
uint i, nearest_len = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifndef NDEBUG
|
||||
BLI_assert(tree->is_balanced == true);
|
||||
#endif
|
||||
|
||||
@ -652,7 +652,7 @@ int BLI_kdtree_nd_(range_search_with_len_squared_cb)(
|
||||
uint stack_len_capacity, cur = 0;
|
||||
uint nearest_len = 0, nearest_len_capacity = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifndef NDEBUG
|
||||
BLI_assert(tree->is_balanced == true);
|
||||
#endif
|
||||
|
||||
@ -746,7 +746,7 @@ void BLI_kdtree_nd_(range_search_cb)(
|
||||
float range_sq = range * range, dist_sq;
|
||||
uint stack_len_capacity, cur = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifndef NDEBUG
|
||||
BLI_assert(tree->is_balanced == true);
|
||||
#endif
|
||||
|
||||
@ -978,7 +978,7 @@ static int kdtree_node_cmp_deduplicate(const void *n0_p, const void *n1_p)
|
||||
*/
|
||||
int BLI_kdtree_nd_(deduplicate)(KDTree *tree)
|
||||
{
|
||||
#ifdef DEBUG
|
||||
#ifndef NDEBUG
|
||||
tree->is_balanced = false;
|
||||
#endif
|
||||
qsort(tree->nodes, (size_t)tree->nodes_len, sizeof(*tree->nodes), kdtree_node_cmp_deduplicate);
|
||||
|
@ -489,7 +489,7 @@ MINLINE void premul_float_to_straight_uchar(unsigned char *result, const float c
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* __MATH_COLOR_INLINE_C__ */
|
||||
#endif /* !__MATH_COLOR_INLINE_C__ */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -3589,7 +3589,7 @@ static bool barycentric_weights(const float v1[3],
|
||||
|
||||
wtot = w[0] + w[1] + w[2];
|
||||
|
||||
#ifdef DEBUG /* Avoid floating point exception when debugging. */
|
||||
#ifndef NDEBUG /* Avoid floating point exception when debugging. */
|
||||
if (wtot != 0.0f)
|
||||
#endif
|
||||
{
|
||||
@ -3686,7 +3686,7 @@ bool barycentric_coords_v2(
|
||||
const float x3 = v3[0], y3 = v3[1];
|
||||
const float det = (y2 - y3) * (x1 - x3) + (x3 - x2) * (y1 - y3);
|
||||
|
||||
#ifdef DEBUG /* Avoid floating point exception when debugging. */
|
||||
#ifndef NDEBUG /* Avoid floating point exception when debugging. */
|
||||
if (det != 0.0f)
|
||||
#endif
|
||||
{
|
||||
@ -3711,7 +3711,7 @@ void barycentric_weights_v2(
|
||||
w[2] = cross_tri_v2(v1, v2, co);
|
||||
wtot = w[0] + w[1] + w[2];
|
||||
|
||||
#ifdef DEBUG /* Avoid floating point exception when debugging. */
|
||||
#ifndef NDEBUG /* Avoid floating point exception when debugging. */
|
||||
if (wtot != 0.0f)
|
||||
#endif
|
||||
{
|
||||
@ -3734,7 +3734,7 @@ void barycentric_weights_v2_clamped(
|
||||
w[2] = max_ff(cross_tri_v2(v1, v2, co), 0.0f);
|
||||
wtot = w[0] + w[1] + w[2];
|
||||
|
||||
#ifdef DEBUG /* Avoid floating point exception when debugging. */
|
||||
#ifndef NDEBUG /* Avoid floating point exception when debugging. */
|
||||
if (wtot != 0.0f)
|
||||
#endif
|
||||
{
|
||||
@ -3757,7 +3757,7 @@ void barycentric_weights_v2_persp(
|
||||
w[2] = cross_tri_v2(v1, v2, co) / v3[3];
|
||||
wtot = w[0] + w[1] + w[2];
|
||||
|
||||
#ifdef DEBUG /* Avoid floating point exception when debugging. */
|
||||
#ifndef NDEBUG /* Avoid floating point exception when debugging. */
|
||||
if (wtot != 0.0f)
|
||||
#endif
|
||||
{
|
||||
@ -3849,7 +3849,7 @@ void barycentric_weights_v2_quad(const float v1[2],
|
||||
|
||||
wtot = w[0] + w[1] + w[2] + w[3];
|
||||
|
||||
#ifdef DEBUG /* Avoid floating point exception when debugging. */
|
||||
#ifndef NDEBUG /* Avoid floating point exception when debugging. */
|
||||
if (wtot != 0.0f)
|
||||
#endif
|
||||
{
|
||||
|
@ -17,7 +17,7 @@
|
||||
/******************************** Quaternions ********************************/
|
||||
|
||||
/* used to test is a quat is not normalized (only used for debug prints) */
|
||||
#ifdef DEBUG
|
||||
#ifndef NDEBUG
|
||||
# define QUAT_EPSILON 0.0001
|
||||
#endif
|
||||
|
||||
@ -216,7 +216,7 @@ static void quat_to_mat3_no_error(float m[3][3], const float q[4])
|
||||
|
||||
void quat_to_mat3(float m[3][3], const float q[4])
|
||||
{
|
||||
#ifdef DEBUG
|
||||
#ifndef NDEBUG
|
||||
float f;
|
||||
if (!((f = dot_qtqt(q, q)) == 0.0f || (fabsf(f - 1.0f) < (float)QUAT_EPSILON))) {
|
||||
fprintf(stderr,
|
||||
@ -232,7 +232,7 @@ void quat_to_mat4(float m[4][4], const float q[4])
|
||||
{
|
||||
double q0, q1, q2, q3, qda, qdb, qdc, qaa, qab, qac, qbb, qbc, qcc;
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifndef NDEBUG
|
||||
if (!((q0 = dot_qtqt(q, q)) == 0.0 || (fabs(q0 - 1.0) < QUAT_EPSILON))) {
|
||||
fprintf(stderr,
|
||||
"Warning! quat_to_mat4() called with non-normalized: size %.8f *** report a bug ***\n",
|
||||
@ -1065,7 +1065,7 @@ void quat_to_axis_angle(float axis[3], float *angle, const float q[4])
|
||||
{
|
||||
float ha, si;
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifndef NDEBUG
|
||||
if (!((ha = dot_qtqt(q, q)) == 0.0f || (fabsf(ha - 1.0f) < (float)QUAT_EPSILON))) {
|
||||
fprintf(stderr,
|
||||
"Warning! quat_to_axis_angle() called with non-normalized: size %.8f *** report a bug "
|
||||
|
@ -455,7 +455,7 @@ static void pf_coord_remove(PolyFill *pf, PolyIndex *pi)
|
||||
if (pf->kdtree.node_num) {
|
||||
kdtree2d_node_remove(&pf->kdtree, pi->index);
|
||||
}
|
||||
#endif
|
||||
#endif /* USE_KDTREE */
|
||||
|
||||
pi->next->prev = pi->prev;
|
||||
pi->prev->next = pi->next;
|
||||
@ -463,10 +463,10 @@ static void pf_coord_remove(PolyFill *pf, PolyIndex *pi)
|
||||
if (UNLIKELY(pf->indices == pi)) {
|
||||
pf->indices = pi->next;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
#ifndef NDEBUG
|
||||
pi->index = (uint32_t)-1;
|
||||
pi->next = pi->prev = NULL;
|
||||
#endif
|
||||
#endif /* !NDEBUG */
|
||||
|
||||
pf->coords_num -= 1;
|
||||
}
|
||||
|
@ -842,7 +842,7 @@ uint BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const float n
|
||||
|
||||
BLI_assert(!nor_proj || len_squared_v3(nor_proj) > FLT_EPSILON);
|
||||
|
||||
#ifdef DEBUG
|
||||
#ifndef NDEBUG
|
||||
for (eve = sf_ctx->fillvertbase.first; eve; eve = eve->next) {
|
||||
/* these values used to be set,
|
||||
* however they should always be zero'd so check instead */
|
||||
@ -984,7 +984,7 @@ uint BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const float n
|
||||
}
|
||||
if (eed) {
|
||||
/* otherwise it's impossible to be sure you can clear vertices */
|
||||
#ifdef DEBUG
|
||||
#ifndef NDEBUG
|
||||
printf("No vertices with 250 edges allowed!\n");
|
||||
#endif
|
||||
return 0;
|
||||
@ -1027,7 +1027,7 @@ uint BLI_scanfill_calc_ex(ScanFillContext *sf_ctx, const int flag, const float n
|
||||
eed->v1->edge_count++;
|
||||
eed->v2->edge_count++;
|
||||
}
|
||||
#ifdef DEBUG
|
||||
#ifndef NDEBUG
|
||||
/* ensure we're right! */
|
||||
for (eed = sf_ctx->filledgebase.first; eed; eed = eed->next) {
|
||||
BLI_assert(eed->v1->edge_count != 1);
|
||||
|
@ -125,7 +125,7 @@ TEST_F(FileOpsTest, rename)
|
||||
ASSERT_TRUE(BLI_exists(test_dirpath_src.c_str()));
|
||||
ASSERT_TRUE(BLI_exists(test_dirpath_dst.c_str()));
|
||||
|
||||
/* `test_dirpath_dst` now exists, but is empty, so overwrite rename should suceed. */
|
||||
/* `test_dirpath_dst` now exists, but is empty, so overwrite rename should succeed. */
|
||||
ASSERT_EQ(0, BLI_rename_overwrite(test_dirpath_src.c_str(), test_dirpath_dst.c_str()));
|
||||
ASSERT_FALSE(BLI_exists(test_dirpath_src.c_str()));
|
||||
ASSERT_TRUE(BLI_exists(test_dirpath_dst.c_str()));
|
||||
|
@ -99,7 +99,6 @@
|
||||
#include "BLO_readfile.h"
|
||||
#include "BLO_undofile.hh"
|
||||
|
||||
#include "SEQ_clipboard.hh"
|
||||
#include "SEQ_iterator.hh"
|
||||
#include "SEQ_modifier.hh"
|
||||
#include "SEQ_sequencer.hh"
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user