WIP: Experiment: Drop import operator helper and file drop type #111242
|
@ -1638,7 +1638,7 @@ class CyclesPreferences(bpy.types.AddonPreferences):
|
|||
elif device_type == 'ONEAPI':
|
||||
import sys
|
||||
if sys.platform.startswith("win"):
|
||||
driver_version = "XX.X.101.4314"
|
||||
driver_version = "XX.X.101.4644"
|
||||
col.label(text="Requires Intel GPU with Xe-HPG architecture", icon='BLANK1')
|
||||
col.label(text=iface_("and Windows driver version %s or newer") % driver_version,
|
||||
icon='BLANK1', translate=False)
|
||||
|
|
|
@ -147,13 +147,14 @@ static inline void colorramp_to_array(BL::ColorRamp &ramp,
|
|||
array<float> &ramp_alpha,
|
||||
int size)
|
||||
{
|
||||
ramp_color.resize(size);
|
||||
ramp_alpha.resize(size);
|
||||
const int full_size = size + 1;
|
||||
ramp_color.resize(full_size);
|
||||
ramp_alpha.resize(full_size);
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
for (int i = 0; i < full_size; i++) {
|
||||
float color[4];
|
||||
|
||||
ramp.evaluate((float)i / (float)(size - 1), color);
|
||||
ramp.evaluate(float(i) / float(size), color);
|
||||
ramp_color[i] = make_float3(color[0], color[1], color[2]);
|
||||
ramp_alpha[i] = color[3];
|
||||
}
|
||||
|
@ -183,9 +184,10 @@ static inline void curvemapping_to_array(BL::CurveMapping &cumap, array<float> &
|
|||
{
|
||||
cumap.update();
|
||||
BL::CurveMap curve = cumap.curves[0];
|
||||
data.resize(size);
|
||||
for (int i = 0; i < size; i++) {
|
||||
float t = (float)i / (float)(size - 1);
|
||||
const int full_size = size + 1;
|
||||
data.resize(full_size);
|
||||
for (int i = 0; i < full_size; i++) {
|
||||
float t = float(i) / float(size);
|
||||
data[i] = cumap.evaluate(curve, t);
|
||||
}
|
||||
}
|
||||
|
@ -204,10 +206,11 @@ static inline void curvemapping_float_to_array(BL::CurveMapping &cumap,
|
|||
|
||||
BL::CurveMap map = cumap.curves[0];
|
||||
|
||||
data.resize(size);
|
||||
const int full_size = size + 1;
|
||||
data.resize(full_size);
|
||||
|
||||
for (int i = 0; i < size; i++) {
|
||||
float t = min + (float)i / (float)(size - 1) * range;
|
||||
for (int i = 0; i < full_size; i++) {
|
||||
float t = min + float(i) / float(size) * range;
|
||||
data[i] = cumap.evaluate(map, t);
|
||||
}
|
||||
}
|
||||
|
@ -241,20 +244,21 @@ static inline void curvemapping_color_to_array(BL::CurveMapping &cumap,
|
|||
BL::CurveMap mapG = cumap.curves[1];
|
||||
BL::CurveMap mapB = cumap.curves[2];
|
||||
|
||||
data.resize(size);
|
||||
const int full_size = size + 1;
|
||||
data.resize(full_size);
|
||||
|
||||
if (rgb_curve) {
|
||||
BL::CurveMap mapI = cumap.curves[3];
|
||||
for (int i = 0; i < size; i++) {
|
||||
const float t = min_x + (float)i / (float)(size - 1) * range_x;
|
||||
for (int i = 0; i < full_size; i++) {
|
||||
const float t = min_x + float(i) / float(size) * range_x;
|
||||
data[i] = make_float3(cumap.evaluate(mapR, cumap.evaluate(mapI, t)),
|
||||
cumap.evaluate(mapG, cumap.evaluate(mapI, t)),
|
||||
cumap.evaluate(mapB, cumap.evaluate(mapI, t)));
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < size; i++) {
|
||||
float t = min_x + (float)i / (float)(size - 1) * range_x;
|
||||
for (int i = 0; i < full_size; i++) {
|
||||
float t = min_x + float(i) / float(size) * range_x;
|
||||
data[i] = make_float3(
|
||||
cumap.evaluate(mapR, t), cumap.evaluate(mapG, t), cumap.evaluate(mapB, t));
|
||||
}
|
||||
|
|
|
@ -853,10 +853,14 @@ void OneapiDevice::get_adjusted_global_and_local_sizes(SyclQueue *queue,
|
|||
|
||||
/* Compute-runtime (ie. NEO) version is what gets returned by sycl/L0 on Windows
|
||||
* since Windows driver 101.3268. */
|
||||
/* The same min compute-runtime version is currently used across Windows and Linux.
|
||||
* For Windows driver 101.4314, compute-runtime version is 25977. */
|
||||
static const int lowest_supported_driver_version_win = 1014314;
|
||||
static const int lowest_supported_driver_version_win = 1014644;
|
||||
# ifdef _WIN32
|
||||
/* For Windows driver 101.4644, compute-runtime version is 26771.
|
||||
* This information is returned by `ocloc query OCL_DRIVER_VERSION`.*/
|
||||
static const int lowest_supported_driver_version_neo = 26771;
|
||||
# else
|
||||
static const int lowest_supported_driver_version_neo = 25812;
|
||||
# endif
|
||||
|
||||
int OneapiDevice::parse_driver_build_version(const sycl::device &device)
|
||||
{
|
||||
|
|
|
@ -857,8 +857,13 @@ if(WITH_CYCLES_DEVICE_ONEAPI)
|
|||
-fsycl-max-parallel-link-jobs=${SYCL_OFFLINE_COMPILER_PARALLEL_JOBS}
|
||||
-shared
|
||||
-DWITH_ONEAPI
|
||||
-ffast-math
|
||||
-O2
|
||||
-fno-fast-math
|
||||
-ffp-contract=fast
|
||||
-fassociative-math
|
||||
-freciprocal-math
|
||||
-fno-signed-zeros
|
||||
-ffinite-math-only
|
||||
-D__KERNEL_LOCAL_ATOMIC_SORT__
|
||||
-o"${cycles_kernel_oneapi_lib}"
|
||||
-I"${CMAKE_CURRENT_SOURCE_DIR}/.."
|
||||
|
|
|
@ -222,15 +222,9 @@ ccl_device_forceinline int __float_as_int(float x)
|
|||
#define fmodf(x, y) sycl::fmod((x), (y))
|
||||
#define lgammaf(x) sycl::lgamma((x))
|
||||
|
||||
/* `sycl::native::cos` precision is not sufficient and `-ffast-math` lets
|
||||
* the current DPC++ compiler overload `sycl::cos` with it.
|
||||
* We work around this issue by directly calling the SPIRV implementation which
|
||||
* provides greater precision. */
|
||||
#if defined(__SYCL_DEVICE_ONLY__) && defined(__SPIR__)
|
||||
# define cosf(x) __spirv_ocl_cos(((float)(x)))
|
||||
#else
|
||||
# define cosf(x) sycl::cos(((float)(x)))
|
||||
#endif
|
||||
/* sycl::native::cos precision is not sufficient when using Nishita Sky node
|
||||
* with a small sun size. */
|
||||
#define cosf(x) sycl::cos(((float)(x)))
|
||||
#define sinf(x) sycl::native::sin(((float)(x)))
|
||||
#define powf(x, y) sycl::native::powr(((float)(x)), ((float)(y)))
|
||||
#define tanf(x) sycl::native::tan(((float)(x)))
|
||||
|
|
|
@ -9,6 +9,8 @@
|
|||
|
||||
#define vector3 point
|
||||
|
||||
/* The fractalization logic is the same as for fBM Noise, except that some additions are replaced
|
||||
* by lerps. */
|
||||
#define FRACTAL_VORONOI_X_FX(T) \
|
||||
VoronoiOutput fractal_voronoi_x_fx(VoronoiParams params, T coord) \
|
||||
{ \
|
||||
|
@ -20,7 +22,7 @@
|
|||
Output.Distance = 0.0; \
|
||||
Output.Color = color(0.0, 0.0, 0.0); \
|
||||
Output.Position = vector4(0.0, 0.0, 0.0, 0.0); \
|
||||
int zero_input = params.detail == 0.0 || params.roughness == 0.0 || params.lacunarity == 0.0; \
|
||||
int zero_input = params.detail == 0.0 || params.roughness == 0.0; \
|
||||
\
|
||||
for (int i = 0; i <= ceil(params.detail); ++i) { \
|
||||
VoronoiOutput octave; \
|
||||
|
@ -71,6 +73,8 @@
|
|||
return Output; \
|
||||
}
|
||||
|
||||
/* The fractalization logic is the same as for fBM Noise, except that some additions are replaced
|
||||
* by lerps. */
|
||||
#define FRACTAL_VORONOI_DISTANCE_TO_EDGE_FUNCTION(T) \
|
||||
float fractal_voronoi_distance_to_edge(VoronoiParams params, T coord) \
|
||||
{ \
|
||||
|
@ -79,7 +83,7 @@
|
|||
float scale = 1.0; \
|
||||
float distance = 8.0; \
|
||||
\
|
||||
int zero_input = params.detail == 0.0 || params.roughness == 0.0 || params.lacunarity == 0.0; \
|
||||
int zero_input = params.detail == 0.0 || params.roughness == 0.0; \
|
||||
\
|
||||
for (int i = 0; i <= ceil(params.detail); ++i) { \
|
||||
float octave_distance = voronoi_distance_to_edge(params, coord * scale); \
|
||||
|
|
|
@ -880,6 +880,8 @@ ccl_device float voronoi_n_sphere_radius(ccl_private const VoronoiParams ¶ms
|
|||
|
||||
/* **** Fractal Voronoi **** */
|
||||
|
||||
/* The fractalization logic is the same as for fBM Noise, except that some additions are replaced
|
||||
* by lerps. */
|
||||
template<typename T>
|
||||
ccl_device VoronoiOutput fractal_voronoi_x_fx(ccl_private const VoronoiParams ¶ms,
|
||||
const T coord)
|
||||
|
@ -889,8 +891,7 @@ ccl_device VoronoiOutput fractal_voronoi_x_fx(ccl_private const VoronoiParams &p
|
|||
float scale = 1.0f;
|
||||
|
||||
VoronoiOutput output;
|
||||
const bool zero_input = params.detail == 0.0f || params.roughness == 0.0f ||
|
||||
params.lacunarity == 0.0f;
|
||||
const bool zero_input = params.detail == 0.0f || params.roughness == 0.0f;
|
||||
|
||||
for (int i = 0; i <= ceilf(params.detail); ++i) {
|
||||
VoronoiOutput octave = (params.feature == NODE_VORONOI_F2) ?
|
||||
|
@ -936,6 +937,8 @@ ccl_device VoronoiOutput fractal_voronoi_x_fx(ccl_private const VoronoiParams &p
|
|||
return output;
|
||||
}
|
||||
|
||||
/* The fractalization logic is the same as for fBM Noise, except that some additions are replaced
|
||||
* by lerps. */
|
||||
template<typename T>
|
||||
ccl_device float fractal_voronoi_distance_to_edge(ccl_private const VoronoiParams ¶ms,
|
||||
const T coord)
|
||||
|
@ -945,8 +948,7 @@ ccl_device float fractal_voronoi_distance_to_edge(ccl_private const VoronoiParam
|
|||
float scale = 1.0f;
|
||||
float distance = 8.0f;
|
||||
|
||||
const bool zero_input = params.detail == 0.0f || params.roughness == 0.0f ||
|
||||
params.lacunarity == 0.0f;
|
||||
const bool zero_input = params.detail == 0.0f || params.roughness == 0.0f;
|
||||
|
||||
for (int i = 0; i <= ceilf(params.detail); ++i) {
|
||||
const float octave_distance = voronoi_distance_to_edge(params, coord * scale);
|
||||
|
|
|
@ -285,6 +285,13 @@ def load_scripts(*, reload_scripts=False, refresh_scripts=False):
|
|||
|
||||
del _global_loaded_modules[:]
|
||||
|
||||
# Update key-maps to account for operators no longer existing.
|
||||
# Typically unloading operators would refresh the event system (such as disabling an add-on)
|
||||
# however reloading scripts re-enable all add-ons immediately (which may inspect key-maps).
|
||||
# For this reason it's important to update key-maps which will have been tagged to update.
|
||||
# Without this, add-on register functions accessing key-map properties can crash, see: #111702.
|
||||
_bpy.context.window_manager.keyconfigs.update()
|
||||
|
||||
from bpy_restrict_state import RestrictBlend
|
||||
|
||||
with RestrictBlend():
|
||||
|
|
|
@ -5,41 +5,79 @@
|
|||
import bpy
|
||||
from bpy.types import Menu
|
||||
from bl_ui import node_add_menu
|
||||
|
||||
from bpy.app.translations import (
|
||||
pgettext_iface as iface_,
|
||||
)
|
||||
|
||||
class NODE_MT_category_COMP_INPUT(Menu):
|
||||
bl_idname = "NODE_MT_category_COMP_INPUT"
|
||||
bl_label = "Input"
|
||||
|
||||
def draw(self, _context):
|
||||
def draw(self, context):
|
||||
snode = context.space_data
|
||||
is_group = (len(snode.path) > 1)
|
||||
|
||||
layout = self.layout
|
||||
layout.menu("NODE_MT_category_COMP_INPUT_CONSTANT")
|
||||
layout.separator()
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeBokehImage")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeImage")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeMask")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeMovieClip")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeRLayers")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeRGB")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeSceneTime")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeTexture")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeTime")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeTrackPos")
|
||||
|
||||
if is_group:
|
||||
layout.separator()
|
||||
node_add_menu.add_node_type(layout, "NodeGroupInput")
|
||||
layout.separator()
|
||||
layout.menu("NODE_MT_category_COMP_INPUT_SCENE")
|
||||
|
||||
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
|
||||
|
||||
|
||||
class NODE_MT_category_COMP_INPUT_CONSTANT(Menu):
|
||||
bl_idname = "NODE_MT_category_COMP_INPUT_CONSTANT"
|
||||
bl_label = "Constant"
|
||||
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeRGB")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeValue")
|
||||
|
||||
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
|
||||
|
||||
|
||||
class NODE_MT_category_COMP_INPUT_SCENE(Menu):
|
||||
bl_idname = "NODE_MT_category_COMP_INPUT_SCENE"
|
||||
bl_label = "Scene"
|
||||
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeRLayers")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeSceneTime")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeTime")
|
||||
|
||||
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
|
||||
|
||||
|
||||
class NODE_MT_category_COMP_OUTPUT(Menu):
|
||||
bl_idname = "NODE_MT_category_COMP_OUTPUT"
|
||||
bl_label = "Output"
|
||||
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
def draw(self, context):
|
||||
snode = context.space_data
|
||||
is_group = (len(snode.path) > 1)
|
||||
|
||||
layout = self.layout
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeComposite")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeOutputFile")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeLevels")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeSplitViewer")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeViewer")
|
||||
layout.separator()
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeOutputFile")
|
||||
|
||||
if is_group:
|
||||
layout.separator()
|
||||
node_add_menu.add_node_type(layout, "NodeGroupOutput")
|
||||
|
||||
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
|
||||
|
||||
|
@ -50,7 +88,27 @@ class NODE_MT_category_COMP_COLOR(Menu):
|
|||
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeAlphaOver")
|
||||
layout.menu("NODE_MT_category_COMP_COLOR_ADJUST")
|
||||
layout.separator()
|
||||
layout.menu("NODE_MT_category_COMP_COLOR_MIX")
|
||||
layout.separator()
|
||||
node_add_menu.add_node_type(layout, "CompositorNodePremulKey")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeValToRGB")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeConvertColorSpace")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeSetAlpha")
|
||||
layout.separator()
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeInvert")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeRGBToBW")
|
||||
|
||||
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
|
||||
|
||||
|
||||
class NODE_MT_category_COMP_COLOR_ADJUST(Menu):
|
||||
bl_idname = "NODE_MT_category_COMP_COLOR_ADJUST"
|
||||
bl_label = "Adjust"
|
||||
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeBrightContrast")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeColorBalance")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeColorCorrection")
|
||||
|
@ -58,35 +116,27 @@ class NODE_MT_category_COMP_COLOR(Menu):
|
|||
node_add_menu.add_node_type(layout, "CompositorNodeGamma")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeHueCorrect")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeHueSat")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeInvert")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeMixRGB")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodePosterize")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeCurveRGB")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeTonemap")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeZcombine")
|
||||
|
||||
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
|
||||
|
||||
|
||||
class NODE_MT_category_COMP_CONVERTER(Menu):
|
||||
bl_idname = "NODE_MT_category_COMP_CONVERTER"
|
||||
bl_label = "Converter"
|
||||
class NODE_MT_category_COMP_COLOR_MIX(Menu):
|
||||
bl_idname = "NODE_MT_category_COMP_COLOR_MIX"
|
||||
bl_label = "Mix"
|
||||
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
node_add_menu.add_node_type(layout, "CompositorNodePremulKey")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeValToRGB")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeAlphaOver")
|
||||
layout.separator()
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeCombineColor")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeCombineXYZ")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeConvertColorSpace")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeIDMask")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeMath")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeRGBToBW")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeSeparateColor")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeSeparateXYZ")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeSetAlpha")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeSwitchView")
|
||||
|
||||
layout.separator()
|
||||
node_add_menu.add_node_type(
|
||||
layout, "CompositorNodeMixRGB",
|
||||
label=iface_("Mix Color"))
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeZcombine")
|
||||
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
|
||||
|
||||
|
||||
|
@ -96,91 +146,41 @@ class NODE_MT_category_COMP_FILTER(Menu):
|
|||
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
layout.menu("NODE_MT_category_COMP_FILTER_BLUR")
|
||||
layout.separator()
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeAntiAliasing")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeDenoise")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeDespeckle")
|
||||
layout.separator()
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeDilateErode")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeInpaint")
|
||||
layout.separator()
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeFilter")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeGlare")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeKuwahara")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodePixelate")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodePosterize")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeSunBeams")
|
||||
|
||||
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
|
||||
|
||||
|
||||
class NODE_MT_category_COMP_FILTER_BLUR(Menu):
|
||||
bl_idname = "NODE_MT_category_COMP_FILTER_BLUR"
|
||||
bl_label = "Blur"
|
||||
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeBilateralblur")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeBlur")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeBokehBlur")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeDefocus")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeDenoise")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeDespeckle")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeDilateErode")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeDBlur")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeFilter")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeGlare")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeInpaint")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeKuwahara")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodePixelate")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeSunBeams")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeVecBlur")
|
||||
|
||||
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
|
||||
|
||||
|
||||
class NODE_MT_category_COMP_VECTOR(Menu):
|
||||
bl_idname = "NODE_MT_category_COMP_VECTOR"
|
||||
bl_label = "Vector"
|
||||
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeMapRange")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeMapValue")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeNormal")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeNormalize")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeCurveVec")
|
||||
|
||||
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
|
||||
|
||||
|
||||
class NODE_MT_category_COMP_MATTE(Menu):
|
||||
bl_idname = "NODE_MT_category_COMP_MATTE"
|
||||
bl_label = "Matte"
|
||||
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeBoxMask")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeChannelMatte")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeChromaMatte")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeColorMatte")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeColorSpill")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeCryptomatteV2")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeCryptomatte")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeDiffMatte")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeDistanceMatte")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeDoubleEdgeMask")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeEllipseMask")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeKeying")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeKeyingScreen")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeLumaMatte")
|
||||
|
||||
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
|
||||
|
||||
|
||||
class NODE_MT_category_COMP_DISTORT(Menu):
|
||||
bl_idname = "NODE_MT_category_COMP_DISTORT"
|
||||
bl_label = "Distort"
|
||||
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeCornerPin")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeCrop")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeDisplace")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeFlip")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeLensdist")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeMapUV")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeMovieDistortion")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodePlaneTrackDeform")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeRotate")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeScale")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeStabilize")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeTransform")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeTranslate")
|
||||
|
||||
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
|
||||
|
||||
|
||||
class NODE_MT_category_COMP_GROUP(Menu):
|
||||
bl_idname = "NODE_MT_category_COMP_GROUP"
|
||||
bl_label = "Group"
|
||||
|
@ -191,6 +191,116 @@ class NODE_MT_category_COMP_GROUP(Menu):
|
|||
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
|
||||
|
||||
|
||||
class NODE_MT_category_COMP_KEYING(Menu):
|
||||
bl_idname = "NODE_MT_category_COMP_KEYING"
|
||||
bl_label = "Keying"
|
||||
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeChannelMatte")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeChromaMatte")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeColorMatte")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeColorSpill")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeDiffMatte")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeDistanceMatte")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeKeying")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeKeyingScreen")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeLumaMatte")
|
||||
|
||||
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
|
||||
|
||||
|
||||
class NODE_MT_category_COMP_MASK(Menu):
|
||||
bl_idname = "NODE_MT_category_COMP_MASK"
|
||||
bl_label = "Mask"
|
||||
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeCryptomatteV2")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeCryptomatte")
|
||||
layout.separator()
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeBoxMask")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeEllipseMask")
|
||||
layout.separator()
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeDoubleEdgeMask")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeIDMask")
|
||||
|
||||
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
|
||||
|
||||
|
||||
class NODE_MT_category_COMP_TRACKING(Menu):
|
||||
bl_idname = "NODE_MT_category_COMP_TRACKING"
|
||||
bl_label = "Tracking"
|
||||
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
node_add_menu.add_node_type(layout, "CompositorNodePlaneTrackDeform")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeStabilize")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeTrackPos")
|
||||
|
||||
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
|
||||
|
||||
|
||||
class NODE_MT_category_COMP_TRANSFORM(Menu):
|
||||
bl_idname = "NODE_MT_category_COMP_TRANSFORM"
|
||||
bl_label = "Transform"
|
||||
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeRotate")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeScale")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeTransform")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeTranslate")
|
||||
layout.separator()
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeCornerPin")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeCrop")
|
||||
layout.separator()
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeDisplace")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeFlip")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeMapUV")
|
||||
layout.separator()
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeLensdist")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeMovieDistortion")
|
||||
|
||||
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
|
||||
|
||||
|
||||
class NODE_MT_category_COMP_UTIL(Menu):
|
||||
bl_idname = "NODE_MT_category_COMP_UTIL"
|
||||
bl_label = "Utilities"
|
||||
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeMapRange")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeMapValue")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeMath")
|
||||
layout.separator()
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeLevels")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeNormalize")
|
||||
layout.separator()
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeSwitch")
|
||||
node_add_menu.add_node_type(
|
||||
layout, "CompositorNodeSwitchView",
|
||||
label=iface_("Switch Stereo View"))
|
||||
|
||||
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
|
||||
|
||||
|
||||
class NODE_MT_category_COMP_VECTOR(Menu):
|
||||
bl_idname = "NODE_MT_category_COMP_VECTOR"
|
||||
bl_label = "Vector"
|
||||
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeCombineXYZ")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeSeparateXYZ")
|
||||
layout.separator()
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeNormal")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeCurveVec")
|
||||
|
||||
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
|
||||
|
||||
|
||||
class NODE_MT_category_COMP_LAYOUT(Menu):
|
||||
bl_idname = "NODE_MT_category_COMP_LAYOUT"
|
||||
bl_label = "Layout"
|
||||
|
@ -213,10 +323,15 @@ class NODE_MT_compositing_node_add_all(Menu):
|
|||
layout.menu("NODE_MT_category_COMP_OUTPUT")
|
||||
layout.separator()
|
||||
layout.menu("NODE_MT_category_COMP_COLOR")
|
||||
layout.menu("NODE_MT_category_COMP_CONVERTER")
|
||||
layout.menu("NODE_MT_category_COMP_DISTORT")
|
||||
layout.menu("NODE_MT_category_COMP_FILTER")
|
||||
layout.menu("NODE_MT_category_COMP_MATTE")
|
||||
layout.separator()
|
||||
layout.menu("NODE_MT_category_COMP_KEYING")
|
||||
layout.menu("NODE_MT_category_COMP_MASK")
|
||||
layout.separator()
|
||||
layout.menu("NODE_MT_category_COMP_TRACKING")
|
||||
layout.separator()
|
||||
layout.menu("NODE_MT_category_COMP_TRANSFORM")
|
||||
layout.menu("NODE_MT_category_COMP_UTIL")
|
||||
layout.menu("NODE_MT_category_COMP_VECTOR")
|
||||
layout.separator()
|
||||
layout.menu("NODE_MT_category_COMP_GROUP")
|
||||
|
@ -228,13 +343,20 @@ class NODE_MT_compositing_node_add_all(Menu):
|
|||
classes = (
|
||||
NODE_MT_compositing_node_add_all,
|
||||
NODE_MT_category_COMP_INPUT,
|
||||
NODE_MT_category_COMP_INPUT_CONSTANT,
|
||||
NODE_MT_category_COMP_INPUT_SCENE,
|
||||
NODE_MT_category_COMP_OUTPUT,
|
||||
NODE_MT_category_COMP_COLOR,
|
||||
NODE_MT_category_COMP_CONVERTER,
|
||||
NODE_MT_category_COMP_COLOR_ADJUST,
|
||||
NODE_MT_category_COMP_COLOR_MIX,
|
||||
NODE_MT_category_COMP_FILTER,
|
||||
NODE_MT_category_COMP_FILTER_BLUR,
|
||||
NODE_MT_category_COMP_KEYING,
|
||||
NODE_MT_category_COMP_MASK,
|
||||
NODE_MT_category_COMP_TRACKING,
|
||||
NODE_MT_category_COMP_TRANSFORM,
|
||||
NODE_MT_category_COMP_UTIL,
|
||||
NODE_MT_category_COMP_VECTOR,
|
||||
NODE_MT_category_COMP_MATTE,
|
||||
NODE_MT_category_COMP_DISTORT,
|
||||
NODE_MT_category_COMP_GROUP,
|
||||
NODE_MT_category_COMP_LAYOUT,
|
||||
)
|
||||
|
|
|
@ -224,12 +224,6 @@ class BONE_PT_relations(BoneButtonsPanel, Panel):
|
|||
bone = context.edit_bone
|
||||
|
||||
col = layout.column()
|
||||
col.use_property_split = False
|
||||
col.prop(bone, "layers", text="")
|
||||
col.use_property_split = True
|
||||
col = layout.column()
|
||||
|
||||
col.separator()
|
||||
|
||||
if context.bone:
|
||||
col.prop(bone, "parent")
|
||||
|
|
|
@ -302,6 +302,7 @@ class GRAPH_MT_key_blending(Menu):
|
|||
layout.operator("graph.blend_offset", text="Blend Offset")
|
||||
layout.operator("graph.blend_to_ease", text="Blend to Ease")
|
||||
layout.operator("graph.match_slope", text="Match Slope")
|
||||
layout.operator("graph.shear", text="Shear Keys")
|
||||
|
||||
|
||||
class GRAPH_MT_key_smoothing(Menu):
|
||||
|
|
|
@ -2593,14 +2593,20 @@ class SEQUENCER_PT_modifiers(SequencerButtonsPanel, Panel):
|
|||
col = flow.column()
|
||||
box = col.box()
|
||||
split = box.split(factor=0.4)
|
||||
split.label(text = "{:.2f}".format(soundEq.curve_mapping.clip_min_x))
|
||||
split.label(text = "Hz")
|
||||
split.label(text="{:.2f}".format(soundEq.curve_mapping.clip_min_x))
|
||||
split.label(text="Hz")
|
||||
split.alignment = "RIGHT"
|
||||
split.label(text = "{:.2f}".format(soundEq.curve_mapping.clip_max_x))
|
||||
box.template_curve_mapping(soundEq, "curve_mapping",
|
||||
type='NONE', levels=False, brush=True, use_negative_slope=True, show_tone=False)
|
||||
split.label(text="{:.2f}".format(soundEq.curve_mapping.clip_max_x))
|
||||
box.template_curve_mapping(
|
||||
soundEq,
|
||||
"curve_mapping",
|
||||
type='NONE',
|
||||
levels=False,
|
||||
brush=True,
|
||||
use_negative_slope=True,
|
||||
show_tone=False)
|
||||
second_row = col.row()
|
||||
second_row.label(text = "dB")
|
||||
second_row.label(text="dB")
|
||||
second_row.alignment = "CENTER"
|
||||
|
||||
|
||||
|
|
|
@ -123,21 +123,13 @@ class TIME_MT_view(Menu):
|
|||
scene = context.scene
|
||||
st = context.space_data
|
||||
|
||||
layout.prop(st, "show_region_hud")
|
||||
layout.menu("INFO_MT_area")
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.prop(st, "show_seconds")
|
||||
layout.prop(st, "show_locked_time")
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.prop(st, "show_markers")
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.prop(scene, "show_keys_from_selected_only")
|
||||
layout.prop(st.dopesheet, "show_only_errors")
|
||||
# NOTE: "action" now, since timeline is in the dopesheet editor, instead of as own editor
|
||||
layout.operator("action.view_frame")
|
||||
layout.operator("action.view_all")
|
||||
|
||||
layout.separator()
|
||||
|
||||
|
@ -145,13 +137,21 @@ class TIME_MT_view(Menu):
|
|||
|
||||
layout.separator()
|
||||
|
||||
# NOTE: "action" now, since timeline is in the dopesheet editor, instead of as own editor
|
||||
layout.operator("action.view_all")
|
||||
layout.operator("action.view_frame")
|
||||
layout.prop(st.dopesheet, "show_only_errors")
|
||||
layout.prop(scene, "show_keys_from_selected_only")
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.menu("INFO_MT_area")
|
||||
layout.prop(st, "show_markers")
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.prop(st, "show_locked_time")
|
||||
layout.prop(st, "show_seconds")
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.prop(st, "show_region_hud")
|
||||
|
||||
|
||||
class TIME_MT_cache(Menu):
|
||||
|
@ -182,27 +182,14 @@ def marker_menu_generic(layout, context):
|
|||
# layout.operator_context = 'EXEC_REGION_WIN'
|
||||
|
||||
layout.column()
|
||||
layout.operator("marker.add", text="Add Marker")
|
||||
layout.operator("marker.duplicate", text="Duplicate Marker")
|
||||
|
||||
if len(bpy.data.scenes) > 10:
|
||||
layout.operator_context = 'INVOKE_DEFAULT'
|
||||
layout.operator("marker.make_links_scene", text="Duplicate Marker to Scene...", icon='OUTLINER_OB_EMPTY')
|
||||
else:
|
||||
layout.operator_menu_enum("marker.make_links_scene", "scene", text="Duplicate Marker to Scene")
|
||||
|
||||
layout.operator("marker.delete", text="Delete Marker")
|
||||
tool_settings = context.tool_settings
|
||||
layout.prop(tool_settings, "lock_markers")
|
||||
|
||||
layout.separator()
|
||||
|
||||
props = layout.operator("wm.call_panel", text="Rename Marker")
|
||||
props.name = "TOPBAR_PT_name_marker"
|
||||
props.keep_open = False
|
||||
layout.operator("marker.move", text="Move Marker")
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.menu('NLA_MT_marker_select')
|
||||
layout.operator("screen.marker_jump", text="Jump to Previous Marker").next = False
|
||||
layout.operator("screen.marker_jump", text="Jump to Next Marker").next = True
|
||||
|
||||
layout.separator()
|
||||
|
||||
|
@ -210,12 +197,28 @@ def marker_menu_generic(layout, context):
|
|||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("screen.marker_jump", text="Jump to Next Marker").next = True
|
||||
layout.operator("screen.marker_jump", text="Jump to Previous Marker").next = False
|
||||
layout.menu('NLA_MT_marker_select')
|
||||
|
||||
layout.separator()
|
||||
tool_settings = context.tool_settings
|
||||
layout.prop(tool_settings, "lock_markers")
|
||||
|
||||
layout.operator("marker.move", text="Move Marker")
|
||||
props = layout.operator("wm.call_panel", text="Rename Marker")
|
||||
props.name = "TOPBAR_PT_name_marker"
|
||||
props.keep_open = False
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("marker.delete", text="Delete Marker")
|
||||
|
||||
if len(bpy.data.scenes) > 10:
|
||||
layout.operator_context = 'INVOKE_DEFAULT'
|
||||
layout.operator("marker.make_links_scene", text="Duplicate Marker to Scene...", icon='OUTLINER_OB_EMPTY')
|
||||
else:
|
||||
layout.operator_menu_enum("marker.make_links_scene", "scene", text="Duplicate Marker to Scene")
|
||||
|
||||
layout.operator("marker.duplicate", text="Duplicate Marker")
|
||||
layout.operator("marker.add", text="Add Marker")
|
||||
|
||||
|
||||
###################################
|
||||
|
||||
|
|
|
@ -923,23 +923,23 @@ class USERPREF_PT_theme_interface_state(ThemePanel, CenterAlignMixIn, Panel):
|
|||
|
||||
col = flow.column(align=True)
|
||||
col.prop(ui_state, "inner_anim")
|
||||
col.prop(ui_state, "inner_anim_sel")
|
||||
col.prop(ui_state, "inner_anim_sel", text="Selected")
|
||||
|
||||
col = flow.column(align=True)
|
||||
col.prop(ui_state, "inner_driven")
|
||||
col.prop(ui_state, "inner_driven_sel")
|
||||
col.prop(ui_state, "inner_driven_sel", text="Selected")
|
||||
|
||||
col = flow.column(align=True)
|
||||
col.prop(ui_state, "inner_key")
|
||||
col.prop(ui_state, "inner_key_sel")
|
||||
col.prop(ui_state, "inner_key_sel", text="Selected")
|
||||
|
||||
col = flow.column(align=True)
|
||||
col.prop(ui_state, "inner_overridden")
|
||||
col.prop(ui_state, "inner_overridden_sel")
|
||||
col.prop(ui_state, "inner_overridden_sel", text="Selected")
|
||||
|
||||
col = flow.column(align=True)
|
||||
col.prop(ui_state, "inner_changed")
|
||||
col.prop(ui_state, "inner_changed_sel")
|
||||
col.prop(ui_state, "inner_changed_sel", text="Selected")
|
||||
|
||||
col = flow.column(align=True)
|
||||
col.prop(ui_state, "blend")
|
||||
|
@ -956,14 +956,19 @@ class USERPREF_PT_theme_interface_styles(ThemePanel, CenterAlignMixIn, Panel):
|
|||
|
||||
flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False)
|
||||
|
||||
flow.prop(ui, "menu_shadow_fac")
|
||||
flow.prop(ui, "menu_shadow_width")
|
||||
flow.prop(ui, "icon_alpha")
|
||||
flow.prop(ui, "icon_saturation")
|
||||
flow.prop(ui, "editor_outline")
|
||||
flow.prop(ui, "widget_text_cursor")
|
||||
flow.prop(ui, "widget_emboss")
|
||||
flow.prop(ui, "panel_roundness")
|
||||
col = flow.column(align=True)
|
||||
col.prop(ui, "menu_shadow_fac")
|
||||
col.prop(ui, "menu_shadow_width", text="Shadow Width")
|
||||
|
||||
col = flow.column(align=True)
|
||||
col.prop(ui, "icon_alpha")
|
||||
col.prop(ui, "icon_saturation", text="Saturation")
|
||||
|
||||
col = flow.column()
|
||||
col.prop(ui, "widget_text_cursor")
|
||||
col.prop(ui, "editor_outline")
|
||||
col.prop(ui, "widget_emboss")
|
||||
col.prop(ui, "panel_roundness")
|
||||
|
||||
|
||||
class USERPREF_PT_theme_interface_transparent_checker(ThemePanel, CenterAlignMixIn, Panel):
|
||||
|
@ -978,9 +983,12 @@ class USERPREF_PT_theme_interface_transparent_checker(ThemePanel, CenterAlignMix
|
|||
flow = layout.grid_flow(
|
||||
row_major=False, columns=0, even_columns=True, even_rows=False, align=False)
|
||||
|
||||
flow.prop(ui, "transparent_checker_primary")
|
||||
flow.prop(ui, "transparent_checker_secondary")
|
||||
flow.prop(ui, "transparent_checker_size")
|
||||
col = flow.column(align=True)
|
||||
col.prop(ui, "transparent_checker_primary")
|
||||
col.prop(ui, "transparent_checker_secondary")
|
||||
|
||||
col = flow.column()
|
||||
col.prop(ui, "transparent_checker_size")
|
||||
|
||||
|
||||
class USERPREF_PT_theme_interface_gizmos(ThemePanel, CenterAlignMixIn, Panel):
|
||||
|
@ -1001,12 +1009,12 @@ class USERPREF_PT_theme_interface_gizmos(ThemePanel, CenterAlignMixIn, Panel):
|
|||
|
||||
col = flow.column()
|
||||
col.prop(ui, "gizmo_primary")
|
||||
col.prop(ui, "gizmo_secondary")
|
||||
col.prop(ui, "gizmo_view_align")
|
||||
col.prop(ui, "gizmo_secondary", text="Secondary")
|
||||
col.prop(ui, "gizmo_view_align", text="View Align")
|
||||
|
||||
col = flow.column()
|
||||
col.prop(ui, "gizmo_a")
|
||||
col.prop(ui, "gizmo_b")
|
||||
col.prop(ui, "gizmo_b", text="B")
|
||||
|
||||
|
||||
class USERPREF_PT_theme_interface_icons(ThemePanel, CenterAlignMixIn, Panel):
|
||||
|
@ -1037,7 +1045,7 @@ class USERPREF_PT_theme_text_style(ThemePanel, CenterAlignMixIn, Panel):
|
|||
@staticmethod
|
||||
def _ui_font_style(layout, font_style):
|
||||
layout.use_property_split = True
|
||||
flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=True)
|
||||
flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False)
|
||||
|
||||
col = flow.column()
|
||||
col.prop(font_style, "points")
|
||||
|
@ -1046,10 +1054,10 @@ class USERPREF_PT_theme_text_style(ThemePanel, CenterAlignMixIn, Panel):
|
|||
col.prop(font_style, "shadow_offset_x", text="Shadow Offset X")
|
||||
col.prop(font_style, "shadow_offset_y", text="Y")
|
||||
|
||||
col = flow.column()
|
||||
col = flow.column(align=True)
|
||||
col.prop(font_style, "shadow")
|
||||
col.prop(font_style, "shadow_alpha")
|
||||
col.prop(font_style, "shadow_value")
|
||||
col.prop(font_style, "shadow_alpha", text="Alpha")
|
||||
col.prop(font_style, "shadow_value", text="Brightness")
|
||||
|
||||
def draw_header(self, _context):
|
||||
layout = self.layout
|
||||
|
@ -1090,10 +1098,10 @@ class USERPREF_PT_theme_bone_color_sets(ThemePanel, CenterAlignMixIn, Panel):
|
|||
for i, ui in enumerate(theme.bone_color_sets, 1):
|
||||
layout.label(text=iface_("Color Set %d") % i, translate=False)
|
||||
|
||||
flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False)
|
||||
flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=True)
|
||||
|
||||
flow.prop(ui, "normal")
|
||||
flow.prop(ui, "select")
|
||||
flow.prop(ui, "select", text="Selected")
|
||||
flow.prop(ui, "active")
|
||||
flow.prop(ui, "show_colored_constraints")
|
||||
|
||||
|
@ -1112,7 +1120,7 @@ class USERPREF_PT_theme_collection_colors(ThemePanel, CenterAlignMixIn, Panel):
|
|||
|
||||
layout.use_property_split = True
|
||||
|
||||
flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False)
|
||||
flow = layout.grid_flow(row_major=False, columns=2, even_columns=True, even_rows=False, align=False)
|
||||
for i, ui in enumerate(theme.collection_color, 1):
|
||||
flow.prop(ui, "color", text=iface_("Color %d") % i, translate=False)
|
||||
|
||||
|
@ -1131,7 +1139,7 @@ class USERPREF_PT_theme_strip_colors(ThemePanel, CenterAlignMixIn, Panel):
|
|||
|
||||
layout.use_property_split = True
|
||||
|
||||
flow = layout.grid_flow(row_major=False, columns=0, even_columns=True, even_rows=False, align=False)
|
||||
flow = layout.grid_flow(row_major=False, columns=2, even_columns=True, even_rows=False, align=False)
|
||||
for i, ui in enumerate(theme.strip_color, 1):
|
||||
flow.prop(ui, "color", text=iface_("Color %d") % i, translate=False)
|
||||
|
||||
|
@ -1217,28 +1225,28 @@ class ThemeGenericClassGenerator:
|
|||
@staticmethod
|
||||
def generate_panel_classes_for_wcols():
|
||||
wcols = [
|
||||
("Box", "wcol_box"),
|
||||
("List Item", "wcol_list_item"),
|
||||
("Menu", "wcol_menu"),
|
||||
("Menu Background", "wcol_menu_back"),
|
||||
("Menu Item", "wcol_menu_item"),
|
||||
("Number Field", "wcol_num"),
|
||||
("Option", "wcol_option"),
|
||||
("Pie Menu", "wcol_pie_menu"),
|
||||
("Progress Bar", "wcol_progress"),
|
||||
("Pulldown", "wcol_pulldown"),
|
||||
("Radio Buttons", "wcol_radio"),
|
||||
("Regular", "wcol_regular"),
|
||||
("Scroll Bar", "wcol_scroll"),
|
||||
("Tab", "wcol_tab"),
|
||||
("Text", "wcol_text"),
|
||||
("Toggle", "wcol_toggle"),
|
||||
("Tool", "wcol_tool"),
|
||||
("Toolbar Item", "wcol_toolbar_item"),
|
||||
("Radio Buttons", "wcol_radio"),
|
||||
("Text", "wcol_text"),
|
||||
("Option", "wcol_option"),
|
||||
("Toggle", "wcol_toggle"),
|
||||
("Number Field", "wcol_num"),
|
||||
("Value Slider", "wcol_numslider"),
|
||||
("Box", "wcol_box"),
|
||||
("Menu", "wcol_menu"),
|
||||
("Pie Menu", "wcol_pie_menu"),
|
||||
("Pulldown", "wcol_pulldown"),
|
||||
("Menu Back", "wcol_menu_back"),
|
||||
("Tooltip", "wcol_tooltip"),
|
||||
("Menu Item", "wcol_menu_item"),
|
||||
("Scroll Bar", "wcol_scroll"),
|
||||
("Progress Bar", "wcol_progress"),
|
||||
("List Item", "wcol_list_item"),
|
||||
("Value Slider", "wcol_numslider"),
|
||||
# Not used yet, so hide this from the UI.
|
||||
# ("Data-View Item", "wcol_view_item"),
|
||||
("Tab", "wcol_tab"),
|
||||
]
|
||||
|
||||
for (name, wcol) in wcols:
|
||||
|
@ -2588,11 +2596,11 @@ classes = (
|
|||
|
||||
USERPREF_MT_interface_theme_presets,
|
||||
USERPREF_PT_theme,
|
||||
USERPREF_PT_theme_interface_gizmos,
|
||||
USERPREF_PT_theme_interface_icons,
|
||||
USERPREF_PT_theme_interface_state,
|
||||
USERPREF_PT_theme_interface_styles,
|
||||
USERPREF_PT_theme_interface_gizmos,
|
||||
USERPREF_PT_theme_interface_transparent_checker,
|
||||
USERPREF_PT_theme_interface_icons,
|
||||
USERPREF_PT_theme_text_style,
|
||||
USERPREF_PT_theme_bone_color_sets,
|
||||
USERPREF_PT_theme_collection_colors,
|
||||
|
|
|
@ -92,7 +92,7 @@ static void bonecoll_ensure_name_unique(bArmature *armature, BoneCollection *bco
|
|||
{
|
||||
BLI_uniquename(&armature->collections,
|
||||
bcoll,
|
||||
bcoll->name,
|
||||
"Bones",
|
||||
'.',
|
||||
offsetof(BoneCollection, name),
|
||||
sizeof(bcoll->name));
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include "BLI_string_ref.hh"
|
||||
#include "BLI_sub_frame.hh"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
namespace blender::bke::bake_paths {
|
||||
|
||||
struct MetaFile {
|
||||
SubFrame frame;
|
||||
std::string path;
|
||||
};
|
||||
|
||||
struct BakePath {
|
||||
/** Path to the directory containing the meta data per frame. */
|
||||
std::string meta_dir;
|
||||
/**
|
||||
* Path to the directory that contains the binary data. Could be shared between multiple bakes
|
||||
* to reduce memory consumption.
|
||||
*/
|
||||
std::string bdata_dir;
|
||||
/**
|
||||
* Folder that is allowed to be deleted when the bake is deleted and it doesn't contain anything
|
||||
* else. Typically, this contains the meta and bdata directories.
|
||||
*/
|
||||
std::optional<std::string> bake_dir;
|
||||
|
||||
static BakePath from_single_root(StringRefNull root_dir);
|
||||
};
|
||||
|
||||
std::string frame_to_file_name(const SubFrame &frame);
|
||||
std::optional<SubFrame> file_name_to_frame(const StringRefNull file_name);
|
||||
|
||||
Vector<MetaFile> find_sorted_meta_files(const StringRefNull meta_dir);
|
||||
|
||||
} // namespace blender::bke::bake_paths
|
|
@ -98,9 +98,6 @@ struct bContextStoreEntry {
|
|||
};
|
||||
|
||||
struct bContextStore {
|
||||
bContextStore *next = nullptr;
|
||||
bContextStore *prev = nullptr;
|
||||
|
||||
blender::Vector<bContextStoreEntry> entries;
|
||||
bool used = false;
|
||||
};
|
||||
|
@ -152,17 +149,16 @@ bContext *CTX_copy(const bContext *C);
|
|||
|
||||
/* Stored Context */
|
||||
|
||||
bContextStore *CTX_store_add(ListBase *contexts,
|
||||
bContextStore *CTX_store_add(blender::Vector<std::unique_ptr<bContextStore>> &contexts,
|
||||
blender::StringRefNull name,
|
||||
const PointerRNA *ptr);
|
||||
bContextStore *CTX_store_add_all(ListBase *contexts, bContextStore *context);
|
||||
bContextStore *CTX_store_get(bContext *C);
|
||||
void CTX_store_set(bContext *C, bContextStore *store);
|
||||
bContextStore *CTX_store_add_all(blender::Vector<std::unique_ptr<bContextStore>> &contexts,
|
||||
const bContextStore *context);
|
||||
const bContextStore *CTX_store_get(const bContext *C);
|
||||
void CTX_store_set(bContext *C, const bContextStore *store);
|
||||
const PointerRNA *CTX_store_ptr_lookup(const bContextStore *store,
|
||||
blender::StringRefNull name,
|
||||
const StructRNA *type = nullptr);
|
||||
bContextStore *CTX_store_copy(const bContextStore *store);
|
||||
void CTX_store_free(bContextStore *store);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -235,6 +235,11 @@ void BKE_lib_override_library_main_hierarchy_root_ensure(Main *bmain);
|
|||
* \param view_layer: the active view layer to search instantiated collections in, can be NULL (in
|
||||
* which case \a scene's master collection children hierarchy is used instead).
|
||||
* \param id_root: The root liboverride ID to resync from.
|
||||
* \param do_hierarchy_enforce: If `true`, enforce the liboverride hierarchy of dependencies to
|
||||
* match the one from the reference linked data (i.e. if some manually
|
||||
* override were applied to some ID pointers, they will be reset to
|
||||
* the default reference value).
|
||||
*
|
||||
* \return true if override was successfully resynced.
|
||||
*/
|
||||
bool BKE_lib_override_library_resync(Main *bmain,
|
||||
|
|
|
@ -321,16 +321,10 @@ void BKE_mesh_recalc_looptri(const int *corner_verts,
|
|||
|
||||
/* *** mesh_normals.cc *** */
|
||||
|
||||
/**
|
||||
* Return true if the mesh vertex normals either are not stored or are dirty.
|
||||
* This can be used to help decide whether to transfer them when copying a mesh.
|
||||
*/
|
||||
/** Return true if the mesh vertex normals either are not stored or are dirty. */
|
||||
bool BKE_mesh_vert_normals_are_dirty(const struct Mesh *mesh);
|
||||
|
||||
/**
|
||||
* Return true if the mesh face normals either are not stored or are dirty.
|
||||
* This can be used to help decide whether to transfer them when copying a mesh.
|
||||
*/
|
||||
/** Return true if the mesh face normals either are not stored or are dirty. */
|
||||
bool BKE_mesh_face_normals_are_dirty(const struct Mesh *mesh);
|
||||
|
||||
/**
|
||||
|
|
|
@ -288,7 +288,7 @@ class bNodeRuntime : NonCopyable, NonMovable {
|
|||
/** Update flags. */
|
||||
int update = 0;
|
||||
|
||||
/** Offset that will be added to locx for insert offset animation. */
|
||||
/** Offset that will be added to #bNote::locx for insert offset animation. */
|
||||
float anim_ofsx;
|
||||
|
||||
/** List of cached internal links (input to output), for muted nodes and operators. */
|
||||
|
|
|
@ -210,7 +210,7 @@ void BKE_pbvh_build_grids(PBVH *pbvh,
|
|||
CCGElem **grids,
|
||||
int totgrid,
|
||||
CCGKey *key,
|
||||
void **gridfaces,
|
||||
blender::Span<int> grid_to_face_map,
|
||||
DMFlagMat *flagmats,
|
||||
unsigned int **grid_hidden,
|
||||
Mesh *me,
|
||||
|
@ -445,7 +445,7 @@ void BKE_pbvh_redraw_BB(PBVH *pbvh, float bb_min[3], float bb_max[3]);
|
|||
void BKE_pbvh_get_grid_updates(PBVH *pbvh, bool clear, void ***r_gridfaces, int *r_totface);
|
||||
void BKE_pbvh_grids_update(PBVH *pbvh,
|
||||
CCGElem **grids,
|
||||
void **gridfaces,
|
||||
blender::Span<int> grid_to_face_map,
|
||||
DMFlagMat *flagmats,
|
||||
unsigned int **grid_hidden,
|
||||
CCGKey *key);
|
||||
|
|
|
@ -417,6 +417,12 @@ typedef struct MenuType {
|
|||
void (*draw)(const struct bContext *C, struct Menu *menu);
|
||||
void (*listener)(const wmRegionListenerParams *params);
|
||||
|
||||
/**
|
||||
* True if the menu depends on data retrieved via #CTX_data_pointer_get. If it is context
|
||||
* dependent, menu search has to scan it in different contexts.
|
||||
*/
|
||||
bool context_dependent;
|
||||
|
||||
/* RNA integration */
|
||||
ExtensionRNA rna_ext;
|
||||
} MenuType;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "BKE_bake_items_paths.hh"
|
||||
#include "BKE_bake_items_serialize.hh"
|
||||
#include "BKE_geometry_set.hh"
|
||||
|
||||
|
@ -11,65 +12,11 @@
|
|||
#include "BLI_sub_frame.hh"
|
||||
|
||||
struct bNodeTree;
|
||||
struct NodesModifierData;
|
||||
struct Main;
|
||||
|
||||
namespace blender::bke::sim {
|
||||
|
||||
class ModifierSimulationCache;
|
||||
|
||||
/**
|
||||
* Storage of values for a single simulation input and output node pair.
|
||||
* Used as a cache to allow random access in time, and as an intermediate form before data is
|
||||
* baked.
|
||||
*/
|
||||
class SimulationZoneState {
|
||||
public:
|
||||
Map<int, std::unique_ptr<BakeItem>> item_by_identifier;
|
||||
};
|
||||
|
||||
/** Identifies a simulation zone (input and output node pair) used by a modifier. */
|
||||
struct SimulationZoneID {
|
||||
/** ID of the #bNestedNodeRef that references the output node of the zone. */
|
||||
int32_t nested_node_id;
|
||||
|
||||
uint64_t hash() const
|
||||
{
|
||||
return this->nested_node_id;
|
||||
}
|
||||
|
||||
friend bool operator==(const SimulationZoneID &a, const SimulationZoneID &b)
|
||||
{
|
||||
return a.nested_node_id == b.nested_node_id;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Stores a single frame of simulation states for all simulation zones in a modifier's node
|
||||
* hierarchy.
|
||||
*/
|
||||
class ModifierSimulationState {
|
||||
private:
|
||||
mutable bool bake_loaded_;
|
||||
|
||||
public:
|
||||
ModifierSimulationCache *owner_;
|
||||
mutable std::mutex mutex_;
|
||||
Map<SimulationZoneID, std::unique_ptr<SimulationZoneState>> zone_states_;
|
||||
/** File path to folder containing baked meta-data. */
|
||||
std::optional<std::string> meta_path_;
|
||||
/** File path to folder containing baked data. */
|
||||
std::optional<std::string> bdata_dir_;
|
||||
|
||||
SimulationZoneState *get_zone_state(const SimulationZoneID &zone_id);
|
||||
const SimulationZoneState *get_zone_state(const SimulationZoneID &zone_id) const;
|
||||
SimulationZoneState &get_zone_state_for_write(const SimulationZoneID &zone_id);
|
||||
void ensure_bake_loaded(const bNodeTree &ntree) const;
|
||||
};
|
||||
|
||||
struct ModifierSimulationStateAtFrame {
|
||||
SubFrame frame;
|
||||
ModifierSimulationState state;
|
||||
};
|
||||
|
||||
enum class CacheState {
|
||||
/** The cache is up-to-date with the inputs. */
|
||||
Valid,
|
||||
|
@ -82,56 +29,34 @@ enum class CacheState {
|
|||
Baked,
|
||||
};
|
||||
|
||||
struct StatesAroundFrame {
|
||||
const ModifierSimulationStateAtFrame *prev = nullptr;
|
||||
const ModifierSimulationStateAtFrame *current = nullptr;
|
||||
const ModifierSimulationStateAtFrame *next = nullptr;
|
||||
struct SimulationZoneFrameCache {
|
||||
SubFrame frame;
|
||||
Map<int, std::unique_ptr<BakeItem>> items;
|
||||
/** Used when the baked data is loaded lazily. */
|
||||
std::optional<std::string> meta_path;
|
||||
};
|
||||
|
||||
struct ModifierSimulationCacheRealtime {
|
||||
std::unique_ptr<ModifierSimulationState> prev_state;
|
||||
std::unique_ptr<ModifierSimulationState> current_state;
|
||||
SubFrame prev_frame;
|
||||
SubFrame current_frame;
|
||||
struct SimulationZonePrevState {
|
||||
Map<int, std::unique_ptr<BakeItem>> items;
|
||||
SubFrame frame;
|
||||
};
|
||||
|
||||
struct SimulationZoneCache {
|
||||
Vector<std::unique_ptr<SimulationZoneFrameCache>> frame_caches;
|
||||
std::optional<SimulationZonePrevState> prev_state;
|
||||
|
||||
std::optional<std::string> bdata_dir;
|
||||
std::unique_ptr<BDataSharing> bdata_sharing;
|
||||
bool failed_finding_bake = false;
|
||||
CacheState cache_state = CacheState::Valid;
|
||||
|
||||
void reset();
|
||||
};
|
||||
|
||||
class ModifierSimulationCache {
|
||||
private:
|
||||
mutable std::mutex states_at_frames_mutex_;
|
||||
/**
|
||||
* All simulation states, sorted by frame.
|
||||
*/
|
||||
Vector<std::unique_ptr<ModifierSimulationStateAtFrame>> states_at_frames_;
|
||||
/**
|
||||
* Used for baking to deduplicate arrays when writing and writing from storage. Sharing info
|
||||
* must be kept alive for multiple frames to detect if each data array's version has changed.
|
||||
*/
|
||||
std::unique_ptr<BDataSharing> bdata_sharing_;
|
||||
|
||||
friend ModifierSimulationState;
|
||||
|
||||
bool failed_finding_bake_ = false;
|
||||
|
||||
public:
|
||||
CacheState cache_state = CacheState::Valid;
|
||||
|
||||
/** A non-persistent cache used only to pass simulation state data from one frame to the next. */
|
||||
ModifierSimulationCacheRealtime realtime_cache;
|
||||
|
||||
void try_discover_bake(StringRefNull absolute_bake_dir);
|
||||
|
||||
bool has_state_at_frame(const SubFrame &frame) const;
|
||||
bool has_states() const;
|
||||
const ModifierSimulationState *get_state_at_exact_frame(const SubFrame &frame) const;
|
||||
ModifierSimulationState &get_state_at_frame_for_write(const SubFrame &frame);
|
||||
StatesAroundFrame get_states_around_frame(const SubFrame &frame) const;
|
||||
|
||||
void invalidate()
|
||||
{
|
||||
this->cache_state = CacheState::Invalid;
|
||||
}
|
||||
|
||||
void reset();
|
||||
mutable std::mutex mutex;
|
||||
Map<int, std::unique_ptr<SimulationZoneCache>> cache_by_zone_id;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -140,4 +65,12 @@ class ModifierSimulationCache {
|
|||
*/
|
||||
void scene_simulation_states_reset(Scene &scene);
|
||||
|
||||
std::optional<bake_paths::BakePath> get_simulation_zone_bake_path(const Main &bmain,
|
||||
const Object &object,
|
||||
const NodesModifierData &nmd,
|
||||
int zone_id);
|
||||
std::optional<std::string> get_modifier_simulation_bake_path(const Main &bmain,
|
||||
const Object &object,
|
||||
const NodesModifierData &nmd);
|
||||
|
||||
} // namespace blender::bke::sim
|
||||
|
|
|
@ -29,22 +29,6 @@ std::string get_default_modifier_bake_directory(const Main &bmain,
|
|||
const Object &object,
|
||||
const ModifierData &md);
|
||||
|
||||
/**
|
||||
* Encode the simulation state in a #DictionaryValue which also contains references to external
|
||||
* binary data that has been written using #bdata_writer.
|
||||
*/
|
||||
void serialize_modifier_simulation_state(const ModifierSimulationState &state,
|
||||
BDataWriter &bdata_writer,
|
||||
BDataSharing &bdata_sharing,
|
||||
DictionaryValue &r_io_root);
|
||||
/**
|
||||
* Fill the simulation state by parsing the provided #DictionaryValue which also contains
|
||||
* references to external binary data that is read using #bdata_reader.
|
||||
*/
|
||||
void deserialize_modifier_simulation_state(const bNodeTree &ntree,
|
||||
const DictionaryValue &io_root,
|
||||
const BDataReader &bdata_reader,
|
||||
const BDataSharing &bdata_sharing,
|
||||
ModifierSimulationState &r_state);
|
||||
constexpr int simulation_file_storage_version = 3;
|
||||
|
||||
} // namespace blender::bke::sim
|
||||
|
|
|
@ -160,7 +160,7 @@ struct SubdivCCG {
|
|||
int num_faces = -1;
|
||||
SubdivCCGFace *faces = nullptr;
|
||||
/* Indexed by grid index, points to corresponding face from `faces`. */
|
||||
SubdivCCGFace **grid_faces = nullptr;
|
||||
blender::Array<int> grid_to_face_map;
|
||||
|
||||
/* Edges which are adjacent to faces.
|
||||
* Used for faster grid stitching, in the cost of extra memory.
|
||||
|
|
|
@ -73,6 +73,7 @@ set(SRC
|
|||
intern/attribute_math.cc
|
||||
intern/autoexec.cc
|
||||
intern/bake_items.cc
|
||||
intern/bake_items_paths.cc
|
||||
intern/bake_items_serialize.cc
|
||||
intern/bake_items_socket.cc
|
||||
intern/blender.cc
|
||||
|
@ -333,6 +334,7 @@ set(SRC
|
|||
BKE_attribute_math.hh
|
||||
BKE_autoexec.h
|
||||
BKE_bake_items.hh
|
||||
BKE_bake_items_paths.hh
|
||||
BKE_bake_items_serialize.hh
|
||||
BKE_bake_items_socket.hh
|
||||
BKE_blender.h
|
||||
|
|
|
@ -87,6 +87,7 @@ static void armature_init_data(ID *id)
|
|||
/* Give the Armature its default bone collection. */
|
||||
BoneCollection *default_bonecoll = ANIM_bonecoll_new("");
|
||||
BLI_addhead(&armature->collections, default_bonecoll);
|
||||
ANIM_armature_bonecoll_active_set(armature, default_bonecoll);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
/* SPDX-FileCopyrightText: 2023 Blender Foundation
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "BKE_bake_items_paths.hh"
|
||||
|
||||
#include "BLI_fileops.hh"
|
||||
#include "BLI_path_util.h"
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_string_utils.h"
|
||||
|
||||
namespace blender::bke::bake_paths {
|
||||
|
||||
std::string frame_to_file_name(const SubFrame &frame)
|
||||
{
|
||||
char file_name_c[FILE_MAX];
|
||||
SNPRINTF(file_name_c, "%011.5f", double(frame));
|
||||
BLI_string_replace_char(file_name_c, '.', '_');
|
||||
return file_name_c;
|
||||
}
|
||||
|
||||
std::optional<SubFrame> file_name_to_frame(const StringRefNull file_name)
|
||||
{
|
||||
char modified_file_name[FILE_MAX];
|
||||
STRNCPY(modified_file_name, file_name.c_str());
|
||||
BLI_string_replace_char(modified_file_name, '_', '.');
|
||||
const SubFrame frame = std::stof(modified_file_name);
|
||||
return frame;
|
||||
}
|
||||
|
||||
Vector<MetaFile> find_sorted_meta_files(const StringRefNull meta_dir)
|
||||
{
|
||||
if (!BLI_is_dir(meta_dir.c_str())) {
|
||||
return {};
|
||||
}
|
||||
|
||||
direntry *dir_entries = nullptr;
|
||||
const int dir_entries_num = BLI_filelist_dir_contents(meta_dir.c_str(), &dir_entries);
|
||||
BLI_SCOPED_DEFER([&]() { BLI_filelist_free(dir_entries, dir_entries_num); });
|
||||
|
||||
Vector<MetaFile> meta_files;
|
||||
for (const int i : IndexRange(dir_entries_num)) {
|
||||
const direntry &dir_entry = dir_entries[i];
|
||||
const StringRefNull dir_entry_path = dir_entry.path;
|
||||
if (!dir_entry_path.endswith(".json")) {
|
||||
continue;
|
||||
}
|
||||
const std::optional<SubFrame> frame = file_name_to_frame(dir_entry.relname);
|
||||
if (!frame) {
|
||||
continue;
|
||||
}
|
||||
meta_files.append({*frame, dir_entry_path});
|
||||
}
|
||||
|
||||
std::sort(meta_files.begin(), meta_files.end(), [](const MetaFile &a, const MetaFile &b) {
|
||||
return a.frame < b.frame;
|
||||
});
|
||||
|
||||
return meta_files;
|
||||
}
|
||||
|
||||
BakePath BakePath::from_single_root(StringRefNull root_dir)
|
||||
{
|
||||
char meta_dir[FILE_MAX];
|
||||
BLI_path_join(meta_dir, sizeof(meta_dir), root_dir.c_str(), "meta");
|
||||
char bdata_dir[FILE_MAX];
|
||||
BLI_path_join(bdata_dir, sizeof(bdata_dir), root_dir.c_str(), "bdata");
|
||||
|
||||
BakePath bake_path;
|
||||
bake_path.meta_dir = meta_dir;
|
||||
bake_path.bdata_dir = bdata_dir;
|
||||
bake_path.bake_dir = root_dir;
|
||||
return bake_path;
|
||||
}
|
||||
|
||||
} // namespace blender::bke::bake_paths
|
|
@ -68,7 +68,7 @@ struct bContext {
|
|||
ARegion *region;
|
||||
ARegion *menu;
|
||||
wmGizmoGroup *gizmo_group;
|
||||
bContextStore *store;
|
||||
const bContextStore *store;
|
||||
|
||||
/* Operator poll. */
|
||||
/**
|
||||
|
@ -128,60 +128,51 @@ void CTX_free(bContext *C)
|
|||
|
||||
/* store */
|
||||
|
||||
bContextStore *CTX_store_add(ListBase *contexts,
|
||||
bContextStore *CTX_store_add(blender::Vector<std::unique_ptr<bContextStore>> &contexts,
|
||||
const blender::StringRefNull name,
|
||||
const PointerRNA *ptr)
|
||||
{
|
||||
/* ensure we have a context to put the entry in, if it was already used
|
||||
* we have to copy the context to ensure */
|
||||
bContextStore *ctx = static_cast<bContextStore *>(contexts->last);
|
||||
|
||||
if (!ctx || ctx->used) {
|
||||
if (ctx) {
|
||||
ctx = MEM_new<bContextStore>(__func__, *ctx);
|
||||
}
|
||||
else {
|
||||
ctx = MEM_new<bContextStore>(__func__);
|
||||
}
|
||||
|
||||
BLI_addtail(contexts, ctx);
|
||||
if (contexts.is_empty()) {
|
||||
contexts.append(std::make_unique<bContextStore>());
|
||||
}
|
||||
else if (contexts.last()->used) {
|
||||
auto new_ctx = std::make_unique<bContextStore>(bContextStore{contexts.last()->entries, false});
|
||||
contexts.append(std::move(new_ctx));
|
||||
}
|
||||
|
||||
bContextStore *ctx = contexts.last().get();
|
||||
ctx->entries.append(bContextStoreEntry{name, *ptr});
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
bContextStore *CTX_store_add_all(ListBase *contexts, bContextStore *context)
|
||||
bContextStore *CTX_store_add_all(blender::Vector<std::unique_ptr<bContextStore>> &contexts,
|
||||
const bContextStore *context)
|
||||
{
|
||||
/* ensure we have a context to put the entries in, if it was already used
|
||||
/* ensure we have a context to put the entry in, if it was already used
|
||||
* we have to copy the context to ensure */
|
||||
bContextStore *ctx = static_cast<bContextStore *>(contexts->last);
|
||||
|
||||
if (!ctx || ctx->used) {
|
||||
if (ctx) {
|
||||
ctx = MEM_new<bContextStore>(__func__, *ctx);
|
||||
}
|
||||
else {
|
||||
ctx = MEM_new<bContextStore>(__func__);
|
||||
}
|
||||
|
||||
BLI_addtail(contexts, ctx);
|
||||
if (contexts.is_empty()) {
|
||||
contexts.append(std::make_unique<bContextStore>());
|
||||
}
|
||||
else if (contexts.last()->used) {
|
||||
auto new_ctx = std::make_unique<bContextStore>(bContextStore{contexts.last()->entries, false});
|
||||
contexts.append(std::move(new_ctx));
|
||||
}
|
||||
|
||||
bContextStore *ctx = contexts.last().get();
|
||||
for (const bContextStoreEntry &src_entry : context->entries) {
|
||||
ctx->entries.append(src_entry);
|
||||
}
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
bContextStore *CTX_store_get(bContext *C)
|
||||
const bContextStore *CTX_store_get(const bContext *C)
|
||||
{
|
||||
return C->wm.store;
|
||||
}
|
||||
|
||||
void CTX_store_set(bContext *C, bContextStore *store)
|
||||
void CTX_store_set(bContext *C, const bContextStore *store)
|
||||
{
|
||||
C->wm.store = store;
|
||||
}
|
||||
|
@ -200,16 +191,6 @@ const PointerRNA *CTX_store_ptr_lookup(const bContextStore *store,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
bContextStore *CTX_store_copy(const bContextStore *store)
|
||||
{
|
||||
return MEM_new<bContextStore>(__func__, *store);
|
||||
}
|
||||
|
||||
void CTX_store_free(bContextStore *store)
|
||||
{
|
||||
MEM_delete(store);
|
||||
}
|
||||
|
||||
/* is python initialized? */
|
||||
|
||||
bool CTX_py_init_get(bContext *C)
|
||||
|
|
|
@ -1058,9 +1058,6 @@ Mesh *BKE_mesh_new_nomain_from_template_ex(const Mesh *me_src,
|
|||
CustomData_add_layer(&me_dst->fdata_legacy, CD_MFACE, CD_SET_DEFAULT, me_dst->totface_legacy);
|
||||
}
|
||||
|
||||
/* Expect that normals aren't copied at all, since the destination mesh is new. */
|
||||
BLI_assert(BKE_mesh_vert_normals_are_dirty(me_dst));
|
||||
|
||||
return me_dst;
|
||||
}
|
||||
|
||||
|
|
|
@ -758,7 +758,7 @@ int bNodeTreeInterfacePanel::find_valid_insert_position_for_item(
|
|||
break;
|
||||
}
|
||||
if (items[test_pos]->item_type == NODE_INTERFACE_PANEL) {
|
||||
/* Found valid position, insering moves the first panel. */
|
||||
/* Found valid position, inserting moves the first panel. */
|
||||
pos = test_pos;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -2215,7 +2215,7 @@ static PBVH *build_pbvh_from_ccg(Object *ob, SubdivCCG *subdiv_ccg)
|
|||
subdiv_ccg->grids,
|
||||
subdiv_ccg->num_grids,
|
||||
&key,
|
||||
(void **)subdiv_ccg->grid_faces,
|
||||
subdiv_ccg->grid_to_face_map,
|
||||
subdiv_ccg->grid_flag_mats,
|
||||
subdiv_ccg->grid_hidden,
|
||||
base_mesh,
|
||||
|
@ -2304,7 +2304,7 @@ void BKE_sculpt_bvh_update_from_ccg(PBVH *pbvh, SubdivCCG *subdiv_ccg)
|
|||
|
||||
BKE_pbvh_grids_update(pbvh,
|
||||
subdiv_ccg->grids,
|
||||
(void **)subdiv_ccg->grid_faces,
|
||||
subdiv_ccg->grid_to_face_map,
|
||||
subdiv_ccg->grid_flag_mats,
|
||||
subdiv_ccg->grid_hidden,
|
||||
&key);
|
||||
|
|
|
@ -914,7 +914,7 @@ void BKE_pbvh_build_grids(PBVH *pbvh,
|
|||
CCGElem **grids,
|
||||
int totgrid,
|
||||
CCGKey *key,
|
||||
void **gridfaces,
|
||||
blender::Span<int> grid_to_face_map,
|
||||
DMFlagMat *flagmats,
|
||||
BLI_bitmap **grid_hidden,
|
||||
Mesh *me,
|
||||
|
@ -924,7 +924,7 @@ void BKE_pbvh_build_grids(PBVH *pbvh,
|
|||
|
||||
pbvh->header.type = PBVH_GRIDS;
|
||||
pbvh->grids = grids;
|
||||
pbvh->gridfaces = gridfaces;
|
||||
pbvh->grid_to_face_map = grid_to_face_map;
|
||||
pbvh->grid_flag_mats = flagmats;
|
||||
pbvh->totgrid = totgrid;
|
||||
pbvh->gridkey = *key;
|
||||
|
@ -1715,10 +1715,11 @@ void BKE_pbvh_get_grid_updates(PBVH *pbvh, bool clear, void ***r_gridfaces, int
|
|||
|
||||
pbvh_iter_begin(&iter, pbvh, {});
|
||||
|
||||
SubdivCCGFace *all_faces = pbvh->subdiv_ccg->faces;
|
||||
while ((node = pbvh_iter_next(&iter, PBVH_Leaf))) {
|
||||
if (node->flag & PBVH_UpdateNormals) {
|
||||
for (const int grid : node->prim_indices) {
|
||||
void *face = pbvh->gridfaces[grid];
|
||||
void *face = &all_faces[pbvh->grid_to_face_map[grid]];
|
||||
BLI_gset_add(face_set, face);
|
||||
}
|
||||
|
||||
|
@ -2944,14 +2945,14 @@ void BKE_pbvh_draw_debug_cb(PBVH *pbvh,
|
|||
|
||||
void BKE_pbvh_grids_update(PBVH *pbvh,
|
||||
CCGElem **grids,
|
||||
void **gridfaces,
|
||||
blender::Span<int> grid_to_face_map,
|
||||
DMFlagMat *flagmats,
|
||||
BLI_bitmap **grid_hidden,
|
||||
CCGKey *key)
|
||||
{
|
||||
pbvh->gridkey = *key;
|
||||
pbvh->grids = grids;
|
||||
pbvh->gridfaces = gridfaces;
|
||||
pbvh->grid_to_face_map = grid_to_face_map;
|
||||
|
||||
if (flagmats != pbvh->grid_flag_mats || pbvh->grid_hidden != grid_hidden) {
|
||||
pbvh->grid_flag_mats = flagmats;
|
||||
|
|
|
@ -175,7 +175,7 @@ struct PBVH {
|
|||
/* Grid Data */
|
||||
CCGKey gridkey;
|
||||
CCGElem **grids;
|
||||
void **gridfaces;
|
||||
blender::Span<int> grid_to_face_map;
|
||||
const DMFlagMat *grid_flag_mats;
|
||||
int totgrid;
|
||||
BLI_bitmap **grid_hidden;
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include "BKE_collection.h"
|
||||
#include "BKE_curves.hh"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_simulation_state.hh"
|
||||
#include "BKE_simulation_state_serialize.hh"
|
||||
|
||||
|
@ -21,213 +22,13 @@
|
|||
|
||||
namespace blender::bke::sim {
|
||||
|
||||
void ModifierSimulationCache::try_discover_bake(const StringRefNull absolute_bake_dir)
|
||||
void SimulationZoneCache::reset()
|
||||
{
|
||||
if (failed_finding_bake_) {
|
||||
return;
|
||||
}
|
||||
|
||||
char meta_dir[FILE_MAX];
|
||||
BLI_path_join(meta_dir, sizeof(meta_dir), absolute_bake_dir.c_str(), "meta");
|
||||
char bdata_dir[FILE_MAX];
|
||||
BLI_path_join(bdata_dir, sizeof(bdata_dir), absolute_bake_dir.c_str(), "bdata");
|
||||
|
||||
if (!BLI_is_dir(meta_dir) || !BLI_is_dir(bdata_dir)) {
|
||||
failed_finding_bake_ = true;
|
||||
return;
|
||||
}
|
||||
|
||||
direntry *dir_entries = nullptr;
|
||||
const int dir_entries_num = BLI_filelist_dir_contents(meta_dir, &dir_entries);
|
||||
BLI_SCOPED_DEFER([&]() { BLI_filelist_free(dir_entries, dir_entries_num); });
|
||||
|
||||
if (dir_entries_num == 0) {
|
||||
failed_finding_bake_ = true;
|
||||
return;
|
||||
}
|
||||
|
||||
this->reset();
|
||||
|
||||
{
|
||||
std::lock_guard lock(states_at_frames_mutex_);
|
||||
|
||||
for (const int i : IndexRange(dir_entries_num)) {
|
||||
const direntry &dir_entry = dir_entries[i];
|
||||
const StringRefNull dir_entry_path = dir_entry.path;
|
||||
if (!dir_entry_path.endswith(".json")) {
|
||||
continue;
|
||||
}
|
||||
char modified_file_name[FILE_MAX];
|
||||
STRNCPY(modified_file_name, dir_entry.relname);
|
||||
BLI_string_replace_char(modified_file_name, '_', '.');
|
||||
|
||||
const SubFrame frame = std::stof(modified_file_name);
|
||||
|
||||
auto new_state_at_frame = std::make_unique<ModifierSimulationStateAtFrame>();
|
||||
new_state_at_frame->frame = frame;
|
||||
new_state_at_frame->state.bdata_dir_ = bdata_dir;
|
||||
new_state_at_frame->state.meta_path_ = dir_entry.path;
|
||||
new_state_at_frame->state.owner_ = this;
|
||||
states_at_frames_.append(std::move(new_state_at_frame));
|
||||
}
|
||||
|
||||
bdata_sharing_ = std::make_unique<BDataSharing>();
|
||||
this->cache_state = CacheState::Baked;
|
||||
}
|
||||
}
|
||||
|
||||
static int64_t find_state_at_frame(
|
||||
const Span<std::unique_ptr<ModifierSimulationStateAtFrame>> states, const SubFrame &frame)
|
||||
{
|
||||
const int64_t i = binary_search::find_predicate_begin(
|
||||
states, [&](const auto &item) { return item->frame >= frame; });
|
||||
if (i == states.size()) {
|
||||
return -1;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
static int64_t find_state_at_frame_exact(
|
||||
const Span<std::unique_ptr<ModifierSimulationStateAtFrame>> states, const SubFrame &frame)
|
||||
{
|
||||
const int64_t i = find_state_at_frame(states, frame);
|
||||
if (i == -1) {
|
||||
return -1;
|
||||
}
|
||||
if (states[i]->frame != frame) {
|
||||
return -1;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
bool ModifierSimulationCache::has_state_at_frame(const SubFrame &frame) const
|
||||
{
|
||||
std::lock_guard lock(states_at_frames_mutex_);
|
||||
return find_state_at_frame_exact(states_at_frames_, frame) != -1;
|
||||
}
|
||||
|
||||
bool ModifierSimulationCache::has_states() const
|
||||
{
|
||||
std::lock_guard lock(states_at_frames_mutex_);
|
||||
return !states_at_frames_.is_empty();
|
||||
}
|
||||
|
||||
const ModifierSimulationState *ModifierSimulationCache::get_state_at_exact_frame(
|
||||
const SubFrame &frame) const
|
||||
{
|
||||
std::lock_guard lock(states_at_frames_mutex_);
|
||||
const int64_t i = find_state_at_frame_exact(states_at_frames_, frame);
|
||||
if (i == -1) {
|
||||
return nullptr;
|
||||
}
|
||||
return &states_at_frames_[i]->state;
|
||||
}
|
||||
|
||||
ModifierSimulationState &ModifierSimulationCache::get_state_at_frame_for_write(
|
||||
const SubFrame &frame)
|
||||
{
|
||||
std::lock_guard lock(states_at_frames_mutex_);
|
||||
const int64_t i = find_state_at_frame_exact(states_at_frames_, frame);
|
||||
if (i != -1) {
|
||||
return states_at_frames_[i]->state;
|
||||
}
|
||||
|
||||
if (!states_at_frames_.is_empty()) {
|
||||
BLI_assert(frame > states_at_frames_.last()->frame);
|
||||
}
|
||||
|
||||
states_at_frames_.append(std::make_unique<ModifierSimulationStateAtFrame>());
|
||||
states_at_frames_.last()->frame = frame;
|
||||
states_at_frames_.last()->state.owner_ = this;
|
||||
return states_at_frames_.last()->state;
|
||||
}
|
||||
|
||||
StatesAroundFrame ModifierSimulationCache::get_states_around_frame(const SubFrame &frame) const
|
||||
{
|
||||
std::lock_guard lock(states_at_frames_mutex_);
|
||||
const int64_t i = find_state_at_frame(states_at_frames_, frame);
|
||||
StatesAroundFrame states_around_frame{};
|
||||
if (i == -1) {
|
||||
if (!states_at_frames_.is_empty() && states_at_frames_.last()->frame < frame) {
|
||||
states_around_frame.prev = states_at_frames_.last().get();
|
||||
}
|
||||
return states_around_frame;
|
||||
}
|
||||
if (states_at_frames_[i]->frame == frame) {
|
||||
states_around_frame.current = states_at_frames_[i].get();
|
||||
}
|
||||
if (i > 0) {
|
||||
states_around_frame.prev = states_at_frames_[i - 1].get();
|
||||
}
|
||||
if (i < states_at_frames_.size() - 2) {
|
||||
states_around_frame.next = states_at_frames_[i + 1].get();
|
||||
}
|
||||
return states_around_frame;
|
||||
}
|
||||
|
||||
SimulationZoneState *ModifierSimulationState::get_zone_state(const SimulationZoneID &zone_id)
|
||||
{
|
||||
std::lock_guard lock{mutex_};
|
||||
if (auto *ptr = zone_states_.lookup_ptr(zone_id)) {
|
||||
return ptr->get();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const SimulationZoneState *ModifierSimulationState::get_zone_state(
|
||||
const SimulationZoneID &zone_id) const
|
||||
{
|
||||
std::lock_guard lock{mutex_};
|
||||
if (auto *ptr = zone_states_.lookup_ptr(zone_id)) {
|
||||
return ptr->get();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
SimulationZoneState &ModifierSimulationState::get_zone_state_for_write(
|
||||
const SimulationZoneID &zone_id)
|
||||
{
|
||||
std::lock_guard lock{mutex_};
|
||||
return *zone_states_.lookup_or_add_cb(zone_id,
|
||||
[]() { return std::make_unique<SimulationZoneState>(); });
|
||||
}
|
||||
|
||||
void ModifierSimulationState::ensure_bake_loaded(const bNodeTree &ntree) const
|
||||
{
|
||||
std::scoped_lock lock{mutex_};
|
||||
if (bake_loaded_) {
|
||||
return;
|
||||
}
|
||||
if (!meta_path_ || !bdata_dir_) {
|
||||
return;
|
||||
}
|
||||
|
||||
const std::shared_ptr<io::serialize::Value> io_root_value = io::serialize::read_json_file(
|
||||
*meta_path_);
|
||||
if (!io_root_value) {
|
||||
return;
|
||||
}
|
||||
const DictionaryValue *io_root = io_root_value->as_dictionary_value();
|
||||
if (!io_root) {
|
||||
return;
|
||||
}
|
||||
|
||||
const DiskBDataReader bdata_reader{*bdata_dir_};
|
||||
deserialize_modifier_simulation_state(ntree,
|
||||
*io_root,
|
||||
bdata_reader,
|
||||
*owner_->bdata_sharing_,
|
||||
const_cast<ModifierSimulationState &>(*this));
|
||||
bake_loaded_ = true;
|
||||
}
|
||||
|
||||
void ModifierSimulationCache::reset()
|
||||
{
|
||||
std::lock_guard lock(states_at_frames_mutex_);
|
||||
states_at_frames_.clear();
|
||||
bdata_sharing_.reset();
|
||||
this->realtime_cache.current_state.reset();
|
||||
this->realtime_cache.prev_state.reset();
|
||||
this->frame_caches.clear();
|
||||
this->prev_state.reset();
|
||||
this->bdata_dir.reset();
|
||||
this->bdata_sharing.reset();
|
||||
this->failed_finding_bake = false;
|
||||
this->cache_state = CacheState::Valid;
|
||||
}
|
||||
|
||||
|
@ -239,10 +40,52 @@ void scene_simulation_states_reset(Scene &scene)
|
|||
continue;
|
||||
}
|
||||
NodesModifierData *nmd = reinterpret_cast<NodesModifierData *>(md);
|
||||
nmd->runtime->simulation_cache->reset();
|
||||
if (!nmd->runtime->simulation_cache) {
|
||||
continue;
|
||||
}
|
||||
for (auto item : nmd->runtime->simulation_cache->cache_by_zone_id.items()) {
|
||||
item.value->reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
FOREACH_SCENE_OBJECT_END;
|
||||
}
|
||||
|
||||
std::optional<std::string> get_modifier_simulation_bake_path(const Main &bmain,
|
||||
const Object &object,
|
||||
const NodesModifierData &nmd)
|
||||
{
|
||||
const StringRefNull bmain_path = BKE_main_blendfile_path(&bmain);
|
||||
if (bmain_path.is_empty()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
if (StringRef(nmd.simulation_bake_directory).is_empty()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
const char *base_path = ID_BLEND_PATH(&bmain, &object.id);
|
||||
char absolute_bake_dir[FILE_MAX];
|
||||
STRNCPY(absolute_bake_dir, nmd.simulation_bake_directory);
|
||||
BLI_path_abs(absolute_bake_dir, base_path);
|
||||
return absolute_bake_dir;
|
||||
}
|
||||
|
||||
std::optional<bake_paths::BakePath> get_simulation_zone_bake_path(const Main &bmain,
|
||||
const Object &object,
|
||||
const NodesModifierData &nmd,
|
||||
int zone_id)
|
||||
{
|
||||
const std::optional<std::string> modifier_bake_path = get_modifier_simulation_bake_path(
|
||||
bmain, object, nmd);
|
||||
if (!modifier_bake_path) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
char zone_bake_dir[FILE_MAX];
|
||||
BLI_path_join(zone_bake_dir,
|
||||
sizeof(zone_bake_dir),
|
||||
modifier_bake_path->c_str(),
|
||||
std::to_string(zone_id).c_str());
|
||||
return bake_paths::BakePath::from_single_root(zone_bake_dir);
|
||||
}
|
||||
|
||||
} // namespace blender::bke::sim
|
||||
|
|
|
@ -83,111 +83,4 @@ std::string get_default_modifier_bake_directory(const Main &bmain,
|
|||
return dir;
|
||||
}
|
||||
|
||||
/**
|
||||
* Version written to the baked data.
|
||||
*/
|
||||
static constexpr int serialize_format_version = 2;
|
||||
|
||||
void serialize_modifier_simulation_state(const ModifierSimulationState &state,
|
||||
BDataWriter &bdata_writer,
|
||||
BDataSharing &bdata_sharing,
|
||||
DictionaryValue &r_io_root)
|
||||
{
|
||||
r_io_root.append_int("version", serialize_format_version);
|
||||
auto io_zones = r_io_root.append_array("zones");
|
||||
|
||||
for (const auto item : state.zone_states_.items()) {
|
||||
const SimulationZoneID &zone_id = item.key;
|
||||
const SimulationZoneState &zone_state = *item.value;
|
||||
|
||||
auto io_zone = io_zones->append_dict();
|
||||
|
||||
io_zone->append_int("state_id", zone_id.nested_node_id);
|
||||
|
||||
auto io_state_items = io_zone->append_array("state_items");
|
||||
for (const MapItem<int, std::unique_ptr<BakeItem>> &state_item_with_id :
|
||||
zone_state.item_by_identifier.items())
|
||||
{
|
||||
auto io_state_item = io_state_items->append_dict();
|
||||
|
||||
io_state_item->append_int("id", state_item_with_id.key);
|
||||
serialize_bake_item(*state_item_with_id.value, bdata_writer, bdata_sharing, *io_state_item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void deserialize_modifier_simulation_state(const bNodeTree &ntree,
|
||||
const DictionaryValue &io_root,
|
||||
const BDataReader &bdata_reader,
|
||||
const BDataSharing &bdata_sharing,
|
||||
ModifierSimulationState &r_state)
|
||||
{
|
||||
io::serialize::JsonFormatter formatter;
|
||||
const std::optional<int> version = io_root.lookup_int("version");
|
||||
if (!version) {
|
||||
return;
|
||||
}
|
||||
if (*version > serialize_format_version) {
|
||||
return;
|
||||
}
|
||||
const io::serialize::ArrayValue *io_zones = io_root.lookup_array("zones");
|
||||
if (!io_zones) {
|
||||
return;
|
||||
}
|
||||
for (const auto &io_zone_value : io_zones->elements()) {
|
||||
const DictionaryValue *io_zone = io_zone_value->as_dictionary_value();
|
||||
if (!io_zone) {
|
||||
continue;
|
||||
}
|
||||
bke::sim::SimulationZoneID zone_id;
|
||||
if (const std::optional<int> state_id = io_zone->lookup_int("state_id")) {
|
||||
zone_id.nested_node_id = *state_id;
|
||||
}
|
||||
else if (const io::serialize::ArrayValue *io_zone_id = io_zone->lookup_array("zone_id")) {
|
||||
/* In the initial release of simulation nodes, the entire node id path was written to the
|
||||
* baked data. For backward compatibility the node ids are read here and then the nested node
|
||||
* id is looked up. */
|
||||
Vector<int> node_ids;
|
||||
for (const auto &io_zone_id_element : io_zone_id->elements()) {
|
||||
const io::serialize::IntValue *io_node_id = io_zone_id_element->as_int_value();
|
||||
if (!io_node_id) {
|
||||
continue;
|
||||
}
|
||||
node_ids.append(io_node_id->value());
|
||||
}
|
||||
const bNestedNodeRef *nested_node_ref = ntree.nested_node_ref_from_node_id_path(node_ids);
|
||||
if (!nested_node_ref) {
|
||||
continue;
|
||||
}
|
||||
zone_id.nested_node_id = nested_node_ref->id;
|
||||
}
|
||||
|
||||
const io::serialize::ArrayValue *io_state_items = io_zone->lookup_array("state_items");
|
||||
if (!io_state_items) {
|
||||
continue;
|
||||
}
|
||||
|
||||
auto zone_state = std::make_unique<bke::sim::SimulationZoneState>();
|
||||
|
||||
for (const auto &io_state_item_value : io_state_items->elements()) {
|
||||
const DictionaryValue *io_state_item = io_state_item_value->as_dictionary_value();
|
||||
if (!io_state_item) {
|
||||
continue;
|
||||
}
|
||||
const std::optional<int> state_item_id = io_state_item->lookup_int("id");
|
||||
if (!state_item_id) {
|
||||
continue;
|
||||
}
|
||||
|
||||
std::unique_ptr<BakeItem> new_state_item = deserialize_bake_item(
|
||||
*io_state_item, bdata_reader, bdata_sharing);
|
||||
|
||||
BLI_assert(new_state_item);
|
||||
zone_state->item_by_identifier.add(*state_item_id, std::move(new_state_item));
|
||||
}
|
||||
|
||||
r_state.zone_states_.add_overwrite(zone_id, std::move(zone_state));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace blender::bke::sim
|
||||
|
|
|
@ -155,8 +155,7 @@ static void subdiv_ccg_alloc_elements(SubdivCCG *subdiv_ccg, Subdiv *subdiv)
|
|||
if (num_faces) {
|
||||
subdiv_ccg->faces = static_cast<SubdivCCGFace *>(
|
||||
MEM_calloc_arrayN(num_faces, sizeof(SubdivCCGFace), "Subdiv CCG faces"));
|
||||
subdiv_ccg->grid_faces = static_cast<SubdivCCGFace **>(
|
||||
MEM_calloc_arrayN(num_grids, sizeof(SubdivCCGFace *), "Subdiv CCG grid faces"));
|
||||
subdiv_ccg->grid_to_face_map.reinitialize(num_grids);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -235,7 +234,7 @@ static void subdiv_ccg_eval_regular_grid(CCGEvalGridsData *data, const int face_
|
|||
const float grid_size_1_inv = 1.0f / (grid_size - 1);
|
||||
const int element_size = element_size_bytes_get(subdiv_ccg);
|
||||
SubdivCCGFace *faces = subdiv_ccg->faces;
|
||||
SubdivCCGFace **grid_faces = subdiv_ccg->grid_faces;
|
||||
blender::MutableSpan<int> grid_to_face_map = subdiv_ccg->grid_to_face_map;
|
||||
const SubdivCCGFace *face = &faces[face_index];
|
||||
for (int corner = 0; corner < face->num_grids; corner++) {
|
||||
const int grid_index = face->start_grid_index + corner;
|
||||
|
@ -252,7 +251,7 @@ static void subdiv_ccg_eval_regular_grid(CCGEvalGridsData *data, const int face_
|
|||
}
|
||||
}
|
||||
/* Assign grid's face. */
|
||||
grid_faces[grid_index] = &faces[face_index];
|
||||
grid_to_face_map[grid_index] = face_index;
|
||||
/* Assign material flags. */
|
||||
subdiv_ccg->grid_flag_mats[grid_index] = data->material_flags_evaluator->eval_material_flags(
|
||||
data->material_flags_evaluator, face_index);
|
||||
|
@ -266,7 +265,7 @@ static void subdiv_ccg_eval_special_grid(CCGEvalGridsData *data, const int face_
|
|||
const float grid_size_1_inv = 1.0f / (grid_size - 1);
|
||||
const int element_size = element_size_bytes_get(subdiv_ccg);
|
||||
SubdivCCGFace *faces = subdiv_ccg->faces;
|
||||
SubdivCCGFace **grid_faces = subdiv_ccg->grid_faces;
|
||||
blender::MutableSpan<int> grid_to_face_map = subdiv_ccg->grid_to_face_map;
|
||||
const SubdivCCGFace *face = &faces[face_index];
|
||||
for (int corner = 0; corner < face->num_grids; corner++) {
|
||||
const int grid_index = face->start_grid_index + corner;
|
||||
|
@ -282,7 +281,7 @@ static void subdiv_ccg_eval_special_grid(CCGEvalGridsData *data, const int face_
|
|||
}
|
||||
}
|
||||
/* Assign grid's face. */
|
||||
grid_faces[grid_index] = &faces[face_index];
|
||||
grid_to_face_map[grid_index] = face_index;
|
||||
/* Assign material flags. */
|
||||
subdiv_ccg->grid_flag_mats[grid_index] = data->material_flags_evaluator->eval_material_flags(
|
||||
data->material_flags_evaluator, face_index);
|
||||
|
@ -596,7 +595,6 @@ void BKE_subdiv_ccg_destroy(SubdivCCG *subdiv_ccg)
|
|||
BKE_subdiv_free(subdiv_ccg->subdiv);
|
||||
}
|
||||
MEM_SAFE_FREE(subdiv_ccg->faces);
|
||||
MEM_SAFE_FREE(subdiv_ccg->grid_faces);
|
||||
/* Free map of adjacent edges. */
|
||||
for (int i = 0; i < subdiv_ccg->num_adjacent_edges; i++) {
|
||||
SubdivCCGAdjacentEdge *adjacent_edge = &subdiv_ccg->adjacent_edges[i];
|
||||
|
@ -1452,7 +1450,7 @@ static SubdivCCGCoord coord_step_inside_from_boundary(const SubdivCCG *subdiv_cc
|
|||
BLI_INLINE
|
||||
int next_grid_index_from_coord(const SubdivCCG *subdiv_ccg, const SubdivCCGCoord *coord)
|
||||
{
|
||||
SubdivCCGFace *face = subdiv_ccg->grid_faces[coord->grid_index];
|
||||
const SubdivCCGFace *face = &subdiv_ccg->faces[subdiv_ccg->grid_to_face_map[coord->grid_index]];
|
||||
const int face_grid_index = coord->grid_index;
|
||||
int next_face_grid_index = face_grid_index + 1 - face->start_grid_index;
|
||||
if (next_face_grid_index == face->num_grids) {
|
||||
|
@ -1462,7 +1460,7 @@ int next_grid_index_from_coord(const SubdivCCG *subdiv_ccg, const SubdivCCGCoord
|
|||
}
|
||||
BLI_INLINE int prev_grid_index_from_coord(const SubdivCCG *subdiv_ccg, const SubdivCCGCoord *coord)
|
||||
{
|
||||
SubdivCCGFace *face = subdiv_ccg->grid_faces[coord->grid_index];
|
||||
const SubdivCCGFace *face = &subdiv_ccg->faces[subdiv_ccg->grid_to_face_map[coord->grid_index]];
|
||||
const int face_grid_index = coord->grid_index;
|
||||
int prev_face_grid_index = face_grid_index - 1 - face->start_grid_index;
|
||||
if (prev_face_grid_index < 0) {
|
||||
|
@ -1478,7 +1476,7 @@ static void neighbor_coords_corner_center_get(const SubdivCCG *subdiv_ccg,
|
|||
const bool include_duplicates,
|
||||
SubdivCCGNeighbors *r_neighbors)
|
||||
{
|
||||
SubdivCCGFace *face = subdiv_ccg->grid_faces[coord->grid_index];
|
||||
const SubdivCCGFace *face = &subdiv_ccg->faces[subdiv_ccg->grid_to_face_map[coord->grid_index]];
|
||||
const int num_adjacent_grids = face->num_grids;
|
||||
|
||||
subdiv_ccg_neighbors_init(
|
||||
|
@ -1506,7 +1504,7 @@ static int adjacent_vertex_index_from_coord(const SubdivCCG *subdiv_ccg,
|
|||
Subdiv *subdiv = subdiv_ccg->subdiv;
|
||||
OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner;
|
||||
|
||||
const SubdivCCGFace *face = subdiv_ccg->grid_faces[coord->grid_index];
|
||||
const SubdivCCGFace *face = &subdiv_ccg->faces[subdiv_ccg->grid_to_face_map[coord->grid_index]];
|
||||
const int face_index = face - subdiv_ccg->faces;
|
||||
const int face_grid_index = coord->grid_index - face->start_grid_index;
|
||||
const int num_face_grids = face->num_grids;
|
||||
|
@ -1583,7 +1581,7 @@ static int adjacent_edge_index_from_coord(const SubdivCCG *subdiv_ccg, const Sub
|
|||
{
|
||||
Subdiv *subdiv = subdiv_ccg->subdiv;
|
||||
OpenSubdiv_TopologyRefiner *topology_refiner = subdiv->topology_refiner;
|
||||
SubdivCCGFace *face = subdiv_ccg->grid_faces[coord->grid_index];
|
||||
const SubdivCCGFace *face = &subdiv_ccg->faces[subdiv_ccg->grid_to_face_map[coord->grid_index]];
|
||||
|
||||
const int face_grid_index = coord->grid_index - face->start_grid_index;
|
||||
const int face_index = face - subdiv_ccg->faces;
|
||||
|
@ -1876,9 +1874,7 @@ void BKE_subdiv_ccg_neighbor_coords_get(const SubdivCCG *subdiv_ccg,
|
|||
|
||||
int BKE_subdiv_ccg_grid_to_face_index(const SubdivCCG *subdiv_ccg, const int grid_index)
|
||||
{
|
||||
const SubdivCCGFace *face = subdiv_ccg->grid_faces[grid_index];
|
||||
const int face_index = face - subdiv_ccg->faces;
|
||||
return face_index;
|
||||
return subdiv_ccg->grid_to_face_map[grid_index];
|
||||
}
|
||||
|
||||
const int *BKE_subdiv_ccg_start_face_grid_index_ensure(SubdivCCG *subdiv_ccg)
|
||||
|
|
|
@ -1196,6 +1196,11 @@ Mesh *BKE_subdiv_to_mesh(Subdiv *subdiv,
|
|||
BKE_subdiv_stats_end(&subdiv->stats, SUBDIV_STATS_SUBDIV_TO_MESH_GEOMETRY);
|
||||
Mesh *result = subdiv_context.subdiv_mesh;
|
||||
|
||||
/* NOTE: Using normals from the limit surface gives different results than Blender's vertex
|
||||
* normal calculation. Since vertex normals are supposed to be a consistent cache, don't bother
|
||||
* calculating them here. The work may have been pointless anyway if the mesh is deformed or
|
||||
* changed afterwards. */
|
||||
|
||||
/* Move the optimal display edge array to the final bit vector. */
|
||||
if (!subdiv_context.subdiv_display_edges.is_empty()) {
|
||||
const Span<bool> span = subdiv_context.subdiv_display_edges;
|
||||
|
@ -1224,12 +1229,6 @@ Mesh *BKE_subdiv_to_mesh(Subdiv *subdiv,
|
|||
|
||||
// BKE_mesh_validate(result, true, true);
|
||||
BKE_subdiv_stats_end(&subdiv->stats, SUBDIV_STATS_SUBDIV_TO_MESH);
|
||||
/* Using normals from the limit surface gives different results than Blender's vertex normal
|
||||
* calculation. Since vertex normals are supposed to be a consistent cache, don't bother
|
||||
* calculating them here. The work may have been pointless anyway if the mesh is deformed or
|
||||
* changed afterwards. */
|
||||
BLI_assert(BKE_mesh_vert_normals_are_dirty(result) || BKE_mesh_face_normals_are_dirty(result));
|
||||
/* Free used memory. */
|
||||
subdiv_mesh_context_free(&subdiv_context);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -85,11 +85,6 @@ struct SubFrame {
|
|||
{
|
||||
return a.frame_ >= b.frame_ || (a.frame_ == b.frame_ && a.subframe_ >= b.subframe_);
|
||||
}
|
||||
|
||||
friend std::ostream &operator<<(std::ostream &stream, const SubFrame &a)
|
||||
{
|
||||
return stream << float(a);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace blender
|
||||
|
|
|
@ -2309,6 +2309,8 @@ float voronoi_n_sphere_radius(const VoronoiParams ¶ms, const float4 coord)
|
|||
|
||||
/* **** Fractal Voronoi **** */
|
||||
|
||||
/* The fractalization logic is the same as for fBM Noise, except that some additions are replaced
|
||||
* by lerps. */
|
||||
template<typename T>
|
||||
VoronoiOutput fractal_voronoi_x_fx(const VoronoiParams ¶ms,
|
||||
const T coord,
|
||||
|
@ -2319,8 +2321,7 @@ VoronoiOutput fractal_voronoi_x_fx(const VoronoiParams ¶ms,
|
|||
float scale = 1.0f;
|
||||
|
||||
VoronoiOutput output;
|
||||
const bool zero_input = params.detail == 0.0f || params.roughness == 0.0f ||
|
||||
params.lacunarity == 0.0f;
|
||||
const bool zero_input = params.detail == 0.0f || params.roughness == 0.0f;
|
||||
|
||||
for (int i = 0; i <= ceilf(params.detail); ++i) {
|
||||
VoronoiOutput octave = (params.feature == NOISE_SHD_VORONOI_F2) ?
|
||||
|
@ -2367,6 +2368,8 @@ VoronoiOutput fractal_voronoi_x_fx(const VoronoiParams ¶ms,
|
|||
return output;
|
||||
}
|
||||
|
||||
/* The fractalization logic is the same as for fBM Noise, except that some additions are replaced
|
||||
* by lerps. */
|
||||
template<typename T>
|
||||
float fractal_voronoi_distance_to_edge(const VoronoiParams ¶ms, const T coord)
|
||||
{
|
||||
|
@ -2375,8 +2378,7 @@ float fractal_voronoi_distance_to_edge(const VoronoiParams ¶ms, const T coor
|
|||
float scale = 1.0f;
|
||||
float distance = 8.0f;
|
||||
|
||||
const bool zero_input = params.detail == 0.0f || params.roughness == 0.0f ||
|
||||
params.lacunarity == 0.0f;
|
||||
const bool zero_input = params.detail == 0.0f || params.roughness == 0.0f;
|
||||
|
||||
for (int i = 0; i <= ceilf(params.detail); ++i) {
|
||||
const float octave_distance = voronoi_distance_to_edge(params, coord * scale);
|
||||
|
|
|
@ -984,7 +984,7 @@ void blo_do_versions_400(FileData *fd, Library * /*lib*/, Main *bmain)
|
|||
FOREACH_NODETREE_END;
|
||||
}
|
||||
else {
|
||||
/* Legacy node tree sockets are created for forward compatibilty,
|
||||
/* Legacy node tree sockets are created for forward compatibility,
|
||||
* but have to be freed after loading and versioning. */
|
||||
FOREACH_NODETREE_BEGIN (bmain, ntree, id) {
|
||||
/* Clear legacy sockets after conversion.
|
||||
|
|
|
@ -871,6 +871,9 @@ void blo_do_versions_userdef(UserDef *userdef)
|
|||
*/
|
||||
{
|
||||
/* Keep this block, even when empty. */
|
||||
|
||||
/* Clear deprecated USER_MENUFIXEDORDER user flag for reuse. */
|
||||
userdef->uiflag &= ~USER_UIFLAG_UNUSED_4;
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (bTheme *, btheme, &userdef->themes) {
|
||||
|
|
|
@ -292,9 +292,15 @@ void AntiAliasingPass::draw(Manager &manager,
|
|||
draw_overlay_depth(sample0_depth_tx_);
|
||||
GPU_texture_copy(sample0_depth_in_front_tx_, resources.depth_in_front_tx);
|
||||
}
|
||||
/* Copy back the saved depth buffer for correct overlays. */
|
||||
GPU_texture_copy(depth_tx, sample0_depth_tx_);
|
||||
GPU_texture_copy(depth_in_front_tx, sample0_depth_in_front_tx_);
|
||||
if (!DRW_state_is_scene_render()) {
|
||||
/* Copy back the saved depth buffer for correct overlays. */
|
||||
GPU_texture_copy(depth_tx, sample0_depth_tx_);
|
||||
GPU_texture_copy(depth_in_front_tx, sample0_depth_in_front_tx_);
|
||||
}
|
||||
else if (last_sample) {
|
||||
GPU_texture_copy(depth_tx, sample0_depth_tx_);
|
||||
/* There's no depth_in_front_tx in scene image renders. */
|
||||
}
|
||||
|
||||
if (!DRW_state_is_image_render() || last_sample) {
|
||||
smaa_weight_tx_.acquire(
|
||||
|
|
|
@ -826,6 +826,42 @@ bool match_slope_fcurve_segment(FCurve *fcu, FCurveSegment *segment, const float
|
|||
|
||||
/* ---------------- */
|
||||
|
||||
void shear_fcurve_segment(FCurve *fcu,
|
||||
FCurveSegment *segment,
|
||||
const float factor,
|
||||
tShearDirection direction)
|
||||
{
|
||||
const BezTriple *left_key = fcurve_segment_start_get(fcu, segment->start_index);
|
||||
const BezTriple *right_key = fcurve_segment_end_get(fcu, segment->start_index + segment->length);
|
||||
|
||||
const float key_x_range = right_key->vec[1][0] - left_key->vec[1][0];
|
||||
const float key_y_range = right_key->vec[1][1] - left_key->vec[1][1];
|
||||
|
||||
/* Happens if there is only 1 key on the FCurve. Needs to be skipped because it
|
||||
* would be a divide by 0. */
|
||||
if (IS_EQF(key_x_range, 0.0f)) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = segment->start_index; i < segment->start_index + segment->length; i++) {
|
||||
/* For easy calculation of the curve, the values are normalized. */
|
||||
float normalized_x;
|
||||
if (direction == SHEAR_FROM_LEFT) {
|
||||
normalized_x = (fcu->bezt[i].vec[1][0] - left_key->vec[1][0]) / key_x_range;
|
||||
}
|
||||
else {
|
||||
normalized_x = (right_key->vec[1][0] - fcu->bezt[i].vec[1][0]) / key_x_range;
|
||||
}
|
||||
|
||||
const float y_delta = key_y_range * normalized_x;
|
||||
|
||||
const float key_y_value = fcu->bezt[i].vec[1][1] + y_delta * factor;
|
||||
BKE_fcurve_keyframe_move_value_with_handles(&fcu->bezt[i], key_y_value);
|
||||
}
|
||||
}
|
||||
|
||||
/* ---------------- */
|
||||
|
||||
void breakdown_fcurve_segment(FCurve *fcu, FCurveSegment *segment, const float factor)
|
||||
{
|
||||
const BezTriple *left_bezt = fcurve_segment_start_get(fcu, segment->start_index);
|
||||
|
|
|
@ -87,7 +87,8 @@ static int bone_collection_add_exec(bContext *C, wmOperator * /* op */)
|
|||
}
|
||||
|
||||
bArmature *armature = static_cast<bArmature *>(ob->data);
|
||||
ANIM_armature_bonecoll_new(armature, nullptr);
|
||||
BoneCollection *bcoll = ANIM_armature_bonecoll_new(armature, nullptr);
|
||||
ANIM_armature_bonecoll_active_set(armature, bcoll);
|
||||
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
|
||||
return OPERATOR_FINISHED;
|
||||
|
@ -465,13 +466,7 @@ static void bone_collection_select(bContext *C,
|
|||
if (!editbone_is_member(ebone, bcoll)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (select) {
|
||||
ebone->flag |= BONE_SELECTED;
|
||||
}
|
||||
else {
|
||||
ebone->flag &= ~BONE_SELECTED;
|
||||
}
|
||||
ED_armature_ebone_select_set(ebone, select);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -494,7 +489,12 @@ static void bone_collection_select(bContext *C,
|
|||
}
|
||||
|
||||
DEG_id_tag_update(&armature->id, ID_RECALC_SELECT);
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
|
||||
if (is_editmode) {
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_BONE_SELECT, ob);
|
||||
}
|
||||
else {
|
||||
WM_event_add_notifier(C, NC_OBJECT | ND_POSE, ob);
|
||||
}
|
||||
|
||||
if (is_editmode) {
|
||||
ED_outliner_select_sync_from_edit_bone_tag(C);
|
||||
|
|
|
@ -749,6 +749,7 @@ MenuType node_group_operator_assets_menu()
|
|||
type.poll = asset_menu_poll;
|
||||
type.draw = node_add_catalog_assets_draw;
|
||||
type.listener = asset::asset_reading_region_listen_fn;
|
||||
type.context_dependent = true;
|
||||
return type;
|
||||
}
|
||||
|
||||
|
|
|
@ -458,6 +458,14 @@ void smooth_fcurve_segment(FCurve *fcu,
|
|||
int kernel_size,
|
||||
double *kernel);
|
||||
void ease_fcurve_segment(FCurve *fcu, FCurveSegment *segment, float factor);
|
||||
enum tShearDirection {
|
||||
SHEAR_FROM_LEFT = 1,
|
||||
SHEAR_FROM_RIGHT,
|
||||
};
|
||||
void shear_fcurve_segment(struct FCurve *fcu,
|
||||
struct FCurveSegment *segment,
|
||||
float factor,
|
||||
tShearDirection direction);
|
||||
/**
|
||||
* Shift the FCurve segment up/down so that it aligns with the key before/after
|
||||
* the segment.
|
||||
|
|
|
@ -36,12 +36,22 @@ void ED_operatortypes_uvedit();
|
|||
void ED_operatormacros_uvedit();
|
||||
void ED_keymap_uvedit(wmKeyConfig *keyconf);
|
||||
|
||||
bool ED_uvedit_minmax(const Scene *scene, Object *obedit, float min[2], float max[2]);
|
||||
/**
|
||||
* Be careful when using this, it bypasses all synchronization options.
|
||||
*/
|
||||
void ED_uvedit_select_all(BMesh *bm);
|
||||
|
||||
void ED_uvedit_foreach_uv(const Scene *scene,
|
||||
BMesh *bm,
|
||||
const bool skip_invisible,
|
||||
const bool selected,
|
||||
blender::FunctionRef<void(float[2])> user_fn);
|
||||
void ED_uvedit_foreach_uv_multi(const Scene *scene,
|
||||
Object **objects_edit,
|
||||
uint objects_len,
|
||||
const bool skip_invisible,
|
||||
const bool skip_nonselected,
|
||||
blender::FunctionRef<void(float[2])> user_fn);
|
||||
bool ED_uvedit_minmax_multi(
|
||||
const Scene *scene, Object **objects_edit, uint objects_len, float r_min[2], float r_max[2]);
|
||||
bool ED_uvedit_center_multi(
|
||||
|
@ -53,8 +63,6 @@ bool ED_uvedit_center_from_pivot_ex(SpaceImage *sima,
|
|||
float r_center[2],
|
||||
char mode,
|
||||
bool *r_has_select);
|
||||
bool ED_uvedit_center_from_pivot(
|
||||
SpaceImage *sima, Scene *scene, ViewLayer *view_layer, float r_center[2], char mode);
|
||||
|
||||
bool ED_object_get_active_image(Object *ob,
|
||||
int mat_nr,
|
||||
|
|
|
@ -145,23 +145,19 @@ enum {
|
|||
/** #uiBlock.flag (controls) */
|
||||
enum {
|
||||
UI_BLOCK_LOOP = 1 << 0,
|
||||
/** Indicate that items in a popup are drawn with inverted order. Used for arrow key navigation
|
||||
* so that it knows to invert the navigation direction to match the drawing order. */
|
||||
UI_BLOCK_IS_FLIP = 1 << 1,
|
||||
UI_BLOCK_NO_FLIP = 1 << 2,
|
||||
UI_BLOCK_NUMSELECT = 1 << 3,
|
||||
UI_BLOCK_NUMSELECT = 1 << 1,
|
||||
/** Don't apply window clipping. */
|
||||
UI_BLOCK_NO_WIN_CLIP = 1 << 4,
|
||||
UI_BLOCK_CLIPBOTTOM = 1 << 5,
|
||||
UI_BLOCK_CLIPTOP = 1 << 6,
|
||||
UI_BLOCK_MOVEMOUSE_QUIT = 1 << 7,
|
||||
UI_BLOCK_KEEP_OPEN = 1 << 8,
|
||||
UI_BLOCK_POPUP = 1 << 9,
|
||||
UI_BLOCK_OUT_1 = 1 << 10,
|
||||
UI_BLOCK_SEARCH_MENU = 1 << 11,
|
||||
UI_BLOCK_POPUP_MEMORY = 1 << 12,
|
||||
UI_BLOCK_NO_WIN_CLIP = 1 << 2,
|
||||
UI_BLOCK_CLIPBOTTOM = 1 << 3,
|
||||
UI_BLOCK_CLIPTOP = 1 << 4,
|
||||
UI_BLOCK_MOVEMOUSE_QUIT = 1 << 5,
|
||||
UI_BLOCK_KEEP_OPEN = 1 << 6,
|
||||
UI_BLOCK_POPUP = 1 << 7,
|
||||
UI_BLOCK_OUT_1 = 1 << 8,
|
||||
UI_BLOCK_SEARCH_MENU = 1 << 9,
|
||||
UI_BLOCK_POPUP_MEMORY = 1 << 10,
|
||||
/** Stop handling mouse events. */
|
||||
UI_BLOCK_CLIP_EVENTS = 1 << 13,
|
||||
UI_BLOCK_CLIP_EVENTS = 1 << 11,
|
||||
|
||||
/* #uiBlock::flags bits 14-17 are identical to #uiBut::drawflag bits. */
|
||||
|
||||
|
@ -874,7 +870,6 @@ void UI_block_direction_set(uiBlock *block, char direction);
|
|||
/**
|
||||
* This call escapes if there's alignment flags.
|
||||
*/
|
||||
void UI_block_order_flip(uiBlock *block);
|
||||
void UI_block_flag_enable(uiBlock *block, int flag);
|
||||
void UI_block_flag_disable(uiBlock *block, int flag);
|
||||
void UI_block_translate(uiBlock *block, int x, int y);
|
||||
|
@ -1365,7 +1360,7 @@ void UI_but_context_ptr_set(uiBlock *block, uiBut *but, const char *name, const
|
|||
const PointerRNA *UI_but_context_ptr_get(const uiBut *but,
|
||||
const char *name,
|
||||
const StructRNA *type CPP_ARG_DEFAULT(nullptr));
|
||||
bContextStore *UI_but_context_get(const uiBut *but);
|
||||
const bContextStore *UI_but_context_get(const uiBut *but);
|
||||
|
||||
void UI_but_unit_type_set(uiBut *but, int unit_type);
|
||||
int UI_but_unit_type_get(const uiBut *but);
|
||||
|
@ -2111,7 +2106,7 @@ uiBlock *uiLayoutGetBlock(uiLayout *layout);
|
|||
void uiLayoutSetFunc(uiLayout *layout, uiMenuHandleFunc handlefunc, void *argv);
|
||||
void uiLayoutSetContextPointer(uiLayout *layout, const char *name, PointerRNA *ptr);
|
||||
bContextStore *uiLayoutGetContextStore(uiLayout *layout);
|
||||
void uiLayoutContextCopy(uiLayout *layout, bContextStore *context);
|
||||
void uiLayoutContextCopy(uiLayout *layout, const bContextStore *context);
|
||||
|
||||
/**
|
||||
* Set tooltip function for all buttons in the layout.
|
||||
|
|
|
@ -3523,10 +3523,6 @@ void UI_block_free(const bContext *C, uiBlock *block)
|
|||
MEM_freeN(block->func_argN);
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH_MUTABLE (bContextStore *, store, &block->contexts) {
|
||||
CTX_store_free(store);
|
||||
}
|
||||
|
||||
BLI_freelistN(&block->saferct);
|
||||
BLI_freelistN(&block->color_pickers.list);
|
||||
BLI_freelistN(&block->dynamic_listeners);
|
||||
|
@ -4315,7 +4311,6 @@ static void ui_def_but_rna__menu(bContext * /*C*/, uiLayout *layout, void *but_p
|
|||
if (!item->identifier[0]) {
|
||||
/* inconsistent, but menus with categories do not look good flipped */
|
||||
if (item->name) {
|
||||
block->flag |= UI_BLOCK_NO_FLIP;
|
||||
categories++;
|
||||
entries_nosepr_count++;
|
||||
}
|
||||
|
@ -4347,8 +4342,8 @@ static void ui_def_but_rna__menu(bContext * /*C*/, uiLayout *layout, void *but_p
|
|||
|
||||
const char *title = RNA_property_ui_name(but->rnaprop);
|
||||
|
||||
if (title[0] && (categories == 0) && (block->flag & UI_BLOCK_NO_FLIP)) {
|
||||
/* Title at the top for menus with categories. */
|
||||
if (title[0] && !but->str[0] && (categories == 0)) {
|
||||
/* Show title when no categories and calling button has no text. */
|
||||
uiDefBut(block,
|
||||
UI_BTYPE_LABEL,
|
||||
0,
|
||||
|
@ -4472,32 +4467,11 @@ static void ui_def_but_rna__menu(bContext * /*C*/, uiLayout *layout, void *but_p
|
|||
}
|
||||
}
|
||||
|
||||
if (title[0] && (categories == 0) && !(block->flag & UI_BLOCK_NO_FLIP)) {
|
||||
/* Title at the bottom for menus without categories. */
|
||||
uiItemS(layout);
|
||||
uiDefBut(block,
|
||||
UI_BTYPE_LABEL,
|
||||
0,
|
||||
title,
|
||||
0,
|
||||
0,
|
||||
UI_UNIT_X * 5,
|
||||
UI_UNIT_Y,
|
||||
nullptr,
|
||||
0.0,
|
||||
0.0,
|
||||
0,
|
||||
0,
|
||||
"");
|
||||
}
|
||||
|
||||
UI_block_layout_set_current(block, layout);
|
||||
|
||||
if (free) {
|
||||
MEM_freeN((void *)item_array);
|
||||
}
|
||||
BLI_assert((block->flag & UI_BLOCK_IS_FLIP) == 0);
|
||||
block->flag |= UI_BLOCK_IS_FLIP;
|
||||
}
|
||||
|
||||
static void ui_def_but_rna__panel_type(bContext *C, uiLayout *layout, void *but_p)
|
||||
|
@ -4739,7 +4713,7 @@ static uiBut *ui_def_but_rna(uiBlock *block,
|
|||
* access it. */
|
||||
const PointerRNA pptr = RNA_property_pointer_get(ptr, prop);
|
||||
if (pptr.data && RNA_struct_is_ID(pptr.type)) {
|
||||
but->context = CTX_store_add(&block->contexts, "id", &pptr);
|
||||
but->context = CTX_store_add(block->contexts, "id", &pptr);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5852,39 +5826,6 @@ void UI_block_direction_set(uiBlock *block, char direction)
|
|||
block->direction = direction;
|
||||
}
|
||||
|
||||
void UI_block_order_flip(uiBlock *block)
|
||||
{
|
||||
float centy, miny = 10000, maxy = -10000;
|
||||
|
||||
if (U.uiflag & USER_MENUFIXEDORDER) {
|
||||
return;
|
||||
}
|
||||
if (block->flag & UI_BLOCK_NO_FLIP) {
|
||||
return;
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
|
||||
if (but->drawflag & UI_BUT_ALIGN) {
|
||||
return;
|
||||
}
|
||||
if (but->rect.ymin < miny) {
|
||||
miny = but->rect.ymin;
|
||||
}
|
||||
if (but->rect.ymax > maxy) {
|
||||
maxy = but->rect.ymax;
|
||||
}
|
||||
}
|
||||
/* mirror trick */
|
||||
centy = (miny + maxy) / 2.0f;
|
||||
LISTBASE_FOREACH (uiBut *, but, &block->buttons) {
|
||||
but->rect.ymin = centy - (but->rect.ymin - centy);
|
||||
but->rect.ymax = centy - (but->rect.ymax - centy);
|
||||
std::swap(but->rect.ymin, but->rect.ymax);
|
||||
}
|
||||
|
||||
block->flag ^= UI_BLOCK_IS_FLIP;
|
||||
}
|
||||
|
||||
void UI_block_flag_enable(uiBlock *block, int flag)
|
||||
{
|
||||
block->flag |= flag;
|
||||
|
@ -5967,8 +5908,9 @@ PointerRNA *UI_but_operator_ptr_get(uiBut *but)
|
|||
|
||||
void UI_but_context_ptr_set(uiBlock *block, uiBut *but, const char *name, const PointerRNA *ptr)
|
||||
{
|
||||
but->context = CTX_store_add(&block->contexts, name, ptr);
|
||||
but->context->used = true;
|
||||
bContextStore *ctx = CTX_store_add(block->contexts, name, ptr);
|
||||
ctx->used = true;
|
||||
but->context = ctx;
|
||||
}
|
||||
|
||||
const PointerRNA *UI_but_context_ptr_get(const uiBut *but, const char *name, const StructRNA *type)
|
||||
|
@ -5976,7 +5918,7 @@ const PointerRNA *UI_but_context_ptr_get(const uiBut *but, const char *name, con
|
|||
return CTX_store_ptr_lookup(but->context, name, type);
|
||||
}
|
||||
|
||||
bContextStore *UI_but_context_get(const uiBut *but)
|
||||
const bContextStore *UI_but_context_get(const uiBut *but)
|
||||
{
|
||||
return but->context;
|
||||
}
|
||||
|
@ -6666,7 +6608,7 @@ void UI_but_string_info_get(bContext *C, uiBut *but, ...)
|
|||
tmp = BLI_strdup(WM_operatortype_name(but->optype, opptr).c_str());
|
||||
}
|
||||
else {
|
||||
bContextStore *previous_ctx = CTX_store_get(C);
|
||||
const bContextStore *previous_ctx = CTX_store_get(C);
|
||||
CTX_store_set(C, but->context);
|
||||
tmp = BLI_strdup(WM_operatortype_description(C, but->optype, opptr).c_str());
|
||||
CTX_store_set(C, previous_ctx);
|
||||
|
|
|
@ -489,7 +489,7 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but, const wmEvent *ev
|
|||
|
||||
uiPopupMenu *pup;
|
||||
uiLayout *layout;
|
||||
bContextStore *previous_ctx = CTX_store_get(C);
|
||||
const bContextStore *previous_ctx = CTX_store_get(C);
|
||||
{
|
||||
uiStringInfo label = {BUT_GET_LABEL, nullptr};
|
||||
|
||||
|
@ -946,7 +946,7 @@ bool ui_popup_context_menu_for_button(bContext *C, uiBut *but, const wmEvent *ev
|
|||
if (view_item_but) {
|
||||
BLI_assert(view_item_but->type == UI_BTYPE_VIEW_ITEM);
|
||||
|
||||
bContextStore *prev_ctx = CTX_store_get(C);
|
||||
const bContextStore *prev_ctx = CTX_store_get(C);
|
||||
/* Sub-layout for context override. */
|
||||
uiLayout *sub = uiLayoutColumn(layout, false);
|
||||
set_layout_context_from_button(C, sub, view_item_but);
|
||||
|
|
|
@ -503,7 +503,7 @@ struct uiAfterFunc {
|
|||
uiBlockInteraction_CallbackData custom_interaction_callbacks;
|
||||
uiBlockInteraction_Handle *custom_interaction_handle;
|
||||
|
||||
bContextStore *context;
|
||||
std::optional<bContextStore> context;
|
||||
|
||||
char undostr[BKE_UNDO_STR_MAX];
|
||||
char drawstr[UI_MAX_DRAW_STR];
|
||||
|
@ -789,7 +789,7 @@ static void ui_handle_afterfunc_add_operator_ex(wmOperatorType *ot,
|
|||
}
|
||||
|
||||
if (context_but && context_but->context) {
|
||||
after->context = CTX_store_copy(context_but->context);
|
||||
after->context = *context_but->context;
|
||||
}
|
||||
|
||||
if (context_but) {
|
||||
|
@ -905,7 +905,7 @@ static void ui_apply_but_func(bContext *C, uiBut *but)
|
|||
}
|
||||
|
||||
if (but->context) {
|
||||
after->context = CTX_store_copy(but->context);
|
||||
after->context = *but->context;
|
||||
}
|
||||
|
||||
ui_but_drawstr_without_sep_char(but, after->drawstr, sizeof(after->drawstr));
|
||||
|
@ -1020,7 +1020,7 @@ static void ui_apply_but_funcs_after(bContext *C)
|
|||
MEM_delete(afterf);
|
||||
|
||||
if (after.context) {
|
||||
CTX_store_set(C, after.context);
|
||||
CTX_store_set(C, &after.context.value());
|
||||
}
|
||||
|
||||
if (after.popup_op) {
|
||||
|
@ -1053,7 +1053,6 @@ static void ui_apply_but_funcs_after(bContext *C)
|
|||
|
||||
if (after.context) {
|
||||
CTX_store_set(C, nullptr);
|
||||
CTX_store_free(after.context);
|
||||
}
|
||||
|
||||
if (after.func) {
|
||||
|
@ -10483,19 +10482,18 @@ static int ui_handle_menu_event(bContext *C,
|
|||
if (val == KM_PRESS) {
|
||||
/* Determine scroll operation. */
|
||||
uiMenuScrollType scrolltype;
|
||||
const bool ui_block_flipped = (block->flag & UI_BLOCK_IS_FLIP) != 0;
|
||||
|
||||
if (ELEM(type, EVT_PAGEUPKEY, EVT_HOMEKEY)) {
|
||||
scrolltype = ui_block_flipped ? MENU_SCROLL_TOP : MENU_SCROLL_BOTTOM;
|
||||
scrolltype = MENU_SCROLL_TOP;
|
||||
}
|
||||
else if (ELEM(type, EVT_PAGEDOWNKEY, EVT_ENDKEY)) {
|
||||
scrolltype = ui_block_flipped ? MENU_SCROLL_BOTTOM : MENU_SCROLL_TOP;
|
||||
scrolltype = MENU_SCROLL_BOTTOM;
|
||||
}
|
||||
else if (ELEM(type, EVT_UPARROWKEY, WHEELUPMOUSE)) {
|
||||
scrolltype = ui_block_flipped ? MENU_SCROLL_UP : MENU_SCROLL_DOWN;
|
||||
scrolltype = MENU_SCROLL_UP;
|
||||
}
|
||||
else {
|
||||
scrolltype = ui_block_flipped ? MENU_SCROLL_DOWN : MENU_SCROLL_UP;
|
||||
scrolltype = MENU_SCROLL_DOWN;
|
||||
}
|
||||
|
||||
if (ui_menu_pass_event_to_parent_if_nonactive(
|
||||
|
|
|
@ -202,7 +202,7 @@ struct uiBut {
|
|||
uiButHandleNFunc funcN = nullptr;
|
||||
void *func_argN = nullptr;
|
||||
|
||||
bContextStore *context = nullptr;
|
||||
const bContextStore *context = nullptr;
|
||||
|
||||
uiButCompleteFunc autocomplete_func = nullptr;
|
||||
void *autofunc_arg = nullptr;
|
||||
|
@ -487,7 +487,7 @@ struct uiBlock {
|
|||
ListBase layouts;
|
||||
uiLayout *curlayout;
|
||||
|
||||
ListBase contexts;
|
||||
blender::Vector<std::unique_ptr<bContextStore>> contexts;
|
||||
|
||||
/** A block can store "views" on data-sets. Currently tree-views (#AbstractTreeView) only.
|
||||
* Others are imaginable, e.g. table-views, grid-views, etc. These are stored here to support
|
||||
|
|
|
@ -1290,7 +1290,6 @@ static void ui_item_menu_hold(bContext *C, ARegion *butregion, uiBut *but)
|
|||
UI_popup_menu_but_set(pup, butregion, but);
|
||||
|
||||
block->flag |= UI_BLOCK_POPUP_HOLD;
|
||||
block->flag |= UI_BLOCK_IS_FLIP;
|
||||
|
||||
char direction = UI_DIR_DOWN;
|
||||
if (!but->drawstr[0]) {
|
||||
|
@ -1554,9 +1553,6 @@ void uiItemsFullEnumO_items(uiLayout *layout,
|
|||
if (item->name) {
|
||||
if (item != item_array && !radial && split != nullptr) {
|
||||
target = uiLayoutColumn(split, layout->align);
|
||||
|
||||
/* inconsistent, but menus with labels do not look good flipped */
|
||||
block->flag |= UI_BLOCK_NO_FLIP;
|
||||
}
|
||||
|
||||
uiBut *but;
|
||||
|
@ -1647,7 +1643,7 @@ void uiItemsFullEnumO(uiLayout *layout,
|
|||
}
|
||||
else {
|
||||
bContext *C = static_cast<bContext *>(block->evil_C);
|
||||
bContextStore *previous_ctx = CTX_store_get(C);
|
||||
const bContextStore *previous_ctx = CTX_store_get(C);
|
||||
CTX_store_set(C, layout->context);
|
||||
RNA_property_enum_items_gettexted(C, &ptr, prop, &item_array, &totitem, &free);
|
||||
CTX_store_set(C, previous_ctx);
|
||||
|
@ -1659,9 +1655,6 @@ void uiItemsFullEnumO(uiLayout *layout,
|
|||
if (free) {
|
||||
MEM_freeN((void *)item_array);
|
||||
}
|
||||
|
||||
/* intentionally don't touch UI_BLOCK_IS_FLIP here,
|
||||
* we don't know the context this is called in */
|
||||
}
|
||||
else if (prop && RNA_property_type(prop) != PROP_ENUM) {
|
||||
RNA_warning("%s.%s, not an enum type", RNA_struct_identifier(ptr.type), propname);
|
||||
|
@ -2723,8 +2716,6 @@ void uiItemsEnumR(uiLayout *layout, PointerRNA *ptr, const char *propname)
|
|||
if (item[i].name) {
|
||||
if (i != 0) {
|
||||
column = uiLayoutColumn(split, false);
|
||||
/* inconsistent, but menus with labels do not look good flipped */
|
||||
block->flag |= UI_BLOCK_NO_FLIP;
|
||||
}
|
||||
|
||||
uiItemL(column, item[i].name, ICON_NONE);
|
||||
|
@ -2742,9 +2733,6 @@ void uiItemsEnumR(uiLayout *layout, PointerRNA *ptr, const char *propname)
|
|||
if (free) {
|
||||
MEM_freeN((void *)item);
|
||||
}
|
||||
|
||||
/* intentionally don't touch UI_BLOCK_IS_FLIP here,
|
||||
* we don't know the context this is called in */
|
||||
}
|
||||
|
||||
/* Pointer RNA button with search */
|
||||
|
@ -2955,20 +2943,13 @@ void uiItemPointerR(uiLayout *layout,
|
|||
void ui_item_menutype_func(bContext *C, uiLayout *layout, void *arg_mt)
|
||||
{
|
||||
MenuType *mt = (MenuType *)arg_mt;
|
||||
|
||||
UI_menutype_draw(C, mt, layout);
|
||||
|
||||
/* Menus are created flipped (from event handling point of view). */
|
||||
layout->root->block->flag ^= UI_BLOCK_IS_FLIP;
|
||||
}
|
||||
|
||||
void ui_item_paneltype_func(bContext *C, uiLayout *layout, void *arg_pt)
|
||||
{
|
||||
PanelType *pt = (PanelType *)arg_pt;
|
||||
UI_paneltype_draw(C, pt, layout);
|
||||
|
||||
/* Panels are created flipped (from event handling POV). */
|
||||
layout->root->block->flag ^= UI_BLOCK_IS_FLIP;
|
||||
}
|
||||
|
||||
static uiBut *ui_item_menu(uiLayout *layout,
|
||||
|
@ -3096,7 +3077,7 @@ void uiItemMContents(uiLayout *layout, const char *menuname)
|
|||
return;
|
||||
}
|
||||
|
||||
bContextStore *previous_ctx = CTX_store_get(C);
|
||||
const bContextStore *previous_ctx = CTX_store_get(C);
|
||||
UI_menutype_draw(C, mt, layout);
|
||||
|
||||
/* Restore context that was cleared by `UI_menutype_draw`. */
|
||||
|
@ -3576,8 +3557,6 @@ static void menu_item_enum_opname_menu(bContext * /*C*/, uiLayout *layout, void
|
|||
uiLayoutSetOperatorContext(layout, lvl->opcontext);
|
||||
uiItemsFullEnumO(layout, lvl->opname, lvl->propname, op_props, lvl->opcontext, UI_ITEM_NONE);
|
||||
|
||||
layout->root->block->flag |= UI_BLOCK_IS_FLIP;
|
||||
|
||||
/* override default, needed since this was assumed pre 2.70 */
|
||||
UI_block_direction_set(layout->root->block, UI_DIR_DOWN);
|
||||
}
|
||||
|
@ -3668,7 +3647,6 @@ static void menu_item_enum_rna_menu(bContext * /*C*/, uiLayout *layout, void *ar
|
|||
|
||||
uiLayoutSetOperatorContext(layout, lvl->opcontext);
|
||||
uiItemsEnumR(layout, &lvl->rnapoin, lvl->propname);
|
||||
layout->root->block->flag |= UI_BLOCK_IS_FLIP;
|
||||
}
|
||||
|
||||
void uiItemMenuEnumR_prop(
|
||||
|
@ -5703,7 +5681,7 @@ void ui_layout_add_but(uiLayout *layout, uiBut *but)
|
|||
|
||||
if (layout->context) {
|
||||
but->context = layout->context;
|
||||
but->context->used = true;
|
||||
layout->context->used = true;
|
||||
}
|
||||
|
||||
if (layout->emboss != UI_EMBOSS_UNDEFINED) {
|
||||
|
@ -5832,7 +5810,7 @@ bool UI_block_layout_needs_resolving(const uiBlock *block)
|
|||
void uiLayoutSetContextPointer(uiLayout *layout, const char *name, PointerRNA *ptr)
|
||||
{
|
||||
uiBlock *block = layout->root->block;
|
||||
layout->context = CTX_store_add(&block->contexts, name, ptr);
|
||||
layout->context = CTX_store_add(block->contexts, name, ptr);
|
||||
}
|
||||
|
||||
bContextStore *uiLayoutGetContextStore(uiLayout *layout)
|
||||
|
@ -5840,10 +5818,10 @@ bContextStore *uiLayoutGetContextStore(uiLayout *layout)
|
|||
return layout->context;
|
||||
}
|
||||
|
||||
void uiLayoutContextCopy(uiLayout *layout, bContextStore *context)
|
||||
void uiLayoutContextCopy(uiLayout *layout, const bContextStore *context)
|
||||
{
|
||||
uiBlock *block = layout->root->block;
|
||||
layout->context = CTX_store_add_all(&block->contexts, context);
|
||||
layout->context = CTX_store_add_all(block->contexts, context);
|
||||
}
|
||||
|
||||
void uiLayoutSetTooltipFunc(uiLayout *layout,
|
||||
|
|
|
@ -188,9 +188,7 @@ static void ui_popup_menu_create_block(bContext *C,
|
|||
const uiStyle *style = UI_style_get_dpi();
|
||||
|
||||
pup->block = UI_block_begin(C, nullptr, block_name, UI_EMBOSS_PULLDOWN);
|
||||
if (!pup->but) {
|
||||
pup->block->flag |= UI_BLOCK_NO_FLIP;
|
||||
}
|
||||
|
||||
/* A title is only provided when a Menu has a label, this is not always the case, see e.g.
|
||||
* `VIEW3D_MT_edit_mesh_context_menu` -- this specifies its own label inside the draw function
|
||||
* depending on vertex/edge/face mode. We still want to flag the uiBlock (but only insert into
|
||||
|
@ -360,7 +358,6 @@ static uiBlock *ui_block_func_POPUP(bContext *C, uiPopupBlockHandle *handle, voi
|
|||
if (RGN_TYPE_IS_HEADER_ANY(region->regiontype)) {
|
||||
if (RGN_ALIGN_ENUM_FROM_MASK(region->alignment) == RGN_ALIGN_BOTTOM) {
|
||||
UI_block_direction_set(block, UI_DIR_UP);
|
||||
UI_block_order_flip(block);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -408,20 +405,6 @@ static uiPopupBlockHandle *ui_popup_menu_create(
|
|||
pup->my = window->eventstate->xy[1];
|
||||
pup->popup = true;
|
||||
}
|
||||
/* some enums reversing is strange, currently we have no good way to
|
||||
* reverse some enum's but not others, so reverse all so the first menu
|
||||
* items are always close to the mouse cursor */
|
||||
else {
|
||||
#if 0
|
||||
/* if this is an rna button then we can assume its an enum
|
||||
* flipping enums is generally not good since the order can be
|
||||
* important #28786. */
|
||||
if (but->rnaprop && RNA_property_type(but->rnaprop) == PROP_ENUM) {
|
||||
pup->block->flag |= UI_BLOCK_NO_FLIP;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
uiPopupBlockHandle *handle = ui_popup_block_create(
|
||||
C, butregion, but, nullptr, ui_block_func_POPUP, pup, ui_block_free_func_POPUP);
|
||||
|
||||
|
@ -492,8 +475,6 @@ uiPopupMenu *UI_popup_menu_begin_ex(bContext *C,
|
|||
pup->title = title;
|
||||
|
||||
ui_popup_menu_create_block(C, pup, title, block_name);
|
||||
/* Further buttons will be laid out top to bottom by default. */
|
||||
pup->block->flag |= UI_BLOCK_IS_FLIP;
|
||||
|
||||
/* create in advance so we can let buttons point to retval already */
|
||||
pup->block->handle = MEM_cnew<uiPopupBlockHandle>(__func__);
|
||||
|
|
|
@ -107,8 +107,6 @@ static void ui_popover_create_block(bContext *C,
|
|||
uiLayoutContextCopy(pup->layout, pup->but->context);
|
||||
}
|
||||
}
|
||||
|
||||
pup->block->flag |= UI_BLOCK_NO_FLIP;
|
||||
}
|
||||
|
||||
static uiBlock *ui_block_func_POPOVER(bContext *C, uiPopupBlockHandle *handle, void *arg_pup)
|
||||
|
@ -415,9 +413,6 @@ void UI_popover_end(bContext *C, uiPopover *pup, wmKeyMap *keymap)
|
|||
* The begin/end stype of calling popups doesn't allow 'can_refresh' to be set.
|
||||
* For now close this style of popovers when accessed. */
|
||||
UI_block_flag_disable(pup->block, UI_BLOCK_KEEP_OPEN);
|
||||
|
||||
/* Panels are created flipped (from event handling POV). */
|
||||
pup->block->flag ^= UI_BLOCK_IS_FLIP;
|
||||
}
|
||||
|
||||
uiLayout *UI_popover_layout(uiPopover *pup)
|
||||
|
|
|
@ -253,11 +253,6 @@ static void ui_popup_block_position(wmWindow *window,
|
|||
else {
|
||||
offset_x = butrct.xmin - block->rect.xmin - center_x;
|
||||
}
|
||||
/* changed direction? */
|
||||
if ((dir1 & block->direction) == 0) {
|
||||
/* TODO: still do */
|
||||
UI_block_order_flip(block);
|
||||
}
|
||||
}
|
||||
else if (dir1 == UI_DIR_DOWN) {
|
||||
offset_y = (butrct.ymin - block->rect.ymax) + offset_overlap;
|
||||
|
@ -276,11 +271,6 @@ static void ui_popup_block_position(wmWindow *window,
|
|||
else {
|
||||
offset_x = butrct.xmin - block->rect.xmin - center_x;
|
||||
}
|
||||
/* changed direction? */
|
||||
if ((dir1 & block->direction) == 0) {
|
||||
/* TODO: still do */
|
||||
UI_block_order_flip(block);
|
||||
}
|
||||
}
|
||||
|
||||
/* Center over popovers for eg. */
|
||||
|
|
|
@ -22,13 +22,14 @@
|
|||
#include "DNA_shader_fx_types.h"
|
||||
#include "DNA_texture_types.h"
|
||||
|
||||
#include "BLI_alloca.h"
|
||||
#include "BLI_dynstr.h"
|
||||
#include "BLI_ghash.h"
|
||||
#include "BLI_linklist.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_map.hh"
|
||||
#include "BLI_math_matrix.h"
|
||||
#include "BLI_memarena.h"
|
||||
#include "BLI_set.hh"
|
||||
#include "BLI_stack.hh"
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_string_search.hh"
|
||||
#include "BLI_string_utils.h"
|
||||
|
@ -75,7 +76,6 @@ struct MenuSearch_Context {
|
|||
|
||||
struct MenuSearch_Parent {
|
||||
MenuSearch_Parent *parent;
|
||||
MenuType *parent_mt;
|
||||
const char *drawstr;
|
||||
|
||||
/** Set while writing menu items only. */
|
||||
|
@ -86,8 +86,6 @@ struct MenuSearch_Item {
|
|||
MenuSearch_Item *next, *prev;
|
||||
const char *drawstr;
|
||||
const char *drawwstr_full;
|
||||
/** Support a single level sub-menu nesting (for operator buttons that expand). */
|
||||
const char *drawstr_submenu;
|
||||
int icon;
|
||||
int state;
|
||||
|
||||
|
@ -105,7 +103,7 @@ struct MenuSearch_Item {
|
|||
wmOperatorType *type;
|
||||
PointerRNA *opptr;
|
||||
wmOperatorCallContext opcontext;
|
||||
bContextStore *context;
|
||||
const bContextStore *context;
|
||||
} op;
|
||||
|
||||
/** Property (only for check-box/boolean). */
|
||||
|
@ -161,9 +159,9 @@ static const char *strdup_memarena_from_dynstr(MemArena *memarena, DynStr *dyn_s
|
|||
static bool menu_items_from_ui_create_item_from_button(MenuSearch_Data *data,
|
||||
MemArena *memarena,
|
||||
MenuType *mt,
|
||||
const char *drawstr_submenu,
|
||||
uiBut *but,
|
||||
MenuSearch_Context *wm_context)
|
||||
MenuSearch_Context *wm_context,
|
||||
MenuSearch_Parent *menu_parent)
|
||||
{
|
||||
MenuSearch_Item *item = nullptr;
|
||||
|
||||
|
@ -184,7 +182,7 @@ static bool menu_items_from_ui_create_item_from_button(MenuSearch_Data *data,
|
|||
|
||||
item->op.type = but->optype;
|
||||
item->op.opcontext = but->opcontext;
|
||||
item->op.context = but->context;
|
||||
item->op.context = but->context ? MEM_new<bContextStore>(__func__, *but->context) : nullptr;
|
||||
item->op.opptr = but->opptr;
|
||||
but->opptr = nullptr;
|
||||
}
|
||||
|
@ -250,9 +248,9 @@ static bool menu_items_from_ui_create_item_from_button(MenuSearch_Data *data,
|
|||
item->state = (but->flag &
|
||||
(UI_BUT_DISABLED | UI_BUT_INACTIVE | UI_BUT_REDALERT | UI_BUT_HAS_SEP_CHAR));
|
||||
item->mt = mt;
|
||||
item->drawstr_submenu = drawstr_submenu ? strdup_memarena(memarena, drawstr_submenu) : nullptr;
|
||||
|
||||
item->wm_context = wm_context;
|
||||
item->menu_parent = menu_parent;
|
||||
|
||||
BLI_addtail(&data->items, item);
|
||||
return true;
|
||||
|
@ -306,6 +304,14 @@ static bool menu_items_to_ui_button(MenuSearch_Item *item, uiBut *but)
|
|||
return changed;
|
||||
}
|
||||
|
||||
struct MenuStackEntry {
|
||||
MenuType *mt = nullptr;
|
||||
/** Used as parent in submenus. */
|
||||
MenuSearch_Parent *self_as_parent = nullptr;
|
||||
/** The menu might be context dependent. */
|
||||
std::optional<bContextStore> context;
|
||||
};
|
||||
|
||||
/**
|
||||
* Populate \a menu_stack with menus from inspecting active key-maps for this context.
|
||||
*/
|
||||
|
@ -313,9 +319,9 @@ static void menu_types_add_from_keymap_items(bContext *C,
|
|||
wmWindow *win,
|
||||
ScrArea *area,
|
||||
ARegion *region,
|
||||
LinkNode **menuid_stack_p,
|
||||
GHash *menu_to_kmi,
|
||||
GSet *menu_tagged)
|
||||
blender::Stack<MenuStackEntry> &menu_stack,
|
||||
blender::Map<MenuType *, wmKeyMapItem *> &menu_to_kmi,
|
||||
blender::Set<MenuType *> &menu_tagged)
|
||||
{
|
||||
wmWindowManager *wm = CTX_wm_manager(C);
|
||||
ListBase *handlers[] = {
|
||||
|
@ -353,14 +359,10 @@ static void menu_types_add_from_keymap_items(bContext *C,
|
|||
RNA_string_get(kmi->ptr, "name", menu_idname);
|
||||
MenuType *mt = WM_menutype_find(menu_idname, false);
|
||||
|
||||
if (mt && BLI_gset_add(menu_tagged, mt)) {
|
||||
if (mt && menu_tagged.add(mt)) {
|
||||
/* Unlikely, but possible this will be included twice. */
|
||||
BLI_linklist_prepend(menuid_stack_p, mt);
|
||||
|
||||
void **kmi_p;
|
||||
if (!BLI_ghash_ensure_p(menu_to_kmi, mt, &kmi_p)) {
|
||||
*kmi_p = kmi;
|
||||
}
|
||||
menu_stack.push({mt});
|
||||
menu_to_kmi.add(mt, kmi);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -430,9 +432,7 @@ static MenuSearch_Data *menu_items_from_ui_create(
|
|||
bContext *C, wmWindow *win, ScrArea *area_init, ARegion *region_init, bool include_all_areas)
|
||||
{
|
||||
MemArena *memarena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
|
||||
/** Map (#MenuType to #MenuSearch_Parent) */
|
||||
GHash *menu_parent_map = BLI_ghash_ptr_new(__func__);
|
||||
GHash *menu_display_name_map = BLI_ghash_ptr_new(__func__);
|
||||
blender::Map<MenuType *, const char *> menu_display_name_map;
|
||||
const uiStyle *style = UI_style_get_dpi();
|
||||
|
||||
/* Convert into non-ui structure. */
|
||||
|
@ -441,14 +441,12 @@ static MenuSearch_Data *menu_items_from_ui_create(
|
|||
DynStr *dyn_str = BLI_dynstr_new_memarena();
|
||||
|
||||
/* Use a stack of menus to handle and discover new menus in passes. */
|
||||
LinkNode *menu_stack = nullptr;
|
||||
blender::Stack<MenuStackEntry> menu_stack;
|
||||
|
||||
/* Tag menu types not to add, either because they have already been added
|
||||
* or they have been blacklisted.
|
||||
* Set of #MenuType. */
|
||||
GSet *menu_tagged = BLI_gset_ptr_new(__func__);
|
||||
/** Map (#MenuType -> #wmKeyMapItem). */
|
||||
GHash *menu_to_kmi = BLI_ghash_ptr_new(__func__);
|
||||
* or they have been blacklisted. */
|
||||
blender::Set<MenuType *> menu_tagged;
|
||||
blender::Map<MenuType *, wmKeyMapItem *> menu_to_kmi;
|
||||
|
||||
/* Blacklist menus we don't want to show. */
|
||||
{
|
||||
|
@ -462,7 +460,7 @@ static MenuSearch_Data *menu_items_from_ui_create(
|
|||
for (int i = 0; i < ARRAY_SIZE(idname_array); i++) {
|
||||
MenuType *mt = WM_menutype_find(idname_array[i], false);
|
||||
if (mt != nullptr) {
|
||||
BLI_gset_add(menu_tagged, mt);
|
||||
menu_tagged.add(mt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -479,7 +477,7 @@ static MenuSearch_Data *menu_items_from_ui_create(
|
|||
for (WM_menutype_iter(&iter); !BLI_ghashIterator_done(&iter); BLI_ghashIterator_step(&iter)) {
|
||||
MenuType *mt = (MenuType *)BLI_ghashIterator_getValue(&iter);
|
||||
if (BLI_str_endswith(mt->idname, "_context_menu")) {
|
||||
BLI_gset_add(menu_tagged, mt);
|
||||
menu_tagged.add(mt);
|
||||
}
|
||||
}
|
||||
const char *idname_array[] = {
|
||||
|
@ -489,7 +487,7 @@ static MenuSearch_Data *menu_items_from_ui_create(
|
|||
for (int i = 0; i < ARRAY_SIZE(idname_array); i++) {
|
||||
MenuType *mt = WM_menutype_find(idname_array[i], false);
|
||||
if (mt != nullptr) {
|
||||
BLI_gset_remove(menu_tagged, mt, nullptr);
|
||||
menu_tagged.remove(mt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -562,8 +560,6 @@ static MenuSearch_Data *menu_items_from_ui_create(
|
|||
global_menu_prefix = CTX_IFACE_(RNA_property_translation_context(prop_ui_type), "Top Bar");
|
||||
}
|
||||
|
||||
GHashIterator iter;
|
||||
|
||||
for (int space_type_ui_index = -1; space_type_ui_index < space_type_ui_items_len;
|
||||
space_type_ui_index += 1)
|
||||
{
|
||||
|
@ -653,8 +649,8 @@ static MenuSearch_Data *menu_items_from_ui_create(
|
|||
MenuType *mt = WM_menutype_find(idname_array[i], false);
|
||||
if (mt != nullptr) {
|
||||
/* Check if this exists because of 'include_all_areas'. */
|
||||
if (BLI_gset_add(menu_tagged, mt)) {
|
||||
BLI_linklist_prepend(&menu_stack, mt);
|
||||
if (menu_tagged.add(mt)) {
|
||||
menu_stack.push({mt});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -664,8 +660,9 @@ static MenuSearch_Data *menu_items_from_ui_create(
|
|||
|
||||
bool has_keymap_menu_items = false;
|
||||
|
||||
while (menu_stack != nullptr) {
|
||||
MenuType *mt = (MenuType *)BLI_linklist_pop(&menu_stack);
|
||||
while (!menu_stack.is_empty()) {
|
||||
MenuStackEntry current_menu = menu_stack.pop();
|
||||
MenuType *mt = current_menu.mt;
|
||||
if (!WM_menutype_poll(C, mt)) {
|
||||
continue;
|
||||
}
|
||||
|
@ -676,6 +673,9 @@ static MenuSearch_Data *menu_items_from_ui_create(
|
|||
|
||||
UI_block_flag_enable(block, UI_BLOCK_SHOW_SHORTCUT_ALWAYS);
|
||||
|
||||
if (current_menu.context.has_value()) {
|
||||
uiLayoutContextCopy(layout, &*current_menu.context);
|
||||
}
|
||||
uiLayoutSetOperatorContext(layout, WM_OP_INVOKE_REGION_WIN);
|
||||
UI_menutype_draw(C, mt, layout);
|
||||
|
||||
|
@ -694,21 +694,20 @@ static MenuSearch_Data *menu_items_from_ui_create(
|
|||
}
|
||||
|
||||
if (but_test == nullptr) {
|
||||
BLI_ghash_insert(
|
||||
menu_display_name_map, mt, (void *)strdup_memarena(memarena, but->drawstr));
|
||||
menu_display_name_map.add(mt, strdup_memarena(memarena, but->drawstr));
|
||||
}
|
||||
}
|
||||
else if (menu_items_from_ui_create_item_from_button(
|
||||
data, memarena, mt, nullptr, but, wm_context)) {
|
||||
data, memarena, mt, but, wm_context, current_menu.self_as_parent))
|
||||
{
|
||||
/* pass */
|
||||
}
|
||||
else if ((mt_from_but = UI_but_menutype_get(but))) {
|
||||
const bool uses_context = but->context && mt_from_but->context_dependent;
|
||||
const bool tagged_first_time = menu_tagged.add(mt_from_but);
|
||||
const bool scan_submenu = tagged_first_time || uses_context;
|
||||
|
||||
if (BLI_gset_add(menu_tagged, mt_from_but)) {
|
||||
BLI_linklist_prepend(&menu_stack, mt_from_but);
|
||||
}
|
||||
|
||||
if (!BLI_ghash_haskey(menu_parent_map, mt_from_but)) {
|
||||
if (scan_submenu) {
|
||||
MenuSearch_Parent *menu_parent = (MenuSearch_Parent *)BLI_memarena_calloc(
|
||||
memarena, sizeof(*menu_parent));
|
||||
/* Use brackets for menu key shortcuts,
|
||||
|
@ -747,20 +746,23 @@ static MenuSearch_Data *menu_items_from_ui_create(
|
|||
}
|
||||
menu_parent->drawstr = strdup_memarena(memarena, drawstr);
|
||||
}
|
||||
menu_parent->parent_mt = mt;
|
||||
BLI_ghash_insert(menu_parent_map, mt_from_but, menu_parent);
|
||||
menu_parent->parent = current_menu.self_as_parent;
|
||||
|
||||
if (drawstr_is_empty) {
|
||||
printf("Warning: '%s' menu has empty 'bl_label'.\n", mt_from_but->idname);
|
||||
}
|
||||
|
||||
if (uses_context) {
|
||||
menu_stack.push({mt_from_but, menu_parent, *but->context});
|
||||
}
|
||||
else {
|
||||
menu_stack.push({mt_from_but, menu_parent});
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (but->menu_create_func != nullptr) {
|
||||
/* A non 'MenuType' menu button. */
|
||||
|
||||
/* Only expand one level deep, this is mainly for expanding operator menus. */
|
||||
const char *drawstr_submenu = but->drawstr;
|
||||
|
||||
/* +1 to avoid overlap with the current 'block'. */
|
||||
uiBlock *sub_block = UI_block_begin(C, region, __func__ + 1, UI_EMBOSS);
|
||||
uiLayout *sub_layout = UI_block_layout(
|
||||
|
@ -774,9 +776,14 @@ static MenuSearch_Data *menu_items_from_ui_create(
|
|||
|
||||
UI_block_end(C, sub_block);
|
||||
|
||||
MenuSearch_Parent *menu_parent = (MenuSearch_Parent *)BLI_memarena_calloc(
|
||||
memarena, sizeof(*menu_parent));
|
||||
menu_parent->drawstr = strdup_memarena(memarena, but->drawstr);
|
||||
menu_parent->parent = current_menu.self_as_parent;
|
||||
|
||||
LISTBASE_FOREACH (uiBut *, sub_but, &sub_block->buttons) {
|
||||
menu_items_from_ui_create_item_from_button(
|
||||
data, memarena, mt, drawstr_submenu, sub_but, wm_context);
|
||||
data, memarena, mt, sub_but, wm_context, menu_parent);
|
||||
}
|
||||
|
||||
if (region) {
|
||||
|
@ -794,24 +801,14 @@ static MenuSearch_Data *menu_items_from_ui_create(
|
|||
|
||||
/* Add key-map items as a second pass,
|
||||
* so all menus are accessed from the header & top-bar before key shortcuts are expanded. */
|
||||
if ((menu_stack == nullptr) && (has_keymap_menu_items == false)) {
|
||||
if (menu_stack.is_empty() && (has_keymap_menu_items == false)) {
|
||||
has_keymap_menu_items = true;
|
||||
menu_types_add_from_keymap_items(
|
||||
C, win, area, region, &menu_stack, menu_to_kmi, menu_tagged);
|
||||
C, win, area, region, menu_stack, menu_to_kmi, menu_tagged);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LISTBASE_FOREACH (MenuSearch_Item *, item, &data->items) {
|
||||
item->menu_parent = (MenuSearch_Parent *)BLI_ghash_lookup(menu_parent_map, item->mt);
|
||||
}
|
||||
|
||||
GHASH_ITER (iter, menu_parent_map) {
|
||||
MenuSearch_Parent *menu_parent = (MenuSearch_Parent *)BLI_ghashIterator_getValue(&iter);
|
||||
menu_parent->parent = (MenuSearch_Parent *)BLI_ghash_lookup(menu_parent_map,
|
||||
menu_parent->parent_mt);
|
||||
}
|
||||
|
||||
/* NOTE: currently this builds the full path for each menu item,
|
||||
* that could be moved into the parent menu. */
|
||||
|
||||
|
@ -841,13 +838,13 @@ static MenuSearch_Data *menu_items_from_ui_create(
|
|||
}
|
||||
}
|
||||
else {
|
||||
const char *drawstr = (const char *)BLI_ghash_lookup(menu_display_name_map, item->mt);
|
||||
const char *drawstr = menu_display_name_map.lookup_default(item->mt, nullptr);
|
||||
if (drawstr == nullptr) {
|
||||
drawstr = CTX_IFACE_(item->mt->translation_context, item->mt->label);
|
||||
}
|
||||
BLI_dynstr_append(dyn_str, drawstr);
|
||||
|
||||
wmKeyMapItem *kmi = (wmKeyMapItem *)BLI_ghash_lookup(menu_to_kmi, item->mt);
|
||||
wmKeyMapItem *kmi = menu_to_kmi.lookup_default(item->mt, nullptr);
|
||||
if (kmi != nullptr) {
|
||||
char kmi_str[128];
|
||||
WM_keymap_item_to_string(kmi, false, kmi_str, sizeof(kmi_str));
|
||||
|
@ -857,12 +854,6 @@ static MenuSearch_Data *menu_items_from_ui_create(
|
|||
BLI_dynstr_append(dyn_str, " " UI_MENU_ARROW_SEP " ");
|
||||
}
|
||||
|
||||
/* Optional nested menu. */
|
||||
if (item->drawstr_submenu != nullptr) {
|
||||
BLI_dynstr_append(dyn_str, item->drawstr_submenu);
|
||||
BLI_dynstr_append(dyn_str, " " UI_MENU_ARROW_SEP " ");
|
||||
}
|
||||
|
||||
BLI_dynstr_append(dyn_str, item->drawstr);
|
||||
|
||||
item->drawwstr_full = strdup_memarena_from_dynstr(memarena, dyn_str);
|
||||
|
@ -875,13 +866,6 @@ static MenuSearch_Data *menu_items_from_ui_create(
|
|||
* NOTE: we might want to keep the in-menu order, for now sort all. */
|
||||
BLI_listbase_sort(&data->items, menu_item_sort_by_drawstr_full);
|
||||
|
||||
BLI_ghash_free(menu_parent_map, nullptr, nullptr);
|
||||
BLI_ghash_free(menu_display_name_map, nullptr, nullptr);
|
||||
|
||||
BLI_ghash_free(menu_to_kmi, nullptr, nullptr);
|
||||
|
||||
BLI_gset_free(menu_tagged, nullptr);
|
||||
|
||||
data->memarena = memarena;
|
||||
|
||||
if (include_all_areas) {
|
||||
|
@ -921,6 +905,7 @@ static void menu_search_arg_free_fn(void *data_v)
|
|||
WM_operator_properties_free(item->op.opptr);
|
||||
MEM_freeN(item->op.opptr);
|
||||
}
|
||||
MEM_delete(item->op.context);
|
||||
break;
|
||||
}
|
||||
case MenuSearch_Item::Type::RNA: {
|
||||
|
|
|
@ -2986,8 +2986,6 @@ static void constraint_ops_extra_draw(bContext *C, uiLayout *layout, void *con_v
|
|||
|
||||
uiLayoutSetUnitsX(layout, 4.0f);
|
||||
|
||||
UI_block_flag_enable(uiLayoutGetBlock(layout), UI_BLOCK_IS_FLIP);
|
||||
|
||||
/* Apply. */
|
||||
uiItemO(layout,
|
||||
CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Apply"),
|
||||
|
@ -3863,7 +3861,7 @@ static uiBlock *ui_icon_view_menu_cb(bContext *C, ARegion *region, void *arg_lit
|
|||
const int h = UI_UNIT_X * (args.icon_scale + args.show_labels);
|
||||
|
||||
uiBlock *block = UI_block_begin(C, region, "_popup", UI_EMBOSS_PULLDOWN);
|
||||
UI_block_flag_enable(block, UI_BLOCK_LOOP | UI_BLOCK_NO_FLIP);
|
||||
UI_block_flag_enable(block, UI_BLOCK_LOOP);
|
||||
UI_block_theme_style_set(block, UI_BLOCK_THEME_STYLE_POPUP);
|
||||
|
||||
bool free;
|
||||
|
|
|
@ -36,9 +36,9 @@
|
|||
|
||||
# include "DEG_depsgraph.h"
|
||||
|
||||
# include "IO_orientation.h"
|
||||
# include "IO_path_util_types.h"
|
||||
# include "IO_wavefront_obj.h"
|
||||
# include "IO_orientation.hh"
|
||||
# include "IO_path_util_types.hh"
|
||||
# include "IO_wavefront_obj.hh"
|
||||
|
||||
# include "io_obj.hh"
|
||||
# include "io_utils.hh"
|
||||
|
@ -83,8 +83,9 @@ static int wm_obj_export_exec(bContext *C, wmOperator *op)
|
|||
export_params.start_frame = RNA_int_get(op->ptr, "start_frame");
|
||||
export_params.end_frame = RNA_int_get(op->ptr, "end_frame");
|
||||
|
||||
export_params.forward_axis = eIOAxis(RNA_enum_get(op->ptr, "forward_axis"));
|
||||
export_params.up_axis = eIOAxis(RNA_enum_get(op->ptr, "up_axis"));
|
||||
export_params.forward_axis = blender::math::AxisSigned::from_int(
|
||||
RNA_enum_get(op->ptr, "forward_axis"));
|
||||
export_params.up_axis = blender::math::AxisSigned::from_int(RNA_enum_get(op->ptr, "up_axis"));
|
||||
export_params.global_scale = RNA_float_get(op->ptr, "global_scale");
|
||||
export_params.apply_modifiers = RNA_boolean_get(op->ptr, "apply_modifiers");
|
||||
export_params.export_eval_mode = eEvaluationMode(RNA_enum_get(op->ptr, "export_eval_mode"));
|
||||
|
@ -287,11 +288,7 @@ void WM_OT_obj_export(wmOperatorType *ot)
|
|||
INT_MIN,
|
||||
INT_MAX);
|
||||
/* Object transform options. */
|
||||
prop = RNA_def_enum(
|
||||
ot->srna, "forward_axis", io_transform_axis, IO_AXIS_NEGATIVE_Z, "Forward Axis", "");
|
||||
RNA_def_property_update_runtime(prop, io_ui_forward_axis_update);
|
||||
prop = RNA_def_enum(ot->srna, "up_axis", io_transform_axis, IO_AXIS_Y, "Up Axis", "");
|
||||
RNA_def_property_update_runtime(prop, io_ui_up_axis_update);
|
||||
io_ui_axes_register(*ot->srna);
|
||||
RNA_def_float(
|
||||
ot->srna,
|
||||
"global_scale",
|
||||
|
@ -393,8 +390,9 @@ static int wm_obj_import_exec(bContext *C, wmOperator *op)
|
|||
RNA_string_get(op->ptr, "filepath", import_params.filepath);
|
||||
import_params.global_scale = RNA_float_get(op->ptr, "global_scale");
|
||||
import_params.clamp_size = RNA_float_get(op->ptr, "clamp_size");
|
||||
import_params.forward_axis = eIOAxis(RNA_enum_get(op->ptr, "forward_axis"));
|
||||
import_params.up_axis = eIOAxis(RNA_enum_get(op->ptr, "up_axis"));
|
||||
import_params.forward_axis = blender::math::AxisSigned::from_int(
|
||||
RNA_enum_get(op->ptr, "forward_axis"));
|
||||
import_params.up_axis = blender::math::AxisSigned::from_int(RNA_enum_get(op->ptr, "up_axis"));
|
||||
import_params.use_split_objects = RNA_boolean_get(op->ptr, "use_split_objects");
|
||||
import_params.use_split_groups = RNA_boolean_get(op->ptr, "use_split_groups");
|
||||
import_params.import_vertex_groups = RNA_boolean_get(op->ptr, "import_vertex_groups");
|
||||
|
@ -517,11 +515,7 @@ void WM_OT_obj_import(wmOperatorType *ot)
|
|||
"Resize the objects to keep bounding box under this value. Value 0 disables clamping",
|
||||
0.0f,
|
||||
1000.0f);
|
||||
prop = RNA_def_enum(
|
||||
ot->srna, "forward_axis", io_transform_axis, IO_AXIS_NEGATIVE_Z, "Forward Axis", "");
|
||||
RNA_def_property_update_runtime(prop, io_ui_forward_axis_update);
|
||||
prop = RNA_def_enum(ot->srna, "up_axis", io_transform_axis, IO_AXIS_Y, "Up Axis", "");
|
||||
RNA_def_property_update_runtime(prop, io_ui_up_axis_update);
|
||||
io_ui_axes_register(*ot->srna);
|
||||
RNA_def_boolean(ot->srna,
|
||||
"use_split_objects",
|
||||
true,
|
||||
|
|
|
@ -32,10 +32,10 @@
|
|||
|
||||
# include "DEG_depsgraph.h"
|
||||
|
||||
# include "IO_orientation.h"
|
||||
# include "IO_path_util_types.h"
|
||||
# include "IO_orientation.hh"
|
||||
# include "IO_path_util_types.hh"
|
||||
|
||||
# include "IO_ply.h"
|
||||
# include "IO_ply.hh"
|
||||
# include "io_ply_ops.hh"
|
||||
# include "io_utils.hh"
|
||||
|
||||
|
@ -72,8 +72,9 @@ static int wm_ply_export_exec(bContext *C, wmOperator *op)
|
|||
RNA_string_get(op->ptr, "filepath", export_params.filepath);
|
||||
export_params.blen_filepath = CTX_data_main(C)->filepath;
|
||||
|
||||
export_params.forward_axis = eIOAxis(RNA_enum_get(op->ptr, "forward_axis"));
|
||||
export_params.up_axis = eIOAxis(RNA_enum_get(op->ptr, "up_axis"));
|
||||
export_params.forward_axis = blender::math::AxisSigned::from_int(
|
||||
RNA_enum_get(op->ptr, "forward_axis"));
|
||||
export_params.up_axis = blender::math::AxisSigned::from_int(RNA_enum_get(op->ptr, "up_axis"));
|
||||
export_params.global_scale = RNA_float_get(op->ptr, "global_scale");
|
||||
export_params.apply_modifiers = RNA_boolean_get(op->ptr, "apply_modifiers");
|
||||
|
||||
|
@ -178,10 +179,7 @@ void WM_OT_ply_export(wmOperatorType *ot)
|
|||
FILE_SORT_DEFAULT);
|
||||
|
||||
/* Object transform options. */
|
||||
prop = RNA_def_enum(ot->srna, "forward_axis", io_transform_axis, IO_AXIS_Y, "Forward Axis", "");
|
||||
RNA_def_property_update_runtime(prop, io_ui_forward_axis_update);
|
||||
prop = RNA_def_enum(ot->srna, "up_axis", io_transform_axis, IO_AXIS_Z, "Up Axis", "");
|
||||
RNA_def_property_update_runtime(prop, io_ui_up_axis_update);
|
||||
io_ui_axes_register(*ot->srna);
|
||||
RNA_def_float(
|
||||
ot->srna,
|
||||
"global_scale",
|
||||
|
@ -235,8 +233,8 @@ void WM_OT_ply_export(wmOperatorType *ot)
|
|||
static int wm_ply_import_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
PLYImportParams params{};
|
||||
params.forward_axis = eIOAxis(RNA_enum_get(op->ptr, "forward_axis"));
|
||||
params.up_axis = eIOAxis(RNA_enum_get(op->ptr, "up_axis"));
|
||||
params.forward_axis = blender::math::AxisSigned::from_int(RNA_enum_get(op->ptr, "forward_axis"));
|
||||
params.up_axis = blender::math::AxisSigned::from_int(RNA_enum_get(op->ptr, "up_axis"));
|
||||
params.use_scene_unit = RNA_boolean_get(op->ptr, "use_scene_unit");
|
||||
params.global_scale = RNA_float_get(op->ptr, "global_scale");
|
||||
params.merge_verts = RNA_boolean_get(op->ptr, "merge_verts");
|
||||
|
@ -330,10 +328,7 @@ void WM_OT_ply_import(wmOperatorType *ot)
|
|||
false,
|
||||
"Scene Unit",
|
||||
"Apply current scene's unit (as defined by unit scale) to imported data");
|
||||
prop = RNA_def_enum(ot->srna, "forward_axis", io_transform_axis, IO_AXIS_Y, "Forward Axis", "");
|
||||
RNA_def_property_update_runtime(prop, io_ui_forward_axis_update);
|
||||
prop = RNA_def_enum(ot->srna, "up_axis", io_transform_axis, IO_AXIS_Z, "Up Axis", "");
|
||||
RNA_def_property_update_runtime(prop, io_ui_up_axis_update);
|
||||
io_ui_axes_register(*ot->srna);
|
||||
RNA_def_boolean(ot->srna, "merge_verts", false, "Merge Vertices", "Merges vertices by distance");
|
||||
RNA_def_enum(ot->srna,
|
||||
"import_colors",
|
||||
|
|
|
@ -26,15 +26,19 @@
|
|||
# include "UI_interface.hh"
|
||||
# include "UI_resources.hh"
|
||||
|
||||
# include "IO_stl.h"
|
||||
# include "UI_interface.hh"
|
||||
# include "UI_resources.hh"
|
||||
|
||||
# include "IO_orientation.hh"
|
||||
# include "IO_stl.hh"
|
||||
# include "io_stl_ops.hh"
|
||||
# include "io_utils.hh"
|
||||
|
||||
static int wm_stl_import_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
STLImportParams params{};
|
||||
params.forward_axis = eIOAxis(RNA_enum_get(op->ptr, "forward_axis"));
|
||||
params.up_axis = eIOAxis(RNA_enum_get(op->ptr, "up_axis"));
|
||||
params.forward_axis = blender::math::AxisSigned::from_int(RNA_enum_get(op->ptr, "forward_axis"));
|
||||
params.up_axis = blender::math::AxisSigned::from_int(RNA_enum_get(op->ptr, "up_axis"));
|
||||
params.use_facet_normal = RNA_boolean_get(op->ptr, "use_facet_normal");
|
||||
params.use_scene_unit = RNA_boolean_get(op->ptr, "use_scene_unit");
|
||||
params.global_scale = RNA_float_get(op->ptr, "global_scale");
|
||||
|
@ -146,8 +150,7 @@ void WM_OT_stl_import(wmOperatorType *ot)
|
|||
false,
|
||||
"Facet Normals",
|
||||
"Use (import) facet normals (note that this will still give flat shading)");
|
||||
RNA_def_enum(ot->srna, "forward_axis", io_transform_axis, IO_AXIS_Y, "Forward Axis", "");
|
||||
RNA_def_enum(ot->srna, "up_axis", io_transform_axis, IO_AXIS_Z, "Up Axis", "");
|
||||
io_ui_axes_register(*ot->srna);
|
||||
RNA_def_boolean(ot->srna,
|
||||
"use_mesh_validate",
|
||||
false,
|
||||
|
|
|
@ -825,10 +825,6 @@ static void undomesh_to_editmesh(UndoMesh *um, Object *ob, BMEditMesh *em)
|
|||
em_tmp = BKE_editmesh_create(bm);
|
||||
*em = *em_tmp;
|
||||
|
||||
/* Normals should not be stored in the undo mesh, so recalculate them. The edit
|
||||
* mesh is expected to have valid normals and there is no tracked dirty state. */
|
||||
BLI_assert(BKE_mesh_vert_normals_are_dirty(&um->me));
|
||||
|
||||
/* Calculate face normals and tessellation at once since it's multi-threaded. */
|
||||
BKE_editmesh_looptri_and_normals_calc(em);
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
#include "BKE_lib_id.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_mesh.hh"
|
||||
#include "BKE_node_runtime.hh"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_pointcloud.h"
|
||||
#include "BKE_report.h"
|
||||
|
@ -98,7 +99,14 @@ static void calculate_simulation_job_startjob(void *customdata,
|
|||
LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
|
||||
if (md->type == eModifierType_Nodes) {
|
||||
NodesModifierData *nmd = reinterpret_cast<NodesModifierData *>(md);
|
||||
nmd->runtime->simulation_cache->reset();
|
||||
if (!nmd->runtime->simulation_cache) {
|
||||
continue;
|
||||
}
|
||||
for (auto item : nmd->runtime->simulation_cache->cache_by_zone_id.items()) {
|
||||
if (item.value->cache_state != CacheState::Baked) {
|
||||
item.value->reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
objects_to_calc.append(object);
|
||||
|
@ -214,10 +222,15 @@ static bool bake_simulation_poll(bContext *C)
|
|||
return true;
|
||||
}
|
||||
|
||||
struct ZoneBakeData {
|
||||
int zone_id;
|
||||
bke::bake_paths::BakePath path;
|
||||
std::unique_ptr<bke::BDataSharing> bdata_sharing;
|
||||
};
|
||||
|
||||
struct ModifierBakeData {
|
||||
NodesModifierData *nmd;
|
||||
std::string absolute_bake_dir;
|
||||
std::unique_ptr<bke::BDataSharing> bdata_sharing;
|
||||
Vector<ZoneBakeData> zones;
|
||||
};
|
||||
|
||||
struct ObjectBakeData {
|
||||
|
@ -251,19 +264,38 @@ static void bake_simulation_job_startjob(void *customdata,
|
|||
continue;
|
||||
}
|
||||
|
||||
const char *base_path = ID_BLEND_PATH(job.bmain, &object->id);
|
||||
|
||||
ObjectBakeData bake_data;
|
||||
bake_data.object = object;
|
||||
LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
|
||||
if (md->type == eModifierType_Nodes) {
|
||||
NodesModifierData *nmd = reinterpret_cast<NodesModifierData *>(md);
|
||||
nmd->runtime->simulation_cache->reset();
|
||||
char absolute_bake_dir[FILE_MAX];
|
||||
STRNCPY(absolute_bake_dir, nmd->simulation_bake_directory);
|
||||
BLI_path_abs(absolute_bake_dir, base_path);
|
||||
bake_data.modifiers.append(
|
||||
{nmd, absolute_bake_dir, std::make_unique<bke::BDataSharing>()});
|
||||
if (!nmd->node_group) {
|
||||
continue;
|
||||
}
|
||||
if (!nmd->runtime->simulation_cache) {
|
||||
continue;
|
||||
}
|
||||
ModifierBakeData modifier_bake_data;
|
||||
modifier_bake_data.nmd = nmd;
|
||||
|
||||
for (auto item : nmd->runtime->simulation_cache->cache_by_zone_id.items()) {
|
||||
item.value->reset();
|
||||
}
|
||||
|
||||
for (const bNestedNodeRef &nested_node_ref : nmd->node_group->nested_node_refs_span()) {
|
||||
ZoneBakeData zone_bake_data;
|
||||
zone_bake_data.zone_id = nested_node_ref.id;
|
||||
zone_bake_data.bdata_sharing = std::make_unique<bke::BDataSharing>();
|
||||
if (std::optional<bke::bake_paths::BakePath> path =
|
||||
bke::sim::get_simulation_zone_bake_path(
|
||||
*job.bmain, *object, *nmd, nested_node_ref.id))
|
||||
{
|
||||
zone_bake_data.path = std::move(*path);
|
||||
modifier_bake_data.zones.append(std::move(zone_bake_data));
|
||||
}
|
||||
}
|
||||
|
||||
bake_data.modifiers.append(std::move(modifier_bake_data));
|
||||
}
|
||||
}
|
||||
objects_to_bake.append(std::move(bake_data));
|
||||
|
@ -288,51 +320,56 @@ static void bake_simulation_job_startjob(void *customdata,
|
|||
job.scene->r.cfra = frame.frame();
|
||||
job.scene->r.subframe = frame.subframe();
|
||||
|
||||
char frame_file_c_str[64];
|
||||
SNPRINTF(frame_file_c_str, "%011.5f", double(frame));
|
||||
BLI_string_replace_char(frame_file_c_str, '.', '_');
|
||||
const StringRefNull frame_file_str = frame_file_c_str;
|
||||
|
||||
BKE_scene_graph_update_for_newframe(job.depsgraph);
|
||||
|
||||
const std::string frame_file_name = bke::bake_paths::frame_to_file_name(frame);
|
||||
|
||||
for (ObjectBakeData &object_bake_data : objects_to_bake) {
|
||||
for (ModifierBakeData &modifier_bake_data : object_bake_data.modifiers) {
|
||||
NodesModifierData &nmd = *modifier_bake_data.nmd;
|
||||
if (!nmd.runtime->simulation_cache) {
|
||||
continue;
|
||||
const ModifierSimulationCache &simulation_cache = *nmd.runtime->simulation_cache;
|
||||
for (ZoneBakeData &zone_bake_data : modifier_bake_data.zones) {
|
||||
if (!simulation_cache.cache_by_zone_id.contains(zone_bake_data.zone_id)) {
|
||||
continue;
|
||||
}
|
||||
const SimulationZoneCache &zone_cache = *simulation_cache.cache_by_zone_id.lookup(
|
||||
zone_bake_data.zone_id);
|
||||
if (zone_cache.frame_caches.is_empty()) {
|
||||
continue;
|
||||
}
|
||||
const SimulationZoneFrameCache &frame_cache = *zone_cache.frame_caches.last();
|
||||
if (frame_cache.frame != frame) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const bke::bake_paths::BakePath path = zone_bake_data.path;
|
||||
|
||||
const std::string bdata_file_name = frame_file_name + ".bdata";
|
||||
|
||||
char bdata_path[FILE_MAX];
|
||||
BLI_path_join(
|
||||
bdata_path, sizeof(bdata_path), path.bdata_dir.c_str(), bdata_file_name.c_str());
|
||||
char meta_path[FILE_MAX];
|
||||
BLI_path_join(meta_path,
|
||||
sizeof(meta_path),
|
||||
path.meta_dir.c_str(),
|
||||
(frame_file_name + ".json").c_str());
|
||||
BLI_file_ensure_parent_dir_exists(meta_path);
|
||||
BLI_file_ensure_parent_dir_exists(bdata_path);
|
||||
fstream bdata_file{bdata_path, std::ios::out | std::ios::binary};
|
||||
bke::DiskBDataWriter bdata_writer{bdata_file_name, bdata_file, 0};
|
||||
|
||||
io::serialize::DictionaryValue io_root;
|
||||
io_root.append_int("version", simulation_file_storage_version);
|
||||
io::serialize::DictionaryValue &io_items = *io_root.append_dict("items");
|
||||
for (auto item : frame_cache.items.items()) {
|
||||
io::serialize::DictionaryValue &io_item = *io_items.append_dict(
|
||||
std::to_string(item.key));
|
||||
bke::serialize_bake_item(
|
||||
*item.value, bdata_writer, *zone_bake_data.bdata_sharing, io_item);
|
||||
}
|
||||
io::serialize::write_json_file(meta_path, io_root);
|
||||
}
|
||||
ModifierSimulationCache &sim_cache = *nmd.runtime->simulation_cache;
|
||||
const ModifierSimulationState *sim_state = sim_cache.get_state_at_exact_frame(frame);
|
||||
if (sim_state == nullptr || sim_state->zone_states_.is_empty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const std::string bdata_file_name = frame_file_str + ".bdata";
|
||||
const std::string meta_file_name = frame_file_str + ".json";
|
||||
|
||||
char bdata_path[FILE_MAX];
|
||||
BLI_path_join(bdata_path,
|
||||
sizeof(bdata_path),
|
||||
modifier_bake_data.absolute_bake_dir.c_str(),
|
||||
"bdata",
|
||||
bdata_file_name.c_str());
|
||||
char meta_path[FILE_MAX];
|
||||
BLI_path_join(meta_path,
|
||||
sizeof(meta_path),
|
||||
modifier_bake_data.absolute_bake_dir.c_str(),
|
||||
"meta",
|
||||
meta_file_name.c_str());
|
||||
|
||||
BLI_file_ensure_parent_dir_exists(bdata_path);
|
||||
fstream bdata_file{bdata_path, std::ios::out | std::ios::binary};
|
||||
bke::DiskBDataWriter bdata_writer{bdata_file_name, bdata_file, 0};
|
||||
|
||||
io::serialize::DictionaryValue io_root;
|
||||
bke::sim::serialize_modifier_simulation_state(
|
||||
*sim_state, bdata_writer, *modifier_bake_data.bdata_sharing, io_root);
|
||||
|
||||
BLI_file_ensure_parent_dir_exists(meta_path);
|
||||
io::serialize::write_json_file(meta_path, io_root);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -343,9 +380,13 @@ static void bake_simulation_job_startjob(void *customdata,
|
|||
for (ObjectBakeData &object_bake_data : objects_to_bake) {
|
||||
for (ModifierBakeData &modifier_bake_data : object_bake_data.modifiers) {
|
||||
NodesModifierData &nmd = *modifier_bake_data.nmd;
|
||||
if (nmd.runtime->simulation_cache) {
|
||||
/* Tag the caches as being baked so that they are not changed anymore. */
|
||||
nmd.runtime->simulation_cache->cache_state = CacheState::Baked;
|
||||
for (ZoneBakeData &zone_bake_data : modifier_bake_data.zones) {
|
||||
if (std::unique_ptr<SimulationZoneCache> &zone_cache =
|
||||
nmd.runtime->simulation_cache->cache_by_zone_id.lookup(zone_bake_data.zone_id))
|
||||
{
|
||||
/* Tag the caches as being baked so that they are not changed anymore. */
|
||||
zone_cache->cache_state = CacheState::Baked;
|
||||
}
|
||||
}
|
||||
}
|
||||
DEG_id_tag_update(&object_bake_data.object->id, ID_RECALC_GEOMETRY);
|
||||
|
@ -593,40 +634,45 @@ static int delete_baked_simulation_exec(bContext *C, wmOperator *op)
|
|||
}
|
||||
|
||||
for (Object *object : objects) {
|
||||
const char *base_path = ID_BLEND_PATH(bmain, &object->id);
|
||||
LISTBASE_FOREACH (ModifierData *, md, &object->modifiers) {
|
||||
if (md->type == eModifierType_Nodes) {
|
||||
NodesModifierData *nmd = reinterpret_cast<NodesModifierData *>(md);
|
||||
nmd->runtime->simulation_cache->reset();
|
||||
if (StringRef(nmd->simulation_bake_directory).is_empty()) {
|
||||
if (!nmd->runtime->simulation_cache) {
|
||||
continue;
|
||||
}
|
||||
char absolute_bake_dir[FILE_MAX];
|
||||
STRNCPY(absolute_bake_dir, nmd->simulation_bake_directory);
|
||||
BLI_path_abs(absolute_bake_dir, base_path);
|
||||
for (auto item : nmd->runtime->simulation_cache->cache_by_zone_id.items()) {
|
||||
item.value->reset();
|
||||
|
||||
char meta_dir[FILE_MAX];
|
||||
BLI_path_join(meta_dir, sizeof(meta_dir), absolute_bake_dir, "meta");
|
||||
char bdata_dir[FILE_MAX];
|
||||
BLI_path_join(bdata_dir, sizeof(bdata_dir), absolute_bake_dir, "bdata");
|
||||
const std::optional<bke::bake_paths::BakePath> bake_path =
|
||||
bke::sim::get_simulation_zone_bake_path(*bmain, *object, *nmd, item.key);
|
||||
if (!bake_path) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (BLI_exists(absolute_bake_dir)) {
|
||||
const char *meta_dir = bake_path->meta_dir.c_str();
|
||||
if (BLI_exists(meta_dir)) {
|
||||
if (BLI_delete(meta_dir, true, true)) {
|
||||
BKE_reportf(op->reports, RPT_ERROR, "Failed to remove meta directory %s", meta_dir);
|
||||
}
|
||||
}
|
||||
const char *bdata_dir = bake_path->bdata_dir.c_str();
|
||||
if (BLI_exists(bdata_dir)) {
|
||||
if (BLI_delete(bdata_dir, true, true)) {
|
||||
BKE_reportf(
|
||||
op->reports, RPT_ERROR, "Failed to remove bdata directory %s", bdata_dir);
|
||||
}
|
||||
}
|
||||
/* Delete the folder if it's empty. */
|
||||
BLI_delete(absolute_bake_dir, true, false);
|
||||
if (bake_path->bake_dir.has_value()) {
|
||||
const char *zone_bake_dir = bake_path->bake_dir->c_str();
|
||||
/* Try to delete zone bake directory if it is empty. */
|
||||
BLI_delete(zone_bake_dir, true, false);
|
||||
}
|
||||
}
|
||||
else {
|
||||
BKE_reportf(op->reports, RPT_ERROR, "Bake directory %s not found", absolute_bake_dir);
|
||||
if (const std::optional<std::string> modifier_bake_dir =
|
||||
bke::sim::get_modifier_simulation_bake_path(*bmain, *object, *nmd))
|
||||
{
|
||||
/* Try to delete modifier bake directory if it is empty. */
|
||||
BLI_delete(modifier_bake_dir->c_str(), true, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2062,8 +2062,6 @@ static void move_to_collection_menu_create(bContext *C, uiLayout *layout, void *
|
|||
MoveToCollectionData *menu = static_cast<MoveToCollectionData *>(menu_v);
|
||||
const char *name = BKE_collection_ui_name_get(menu->collection);
|
||||
|
||||
UI_block_flag_enable(uiLayoutGetBlock(layout), UI_BLOCK_IS_FLIP);
|
||||
|
||||
WM_operator_properties_create_ptr(&menu->ptr, menu->ot);
|
||||
RNA_int_set(&menu->ptr, "collection_index", menu->index);
|
||||
RNA_boolean_set(&menu->ptr, "is_new", true);
|
||||
|
|
|
@ -473,8 +473,6 @@ static void workspace_add_menu(bContext * /*C*/, uiLayout *layout, void *templat
|
|||
WorkspaceConfigFileData *startup_config = workspace_config_file_read(app_template);
|
||||
WorkspaceConfigFileData *builtin_config = workspace_system_file_read(app_template);
|
||||
|
||||
UI_block_flag_enable(uiLayoutGetBlock(layout), UI_BLOCK_IS_FLIP);
|
||||
|
||||
if (startup_config) {
|
||||
LISTBASE_FOREACH (WorkSpace *, workspace, &startup_config->workspaces) {
|
||||
uiLayout *row = uiLayoutRow(layout, false);
|
||||
|
|
|
@ -748,19 +748,30 @@ static void timeline_cache_draw_single(PTCacheID *pid, float y_offset, float hei
|
|||
}
|
||||
|
||||
static void timeline_cache_draw_simulation_nodes(
|
||||
const Scene &scene,
|
||||
const blender::bke::sim::ModifierSimulationCache &cache,
|
||||
const float y_offset,
|
||||
const float height,
|
||||
const uint pos_id)
|
||||
{
|
||||
std::lock_guard lock{cache.mutex};
|
||||
if (cache.cache_by_zone_id.is_empty()) {
|
||||
return;
|
||||
}
|
||||
/* Draw the state if one of the simulation zones. This is fine for now, because there is no ui
|
||||
* that allows caching zones independently. */
|
||||
const blender::bke::sim::SimulationZoneCache &zone_cache =
|
||||
**cache.cache_by_zone_id.values().begin();
|
||||
if (zone_cache.frame_caches.is_empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
GPU_matrix_push();
|
||||
GPU_matrix_translate_2f(0.0, float(V2D_SCROLL_HANDLE_HEIGHT) + y_offset);
|
||||
GPU_matrix_scale_2f(1.0, height);
|
||||
|
||||
float color[4];
|
||||
UI_GetThemeColor4fv(TH_SIMULATED_FRAMES, color);
|
||||
switch (cache.cache_state) {
|
||||
switch (zone_cache.cache_state) {
|
||||
case blender::bke::sim::CacheState::Invalid: {
|
||||
color[3] = 0.4f;
|
||||
break;
|
||||
|
@ -777,16 +788,13 @@ static void timeline_cache_draw_simulation_nodes(
|
|||
|
||||
immUniformColor4fv(color);
|
||||
|
||||
const int start_frame = scene.r.sfra;
|
||||
const int end_frame = scene.r.efra;
|
||||
const int frames_num = end_frame - start_frame + 1;
|
||||
const blender::IndexRange frames_range(start_frame, frames_num);
|
||||
immBeginAtMost(GPU_PRIM_TRIS, zone_cache.frame_caches.size() * 6);
|
||||
|
||||
immBeginAtMost(GPU_PRIM_TRIS, frames_num * 6);
|
||||
for (const int frame : frames_range) {
|
||||
if (cache.has_state_at_frame(frame)) {
|
||||
immRectf_fast(pos_id, frame - 0.5f, 0, frame + 0.5f, 1.0f);
|
||||
}
|
||||
for (const std::unique_ptr<blender::bke::sim::SimulationZoneFrameCache> &frame_cache :
|
||||
zone_cache.frame_caches.as_span())
|
||||
{
|
||||
const int frame = frame_cache->frame.frame();
|
||||
immRectf_fast(pos_id, frame - 0.5f, 0, frame + 0.5f, 1.0f);
|
||||
}
|
||||
immEnd();
|
||||
|
||||
|
@ -840,7 +848,7 @@ void timeline_draw_cache(const SpaceAction *saction, const Object *ob, const Sce
|
|||
continue;
|
||||
}
|
||||
timeline_cache_draw_simulation_nodes(
|
||||
*scene, *nmd->runtime->simulation_cache, y_offset, cache_draw_height, pos_id);
|
||||
*nmd->runtime->simulation_cache, y_offset, cache_draw_height, pos_id);
|
||||
y_offset += cache_draw_height;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -533,8 +533,6 @@ static void template_texture_user_menu(bContext *C, uiLayout *layout, void * /*a
|
|||
|
||||
last_category = user->category;
|
||||
}
|
||||
|
||||
UI_block_flag_enable(block, UI_BLOCK_NO_FLIP);
|
||||
}
|
||||
|
||||
void uiTemplateTextureUser(uiLayout *layout, bContext *C)
|
||||
|
|
|
@ -122,6 +122,7 @@ void GRAPH_OT_ease(struct wmOperatorType *ot);
|
|||
void GRAPH_OT_blend_offset(struct wmOperatorType *ot);
|
||||
void GRAPH_OT_blend_to_ease(struct wmOperatorType *ot);
|
||||
void GRAPH_OT_match_slope(struct wmOperatorType *ot);
|
||||
void GRAPH_OT_shear(struct wmOperatorType *ot);
|
||||
void GRAPH_OT_decimate(struct wmOperatorType *ot);
|
||||
void GRAPH_OT_blend_to_default(struct wmOperatorType *ot);
|
||||
void GRAPH_OT_butterworth_smooth(struct wmOperatorType *ot);
|
||||
|
|
|
@ -469,6 +469,7 @@ void graphedit_operatortypes()
|
|||
WM_operatortype_append(GRAPH_OT_blend_to_neighbor);
|
||||
WM_operatortype_append(GRAPH_OT_breakdown);
|
||||
WM_operatortype_append(GRAPH_OT_ease);
|
||||
WM_operatortype_append(GRAPH_OT_shear);
|
||||
WM_operatortype_append(GRAPH_OT_blend_offset);
|
||||
WM_operatortype_append(GRAPH_OT_blend_to_ease);
|
||||
WM_operatortype_append(GRAPH_OT_match_slope);
|
||||
|
|
|
@ -1162,8 +1162,8 @@ void GRAPH_OT_blend_to_ease(wmOperatorType *ot)
|
|||
0.0f,
|
||||
-FLT_MAX,
|
||||
FLT_MAX,
|
||||
"Curve Bend",
|
||||
"Control the bend of the curve",
|
||||
"Blend",
|
||||
"Favor either original data or ease curve",
|
||||
-1.0f,
|
||||
1.0f);
|
||||
}
|
||||
|
@ -1290,6 +1290,176 @@ void GRAPH_OT_match_slope(wmOperatorType *ot)
|
|||
1.0f);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Shear Operator
|
||||
* \{ */
|
||||
|
||||
static const EnumPropertyItem shear_direction_items[] = {
|
||||
{SHEAR_FROM_LEFT, "FROM_LEFT", 0, "From Left", "foo"},
|
||||
{SHEAR_FROM_RIGHT, "FROM_RIGHT", 0, "From Right", "foo"},
|
||||
{0, nullptr, 0, nullptr, nullptr},
|
||||
};
|
||||
|
||||
static void shear_graph_keys(bAnimContext *ac, const float factor, tShearDirection direction)
|
||||
{
|
||||
ListBase anim_data = {nullptr, nullptr};
|
||||
|
||||
ANIM_animdata_filter(
|
||||
ac, &anim_data, OPERATOR_DATA_FILTER, ac->data, eAnimCont_Types(ac->datatype));
|
||||
LISTBASE_FOREACH (bAnimListElem *, ale, &anim_data) {
|
||||
FCurve *fcu = (FCurve *)ale->key_data;
|
||||
ListBase segments = find_fcurve_segments(fcu);
|
||||
|
||||
LISTBASE_FOREACH (FCurveSegment *, segment, &segments) {
|
||||
shear_fcurve_segment(fcu, segment, factor, direction);
|
||||
}
|
||||
|
||||
ale->update |= ANIM_UPDATE_DEFAULT;
|
||||
BLI_freelistN(&segments);
|
||||
}
|
||||
|
||||
ANIM_animdata_update(ac, &anim_data);
|
||||
ANIM_animdata_freelist(&anim_data);
|
||||
}
|
||||
|
||||
static void shear_draw_status_header(bContext *C, tGraphSliderOp *gso)
|
||||
{
|
||||
char status_str[UI_MAX_DRAW_STR];
|
||||
char mode_str[32];
|
||||
char slider_string[UI_MAX_DRAW_STR];
|
||||
ED_slider_status_string_get(gso->slider, slider_string, UI_MAX_DRAW_STR);
|
||||
|
||||
STRNCPY(mode_str, TIP_("Shear Keys"));
|
||||
|
||||
if (hasNumInput(&gso->num)) {
|
||||
char str_ofs[NUM_STR_REP_LEN];
|
||||
|
||||
outputNumInput(&gso->num, str_ofs, &gso->scene->unit);
|
||||
|
||||
SNPRINTF(status_str, "%s: %s", mode_str, str_ofs);
|
||||
}
|
||||
else {
|
||||
const char *operator_string = "D - Toggle Direction";
|
||||
SNPRINTF(status_str, "%s: %s | %s", mode_str, slider_string, operator_string);
|
||||
}
|
||||
|
||||
ED_workspace_status_text(C, status_str);
|
||||
}
|
||||
|
||||
static void shear_modal_update(bContext *C, wmOperator *op)
|
||||
{
|
||||
tGraphSliderOp *gso = static_cast<tGraphSliderOp *>(op->customdata);
|
||||
|
||||
shear_draw_status_header(C, gso);
|
||||
|
||||
/* Reset keyframes to the state at invoke. */
|
||||
reset_bezts(gso);
|
||||
const float factor = slider_factor_get_and_remember(op);
|
||||
const tShearDirection direction = tShearDirection(RNA_enum_get(op->ptr, "direction"));
|
||||
|
||||
shear_graph_keys(&gso->ac, factor, direction);
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
|
||||
}
|
||||
|
||||
static int shear_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
{
|
||||
if (event->val != KM_PRESS) {
|
||||
return graph_slider_modal(C, op, event);
|
||||
}
|
||||
|
||||
switch (event->type) {
|
||||
{
|
||||
case EVT_DKEY: {
|
||||
tShearDirection direction = tShearDirection(RNA_enum_get(op->ptr, "direction"));
|
||||
RNA_enum_set(op->ptr,
|
||||
"direction",
|
||||
(direction == SHEAR_FROM_LEFT) ? SHEAR_FROM_RIGHT : SHEAR_FROM_LEFT);
|
||||
shear_modal_update(C, op);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
return graph_slider_modal(C, op, event);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
||||
static int shear_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
{
|
||||
const int invoke_result = graph_slider_invoke(C, op, event);
|
||||
|
||||
if (invoke_result == OPERATOR_CANCELLED) {
|
||||
return invoke_result;
|
||||
}
|
||||
|
||||
tGraphSliderOp *gso = static_cast<tGraphSliderOp *>(op->customdata);
|
||||
gso->modal_update = shear_modal_update;
|
||||
gso->factor_prop = RNA_struct_find_property(op->ptr, "factor");
|
||||
shear_draw_status_header(C, gso);
|
||||
ED_slider_factor_bounds_set(gso->slider, -1, 1);
|
||||
ED_slider_factor_set(gso->slider, 0.0f);
|
||||
|
||||
return invoke_result;
|
||||
}
|
||||
|
||||
static int shear_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
bAnimContext ac;
|
||||
|
||||
/* Get editor data. */
|
||||
if (ANIM_animdata_get_context(C, &ac) == 0) {
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
const float factor = RNA_float_get(op->ptr, "factor");
|
||||
const tShearDirection direction = tShearDirection(RNA_enum_get(op->ptr, "direction"));
|
||||
|
||||
shear_graph_keys(&ac, factor, direction);
|
||||
|
||||
/* Set notifier that keyframes have changed. */
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void GRAPH_OT_shear(wmOperatorType *ot)
|
||||
{
|
||||
/* Identifiers. */
|
||||
ot->name = "Shear Keyframes";
|
||||
ot->idname = "GRAPH_OT_shear";
|
||||
ot->description =
|
||||
"Affects the value of the keys linearly keeping the same \n\
|
||||
relationship between them using either the left or the right key as reference";
|
||||
|
||||
/* API callbacks. */
|
||||
ot->invoke = shear_invoke;
|
||||
ot->modal = shear_modal;
|
||||
ot->exec = shear_exec;
|
||||
ot->poll = graphop_editable_keyframes_poll;
|
||||
|
||||
/* Flags. */
|
||||
ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
|
||||
|
||||
RNA_def_float_factor(ot->srna,
|
||||
"factor",
|
||||
0.0f,
|
||||
-FLT_MAX,
|
||||
FLT_MAX,
|
||||
"Shear Factor",
|
||||
"The amount of shear to apply",
|
||||
-1.0f,
|
||||
1.0f);
|
||||
|
||||
RNA_def_enum(ot->srna,
|
||||
"direction",
|
||||
shear_direction_items,
|
||||
SHEAR_FROM_LEFT,
|
||||
"Direction",
|
||||
"Which end of the segment to use as a reference to shear from");
|
||||
}
|
||||
|
||||
/** \} */
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Gauss Smooth Operator
|
||||
|
|
|
@ -200,6 +200,7 @@ MenuType add_catalog_assets_menu_type()
|
|||
type.poll = node_add_menu_poll;
|
||||
type.draw = node_add_catalog_assets_draw;
|
||||
type.listener = asset::asset_reading_region_listen_fn;
|
||||
type.context_dependent = true;
|
||||
return type;
|
||||
}
|
||||
|
||||
|
|
|
@ -87,16 +87,14 @@ static void add_reroute_node_fn(nodes::LinkSearchOpParams ¶ms)
|
|||
static void add_group_input_node_fn(nodes::LinkSearchOpParams ¶ms)
|
||||
{
|
||||
/* Add a group input based on the connected socket, and add a new group input node. */
|
||||
const eNodeSocketInOut in_out = eNodeSocketInOut(params.socket.in_out);
|
||||
NodeTreeInterfaceSocketFlag flag = NodeTreeInterfaceSocketFlag(0);
|
||||
SET_FLAG_FROM_TEST(flag, in_out & SOCK_IN, NODE_INTERFACE_SOCKET_INPUT);
|
||||
SET_FLAG_FROM_TEST(flag, in_out & SOCK_OUT, NODE_INTERFACE_SOCKET_OUTPUT);
|
||||
bNodeTreeInterfaceSocket *socket_iface = params.node_tree.tree_interface.add_socket(
|
||||
params.socket.name,
|
||||
params.socket.description,
|
||||
params.socket.typeinfo->idname,
|
||||
flag,
|
||||
NODE_INTERFACE_SOCKET_INPUT,
|
||||
nullptr);
|
||||
BKE_ntree_update_tag_interface(¶ms.node_tree);
|
||||
|
||||
bNode &group_input = params.add_node("NodeGroupInput");
|
||||
|
||||
/* This is necessary to create the new sockets in the other input nodes. */
|
||||
|
@ -105,7 +103,8 @@ static void add_group_input_node_fn(nodes::LinkSearchOpParams ¶ms)
|
|||
/* Hide the new input in all other group input nodes, to avoid making them taller. */
|
||||
for (bNode *node : params.node_tree.all_nodes()) {
|
||||
if (node->type == NODE_GROUP_INPUT) {
|
||||
bNodeSocket *new_group_input_socket = nodeFindSocket(node, in_out, socket_iface->identifier);
|
||||
bNodeSocket *new_group_input_socket = nodeFindSocket(
|
||||
node, SOCK_OUT, socket_iface->identifier);
|
||||
if (new_group_input_socket) {
|
||||
new_group_input_socket->flag |= SOCK_HIDDEN;
|
||||
}
|
||||
|
@ -117,7 +116,7 @@ static void add_group_input_node_fn(nodes::LinkSearchOpParams ¶ms)
|
|||
socket->flag |= SOCK_HIDDEN;
|
||||
}
|
||||
|
||||
bNodeSocket *socket = nodeFindSocket(&group_input, in_out, socket_iface->identifier);
|
||||
bNodeSocket *socket = nodeFindSocket(&group_input, SOCK_OUT, socket_iface->identifier);
|
||||
if (socket) {
|
||||
/* Unhide the socket for the new input in the new node and make a connection to it. */
|
||||
socket->flag &= ~SOCK_HIDDEN;
|
||||
|
|
|
@ -148,7 +148,7 @@ static bNode *node_under_mouse_select(const SpaceNode &snode, const float2 mouse
|
|||
|
||||
static bool node_under_mouse_tweak(const SpaceNode &snode, const float2 &mouse)
|
||||
{
|
||||
const bNodeTree ntree = *snode.edittree;
|
||||
const bNodeTree &ntree = *snode.edittree;
|
||||
LISTBASE_FOREACH_BACKWARD (const bNode *, node, &ntree.nodes) {
|
||||
switch (node->type) {
|
||||
case NODE_REROUTE: {
|
||||
|
|
|
@ -651,7 +651,6 @@ static void ui_template_node_link_menu(bContext *C, uiLayout *layout, void *but_
|
|||
bNodeSocket *sock = arg->sock;
|
||||
bNodeTreeType *ntreetype = arg->ntree->typeinfo;
|
||||
|
||||
UI_block_flag_enable(block, UI_BLOCK_NO_FLIP | UI_BLOCK_IS_FLIP);
|
||||
UI_block_layout_set_current(block, layout);
|
||||
split = uiLayoutSplit(layout, 0.0f, false);
|
||||
|
||||
|
|
|
@ -1910,7 +1910,7 @@ static void outliner_draw_overrides_rna_buts(uiBlock *block,
|
|||
if (const TreeElementOverridesPropertyOperation *override_op_elem =
|
||||
tree_element_cast<TreeElementOverridesPropertyOperation>(te))
|
||||
{
|
||||
StringRefNull op_label = override_op_elem->getOverrideOperationLabel();
|
||||
StringRefNull op_label = override_op_elem->get_override_operation_label();
|
||||
if (!op_label.is_empty()) {
|
||||
uiDefBut(block,
|
||||
UI_BTYPE_LABEL,
|
||||
|
@ -2058,8 +2058,8 @@ static void outliner_draw_rnabuts(uiBlock *block,
|
|||
}
|
||||
|
||||
if (TreeElementRNAProperty *te_rna_prop = tree_element_cast<TreeElementRNAProperty>(te)) {
|
||||
ptr = te_rna_prop->getPointerRNA();
|
||||
prop = te_rna_prop->getPropertyRNA();
|
||||
ptr = te_rna_prop->get_pointer_rna();
|
||||
prop = te_rna_prop->get_property_rna();
|
||||
|
||||
if (!TSELEM_OPEN(tselem, space_outliner)) {
|
||||
if (RNA_property_type(prop) == PROP_POINTER) {
|
||||
|
@ -2104,8 +2104,8 @@ static void outliner_draw_rnabuts(uiBlock *block,
|
|||
else if (TreeElementRNAArrayElement *te_rna_array_elem =
|
||||
tree_element_cast<TreeElementRNAArrayElement>(te))
|
||||
{
|
||||
ptr = te_rna_array_elem->getPointerRNA();
|
||||
prop = te_rna_array_elem->getPropertyRNA();
|
||||
ptr = te_rna_array_elem->get_pointer_rna();
|
||||
prop = te_rna_array_elem->get_property_rna();
|
||||
|
||||
uiDefAutoButR(block,
|
||||
&ptr,
|
||||
|
@ -2295,7 +2295,7 @@ static StringRefNull outliner_draw_get_warning_tree_element_subtree(const TreeEl
|
|||
{
|
||||
LISTBASE_FOREACH (const TreeElement *, sub_te, &parent_te->subtree) {
|
||||
const AbstractTreeElement *abstract_te = tree_element_cast<AbstractTreeElement>(sub_te);
|
||||
StringRefNull warning_msg = abstract_te ? abstract_te->getWarning() : "";
|
||||
StringRefNull warning_msg = abstract_te ? abstract_te->get_warning() : "";
|
||||
|
||||
if (!warning_msg.is_empty()) {
|
||||
return warning_msg;
|
||||
|
@ -2314,7 +2314,7 @@ static StringRefNull outliner_draw_get_warning_tree_element(const SpaceOutliner
|
|||
const TreeElement *te)
|
||||
{
|
||||
const AbstractTreeElement *abstract_te = tree_element_cast<AbstractTreeElement>(te);
|
||||
const StringRefNull warning_msg = abstract_te ? abstract_te->getWarning() : "";
|
||||
const StringRefNull warning_msg = abstract_te ? abstract_te->get_warning() : "";
|
||||
|
||||
if (!warning_msg.is_empty()) {
|
||||
return warning_msg;
|
||||
|
@ -2824,7 +2824,7 @@ TreeElementIcon tree_element_get_icon(TreeStoreElem *tselem, TreeElement *te)
|
|||
break;
|
||||
case TSE_SEQUENCE: {
|
||||
const TreeElementSequence *te_seq = tree_element_cast<TreeElementSequence>(te);
|
||||
switch (te_seq->getSequenceType()) {
|
||||
switch (te_seq->get_sequence_type()) {
|
||||
case SEQ_TYPE_SCENE:
|
||||
data.icon = ICON_SCENE_DATA;
|
||||
break;
|
||||
|
@ -2886,7 +2886,7 @@ TreeElementIcon tree_element_get_icon(TreeStoreElem *tselem, TreeElement *te)
|
|||
break;
|
||||
case TSE_RNA_STRUCT: {
|
||||
const TreeElementRNAStruct *te_rna_struct = tree_element_cast<TreeElementRNAStruct>(te);
|
||||
const PointerRNA &ptr = te_rna_struct->getPointerRNA();
|
||||
const PointerRNA &ptr = te_rna_struct->get_pointer_rna();
|
||||
|
||||
if (RNA_struct_is_ID(ptr.type)) {
|
||||
data.drag_id = static_cast<ID *>(ptr.data);
|
||||
|
@ -2943,7 +2943,7 @@ TreeElementIcon tree_element_get_icon(TreeStoreElem *tselem, TreeElement *te)
|
|||
if (!te->abstract_element) {
|
||||
/* Pass */
|
||||
}
|
||||
else if (auto icon = te->abstract_element->getIcon()) {
|
||||
else if (auto icon = te->abstract_element->get_icon()) {
|
||||
data.icon = *icon;
|
||||
}
|
||||
|
||||
|
@ -3470,7 +3470,7 @@ static void outliner_draw_tree_element(bContext *C,
|
|||
|
||||
const TreeElementRNAStruct *te_rna_struct = tree_element_cast<TreeElementRNAStruct>(te);
|
||||
if (ELEM(tselem->type, TSE_SOME_ID, TSE_LAYER_COLLECTION) ||
|
||||
(te_rna_struct && RNA_struct_is_ID(te_rna_struct->getPointerRNA().type)))
|
||||
(te_rna_struct && RNA_struct_is_ID(te_rna_struct->get_pointer_rna().type)))
|
||||
{
|
||||
const BIFIconID lib_icon = UI_icon_from_library(tselem->id);
|
||||
if (lib_icon != ICON_NONE) {
|
||||
|
|
|
@ -1656,7 +1656,7 @@ static void tree_element_to_path(TreeElement *te,
|
|||
/* get data */
|
||||
TreeElement *tem = (TreeElement *)ld->data;
|
||||
TreeElementRNACommon *tem_rna = tree_element_cast<TreeElementRNACommon>(tem);
|
||||
PointerRNA ptr = tem_rna->getPointerRNA();
|
||||
PointerRNA ptr = tem_rna->get_pointer_rna();
|
||||
|
||||
/* check if we're looking for first ID, or appending to path */
|
||||
if (*id) {
|
||||
|
@ -1665,7 +1665,7 @@ static void tree_element_to_path(TreeElement *te,
|
|||
* then free old path + swap them.
|
||||
*/
|
||||
if (TreeElementRNAProperty *tem_rna_prop = tree_element_cast<TreeElementRNAProperty>(tem)) {
|
||||
PropertyRNA *prop = tem_rna_prop->getPropertyRNA();
|
||||
PropertyRNA *prop = tem_rna_prop->get_property_rna();
|
||||
|
||||
if (RNA_property_type(prop) == PROP_POINTER) {
|
||||
/* for pointer we just append property name */
|
||||
|
@ -1675,7 +1675,7 @@ static void tree_element_to_path(TreeElement *te,
|
|||
char buf[128], *name;
|
||||
|
||||
TreeElement *temnext = (TreeElement *)(ld->next->data);
|
||||
PointerRNA nextptr = tree_element_cast<TreeElementRNACommon>(temnext)->getPointerRNA();
|
||||
PointerRNA nextptr = tree_element_cast<TreeElementRNACommon>(temnext)->get_pointer_rna();
|
||||
name = RNA_struct_name_get_alloc(&nextptr, buf, sizeof(buf), nullptr);
|
||||
|
||||
if (name) {
|
||||
|
@ -1733,7 +1733,7 @@ static void tree_element_to_path(TreeElement *te,
|
|||
/* step 3: if we've got an ID, add the current item to the path */
|
||||
if (*id) {
|
||||
/* add the active property to the path */
|
||||
PropertyRNA *prop = tree_element_cast<TreeElementRNACommon>(te)->getPropertyRNA();
|
||||
PropertyRNA *prop = tree_element_cast<TreeElementRNACommon>(te)->get_property_rna();
|
||||
|
||||
/* array checks */
|
||||
if (tselem->type == TSE_RNA_ARRAY_ELEM) {
|
||||
|
@ -1794,8 +1794,8 @@ static void do_outliner_drivers_editop(SpaceOutliner *space_outliner,
|
|||
short groupmode = KSP_GROUP_KSNAME;
|
||||
|
||||
TreeElementRNACommon *te_rna = tree_element_cast<TreeElementRNACommon>(te);
|
||||
PointerRNA ptr = te_rna ? te_rna->getPointerRNA() : PointerRNA_NULL;
|
||||
PropertyRNA *prop = te_rna ? te_rna->getPropertyRNA() : nullptr;
|
||||
PointerRNA ptr = te_rna ? te_rna->get_pointer_rna() : PointerRNA_NULL;
|
||||
PropertyRNA *prop = te_rna ? te_rna->get_property_rna() : nullptr;
|
||||
|
||||
/* check if RNA-property described by this selected element is an animatable prop */
|
||||
if (prop && RNA_property_animateable(&ptr, prop)) {
|
||||
|
@ -1987,9 +1987,10 @@ static void do_outliner_keyingset_editop(SpaceOutliner *space_outliner,
|
|||
|
||||
/* check if RNA-property described by this selected element is an animatable prop */
|
||||
const TreeElementRNACommon *te_rna = tree_element_cast<TreeElementRNACommon>(te);
|
||||
PointerRNA ptr = te_rna->getPointerRNA();
|
||||
if (te_rna && te_rna->getPropertyRNA() &&
|
||||
RNA_property_animateable(&ptr, te_rna->getPropertyRNA())) {
|
||||
PointerRNA ptr = te_rna->get_pointer_rna();
|
||||
if (te_rna && te_rna->get_property_rna() &&
|
||||
RNA_property_animateable(&ptr, te_rna->get_property_rna()))
|
||||
{
|
||||
/* get id + path + index info from the selected element */
|
||||
tree_element_to_path(te, tselem, &id, &path, &array_index, &flag, &groupmode);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@ bool outliner_shows_mode_column(const SpaceOutliner &space_outliner)
|
|||
{
|
||||
const AbstractTreeDisplay &tree_display = *space_outliner.runtime->tree_display;
|
||||
|
||||
return tree_display.supportsModeColumn() && (space_outliner.flag & SO_MODE_COLUMN);
|
||||
return tree_display.supports_mode_column() && (space_outliner.flag & SO_MODE_COLUMN);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -34,7 +34,7 @@ bool outliner_has_element_warnings(const SpaceOutliner &space_outliner)
|
|||
|
||||
recursive_fn = [&](const ListBase &lb) {
|
||||
LISTBASE_FOREACH (const TreeElement *, te, &lb) {
|
||||
if (te->abstract_element && !te->abstract_element->getWarning().is_empty()) {
|
||||
if (te->abstract_element && !te->abstract_element->get_warning().is_empty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -719,7 +719,7 @@ static void tree_element_sequence_activate(bContext *C,
|
|||
const eOLSetState set)
|
||||
{
|
||||
const TreeElementSequence *te_seq = tree_element_cast<TreeElementSequence>(te);
|
||||
Sequence *seq = &te_seq->getSequence();
|
||||
Sequence *seq = &te_seq->get_sequence();
|
||||
Editing *ed = SEQ_editing_get(scene);
|
||||
|
||||
if (BLI_findindex(ed->seqbasep, seq) != -1) {
|
||||
|
@ -1010,7 +1010,7 @@ static eOLDrawState tree_element_posegroup_state_get(const Scene *scene,
|
|||
static eOLDrawState tree_element_sequence_state_get(const Scene *scene, const TreeElement *te)
|
||||
{
|
||||
const TreeElementSequence *te_seq = tree_element_cast<TreeElementSequence>(te);
|
||||
const Sequence *seq = &te_seq->getSequence();
|
||||
const Sequence *seq = &te_seq->get_sequence();
|
||||
const Editing *ed = scene->ed;
|
||||
|
||||
if (ed && ed->act_seq == seq && seq->flag & SELECT) {
|
||||
|
@ -1023,7 +1023,7 @@ static eOLDrawState tree_element_sequence_dup_state_get(const TreeElement *te)
|
|||
{
|
||||
const TreeElementSequenceStripDuplicate *te_dup =
|
||||
tree_element_cast<TreeElementSequenceStripDuplicate>(te);
|
||||
const Sequence *seq = &te_dup->getSequence();
|
||||
const Sequence *seq = &te_dup->get_sequence();
|
||||
if (seq->flag & SELECT) {
|
||||
return OL_DRAWSEL_NORMAL;
|
||||
}
|
||||
|
|
|
@ -297,7 +297,7 @@ static void outliner_select_sync_to_sequence(Scene *scene, const TreeElement *te
|
|||
const TreeStoreElem *tselem = TREESTORE(te);
|
||||
|
||||
const TreeElementSequence *te_sequence = tree_element_cast<TreeElementSequence>(te);
|
||||
Sequence *seq = &te_sequence->getSequence();
|
||||
Sequence *seq = &te_sequence->get_sequence();
|
||||
|
||||
if (tselem->flag & TSE_ACTIVE) {
|
||||
SEQ_select_active_set(scene, seq);
|
||||
|
@ -476,7 +476,7 @@ static void outliner_select_sync_from_sequence(Sequence *sequence_active, const
|
|||
TreeStoreElem *tselem = TREESTORE(te);
|
||||
|
||||
const TreeElementSequence *te_sequence = tree_element_cast<TreeElementSequence>(te);
|
||||
const Sequence *seq = &te_sequence->getSequence();
|
||||
const Sequence *seq = &te_sequence->get_sequence();
|
||||
|
||||
if (seq == sequence_active) {
|
||||
tselem->flag |= TSE_ACTIVE;
|
||||
|
|
|
@ -2163,7 +2163,7 @@ static void ebone_fn(int event, TreeElement *te, TreeStoreElem * /*tselem*/, voi
|
|||
static void sequence_fn(int event, TreeElement *te, TreeStoreElem * /*tselem*/, void *scene_ptr)
|
||||
{
|
||||
TreeElementSequence *te_seq = tree_element_cast<TreeElementSequence>(te);
|
||||
Sequence *seq = &te_seq->getSequence();
|
||||
Sequence *seq = &te_seq->get_sequence();
|
||||
Scene *scene = (Scene *)scene_ptr;
|
||||
Editing *ed = SEQ_editing_get(scene);
|
||||
if (BLI_findindex(ed->seqbasep, seq) != -1) {
|
||||
|
@ -2241,7 +2241,7 @@ static void data_select_linked_fn(int event,
|
|||
}
|
||||
|
||||
if (event == OL_DOP_SELECT_LINKED) {
|
||||
const PointerRNA &ptr = te_rna_struct->getPointerRNA();
|
||||
const PointerRNA &ptr = te_rna_struct->get_pointer_rna();
|
||||
if (RNA_struct_is_ID(ptr.type)) {
|
||||
bContext *C = (bContext *)C_v;
|
||||
ID *id = static_cast<ID *>(ptr.data);
|
||||
|
|
|
@ -311,7 +311,7 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
|
|||
|
||||
/* New inheritance based element representation. Not all element types support this yet,
|
||||
* eventually it should replace #TreeElement entirely. */
|
||||
te->abstract_element = AbstractTreeElement::createFromType(type, *te, idv);
|
||||
te->abstract_element = AbstractTreeElement::create_from_type(type, *te, idv);
|
||||
if (te->abstract_element) {
|
||||
/* Element types ported to the new design are expected to have their name set at this point! */
|
||||
BLI_assert(te->name != nullptr);
|
||||
|
@ -366,29 +366,26 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
|
|||
/* pass */
|
||||
}
|
||||
else if (type == TSE_SOME_ID) {
|
||||
if (!te->abstract_element) {
|
||||
BLI_assert_msg(0, "Expected this ID type to be ported to new Outliner tree-element design");
|
||||
}
|
||||
BLI_assert_msg(te->abstract_element != nullptr,
|
||||
"Expected this ID type to be ported to new Outliner tree-element design");
|
||||
}
|
||||
else if (ELEM(type,
|
||||
TSE_LIBRARY_OVERRIDE_BASE,
|
||||
TSE_LIBRARY_OVERRIDE,
|
||||
TSE_LIBRARY_OVERRIDE_OPERATION))
|
||||
{
|
||||
if (!te->abstract_element) {
|
||||
BLI_assert_msg(0,
|
||||
"Expected override types to be ported to new Outliner tree-element design");
|
||||
}
|
||||
BLI_assert_msg(te->abstract_element != nullptr,
|
||||
"Expected override types to be ported to new Outliner tree-element design");
|
||||
}
|
||||
else {
|
||||
/* Other cases must be caught above. */
|
||||
BLI_assert(TSE_IS_REAL_ID(tselem));
|
||||
BLI_assert_msg(te->abstract_element != nullptr,
|
||||
"Element type should use `AbstractTreeElement` to for correct initialization "
|
||||
"of its `TreeElement` data");
|
||||
|
||||
/* The new type design sets the name already, don't override that here. We need to figure out
|
||||
* how to deal with the idcode for non-TSE_SOME_ID types still. Some rely on it... */
|
||||
if (!te->abstract_element) {
|
||||
te->name = id->name + 2; /* Default, can be overridden by Library or non-ID data. */
|
||||
}
|
||||
te->idcode = GS(id->name);
|
||||
}
|
||||
|
||||
|
@ -398,43 +395,9 @@ TreeElement *outliner_add_element(SpaceOutliner *space_outliner,
|
|||
else if (te->abstract_element) {
|
||||
tree_element_expand(*te->abstract_element, *space_outliner);
|
||||
}
|
||||
else if (ELEM(type,
|
||||
TSE_ANIM_DATA,
|
||||
TSE_BONE,
|
||||
TSE_DRIVER_BASE,
|
||||
TSE_EBONE,
|
||||
TSE_LINKED_PSYS,
|
||||
TSE_NLA,
|
||||
TSE_NLA_ACTION,
|
||||
TSE_NLA_TRACK,
|
||||
TSE_GP_LAYER,
|
||||
TSE_RNA_STRUCT,
|
||||
TSE_RNA_PROPERTY,
|
||||
TSE_RNA_ARRAY_ELEM,
|
||||
TSE_SEQUENCE,
|
||||
TSE_SEQ_STRIP,
|
||||
TSE_SEQUENCE_DUP,
|
||||
TSE_GENERIC_LABEL) ||
|
||||
ELEM(type,
|
||||
TSE_DEFGROUP,
|
||||
TSE_DEFGROUP_BASE,
|
||||
TSE_GPENCIL_EFFECT,
|
||||
TSE_GPENCIL_EFFECT_BASE,
|
||||
TSE_CONSTRAINT,
|
||||
TSE_CONSTRAINT_BASE,
|
||||
TSE_POSE_BASE,
|
||||
TSE_POSE_CHANNEL,
|
||||
TSE_POSEGRP,
|
||||
TSE_POSEGRP_BASE,
|
||||
TSE_R_LAYER,
|
||||
TSE_R_LAYER_BASE,
|
||||
TSE_MODIFIER,
|
||||
TSE_MODIFIER_BASE,
|
||||
TSE_GREASE_PENCIL_NODE,
|
||||
TSE_LINKED_OB) ||
|
||||
ELEM(type, TSE_LAYER_COLLECTION, TSE_VIEW_COLLECTION_BASE))
|
||||
{
|
||||
BLI_assert_msg(false, "Element type should already use new AbstractTreeElement design");
|
||||
/* Only #TSE_ID_BASE isn't ported to use the abstract elements design yet. */
|
||||
else if (!ELEM(type, TSE_ID_BASE)) {
|
||||
BLI_assert_msg(false, "Element type should use `AbstractTreeElement`");
|
||||
}
|
||||
|
||||
return te;
|
||||
|
@ -1229,14 +1192,14 @@ void outliner_build_tree(Main *mainvar,
|
|||
outliner_free_tree(&space_outliner->tree);
|
||||
outliner_storage_cleanup(space_outliner);
|
||||
|
||||
space_outliner->runtime->tree_display = AbstractTreeDisplay::createFromDisplayMode(
|
||||
space_outliner->runtime->tree_display = AbstractTreeDisplay::create_from_display_mode(
|
||||
space_outliner->outlinevis, *space_outliner);
|
||||
|
||||
/* All tree displays should be created as sub-classes of AbstractTreeDisplay. */
|
||||
BLI_assert(space_outliner->runtime->tree_display != nullptr);
|
||||
|
||||
TreeSourceData source_data{*mainvar, *scene, *view_layer};
|
||||
space_outliner->tree = space_outliner->runtime->tree_display->buildTree(source_data);
|
||||
space_outliner->tree = space_outliner->runtime->tree_display->build_tree(source_data);
|
||||
|
||||
if ((space_outliner->flag & SO_SKIP_SORT_ALPHA) == 0) {
|
||||
outliner_sort(&space_outliner->tree);
|
||||
|
|
|
@ -17,7 +17,7 @@ using namespace blender::ed::outliner;
|
|||
|
||||
namespace blender::ed::outliner {
|
||||
|
||||
std::unique_ptr<AbstractTreeDisplay> AbstractTreeDisplay::createFromDisplayMode(
|
||||
std::unique_ptr<AbstractTreeDisplay> AbstractTreeDisplay::create_from_display_mode(
|
||||
int /*eSpaceOutliner_Mode*/ mode, SpaceOutliner &space_outliner)
|
||||
{
|
||||
switch ((eSpaceOutliner_Mode)mode) {
|
||||
|
@ -47,7 +47,7 @@ std::unique_ptr<AbstractTreeDisplay> AbstractTreeDisplay::createFromDisplayMode(
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
bool AbstractTreeDisplay::supportsModeColumn() const
|
||||
bool AbstractTreeDisplay::supports_mode_column() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
* tree-display class with the #AbstractTreeDisplay interface.
|
||||
*
|
||||
* Their main responsibility is building the Outliner tree for a display mode. For that, they
|
||||
* implement the #buildTree() function, which based on Blender data (#TreeSourceData), builds a
|
||||
* implement the #build_tree() function, which based on Blender data (#TreeSourceData), builds a
|
||||
* custom tree of whatever data it wants to visualize.
|
||||
* Further, they can implement display mode dependent queries and general operations using the
|
||||
* #AbstractTreeDisplay abstraction as common interface.
|
||||
|
@ -66,14 +66,14 @@ class AbstractTreeDisplay {
|
|||
AbstractTreeDisplay(SpaceOutliner &space_outliner) : space_outliner_(space_outliner) {}
|
||||
virtual ~AbstractTreeDisplay() = default;
|
||||
|
||||
static std::unique_ptr<AbstractTreeDisplay> createFromDisplayMode(
|
||||
static std::unique_ptr<AbstractTreeDisplay> create_from_display_mode(
|
||||
int /*eSpaceOutliner_Mode*/ mode, SpaceOutliner &space_outliner);
|
||||
|
||||
/**
|
||||
* Build a tree for this display mode with the Blender context data given in \a source_data and
|
||||
* the view settings in \a space_outliner.
|
||||
*/
|
||||
virtual ListBase buildTree(const TreeSourceData &source_data) = 0;
|
||||
virtual ListBase build_tree(const TreeSourceData &source_data) = 0;
|
||||
|
||||
/**
|
||||
* Define if the display mode should be allowed to show a mode column on the left. This column
|
||||
|
@ -82,7 +82,7 @@ class AbstractTreeDisplay {
|
|||
*
|
||||
* Returns false by default.
|
||||
*/
|
||||
virtual bool supportsModeColumn() const;
|
||||
virtual bool supports_mode_column() const;
|
||||
|
||||
/**
|
||||
* Some trees may want to skip building children of collapsed parents. This should be done if the
|
||||
|
@ -112,9 +112,9 @@ class TreeDisplayViewLayer final : public AbstractTreeDisplay {
|
|||
public:
|
||||
TreeDisplayViewLayer(SpaceOutliner &space_outliner);
|
||||
|
||||
ListBase buildTree(const TreeSourceData &source_data) override;
|
||||
ListBase build_tree(const TreeSourceData &source_data) override;
|
||||
|
||||
bool supportsModeColumn() const override;
|
||||
bool supports_mode_column() const override;
|
||||
|
||||
private:
|
||||
void add_view_layer(Scene &, ListBase &, TreeElement *);
|
||||
|
@ -133,7 +133,7 @@ class TreeDisplayLibraries final : public AbstractTreeDisplay {
|
|||
public:
|
||||
TreeDisplayLibraries(SpaceOutliner &space_outliner);
|
||||
|
||||
ListBase buildTree(const TreeSourceData &source_data) override;
|
||||
ListBase build_tree(const TreeSourceData &source_data) override;
|
||||
|
||||
private:
|
||||
TreeElement *add_library_contents(Main &, ListBase &, Library *);
|
||||
|
@ -151,7 +151,7 @@ class TreeDisplayOverrideLibraryProperties final : public AbstractTreeDisplay {
|
|||
public:
|
||||
TreeDisplayOverrideLibraryProperties(SpaceOutliner &space_outliner);
|
||||
|
||||
ListBase buildTree(const TreeSourceData &source_data) override;
|
||||
ListBase build_tree(const TreeSourceData &source_data) override;
|
||||
|
||||
private:
|
||||
ListBase add_library_contents(Main &);
|
||||
|
@ -165,7 +165,7 @@ class TreeDisplayOverrideLibraryHierarchies final : public AbstractTreeDisplay {
|
|||
public:
|
||||
TreeDisplayOverrideLibraryHierarchies(SpaceOutliner &space_outliner);
|
||||
|
||||
ListBase buildTree(const TreeSourceData &source_data) override;
|
||||
ListBase build_tree(const TreeSourceData &source_data) override;
|
||||
|
||||
bool is_lazy_built() const override;
|
||||
|
||||
|
@ -191,7 +191,7 @@ class TreeDisplaySequencer final : public AbstractTreeDisplay {
|
|||
public:
|
||||
TreeDisplaySequencer(SpaceOutliner &space_outliner);
|
||||
|
||||
ListBase buildTree(const TreeSourceData &source_data) override;
|
||||
ListBase build_tree(const TreeSourceData &source_data) override;
|
||||
|
||||
private:
|
||||
TreeElement *add_sequencer_contents() const;
|
||||
|
@ -212,7 +212,7 @@ class TreeDisplayIDOrphans final : public AbstractTreeDisplay {
|
|||
public:
|
||||
TreeDisplayIDOrphans(SpaceOutliner &space_outliner);
|
||||
|
||||
ListBase buildTree(const TreeSourceData &source_data) override;
|
||||
ListBase build_tree(const TreeSourceData &source_data) override;
|
||||
|
||||
private:
|
||||
bool datablock_has_orphans(ListBase &) const;
|
||||
|
@ -228,9 +228,9 @@ class TreeDisplayScenes final : public AbstractTreeDisplay {
|
|||
public:
|
||||
TreeDisplayScenes(SpaceOutliner &space_outliner);
|
||||
|
||||
ListBase buildTree(const TreeSourceData &source_data) override;
|
||||
ListBase build_tree(const TreeSourceData &source_data) override;
|
||||
|
||||
bool supportsModeColumn() const override;
|
||||
bool supports_mode_column() const override;
|
||||
};
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
@ -243,7 +243,7 @@ class TreeDisplayDataAPI final : public AbstractTreeDisplay {
|
|||
public:
|
||||
TreeDisplayDataAPI(SpaceOutliner &space_outliner);
|
||||
|
||||
ListBase buildTree(const TreeSourceData &source_data) override;
|
||||
ListBase build_tree(const TreeSourceData &source_data) override;
|
||||
|
||||
bool is_lazy_built() const override;
|
||||
};
|
||||
|
|
|
@ -24,7 +24,7 @@ TreeDisplayDataAPI::TreeDisplayDataAPI(SpaceOutliner &space_outliner)
|
|||
{
|
||||
}
|
||||
|
||||
ListBase TreeDisplayDataAPI::buildTree(const TreeSourceData &source_data)
|
||||
ListBase TreeDisplayDataAPI::build_tree(const TreeSourceData &source_data)
|
||||
{
|
||||
ListBase tree = {nullptr};
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@ TreeDisplayLibraries::TreeDisplayLibraries(SpaceOutliner &space_outliner)
|
|||
{
|
||||
}
|
||||
|
||||
ListBase TreeDisplayLibraries::buildTree(const TreeSourceData &source_data)
|
||||
ListBase TreeDisplayLibraries::build_tree(const TreeSourceData &source_data)
|
||||
{
|
||||
ListBase tree = {nullptr};
|
||||
|
||||
|
|
|
@ -29,7 +29,7 @@ TreeDisplayIDOrphans::TreeDisplayIDOrphans(SpaceOutliner &space_outliner)
|
|||
{
|
||||
}
|
||||
|
||||
ListBase TreeDisplayIDOrphans::buildTree(const TreeSourceData &source_data)
|
||||
ListBase TreeDisplayIDOrphans::build_tree(const TreeSourceData &source_data)
|
||||
{
|
||||
ListBase tree = {nullptr};
|
||||
ListBase *lbarray[INDEX_ID_MAX];
|
||||
|
|
|
@ -35,7 +35,7 @@ TreeDisplayOverrideLibraryHierarchies::TreeDisplayOverrideLibraryHierarchies(
|
|||
{
|
||||
}
|
||||
|
||||
ListBase TreeDisplayOverrideLibraryHierarchies::buildTree(const TreeSourceData &source_data)
|
||||
ListBase TreeDisplayOverrideLibraryHierarchies::build_tree(const TreeSourceData &source_data)
|
||||
{
|
||||
ListBase tree = {nullptr};
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@ TreeDisplayOverrideLibraryProperties::TreeDisplayOverrideLibraryProperties(
|
|||
{
|
||||
}
|
||||
|
||||
ListBase TreeDisplayOverrideLibraryProperties::buildTree(const TreeSourceData &source_data)
|
||||
ListBase TreeDisplayOverrideLibraryProperties::build_tree(const TreeSourceData &source_data)
|
||||
{
|
||||
ListBase tree = add_library_contents(*source_data.bmain);
|
||||
|
||||
|
|
|
@ -28,12 +28,12 @@ TreeDisplayScenes::TreeDisplayScenes(SpaceOutliner &space_outliner)
|
|||
{
|
||||
}
|
||||
|
||||
bool TreeDisplayScenes::supportsModeColumn() const
|
||||
bool TreeDisplayScenes::supports_mode_column() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
ListBase TreeDisplayScenes::buildTree(const TreeSourceData &source_data)
|
||||
ListBase TreeDisplayScenes::build_tree(const TreeSourceData &source_data)
|
||||
{
|
||||
/* On first view we open scenes. */
|
||||
const int show_opened = !space_outliner_.treestore ||
|
||||
|
|
|
@ -30,7 +30,7 @@ TreeDisplaySequencer::TreeDisplaySequencer(SpaceOutliner &space_outliner)
|
|||
{
|
||||
}
|
||||
|
||||
ListBase TreeDisplaySequencer::buildTree(const TreeSourceData &source_data)
|
||||
ListBase TreeDisplaySequencer::build_tree(const TreeSourceData &source_data)
|
||||
{
|
||||
ListBase tree = {nullptr};
|
||||
|
||||
|
|
|
@ -57,12 +57,12 @@ TreeDisplayViewLayer::TreeDisplayViewLayer(SpaceOutliner &space_outliner)
|
|||
{
|
||||
}
|
||||
|
||||
bool TreeDisplayViewLayer::supportsModeColumn() const
|
||||
bool TreeDisplayViewLayer::supports_mode_column() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
ListBase TreeDisplayViewLayer::buildTree(const TreeSourceData &source_data)
|
||||
ListBase TreeDisplayViewLayer::build_tree(const TreeSourceData &source_data)
|
||||
{
|
||||
ListBase tree = {nullptr};
|
||||
Scene *scene = source_data.scene;
|
||||
|
|
|
@ -49,9 +49,9 @@
|
|||
|
||||
namespace blender::ed::outliner {
|
||||
|
||||
std::unique_ptr<AbstractTreeElement> AbstractTreeElement::createFromType(const int type,
|
||||
TreeElement &legacy_te,
|
||||
void *idv)
|
||||
std::unique_ptr<AbstractTreeElement> AbstractTreeElement::create_from_type(const int type,
|
||||
TreeElement &legacy_te,
|
||||
void *idv)
|
||||
{
|
||||
if (idv == nullptr) {
|
||||
return nullptr;
|
||||
|
@ -71,7 +71,7 @@ std::unique_ptr<AbstractTreeElement> AbstractTreeElement::createFromType(const i
|
|||
|
||||
switch (type) {
|
||||
case TSE_SOME_ID:
|
||||
return TreeElementID::createFromID(legacy_te, *static_cast<ID *>(idv));
|
||||
return TreeElementID::create_from_id(legacy_te, *static_cast<ID *>(idv));
|
||||
case TSE_GENERIC_LABEL:
|
||||
return std::make_unique<TreeElementLabel>(legacy_te, static_cast<const char *>(idv));
|
||||
case TSE_ANIM_DATA:
|
||||
|
@ -198,12 +198,12 @@ std::unique_ptr<AbstractTreeElement> AbstractTreeElement::createFromType(const i
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
StringRefNull AbstractTreeElement::getWarning() const
|
||||
StringRefNull AbstractTreeElement::get_warning() const
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
std::optional<BIFIconID> AbstractTreeElement::getIcon() const
|
||||
std::optional<BIFIconID> AbstractTreeElement::get_icon() const
|
||||
{
|
||||
return {};
|
||||
}
|
||||
|
@ -231,7 +231,7 @@ void tree_element_expand(const AbstractTreeElement &tree_element, SpaceOutliner
|
|||
/* Most types can just expand. IDs optionally expand (hence the poll) and do additional, common
|
||||
* expanding. Could be done nicer, we could request a small "expander" helper object from the
|
||||
* element type, that the IDs have a more advanced implementation for. */
|
||||
if (!tree_element.expandPoll(space_outliner)) {
|
||||
if (!tree_element.expand_poll(space_outliner)) {
|
||||
return;
|
||||
}
|
||||
tree_element.expand(space_outliner);
|
||||
|
|
|
@ -36,19 +36,19 @@ class AbstractTreeElement {
|
|||
public:
|
||||
virtual ~AbstractTreeElement() = default;
|
||||
|
||||
static std::unique_ptr<AbstractTreeElement> createFromType(int type,
|
||||
TreeElement &legacy_te,
|
||||
void *idv);
|
||||
static std::unique_ptr<AbstractTreeElement> create_from_type(int type,
|
||||
TreeElement &legacy_te,
|
||||
void *idv);
|
||||
|
||||
/**
|
||||
* Check if the type is expandable in current context.
|
||||
*/
|
||||
virtual bool expandPoll(const SpaceOutliner &) const
|
||||
virtual bool expand_poll(const SpaceOutliner &) const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
TreeElement &getLegacyElement()
|
||||
TreeElement &get_legacy_element()
|
||||
{
|
||||
return legacy_te_;
|
||||
}
|
||||
|
@ -57,7 +57,7 @@ class AbstractTreeElement {
|
|||
* By letting this return a warning message, the tree element will display a warning icon with
|
||||
* the message in the tooltip.
|
||||
*/
|
||||
virtual StringRefNull getWarning() const;
|
||||
virtual StringRefNull get_warning() const;
|
||||
|
||||
/**
|
||||
* Define the icon to be displayed for this element. If this returns an icon, this will be
|
||||
|
@ -66,7 +66,7 @@ class AbstractTreeElement {
|
|||
*
|
||||
* All elements should be ported to use this over #tree_element_get_icon().
|
||||
*/
|
||||
virtual std::optional<BIFIconID> getIcon() const;
|
||||
virtual std::optional<BIFIconID> get_icon() const;
|
||||
|
||||
/**
|
||||
* Debugging helper: Print effective path of this tree element, constructed out of the
|
||||
|
|
|
@ -38,7 +38,7 @@
|
|||
|
||||
namespace blender::ed::outliner {
|
||||
|
||||
std::unique_ptr<TreeElementID> TreeElementID::createFromID(TreeElement &legacy_te, ID &id)
|
||||
std::unique_ptr<TreeElementID> TreeElementID::create_from_id(TreeElement &legacy_te, ID &id)
|
||||
{
|
||||
if (ID_TYPE_IS_DEPRECATED(GS(id.name))) {
|
||||
BLI_assert_msg(0, "Outliner trying to build tree-element for deprecated ID type");
|
||||
|
@ -120,7 +120,7 @@ TreeElementID::TreeElementID(TreeElement &legacy_te, ID &id)
|
|||
legacy_te_.idcode = GS(id.name);
|
||||
}
|
||||
|
||||
bool TreeElementID::expandPoll(const SpaceOutliner &space_outliner) const
|
||||
bool TreeElementID::expand_poll(const SpaceOutliner &space_outliner) const
|
||||
{
|
||||
const TreeStoreElem *tsepar = legacy_te_.parent ? TREESTORE(legacy_te_.parent) : nullptr;
|
||||
return (tsepar == nullptr || tsepar->type != TSE_ID_BASE || space_outliner.filter_id_type);
|
||||
|
|
|
@ -24,9 +24,9 @@ class TreeElementID : public AbstractTreeElement {
|
|||
public:
|
||||
TreeElementID(TreeElement &legacy_te, ID &id);
|
||||
|
||||
static std::unique_ptr<TreeElementID> createFromID(TreeElement &legacy_te, ID &id);
|
||||
static std::unique_ptr<TreeElementID> create_from_id(TreeElement &legacy_te, ID &id);
|
||||
|
||||
bool expandPoll(const SpaceOutliner &) const override;
|
||||
bool expand_poll(const SpaceOutliner &) const override;
|
||||
|
||||
void expand(SpaceOutliner &) const override;
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ TreeElementIDLibrary::TreeElementIDLibrary(TreeElement &legacy_te, Library &libr
|
|||
legacy_te.name = library.filepath;
|
||||
}
|
||||
|
||||
StringRefNull TreeElementIDLibrary::getWarning() const
|
||||
StringRefNull TreeElementIDLibrary::get_warning() const
|
||||
{
|
||||
Library &library = reinterpret_cast<Library &>(id_);
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ class TreeElementIDLibrary final : public TreeElementID {
|
|||
public:
|
||||
TreeElementIDLibrary(TreeElement &legacy_te, Library &library);
|
||||
|
||||
blender::StringRefNull getWarning() const override;
|
||||
blender::StringRefNull get_warning() const override;
|
||||
};
|
||||
|
||||
} // namespace blender::ed::outliner
|
||||
|
|
|
@ -25,12 +25,12 @@ TreeElementLabel::TreeElementLabel(TreeElement &legacy_te, const char *label)
|
|||
legacy_te_.name = label_.c_str();
|
||||
}
|
||||
|
||||
void TreeElementLabel::setIcon(const BIFIconID icon)
|
||||
void TreeElementLabel::set_icon(const BIFIconID icon)
|
||||
{
|
||||
icon_ = icon;
|
||||
}
|
||||
|
||||
std::optional<BIFIconID> TreeElementLabel::getIcon() const
|
||||
std::optional<BIFIconID> TreeElementLabel::get_icon() const
|
||||
{
|
||||
return icon_;
|
||||
}
|
||||
|
|
|
@ -31,8 +31,8 @@ class TreeElementLabel final : public AbstractTreeElement {
|
|||
public:
|
||||
TreeElementLabel(TreeElement &legacy_te, const char *label);
|
||||
|
||||
void setIcon(BIFIconID icon);
|
||||
std::optional<BIFIconID> getIcon() const override;
|
||||
void set_icon(BIFIconID icon);
|
||||
std::optional<BIFIconID> get_icon() const override;
|
||||
};
|
||||
|
||||
} // namespace blender::ed::outliner
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue