WIP: Brush assets project #106303
|
@ -703,12 +703,7 @@ mark_as_advanced(WITH_DRAW_DEBUG)
|
|||
|
||||
# LLVM
|
||||
option(WITH_LLVM "Use LLVM" OFF)
|
||||
if(APPLE)
|
||||
# We prefer static llvm build on Apple, dyn build possible though.
|
||||
option(LLVM_STATIC "Link with LLVM static libraries" ON)
|
||||
else()
|
||||
option(LLVM_STATIC "Link with LLVM static libraries" OFF)
|
||||
endif()
|
||||
option(LLVM_STATIC "Link with LLVM static libraries" OFF)
|
||||
mark_as_advanced(LLVM_STATIC)
|
||||
option(WITH_CLANG "Use Clang" OFF)
|
||||
|
||||
|
@ -1156,14 +1151,7 @@ set_and_warn_dependency(WITH_IMAGE_OPENEXR WITH_CYCLES_OSL OFF)
|
|||
# Hydra requires USD.
|
||||
set_and_warn_dependency(WITH_USD WITH_HYDRA OFF)
|
||||
|
||||
# auto enable openimageio for cycles
|
||||
if(WITH_CYCLES)
|
||||
# auto enable llvm for cycles_osl
|
||||
if(WITH_CYCLES_OSL)
|
||||
set(WITH_LLVM ON CACHE BOOL "" FORCE)
|
||||
set(WITH_CLANG ON CACHE BOOL "" FORCE)
|
||||
endif()
|
||||
else()
|
||||
if(NOT WITH_CYCLES)
|
||||
set(WITH_CYCLES_OSL OFF)
|
||||
endif()
|
||||
|
||||
|
@ -1382,18 +1370,6 @@ if(NOT WITH_FFTW3 AND WITH_MOD_OCEANSIM)
|
|||
message(FATAL_ERROR "WITH_MOD_OCEANSIM requires WITH_FFTW3 to be ON")
|
||||
endif()
|
||||
|
||||
if(WITH_CYCLES)
|
||||
if(WITH_CYCLES_OSL)
|
||||
if(NOT WITH_LLVM)
|
||||
message(
|
||||
FATAL_ERROR
|
||||
"Cycles OSL requires WITH_LLVM, the library may not have been found. "
|
||||
"Configure LLVM or disable WITH_CYCLES_OSL"
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(WITH_INTERNATIONAL)
|
||||
if(NOT WITH_BOOST)
|
||||
message(
|
||||
|
|
|
@ -176,19 +176,6 @@ int CLG_color_support_get(CLG_LogRef *clg_ref);
|
|||
} \
|
||||
((void)0)
|
||||
|
||||
#define CLOG_STR_AT_SEVERITY_N(clg_ref, severity, verbose_level, str) \
|
||||
{ \
|
||||
CLG_LogType *_lg_ty = CLOG_ENSURE(clg_ref); \
|
||||
if (((_lg_ty->flag & CLG_FLAG_USE) && (_lg_ty->level >= verbose_level)) || \
|
||||
(severity >= CLG_SEVERITY_WARN)) \
|
||||
{ \
|
||||
const char *_str = str; \
|
||||
CLG_log_str(_lg_ty, severity, __FILE__ ":" STRINGIFY(__LINE__), __func__, _str); \
|
||||
MEM_freeN((void *)_str); \
|
||||
} \
|
||||
} \
|
||||
((void)0)
|
||||
|
||||
#define CLOG_INFO(clg_ref, level, ...) \
|
||||
CLOG_AT_SEVERITY(clg_ref, CLG_SEVERITY_INFO, level, __VA_ARGS__)
|
||||
#define CLOG_WARN(clg_ref, ...) CLOG_AT_SEVERITY(clg_ref, CLG_SEVERITY_WARN, 0, __VA_ARGS__)
|
||||
|
@ -201,13 +188,6 @@ int CLG_color_support_get(CLG_LogRef *clg_ref);
|
|||
#define CLOG_STR_ERROR(clg_ref, str) CLOG_STR_AT_SEVERITY(clg_ref, CLG_SEVERITY_ERROR, 0, str)
|
||||
#define CLOG_STR_FATAL(clg_ref, str) CLOG_STR_AT_SEVERITY(clg_ref, CLG_SEVERITY_FATAL, 0, str)
|
||||
|
||||
/* Allocated string which is immediately freed. */
|
||||
#define CLOG_STR_INFO_N(clg_ref, level, str) \
|
||||
CLOG_STR_AT_SEVERITY_N(clg_ref, CLG_SEVERITY_INFO, level, str)
|
||||
#define CLOG_STR_WARN_N(clg_ref, str) CLOG_STR_AT_SEVERITY_N(clg_ref, CLG_SEVERITY_WARN, 0, str)
|
||||
#define CLOG_STR_ERROR_N(clg_ref, str) CLOG_STR_AT_SEVERITY_N(clg_ref, CLG_SEVERITY_ERROR, 0, str)
|
||||
#define CLOG_STR_FATAL_N(clg_ref, str) CLOG_STR_AT_SEVERITY_N(clg_ref, CLG_SEVERITY_FATAL, 0, str)
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -93,7 +93,7 @@ macro(cycles_external_libraries_append libraries)
|
|||
list(APPEND ${libraries} ${GLOG_LIBRARIES} ${GFLAGS_LIBRARIES})
|
||||
endif()
|
||||
if(WITH_CYCLES_OSL)
|
||||
list(APPEND ${libraries} ${OSL_LIBRARIES} ${CLANG_LIBRARIES} ${LLVM_LIBRARY})
|
||||
list(APPEND ${libraries} ${OSL_LIBRARIES})
|
||||
endif()
|
||||
if(WITH_CYCLES_EMBREE)
|
||||
list(APPEND ${libraries} ${EMBREE_LIBRARIES})
|
||||
|
|
|
@ -32,8 +32,6 @@ set(LIB
|
|||
${OSL_LIBRARIES}
|
||||
${OPENIMAGEIO_LIBRARIES}
|
||||
${PUGIXML_LIBRARIES}
|
||||
${CLANG_LIBRARIES}
|
||||
${LLVM_LIBRARY}
|
||||
)
|
||||
|
||||
if(APPLE)
|
||||
|
|
|
@ -3286,10 +3286,10 @@ static void data_device_handle_drop(void *data, wl_data_device * /*wl_data_devic
|
|||
GHOST_SystemWayland *const system = seat->system;
|
||||
|
||||
if (mime_receive == ghost_wl_mime_text_uri) {
|
||||
static constexpr const char *file_proto = "file://";
|
||||
const char file_proto[] = "file://";
|
||||
/* NOTE: some applications CRLF (`\r\n`) GTK3 for e.g. & others don't `pcmanfm-qt`.
|
||||
* So support both, once `\n` is found, strip the preceding `\r` if found. */
|
||||
static constexpr const char *lf = "\n";
|
||||
const char lf = '\n';
|
||||
|
||||
GHOST_WindowWayland *win = ghost_wl_surface_user_data(wl_surface_window);
|
||||
std::vector<std::string> uris;
|
||||
|
|
|
@ -55,6 +55,10 @@ class GREASE_PENCIL_MT_grease_pencil_add_layer_extra(Menu):
|
|||
layout.operator("grease_pencil.layer_reveal", icon='RESTRICT_VIEW_OFF', text="Show All")
|
||||
layout.operator("grease_pencil.layer_hide", icon='RESTRICT_VIEW_ON', text="Hide Others").unselected = True
|
||||
|
||||
layout.separator()
|
||||
layout.operator("grease_pencil.layer_lock_all", icon='LOCKED', text="Lock All")
|
||||
layout.operator("grease_pencil.layer_lock_all", icon='UNLOCKED', text="Unlock All").lock = False
|
||||
|
||||
|
||||
class DATA_PT_grease_pencil_layers(DataButtonsPanel, Panel):
|
||||
bl_label = "Layers"
|
||||
|
|
|
@ -151,7 +151,9 @@ class OBJECT_MT_modifier_add_generate(ModifierAddMenu, Menu):
|
|||
self.operator_modifier_add(layout, 'WIREFRAME')
|
||||
if ob_type == 'GREASEPENCIL':
|
||||
self.operator_modifier_add(layout, 'GREASE_PENCIL_DASH')
|
||||
self.operator_modifier_add(layout, 'GREASE_PENCIL_LENGTH')
|
||||
self.operator_modifier_add(layout, 'GREASE_PENCIL_MIRROR')
|
||||
self.operator_modifier_add(layout, 'GREASE_PENCIL_MULTIPLY')
|
||||
self.operator_modifier_add(layout, 'GREASE_PENCIL_SUBDIV')
|
||||
layout.template_modifier_asset_menu_items(catalog_path=self.bl_label)
|
||||
|
||||
|
|
|
@ -94,7 +94,6 @@ std::string AS_asset_library_find_suitable_root_path_from_main(const Main *bmain
|
|||
return AS_asset_library_find_suitable_root_path_from_path(bmain->filepath);
|
||||
}
|
||||
|
||||
|
||||
void AS_asset_library_remap_ids(const bke::id::IDRemapper &mappings)
|
||||
{
|
||||
AssetLibraryService *service = AssetLibraryService::get();
|
||||
|
|
|
@ -212,12 +212,13 @@ enum {
|
|||
G_DEBUG_GPU = (1 << 16), /* gpu debug */
|
||||
G_DEBUG_IO = (1 << 17), /* IO Debugging (for Collada, ...). */
|
||||
G_DEBUG_GPU_FORCE_WORKAROUNDS = (1 << 18), /* force gpu workarounds bypassing detections. */
|
||||
G_DEBUG_GPU_RENDERDOC = (1 << 19), /* Enable RenderDoc integration. */
|
||||
G_DEBUG_XR = (1 << 20), /* XR/OpenXR messages */
|
||||
G_DEBUG_XR_TIME = (1 << 21), /* XR/OpenXR timing messages */
|
||||
G_DEBUG_GPU_COMPILE_SHADERS = (1 << 19), /* Compile all statically defined shaders. . */
|
||||
G_DEBUG_GPU_RENDERDOC = (1 << 20), /* Enable RenderDoc integration. */
|
||||
G_DEBUG_XR = (1 << 21), /* XR/OpenXR messages */
|
||||
G_DEBUG_XR_TIME = (1 << 22), /* XR/OpenXR timing messages */
|
||||
|
||||
G_DEBUG_GHOST = (1 << 22), /* Debug GHOST module. */
|
||||
G_DEBUG_WINTAB = (1 << 23), /* Debug Wintab. */
|
||||
G_DEBUG_GHOST = (1 << 23), /* Debug GHOST module. */
|
||||
G_DEBUG_WINTAB = (1 << 24), /* Debug Wintab. */
|
||||
};
|
||||
|
||||
#define G_DEBUG_ALL \
|
||||
|
|
|
@ -513,6 +513,8 @@ class LayerGroup : public ::GreasePencilLayerTreeGroup {
|
|||
LayerGroup(const LayerGroup &other);
|
||||
~LayerGroup();
|
||||
|
||||
LayerGroup &operator=(const LayerGroup &other);
|
||||
|
||||
public:
|
||||
/* Define the common functions for #TreeNode. */
|
||||
TREENODE_COMMON_METHODS;
|
||||
|
|
|
@ -33,6 +33,8 @@
|
|||
#include "BLI_compiler_attrs.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BLI_set.hh"
|
||||
|
||||
#include "DNA_userdef_enums.h"
|
||||
|
||||
struct BlendWriter;
|
||||
|
@ -319,11 +321,23 @@ void BKE_id_delete_ex(Main *bmain, void *idv, const int extra_remapping_flags) A
|
|||
* This is more efficient than calling #BKE_id_delete repetitively on a large set of IDs
|
||||
* (several times faster when deleting most of the IDs at once).
|
||||
*
|
||||
* \warning Considered experimental for now, seems to be working OK but this is
|
||||
* risky code in a complicated area.
|
||||
* \return Number of deleted data-blocks.
|
||||
*/
|
||||
size_t BKE_id_multi_tagged_delete(Main *bmain) ATTR_NONNULL();
|
||||
/**
|
||||
* Properly delete all IDs from \a ids_to_delete, from given \a bmain database.
|
||||
*
|
||||
* This is more efficient than calling #BKE_id_delete repetitively on a large set of IDs
|
||||
* (several times faster when deleting most of the IDs at once).
|
||||
*
|
||||
* \note The ID pointers are not removed from the Set (which may contain more pointers than
|
||||
* originally given, when extra users or dependencies also had to be deleted with the original set
|
||||
* of IDs). They are all freed though, so these pointers are all invalid after calling this
|
||||
* function.
|
||||
*
|
||||
* \return Number of deleted data-blocks.
|
||||
*/
|
||||
size_t BKE_id_multi_delete(Main *bmain, blender::Set<ID *> &ids_to_delete);
|
||||
|
||||
/**
|
||||
* Add a 'NO_MAIN' data-block to given main (also sets user-counts of its IDs if needed).
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include "BLI_compiler_attrs.h"
|
||||
#include "BLI_map.hh"
|
||||
#include "BLI_set.hh"
|
||||
#include "BLI_span.hh"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
|
@ -48,10 +49,11 @@ enum {
|
|||
*/
|
||||
ID_REMAP_SKIP_NEVER_NULL_USAGE = 1 << 1,
|
||||
/**
|
||||
* This tells the callback func to flag with #LIB_DOIT all IDs
|
||||
* using target one with a 'never NULL' pointer (like e.g. #Object.data).
|
||||
* Store in the #IDRemapper all IDs using target one with a 'never NULL' pointer (like e.g.
|
||||
* #Object.data), when such ID usage has (or should have) been remapped to `nullptr`. See also
|
||||
* #ID_REMAP_FORCE_NEVER_NULL_USAGE and #ID_REMAP_SKIP_NEVER_NULL_USAGE.
|
||||
*/
|
||||
ID_REMAP_FLAG_NEVER_NULL_USAGE = 1 << 2,
|
||||
ID_REMAP_STORE_NEVER_NULL_USAGE = 1 << 2,
|
||||
/**
|
||||
* This tells the callback func to force setting IDs
|
||||
* using target one with a 'never NULL' pointer to NULL.
|
||||
|
@ -163,12 +165,8 @@ void BKE_libblock_remap(Main *bmain, void *old_idv, void *new_idv, int remap_fla
|
|||
/**
|
||||
* Unlink given \a id from given \a bmain
|
||||
* (does not touch to indirect, i.e. library, usages of the ID).
|
||||
*
|
||||
* \param do_flag_never_null: If true, all IDs using \a idv in a 'non-NULL' way are flagged by
|
||||
* #LIB_TAG_DOIT flag (quite obviously, 'non-NULL' usages can never be unlinked by this function).
|
||||
*/
|
||||
void BKE_libblock_unlink(Main *bmain, void *idv, bool do_flag_never_null, bool do_skip_indirect)
|
||||
ATTR_NONNULL();
|
||||
void BKE_libblock_unlink(Main *bmain, void *idv, bool do_skip_indirect) ATTR_NONNULL();
|
||||
|
||||
/**
|
||||
* Similar to libblock_remap, but only affects IDs used by given \a idv ID.
|
||||
|
@ -263,10 +261,17 @@ class IDRemapper {
|
|||
blender::Map<ID *, ID *> mappings_;
|
||||
IDTypeFilter source_types_ = 0;
|
||||
|
||||
/**
|
||||
* Store all IDs using another ID with the 'NEVER_NULL' flag, which have (or
|
||||
* should have been) remapped to `nullptr`.
|
||||
*/
|
||||
blender::Set<ID *> never_null_users_;
|
||||
|
||||
public:
|
||||
void clear(void)
|
||||
{
|
||||
mappings_.clear();
|
||||
never_null_users_.clear();
|
||||
source_types_ = 0;
|
||||
}
|
||||
|
||||
|
@ -302,6 +307,16 @@ class IDRemapper {
|
|||
IDRemapperApplyOptions options,
|
||||
ID *id_self = nullptr) const;
|
||||
|
||||
void never_null_users_add(ID *id)
|
||||
{
|
||||
never_null_users_.add(id);
|
||||
}
|
||||
|
||||
const blender::Set<ID *> &never_null_users(void) const
|
||||
{
|
||||
return never_null_users_;
|
||||
}
|
||||
|
||||
/** Iterate over all remapping pairs in the remapper, and call the callback function on them. */
|
||||
void iter(IDRemapperIterFunction func, void *user_data) const
|
||||
{
|
||||
|
|
|
@ -17,6 +17,7 @@ struct UndoType;
|
|||
struct bContext;
|
||||
|
||||
/* IDs */
|
||||
struct GreasePencil;
|
||||
struct Main;
|
||||
struct Mesh;
|
||||
struct Object;
|
||||
|
@ -33,6 +34,7 @@ struct UndoRefID {
|
|||
struct ptr_ty *ptr; \
|
||||
char name[MAX_ID_NAME]; \
|
||||
}
|
||||
UNDO_REF_ID_TYPE(GreasePencil);
|
||||
UNDO_REF_ID_TYPE(Mesh);
|
||||
UNDO_REF_ID_TYPE(Object);
|
||||
UNDO_REF_ID_TYPE(Scene);
|
||||
|
|
|
@ -4,12 +4,20 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "DNA_windowmanager_types.h"
|
||||
|
||||
namespace blender::bke {
|
||||
|
||||
class WindowManagerRuntime {
|
||||
public:
|
||||
/** Indicates whether interface is locked for user interaction. */
|
||||
bool is_interface_locked = false;
|
||||
|
||||
/** Information and error reports. */
|
||||
ReportList reports;
|
||||
|
||||
WindowManagerRuntime();
|
||||
~WindowManagerRuntime();
|
||||
};
|
||||
|
||||
} // namespace blender::bke
|
||||
|
|
|
@ -71,8 +71,18 @@ bool BKE_ffmpeg_alpha_channel_is_supported(const RenderData *rd);
|
|||
void *BKE_ffmpeg_context_create(void);
|
||||
void BKE_ffmpeg_context_free(void *context_v);
|
||||
|
||||
void BKE_ffmpeg_exit();
|
||||
|
||||
/**
|
||||
* Gets a libswscale context for given size and format parameters.
|
||||
* After you're done using the context, call #BKE_ffmpeg_sws_release_context
|
||||
* to release it. Internally the contexts are coming from the context
|
||||
* pool/cache.
|
||||
*/
|
||||
SwsContext *BKE_ffmpeg_sws_get_context(
|
||||
int width, int height, int av_src_format, int av_dst_format, int sws_flags);
|
||||
void BKE_ffmpeg_sws_release_context(SwsContext *ctx);
|
||||
|
||||
void BKE_ffmpeg_sws_scale_frame(SwsContext *ctx, AVFrame *dst, const AVFrame *src);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -315,6 +315,7 @@ set(SRC
|
|||
intern/volume_grid_file_cache.cc
|
||||
intern/volume_render.cc
|
||||
intern/volume_to_mesh.cc
|
||||
intern/wm_runtime.cc
|
||||
intern/workspace.cc
|
||||
intern/world.cc
|
||||
intern/writeavi.cc
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "BKE_report.hh"
|
||||
#include "BKE_screen.hh"
|
||||
#include "BKE_studiolight.h"
|
||||
#include "BKE_writeffmpeg.hh"
|
||||
|
||||
#include "DEG_depsgraph.hh"
|
||||
|
||||
|
@ -75,6 +76,9 @@ void BKE_blender_free()
|
|||
BKE_callback_global_finalize();
|
||||
|
||||
IMB_moviecache_destruct();
|
||||
#ifdef WITH_FFMPEG
|
||||
BKE_ffmpeg_exit();
|
||||
#endif
|
||||
|
||||
BKE_node_system_exit();
|
||||
}
|
||||
|
|
|
@ -1131,7 +1131,7 @@ static void setup_app_data(bContext *C,
|
|||
BLI_assert(BKE_main_namemap_validate(bmain));
|
||||
|
||||
if (mode != LOAD_UNDO && !USER_EXPERIMENTAL_TEST(&U, no_override_auto_resync)) {
|
||||
reports->duration.lib_overrides_resync = BLI_check_seconds_timer();
|
||||
reports->duration.lib_overrides_resync = BLI_time_now_seconds();
|
||||
|
||||
BKE_lib_override_library_main_resync(
|
||||
bmain,
|
||||
|
@ -1139,7 +1139,7 @@ static void setup_app_data(bContext *C,
|
|||
bfd->cur_view_layer ? bfd->cur_view_layer : BKE_view_layer_default_view(curscene),
|
||||
reports);
|
||||
|
||||
reports->duration.lib_overrides_resync = BLI_check_seconds_timer() -
|
||||
reports->duration.lib_overrides_resync = BLI_time_now_seconds() -
|
||||
reports->duration.lib_overrides_resync;
|
||||
|
||||
/* We need to rebuild some of the deleted override rules (for UI feedback purpose). */
|
||||
|
|
|
@ -767,7 +767,7 @@ wmMsgBus *CTX_wm_message_bus(const bContext *C)
|
|||
ReportList *CTX_wm_reports(const bContext *C)
|
||||
{
|
||||
if (C->wm.manager) {
|
||||
return &(C->wm.manager->reports);
|
||||
return &(C->wm.manager->runtime->reports);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
|
|
@ -79,7 +79,7 @@ PartDeflect *BKE_partdeflect_new(int type)
|
|||
pd->pdef_sbift = 0.2f;
|
||||
pd->pdef_sboft = 0.02f;
|
||||
pd->pdef_cfrict = 5.0f;
|
||||
pd->seed = (uint(ceil(BLI_check_seconds_timer())) + 1) % 128;
|
||||
pd->seed = (uint(ceil(BLI_time_now_seconds())) + 1) % 128;
|
||||
pd->f_strength = 1.0f;
|
||||
pd->f_damp = 1.0f;
|
||||
|
||||
|
|
|
@ -1065,6 +1065,18 @@ LayerGroup::~LayerGroup()
|
|||
this->runtime = nullptr;
|
||||
}
|
||||
|
||||
LayerGroup &LayerGroup::operator=(const LayerGroup &other)
|
||||
{
|
||||
if (this == &other) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
this->~LayerGroup();
|
||||
new (this) LayerGroup(other);
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Layer &LayerGroup::add_layer(StringRefNull name)
|
||||
{
|
||||
Layer *new_layer = MEM_new<Layer>(__func__, name);
|
||||
|
@ -1715,6 +1727,32 @@ blender::MutableSpan<GreasePencilDrawingBase *> GreasePencil::drawings()
|
|||
this->drawing_array_num};
|
||||
}
|
||||
|
||||
void GreasePencil::resize_drawings(const int new_num)
|
||||
{
|
||||
using namespace blender;
|
||||
BLI_assert(new_num > 0);
|
||||
|
||||
const int prev_num = int(this->drawings().size());
|
||||
if (new_num == prev_num) {
|
||||
return;
|
||||
}
|
||||
if (new_num > prev_num) {
|
||||
const int add_num = new_num - prev_num;
|
||||
grow_array<GreasePencilDrawingBase *>(&this->drawing_array, &this->drawing_array_num, add_num);
|
||||
}
|
||||
else { /* if (new_num < prev_num) */
|
||||
const int shrink_num = prev_num - new_num;
|
||||
MutableSpan<GreasePencilDrawingBase *> old_drawings = this->drawings().drop_front(new_num);
|
||||
for (const int64_t i : old_drawings.index_range()) {
|
||||
if (old_drawings[i]) {
|
||||
MEM_delete(old_drawings[i]);
|
||||
}
|
||||
}
|
||||
shrink_array<GreasePencilDrawingBase *>(
|
||||
&this->drawing_array, &this->drawing_array_num, shrink_num);
|
||||
}
|
||||
}
|
||||
|
||||
void GreasePencil::add_empty_drawings(const int add_num)
|
||||
{
|
||||
using namespace blender;
|
||||
|
|
|
@ -1494,7 +1494,7 @@ void BKE_image_packfiles_from_mem(ReportList *reports,
|
|||
|
||||
void BKE_image_tag_time(Image *ima)
|
||||
{
|
||||
ima->lastused = BLI_check_seconds_timer_i();
|
||||
ima->lastused = BLI_time_now_seconds_i();
|
||||
}
|
||||
|
||||
static uintptr_t image_mem_size(Image *image)
|
||||
|
|
|
@ -585,7 +585,7 @@ void BKE_image_free_anim_gputextures(Main *bmain)
|
|||
void BKE_image_free_old_gputextures(Main *bmain)
|
||||
{
|
||||
static int lasttime = 0;
|
||||
int ctime = int(BLI_check_seconds_timer());
|
||||
int ctime = int(BLI_time_now_seconds());
|
||||
|
||||
/*
|
||||
* Run garbage collector once for every collecting period of time
|
||||
|
|
|
@ -8,8 +8,6 @@
|
|||
* Contains management of ID's for freeing & deletion.
|
||||
*/
|
||||
|
||||
#include "CLG_log.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
/* all types are needed here, in order to do memory operations */
|
||||
|
@ -18,8 +16,8 @@
|
|||
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BLI_linklist.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_set.hh"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
#include "BKE_anim_data.h"
|
||||
|
@ -44,8 +42,6 @@
|
|||
|
||||
using namespace blender::bke::id;
|
||||
|
||||
static CLG_LogRef LOG = {"bke.lib_id_delete"};
|
||||
|
||||
void BKE_libblock_free_data(ID *id, const bool do_id_user)
|
||||
{
|
||||
if (id->properties) {
|
||||
|
@ -214,213 +210,132 @@ void BKE_id_free_us(Main *bmain, void *idv) /* test users */
|
|||
}
|
||||
|
||||
if (id->us == 0) {
|
||||
BKE_libblock_unlink(bmain, id, false, false);
|
||||
BKE_libblock_unlink(bmain, id, false);
|
||||
|
||||
BKE_id_free(bmain, id);
|
||||
}
|
||||
}
|
||||
|
||||
static size_t id_delete(Main *bmain,
|
||||
const bool do_tagged_deletion,
|
||||
blender::Set<ID *> &ids_to_delete,
|
||||
const int extra_remapping_flags)
|
||||
{
|
||||
const int tag = LIB_TAG_DOIT;
|
||||
ListBase *lbarray[INDEX_ID_MAX];
|
||||
int base_count, i;
|
||||
|
||||
/* Used by batch tagged deletion, when we call BKE_id_free then, id is no more in Main database,
|
||||
* and has already properly unlinked its other IDs usages.
|
||||
* UI users are always cleared in BKE_libblock_remap_locked() call, so we can always skip it. */
|
||||
const int free_flag = LIB_ID_FREE_NO_UI_USER |
|
||||
(do_tagged_deletion ? LIB_ID_FREE_NO_MAIN | LIB_ID_FREE_NO_USER_REFCOUNT :
|
||||
0);
|
||||
const int remapping_flags = (ID_REMAP_FLAG_NEVER_NULL_USAGE | ID_REMAP_FORCE_NEVER_NULL_USAGE |
|
||||
const int free_flag = LIB_ID_FREE_NO_UI_USER | LIB_ID_FREE_NO_MAIN |
|
||||
LIB_ID_FREE_NO_USER_REFCOUNT;
|
||||
const int remapping_flags = (ID_REMAP_STORE_NEVER_NULL_USAGE | ID_REMAP_FORCE_NEVER_NULL_USAGE |
|
||||
ID_REMAP_FORCE_INTERNAL_RUNTIME_POINTERS | extra_remapping_flags);
|
||||
ListBase tagged_deleted_ids = {nullptr};
|
||||
|
||||
base_count = set_listbasepointers(bmain, lbarray);
|
||||
ListBase *lbarray[INDEX_ID_MAX];
|
||||
const int base_count = set_listbasepointers(bmain, lbarray);
|
||||
|
||||
BKE_main_lock(bmain);
|
||||
if (do_tagged_deletion) {
|
||||
IDRemapper id_remapper;
|
||||
BKE_layer_collection_resync_forbid();
|
||||
BKE_layer_collection_resync_forbid();
|
||||
IDRemapper id_remapper;
|
||||
|
||||
/* Main idea of batch deletion is to remove all IDs to be deleted from Main database.
|
||||
* This means that we won't have to loop over all deleted IDs to remove usages
|
||||
* of other deleted IDs.
|
||||
* This gives tremendous speed-up when deleting a large amount of IDs from a Main
|
||||
* containing thousands of those.
|
||||
* This also means that we have to be very careful here, as we by-pass many 'common'
|
||||
* processing, hence risking to 'corrupt' at least user counts, if not IDs themselves. */
|
||||
bool keep_looping = true;
|
||||
while (keep_looping) {
|
||||
ID *id, *id_next;
|
||||
keep_looping = false;
|
||||
/* Main idea of batch deletion is to remove all IDs to be deleted from Main database.
|
||||
* This means that we won't have to loop over all deleted IDs to remove usages
|
||||
* of other deleted IDs.
|
||||
* This gives tremendous speed-up when deleting a large amount of IDs from a Main
|
||||
* containing thousands of these.
|
||||
* This also means that we have to be very careful here, as we by-pass many 'common'
|
||||
* processing, hence risking to 'corrupt' at least user counts, if not IDs themselves. */
|
||||
bool keep_looping = true;
|
||||
while (keep_looping) {
|
||||
keep_looping = false;
|
||||
|
||||
/* First tag and remove from Main all datablocks directly from target lib.
|
||||
* Note that we go forward here, since we want to check dependencies before users
|
||||
* (e.g. meshes before objects). Avoids to have to loop twice. */
|
||||
for (i = 0; i < base_count; i++) {
|
||||
ListBase *lb = lbarray[i];
|
||||
|
||||
for (id = static_cast<ID *>(lb->first); id; id = id_next) {
|
||||
id_next = static_cast<ID *>(id->next);
|
||||
/* NOTE: in case we delete a library, we also delete all its datablocks! */
|
||||
if ((id->tag & tag) || (ID_IS_LINKED(id) && (id->lib->id.tag & tag))) {
|
||||
BLI_remlink(lb, id);
|
||||
BKE_main_namemap_remove_name(bmain, id, id->name + 2);
|
||||
BLI_addtail(&tagged_deleted_ids, id);
|
||||
id_remapper.add(id, nullptr);
|
||||
/* Do not tag as no_main now, we want to unlink it first (lower-level ID management
|
||||
* code has some specific handling of 'no main' IDs that would be a problem in that
|
||||
* case). */
|
||||
id->tag |= tag;
|
||||
|
||||
/* Forcefully also delete shapekeys of the deleted ID if any, 'orphaned' shapekeys are
|
||||
* not allowed in Blender and will cause lots of problem in modern code (liboverrides,
|
||||
* warning on write & read, etc.). */
|
||||
Key *shape_key = BKE_key_from_id(id);
|
||||
if (shape_key && (shape_key->id.tag & tag) == 0) {
|
||||
BLI_remlink(&bmain->shapekeys, &shape_key->id);
|
||||
BKE_main_namemap_remove_name(bmain, &shape_key->id, shape_key->id.name + 2);
|
||||
BLI_addtail(&tagged_deleted_ids, &shape_key->id);
|
||||
id_remapper.add(&shape_key->id, nullptr);
|
||||
shape_key->id.tag |= tag;
|
||||
}
|
||||
|
||||
keep_looping = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Will tag 'never nullptr' users of this ID too.
|
||||
*
|
||||
* NOTE: #BKE_libblock_unlink() cannot be used here, since it would ignore indirect
|
||||
* links, this can lead to nasty crashing here in second, actual deleting loop.
|
||||
* Also, this will also flag users of deleted data that cannot be unlinked
|
||||
* (object using deleted obdata, etc.), so that they also get deleted. */
|
||||
BKE_libblock_remap_multiple_locked(bmain, id_remapper, remapping_flags);
|
||||
id_remapper.clear();
|
||||
}
|
||||
|
||||
/* Since we removed IDs from Main, their own other IDs usages need to be removed 'manually'. */
|
||||
blender::Vector<ID *> cleanup_ids;
|
||||
for (ID *id = static_cast<ID *>(tagged_deleted_ids.first); id;
|
||||
id = static_cast<ID *>(id->next))
|
||||
{
|
||||
cleanup_ids.append(id);
|
||||
}
|
||||
BKE_libblock_relink_multiple(bmain,
|
||||
cleanup_ids,
|
||||
ID_REMAP_TYPE_CLEANUP,
|
||||
id_remapper,
|
||||
ID_REMAP_FORCE_INTERNAL_RUNTIME_POINTERS |
|
||||
ID_REMAP_SKIP_USER_CLEAR);
|
||||
cleanup_ids.clear();
|
||||
|
||||
BKE_layer_collection_resync_allow();
|
||||
BKE_main_collection_sync_remap(bmain);
|
||||
|
||||
/* Now we can safely mark that ID as not being in Main database anymore. */
|
||||
/* NOTE: This needs to be done in a separate loop than above, otherwise some user-counts of
|
||||
* deleted IDs may not be properly decreased by the remappings (since `NO_MAIN` ID user-counts
|
||||
* is never affected). */
|
||||
for (ID *id = static_cast<ID *>(tagged_deleted_ids.first); id;
|
||||
id = static_cast<ID *>(id->next))
|
||||
{
|
||||
id->tag |= LIB_TAG_NO_MAIN;
|
||||
/* User-count needs to be reset artificially, since some usages may not be cleared in batch
|
||||
* deletion (typically, if one deleted ID uses another deleted ID, this may not be cleared by
|
||||
* remapping code, depending on order in which these are handled). */
|
||||
id->us = ID_FAKE_USERS(id);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* First tag all data-blocks directly from target lib.
|
||||
/* First tag and remove from Main all datablocks directly from target lib.
|
||||
* Note that we go forward here, since we want to check dependencies before users
|
||||
* (e.g. meshes before objects).
|
||||
* Avoids to have to loop twice. */
|
||||
IDRemapper remapper;
|
||||
for (i = 0; i < base_count; i++) {
|
||||
* (e.g. meshes before objects). Reduces the chances to have to loop many times in the
|
||||
* `while (keep_looking)` outer loop. */
|
||||
for (int i = 0; i < base_count; i++) {
|
||||
ListBase *lb = lbarray[i];
|
||||
ID *id, *id_next;
|
||||
remapper.clear();
|
||||
ID *id_iter;
|
||||
|
||||
for (id = static_cast<ID *>(lb->first); id; id = id_next) {
|
||||
id_next = static_cast<ID *>(id->next);
|
||||
FOREACH_MAIN_LISTBASE_ID_BEGIN (lb, id_iter) {
|
||||
/* NOTE: in case we delete a library, we also delete all its datablocks! */
|
||||
if ((id->tag & tag) || (ID_IS_LINKED(id) && (id->lib->id.tag & tag))) {
|
||||
id->tag |= tag;
|
||||
remapper.add(id, nullptr);
|
||||
if (ids_to_delete.contains(id_iter) ||
|
||||
(ID_IS_LINKED(id_iter) && ids_to_delete.contains(&id_iter->lib->id)))
|
||||
{
|
||||
BLI_remlink(lb, id_iter);
|
||||
BKE_main_namemap_remove_name(bmain, id_iter, id_iter->name + 2);
|
||||
ids_to_delete.add(id_iter);
|
||||
id_remapper.add(id_iter, nullptr);
|
||||
/* Do not tag as no_main now, we want to unlink it first (lower-level ID management
|
||||
* code has some specific handling of 'no main' IDs that would be a problem in that
|
||||
* case). */
|
||||
|
||||
/* Forcefully also delete shapekeys of the deleted ID if any, 'orphaned' shapekeys are
|
||||
* not allowed in Blender and will cause lots of problem in modern code (liboverrides,
|
||||
* warning on write & read, etc.). */
|
||||
Key *shape_key = BKE_key_from_id(id_iter);
|
||||
if (shape_key && !ids_to_delete.contains(&shape_key->id)) {
|
||||
BLI_remlink(&bmain->shapekeys, &shape_key->id);
|
||||
BKE_main_namemap_remove_name(bmain, &shape_key->id, shape_key->id.name + 2);
|
||||
ids_to_delete.add(&shape_key->id);
|
||||
id_remapper.add(&shape_key->id, nullptr);
|
||||
}
|
||||
|
||||
keep_looping = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (remapper.is_empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Will tag 'never nullptr' users of this ID too.
|
||||
*
|
||||
* NOTE: #BKE_libblock_unlink() cannot be used here, since it would ignore indirect
|
||||
* links, this can lead to nasty crashing here in second, actual deleting loop.
|
||||
* Also, this will also flag users of deleted data that cannot be unlinked
|
||||
* (object using deleted obdata, etc.), so that they also get deleted. */
|
||||
BKE_libblock_remap_multiple_locked(bmain, remapper, remapping_flags);
|
||||
FOREACH_MAIN_LISTBASE_ID_END;
|
||||
}
|
||||
|
||||
/* Will tag 'never nullptr' users of this ID too.
|
||||
*
|
||||
* NOTE: #BKE_libblock_unlink() cannot be used here, since it would ignore indirect
|
||||
* links, this can lead to nasty crashing here in second, actual deleting loop.
|
||||
* Also, this will also flag users of deleted data that cannot be unlinked
|
||||
* (object using deleted obdata, etc.), so that they also get deleted. */
|
||||
BKE_libblock_remap_multiple_locked(bmain, id_remapper, remapping_flags);
|
||||
for (ID *id_never_null_iter : id_remapper.never_null_users()) {
|
||||
ids_to_delete.add(id_never_null_iter);
|
||||
}
|
||||
id_remapper.clear();
|
||||
}
|
||||
|
||||
/* Since we removed IDs from Main, their own other IDs usages need to be removed 'manually'. */
|
||||
blender::Vector<ID *> cleanup_ids{ids_to_delete.begin(), ids_to_delete.end()};
|
||||
BKE_libblock_relink_multiple(
|
||||
bmain,
|
||||
cleanup_ids,
|
||||
ID_REMAP_TYPE_CLEANUP,
|
||||
id_remapper,
|
||||
(ID_REMAP_FORCE_INTERNAL_RUNTIME_POINTERS | ID_REMAP_SKIP_USER_CLEAR));
|
||||
cleanup_ids.clear();
|
||||
|
||||
/* Now we can safely mark that ID as not being in Main database anymore. */
|
||||
/* NOTE: This needs to be done in a separate loop than above, otherwise some user-counts of
|
||||
* deleted IDs may not be properly decreased by the remappings (since `NO_MAIN` ID user-counts
|
||||
* is never affected). */
|
||||
for (ID *id : ids_to_delete) {
|
||||
id->tag |= LIB_TAG_NO_MAIN;
|
||||
/* User-count needs to be reset artificially, since some usages may not be cleared in batch
|
||||
* deletion (typically, if one deleted ID uses another deleted ID, this may not be cleared by
|
||||
* remapping code, depending on order in which these are handled). */
|
||||
id->us = ID_FAKE_USERS(id);
|
||||
|
||||
id_free(bmain, id, free_flag, false);
|
||||
}
|
||||
|
||||
BKE_main_unlock(bmain);
|
||||
|
||||
/* ViewLayer resync needs to be delayed during Scene freeing, since internal relationships
|
||||
* between the Scene's master collection and its view_layers become invalid
|
||||
* (due to remapping). */
|
||||
BKE_layer_collection_resync_forbid();
|
||||
|
||||
/* In usual reversed order, such that all usage of a given ID, even 'never nullptr' ones,
|
||||
* have been already cleared when we reach it
|
||||
* (e.g. Objects being processed before meshes, they'll have already released their 'reference'
|
||||
* over meshes when we come to freeing obdata). */
|
||||
size_t num_datablocks_deleted = 0;
|
||||
for (i = do_tagged_deletion ? 1 : base_count; i--;) {
|
||||
ListBase *lb = lbarray[i];
|
||||
ID *id, *id_next;
|
||||
|
||||
for (id = static_cast<ID *>(do_tagged_deletion ? tagged_deleted_ids.first : lb->first); id;
|
||||
id = id_next)
|
||||
{
|
||||
id_next = static_cast<ID *>(id->next);
|
||||
if (id->tag & tag) {
|
||||
if (((id->tag & LIB_TAG_EXTRAUSER_SET) == 0 && ID_REAL_USERS(id) != 0) ||
|
||||
((id->tag & LIB_TAG_EXTRAUSER_SET) != 0 && ID_REAL_USERS(id) != 1))
|
||||
{
|
||||
CLOG_ERROR(&LOG,
|
||||
"Deleting %s which still has %d users (including %d 'extra' shallow users)\n",
|
||||
id->name,
|
||||
ID_REAL_USERS(id),
|
||||
(id->tag & LIB_TAG_EXTRAUSER_SET) != 0 ? 1 : 0);
|
||||
}
|
||||
id_free(bmain, id, free_flag, !do_tagged_deletion);
|
||||
++num_datablocks_deleted;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BKE_layer_collection_resync_allow();
|
||||
BKE_main_collection_sync_remap(bmain);
|
||||
|
||||
bmain->is_memfile_undo_written = false;
|
||||
return num_datablocks_deleted;
|
||||
return size_t(ids_to_delete.size());
|
||||
}
|
||||
|
||||
void BKE_id_delete_ex(Main *bmain, void *idv, const int extra_remapping_flags)
|
||||
{
|
||||
BLI_assert_msg((((ID *)idv)->tag & LIB_TAG_NO_MAIN) == 0,
|
||||
"Cannot be used with IDs outside of Main");
|
||||
ID *id = static_cast<ID *>(idv);
|
||||
BLI_assert_msg((id->tag & LIB_TAG_NO_MAIN) == 0, "Cannot be used with IDs outside of Main");
|
||||
|
||||
BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
|
||||
((ID *)idv)->tag |= LIB_TAG_DOIT;
|
||||
|
||||
id_delete(bmain, false, extra_remapping_flags);
|
||||
blender::Set<ID *> ids_to_delete = {id};
|
||||
id_delete(bmain, ids_to_delete, extra_remapping_flags);
|
||||
}
|
||||
|
||||
void BKE_id_delete(Main *bmain, void *idv)
|
||||
|
@ -430,7 +345,20 @@ void BKE_id_delete(Main *bmain, void *idv)
|
|||
|
||||
size_t BKE_id_multi_tagged_delete(Main *bmain)
|
||||
{
|
||||
return id_delete(bmain, true, 0);
|
||||
blender::Set<ID *> ids_to_delete;
|
||||
ID *id_iter;
|
||||
FOREACH_MAIN_ID_BEGIN (bmain, id_iter) {
|
||||
if (id_iter->tag & LIB_TAG_DOIT) {
|
||||
ids_to_delete.add(id_iter);
|
||||
}
|
||||
}
|
||||
FOREACH_MAIN_ID_END;
|
||||
return id_delete(bmain, ids_to_delete, 0);
|
||||
}
|
||||
|
||||
size_t BKE_id_multi_delete(Main *bmain, blender::Set<ID *> &ids_to_delete)
|
||||
{
|
||||
return id_delete(bmain, ids_to_delete, 0);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
|
|
@ -3212,7 +3212,7 @@ static bool lib_override_library_main_resync_on_library_indirect_level(
|
|||
BlendFileReadReport *reports)
|
||||
{
|
||||
const bool do_reports_recursive_resync_timing = (library_indirect_level != 0);
|
||||
const double init_time = do_reports_recursive_resync_timing ? BLI_check_seconds_timer() : 0.0;
|
||||
const double init_time = do_reports_recursive_resync_timing ? BLI_time_now_seconds() : 0.0;
|
||||
|
||||
BKE_main_relations_create(bmain, 0);
|
||||
BKE_main_id_tag_all(bmain, LIB_TAG_DOIT, false);
|
||||
|
@ -3518,7 +3518,7 @@ static bool lib_override_library_main_resync_on_library_indirect_level(
|
|||
BKE_lib_override_library_main_hierarchy_root_ensure(bmain);
|
||||
|
||||
if (do_reports_recursive_resync_timing) {
|
||||
reports->duration.lib_overrides_recursive_resync += BLI_check_seconds_timer() - init_time;
|
||||
reports->duration.lib_overrides_recursive_resync += BLI_time_now_seconds() - init_time;
|
||||
}
|
||||
|
||||
return process_lib_level_again;
|
||||
|
|
|
@ -256,8 +256,11 @@ static int foreach_libblock_remap_callback(LibraryIDLinkCallbackData *cb_data)
|
|||
skip_reference);
|
||||
#endif
|
||||
|
||||
if ((id_remap_data->flag & ID_REMAP_FLAG_NEVER_NULL_USAGE) && (cb_flag & IDWALK_CB_NEVER_NULL)) {
|
||||
id_owner->tag |= LIB_TAG_DOIT;
|
||||
if ((id_remap_data->flag & ID_REMAP_STORE_NEVER_NULL_USAGE) &&
|
||||
(cb_flag & IDWALK_CB_NEVER_NULL) &&
|
||||
(expected_mapping_result == ID_REMAP_RESULT_SOURCE_UNASSIGNED))
|
||||
{
|
||||
id_remapper.never_null_users_add(id_owner);
|
||||
}
|
||||
|
||||
/* Special hack in case it's Object->data and we are in edit mode, and new_id is not nullptr
|
||||
|
@ -715,13 +718,9 @@ void BKE_libblock_remap_multiple(Main *bmain, IDRemapper &mappings, const int re
|
|||
BKE_main_unlock(bmain);
|
||||
}
|
||||
|
||||
void BKE_libblock_unlink(Main *bmain,
|
||||
void *idv,
|
||||
const bool do_flag_never_null,
|
||||
const bool do_skip_indirect)
|
||||
void BKE_libblock_unlink(Main *bmain, void *idv, const bool do_skip_indirect)
|
||||
{
|
||||
const int remap_flags = (do_skip_indirect ? ID_REMAP_SKIP_INDIRECT_USAGE : 0) |
|
||||
(do_flag_never_null ? ID_REMAP_FLAG_NEVER_NULL_USAGE : 0);
|
||||
const int remap_flags = (do_skip_indirect ? ID_REMAP_SKIP_INDIRECT_USAGE : 0);
|
||||
|
||||
BKE_main_lock(bmain);
|
||||
|
||||
|
|
|
@ -32,6 +32,8 @@
|
|||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
using namespace blender::bke::id;
|
||||
|
||||
namespace blender::bke::tests {
|
||||
|
||||
class TestData {
|
||||
|
@ -298,7 +300,7 @@ TEST(lib_remap, never_null_usage_flag_not_requested_on_delete)
|
|||
EXPECT_EQ(context.test_data.object->id.tag & LIB_TAG_DOIT, 0);
|
||||
}
|
||||
|
||||
TEST(lib_remap, never_null_usage_flag_requested_on_delete)
|
||||
TEST(lib_remap, never_null_usage_storage_requested_on_delete)
|
||||
{
|
||||
Context<MeshObjectTestData> context;
|
||||
|
||||
|
@ -306,14 +308,19 @@ TEST(lib_remap, never_null_usage_flag_requested_on_delete)
|
|||
EXPECT_EQ(context.test_data.object->data, context.test_data.mesh);
|
||||
EXPECT_EQ(context.test_data.object->id.tag & LIB_TAG_DOIT, 0);
|
||||
|
||||
/* Never null usage is requested so the flag should be set. */
|
||||
BKE_libblock_remap(context.test_data.bmain,
|
||||
context.test_data.mesh,
|
||||
nullptr,
|
||||
ID_REMAP_SKIP_NEVER_NULL_USAGE | ID_REMAP_FLAG_NEVER_NULL_USAGE);
|
||||
/* Never null usage is requested so the owner ID (the Object) should be added to the set. */
|
||||
IDRemapper remapper;
|
||||
remapper.add(&context.test_data.mesh->id, nullptr);
|
||||
BKE_libblock_remap_multiple_locked(
|
||||
context.test_data.bmain,
|
||||
remapper,
|
||||
(ID_REMAP_SKIP_NEVER_NULL_USAGE | ID_REMAP_STORE_NEVER_NULL_USAGE));
|
||||
|
||||
/* Never null usages unassignement is not enforced (no #ID_REMAP_FORCE_NEVER_NULL_USAGE), so the
|
||||
* obdta should still use the original mesh. */
|
||||
EXPECT_EQ(context.test_data.object->data, context.test_data.mesh);
|
||||
EXPECT_NE(context.test_data.object->data, nullptr);
|
||||
EXPECT_EQ(context.test_data.object->id.tag & LIB_TAG_DOIT, LIB_TAG_DOIT);
|
||||
EXPECT_TRUE(remapper.never_null_users().contains(&context.test_data.object->id));
|
||||
}
|
||||
|
||||
TEST(lib_remap, never_null_usage_flag_not_requested_on_remap)
|
||||
|
@ -332,7 +339,7 @@ TEST(lib_remap, never_null_usage_flag_not_requested_on_remap)
|
|||
EXPECT_EQ(context.test_data.object->id.tag & LIB_TAG_DOIT, 0);
|
||||
}
|
||||
|
||||
TEST(lib_remap, never_null_usage_flag_requested_on_remap)
|
||||
TEST(lib_remap, never_null_usage_storage_requested_on_remap)
|
||||
{
|
||||
Context<MeshObjectTestData> context;
|
||||
Mesh *other_mesh = BKE_mesh_add(context.test_data.bmain, nullptr);
|
||||
|
@ -341,13 +348,16 @@ TEST(lib_remap, never_null_usage_flag_requested_on_remap)
|
|||
EXPECT_EQ(context.test_data.object->data, context.test_data.mesh);
|
||||
EXPECT_EQ(context.test_data.object->id.tag & LIB_TAG_DOIT, 0);
|
||||
|
||||
/* Never null usage is requested so the flag should be set. */
|
||||
BKE_libblock_remap(context.test_data.bmain,
|
||||
context.test_data.mesh,
|
||||
other_mesh,
|
||||
ID_REMAP_SKIP_NEVER_NULL_USAGE | ID_REMAP_FLAG_NEVER_NULL_USAGE);
|
||||
/* Never null usage is requested, but the obdata is remapped to another Mesh, not to `nullptr`,
|
||||
* so the `never_null_users` set should remain empty. */
|
||||
IDRemapper remapper;
|
||||
remapper.add(&context.test_data.mesh->id, &other_mesh->id);
|
||||
BKE_libblock_remap_multiple_locked(
|
||||
context.test_data.bmain,
|
||||
remapper,
|
||||
(ID_REMAP_SKIP_NEVER_NULL_USAGE | ID_REMAP_STORE_NEVER_NULL_USAGE));
|
||||
EXPECT_EQ(context.test_data.object->data, other_mesh);
|
||||
EXPECT_EQ(context.test_data.object->id.tag & LIB_TAG_DOIT, LIB_TAG_DOIT);
|
||||
EXPECT_TRUE(remapper.never_null_users().is_empty());
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -96,7 +96,7 @@ static void mesh_init_data(ID *id)
|
|||
|
||||
mesh->runtime = new blender::bke::MeshRuntime();
|
||||
|
||||
mesh->face_sets_color_seed = BLI_hash_int(BLI_check_seconds_timer_i() & UINT_MAX);
|
||||
mesh->face_sets_color_seed = BLI_hash_int(BLI_time_now_seconds_i() & UINT_MAX);
|
||||
}
|
||||
|
||||
static void mesh_copy_data(Main *bmain, ID *id_dst, const ID *id_src, const int flag)
|
||||
|
|
|
@ -2539,7 +2539,7 @@ void nodeUniqueName(bNodeTree *ntree, bNode *node)
|
|||
void nodeUniqueID(bNodeTree *ntree, bNode *node)
|
||||
{
|
||||
/* Use a pointer cast to avoid overflow warnings. */
|
||||
const double time = BLI_check_seconds_timer() * 1000000.0;
|
||||
const double time = BLI_time_now_seconds() * 1000000.0;
|
||||
blender::RandomNumberGenerator id_rng{*reinterpret_cast<const uint32_t *>(&time)};
|
||||
|
||||
/* In the unlikely case that the random ID doesn't match, choose a new one until it does. */
|
||||
|
|
|
@ -1224,7 +1224,7 @@ static void pbvh_bmesh_split_edge(EdgeQueueContext *eq_ctx, PBVH *pbvh, BMEdge *
|
|||
|
||||
static bool pbvh_bmesh_subdivide_long_edges(EdgeQueueContext *eq_ctx, PBVH *pbvh)
|
||||
{
|
||||
const double start_time = BLI_check_seconds_timer();
|
||||
const double start_time = BLI_time_now_seconds();
|
||||
|
||||
bool any_subdivided = false;
|
||||
|
||||
|
@ -1267,7 +1267,7 @@ static bool pbvh_bmesh_subdivide_long_edges(EdgeQueueContext *eq_ctx, PBVH *pbvh
|
|||
#endif
|
||||
|
||||
CLOG_INFO(
|
||||
&LOG, 2, "Long edge subdivision took %f seconds.", BLI_check_seconds_timer() - start_time);
|
||||
&LOG, 2, "Long edge subdivision took %f seconds.", BLI_time_now_seconds() - start_time);
|
||||
|
||||
return any_subdivided;
|
||||
}
|
||||
|
@ -1701,7 +1701,7 @@ static void pbvh_bmesh_collapse_edge(
|
|||
|
||||
static bool pbvh_bmesh_collapse_short_edges(EdgeQueueContext *eq_ctx, PBVH *pbvh)
|
||||
{
|
||||
const double start_time = BLI_check_seconds_timer();
|
||||
const double start_time = BLI_time_now_seconds();
|
||||
|
||||
const float min_len_squared = pbvh->bm_min_edge_len * pbvh->bm_min_edge_len;
|
||||
bool any_collapsed = false;
|
||||
|
@ -1751,8 +1751,7 @@ static bool pbvh_bmesh_collapse_short_edges(EdgeQueueContext *eq_ctx, PBVH *pbvh
|
|||
|
||||
BLI_ghash_free(deleted_verts, nullptr, nullptr);
|
||||
|
||||
CLOG_INFO(
|
||||
&LOG, 2, "Short edge collapse took %f seconds.", BLI_check_seconds_timer() - start_time);
|
||||
CLOG_INFO(&LOG, 2, "Short edge collapse took %f seconds.", BLI_time_now_seconds() - start_time);
|
||||
|
||||
return any_collapsed;
|
||||
}
|
||||
|
|
|
@ -3297,7 +3297,7 @@ void BKE_ptcache_bake(PTCacheBaker *baker)
|
|||
char run[32], cur[32], etd[32];
|
||||
int cancel = 0;
|
||||
|
||||
stime = ptime = BLI_check_seconds_timer();
|
||||
stime = ptime = BLI_time_now_seconds();
|
||||
|
||||
for (int fr = scene->r.cfra; fr <= endframe; fr += baker->quick_step, scene->r.cfra = fr) {
|
||||
BKE_scene_graph_update_for_newframe(depsgraph);
|
||||
|
@ -3311,7 +3311,7 @@ void BKE_ptcache_bake(PTCacheBaker *baker)
|
|||
printf("bake: frame %d :: %d\n", scene->r.cfra, endframe);
|
||||
}
|
||||
else {
|
||||
ctime = BLI_check_seconds_timer();
|
||||
ctime = BLI_time_now_seconds();
|
||||
|
||||
fetd = (ctime - ptime) * (endframe - scene->r.cfra) / baker->quick_step;
|
||||
|
||||
|
@ -3343,7 +3343,7 @@ void BKE_ptcache_bake(PTCacheBaker *baker)
|
|||
|
||||
if (use_timer) {
|
||||
/* start with newline because of \r above */
|
||||
ptcache_dt_to_str(run, sizeof(run), BLI_check_seconds_timer() - stime);
|
||||
ptcache_dt_to_str(run, sizeof(run), BLI_time_now_seconds() - stime);
|
||||
printf("\nBake %s %s (%i frames simulated).\n",
|
||||
(cancel ? "canceled after" : "finished in"),
|
||||
run,
|
||||
|
|
|
@ -3357,7 +3357,7 @@ static void softbody_step(
|
|||
float forcetime;
|
||||
double sct, sst;
|
||||
|
||||
sst = BLI_check_seconds_timer();
|
||||
sst = BLI_time_now_seconds();
|
||||
/* Integration back in time is possible in theory, but pretty useless here.
|
||||
* So we refuse to do so. Since we do not know anything about 'outside' changes
|
||||
* especially colliders we refuse to go more than 10 frames.
|
||||
|
@ -3453,7 +3453,7 @@ static void softbody_step(
|
|||
}
|
||||
loops++;
|
||||
if (sb->solverflags & SBSO_MONITOR) {
|
||||
sct = BLI_check_seconds_timer();
|
||||
sct = BLI_time_now_seconds();
|
||||
if (sct - sst > 0.5) {
|
||||
printf("%3.0f%% \r", 100.0f * timedone / dtime);
|
||||
}
|
||||
|
@ -3494,7 +3494,7 @@ static void softbody_step(
|
|||
}
|
||||
|
||||
if (sb->solverflags & SBSO_MONITOR) {
|
||||
sct = BLI_check_seconds_timer();
|
||||
sct = BLI_time_now_seconds();
|
||||
if ((sct - sst > 0.5) || (G.debug & G_DEBUG)) {
|
||||
printf(" solver time %f sec %s\n", sct - sst, ob->id.name);
|
||||
}
|
||||
|
|
|
@ -26,12 +26,12 @@ void BKE_subdiv_stats_init(SubdivStats *stats)
|
|||
|
||||
void BKE_subdiv_stats_begin(SubdivStats *stats, eSubdivStatsValue value)
|
||||
{
|
||||
stats->begin_timestamp_[value] = BLI_check_seconds_timer();
|
||||
stats->begin_timestamp_[value] = BLI_time_now_seconds();
|
||||
}
|
||||
|
||||
void BKE_subdiv_stats_end(SubdivStats *stats, eSubdivStatsValue value)
|
||||
{
|
||||
stats->values_[value] = BLI_check_seconds_timer() - stats->begin_timestamp_[value];
|
||||
stats->values_[value] = BLI_time_now_seconds() - stats->begin_timestamp_[value];
|
||||
}
|
||||
|
||||
void BKE_subdiv_stats_reset(SubdivStats *stats, eSubdivStatsValue value)
|
||||
|
|
|
@ -0,0 +1,24 @@
|
|||
/* SPDX-FileCopyrightText: 2024 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup bke
|
||||
*/
|
||||
|
||||
#include "BKE_report.hh"
|
||||
#include "BKE_wm_runtime.hh"
|
||||
|
||||
namespace blender::bke {
|
||||
|
||||
WindowManagerRuntime::WindowManagerRuntime()
|
||||
{
|
||||
BKE_reports_init(&this->reports, RPT_STORE);
|
||||
}
|
||||
|
||||
WindowManagerRuntime::~WindowManagerRuntime()
|
||||
{
|
||||
BKE_reports_free(&this->reports);
|
||||
}
|
||||
|
||||
} // namespace blender::bke
|
|
@ -28,6 +28,7 @@
|
|||
# include "BLI_math_base.h"
|
||||
# include "BLI_threads.h"
|
||||
# include "BLI_utildefines.h"
|
||||
# include "BLI_vector.hh"
|
||||
|
||||
# include "BKE_global.hh"
|
||||
# include "BKE_image.h"
|
||||
|
@ -56,6 +57,25 @@ extern "C" {
|
|||
|
||||
struct StampData;
|
||||
|
||||
/* libswscale context creation and destruction is expensive.
|
||||
* Maintain a cache of already created contexts. */
|
||||
|
||||
constexpr int64_t swscale_cache_max_entries = 32;
|
||||
|
||||
struct SwscaleContext {
|
||||
int width = 0, height = 0;
|
||||
AVPixelFormat src_format = AV_PIX_FMT_NONE, dst_format = AV_PIX_FMT_NONE;
|
||||
int flags = 0;
|
||||
|
||||
SwsContext *context = nullptr;
|
||||
int64_t last_use_timestamp = 0;
|
||||
bool is_used = false;
|
||||
};
|
||||
|
||||
static ThreadMutex swscale_cache_lock = PTHREAD_MUTEX_INITIALIZER;
|
||||
static int64_t swscale_cache_timestamp = 0;
|
||||
static blender::Vector<SwscaleContext> *swscale_cache = nullptr;
|
||||
|
||||
struct FFMpegContext {
|
||||
int ffmpeg_type;
|
||||
AVCodecID ffmpeg_codec;
|
||||
|
@ -665,7 +685,7 @@ static const AVCodec *get_av1_encoder(
|
|||
return codec;
|
||||
}
|
||||
|
||||
SwsContext *BKE_ffmpeg_sws_get_context(
|
||||
static SwsContext *sws_create_context(
|
||||
int width, int height, int av_src_format, int av_dst_format, int sws_flags)
|
||||
{
|
||||
# if defined(FFMPEG_SWSCALE_THREADING)
|
||||
|
@ -703,6 +723,128 @@ SwsContext *BKE_ffmpeg_sws_get_context(
|
|||
|
||||
return c;
|
||||
}
|
||||
|
||||
static void init_swscale_cache_if_needed()
|
||||
{
|
||||
if (swscale_cache == nullptr) {
|
||||
swscale_cache = new blender::Vector<SwscaleContext>();
|
||||
swscale_cache_timestamp = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static bool remove_oldest_swscale_context()
|
||||
{
|
||||
int64_t oldest_index = -1;
|
||||
int64_t oldest_time = 0;
|
||||
for (int64_t index = 0; index < swscale_cache->size(); index++) {
|
||||
SwscaleContext &ctx = (*swscale_cache)[index];
|
||||
if (ctx.is_used) {
|
||||
continue;
|
||||
}
|
||||
int64_t time = swscale_cache_timestamp - ctx.last_use_timestamp;
|
||||
if (time > oldest_time) {
|
||||
oldest_time = time;
|
||||
oldest_index = index;
|
||||
}
|
||||
}
|
||||
|
||||
if (oldest_index >= 0) {
|
||||
SwscaleContext &ctx = (*swscale_cache)[oldest_index];
|
||||
sws_freeContext(ctx.context);
|
||||
swscale_cache->remove_and_reorder(oldest_index);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static void maintain_swscale_cache_size()
|
||||
{
|
||||
while (swscale_cache->size() > swscale_cache_max_entries) {
|
||||
if (!remove_oldest_swscale_context()) {
|
||||
/* Could not remove anything (all contexts are actively used),
|
||||
* stop trying. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SwsContext *BKE_ffmpeg_sws_get_context(
|
||||
int width, int height, int av_src_format, int av_dst_format, int sws_flags)
|
||||
{
|
||||
BLI_mutex_lock(&swscale_cache_lock);
|
||||
|
||||
init_swscale_cache_if_needed();
|
||||
|
||||
swscale_cache_timestamp++;
|
||||
|
||||
/* Search for unused context that has suitable parameters. */
|
||||
SwsContext *ctx = nullptr;
|
||||
for (SwscaleContext &c : *swscale_cache) {
|
||||
if (!c.is_used && c.width == width && c.height == height && c.src_format == av_src_format &&
|
||||
c.dst_format == av_dst_format && c.flags == sws_flags)
|
||||
{
|
||||
ctx = c.context;
|
||||
/* Mark as used. */
|
||||
c.is_used = true;
|
||||
c.last_use_timestamp = swscale_cache_timestamp;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ctx == nullptr) {
|
||||
/* No free matching context in cache: create a new one. */
|
||||
ctx = sws_create_context(width, height, av_src_format, av_dst_format, sws_flags);
|
||||
SwscaleContext c;
|
||||
c.width = width;
|
||||
c.height = height;
|
||||
c.src_format = AVPixelFormat(av_src_format);
|
||||
c.dst_format = AVPixelFormat(av_dst_format);
|
||||
c.flags = sws_flags;
|
||||
c.context = ctx;
|
||||
c.is_used = true;
|
||||
c.last_use_timestamp = swscale_cache_timestamp;
|
||||
swscale_cache->append(c);
|
||||
|
||||
maintain_swscale_cache_size();
|
||||
}
|
||||
|
||||
BLI_mutex_unlock(&swscale_cache_lock);
|
||||
return ctx;
|
||||
}
|
||||
|
||||
void BKE_ffmpeg_sws_release_context(SwsContext *ctx)
|
||||
{
|
||||
BLI_mutex_lock(&swscale_cache_lock);
|
||||
init_swscale_cache_if_needed();
|
||||
|
||||
bool found = false;
|
||||
for (SwscaleContext &c : *swscale_cache) {
|
||||
if (c.context == ctx) {
|
||||
BLI_assert_msg(c.is_used, "Releasing ffmpeg swscale context that is not in use");
|
||||
c.is_used = false;
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
BLI_assert_msg(found, "Releasing ffmpeg swscale context that is not in cache");
|
||||
UNUSED_VARS_NDEBUG(found);
|
||||
maintain_swscale_cache_size();
|
||||
|
||||
BLI_mutex_unlock(&swscale_cache_lock);
|
||||
}
|
||||
|
||||
void BKE_ffmpeg_exit()
|
||||
{
|
||||
BLI_mutex_lock(&swscale_cache_lock);
|
||||
if (swscale_cache != nullptr) {
|
||||
for (SwscaleContext &c : *swscale_cache) {
|
||||
sws_freeContext(c.context);
|
||||
}
|
||||
delete swscale_cache;
|
||||
swscale_cache = nullptr;
|
||||
}
|
||||
BLI_mutex_unlock(&swscale_cache_lock);
|
||||
}
|
||||
|
||||
void BKE_ffmpeg_sws_scale_frame(SwsContext *ctx, AVFrame *dst, const AVFrame *src)
|
||||
{
|
||||
# if defined(FFMPEG_SWSCALE_THREADING)
|
||||
|
@ -1677,7 +1819,7 @@ static void end_ffmpeg_impl(FFMpegContext *context, int is_autosplit)
|
|||
}
|
||||
|
||||
if (context->img_convert_ctx != nullptr) {
|
||||
sws_freeContext(context->img_convert_ctx);
|
||||
BKE_ffmpeg_sws_release_context(context->img_convert_ctx);
|
||||
context->img_convert_ctx = nullptr;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,24 +13,20 @@
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern
|
||||
/** Return an indication of time, expressed as
|
||||
* seconds since some fixed point. Successive calls
|
||||
* are guaranteed to generate values greater than or
|
||||
* equal to the last call. */
|
||||
double
|
||||
BLI_check_seconds_timer(void);
|
||||
/**
|
||||
* Return an indication of time, expressed as seconds since some fixed point.
|
||||
* Successive calls are guaranteed to generate values greater than or equal to the last call.
|
||||
*/
|
||||
extern double BLI_time_now_seconds(void);
|
||||
|
||||
extern
|
||||
/** `int` version of #BLI_check_seconds_timer. */
|
||||
long int
|
||||
BLI_check_seconds_timer_i(void);
|
||||
/** `int` version of #BLI_time_now_seconds. */
|
||||
extern long int BLI_time_now_seconds_i(void);
|
||||
|
||||
/**
|
||||
* Platform-independent sleep function.
|
||||
* \param ms: Number of milliseconds to sleep
|
||||
*/
|
||||
void BLI_sleep_ms(int ms);
|
||||
void BLI_time_sleep_ms(int ms);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -9,12 +9,12 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "BLI_time.h" /* for BLI_check_seconds_timer */
|
||||
#include "BLI_time.h" /* for BLI_time_now_seconds */
|
||||
#include "BLI_utildefines.h" /* for AT */
|
||||
|
||||
#define TIMEIT_START(var) \
|
||||
{ \
|
||||
double _timeit_##var = BLI_check_seconds_timer(); \
|
||||
double _timeit_##var = BLI_time_now_seconds(); \
|
||||
printf("time start (" #var "): " AT "\n"); \
|
||||
fflush(stdout); \
|
||||
{ \
|
||||
|
@ -23,7 +23,7 @@
|
|||
/**
|
||||
* \return the time since TIMEIT_START was called.
|
||||
*/
|
||||
#define TIMEIT_VALUE(var) (float)(BLI_check_seconds_timer() - _timeit_##var)
|
||||
#define TIMEIT_VALUE(var) (float)(BLI_time_now_seconds() - _timeit_##var)
|
||||
|
||||
#define TIMEIT_VALUE_PRINT(var) \
|
||||
{ \
|
||||
|
@ -54,7 +54,7 @@
|
|||
{ \
|
||||
static float _sum_##var = 0.0f; \
|
||||
static float _num_##var = 0.0f; \
|
||||
double _timeit_##var = BLI_check_seconds_timer(); \
|
||||
double _timeit_##var = BLI_time_now_seconds(); \
|
||||
printf("time start (" #var "): " AT "\n"); \
|
||||
fflush(stdout); \
|
||||
{ \
|
||||
|
@ -95,13 +95,13 @@
|
|||
|
||||
#define TIMEIT_BLOCK_START(id) \
|
||||
{ \
|
||||
double _timeit_block_start_##id = BLI_check_seconds_timer(); \
|
||||
double _timeit_block_start_##id = BLI_time_now_seconds(); \
|
||||
{ \
|
||||
(void)0
|
||||
|
||||
#define TIMEIT_BLOCK_END(id) \
|
||||
} \
|
||||
_timeit_var_##id += (BLI_check_seconds_timer() - _timeit_block_start_##id); \
|
||||
_timeit_var_##id += (BLI_time_now_seconds() - _timeit_block_start_##id); \
|
||||
} \
|
||||
(void)0
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#define GET_TIME() BLI_check_seconds_timer()
|
||||
#define GET_TIME() BLI_time_now_seconds()
|
||||
|
||||
typedef struct TimedFunction {
|
||||
struct TimedFunction *next, *prev;
|
||||
|
|
|
@ -3557,7 +3557,7 @@ IMesh boolean_trimesh(IMesh &tm_in,
|
|||
return IMesh(tm_in);
|
||||
}
|
||||
# ifdef PERFDEBUG
|
||||
double start_time = BLI_check_seconds_timer();
|
||||
double start_time = BLI_time_now_seconds();
|
||||
std::cout << " boolean_trimesh, timing begins\n";
|
||||
# endif
|
||||
|
||||
|
@ -3567,7 +3567,7 @@ IMesh boolean_trimesh(IMesh &tm_in,
|
|||
std::cout << "\nboolean_tm_input after intersection:\n" << tm_si;
|
||||
}
|
||||
# ifdef PERFDEBUG
|
||||
double intersect_time = BLI_check_seconds_timer();
|
||||
double intersect_time = BLI_time_now_seconds();
|
||||
std::cout << " intersected, time = " << intersect_time - start_time << "\n";
|
||||
# endif
|
||||
|
||||
|
@ -3578,12 +3578,12 @@ IMesh boolean_trimesh(IMesh &tm_in,
|
|||
auto si_shape_fn = [shape_fn, tm_si](int t) { return shape_fn(tm_si.face(t)->orig); };
|
||||
TriMeshTopology tm_si_topo(tm_si);
|
||||
# ifdef PERFDEBUG
|
||||
double topo_time = BLI_check_seconds_timer();
|
||||
double topo_time = BLI_time_now_seconds();
|
||||
std::cout << " topology built, time = " << topo_time - intersect_time << "\n";
|
||||
# endif
|
||||
bool pwn = is_pwn(tm_si, tm_si_topo);
|
||||
# ifdef PERFDEBUG
|
||||
double pwn_time = BLI_check_seconds_timer();
|
||||
double pwn_time = BLI_time_now_seconds();
|
||||
std::cout << " pwn checked, time = " << pwn_time - topo_time << "\n";
|
||||
# endif
|
||||
IMesh tm_out;
|
||||
|
@ -3599,14 +3599,14 @@ IMesh boolean_trimesh(IMesh &tm_in,
|
|||
tm_out = raycast_patches_boolean(tm_si, op, nshapes, shape_fn, pinfo, arena);
|
||||
}
|
||||
# ifdef PERFDEBUG
|
||||
double raycast_time = BLI_check_seconds_timer();
|
||||
double raycast_time = BLI_time_now_seconds();
|
||||
std::cout << " raycast_boolean done, time = " << raycast_time - pwn_time << "\n";
|
||||
# endif
|
||||
}
|
||||
else {
|
||||
PatchesInfo pinfo = find_patches(tm_si, tm_si_topo);
|
||||
# ifdef PERFDEBUG
|
||||
double patch_time = BLI_check_seconds_timer();
|
||||
double patch_time = BLI_time_now_seconds();
|
||||
std::cout << " patches found, time = " << patch_time - pwn_time << "\n";
|
||||
# endif
|
||||
CellsInfo cinfo = find_cells(tm_si, tm_si_topo, pinfo);
|
||||
|
@ -3614,12 +3614,12 @@ IMesh boolean_trimesh(IMesh &tm_in,
|
|||
std::cout << "Input is PWN\n";
|
||||
}
|
||||
# ifdef PERFDEBUG
|
||||
double cell_time = BLI_check_seconds_timer();
|
||||
double cell_time = BLI_time_now_seconds();
|
||||
std::cout << " cells found, time = " << cell_time - pwn_time << "\n";
|
||||
# endif
|
||||
finish_patch_cell_graph(tm_si, cinfo, pinfo, tm_si_topo, arena);
|
||||
# ifdef PERFDEBUG
|
||||
double finish_pc_time = BLI_check_seconds_timer();
|
||||
double finish_pc_time = BLI_time_now_seconds();
|
||||
std::cout << " finished patch-cell graph, time = " << finish_pc_time - cell_time << "\n";
|
||||
# endif
|
||||
bool pc_ok = patch_cell_graph_ok(cinfo, pinfo);
|
||||
|
@ -3631,7 +3631,7 @@ IMesh boolean_trimesh(IMesh &tm_in,
|
|||
cinfo.init_windings(nshapes);
|
||||
int c_ambient = find_ambient_cell(tm_si, nullptr, tm_si_topo, pinfo, arena);
|
||||
# ifdef PERFDEBUG
|
||||
double amb_time = BLI_check_seconds_timer();
|
||||
double amb_time = BLI_time_now_seconds();
|
||||
std::cout << " ambient cell found, time = " << amb_time - finish_pc_time << "\n";
|
||||
# endif
|
||||
if (c_ambient == NO_INDEX) {
|
||||
|
@ -3641,12 +3641,12 @@ IMesh boolean_trimesh(IMesh &tm_in,
|
|||
}
|
||||
propagate_windings_and_in_output_volume(pinfo, cinfo, c_ambient, op, nshapes, si_shape_fn);
|
||||
# ifdef PERFDEBUG
|
||||
double propagate_time = BLI_check_seconds_timer();
|
||||
double propagate_time = BLI_time_now_seconds();
|
||||
std::cout << " windings propagated, time = " << propagate_time - amb_time << "\n";
|
||||
# endif
|
||||
tm_out = extract_from_in_output_volume_diffs(tm_si, pinfo, cinfo, arena);
|
||||
# ifdef PERFDEBUG
|
||||
double extract_time = BLI_check_seconds_timer();
|
||||
double extract_time = BLI_time_now_seconds();
|
||||
std::cout << " extracted, time = " << extract_time - propagate_time << "\n";
|
||||
# endif
|
||||
if (dbg_level > 0) {
|
||||
|
@ -3662,7 +3662,7 @@ IMesh boolean_trimesh(IMesh &tm_in,
|
|||
std::cout << "boolean tm output:\n" << tm_out;
|
||||
}
|
||||
# ifdef PERFDEBUG
|
||||
double end_time = BLI_check_seconds_timer();
|
||||
double end_time = BLI_time_now_seconds();
|
||||
std::cout << " boolean_trimesh done, total time = " << end_time - start_time << "\n";
|
||||
# endif
|
||||
return tm_out;
|
||||
|
@ -3708,7 +3708,7 @@ IMesh boolean_mesh(IMesh &imesh,
|
|||
IMesh *tm_in = imesh_triangulated;
|
||||
IMesh our_triangulation;
|
||||
# ifdef PERFDEBUG
|
||||
double start_time = BLI_check_seconds_timer();
|
||||
double start_time = BLI_time_now_seconds();
|
||||
std::cout << "boolean_mesh, timing begins\n";
|
||||
# endif
|
||||
if (tm_in == nullptr) {
|
||||
|
@ -3716,7 +3716,7 @@ IMesh boolean_mesh(IMesh &imesh,
|
|||
tm_in = &our_triangulation;
|
||||
}
|
||||
# ifdef PERFDEBUG
|
||||
double tri_time = BLI_check_seconds_timer();
|
||||
double tri_time = BLI_time_now_seconds();
|
||||
std::cout << "triangulated, time = " << tri_time - start_time << "\n";
|
||||
# endif
|
||||
if (dbg_level > 1) {
|
||||
|
@ -3724,7 +3724,7 @@ IMesh boolean_mesh(IMesh &imesh,
|
|||
}
|
||||
IMesh tm_out = boolean_trimesh(*tm_in, op, nshapes, shape_fn, use_self, hole_tolerant, arena);
|
||||
# ifdef PERFDEBUG
|
||||
double bool_tri_time = BLI_check_seconds_timer();
|
||||
double bool_tri_time = BLI_time_now_seconds();
|
||||
std::cout << "boolean_trimesh done, time = " << bool_tri_time - tri_time << "\n";
|
||||
# endif
|
||||
if (dbg_level > 1) {
|
||||
|
@ -3733,7 +3733,7 @@ IMesh boolean_mesh(IMesh &imesh,
|
|||
}
|
||||
IMesh ans = polymesh_from_trimesh_with_dissolve(tm_out, imesh, arena);
|
||||
# ifdef PERFDEBUG
|
||||
double dissolve_time = BLI_check_seconds_timer();
|
||||
double dissolve_time = BLI_time_now_seconds();
|
||||
std::cout << "polymesh from dissolving, time = " << dissolve_time - bool_tri_time << "\n";
|
||||
# endif
|
||||
if (dbg_level > 0) {
|
||||
|
@ -3744,7 +3744,7 @@ IMesh boolean_mesh(IMesh &imesh,
|
|||
}
|
||||
}
|
||||
# ifdef PERFDEBUG
|
||||
double end_time = BLI_check_seconds_timer();
|
||||
double end_time = BLI_time_now_seconds();
|
||||
std::cout << "boolean_mesh done, total time = " << end_time - start_time << "\n";
|
||||
# endif
|
||||
return ans;
|
||||
|
|
|
@ -2954,7 +2954,7 @@ IMesh trimesh_nary_intersect(const IMesh &tm_in,
|
|||
}
|
||||
# ifdef PERFDEBUG
|
||||
perfdata_init();
|
||||
double start_time = BLI_check_seconds_timer();
|
||||
double start_time = BLI_time_now_seconds();
|
||||
std::cout << "trimesh_nary_intersect start\n";
|
||||
# endif
|
||||
/* Usually can use tm_in but if it has degenerate or illegal triangles,
|
||||
|
@ -2972,17 +2972,17 @@ IMesh trimesh_nary_intersect(const IMesh &tm_in,
|
|||
}
|
||||
}
|
||||
# ifdef PERFDEBUG
|
||||
double clean_time = BLI_check_seconds_timer();
|
||||
double clean_time = BLI_time_now_seconds();
|
||||
std::cout << "cleaned, time = " << clean_time - start_time << "\n";
|
||||
# endif
|
||||
Array<BoundingBox> tri_bb = calc_face_bounding_boxes(*tm_clean);
|
||||
# ifdef PERFDEBUG
|
||||
double bb_calc_time = BLI_check_seconds_timer();
|
||||
double bb_calc_time = BLI_time_now_seconds();
|
||||
std::cout << "bbs calculated, time = " << bb_calc_time - clean_time << "\n";
|
||||
# endif
|
||||
TriOverlaps tri_ov(*tm_clean, tri_bb, nshapes, shape_fn, use_self);
|
||||
# ifdef PERFDEBUG
|
||||
double overlap_time = BLI_check_seconds_timer();
|
||||
double overlap_time = BLI_time_now_seconds();
|
||||
std::cout << "intersect overlaps calculated, time = " << overlap_time - bb_calc_time << "\n";
|
||||
# endif
|
||||
Array<IMesh> tri_subdivided(tm_clean->face_size(), NoInitialization());
|
||||
|
@ -2995,7 +2995,7 @@ IMesh trimesh_nary_intersect(const IMesh &tm_in,
|
|||
}
|
||||
});
|
||||
# ifdef PERFDEBUG
|
||||
double plane_populate = BLI_check_seconds_timer();
|
||||
double plane_populate = BLI_time_now_seconds();
|
||||
std::cout << "planes populated, time = " << plane_populate - overlap_time << "\n";
|
||||
# endif
|
||||
/* itt_map((a,b)) will hold the intersection value resulting from intersecting
|
||||
|
@ -3004,7 +3004,7 @@ IMesh trimesh_nary_intersect(const IMesh &tm_in,
|
|||
itt_map.reserve(tri_ov.overlap().size());
|
||||
calc_overlap_itts(itt_map, *tm_clean, tri_ov, arena);
|
||||
# ifdef PERFDEBUG
|
||||
double itt_time = BLI_check_seconds_timer();
|
||||
double itt_time = BLI_time_now_seconds();
|
||||
std::cout << "itts found, time = " << itt_time - plane_populate << "\n";
|
||||
# endif
|
||||
CoplanarClusterInfo clinfo = find_clusters(*tm_clean, tri_bb, itt_map);
|
||||
|
@ -3012,7 +3012,7 @@ IMesh trimesh_nary_intersect(const IMesh &tm_in,
|
|||
std::cout << clinfo;
|
||||
}
|
||||
# ifdef PERFDEBUG
|
||||
double find_cluster_time = BLI_check_seconds_timer();
|
||||
double find_cluster_time = BLI_time_now_seconds();
|
||||
std::cout << "clusters found, time = " << find_cluster_time - itt_time << "\n";
|
||||
doperfmax(0, tm_in.face_size());
|
||||
doperfmax(1, clinfo.tot_cluster());
|
||||
|
@ -3020,7 +3020,7 @@ IMesh trimesh_nary_intersect(const IMesh &tm_in,
|
|||
# endif
|
||||
calc_subdivided_non_cluster_tris(tri_subdivided, *tm_clean, itt_map, clinfo, tri_ov, arena);
|
||||
# ifdef PERFDEBUG
|
||||
double subdivided_tris_time = BLI_check_seconds_timer();
|
||||
double subdivided_tris_time = BLI_time_now_seconds();
|
||||
std::cout << "subdivided non-cluster tris found, time = " << subdivided_tris_time - itt_time
|
||||
<< "\n";
|
||||
# endif
|
||||
|
@ -3029,13 +3029,13 @@ IMesh trimesh_nary_intersect(const IMesh &tm_in,
|
|||
cluster_subdivided[c] = calc_cluster_subdivided(clinfo, c, *tm_clean, tri_ov, itt_map, arena);
|
||||
}
|
||||
# ifdef PERFDEBUG
|
||||
double cluster_subdivide_time = BLI_check_seconds_timer();
|
||||
double cluster_subdivide_time = BLI_time_now_seconds();
|
||||
std::cout << "subdivided clusters found, time = "
|
||||
<< cluster_subdivide_time - subdivided_tris_time << "\n";
|
||||
# endif
|
||||
calc_cluster_tris(tri_subdivided, *tm_clean, clinfo, cluster_subdivided, arena);
|
||||
# ifdef PERFDEBUG
|
||||
double extract_time = BLI_check_seconds_timer();
|
||||
double extract_time = BLI_time_now_seconds();
|
||||
std::cout << "subdivided cluster tris found, time = " << extract_time - cluster_subdivide_time
|
||||
<< "\n";
|
||||
# endif
|
||||
|
@ -3045,7 +3045,7 @@ IMesh trimesh_nary_intersect(const IMesh &tm_in,
|
|||
std::cout << combined;
|
||||
}
|
||||
# ifdef PERFDEBUG
|
||||
double end_time = BLI_check_seconds_timer();
|
||||
double end_time = BLI_time_now_seconds();
|
||||
std::cout << "triangles combined, time = " << end_time - extract_time << "\n";
|
||||
std::cout << "trimesh_nary_intersect done, total time = " << end_time - start_time << "\n";
|
||||
dump_perfdata();
|
||||
|
|
|
@ -63,7 +63,7 @@
|
|||
* // tag job 'processed
|
||||
* BLI_threadpool_insert(&lb, job);
|
||||
* }
|
||||
* else BLI_sleep_ms(50);
|
||||
* else BLI_time_sleep_ms(50);
|
||||
*
|
||||
* // Find if a job is ready, this the do_something_func() should write in job somewhere.
|
||||
* cont = 0;
|
||||
|
@ -687,7 +687,7 @@ void *BLI_thread_queue_pop_timeout(ThreadQueue *queue, int ms)
|
|||
void *work = nullptr;
|
||||
timespec timeout;
|
||||
|
||||
t = BLI_check_seconds_timer();
|
||||
t = BLI_time_now_seconds();
|
||||
wait_timeout(&timeout, ms);
|
||||
|
||||
/* wait until there is work */
|
||||
|
@ -696,7 +696,7 @@ void *BLI_thread_queue_pop_timeout(ThreadQueue *queue, int ms)
|
|||
if (pthread_cond_timedwait(&queue->push_cond, &queue->mutex, &timeout) == ETIMEDOUT) {
|
||||
break;
|
||||
}
|
||||
if (BLI_check_seconds_timer() - t >= ms * 0.001) {
|
||||
if (BLI_time_now_seconds() - t >= ms * 0.001) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
# define WIN32_LEAN_AND_MEAN
|
||||
# include <windows.h>
|
||||
|
||||
double BLI_check_seconds_timer(void)
|
||||
double BLI_time_now_seconds(void)
|
||||
{
|
||||
static int hasperfcounter = -1; /* (-1 == unknown) */
|
||||
static double perffreq;
|
||||
|
@ -47,12 +47,12 @@ double BLI_check_seconds_timer(void)
|
|||
}
|
||||
}
|
||||
|
||||
long int BLI_check_seconds_timer_i(void)
|
||||
long int BLI_time_now_seconds_i(void)
|
||||
{
|
||||
return (long int)BLI_check_seconds_timer();
|
||||
return (long int)BLI_time_now_seconds();
|
||||
}
|
||||
|
||||
void BLI_sleep_ms(int ms)
|
||||
void BLI_time_sleep_ms(int ms)
|
||||
{
|
||||
Sleep(ms);
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ void BLI_sleep_ms(int ms)
|
|||
# include <sys/time.h>
|
||||
# include <unistd.h>
|
||||
|
||||
double BLI_check_seconds_timer(void)
|
||||
double BLI_time_now_seconds(void)
|
||||
{
|
||||
struct timeval tv;
|
||||
struct timezone tz;
|
||||
|
@ -72,7 +72,7 @@ double BLI_check_seconds_timer(void)
|
|||
return ((double)tv.tv_sec + tv.tv_usec / 1000000.0);
|
||||
}
|
||||
|
||||
long int BLI_check_seconds_timer_i(void)
|
||||
long int BLI_time_now_seconds_i(void)
|
||||
{
|
||||
struct timeval tv;
|
||||
struct timezone tz;
|
||||
|
@ -82,7 +82,7 @@ long int BLI_check_seconds_timer_i(void)
|
|||
return tv.tv_sec;
|
||||
}
|
||||
|
||||
void BLI_sleep_ms(int ms)
|
||||
void BLI_time_sleep_ms(int ms)
|
||||
{
|
||||
if (ms >= 1000) {
|
||||
sleep(ms / 1000);
|
||||
|
|
|
@ -1877,9 +1877,9 @@ void text_test(
|
|||
}
|
||||
in.epsilon = b_before_arcs_in.epsilon;
|
||||
in.need_ids = need_ids;
|
||||
double tstart = BLI_check_seconds_timer();
|
||||
double tstart = BLI_time_now_seconds();
|
||||
CDT_result<T> out = delaunay_2d_calc(in, otype);
|
||||
double tend = BLI_check_seconds_timer();
|
||||
double tend = BLI_time_now_seconds();
|
||||
if (print_timing) {
|
||||
std::cout << "time = " << tend - tstart << "\n";
|
||||
}
|
||||
|
@ -2190,10 +2190,10 @@ void rand_delaunay_test(int test_kind,
|
|||
}
|
||||
|
||||
/* Run the test. */
|
||||
double tstart = BLI_check_seconds_timer();
|
||||
double tstart = BLI_time_now_seconds();
|
||||
CDT_result<T> out = delaunay_2d_calc(in, otype);
|
||||
EXPECT_NE(out.vert.size(), 0);
|
||||
times[lg_size] += BLI_check_seconds_timer() - tstart;
|
||||
times[lg_size] += BLI_time_now_seconds() - tstart;
|
||||
if (DO_DRAW) {
|
||||
graph_draw<T>(test_label, out.vert, out.edge, out.face);
|
||||
}
|
||||
|
|
|
@ -980,7 +980,7 @@ static void spheresphere_test(int nrings, double y_offset, bool use_self)
|
|||
return;
|
||||
}
|
||||
BLI_task_scheduler_init(); /* Without this, no parallelism. */
|
||||
double time_start = BLI_check_seconds_timer();
|
||||
double time_start = BLI_time_now_seconds();
|
||||
IMeshArena arena;
|
||||
int nsegs = 2 * nrings;
|
||||
int sphere_verts_num;
|
||||
|
@ -1009,7 +1009,7 @@ static void spheresphere_test(int nrings, double y_offset, bool use_self)
|
|||
sphere_verts_num,
|
||||
&arena);
|
||||
IMesh mesh(tris);
|
||||
double time_create = BLI_check_seconds_timer();
|
||||
double time_create = BLI_time_now_seconds();
|
||||
// write_obj_mesh(mesh, "spheresphere_in");
|
||||
IMesh out;
|
||||
if (use_self) {
|
||||
|
@ -1020,7 +1020,7 @@ static void spheresphere_test(int nrings, double y_offset, bool use_self)
|
|||
out = trimesh_nary_intersect(
|
||||
mesh, 2, [nf](int t) { return t < nf ? 0 : 1; }, false, &arena);
|
||||
}
|
||||
double time_intersect = BLI_check_seconds_timer();
|
||||
double time_intersect = BLI_time_now_seconds();
|
||||
std::cout << "Create time: " << time_create - time_start << "\n";
|
||||
std::cout << "Intersect time: " << time_intersect - time_create << "\n";
|
||||
std::cout << "Total time: " << time_intersect - time_start << "\n";
|
||||
|
@ -1120,7 +1120,7 @@ static void spheregrid_test(int nrings, int grid_level, double z_offset, bool us
|
|||
return;
|
||||
}
|
||||
BLI_task_scheduler_init(); /* Without this, no parallelism. */
|
||||
double time_start = BLI_check_seconds_timer();
|
||||
double time_start = BLI_time_now_seconds();
|
||||
IMeshArena arena;
|
||||
int sphere_verts_num;
|
||||
int sphere_tris_num;
|
||||
|
@ -1154,7 +1154,7 @@ static void spheregrid_test(int nrings, int grid_level, double z_offset, bool us
|
|||
sphere_tris_num,
|
||||
&arena);
|
||||
IMesh mesh(tris);
|
||||
double time_create = BLI_check_seconds_timer();
|
||||
double time_create = BLI_time_now_seconds();
|
||||
// write_obj_mesh(mesh, "spheregrid_in");
|
||||
IMesh out;
|
||||
if (use_self) {
|
||||
|
@ -1165,7 +1165,7 @@ static void spheregrid_test(int nrings, int grid_level, double z_offset, bool us
|
|||
out = trimesh_nary_intersect(
|
||||
mesh, 2, [nf](int t) { return t < nf ? 0 : 1; }, false, &arena);
|
||||
}
|
||||
double time_intersect = BLI_check_seconds_timer();
|
||||
double time_intersect = BLI_time_now_seconds();
|
||||
std::cout << "Create time: " << time_create - time_start << "\n";
|
||||
std::cout << "Intersect time: " << time_intersect - time_create << "\n";
|
||||
std::cout << "Total time: " << time_intersect - time_start << "\n";
|
||||
|
@ -1187,7 +1187,7 @@ static void gridgrid_test(int x_level_1,
|
|||
/* Make two grids, each 4x4, with given subdivision levels in x and y,
|
||||
* and the second offset from the first by x_off, y_off, and rotated by rot_deg degrees. */
|
||||
BLI_task_scheduler_init(); /* Without this, no parallelism. */
|
||||
double time_start = BLI_check_seconds_timer();
|
||||
double time_start = BLI_time_now_seconds();
|
||||
IMeshArena arena;
|
||||
int x_subdivs_1 = 1 << x_level_1;
|
||||
int y_subdivs_1 = 1 << y_level_1;
|
||||
|
@ -1223,7 +1223,7 @@ static void gridgrid_test(int x_level_1,
|
|||
grid_tris_1_num,
|
||||
&arena);
|
||||
IMesh mesh(tris);
|
||||
double time_create = BLI_check_seconds_timer();
|
||||
double time_create = BLI_time_now_seconds();
|
||||
// write_obj_mesh(mesh, "gridgrid_in");
|
||||
IMesh out;
|
||||
if (use_self) {
|
||||
|
@ -1234,7 +1234,7 @@ static void gridgrid_test(int x_level_1,
|
|||
out = trimesh_nary_intersect(
|
||||
mesh, 2, [nf](int t) { return t < nf ? 0 : 1; }, false, &arena);
|
||||
}
|
||||
double time_intersect = BLI_check_seconds_timer();
|
||||
double time_intersect = BLI_time_now_seconds();
|
||||
std::cout << "Create time: " << time_create - time_start << "\n";
|
||||
std::cout << "Intersect time: " << time_intersect - time_create << "\n";
|
||||
std::cout << "Total time: " << time_intersect - time_start << "\n";
|
||||
|
|
|
@ -3666,7 +3666,7 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
|
|||
}
|
||||
|
||||
if ((fd->skip_flags & BLO_READ_SKIP_DATA) == 0) {
|
||||
fd->reports->duration.libraries = BLI_check_seconds_timer();
|
||||
fd->reports->duration.libraries = BLI_time_now_seconds();
|
||||
read_libraries(fd, &mainlist);
|
||||
|
||||
blo_join_main(&mainlist);
|
||||
|
@ -3681,7 +3681,7 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
|
|||
read_undo_remap_noundo_data(fd);
|
||||
}
|
||||
|
||||
fd->reports->duration.libraries = BLI_check_seconds_timer() - fd->reports->duration.libraries;
|
||||
fd->reports->duration.libraries = BLI_time_now_seconds() - fd->reports->duration.libraries;
|
||||
|
||||
/* Skip in undo case. */
|
||||
if ((fd->flags & FD_FLAGS_IS_MEMFILE) == 0) {
|
||||
|
@ -3739,7 +3739,7 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
|
|||
* we can re-generate overrides from their references. */
|
||||
if ((fd->flags & FD_FLAGS_IS_MEMFILE) == 0) {
|
||||
/* Do not apply in undo case! */
|
||||
fd->reports->duration.lib_overrides = BLI_check_seconds_timer();
|
||||
fd->reports->duration.lib_overrides = BLI_time_now_seconds();
|
||||
|
||||
std::string cur_view_layer_name = bfd->cur_view_layer != nullptr ?
|
||||
bfd->cur_view_layer->name :
|
||||
|
@ -3760,7 +3760,7 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
|
|||
* Proper fix involves first addressing #90610. */
|
||||
BKE_main_collections_parent_relations_rebuild(bfd->main);
|
||||
|
||||
fd->reports->duration.lib_overrides = BLI_check_seconds_timer() -
|
||||
fd->reports->duration.lib_overrides = BLI_time_now_seconds() -
|
||||
fd->reports->duration.lib_overrides;
|
||||
}
|
||||
|
||||
|
|
|
@ -2592,7 +2592,7 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *bmain)
|
|||
ob = static_cast<Object *>(ob->id.next))
|
||||
{
|
||||
if (ob->pd) {
|
||||
ob->pd->seed = (uint(ceil(BLI_check_seconds_timer())) + 1) % 128;
|
||||
ob->pd->seed = (uint(ceil(BLI_time_now_seconds())) + 1) % 128;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7763,7 +7763,7 @@ void BM_mesh_bevel(BMesh *bm,
|
|||
}
|
||||
|
||||
#ifdef BEVEL_DEBUG_TIME
|
||||
double start_time = BLI_check_seconds_timer();
|
||||
double start_time = BLI_time_now_seconds();
|
||||
#endif
|
||||
|
||||
/* Disable the miters with the cutoff vertex mesh method, the combination isn't useful anyway. */
|
||||
|
@ -7931,7 +7931,7 @@ void BM_mesh_bevel(BMesh *bm,
|
|||
BLI_memarena_free(bp.mem_arena);
|
||||
|
||||
#ifdef BEVEL_DEBUG_TIME
|
||||
double end_time = BLI_check_seconds_timer();
|
||||
double end_time = BLI_time_now_seconds();
|
||||
printf("BMESH BEVEL TIME = %.3f\n", end_time - start_time);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -350,11 +350,11 @@ static bool bmesh_boolean(BMesh *bm,
|
|||
IMeshArena arena;
|
||||
IMesh m_triangulated;
|
||||
# ifdef PERF_DEBUG
|
||||
double start_time = BLI_check_seconds_timer();
|
||||
double start_time = BLI_time_now_seconds();
|
||||
# endif
|
||||
IMesh m_in = mesh_from_bm(bm, looptris, looptris_tot, &m_triangulated, &arena);
|
||||
# ifdef PERF_DEBUG
|
||||
double mesh_time = BLI_check_seconds_timer();
|
||||
double mesh_time = BLI_time_now_seconds();
|
||||
std::cout << "bmesh_boolean, imesh_from_bm done, time = " << mesh_time - start_time << "\n";
|
||||
# endif
|
||||
std::function<int(int)> shape_fn;
|
||||
|
@ -382,12 +382,12 @@ static bool bmesh_boolean(BMesh *bm,
|
|||
IMesh m_out = boolean_mesh(
|
||||
m_in, boolean_mode, nshapes, shape_fn, use_self, hole_tolerant, &m_triangulated, &arena);
|
||||
# ifdef PERF_DEBUG
|
||||
double boolean_time = BLI_check_seconds_timer();
|
||||
double boolean_time = BLI_time_now_seconds();
|
||||
std::cout << "boolean done, time = " << boolean_time - mesh_time << "\n";
|
||||
# endif
|
||||
bool any_change = apply_mesh_output_to_bmesh(bm, m_out, keep_hidden);
|
||||
# ifdef PERF_DEBUG
|
||||
double apply_mesh_time = BLI_check_seconds_timer();
|
||||
double apply_mesh_time = BLI_time_now_seconds();
|
||||
std::cout << "applied boolean output to bmesh, time = " << apply_mesh_time - boolean_time
|
||||
<< "\n";
|
||||
# endif
|
||||
|
|
|
@ -304,7 +304,7 @@ void ExecutionGroup::execute(ExecutionSystem *graph)
|
|||
} /** \note Early break out. */
|
||||
uint chunk_index;
|
||||
|
||||
execution_start_time_ = BLI_check_seconds_timer();
|
||||
execution_start_time_ = BLI_time_now_seconds();
|
||||
|
||||
chunks_finished_ = 0;
|
||||
bTree_ = bTree;
|
||||
|
|
|
@ -73,7 +73,7 @@ void ScreenLensDistortionOperation::init_execution()
|
|||
input_program_ = this->get_input_socket_reader(0);
|
||||
this->init_mutex();
|
||||
|
||||
uint rng_seed = uint(BLI_check_seconds_timer_i() & UINT_MAX);
|
||||
uint rng_seed = uint(BLI_time_now_seconds_i() & UINT_MAX);
|
||||
rng_seed ^= uint(POINTER_AS_INT(input_program_));
|
||||
rng_ = BLI_rng_new(rng_seed);
|
||||
}
|
||||
|
|
|
@ -7,6 +7,11 @@
|
|||
void main()
|
||||
{
|
||||
ivec2 texel = ivec2(gl_GlobalInvocationID.xy);
|
||||
ivec2 output_texel = texel + lower_bound;
|
||||
if (any(greaterThan(output_texel, upper_bound))) {
|
||||
return;
|
||||
}
|
||||
|
||||
vec4 input_color = texture_load(input_tx, texel);
|
||||
|
||||
#if defined(DIRECT_OUTPUT)
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
GPU_SHADER_CREATE_INFO(compositor_write_output_shared)
|
||||
.local_group_size(16, 16)
|
||||
.push_constant(Type::IVEC2, "lower_bound")
|
||||
.push_constant(Type::IVEC2, "upper_bound")
|
||||
.sampler(0, ImageType::FLOAT_2D, "input_tx")
|
||||
.image(0, GPU_RGBA16F, Qualifier::WRITE, ImageType::FLOAT_2D, "output_img")
|
||||
.compute_source("compositor_write_output.glsl");
|
||||
|
|
|
@ -29,7 +29,7 @@ void AbstractBuilderPipeline::build()
|
|||
{
|
||||
double start_time = 0.0;
|
||||
if (G.debug & (G_DEBUG_DEPSGRAPH_BUILD | G_DEBUG_DEPSGRAPH_TIME)) {
|
||||
start_time = BLI_check_seconds_timer();
|
||||
start_time = BLI_time_now_seconds();
|
||||
}
|
||||
|
||||
build_step_sanity_check();
|
||||
|
@ -38,7 +38,7 @@ void AbstractBuilderPipeline::build()
|
|||
build_step_finalize();
|
||||
|
||||
if (G.debug & (G_DEBUG_DEPSGRAPH_BUILD | G_DEBUG_DEPSGRAPH_TIME)) {
|
||||
printf("Depsgraph built in %f seconds.\n", BLI_check_seconds_timer() - start_time);
|
||||
printf("Depsgraph built in %f seconds.\n", BLI_time_now_seconds() - start_time);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ void DepsgraphDebug::begin_graph_evaluation()
|
|||
return;
|
||||
}
|
||||
|
||||
const double current_time = BLI_check_seconds_timer();
|
||||
const double current_time = BLI_time_now_seconds();
|
||||
|
||||
graph_evaluation_start_time_ = current_time;
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ void DepsgraphDebug::end_graph_evaluation()
|
|||
return;
|
||||
}
|
||||
|
||||
const double graph_eval_end_time = BLI_check_seconds_timer();
|
||||
const double graph_eval_end_time = BLI_time_now_seconds();
|
||||
const double graph_eval_time = graph_eval_end_time - graph_evaluation_start_time_;
|
||||
|
||||
if (name.empty()) {
|
||||
|
|
|
@ -93,9 +93,9 @@ void evaluate_node(const DepsgraphEvalState *state, OperationNode *operation_nod
|
|||
BLI_assert_msg(!operation_node->is_noop(), "NOOP nodes should not actually be scheduled");
|
||||
/* Perform operation. */
|
||||
if (state->do_stats) {
|
||||
const double start_time = BLI_check_seconds_timer();
|
||||
const double start_time = BLI_time_now_seconds();
|
||||
operation_node->evaluate(depsgraph);
|
||||
operation_node->stats.current_time += BLI_check_seconds_timer() - start_time;
|
||||
operation_node->stats.current_time += BLI_time_now_seconds() - start_time;
|
||||
}
|
||||
else {
|
||||
operation_node->evaluate(depsgraph);
|
||||
|
|
|
@ -91,42 +91,14 @@ class Context : public realtime_compositor::Context {
|
|||
return int2(float2(DRW_viewport_size_get()));
|
||||
}
|
||||
|
||||
/* Returns true if the viewport is in camera view and has an opaque passepartout, that is, the
|
||||
* area outside of the camera border is not visible. */
|
||||
bool is_opaque_camera_view() const
|
||||
{
|
||||
/* Check if the viewport is in camera view. */
|
||||
if (DRW_context_state_get()->rv3d->persp != RV3D_CAMOB) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check if the camera object that is currently in view is an actual camera. It is possible for
|
||||
* a non camera object to be used as a camera, in which case, there will be no passepartout or
|
||||
* any other camera setting, so those pseudo cameras can be ignored. */
|
||||
Object *camera_object = DRW_context_state_get()->v3d->camera;
|
||||
if (camera_object->type != OB_CAMERA) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check if the camera has passepartout active and is totally opaque. */
|
||||
Camera *cam = static_cast<Camera *>(camera_object->data);
|
||||
if (!(cam->flag & CAM_SHOWPASSEPARTOUT) || cam->passepartalpha != 1.0f) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* We limit the compositing region to the camera region if in camera view, while we use the
|
||||
* entire viewport otherwise. */
|
||||
rcti get_compositing_region() const override
|
||||
{
|
||||
const int2 viewport_size = int2(float2(DRW_viewport_size_get()));
|
||||
const rcti render_region = rcti{0, viewport_size.x, 0, viewport_size.y};
|
||||
|
||||
/* If the camera view is not opaque, that means the content outside of the camera region is
|
||||
* visible to some extent, so it would make sense to include them in the compositing region.
|
||||
* Otherwise, we limit the compositing region to the visible camera region because anything
|
||||
* outside of the camera region will not be visible anyways. */
|
||||
if (!is_opaque_camera_view()) {
|
||||
if (DRW_context_state_get()->rv3d->persp != RV3D_CAMOB) {
|
||||
return render_region;
|
||||
}
|
||||
|
||||
|
|
|
@ -1453,7 +1453,7 @@ void EEVEE_lightbake_job(void *custom_data, wmJobWorkerStatus *worker_status)
|
|||
* because this step is locking at this moment. */
|
||||
/* TODO: remove this. */
|
||||
if (lbake->delay) {
|
||||
BLI_sleep_ms(lbake->delay);
|
||||
BLI_time_sleep_ms(lbake->delay);
|
||||
}
|
||||
|
||||
/* Render world irradiance and reflection first */
|
||||
|
|
|
@ -142,7 +142,7 @@ class LightBake {
|
|||
DEG_evaluate_on_framechange(depsgraph_, frame_);
|
||||
|
||||
if (delay_ms_ > 0) {
|
||||
BLI_sleep_ms(delay_ms_);
|
||||
BLI_time_sleep_ms(delay_ms_);
|
||||
}
|
||||
|
||||
context_enable();
|
||||
|
|
|
@ -25,7 +25,7 @@ void OVERLAY_mode_transfer_cache_init(OVERLAY_Data *vedata)
|
|||
OVERLAY_PassList *psl = vedata->psl;
|
||||
OVERLAY_PrivateData *pd = vedata->stl->pd;
|
||||
|
||||
pd->mode_transfer.time = BLI_check_seconds_timer();
|
||||
pd->mode_transfer.time = BLI_time_now_seconds();
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
/* Non Meshes Pass (Camera, empties, lights ...) */
|
||||
|
|
|
@ -692,7 +692,7 @@ void mesh_buffer_cache_create_requested(TaskGraph *task_graph,
|
|||
}
|
||||
|
||||
#ifdef DEBUG_TIME
|
||||
double rdata_start = BLI_check_seconds_timer();
|
||||
double rdata_start = BLI_time_now_seconds();
|
||||
#endif
|
||||
|
||||
MeshRenderData *mr = mesh_render_data_create(
|
||||
|
@ -703,7 +703,7 @@ void mesh_buffer_cache_create_requested(TaskGraph *task_graph,
|
|||
mr->use_simplify_normals = (scene->r.mode & R_SIMPLIFY) && (scene->r.mode & R_SIMPLIFY_NORMALS);
|
||||
|
||||
#ifdef DEBUG_TIME
|
||||
double rdata_end = BLI_check_seconds_timer();
|
||||
double rdata_end = BLI_time_now_seconds();
|
||||
#endif
|
||||
|
||||
eMRIterType iter_type = extractors.iter_types();
|
||||
|
@ -757,7 +757,7 @@ void mesh_buffer_cache_create_requested(TaskGraph *task_graph,
|
|||
|
||||
#ifdef DEBUG_TIME
|
||||
BLI_task_graph_work_and_wait(task_graph);
|
||||
double end = BLI_check_seconds_timer();
|
||||
double end = BLI_time_now_seconds();
|
||||
|
||||
static double avg = 0;
|
||||
static double avg_fps = 0;
|
||||
|
|
|
@ -2323,7 +2323,7 @@ void DRW_create_subdivision(Object *ob,
|
|||
#undef TIME_SUBDIV
|
||||
|
||||
#ifdef TIME_SUBDIV
|
||||
const double begin_time = BLI_check_seconds_timer();
|
||||
const double begin_time = BLI_time_now_seconds();
|
||||
#endif
|
||||
|
||||
if (!draw_subdiv_create_requested_buffers(ob,
|
||||
|
@ -2345,7 +2345,7 @@ void DRW_create_subdivision(Object *ob,
|
|||
}
|
||||
|
||||
#ifdef TIME_SUBDIV
|
||||
const double end_time = BLI_check_seconds_timer();
|
||||
const double end_time = BLI_time_now_seconds();
|
||||
fprintf(stderr, "Time to update subdivision: %f\n", end_time - begin_time);
|
||||
fprintf(stderr, "Maximum FPS: %f\n", 1.0 / (end_time - begin_time));
|
||||
#endif
|
||||
|
|
|
@ -58,19 +58,19 @@ struct CurvesUniformBufPool;
|
|||
# define PROFILE_TIMER_FALLOFF 0.04
|
||||
|
||||
# define PROFILE_START(time_start) \
|
||||
double time_start = BLI_check_seconds_timer(); \
|
||||
double time_start = BLI_time_now_seconds(); \
|
||||
((void)0)
|
||||
|
||||
# define PROFILE_END_ACCUM(time_accum, time_start) \
|
||||
{ \
|
||||
time_accum += (BLI_check_seconds_timer() - time_start) * 1e3; \
|
||||
time_accum += (BLI_time_now_seconds() - time_start) * 1e3; \
|
||||
} \
|
||||
((void)0)
|
||||
|
||||
/* exp average */
|
||||
# define PROFILE_END_UPDATE(time_update, time_start) \
|
||||
{ \
|
||||
double _time_delta = (BLI_check_seconds_timer() - time_start) * 1e3; \
|
||||
double _time_delta = (BLI_time_now_seconds() - time_start) * 1e3; \
|
||||
time_update = (time_update * (1.0 - PROFILE_TIMER_FALLOFF)) + \
|
||||
(_time_delta * PROFILE_TIMER_FALLOFF); \
|
||||
} \
|
||||
|
|
|
@ -976,7 +976,7 @@ void DRW_cache_free_old_batches(Main *bmain)
|
|||
using namespace blender::draw;
|
||||
Scene *scene;
|
||||
static int lasttime = 0;
|
||||
int ctime = int(BLI_check_seconds_timer());
|
||||
int ctime = int(BLI_time_now_seconds());
|
||||
|
||||
if (U.vbotimeout == 0 || (ctime - lasttime) < U.vbocollectrate || ctime == lasttime) {
|
||||
return;
|
||||
|
|
|
@ -270,7 +270,7 @@ static void drw_deferred_shader_add(GPUMaterial *mat, bool deferred)
|
|||
DRW_deferred_shader_remove(mat);
|
||||
/* Shaders could already be compiling. Have to wait for compilation to finish. */
|
||||
while (GPU_material_status(mat) == GPU_MAT_QUEUED) {
|
||||
BLI_sleep_ms(20);
|
||||
BLI_time_sleep_ms(20);
|
||||
}
|
||||
if (GPU_material_status(mat) == GPU_MAT_CREATED) {
|
||||
GPU_material_compile(mat);
|
||||
|
@ -568,7 +568,7 @@ void DRW_shader_queue_optimize_material(GPUMaterial *mat)
|
|||
DRW_deferred_shader_optimize_remove(mat);
|
||||
/* If optimization job had already started, wait for it to complete. */
|
||||
while (GPU_material_optimization_status(mat) == GPU_MAT_OPTIMIZATION_QUEUED) {
|
||||
BLI_sleep_ms(20);
|
||||
BLI_time_sleep_ms(20);
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
|
|
@ -4477,36 +4477,33 @@ static void ANIM_OT_channels_bake(wmOperatorType *ot)
|
|||
"Bake Modifiers into keyframes and delete them after");
|
||||
}
|
||||
|
||||
/* Find a Graph Editor area and modify the given context to be the window region of it. */
|
||||
static bool move_context_to_graph_editor(bContext *C)
|
||||
/**
|
||||
* Find a Graph Editor area and set the context arguments accordingly.
|
||||
*/
|
||||
static bool context_find_graph_editor(bContext *C,
|
||||
wmWindow **r_win,
|
||||
ScrArea **r_area,
|
||||
ARegion **r_region)
|
||||
{
|
||||
bool found_graph_editor = false;
|
||||
LISTBASE_FOREACH (wmWindow *, win, &CTX_wm_manager(C)->windows) {
|
||||
bScreen *screen = BKE_workspace_active_screen_get(win->workspace_hook);
|
||||
bScreen *screen = WM_window_get_active_screen(win);
|
||||
|
||||
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
|
||||
if (area->spacetype != SPACE_GRAPH) {
|
||||
continue;
|
||||
}
|
||||
ARegion *window_region = BKE_area_find_region_type(area, RGN_TYPE_WINDOW);
|
||||
|
||||
if (!window_region) {
|
||||
ARegion *region = BKE_area_find_region_type(area, RGN_TYPE_WINDOW);
|
||||
if (!region) {
|
||||
continue;
|
||||
}
|
||||
|
||||
CTX_wm_window_set(C, win);
|
||||
CTX_wm_screen_set(C, screen);
|
||||
CTX_wm_area_set(C, area);
|
||||
CTX_wm_region_set(C, window_region);
|
||||
found_graph_editor = true;
|
||||
break;
|
||||
}
|
||||
|
||||
if (found_graph_editor) {
|
||||
break;
|
||||
*r_win = win;
|
||||
*r_area = area;
|
||||
*r_region = region;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return found_graph_editor;
|
||||
return false;
|
||||
}
|
||||
|
||||
static void deselect_all_fcurves(bAnimContext *ac, const bool hide)
|
||||
|
@ -4628,8 +4625,16 @@ static int view_curve_in_graph_editor_exec(bContext *C, wmOperator *op)
|
|||
return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
|
||||
}
|
||||
|
||||
int retval = OPERATOR_FINISHED;
|
||||
|
||||
ListBase selection = {nullptr, nullptr};
|
||||
|
||||
struct {
|
||||
wmWindow *win;
|
||||
ScrArea *area;
|
||||
ARegion *region;
|
||||
} wm_context_prev = {nullptr}, wm_context_temp = {nullptr};
|
||||
|
||||
bool path_from_id;
|
||||
std::optional<std::string> id_to_prop_path;
|
||||
const bool selected_list_success = UI_context_copy_to_selected_list(
|
||||
|
@ -4637,49 +4642,63 @@ static int view_curve_in_graph_editor_exec(bContext *C, wmOperator *op)
|
|||
|
||||
if (BLI_listbase_is_empty(&selection) || !selected_list_success) {
|
||||
WM_report(RPT_ERROR, "Nothing selected");
|
||||
BLI_freelistN(&selection);
|
||||
return OPERATOR_CANCELLED;
|
||||
retval = OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
const bool found_graph_editor = move_context_to_graph_editor(C);
|
||||
|
||||
if (!found_graph_editor) {
|
||||
else if (!context_find_graph_editor(
|
||||
C, &wm_context_temp.win, &wm_context_temp.area, &wm_context_temp.region))
|
||||
{
|
||||
WM_report(RPT_WARNING, "No open Graph Editor window found");
|
||||
return OPERATOR_CANCELLED;
|
||||
retval = OPERATOR_CANCELLED;
|
||||
}
|
||||
else {
|
||||
wm_context_prev.win = CTX_wm_window(C);
|
||||
wm_context_prev.area = CTX_wm_area(C);
|
||||
wm_context_prev.region = CTX_wm_region(C);
|
||||
|
||||
bAnimContext ac;
|
||||
if (!ANIM_animdata_get_context(C, &ac)) {
|
||||
/* This might never be called since we are manually setting the Graph Editor just before. */
|
||||
WM_report(RPT_ERROR, "Cannot create the Animation Context");
|
||||
return OPERATOR_CANCELLED;
|
||||
CTX_wm_window_set(C, wm_context_temp.win);
|
||||
CTX_wm_area_set(C, wm_context_temp.area);
|
||||
CTX_wm_region_set(C, wm_context_temp.region);
|
||||
|
||||
bAnimContext ac;
|
||||
if (!ANIM_animdata_get_context(C, &ac)) {
|
||||
/* This might never be called since we are manually setting the Graph Editor just before. */
|
||||
WM_report(RPT_ERROR, "Cannot create the Animation Context");
|
||||
retval = OPERATOR_CANCELLED;
|
||||
}
|
||||
else {
|
||||
const bool isolate = RNA_boolean_get(op->ptr, "isolate");
|
||||
deselect_all_fcurves(&ac, isolate);
|
||||
|
||||
const bool whole_array = RNA_boolean_get(op->ptr, "all");
|
||||
|
||||
rctf bounds = calculate_selection_fcurve_bounds_and_unhide(
|
||||
C, &selection, prop, id_to_prop_path.value_or(""), index, whole_array);
|
||||
|
||||
if (!BLI_rctf_is_valid(&bounds)) {
|
||||
WM_report(RPT_ERROR, "F-Curves have no valid size");
|
||||
retval = OPERATOR_CANCELLED;
|
||||
}
|
||||
else {
|
||||
ARegion *region = wm_context_temp.region;
|
||||
ScrArea *area = wm_context_temp.area;
|
||||
add_region_padding(C, region, &bounds);
|
||||
|
||||
const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
|
||||
UI_view2d_smooth_view(C, region, &bounds, smooth_viewtx);
|
||||
|
||||
/* This ensures the channel list updates. */
|
||||
ED_area_tag_redraw(area);
|
||||
}
|
||||
}
|
||||
|
||||
CTX_wm_window_set(C, wm_context_prev.win);
|
||||
CTX_wm_area_set(C, wm_context_prev.area);
|
||||
CTX_wm_region_set(C, wm_context_prev.region);
|
||||
}
|
||||
|
||||
const bool isolate = RNA_boolean_get(op->ptr, "isolate");
|
||||
deselect_all_fcurves(&ac, isolate);
|
||||
|
||||
const bool whole_array = RNA_boolean_get(op->ptr, "all");
|
||||
|
||||
rctf bounds = calculate_selection_fcurve_bounds_and_unhide(
|
||||
C, &selection, prop, id_to_prop_path.value_or(""), index, whole_array);
|
||||
|
||||
BLI_freelistN(&selection);
|
||||
|
||||
if (!BLI_rctf_is_valid(&bounds)) {
|
||||
WM_report(RPT_ERROR, "F-Curves have no valid size");
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
ARegion *region = CTX_wm_region(C);
|
||||
add_region_padding(C, region, &bounds);
|
||||
|
||||
const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
|
||||
UI_view2d_smooth_view(C, region, &bounds, smooth_viewtx);
|
||||
|
||||
/* This ensures the channel list updates. */
|
||||
ED_area_tag_redraw(CTX_wm_area(C));
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
return retval;
|
||||
}
|
||||
|
||||
static void ANIM_OT_view_curve_in_graph_editor(wmOperatorType *ot)
|
||||
|
|
|
@ -2146,7 +2146,7 @@ static void annotation_draw_apply_event(
|
|||
}
|
||||
}
|
||||
|
||||
p->curtime = BLI_check_seconds_timer();
|
||||
p->curtime = BLI_time_now_seconds();
|
||||
|
||||
/* handle pressure sensitivity (which is supplied by tablets or otherwise 1.0) */
|
||||
p->pressure = event->tablet.pressure;
|
||||
|
|
|
@ -2159,7 +2159,7 @@ static tGPsdata *gpencil_session_initpaint(bContext *C, wmOperator *op)
|
|||
}
|
||||
|
||||
/* Random generator, only init once. */
|
||||
uint rng_seed = uint(BLI_check_seconds_timer_i() & UINT_MAX);
|
||||
uint rng_seed = uint(BLI_time_now_seconds_i() & UINT_MAX);
|
||||
rng_seed ^= POINTER_AS_UINT(p);
|
||||
p->rng = BLI_rng_new(rng_seed);
|
||||
|
||||
|
@ -2961,7 +2961,7 @@ static void gpencil_draw_apply_event(bContext *C,
|
|||
}
|
||||
}
|
||||
|
||||
p->curtime = BLI_check_seconds_timer();
|
||||
p->curtime = BLI_time_now_seconds();
|
||||
|
||||
/* handle pressure sensitivity (which is supplied by tablets or otherwise 1.0) */
|
||||
p->pressure = event->tablet.pressure;
|
||||
|
|
|
@ -363,7 +363,7 @@ static void gpencil_primitive_set_initdata(bContext *C, tGPDprimitive *tgpi)
|
|||
gpencil_primitive_allocate_memory(tgpi);
|
||||
|
||||
/* Random generator, only init once. */
|
||||
uint rng_seed = uint(BLI_check_seconds_timer_i() & UINT_MAX);
|
||||
uint rng_seed = uint(BLI_time_now_seconds_i() & UINT_MAX);
|
||||
tgpi->rng = BLI_rng_new(rng_seed);
|
||||
|
||||
DEG_id_tag_update(&tgpi->gpd->id, ID_RECALC_COPY_ON_WRITE);
|
||||
|
|
|
@ -1165,7 +1165,7 @@ static bool gpencil_sculpt_brush_init(bContext *C, wmOperator *op)
|
|||
gso->settings = gpencil_sculpt_get_settings(scene);
|
||||
|
||||
/* Random generator, only init once. */
|
||||
uint rng_seed = uint(BLI_check_seconds_timer_i() & UINT_MAX);
|
||||
uint rng_seed = uint(BLI_time_now_seconds_i() & UINT_MAX);
|
||||
rng_seed ^= POINTER_AS_UINT(gso);
|
||||
gso->rng = BLI_rng_new(rng_seed);
|
||||
|
||||
|
|
|
@ -2838,7 +2838,7 @@ void ED_gpencil_init_random_settings(Brush *brush,
|
|||
const int mval[2],
|
||||
GpRandomSettings *random_settings)
|
||||
{
|
||||
int seed = (uint(ceil(BLI_check_seconds_timer())) + 1) % 128;
|
||||
int seed = (uint(ceil(BLI_time_now_seconds())) + 1) % 128;
|
||||
/* Use mouse position to get randomness. */
|
||||
int ix = mval[0] * seed;
|
||||
int iy = mval[1] * seed;
|
||||
|
@ -2884,7 +2884,7 @@ static void gpencil_sbuffer_vertex_color_random(
|
|||
{
|
||||
BrushGpencilSettings *brush_settings = brush->gpencil_settings;
|
||||
if (brush_settings->flag & GP_BRUSH_GROUP_RANDOM) {
|
||||
int seed = (uint(ceil(BLI_check_seconds_timer())) + 1) % 128;
|
||||
int seed = (uint(ceil(BLI_time_now_seconds())) + 1) % 128;
|
||||
|
||||
int ix = int(tpt->m_xy[0] * seed);
|
||||
int iy = int(tpt->m_xy[1] * seed);
|
||||
|
|
|
@ -29,6 +29,7 @@ set(SRC
|
|||
intern/grease_pencil_material.cc
|
||||
intern/grease_pencil_ops.cc
|
||||
intern/grease_pencil_select.cc
|
||||
intern/grease_pencil_undo.cc
|
||||
intern/grease_pencil_utils.cc
|
||||
)
|
||||
|
||||
|
@ -38,6 +39,7 @@ set(LIB
|
|||
PRIVATE bf::depsgraph
|
||||
PRIVATE bf::dna
|
||||
PRIVATE bf::intern::guardedalloc
|
||||
PRIVATE bf::intern::clog
|
||||
extern_curve_fit_nd
|
||||
)
|
||||
|
||||
|
|
|
@ -428,6 +428,47 @@ static void GREASE_PENCIL_OT_layer_isolate(wmOperatorType *ot)
|
|||
RNA_def_boolean(
|
||||
ot->srna, "affect_visibility", false, "Affect Visibility", "Also affect the visibility");
|
||||
}
|
||||
|
||||
static int grease_pencil_layer_lock_all_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
using namespace blender::bke::greasepencil;
|
||||
Object *object = CTX_data_active_object(C);
|
||||
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(object->data);
|
||||
const bool lock_value = RNA_boolean_get(op->ptr, "lock");
|
||||
|
||||
if (grease_pencil.layers().is_empty()) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
for (Layer *layer : grease_pencil.layers_for_write()) {
|
||||
layer->set_locked(lock_value);
|
||||
}
|
||||
|
||||
DEG_id_tag_update(&grease_pencil.id, ID_RECALC_GEOMETRY);
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_DATA, &grease_pencil);
|
||||
WM_event_add_notifier(C, NC_GPENCIL | NA_EDITED, nullptr);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static void GREASE_PENCIL_OT_layer_lock_all(wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name = "Lock All Layers";
|
||||
ot->idname = "GREASE_PENCIL_OT_layer_lock_all";
|
||||
ot->description =
|
||||
"Lock all Grease Pencil layers to prevent them from being accidentally modified";
|
||||
|
||||
/* callbacks */
|
||||
ot->exec = grease_pencil_layer_lock_all_exec;
|
||||
ot->poll = active_grease_pencil_poll;
|
||||
|
||||
/* flags */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
/* properties */
|
||||
RNA_def_boolean(ot->srna, "lock", true, "Lock Value", "Lock/Unlock all layers");
|
||||
}
|
||||
} // namespace blender::ed::greasepencil
|
||||
|
||||
void ED_operatortypes_grease_pencil_layers()
|
||||
|
@ -440,6 +481,7 @@ void ED_operatortypes_grease_pencil_layers()
|
|||
WM_operatortype_append(GREASE_PENCIL_OT_layer_hide);
|
||||
WM_operatortype_append(GREASE_PENCIL_OT_layer_reveal);
|
||||
WM_operatortype_append(GREASE_PENCIL_OT_layer_isolate);
|
||||
WM_operatortype_append(GREASE_PENCIL_OT_layer_lock_all);
|
||||
|
||||
WM_operatortype_append(GREASE_PENCIL_OT_layer_group_add);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,424 @@
|
|||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
/** \file
|
||||
* \ingroup edgrease_pencil
|
||||
*/
|
||||
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_task.hh"
|
||||
|
||||
#include "BKE_context.hh"
|
||||
#include "BKE_curves.hh"
|
||||
#include "BKE_customdata.hh"
|
||||
#include "BKE_grease_pencil.hh"
|
||||
#include "BKE_lib_id.hh"
|
||||
#include "BKE_main.hh"
|
||||
#include "BKE_object.hh"
|
||||
#include "BKE_undo_system.hh"
|
||||
|
||||
#include "CLG_log.h"
|
||||
|
||||
#include "DEG_depsgraph.hh"
|
||||
#include "DEG_depsgraph_build.hh"
|
||||
|
||||
#include "ED_grease_pencil.hh"
|
||||
#include "ED_undo.hh"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "WM_api.hh"
|
||||
#include "WM_types.hh"
|
||||
|
||||
#include <iostream>
|
||||
#include <ostream>
|
||||
|
||||
static CLG_LogRef LOG = {"ed.undo.greasepencil"};
|
||||
|
||||
namespace blender::ed::greasepencil::undo {
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Implements ED Undo System
|
||||
*
|
||||
* \note This is similar for all edit-mode types.
|
||||
* \{ */
|
||||
|
||||
/**
|
||||
* Store all drawings, layers and layers data, in each undo step.
|
||||
*
|
||||
* Each drawing type has its own array in the undo #StepObject data.
|
||||
*
|
||||
* NOTE: Storing Reference drawings is also needed, since drawings can be added or removed, data
|
||||
* from Reference ones also needs to be stored.
|
||||
*/
|
||||
|
||||
/* Store contextual data and status info during undo step encoding or decoding. */
|
||||
struct StepEncodeStatus {};
|
||||
|
||||
struct StepDecodeStatus {
|
||||
/**
|
||||
* In case some reference drawing needs to be re-created, the GreasePencil ID gets a new
|
||||
* relation to another GreasePencil ID.
|
||||
*/
|
||||
bool needs_relationships_update = false;
|
||||
};
|
||||
|
||||
class StepDrawingGeometryBase {
|
||||
protected:
|
||||
/* Index of this drawing in the original combined array of all drawings in GreasePencil ID. */
|
||||
int index_;
|
||||
|
||||
/* Data from #GreasePencilDrawingBase that needs to be saved in udo steps. */
|
||||
uint32_t flag_;
|
||||
|
||||
protected:
|
||||
/* Ensures that the drawing from the given array at the current index exists, and has the propoer
|
||||
* type.
|
||||
*
|
||||
* Non-existing drawings can happen after extenting the drawings array.
|
||||
*
|
||||
* Mismatch in drawing types can happen when some drawings have been deleted between the undo
|
||||
* step storage, and the current state of the GreasePencil data. */
|
||||
void decode_valid_drawingtype_at_index_ensure(MutableSpan<GreasePencilDrawingBase *> &drawings,
|
||||
const GreasePencilDrawingType drawing_type) const
|
||||
{
|
||||
/* TODO: Maybe that code should rather be part of GreasePencil:: API, together with
|
||||
* `add_empty_drawings` and such? */
|
||||
GreasePencilDrawingBase *drawing = drawings[index_];
|
||||
if (drawing != nullptr) {
|
||||
if (drawing->type == drawing_type) {
|
||||
return;
|
||||
}
|
||||
switch (drawing->type) {
|
||||
case GP_DRAWING:
|
||||
MEM_delete(&reinterpret_cast<GreasePencilDrawing *>(drawing)->wrap());
|
||||
break;
|
||||
case GP_DRAWING_REFERENCE:
|
||||
MEM_delete(&reinterpret_cast<GreasePencilDrawingReference *>(drawing)->wrap());
|
||||
break;
|
||||
}
|
||||
drawing = nullptr;
|
||||
}
|
||||
if (drawing == nullptr) {
|
||||
switch (drawing_type) {
|
||||
case GP_DRAWING:
|
||||
drawings[index_] = reinterpret_cast<GreasePencilDrawingBase *>(
|
||||
MEM_new<bke::greasepencil::Drawing>(__func__));
|
||||
break;
|
||||
case GP_DRAWING_REFERENCE:
|
||||
drawings[index_] = reinterpret_cast<GreasePencilDrawingBase *>(
|
||||
MEM_new<bke::greasepencil::DrawingReference>(__func__));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class StepDrawingGeometry : public StepDrawingGeometryBase {
|
||||
bke::CurvesGeometry geometry_;
|
||||
|
||||
public:
|
||||
void encode(const GreasePencilDrawing &drawing_geometry,
|
||||
const int64_t drawing_index,
|
||||
StepEncodeStatus & /* encode_status */)
|
||||
{
|
||||
BLI_assert(drawing_index >= 0 && drawing_index < INT32_MAX);
|
||||
index_ = int(drawing_index);
|
||||
|
||||
flag_ = drawing_geometry.base.flag;
|
||||
geometry_ = drawing_geometry.geometry.wrap();
|
||||
}
|
||||
|
||||
void decode(GreasePencil &grease_pencil, StepDecodeStatus & /*decode_status*/) const
|
||||
{
|
||||
MutableSpan<GreasePencilDrawingBase *> drawings = grease_pencil.drawings();
|
||||
this->decode_valid_drawingtype_at_index_ensure(drawings, GP_DRAWING);
|
||||
BLI_assert(drawings[index_]->type == GP_DRAWING);
|
||||
|
||||
GreasePencilDrawing &drawing_geometry = *reinterpret_cast<GreasePencilDrawing *>(
|
||||
drawings[index_]);
|
||||
|
||||
drawing_geometry.base.flag = flag_;
|
||||
drawing_geometry.geometry.wrap() = geometry_;
|
||||
|
||||
/* TODO: Check if there is a way to tell if both stored and current geometry are still the
|
||||
* same, to avoid recomputing the cache all the time for all drawings? */
|
||||
drawing_geometry.runtime->triangles_cache.tag_dirty();
|
||||
}
|
||||
};
|
||||
|
||||
class StepDrawingReference : public StepDrawingGeometryBase {
|
||||
UndoRefID_GreasePencil grease_pencil_ref_ = {};
|
||||
|
||||
public:
|
||||
void encode(const GreasePencilDrawingReference &drawing_reference,
|
||||
const int64_t drawing_index,
|
||||
StepEncodeStatus & /* encode_status */)
|
||||
{
|
||||
BLI_assert(drawing_index >= 0 && drawing_index < INT32_MAX);
|
||||
index_ = int(drawing_index);
|
||||
|
||||
flag_ = drawing_reference.base.flag;
|
||||
grease_pencil_ref_.ptr = drawing_reference.id_reference;
|
||||
}
|
||||
|
||||
void decode(GreasePencil &grease_pencil, StepDecodeStatus &decode_status) const
|
||||
{
|
||||
MutableSpan<GreasePencilDrawingBase *> drawings = grease_pencil.drawings();
|
||||
this->decode_valid_drawingtype_at_index_ensure(drawings, GP_DRAWING_REFERENCE);
|
||||
BLI_assert(drawings[index_]->type == GP_DRAWING_REFERENCE);
|
||||
|
||||
GreasePencilDrawingReference &drawing_reference =
|
||||
*reinterpret_cast<GreasePencilDrawingReference *>(drawings[index_]);
|
||||
drawing_reference.base.flag = flag_;
|
||||
|
||||
if (drawing_reference.id_reference != grease_pencil_ref_.ptr) {
|
||||
id_us_min(reinterpret_cast<ID *>(drawing_reference.id_reference));
|
||||
drawing_reference.id_reference = grease_pencil_ref_.ptr;
|
||||
id_us_plus(reinterpret_cast<ID *>(drawing_reference.id_reference));
|
||||
decode_status.needs_relationships_update = true;
|
||||
}
|
||||
}
|
||||
|
||||
void foreach_id_ref(UndoTypeForEachIDRefFn foreach_ID_ref_fn, void *user_data)
|
||||
{
|
||||
foreach_ID_ref_fn(user_data, reinterpret_cast<UndoRefID *>(&grease_pencil_ref_));
|
||||
}
|
||||
};
|
||||
|
||||
class StepObject {
|
||||
public:
|
||||
UndoRefID_Object obedit_ref = {};
|
||||
|
||||
private:
|
||||
Array<StepDrawingGeometry> drawings_geometry_;
|
||||
Array<StepDrawingReference> drawings_reference_;
|
||||
|
||||
int layers_num_ = 0;
|
||||
bke::greasepencil::LayerGroup root_group_;
|
||||
std::string active_layer_name_;
|
||||
CustomData layers_data_ = {};
|
||||
|
||||
private:
|
||||
void encode_drawings(const GreasePencil &grease_pencil, StepEncodeStatus &encode_status)
|
||||
{
|
||||
const Span<const GreasePencilDrawingBase *> drawings = grease_pencil.drawings();
|
||||
|
||||
int64_t drawings_geometry_num = 0;
|
||||
int64_t drawings_reference_num = 0;
|
||||
for (const int64_t idx : drawings.index_range()) {
|
||||
const GreasePencilDrawingBase &drawing = *drawings[idx];
|
||||
switch (drawing.type) {
|
||||
case GP_DRAWING:
|
||||
drawings_geometry_num++;
|
||||
break;
|
||||
case GP_DRAWING_REFERENCE:
|
||||
drawings_reference_num++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
drawings_geometry_.reinitialize(drawings_geometry_num);
|
||||
drawings_reference_.reinitialize(drawings_reference_num);
|
||||
|
||||
int drawings_geometry_idx = 0;
|
||||
int drawings_reference_idx = 0;
|
||||
for (const int64_t idx : drawings.index_range()) {
|
||||
const GreasePencilDrawingBase &drawing = *drawings[idx];
|
||||
switch (drawing.type) {
|
||||
case GP_DRAWING:
|
||||
drawings_geometry_[drawings_geometry_idx++].encode(
|
||||
reinterpret_cast<const GreasePencilDrawing &>(drawing), idx, encode_status);
|
||||
break;
|
||||
case GP_DRAWING_REFERENCE:
|
||||
drawings_reference_[drawings_reference_idx++].encode(
|
||||
reinterpret_cast<const GreasePencilDrawingReference &>(drawing), idx, encode_status);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void decode_drawings(GreasePencil &grease_pencil, StepDecodeStatus &decode_status) const
|
||||
{
|
||||
const int drawing_array_num = int(drawings_geometry_.size() + drawings_reference_.size());
|
||||
grease_pencil.resize_drawings(drawing_array_num);
|
||||
|
||||
for (const StepDrawingGeometry &drawing : drawings_geometry_) {
|
||||
drawing.decode(grease_pencil, decode_status);
|
||||
}
|
||||
for (const StepDrawingReference &drawing : drawings_reference_) {
|
||||
drawing.decode(grease_pencil, decode_status);
|
||||
}
|
||||
}
|
||||
|
||||
void encode_layers(const GreasePencil &grease_pencil, StepEncodeStatus & /*encode_status*/)
|
||||
{
|
||||
layers_num_ = int(grease_pencil.layers().size());
|
||||
|
||||
CustomData_copy(
|
||||
&grease_pencil.layers_data, &layers_data_, eCustomDataMask(CD_MASK_ALL), layers_num_);
|
||||
|
||||
if (grease_pencil.has_active_layer()) {
|
||||
active_layer_name_ = grease_pencil.get_active_layer()->name();
|
||||
}
|
||||
|
||||
root_group_ = grease_pencil.root_group();
|
||||
}
|
||||
|
||||
void decode_layers(GreasePencil &grease_pencil, StepDecodeStatus & /*decode_status*/) const
|
||||
{
|
||||
if (grease_pencil.root_group_ptr) {
|
||||
MEM_delete(&grease_pencil.root_group());
|
||||
}
|
||||
|
||||
grease_pencil.root_group_ptr = MEM_new<bke::greasepencil::LayerGroup>(__func__, root_group_);
|
||||
BLI_assert(layers_num_ == grease_pencil.layers().size());
|
||||
|
||||
if (!active_layer_name_.empty()) {
|
||||
const bke::greasepencil::TreeNode *active_node =
|
||||
grease_pencil.root_group().find_node_by_name(active_layer_name_);
|
||||
if (active_node && active_node->is_layer()) {
|
||||
grease_pencil.set_active_layer(&active_node->as_layer());
|
||||
}
|
||||
}
|
||||
|
||||
CustomData_copy(
|
||||
&layers_data_, &grease_pencil.layers_data, eCustomDataMask(CD_MASK_ALL), layers_num_);
|
||||
}
|
||||
|
||||
public:
|
||||
void encode(Object *ob, StepEncodeStatus &encode_status)
|
||||
{
|
||||
const GreasePencil &grease_pencil = *static_cast<GreasePencil *>(ob->data);
|
||||
this->obedit_ref.ptr = ob;
|
||||
|
||||
this->encode_drawings(grease_pencil, encode_status);
|
||||
this->encode_layers(grease_pencil, encode_status);
|
||||
}
|
||||
|
||||
void decode(StepDecodeStatus &decode_status) const
|
||||
{
|
||||
GreasePencil &grease_pencil = *static_cast<GreasePencil *>(this->obedit_ref.ptr->data);
|
||||
|
||||
this->decode_drawings(grease_pencil, decode_status);
|
||||
this->decode_layers(grease_pencil, decode_status);
|
||||
|
||||
DEG_id_tag_update(&grease_pencil.id, ID_RECALC_GEOMETRY);
|
||||
}
|
||||
|
||||
void foreach_id_ref(UndoTypeForEachIDRefFn foreach_ID_ref_fn, void *user_data)
|
||||
{
|
||||
foreach_ID_ref_fn(user_data, reinterpret_cast<UndoRefID *>(&this->obedit_ref));
|
||||
for (StepDrawingReference &drawing_ref : drawings_reference_) {
|
||||
drawing_ref.foreach_id_ref(foreach_ID_ref_fn, user_data);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct GreasePencilUndoStep {
|
||||
UndoStep step;
|
||||
/** See #ED_undo_object_editmode_validate_scene_from_windows code comment for details. */
|
||||
UndoRefID_Scene scene_ref = {};
|
||||
Array<StepObject> objects;
|
||||
};
|
||||
|
||||
static bool step_encode(bContext *C, Main *bmain, UndoStep *us_p)
|
||||
{
|
||||
GreasePencilUndoStep *us = reinterpret_cast<GreasePencilUndoStep *>(us_p);
|
||||
StepEncodeStatus encode_status;
|
||||
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
uint objects_num = 0;
|
||||
Object **objects = ED_undo_editmode_objects_from_view_layer(scene, view_layer, &objects_num);
|
||||
BLI_SCOPED_DEFER([&]() { MEM_SAFE_FREE(objects); })
|
||||
|
||||
us->scene_ref.ptr = scene;
|
||||
new (&us->objects) Array<StepObject>(objects_num);
|
||||
|
||||
threading::parallel_for(us->objects.index_range(), 8, [&](const IndexRange range) {
|
||||
for (const int64_t i : range) {
|
||||
Object *ob = objects[i];
|
||||
us->objects[i].encode(ob, encode_status);
|
||||
}
|
||||
});
|
||||
|
||||
bmain->is_memfile_undo_flush_needed = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void step_decode(
|
||||
bContext *C, Main *bmain, UndoStep *us_p, const eUndoStepDir /*dir*/, bool /*is_final*/)
|
||||
{
|
||||
GreasePencilUndoStep *us = reinterpret_cast<GreasePencilUndoStep *>(us_p);
|
||||
StepDecodeStatus decode_status;
|
||||
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
ViewLayer *view_layer = CTX_data_view_layer(C);
|
||||
|
||||
ED_undo_object_editmode_validate_scene_from_windows(
|
||||
CTX_wm_manager(C), us->scene_ref.ptr, &scene, &view_layer);
|
||||
ED_undo_object_editmode_restore_helper(scene,
|
||||
view_layer,
|
||||
&us->objects.first().obedit_ref.ptr,
|
||||
uint(us->objects.size()),
|
||||
sizeof(decltype(us->objects)::value_type));
|
||||
|
||||
BLI_assert(BKE_object_is_in_editmode(us->objects.first().obedit_ref.ptr));
|
||||
|
||||
for (const StepObject &step_object : us->objects) {
|
||||
step_object.decode(decode_status);
|
||||
}
|
||||
|
||||
if (decode_status.needs_relationships_update) {
|
||||
DEG_relations_tag_update(bmain);
|
||||
}
|
||||
|
||||
ED_undo_object_set_active_or_warn(
|
||||
scene, view_layer, us->objects.first().obedit_ref.ptr, us_p->name, &LOG);
|
||||
|
||||
bmain->is_memfile_undo_flush_needed = true;
|
||||
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_DATA, nullptr);
|
||||
}
|
||||
|
||||
static void step_free(UndoStep *us_p)
|
||||
{
|
||||
GreasePencilUndoStep *us = reinterpret_cast<GreasePencilUndoStep *>(us_p);
|
||||
us->objects.~Array();
|
||||
}
|
||||
|
||||
static void foreach_ID_ref(UndoStep *us_p,
|
||||
UndoTypeForEachIDRefFn foreach_ID_ref_fn,
|
||||
void *user_data)
|
||||
{
|
||||
GreasePencilUndoStep *us = reinterpret_cast<GreasePencilUndoStep *>(us_p);
|
||||
|
||||
foreach_ID_ref_fn(user_data, reinterpret_cast<UndoRefID *>(&us->scene_ref));
|
||||
for (StepObject &object : us->objects) {
|
||||
object.foreach_id_ref(foreach_ID_ref_fn, user_data);
|
||||
}
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
} // namespace blender::ed::greasepencil::undo
|
||||
|
||||
void ED_undosys_type_grease_pencil(UndoType *ut)
|
||||
{
|
||||
using namespace blender::ed;
|
||||
|
||||
ut->name = "Edit GreasePencil";
|
||||
ut->poll = greasepencil::editable_grease_pencil_poll;
|
||||
ut->step_encode = greasepencil::undo::step_encode;
|
||||
ut->step_decode = greasepencil::undo::step_decode;
|
||||
ut->step_free = greasepencil::undo::step_free;
|
||||
|
||||
ut->step_foreach_ID_ref = greasepencil::undo::foreach_ID_ref;
|
||||
|
||||
ut->flags = UNDOTYPE_FLAG_NEED_CONTEXT_FOR_ENCODE;
|
||||
|
||||
ut->step_size = sizeof(greasepencil::undo::GreasePencilUndoStep);
|
||||
}
|
|
@ -25,6 +25,7 @@ struct KeyframeEditData;
|
|||
struct wmKeyConfig;
|
||||
struct ToolSettings;
|
||||
struct Scene;
|
||||
struct UndoType;
|
||||
struct ViewDepths;
|
||||
struct View3D;
|
||||
namespace blender {
|
||||
|
@ -51,6 +52,8 @@ void ED_operatortypes_grease_pencil_edit();
|
|||
void ED_operatortypes_grease_pencil_material();
|
||||
void ED_operatormacros_grease_pencil();
|
||||
void ED_keymap_grease_pencil(wmKeyConfig *keyconf);
|
||||
|
||||
void ED_undosys_type_grease_pencil(UndoType *undo_type);
|
||||
/**
|
||||
* Get the selection mode for Grease Pencil selection operators: point, stroke, segment.
|
||||
*/
|
||||
|
|
|
@ -54,7 +54,7 @@ struct SceneFPS_State {
|
|||
/**
|
||||
* Update frame rate info for viewport drawing.
|
||||
* \param ltime: Time since the last update,
|
||||
* compatible with the result of #BLI_check_seconds_timer.
|
||||
* compatible with the result of #BLI_time_now_seconds.
|
||||
*/
|
||||
void ED_scene_fps_average_accumulate(Scene *scene, short fps_samples, double ltime)
|
||||
ATTR_NONNULL(1);
|
||||
|
|
|
@ -4398,7 +4398,7 @@ static void ui_block_open_end(bContext *C, uiBut *but, uiHandleButtonData *data)
|
|||
but->editval = nullptr;
|
||||
but->editvec = nullptr;
|
||||
|
||||
but->block->auto_open_last = BLI_check_seconds_timer();
|
||||
but->block->auto_open_last = BLI_time_now_seconds();
|
||||
}
|
||||
|
||||
if (data->menu) {
|
||||
|
@ -8650,7 +8650,7 @@ static void button_activate_init(bContext *C,
|
|||
* want to allow auto opening adjacent menus even if no button is activated
|
||||
* in between going over to the other button, but only for a short while */
|
||||
if (type == BUTTON_ACTIVATE_OVER && but->block->auto_open == true) {
|
||||
if (but->block->auto_open_last + BUTTON_AUTO_OPEN_THRESH < BLI_check_seconds_timer()) {
|
||||
if (but->block->auto_open_last + BUTTON_AUTO_OPEN_THRESH < BLI_time_now_seconds()) {
|
||||
but->block->auto_open = false;
|
||||
}
|
||||
}
|
||||
|
@ -8696,7 +8696,7 @@ static void button_activate_init(bContext *C,
|
|||
if (UI_but_has_tooltip_label(but)) {
|
||||
/* Show a label for this button. */
|
||||
bScreen *screen = WM_window_get_active_screen(data->window);
|
||||
if ((BLI_check_seconds_timer() - WM_tooltip_time_closed()) < 0.1) {
|
||||
if ((BLI_time_now_seconds() - WM_tooltip_time_closed()) < 0.1) {
|
||||
WM_tooltip_immediate_init(C, CTX_wm_window(C), data->area, region, ui_but_tooltip_init);
|
||||
if (screen->tool_tip) {
|
||||
screen->tool_tip->pass = 1;
|
||||
|
@ -9977,7 +9977,7 @@ static void ui_mouse_motion_towards_init_ex(uiPopupBlockHandle *menu,
|
|||
menu->towardstime = DBL_MAX; /* unlimited time */
|
||||
}
|
||||
else {
|
||||
menu->towardstime = BLI_check_seconds_timer();
|
||||
menu->towardstime = BLI_time_now_seconds();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10057,7 +10057,7 @@ static bool ui_mouse_motion_towards_check(uiBlock *block,
|
|||
}
|
||||
|
||||
/* 1 second timer */
|
||||
if (BLI_check_seconds_timer() - menu->towardstime > BUTTON_MOUSE_TOWARDS_THRESH) {
|
||||
if (BLI_time_now_seconds() - menu->towardstime > BUTTON_MOUSE_TOWARDS_THRESH) {
|
||||
menu->dotowards = false;
|
||||
}
|
||||
|
||||
|
|
|
@ -1791,7 +1791,7 @@ static void ui_do_animate(bContext *C, Panel *panel)
|
|||
uiHandlePanelData *data = static_cast<uiHandlePanelData *>(panel->activedata);
|
||||
ARegion *region = CTX_wm_region(C);
|
||||
|
||||
float fac = (BLI_check_seconds_timer() - data->starttime) / ANIMATION_TIME;
|
||||
float fac = (BLI_time_now_seconds() - data->starttime) / ANIMATION_TIME;
|
||||
fac = min_ff(sqrtf(fac), 1.0f);
|
||||
|
||||
if (uiAlignPanelStep(region, fac, false)) {
|
||||
|
@ -2649,7 +2649,7 @@ static void panel_handle_data_ensure(const bContext *C,
|
|||
data->startofsy = panel->ofsy;
|
||||
data->start_cur_xmin = region->v2d.cur.xmin;
|
||||
data->start_cur_ymin = region->v2d.cur.ymin;
|
||||
data->starttime = BLI_check_seconds_timer();
|
||||
data->starttime = BLI_time_now_seconds();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -191,7 +191,7 @@ void UI_pie_menu_end(bContext *C, uiPieMenu *pie)
|
|||
|
||||
menu = ui_popup_block_create(C, nullptr, nullptr, nullptr, ui_block_func_PIE, pie, nullptr);
|
||||
menu->popup = true;
|
||||
menu->towardstime = BLI_check_seconds_timer();
|
||||
menu->towardstime = BLI_time_now_seconds();
|
||||
|
||||
UI_popup_handlers_add(C, &window->modalhandlers, menu, WM_HANDLER_ACCEPT_DBL_CLICK);
|
||||
WM_event_add_mousemove(window);
|
||||
|
|
|
@ -6091,7 +6091,7 @@ static std::string progress_tooltip_func(bContext * /*C*/, void *argN, const cha
|
|||
/* create tooltip text and associate it with the job */
|
||||
char elapsed_str[32];
|
||||
char remaining_str[32] = "Unknown";
|
||||
const double elapsed = BLI_check_seconds_timer() - WM_jobs_starttime(wm, owner);
|
||||
const double elapsed = BLI_time_now_seconds() - WM_jobs_starttime(wm, owner);
|
||||
BLI_timecode_string_from_time_simple(elapsed_str, sizeof(elapsed_str), elapsed);
|
||||
|
||||
if (progress) {
|
||||
|
|
|
@ -98,7 +98,7 @@ void UI_view2d_edge_pan_reset(View2DEdgePanData *vpd)
|
|||
{
|
||||
vpd->edge_pan_start_time_x = 0.0;
|
||||
vpd->edge_pan_start_time_y = 0.0;
|
||||
vpd->edge_pan_last_time = BLI_check_seconds_timer();
|
||||
vpd->edge_pan_last_time = BLI_time_now_seconds();
|
||||
vpd->initial_rect = vpd->region->v2d.cur;
|
||||
}
|
||||
|
||||
|
@ -250,7 +250,7 @@ void UI_view2d_edge_pan_apply(bContext *C, View2DEdgePanData *vpd, const int xy[
|
|||
}
|
||||
}
|
||||
|
||||
const double current_time = BLI_check_seconds_timer();
|
||||
const double current_time = BLI_time_now_seconds();
|
||||
edge_pan_manage_delay_timers(vpd, pan_dir_x, pan_dir_y, current_time);
|
||||
|
||||
/* Calculate the delta since the last time the operator was called. */
|
||||
|
|
|
@ -1031,7 +1031,7 @@ static void view_zoomdrag_apply(bContext *C, wmOperator *op)
|
|||
/* Check if the 'timer' is initialized, as zooming with the trackpad
|
||||
* never uses the "Continuous" zoom method, and the 'timer' is not initialized. */
|
||||
if ((U.viewzoom == USER_ZOOM_CONTINUE) && vzd->timer) { /* XXX store this setting as RNA prop? */
|
||||
const double time = BLI_check_seconds_timer();
|
||||
const double time = BLI_time_now_seconds();
|
||||
const float time_step = float(time - vzd->timer_lastdraw);
|
||||
|
||||
dx *= time_step * 5.0f;
|
||||
|
@ -1231,7 +1231,7 @@ static int view_zoomdrag_invoke(bContext *C, wmOperator *op, const wmEvent *even
|
|||
if (U.viewzoom == USER_ZOOM_CONTINUE) {
|
||||
/* needs a timer to continue redrawing */
|
||||
vzd->timer = WM_event_timer_add(CTX_wm_manager(C), window, TIMER, 0.01f);
|
||||
vzd->timer_lastdraw = BLI_check_seconds_timer();
|
||||
vzd->timer_lastdraw = BLI_time_now_seconds();
|
||||
}
|
||||
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
|
|
|
@ -92,13 +92,13 @@ void EDBM_automerge_and_split(Object *obedit,
|
|||
#ifdef DEBUG_TIME
|
||||
em->bm = BM_mesh_copy(bm);
|
||||
|
||||
double t1 = BLI_check_seconds_timer();
|
||||
double t1 = BLI_time_now_seconds();
|
||||
EDBM_automerge(obedit, false, hflag, dist);
|
||||
t1 = BLI_check_seconds_timer() - t1;
|
||||
t1 = BLI_time_now_seconds() - t1;
|
||||
|
||||
BM_mesh_free(em->bm);
|
||||
em->bm = bm;
|
||||
double t2 = BLI_check_seconds_timer();
|
||||
double t2 = BLI_time_now_seconds();
|
||||
#endif
|
||||
|
||||
BMOperator weldop;
|
||||
|
@ -118,7 +118,7 @@ void EDBM_automerge_and_split(Object *obedit,
|
|||
BMO_op_finish(bm, &weldop);
|
||||
|
||||
#ifdef DEBUG_TIME
|
||||
t2 = BLI_check_seconds_timer() - t2;
|
||||
t2 = BLI_time_now_seconds() - t2;
|
||||
printf("t1: %lf; t2: %lf; fac: %lf\n", t1, t2, t1 / t2);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -3982,6 +3982,9 @@ static int edbm_solidify_exec(bContext *C, wmOperator *op)
|
|||
/* select the newly generated faces */
|
||||
BMO_slot_buffer_hflag_enable(bm, bmop.slots_out, "geom.out", BM_FACE, BM_ELEM_SELECT, true);
|
||||
|
||||
/* No need to flush the selection, any selection history is no longer valid. */
|
||||
BM_select_history_clear(bm);
|
||||
|
||||
if (!EDBM_op_finish(em, &bmop, op, true)) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
@ -433,7 +433,7 @@ static void object_overlay_mode_transfer_animation_start(bContext *C, Object *ob
|
|||
{
|
||||
Depsgraph *depsgraph = CTX_data_depsgraph_pointer(C);
|
||||
Object *ob_dst_eval = DEG_get_evaluated_object(depsgraph, ob_dst);
|
||||
ob_dst_eval->runtime->overlay_mode_transfer_start_time = BLI_check_seconds_timer();
|
||||
ob_dst_eval->runtime->overlay_mode_transfer_start_time = BLI_time_now_seconds();
|
||||
}
|
||||
|
||||
static bool object_transfer_mode_to_base(bContext *C, wmOperator *op, Base *base_dst)
|
||||
|
|
|
@ -327,7 +327,7 @@ static void dpaint_bake_endjob(void *customdata)
|
|||
if (job->success) {
|
||||
/* Show bake info */
|
||||
WM_reportf(
|
||||
RPT_INFO, "DynamicPaint: Bake complete! (%.2f)", BLI_check_seconds_timer() - job->start);
|
||||
RPT_INFO, "DynamicPaint: Bake complete! (%.2f)", BLI_time_now_seconds() - job->start);
|
||||
}
|
||||
else {
|
||||
if (strlen(canvas->error)) { /* If an error occurred */
|
||||
|
@ -438,7 +438,7 @@ static void dpaint_bake_startjob(void *customdata, wmJobWorkerStatus *worker_sta
|
|||
job->stop = &worker_status->stop;
|
||||
job->do_update = &worker_status->do_update;
|
||||
job->progress = &worker_status->progress;
|
||||
job->start = BLI_check_seconds_timer();
|
||||
job->start = BLI_time_now_seconds();
|
||||
job->success = 1;
|
||||
|
||||
G.is_break = false;
|
||||
|
|
|
@ -550,7 +550,7 @@ static void PE_free_shape_tree(PEData *data)
|
|||
|
||||
static void PE_create_random_generator(PEData *data)
|
||||
{
|
||||
uint rng_seed = uint(BLI_check_seconds_timer_i() & UINT_MAX);
|
||||
uint rng_seed = uint(BLI_time_now_seconds_i() & UINT_MAX);
|
||||
rng_seed ^= POINTER_AS_UINT(data->ob);
|
||||
rng_seed ^= POINTER_AS_UINT(data->edit);
|
||||
data->rng = BLI_rng_new(rng_seed);
|
||||
|
|
|
@ -338,7 +338,7 @@ static void fluid_bake_endjob(void *customdata)
|
|||
if (job->success) {
|
||||
/* Show bake info. */
|
||||
WM_reportf(
|
||||
RPT_INFO, "Fluid: %s complete! (%.2f)", job->name, BLI_check_seconds_timer() - job->start);
|
||||
RPT_INFO, "Fluid: %s complete! (%.2f)", job->name, BLI_time_now_seconds() - job->start);
|
||||
}
|
||||
else {
|
||||
if (fds->error[0] != '\0') {
|
||||
|
@ -361,7 +361,7 @@ static void fluid_bake_startjob(void *customdata, wmJobWorkerStatus *worker_stat
|
|||
job->stop = &worker_status->stop;
|
||||
job->do_update = &worker_status->do_update;
|
||||
job->progress = &worker_status->progress;
|
||||
job->start = BLI_check_seconds_timer();
|
||||
job->start = BLI_time_now_seconds();
|
||||
job->success = 1;
|
||||
|
||||
G.is_break = false;
|
||||
|
@ -446,7 +446,7 @@ static void fluid_free_endjob(void *customdata)
|
|||
if (job->success) {
|
||||
/* Show free job info */
|
||||
WM_reportf(
|
||||
RPT_INFO, "Fluid: %s complete! (%.2f)", job->name, BLI_check_seconds_timer() - job->start);
|
||||
RPT_INFO, "Fluid: %s complete! (%.2f)", job->name, BLI_time_now_seconds() - job->start);
|
||||
}
|
||||
else {
|
||||
if (fds->error[0] != '\0') {
|
||||
|
@ -466,7 +466,7 @@ static void fluid_free_startjob(void *customdata, wmJobWorkerStatus *worker_stat
|
|||
job->stop = &worker_status->stop;
|
||||
job->do_update = &worker_status->do_update;
|
||||
job->progress = &worker_status->progress;
|
||||
job->start = BLI_check_seconds_timer();
|
||||
job->start = BLI_time_now_seconds();
|
||||
job->success = 1;
|
||||
|
||||
G.is_break = false;
|
||||
|
|
|
@ -459,7 +459,7 @@ static void make_renderinfo_string(const RenderStats *rs,
|
|||
info_time = info_buffers.time_elapsed;
|
||||
BLI_timecode_string_from_time_simple(info_buffers.time_elapsed,
|
||||
sizeof(info_buffers.time_elapsed),
|
||||
BLI_check_seconds_timer() - rs->starttime);
|
||||
BLI_time_now_seconds() - rs->starttime);
|
||||
}
|
||||
|
||||
ret_array[i++] = RPT_("Time:");
|
||||
|
|
|
@ -858,7 +858,7 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op)
|
|||
BLI_condition_init(&oglrender->task_condition);
|
||||
|
||||
#ifdef DEBUG_TIME
|
||||
oglrender->time_start = BLI_check_seconds_timer();
|
||||
oglrender->time_start = BLI_time_now_seconds();
|
||||
#endif
|
||||
|
||||
return true;
|
||||
|
@ -894,7 +894,7 @@ static void screen_opengl_render_end(bContext *C, OGLRender *oglrender)
|
|||
BLI_condition_end(&oglrender->task_condition);
|
||||
|
||||
#ifdef DEBUG_TIME
|
||||
printf("Total render time: %f\n", BLI_check_seconds_timer() - oglrender->time_start);
|
||||
printf("Total render time: %f\n", BLI_time_now_seconds() - oglrender->time_start);
|
||||
#endif
|
||||
|
||||
MEM_SAFE_FREE(oglrender->render_frames);
|
||||
|
|
|
@ -69,6 +69,7 @@
|
|||
#include "WM_api.hh"
|
||||
#include "WM_types.hh"
|
||||
|
||||
#include "ED_gpencil_legacy.hh"
|
||||
#include "ED_paint.hh"
|
||||
#include "ED_screen.hh"
|
||||
#include "ED_sculpt.hh"
|
||||
|
@ -3958,7 +3959,7 @@ bool SCULPT_mode_poll(bContext *C)
|
|||
|
||||
bool SCULPT_mode_poll_view3d(bContext *C)
|
||||
{
|
||||
return (SCULPT_mode_poll(C) && CTX_wm_region_view3d(C));
|
||||
return (SCULPT_mode_poll(C) && CTX_wm_region_view3d(C) && !ED_gpencil_session_active());
|
||||
}
|
||||
|
||||
bool SCULPT_poll(bContext *C)
|
||||
|
|
|
@ -116,7 +116,7 @@ static int sculpt_detail_flood_fill_exec(bContext *C, wmOperator *op)
|
|||
undo::push_begin(ob, op);
|
||||
undo::push_node(ob, nullptr, undo::Type::Position);
|
||||
|
||||
const double start_time = BLI_check_seconds_timer();
|
||||
const double start_time = BLI_time_now_seconds();
|
||||
|
||||
while (bke::pbvh::bmesh_update_topology(
|
||||
ss->pbvh, PBVH_Collapse | PBVH_Subdivide, center, nullptr, size, false, false))
|
||||
|
@ -126,7 +126,7 @@ static int sculpt_detail_flood_fill_exec(bContext *C, wmOperator *op)
|
|||
}
|
||||
}
|
||||
|
||||
CLOG_INFO(&LOG, 2, "Detail flood fill took %f seconds.", BLI_check_seconds_timer() - start_time);
|
||||
CLOG_INFO(&LOG, 2, "Detail flood fill took %f seconds.", BLI_time_now_seconds() - start_time);
|
||||
|
||||
undo::push_end(ob);
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@ static int sculpt_mask_init_exec(bContext *C, wmOperator *op)
|
|||
SCULPT_topology_islands_ensure(ob);
|
||||
}
|
||||
|
||||
const int mask_init_seed = BLI_check_seconds_timer();
|
||||
const int mask_init_seed = BLI_time_now_seconds();
|
||||
|
||||
const SculptMaskWriteInfo mask_write = SCULPT_mask_get_for_write(ss);
|
||||
threading::parallel_for(nodes.index_range(), 1, [&](const IndexRange range) {
|
||||
|
|
|
@ -556,7 +556,7 @@ static void view_zoom_init(bContext *C, wmOperator *op, const wmEvent *event)
|
|||
if (U.viewzoom == USER_ZOOM_CONTINUE) {
|
||||
/* needs a timer to continue redrawing */
|
||||
vpd->timer = WM_event_timer_add(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.01f);
|
||||
vpd->timer_lastdraw = BLI_check_seconds_timer();
|
||||
vpd->timer_lastdraw = BLI_time_now_seconds();
|
||||
}
|
||||
|
||||
vpd->x = event->xy[0];
|
||||
|
@ -648,7 +648,7 @@ static void view_zoom_apply(
|
|||
|
||||
if (U.viewzoom == USER_ZOOM_CONTINUE) {
|
||||
SpaceClip *sclip = CTX_wm_space_clip(C);
|
||||
double time = BLI_check_seconds_timer();
|
||||
double time = BLI_time_now_seconds();
|
||||
float time_step = float(time - vpd->timer_lastdraw);
|
||||
float zfac;
|
||||
|
||||
|
|
|
@ -216,15 +216,15 @@ static void track_markers_startjob(void *tmv, wmJobWorkerStatus *worker_status)
|
|||
* exec_time for "Fastest" tracking
|
||||
*/
|
||||
|
||||
double start_time = BLI_check_seconds_timer(), exec_time;
|
||||
double start_time = BLI_time_now_seconds(), exec_time;
|
||||
|
||||
if (!BKE_autotrack_context_step(tmj->context)) {
|
||||
break;
|
||||
}
|
||||
|
||||
exec_time = BLI_check_seconds_timer() - start_time;
|
||||
exec_time = BLI_time_now_seconds() - start_time;
|
||||
if (tmj->delay > float(exec_time)) {
|
||||
BLI_sleep_ms(tmj->delay - float(exec_time));
|
||||
BLI_time_sleep_ms(tmj->delay - float(exec_time));
|
||||
}
|
||||
}
|
||||
else if (!BKE_autotrack_context_step(tmj->context)) {
|
||||
|
|
|
@ -181,11 +181,14 @@ class AssetCatalogTreeViewUnassignedItem : public ui::BasicTreeViewItem {
|
|||
AssetCatalogTreeView::AssetCatalogTreeView(asset_system::AssetLibrary *library,
|
||||
FileAssetSelectParams *params,
|
||||
SpaceFile &space_file)
|
||||
: asset_library_(library),
|
||||
catalog_tree_(library->catalog_service->get_catalog_tree()),
|
||||
params_(params),
|
||||
space_file_(space_file)
|
||||
: asset_library_(library), params_(params), space_file_(space_file)
|
||||
{
|
||||
if (library && library->catalog_service) {
|
||||
catalog_tree_ = library->catalog_service->get_catalog_tree();
|
||||
}
|
||||
else {
|
||||
catalog_tree_ = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void AssetCatalogTreeView::build_tree()
|
||||
|
|
|
@ -536,7 +536,7 @@ static void image_view_zoom_init(bContext *C, wmOperator *op, const wmEvent *eve
|
|||
if (U.viewzoom == USER_ZOOM_CONTINUE) {
|
||||
/* needs a timer to continue redrawing */
|
||||
vpd->timer = WM_event_timer_add(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.01f);
|
||||
vpd->timer_lastdraw = BLI_check_seconds_timer();
|
||||
vpd->timer_lastdraw = BLI_time_now_seconds();
|
||||
}
|
||||
|
||||
vpd->sima = sima;
|
||||
|
@ -646,7 +646,7 @@ static void image_zoom_apply(ViewZoomData *vpd,
|
|||
}
|
||||
|
||||
if (viewzoom == USER_ZOOM_CONTINUE) {
|
||||
double time = BLI_check_seconds_timer();
|
||||
double time = BLI_time_now_seconds();
|
||||
float time_step = float(time - vpd->timer_lastdraw);
|
||||
float zfac;
|
||||
zfac = 1.0f + ((delta / 20.0f) * time_step);
|
||||
|
|
|
@ -188,7 +188,11 @@ static bool sequencer_write_copy_paste_file(Main *bmain_src,
|
|||
BKE_library_foreach_ID_link(
|
||||
bmain_src, &scene_dst->id, gather_strip_data_ids_to_null, &id_remapper, IDWALK_RECURSE);
|
||||
|
||||
BKE_libblock_remap_multiple(bmain_src, id_remapper, 0);
|
||||
BKE_libblock_relink_multiple(bmain_src,
|
||||
{&scene_dst->id},
|
||||
ID_REMAP_TYPE_REMAP,
|
||||
id_remapper,
|
||||
(ID_REMAP_SKIP_USER_CLEAR | ID_REMAP_SKIP_USER_REFCOUNT));
|
||||
|
||||
/* Ensure that there are no old copy tags around */
|
||||
BKE_blendfile_write_partial_begin(bmain_src);
|
||||
|
|
|
@ -113,7 +113,7 @@ ImBuf *make_waveform_view_from_ibuf(const ImBuf *ibuf)
|
|||
#endif
|
||||
const int w = ibuf->x;
|
||||
const int h = 256;
|
||||
ImBuf *rval = IMB_allocImBuf(w, h, 32, IB_rect);
|
||||
ImBuf *rval = IMB_allocImBuf(w, h, 32, IB_rect | IB_uninitialized_pixels);
|
||||
uchar *tgt = rval->byte_buffer.data;
|
||||
|
||||
uchar wtable[256];
|
||||
|
@ -172,7 +172,7 @@ ImBuf *make_sep_waveform_view_from_ibuf(const ImBuf *ibuf)
|
|||
#endif
|
||||
int w = ibuf->x;
|
||||
int h = 256;
|
||||
ImBuf *rval = IMB_allocImBuf(w, h, 32, IB_rect);
|
||||
ImBuf *rval = IMB_allocImBuf(w, h, 32, IB_rect | IB_uninitialized_pixels);
|
||||
uchar *tgt = rval->byte_buffer.data;
|
||||
int sw = ibuf->x / 3;
|
||||
|
||||
|
@ -222,7 +222,7 @@ ImBuf *make_zebra_view_from_ibuf(const ImBuf *ibuf, float perc)
|
|||
#ifdef DEBUG_TIME
|
||||
SCOPED_TIMER(__func__);
|
||||
#endif
|
||||
ImBuf *res = IMB_allocImBuf(ibuf->x, ibuf->y, 32, IB_rect);
|
||||
ImBuf *res = IMB_allocImBuf(ibuf->x, ibuf->y, 32, IB_rect | IB_uninitialized_pixels);
|
||||
|
||||
threading::parallel_for(IndexRange(ibuf->y), 16, [&](IndexRange y_range) {
|
||||
if (ibuf->float_buffer.data) {
|
||||
|
@ -346,7 +346,7 @@ ImBuf *make_vectorscope_view_from_ibuf(const ImBuf *ibuf)
|
|||
#endif
|
||||
const int size = 512;
|
||||
const float size_mul = size - 1.0f;
|
||||
ImBuf *rval = IMB_allocImBuf(size, size, 32, IB_rect);
|
||||
ImBuf *rval = IMB_allocImBuf(size, size, 32, IB_rect | IB_uninitialized_pixels);
|
||||
|
||||
uchar *dst = rval->byte_buffer.data;
|
||||
float rgb[3];
|
||||
|
|
|
@ -3520,7 +3520,7 @@ static int text_line_number_invoke(bContext *C, wmOperator * /*op*/, const wmEve
|
|||
return OPERATOR_PASS_THROUGH;
|
||||
}
|
||||
|
||||
time = BLI_check_seconds_timer();
|
||||
time = BLI_time_now_seconds();
|
||||
if (last_jump < time - 1) {
|
||||
jump_to = 0;
|
||||
}
|
||||
|
|
|
@ -366,7 +366,7 @@ static bool initFlyInfo(bContext *C, FlyInfo *fly, wmOperator *op, const wmEvent
|
|||
fly->ndof = nullptr;
|
||||
#endif
|
||||
|
||||
fly->time_lastdraw = fly->time_lastwheel = BLI_check_seconds_timer();
|
||||
fly->time_lastdraw = fly->time_lastwheel = BLI_time_now_seconds();
|
||||
|
||||
fly->draw_handle_pixel = ED_region_draw_cb_activate(
|
||||
fly->region->type, drawFlyPixel, fly, REGION_DRAW_POST_PIXEL);
|
||||
|
@ -513,7 +513,7 @@ static void flyEvent(FlyInfo *fly, const wmEvent *event)
|
|||
fly->ndof = nullptr;
|
||||
}
|
||||
/* Update the time else the view will jump when 2D mouse/timer resume. */
|
||||
fly->time_lastdraw = BLI_check_seconds_timer();
|
||||
fly->time_lastdraw = BLI_time_now_seconds();
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
|
@ -561,7 +561,7 @@ static void flyEvent(FlyInfo *fly, const wmEvent *event)
|
|||
fly->speed = fabsf(fly->speed);
|
||||
}
|
||||
|
||||
time_currwheel = BLI_check_seconds_timer();
|
||||
time_currwheel = BLI_time_now_seconds();
|
||||
time_wheel = float(time_currwheel - fly->time_lastwheel);
|
||||
fly->time_lastwheel = time_currwheel;
|
||||
/* Mouse wheel delays range from (0.5 == slow) to (0.01 == fast). */
|
||||
|
@ -586,7 +586,7 @@ static void flyEvent(FlyInfo *fly, const wmEvent *event)
|
|||
fly->speed = -fabsf(fly->speed);
|
||||
}
|
||||
|
||||
time_currwheel = BLI_check_seconds_timer();
|
||||
time_currwheel = BLI_time_now_seconds();
|
||||
time_wheel = float(time_currwheel - fly->time_lastwheel);
|
||||
fly->time_lastwheel = time_currwheel;
|
||||
/* 0-0.5 -> 0-5.0 */
|
||||
|
@ -843,7 +843,7 @@ static int flyApply(bContext *C, FlyInfo *fly, bool is_confirm)
|
|||
#ifdef NDOF_FLY_DRAW_TOOMUCH
|
||||
fly->redraw = 1;
|
||||
#endif
|
||||
time_current = BLI_check_seconds_timer();
|
||||
time_current = BLI_time_now_seconds();
|
||||
time_redraw = float(time_current - fly->time_lastdraw);
|
||||
|
||||
/* Clamp redraw time to avoid jitter in roll correction. */
|
||||
|
@ -1017,7 +1017,7 @@ static int flyApply(bContext *C, FlyInfo *fly, bool is_confirm)
|
|||
}
|
||||
else {
|
||||
/* We're not redrawing but we need to update the time else the view will jump. */
|
||||
fly->time_lastdraw = BLI_check_seconds_timer();
|
||||
fly->time_lastdraw = BLI_time_now_seconds();
|
||||
}
|
||||
/* End drawing. */
|
||||
copy_v3_v3(fly->dvec_prev, dvec);
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue