UI: show recently selected items at the top of searches #110828
21
GNUmakefile
21
GNUmakefile
|
@ -81,9 +81,9 @@ Documentation Checking
|
|||
Spell Checkers
|
||||
This runs the spell checker from the developer tools repositor.
|
||||
|
||||
* check_spelling_c: Check for spelling errors (C/C++ only),
|
||||
* check_spelling_osl: Check for spelling errors (OSL only).
|
||||
* check_spelling_py: Check for spelling errors (Python only).
|
||||
* check_spelling_c: Check for spelling errors (C/C++ only),
|
||||
* check_spelling_py: Check for spelling errors (Python only).
|
||||
* check_spelling_shaders: Check for spelling errors (GLSL,OSL & MSL only).
|
||||
|
||||
Note: an additional word-list is maintained at: 'tools/check_source/check_spelling_c_config.py'
|
||||
|
||||
|
@ -492,24 +492,31 @@ check_spelling_py: .FORCE
|
|||
@cd "$(BUILD_DIR)" ; \
|
||||
PYTHONIOENCODING=utf_8 $(PYTHON) \
|
||||
"$(BLENDER_DIR)/tools/check_source/check_spelling.py" \
|
||||
"$(BLENDER_DIR)/scripts"
|
||||
--cache-file=$(CHECK_SPELLING_CACHE) \
|
||||
--match=".*\.(py)$$" \
|
||||
"$(BLENDER_DIR)/scripts" \
|
||||
"$(BLENDER_DIR)/source" \
|
||||
"$(BLENDER_DIR)/tools"
|
||||
|
||||
check_spelling_c: .FORCE
|
||||
@cd "$(BUILD_DIR)" ; \
|
||||
PYTHONIOENCODING=utf_8 $(PYTHON) \
|
||||
"$(BLENDER_DIR)/tools/check_source/check_spelling.py" \
|
||||
--cache-file=$(CHECK_SPELLING_CACHE) \
|
||||
--match=".*\.(c|cc|cpp|cxx|h|hh|hpp|hxx|inl|m|mm)$$" \
|
||||
"$(BLENDER_DIR)/source" \
|
||||
"$(BLENDER_DIR)/intern/cycles" \
|
||||
"$(BLENDER_DIR)/intern/guardedalloc" \
|
||||
"$(BLENDER_DIR)/intern/ghost" \
|
||||
"$(BLENDER_DIR)/intern/ghost"
|
||||
|
||||
check_spelling_osl: .FORCE
|
||||
check_spelling_shaders: .FORCE
|
||||
@cd "$(BUILD_DIR)" ; \
|
||||
PYTHONIOENCODING=utf_8 $(PYTHON) \
|
||||
"$(BLENDER_DIR)/tools/check_source/check_spelling.py" \
|
||||
--cache-file=$(CHECK_SPELLING_CACHE) \
|
||||
"$(BLENDER_DIR)/intern/cycles/kernel/shaders"
|
||||
--match=".*\.(osl|msl|glsl)$$" \
|
||||
"$(BLENDER_DIR)/intern/" \
|
||||
"$(BLENDER_DIR)/source/"
|
||||
|
||||
check_descriptions: .FORCE
|
||||
@$(BLENDER_BIN) --background -noaudio --factory-startup --python \
|
||||
|
|
|
@ -17,7 +17,7 @@ buildbot:
|
|||
optix:
|
||||
version: '7.3.0'
|
||||
ocloc:
|
||||
version: '101.4032'
|
||||
version: '101.4369'
|
||||
cmake:
|
||||
default:
|
||||
version: any
|
||||
|
|
|
@ -276,7 +276,7 @@ static GHOST_TKey convertSDLKey(SDL_Scancode key)
|
|||
GXMAP(type, SDL_SCANCODE_KP_MULTIPLY, GHOST_kKeyNumpadAsterisk);
|
||||
GXMAP(type, SDL_SCANCODE_KP_DIVIDE, GHOST_kKeyNumpadSlash);
|
||||
|
||||
/* Media keys in some keyboards and laptops with XFree86/Xorg */
|
||||
/* Media keys in some keyboards and laptops with XFree86/XORG. */
|
||||
GXMAP(type, SDL_SCANCODE_AUDIOPLAY, GHOST_kKeyMediaPlay);
|
||||
GXMAP(type, SDL_SCANCODE_AUDIOSTOP, GHOST_kKeyMediaStop);
|
||||
GXMAP(type, SDL_SCANCODE_AUDIOPREV, GHOST_kKeyMediaFirst);
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
*/
|
||||
|
||||
#include "GHOST_SystemWayland.hh"
|
||||
#include "GHOST_Context.hh"
|
||||
#include "GHOST_Event.hh"
|
||||
#include "GHOST_EventButton.hh"
|
||||
#include "GHOST_EventCursor.hh"
|
||||
|
|
|
@ -1882,7 +1882,7 @@ static GHOST_TKey ghost_key_from_keysym(const KeySym key)
|
|||
GXMAP(type, XK_KP_Multiply, GHOST_kKeyNumpadAsterisk);
|
||||
GXMAP(type, XK_KP_Divide, GHOST_kKeyNumpadSlash);
|
||||
|
||||
/* Media keys in some keyboards and laptops with XFree86/Xorg */
|
||||
/* Media keys in some keyboards and laptops with XFree86/XORG. */
|
||||
#ifdef WITH_XF86KEYSYM
|
||||
GXMAP(type, XF86XK_AudioPlay, GHOST_kKeyMediaPlay);
|
||||
GXMAP(type, XF86XK_AudioStop, GHOST_kKeyMediaStop);
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
#ifdef WITH_X11_XINPUT
|
||||
# include <X11/extensions/XInput.h>
|
||||
|
||||
/* Disable XINPUT warp, currently not implemented by Xorg for multi-head display.
|
||||
/* Disable XINPUT warp, currently not implemented by XORG for multi-head display.
|
||||
* (see comment in XSERVER `Xi/xiwarppointer.c` -> `FIXME: panoramix stuff is missing` ~ v1.13.4)
|
||||
* If this is supported we can add back XINPUT for warping (fixing #48901).
|
||||
* For now disable (see #50383). */
|
||||
|
|
|
@ -111,7 +111,7 @@ float dither_random_value(vec2 co)
|
|||
/* Convert uniform distribution into triangle-shaped distribution. */
|
||||
float orig = nrnd0 * 2.0 - 1.0;
|
||||
nrnd0 = orig * inversesqrt(abs(orig));
|
||||
nrnd0 = max(-1.0, nrnd0); /* Removes nan's */
|
||||
nrnd0 = max(-1.0, nrnd0); /* Removes NAN's. */
|
||||
return nrnd0 - sign(orig);
|
||||
}
|
||||
|
||||
|
@ -133,7 +133,7 @@ vec4 apply_dither(vec4 col, vec2 uv)
|
|||
/** \name Main Processing
|
||||
* \{ */
|
||||
|
||||
/* Prototypes: Implementation is generaterd and defined after. */
|
||||
/* Prototypes: Implementation is generated and defined after. */
|
||||
#ifndef GPU_METAL /* Forward declaration invalid in MSL. */
|
||||
vec4 OCIO_to_scene_linear(vec4 pixel);
|
||||
vec4 OCIO_to_display(vec4 pixel);
|
||||
|
@ -151,7 +151,7 @@ vec4 OCIO_ProcessColor(vec4 col, vec4 col_overlay)
|
|||
}
|
||||
}
|
||||
|
||||
/* NOTE: This is true we only do de-premul here and NO premul
|
||||
/* NOTE: This is true we only do de-pre-multiply here and NO pre-multiply
|
||||
* and the reason is simple -- opengl is always configured
|
||||
* for straight alpha at this moment
|
||||
*/
|
||||
|
|
|
@ -126,9 +126,7 @@ int getNumFacePtexFaces(const OpenSubdiv_TopologyRefiner *topology_refiner, cons
|
|||
if (num_face_vertices == 4) {
|
||||
return 1;
|
||||
}
|
||||
else {
|
||||
return num_face_vertices;
|
||||
}
|
||||
return num_face_vertices;
|
||||
}
|
||||
|
||||
int getNumPtexFaces(const OpenSubdiv_TopologyRefiner *topology_refiner)
|
||||
|
|
|
@ -189,8 +189,8 @@ const bTheme U_theme_default = {
|
|||
},
|
||||
.wcol_list_item = {
|
||||
.outline = RGBA(0x2d2d2dff),
|
||||
.inner = RGBA(0x2d2d2d00),
|
||||
.inner_sel = RGBA(0x484a4fff),
|
||||
.inner = RGBA(0xffffff00),
|
||||
.inner_sel = RGBA(0x4772b3ff),
|
||||
.item = RGBA(0x4772b3ff),
|
||||
.text = RGBA(0xccccccff),
|
||||
.text_sel = RGBA(0xffffffff),
|
||||
|
@ -205,15 +205,6 @@ const bTheme U_theme_default = {
|
|||
.text_sel = RGBA(0xffffffff),
|
||||
.roundness = 0.2f,
|
||||
},
|
||||
.wcol_view_item = {
|
||||
.outline = RGBA(0x2d2d2dff),
|
||||
.inner = RGBA(0x303030ff),
|
||||
.inner_sel = RGBA(0x4772b3ff),
|
||||
.item = RGBA(0x4772b3ff),
|
||||
.text = RGBA(0xccccccff),
|
||||
.text_sel = RGBA(0xffffffff),
|
||||
.roundness = 0.2f,
|
||||
},
|
||||
.wcol_state = {
|
||||
.inner_anim = RGBA(0x53992eff),
|
||||
.inner_anim_sel = RGBA(0x38a600ff),
|
||||
|
|
|
@ -113,7 +113,7 @@ def get_object_name(stroke):
|
|||
|
||||
|
||||
def material_from_fedge(fe):
|
||||
"get the diffuse rgba color from an FEdge"
|
||||
"get the diffuse RGBA color from an FEdge"
|
||||
if fe is None:
|
||||
return None
|
||||
if fe.is_smooth:
|
||||
|
|
|
@ -836,7 +836,7 @@ class PerlinNoise2DShader(StrokeShader):
|
|||
that in a scene no strokes will be distorted identically.
|
||||
|
||||
More information on the noise shaders can be found at:
|
||||
freestyleintegration.wordpress.com/2011/09/25/development-updates-on-september-25/
|
||||
https://freestyleintegration.wordpress.com/2011/09/25/development-updates-on-september-25/
|
||||
"""
|
||||
|
||||
def __init__(self, freq=10, amp=10, oct=4, angle=radians(45), seed=-1):
|
||||
|
|
|
@ -43,7 +43,7 @@ def reduce_newlines(text):
|
|||
|
||||
|
||||
def reduce_spaces(text):
|
||||
"""Reduces multiple whitespaces to a single space.
|
||||
"""Reduces multiple white-spaces to a single space.
|
||||
|
||||
:arg text: text with multiple spaces
|
||||
:type text: str
|
||||
|
@ -100,7 +100,7 @@ def get_argspec(func, *, strip_self=True, doc=None, source=None):
|
|||
func_name = func.__name__
|
||||
except AttributeError:
|
||||
return ''
|
||||
# from docstring
|
||||
# From doc-string.
|
||||
if doc is None:
|
||||
doc = get_doc(func)
|
||||
match = re.search(DEF_DOC % func_name, doc, RE_FLAG)
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
# Copyright (c) 2009 Fernando Perez, www.stani.be
|
||||
|
||||
# Original copyright (see docstring):
|
||||
# Original copyright (see doc-string):
|
||||
# ****************************************************************************
|
||||
# Copyright (C) 2001-2006 Fernando Perez <fperez@colorado.edu>
|
||||
#
|
||||
|
@ -175,6 +175,6 @@ def complete(line):
|
|||
return filter_prefix(try_import(mod), words[-1])
|
||||
|
||||
# get here if the import is not found
|
||||
# import invalidmodule
|
||||
# ^, in this case return nothing
|
||||
# import invalid_module
|
||||
# ^, in this case return nothing
|
||||
return []
|
||||
|
|
|
@ -81,7 +81,7 @@ def complete(line, cursor, namespace, private):
|
|||
|
||||
|
||||
def expand(line, cursor, namespace, *, private=True):
|
||||
"""This method is invoked when the user asks autocompletion,
|
||||
"""This method is invoked when the user asks auto-completion,
|
||||
e.g. when Ctrl+Space is clicked.
|
||||
|
||||
:arg line: incomplete text line
|
||||
|
|
|
@ -108,10 +108,10 @@ IMPORT_LANGUAGES_RTL = {
|
|||
'ar_EG', 'fa_IR', 'he_IL',
|
||||
}
|
||||
|
||||
# The comment prefix used in generated messages.txt file.
|
||||
# The comment prefix used in generated `messages.txt` file.
|
||||
MSG_COMMENT_PREFIX = "#~ "
|
||||
|
||||
# The comment prefix used in generated messages.txt file.
|
||||
# The comment prefix used in generated `messages.txt` file.
|
||||
MSG_CONTEXT_PREFIX = "MSGCTXT:"
|
||||
|
||||
# The default comment prefix used in po's.
|
||||
|
@ -514,12 +514,12 @@ if not os.path.exists(BLENDER_EXEC):
|
|||
# The gettext msgfmt "compiler". You’ll likely have to edit it in your user_settings.py if you’re under Windows.
|
||||
GETTEXT_MSGFMT_EXECUTABLE = "msgfmt"
|
||||
|
||||
# The FriBidi C compiled library (.so under Linux, .dll under windows...).
|
||||
# You’ll likely have to edit it in your user_settings.py if you’re under Windows., e.g. using the included one:
|
||||
# FRIBIDI_LIB = os.path.join(TOOLS_DIR, "libfribidi.dll")
|
||||
# The FriBidi C compiled library (.so under Linux, `.dll` under windows...).
|
||||
# You’ll likely have to edit it in your `user_settings.py` if you’re under Windows., e.g. using the included one:
|
||||
# `FRIBIDI_LIB = os.path.join(TOOLS_DIR, "libfribidi.dll")`
|
||||
FRIBIDI_LIB = "libfribidi.so.0"
|
||||
|
||||
# The name of the (currently empty) file that must be present in a po's directory to enable rtl-preprocess.
|
||||
# The name of the (currently empty) file that must be present in a po's directory to enable RTL-preprocess.
|
||||
RTL_PREPROCESS_FILE = "is_rtl"
|
||||
|
||||
# The Blender source root path.
|
||||
|
@ -565,7 +565,7 @@ ASSET_CATALOG_FILE = "blender_assets.cats.txt"
|
|||
# The template messages file (relative to I18N_DIR).
|
||||
REL_FILE_NAME_POT = os.path.join(REL_BRANCHES_DIR, DOMAIN + ".pot")
|
||||
|
||||
# Mo root datapath.
|
||||
# Mo root data-path.
|
||||
REL_MO_PATH_ROOT = os.path.join(REL_TRUNK_DIR, "locale")
|
||||
|
||||
# Mo path generator for a given language.
|
||||
|
|
|
@ -41,7 +41,7 @@ def gen_menu_file(stats, settings):
|
|||
highest_uid = 0
|
||||
for lvl, uid_num, label, uid, flag in stats:
|
||||
if lvl < limits[idx][0]:
|
||||
# Sub-sort languages by iso-codes.
|
||||
# Sub-sort languages by ISO-codes.
|
||||
langs_cats[idx].sort(key=lambda it: it[2])
|
||||
idx += 1
|
||||
if lvl < settings.IMPORT_MIN_LEVEL and flag == OK:
|
||||
|
@ -49,7 +49,7 @@ def gen_menu_file(stats, settings):
|
|||
langs_cats[idx].append((uid_num, label, uid, flag))
|
||||
if abs(uid_num) > highest_uid:
|
||||
highest_uid = abs(uid_num)
|
||||
# Sub-sort last group of languages by iso-codes!
|
||||
# Sub-sort last group of languages by ISO-codes!
|
||||
langs_cats[idx].sort(key=lambda it: it[2])
|
||||
data_lines = [
|
||||
"# File used by Blender to know which languages (translations) are available, ",
|
||||
|
|
|
@ -756,7 +756,7 @@ class SpellChecker:
|
|||
"hc",
|
||||
"hdc",
|
||||
"hdr", "hdri", "hdris",
|
||||
"hh", "mm", "ss", "ff", # hh:mm:ss:ff timecode
|
||||
"hh", "mm", "ss", "ff", # `hh:mm:ss:ff` time-code.
|
||||
"hpg", # Intel Xe-HPG architecture
|
||||
"hsv", "hsva", "hsl",
|
||||
"id",
|
||||
|
|
|
@ -287,7 +287,7 @@ def bake_action_iter(
|
|||
while pbone.constraints:
|
||||
pbone.constraints.remove(pbone.constraints[0])
|
||||
|
||||
# Create compatible eulers, quats.
|
||||
# Create compatible euler & quaternion rotation values.
|
||||
euler_prev = None
|
||||
quat_prev = None
|
||||
|
||||
|
|
|
@ -233,19 +233,19 @@ def edge_loops_from_edges(mesh, edges=None):
|
|||
|
||||
def ngon_tessellate(from_data, indices, fix_loops=True, debug_print=True):
|
||||
"""
|
||||
Takes a polyline of indices (ngon) and returns a list of face
|
||||
Takes a poly-line of indices (ngon) and returns a list of face
|
||||
index lists. Designed to be used for importers that need indices for an
|
||||
ngon to create from existing verts.
|
||||
|
||||
:arg from_data: either a mesh, or a list/tuple of vectors.
|
||||
:type from_data: list or :class:`bpy.types.Mesh`
|
||||
:arg indices: a list of indices to use this list
|
||||
is the ordered closed polyline
|
||||
is the ordered closed poly-line
|
||||
to fill, and can be a subset of the data given.
|
||||
:type indices: list
|
||||
:arg fix_loops: If this is enabled polylines
|
||||
:arg fix_loops: If this is enabled poly-lines
|
||||
that use loops to make multiple
|
||||
polylines are delt with correctly.
|
||||
poly-lines are dealt with correctly.
|
||||
:type fix_loops: bool
|
||||
"""
|
||||
|
||||
|
|
|
@ -159,7 +159,7 @@ def location_3d_to_region_2d(region, rv3d, coord, *, default=None):
|
|||
:type region: :class:`bpy.types.Region`
|
||||
:arg rv3d: 3D region data, typically bpy.context.space_data.region_3d.
|
||||
:type rv3d: :class:`bpy.types.RegionView3D`
|
||||
:arg coord: 3d worldspace location.
|
||||
:arg coord: 3d world-space location.
|
||||
:type coord: 3d vector
|
||||
:arg default: Return this value if ``coord``
|
||||
is behind the origin of a perspective view.
|
||||
|
|
|
@ -305,7 +305,7 @@
|
|||
<ThemeWidgetColors
|
||||
outline="#e6e6e6"
|
||||
inner="#1a1a1a00"
|
||||
inner_sel="#c0c0c0ff"
|
||||
inner_sel="#668cccff"
|
||||
item="#1a1a1aff"
|
||||
text="#1a1a1a"
|
||||
text_sel="#000000"
|
||||
|
@ -316,21 +316,6 @@
|
|||
>
|
||||
</ThemeWidgetColors>
|
||||
</wcol_list_item>
|
||||
<wcol_view_item>
|
||||
<ThemeWidgetColors
|
||||
outline="#e6e6e6"
|
||||
inner="#c0c0c044"
|
||||
inner_sel="#c0c0c0ff"
|
||||
item="#1a1a1aff"
|
||||
text="#1a1a1a"
|
||||
text_sel="#000000"
|
||||
show_shaded="FALSE"
|
||||
shadetop="0"
|
||||
shadedown="0"
|
||||
roundness="0.4"
|
||||
>
|
||||
</ThemeWidgetColors>
|
||||
</wcol_view_item>
|
||||
<wcol_state>
|
||||
<ThemeWidgetStateColors
|
||||
inner_anim="#73be4c"
|
||||
|
|
|
@ -304,7 +304,7 @@ class Prefs(bpy.types.KeyConfigPreferences):
|
|||
col.row().prop(self, "v3d_mmb_action", text="Middle Mouse Action", expand=True)
|
||||
col.row().prop(self, "v3d_alt_mmb_drag_action", text="Alt Middle Mouse Drag Action", expand=True)
|
||||
|
||||
# Checkboxes sub-layout.
|
||||
# Check-boxes sub-layout.
|
||||
col = layout.column()
|
||||
sub = col.column(align=True)
|
||||
sub.prop(self, "use_v3d_tab_menu")
|
||||
|
|
|
@ -850,7 +850,7 @@ def km_screen(params):
|
|||
])
|
||||
|
||||
if params.apple:
|
||||
# Apple undo and user prefs
|
||||
# Apple undo and user-preferences.
|
||||
items.extend([
|
||||
("screen.userpref_show", {"type": 'COMMA', "value": 'PRESS', "oskey": True}, None),
|
||||
])
|
||||
|
@ -4041,7 +4041,7 @@ def km_grease_pencil_stroke_sculpt_mode(params):
|
|||
("gpencil.active_frames_delete_all", {"type": 'DEL', "value": 'PRESS', "shift": True}, None),
|
||||
# Context menu
|
||||
*_template_items_context_panel("VIEW3D_PT_gpencil_sculpt_context_menu", params.context_menu_event),
|
||||
# Automasking Pie menu
|
||||
# Auto-masking Pie menu.
|
||||
op_menu_pie("VIEW3D_MT_sculpt_gpencil_automasking_pie", {
|
||||
"type": 'A', "shift": True, "alt": True, "value": 'PRESS'}),
|
||||
])
|
||||
|
|
|
@ -3442,7 +3442,7 @@ def km_image_paint(params):
|
|||
# Stabilize Strokes
|
||||
("wm.context_toggle", {"type": 'L', "value": 'PRESS'},
|
||||
{"properties": [("data_path", 'tool_settings.image_paint.brush.use_smooth_stroke')]}),
|
||||
# Contrext Menu
|
||||
# Context menu.
|
||||
*_template_items_context_panel("VIEW3D_PT_paint_texture_context_menu",
|
||||
{"type": 'RIGHTMOUSE', "value": 'PRESS'}),
|
||||
# Tools
|
||||
|
@ -3500,7 +3500,7 @@ def km_vertex_paint(params):
|
|||
# Stabilize Stroke
|
||||
("wm.context_toggle", {"type": 'L', "value": 'PRESS'},
|
||||
{"properties": [("data_path", 'tool_settings.vertex_paint.brush.use_smooth_stroke')]}),
|
||||
# Contrext Menu
|
||||
# Context menu.
|
||||
*_template_items_context_panel("VIEW3D_PT_paint_vertex_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}),
|
||||
# Tools
|
||||
op_tool_cycle("builtin.select_box", {"type": 'Q', "value": 'PRESS'}),
|
||||
|
@ -3546,7 +3546,7 @@ def km_weight_paint(params):
|
|||
# Stabilize Stroke
|
||||
("wm.context_toggle", {"type": 'L', "value": 'PRESS'},
|
||||
{"properties": [("data_path", 'tool_settings.weight_paint.brush.use_smooth_stroke')]}),
|
||||
# Contrext Menu
|
||||
# Context menu.
|
||||
*_template_items_context_panel("VIEW3D_PT_paint_weight_context_menu", {"type": 'RIGHTMOUSE', "value": 'PRESS'}),
|
||||
# For combined weight paint + pose mode.
|
||||
("view3d.select", {"type": 'LEFTMOUSE', "value": 'PRESS', "shift": True, "alt": True}, None),
|
||||
|
@ -3817,7 +3817,7 @@ def km_armature(params):
|
|||
return keymap
|
||||
|
||||
|
||||
# Metaball edit mode.
|
||||
# Meta-ball edit mode.
|
||||
def km_metaball(params):
|
||||
items = []
|
||||
keymap = (
|
||||
|
|
|
@ -29,7 +29,7 @@ if sys.platform == "win32":
|
|||
|
||||
# OIIO will by default add all paths from the path variable to add_dll_directory
|
||||
# problem there is that those folders will be searched before ours and versions of
|
||||
# some dlls may be found that are not blenders and may not even be the right version
|
||||
# some DLL files may be found that are not blenders and may not even be the right version
|
||||
# causing compatibility issues.
|
||||
os.environ["OIIO_LOAD_DLLS_FROM_PATH"] = "0"
|
||||
|
||||
|
|
|
@ -677,7 +677,7 @@ class CLIP_OT_setup_tracking_scene(Operator):
|
|||
self.createCollection(context, "foreground")
|
||||
self.createCollection(context, "background")
|
||||
|
||||
# rendersettings
|
||||
# Render settings.
|
||||
setup_collection_recursively(
|
||||
vlayers["Foreground"].layer_collection.children,
|
||||
"background",
|
||||
|
|
|
@ -69,7 +69,7 @@ class SCENE_OT_freestyle_fill_range_by_selection(Operator):
|
|||
else:
|
||||
self.report({'ERROR'}, "Unexpected modifier type: " + m.type)
|
||||
return {'CANCELLED'}
|
||||
# Find selected vertices in editmesh
|
||||
# Find selected vertices in edit-mesh.
|
||||
ob = context.active_object
|
||||
if ob.type == 'MESH' and ob.mode == 'EDIT' and ob.name != ref.name:
|
||||
bpy.ops.object.mode_set(mode='OBJECT')
|
||||
|
|
|
@ -136,7 +136,9 @@ class MoveModifierToNodes(Operator):
|
|||
# Copy default values for inputs and create named attribute input nodes.
|
||||
input_nodes = []
|
||||
first_geometry_input = None
|
||||
for input_socket in old_group.inputs:
|
||||
for input_socket in old_group.interface.ui_items:
|
||||
if input_socket.item_type != 'SOCKET' or (input_socket.in_out not in {'INPUT', 'BOTH'}):
|
||||
continue
|
||||
identifier = input_socket.identifier
|
||||
group_node_input = get_socket_with_identifier(group_node.inputs, identifier)
|
||||
if modifier_input_use_attribute(modifier, identifier):
|
||||
|
@ -168,7 +170,9 @@ class MoveModifierToNodes(Operator):
|
|||
# Connect outputs to store named attribute nodes to replace modifier attribute outputs.
|
||||
store_nodes = []
|
||||
first_geometry_output = None
|
||||
for output_socket in old_group.outputs:
|
||||
for output_socket in old_group.interface.ui_items:
|
||||
if output_socket.item_type != 'SOCKET' or (output_socket.in_out not in {'OUTPUT', 'BOTH'}):
|
||||
continue
|
||||
identifier = output_socket.identifier
|
||||
group_node_output = get_socket_with_identifier(group_node.outputs, identifier)
|
||||
attribute_name = modifier_attribute_name_get(modifier, identifier)
|
||||
|
|
|
@ -313,7 +313,7 @@ class SequencerFadesAdd(Operator):
|
|||
for point in (fade.start, fade.end):
|
||||
keyframe_points.insert(frame=point.x, value=point.y, options={'FAST'})
|
||||
fade_fcurve.update()
|
||||
# The graph editor and the audio waveforms only redraw upon "moving" a keyframe
|
||||
# The graph editor and the audio wave-forms only redraw upon "moving" a keyframe.
|
||||
keyframe_points[-1].co = keyframe_points[-1].co
|
||||
|
||||
|
||||
|
|
|
@ -145,7 +145,7 @@ class PREFERENCES_OT_copy_prev(Operator):
|
|||
import shutil
|
||||
shutil.copytree(self._old_path(), self._new_path(), dirs_exist_ok=True, symlinks=True)
|
||||
|
||||
# reload preferences and recent-files.txt
|
||||
# Reload preferences and `recent-files.txt`.
|
||||
bpy.ops.wm.read_userpref()
|
||||
bpy.ops.wm.read_history()
|
||||
|
||||
|
|
|
@ -1183,7 +1183,7 @@ class WM_OT_path_open(Operator):
|
|||
try:
|
||||
subprocess.check_call(["xdg-open", filepath])
|
||||
except BaseException:
|
||||
# xdg-open *should* be supported by recent Gnome, KDE, Xfce
|
||||
# `xdg-open` *should* be supported by recent Gnome, KDE, XFCE.
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ _modules = [
|
|||
"node_add_menu",
|
||||
"node_add_menu_compositor",
|
||||
"node_add_menu_geometry",
|
||||
"node_add_menu_shader",
|
||||
"properties_animviz",
|
||||
"properties_constraint",
|
||||
"properties_data_armature",
|
||||
|
|
|
@ -3,22 +3,26 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import bpy
|
||||
from bpy.types import Menu
|
||||
from bl_ui import node_add_menu
|
||||
from bpy.app.translations import (
|
||||
pgettext_iface as iface_,
|
||||
contexts as i18n_contexts,
|
||||
)
|
||||
|
||||
|
||||
def add_node_type(layout, node_type, *, label=None):
|
||||
def add_node_type(layout, node_type, *, label=None, poll=None):
|
||||
"""Add a node type to a menu."""
|
||||
bl_rna = bpy.types.Node.bl_rna_get_subclass(node_type)
|
||||
if not label:
|
||||
label = bl_rna.name if bl_rna else iface_("Unknown")
|
||||
translation_context = bl_rna.translation_context if bl_rna else i18n_contexts.default
|
||||
props = layout.operator("node.add_node", text=label, text_ctxt=translation_context)
|
||||
props.type = node_type
|
||||
props.use_transform = True
|
||||
return props
|
||||
|
||||
if poll is True or poll is None:
|
||||
translation_context = bl_rna.translation_context if bl_rna else i18n_contexts.default
|
||||
props = layout.operator("node.add_node", text=label, text_ctxt=translation_context)
|
||||
props.type = node_type
|
||||
props.use_transform = True
|
||||
return props
|
||||
|
||||
|
||||
def draw_node_group_add_menu(context, layout):
|
||||
|
@ -71,7 +75,20 @@ def add_repeat_zone(layout, label):
|
|||
return props
|
||||
|
||||
|
||||
class NODE_MT_category_layout(Menu):
|
||||
bl_idname = "NODE_MT_category_layout"
|
||||
bl_label = "Layout"
|
||||
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
node_add_menu.add_node_type(layout, "NodeFrame")
|
||||
node_add_menu.add_node_type(layout, "NodeReroute")
|
||||
|
||||
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
|
||||
|
||||
|
||||
classes = (
|
||||
NODE_MT_category_layout,
|
||||
)
|
||||
|
||||
if __name__ == "__main__": # only for live edit.
|
||||
|
|
|
@ -10,8 +10,8 @@ from bpy.app.translations import (
|
|||
)
|
||||
|
||||
|
||||
class NODE_MT_category_COMP_INPUT(Menu):
|
||||
bl_idname = "NODE_MT_category_COMP_INPUT"
|
||||
class NODE_MT_category_compositor_input(Menu):
|
||||
bl_idname = "NODE_MT_category_compositor_input"
|
||||
bl_label = "Input"
|
||||
|
||||
def draw(self, context):
|
||||
|
@ -19,7 +19,7 @@ class NODE_MT_category_COMP_INPUT(Menu):
|
|||
is_group = (len(snode.path) > 1)
|
||||
|
||||
layout = self.layout
|
||||
layout.menu("NODE_MT_category_COMP_INPUT_CONSTANT")
|
||||
layout.menu("NODE_MT_category_compositor_input_constant")
|
||||
layout.separator()
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeBokehImage")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeImage")
|
||||
|
@ -31,13 +31,13 @@ class NODE_MT_category_COMP_INPUT(Menu):
|
|||
layout.separator()
|
||||
node_add_menu.add_node_type(layout, "NodeGroupInput")
|
||||
layout.separator()
|
||||
layout.menu("NODE_MT_category_COMP_INPUT_SCENE")
|
||||
layout.menu("NODE_MT_category_compositor_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"
|
||||
class NODE_MT_category_compositor_input_constant(Menu):
|
||||
bl_idname = "NODE_MT_category_compositor_input_constant"
|
||||
bl_label = "Constant"
|
||||
|
||||
def draw(self, _context):
|
||||
|
@ -48,8 +48,8 @@ class NODE_MT_category_COMP_INPUT_CONSTANT(Menu):
|
|||
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"
|
||||
class NODE_MT_category_compositor_input_scene(Menu):
|
||||
bl_idname = "NODE_MT_category_compositor_input_scene"
|
||||
bl_label = "Scene"
|
||||
|
||||
def draw(self, _context):
|
||||
|
@ -61,8 +61,8 @@ class NODE_MT_category_COMP_INPUT_SCENE(Menu):
|
|||
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"
|
||||
class NODE_MT_category_compositor_output(Menu):
|
||||
bl_idname = "NODE_MT_category_compositor_output"
|
||||
bl_label = "Output"
|
||||
|
||||
def draw(self, context):
|
||||
|
@ -83,15 +83,15 @@ class NODE_MT_category_COMP_OUTPUT(Menu):
|
|||
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
|
||||
|
||||
|
||||
class NODE_MT_category_COMP_COLOR(Menu):
|
||||
bl_idname = "NODE_MT_category_COMP_COLOR"
|
||||
class NODE_MT_category_compositor_color(Menu):
|
||||
bl_idname = "NODE_MT_category_compositor_color"
|
||||
bl_label = "Color"
|
||||
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
layout.menu("NODE_MT_category_COMP_COLOR_ADJUST")
|
||||
layout.menu("NODE_MT_category_compositor_color_adjust")
|
||||
layout.separator()
|
||||
layout.menu("NODE_MT_category_COMP_COLOR_MIX")
|
||||
layout.menu("NODE_MT_category_compositor_color_mix")
|
||||
layout.separator()
|
||||
node_add_menu.add_node_type(layout, "CompositorNodePremulKey")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeValToRGB")
|
||||
|
@ -104,8 +104,8 @@ class NODE_MT_category_COMP_COLOR(Menu):
|
|||
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"
|
||||
class NODE_MT_category_compositor_color_adjust(Menu):
|
||||
bl_idname = "NODE_MT_category_compositor_color_adjust"
|
||||
bl_label = "Adjust"
|
||||
|
||||
def draw(self, _context):
|
||||
|
@ -123,8 +123,8 @@ class NODE_MT_category_COMP_COLOR_ADJUST(Menu):
|
|||
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
|
||||
|
||||
|
||||
class NODE_MT_category_COMP_COLOR_MIX(Menu):
|
||||
bl_idname = "NODE_MT_category_COMP_COLOR_MIX"
|
||||
class NODE_MT_category_compositor_color_mix(Menu):
|
||||
bl_idname = "NODE_MT_category_compositor_color_mix"
|
||||
bl_label = "Mix"
|
||||
|
||||
def draw(self, _context):
|
||||
|
@ -141,13 +141,13 @@ class NODE_MT_category_COMP_COLOR_MIX(Menu):
|
|||
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
|
||||
|
||||
|
||||
class NODE_MT_category_COMP_FILTER(Menu):
|
||||
bl_idname = "NODE_MT_category_COMP_FILTER"
|
||||
class NODE_MT_category_compositor_filter(Menu):
|
||||
bl_idname = "NODE_MT_category_compositor_filter"
|
||||
bl_label = "Filter"
|
||||
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
layout.menu("NODE_MT_category_COMP_FILTER_BLUR")
|
||||
layout.menu("NODE_MT_category_compositor_filter_blur")
|
||||
layout.separator()
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeAntiAliasing")
|
||||
node_add_menu.add_node_type(layout, "CompositorNodeDenoise")
|
||||
|
@ -166,8 +166,8 @@ class NODE_MT_category_COMP_FILTER(Menu):
|
|||
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"
|
||||
class NODE_MT_category_compositor_filter_blur(Menu):
|
||||
bl_idname = "NODE_MT_category_compositor_filter_blur"
|
||||
bl_label = "Blur"
|
||||
|
||||
def draw(self, _context):
|
||||
|
@ -182,8 +182,8 @@ class NODE_MT_category_COMP_FILTER_BLUR(Menu):
|
|||
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"
|
||||
class NODE_MT_category_compositor_group(Menu):
|
||||
bl_idname = "NODE_MT_category_compositor_group"
|
||||
bl_label = "Group"
|
||||
|
||||
def draw(self, context):
|
||||
|
@ -192,8 +192,8 @@ 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"
|
||||
class NODE_MT_category_compositor_keying(Menu):
|
||||
bl_idname = "NODE_MT_category_compositor_keying"
|
||||
bl_label = "Keying"
|
||||
|
||||
def draw(self, _context):
|
||||
|
@ -211,8 +211,8 @@ class NODE_MT_category_COMP_KEYING(Menu):
|
|||
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"
|
||||
class NODE_MT_category_compositor_mask(Menu):
|
||||
bl_idname = "NODE_MT_category_compositor_mask"
|
||||
bl_label = "Mask"
|
||||
|
||||
def draw(self, _context):
|
||||
|
@ -229,8 +229,8 @@ class NODE_MT_category_COMP_MASK(Menu):
|
|||
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"
|
||||
class NODE_MT_category_compositor_tracking(Menu):
|
||||
bl_idname = "NODE_MT_category_compositor_tracking"
|
||||
bl_label = "Tracking"
|
||||
|
||||
def draw(self, _context):
|
||||
|
@ -242,8 +242,8 @@ class NODE_MT_category_COMP_TRACKING(Menu):
|
|||
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"
|
||||
class NODE_MT_category_compositor_transform(Menu):
|
||||
bl_idname = "NODE_MT_category_compositor_transform"
|
||||
bl_label = "Transform"
|
||||
|
||||
def draw(self, _context):
|
||||
|
@ -266,8 +266,8 @@ class NODE_MT_category_COMP_TRANSFORM(Menu):
|
|||
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"
|
||||
class NODE_MT_category_compositor_utilities(Menu):
|
||||
bl_idname = "NODE_MT_category_compositor_utilities"
|
||||
bl_label = "Utilities"
|
||||
|
||||
def draw(self, _context):
|
||||
|
@ -287,8 +287,8 @@ class NODE_MT_category_COMP_UTIL(Menu):
|
|||
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"
|
||||
class NODE_MT_category_compositor_vector(Menu):
|
||||
bl_idname = "NODE_MT_category_compositor_vector"
|
||||
bl_label = "Vector"
|
||||
|
||||
def draw(self, _context):
|
||||
|
@ -302,8 +302,8 @@ class NODE_MT_category_COMP_VECTOR(Menu):
|
|||
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"
|
||||
class NODE_MT_category_compositor_LAYOUT(Menu):
|
||||
bl_idname = "NODE_MT_category_compositor_LAYOUT"
|
||||
bl_label = "Layout"
|
||||
|
||||
def draw(self, _context):
|
||||
|
@ -314,52 +314,51 @@ class NODE_MT_category_COMP_LAYOUT(Menu):
|
|||
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
|
||||
|
||||
|
||||
class NODE_MT_compositing_node_add_all(Menu):
|
||||
bl_idname = "NODE_MT_compositing_node_add_all"
|
||||
class NODE_MT_compositor_node_add_all(Menu):
|
||||
bl_idname = "NODE_MT_compositor_node_add_all"
|
||||
bl_label = ""
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
layout.menu("NODE_MT_category_COMP_INPUT")
|
||||
layout.menu("NODE_MT_category_COMP_OUTPUT")
|
||||
layout.menu("NODE_MT_category_compositor_input")
|
||||
layout.menu("NODE_MT_category_compositor_output")
|
||||
layout.separator()
|
||||
layout.menu("NODE_MT_category_COMP_COLOR")
|
||||
layout.menu("NODE_MT_category_COMP_FILTER")
|
||||
layout.menu("NODE_MT_category_compositor_color")
|
||||
layout.menu("NODE_MT_category_compositor_filter")
|
||||
layout.separator()
|
||||
layout.menu("NODE_MT_category_COMP_KEYING")
|
||||
layout.menu("NODE_MT_category_COMP_MASK")
|
||||
layout.menu("NODE_MT_category_compositor_keying")
|
||||
layout.menu("NODE_MT_category_compositor_mask")
|
||||
layout.separator()
|
||||
layout.menu("NODE_MT_category_COMP_TRACKING")
|
||||
layout.menu("NODE_MT_category_compositor_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.menu("NODE_MT_category_compositor_transform")
|
||||
layout.menu("NODE_MT_category_compositor_utilities")
|
||||
layout.menu("NODE_MT_category_compositor_vector")
|
||||
layout.separator()
|
||||
layout.menu("NODE_MT_category_COMP_GROUP")
|
||||
layout.menu("NODE_MT_category_COMP_LAYOUT")
|
||||
layout.menu("NODE_MT_category_compositor_group")
|
||||
layout.menu("NODE_MT_category_layout")
|
||||
|
||||
node_add_menu.draw_root_assets(layout)
|
||||
|
||||
|
||||
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_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_GROUP,
|
||||
NODE_MT_category_COMP_LAYOUT,
|
||||
NODE_MT_compositor_node_add_all,
|
||||
NODE_MT_category_compositor_input,
|
||||
NODE_MT_category_compositor_input_constant,
|
||||
NODE_MT_category_compositor_input_scene,
|
||||
NODE_MT_category_compositor_output,
|
||||
NODE_MT_category_compositor_color,
|
||||
NODE_MT_category_compositor_color_adjust,
|
||||
NODE_MT_category_compositor_color_mix,
|
||||
NODE_MT_category_compositor_filter,
|
||||
NODE_MT_category_compositor_filter_blur,
|
||||
NODE_MT_category_compositor_keying,
|
||||
NODE_MT_category_compositor_mask,
|
||||
NODE_MT_category_compositor_tracking,
|
||||
NODE_MT_category_compositor_transform,
|
||||
NODE_MT_category_compositor_utilities,
|
||||
NODE_MT_category_compositor_vector,
|
||||
NODE_MT_category_compositor_group,
|
||||
)
|
||||
|
||||
if __name__ == "__main__": # only for live edit.
|
||||
|
|
|
@ -653,17 +653,6 @@ class NODE_MT_category_GEO_GROUP(Menu):
|
|||
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
|
||||
|
||||
|
||||
class NODE_MT_category_GEO_LAYOUT(Menu):
|
||||
bl_idname = "NODE_MT_category_GEO_LAYOUT"
|
||||
bl_label = "Layout"
|
||||
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
node_add_menu.add_node_type(layout, "NodeFrame")
|
||||
node_add_menu.add_node_type(layout, "NodeReroute")
|
||||
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
|
||||
|
||||
|
||||
class NODE_MT_geometry_node_add_all(Menu):
|
||||
bl_idname = "NODE_MT_geometry_node_add_all"
|
||||
bl_label = ""
|
||||
|
@ -690,7 +679,7 @@ class NODE_MT_geometry_node_add_all(Menu):
|
|||
layout.menu("NODE_MT_category_GEO_UTILITIES")
|
||||
layout.separator()
|
||||
layout.menu("NODE_MT_category_GEO_GROUP")
|
||||
layout.menu("NODE_MT_category_GEO_LAYOUT")
|
||||
layout.menu("NODE_MT_category_layout")
|
||||
node_add_menu.draw_root_assets(layout)
|
||||
|
||||
|
||||
|
@ -736,7 +725,6 @@ classes = (
|
|||
NODE_MT_category_GEO_UTILITIES_MATH,
|
||||
NODE_MT_category_GEO_UTILITIES_ROTATION,
|
||||
NODE_MT_category_GEO_GROUP,
|
||||
NODE_MT_category_GEO_LAYOUT,
|
||||
)
|
||||
|
||||
if __name__ == "__main__": # only for live edit.
|
||||
|
|
|
@ -0,0 +1,398 @@
|
|||
# SPDX-FileCopyrightText: 2022-2023 Blender Authors
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import bpy
|
||||
from bpy.types import Menu
|
||||
from bl_ui import node_add_menu
|
||||
from bpy.app.translations import (
|
||||
pgettext_iface as iface_,
|
||||
)
|
||||
|
||||
|
||||
# only show input/output nodes when editing line style node trees
|
||||
def line_style_shader_nodes_poll(context):
|
||||
snode = context.space_data
|
||||
return (snode.tree_type == 'ShaderNodeTree' and
|
||||
snode.shader_type == 'LINESTYLE')
|
||||
|
||||
|
||||
# only show nodes working in world node trees
|
||||
def world_shader_nodes_poll(context):
|
||||
snode = context.space_data
|
||||
return (snode.tree_type == 'ShaderNodeTree' and
|
||||
snode.shader_type == 'WORLD')
|
||||
|
||||
|
||||
# only show nodes working in object node trees
|
||||
def object_shader_nodes_poll(context):
|
||||
snode = context.space_data
|
||||
return (snode.tree_type == 'ShaderNodeTree' and
|
||||
snode.shader_type == 'OBJECT')
|
||||
|
||||
|
||||
def cycles_shader_nodes_poll(context):
|
||||
return context.engine == 'CYCLES'
|
||||
|
||||
|
||||
def eevee_shader_nodes_poll(context):
|
||||
return context.engine == 'BLENDER_EEVEE'
|
||||
|
||||
|
||||
def eevee_cycles_shader_nodes_poll(context):
|
||||
return (cycles_shader_nodes_poll(context) or
|
||||
eevee_shader_nodes_poll(context))
|
||||
|
||||
|
||||
def object_cycles_shader_nodes_poll(context):
|
||||
return (object_shader_nodes_poll(context) and
|
||||
cycles_shader_nodes_poll(context))
|
||||
|
||||
|
||||
def object_eevee_shader_nodes_poll(context):
|
||||
return (object_shader_nodes_poll(context) and
|
||||
eevee_shader_nodes_poll(context))
|
||||
|
||||
|
||||
def object_eevee_cycles_shader_nodes_poll(context):
|
||||
return (object_shader_nodes_poll(context) and
|
||||
eevee_cycles_shader_nodes_poll(context))
|
||||
|
||||
|
||||
class NODE_MT_category_shader_input(Menu):
|
||||
bl_idname = "NODE_MT_category_shader_input"
|
||||
bl_label = "Input"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeAmbientOcclusion")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeAttribute")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeBevel")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeCameraData")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeVertexColor")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeHairInfo")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeFresnel")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeNewGeometry")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeLayerWeight")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeLightPath")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeObjectInfo")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeParticleInfo")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodePointInfo")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeRGB")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeTangent")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeTexCoord")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeUVAlongStroke", poll=line_style_shader_nodes_poll(context))
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeUVMap")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeValue")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeVolumeInfo")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeWireframe")
|
||||
|
||||
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
|
||||
|
||||
|
||||
class NODE_MT_category_shader_output(Menu):
|
||||
bl_idname = "NODE_MT_category_shader_output"
|
||||
bl_label = "Output"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
node_add_menu.add_node_type(
|
||||
layout,
|
||||
"ShaderNodeOutputMaterial",
|
||||
poll=object_eevee_cycles_shader_nodes_poll(context),
|
||||
)
|
||||
node_add_menu.add_node_type(
|
||||
layout,
|
||||
"ShaderNodeOutputLight",
|
||||
poll=object_cycles_shader_nodes_poll(context),
|
||||
)
|
||||
node_add_menu.add_node_type(
|
||||
layout,
|
||||
"ShaderNodeOutputAOV",
|
||||
)
|
||||
node_add_menu.add_node_type(
|
||||
layout,
|
||||
"ShaderNodeOutputWorld",
|
||||
poll=world_shader_nodes_poll(context),
|
||||
)
|
||||
node_add_menu.add_node_type(
|
||||
layout,
|
||||
"ShaderNodeOutputLineStyle",
|
||||
poll=line_style_shader_nodes_poll(context),
|
||||
)
|
||||
|
||||
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
|
||||
|
||||
|
||||
class NODE_MT_category_shader_shader(Menu):
|
||||
bl_idname = "NODE_MT_category_shader_shader"
|
||||
bl_label = "Shader"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
node_add_menu.add_node_type(
|
||||
layout,
|
||||
"ShaderNodeAddShader",
|
||||
poll=eevee_cycles_shader_nodes_poll(context),
|
||||
)
|
||||
node_add_menu.add_node_type(
|
||||
layout,
|
||||
"ShaderNodeBackground",
|
||||
poll=world_shader_nodes_poll(context),
|
||||
)
|
||||
node_add_menu.add_node_type(
|
||||
layout,
|
||||
"ShaderNodeBsdfDiffuse",
|
||||
poll=object_eevee_cycles_shader_nodes_poll(context),
|
||||
)
|
||||
node_add_menu.add_node_type(
|
||||
layout,
|
||||
"ShaderNodeEmission",
|
||||
poll=eevee_cycles_shader_nodes_poll(context),
|
||||
)
|
||||
node_add_menu.add_node_type(
|
||||
layout,
|
||||
"ShaderNodeBsdfGlass",
|
||||
poll=object_eevee_cycles_shader_nodes_poll(context),
|
||||
)
|
||||
node_add_menu.add_node_type(
|
||||
layout,
|
||||
"ShaderNodeBsdfGlossy",
|
||||
poll=object_eevee_cycles_shader_nodes_poll(context),
|
||||
)
|
||||
node_add_menu.add_node_type(
|
||||
layout,
|
||||
"ShaderNodeBsdfHair",
|
||||
poll=object_cycles_shader_nodes_poll(context),
|
||||
)
|
||||
node_add_menu.add_node_type(
|
||||
layout,
|
||||
"ShaderNodeHoldout",
|
||||
poll=object_eevee_cycles_shader_nodes_poll(context),
|
||||
)
|
||||
node_add_menu.add_node_type(
|
||||
layout,
|
||||
"ShaderNodeMixShader",
|
||||
poll=eevee_cycles_shader_nodes_poll(context),
|
||||
)
|
||||
node_add_menu.add_node_type(
|
||||
layout,
|
||||
"ShaderNodeBsdfPrincipled",
|
||||
poll=object_eevee_cycles_shader_nodes_poll(context),
|
||||
)
|
||||
node_add_menu.add_node_type(
|
||||
layout,
|
||||
"ShaderNodeBsdfHairPrincipled",
|
||||
poll=object_cycles_shader_nodes_poll(context),
|
||||
)
|
||||
node_add_menu.add_node_type(
|
||||
layout,
|
||||
"ShaderNodeVolumePrincipled"
|
||||
)
|
||||
node_add_menu.add_node_type(
|
||||
layout,
|
||||
"ShaderNodeBsdfRefraction",
|
||||
poll=object_eevee_cycles_shader_nodes_poll(context),
|
||||
)
|
||||
node_add_menu.add_node_type(
|
||||
layout,
|
||||
"ShaderNodeBsdfSheen",
|
||||
poll=object_cycles_shader_nodes_poll(context),
|
||||
)
|
||||
node_add_menu.add_node_type(
|
||||
layout,
|
||||
"ShaderNodeEeveeSpecular",
|
||||
poll=object_eevee_shader_nodes_poll(context),
|
||||
)
|
||||
node_add_menu.add_node_type(
|
||||
layout,
|
||||
"ShaderNodeSubsurfaceScattering",
|
||||
poll=object_eevee_cycles_shader_nodes_poll(context),
|
||||
)
|
||||
node_add_menu.add_node_type(
|
||||
layout,
|
||||
"ShaderNodeBsdfToon",
|
||||
poll=object_cycles_shader_nodes_poll(context),
|
||||
)
|
||||
node_add_menu.add_node_type(
|
||||
layout,
|
||||
"ShaderNodeBsdfTranslucent",
|
||||
poll=object_eevee_cycles_shader_nodes_poll(context),
|
||||
)
|
||||
node_add_menu.add_node_type(
|
||||
layout,
|
||||
"ShaderNodeBsdfTransparent",
|
||||
poll=object_eevee_cycles_shader_nodes_poll(context),
|
||||
)
|
||||
node_add_menu.add_node_type(
|
||||
layout,
|
||||
"ShaderNodeVolumeAbsorption",
|
||||
poll=eevee_cycles_shader_nodes_poll(context),
|
||||
)
|
||||
node_add_menu.add_node_type(
|
||||
layout,
|
||||
"ShaderNodeVolumeScatter",
|
||||
poll=eevee_cycles_shader_nodes_poll(context),
|
||||
)
|
||||
|
||||
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
|
||||
|
||||
|
||||
class NODE_MT_category_shader_color(Menu):
|
||||
bl_idname = "NODE_MT_category_shader_color"
|
||||
bl_label = "Color"
|
||||
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeBrightContrast")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeGamma")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeHueSaturation")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeInvert")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeLightFalloff")
|
||||
props = node_add_menu.add_node_type(layout, "ShaderNodeMix", label=iface_("Mix Color"))
|
||||
ops = props.settings.add()
|
||||
ops.name = "data_type"
|
||||
ops.value = "'RGBA'"
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeRGBCurve")
|
||||
|
||||
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
|
||||
|
||||
|
||||
class NODE_MT_category_shader_converter(Menu):
|
||||
bl_idname = "NODE_MT_category_shader_converter"
|
||||
bl_label = "Converter"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeBlackbody")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeClamp")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeValToRGB")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeCombineColor")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeCombineXYZ")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeFloatCurve")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeMapRange")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeMath")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeMix")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeRGBToBW")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeSeparateColor")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeSeparateXYZ")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeShaderToRGB", poll=object_eevee_shader_nodes_poll(context))
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeVectorMath")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeWavelength")
|
||||
|
||||
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
|
||||
|
||||
|
||||
class NODE_MT_category_shader_texture(Menu):
|
||||
bl_idname = "NODE_MT_category_shader_texture"
|
||||
bl_label = "Texture"
|
||||
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeTexBrick")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeTexChecker")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeTexEnvironment")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeTexGradient")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeTexIES")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeTexImage")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeTexMagic")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeTexMusgrave")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeTexNoise")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeTexPointDensity")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeTexSky")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeTexVoronoi")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeTexWave")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeTexWhiteNoise")
|
||||
|
||||
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
|
||||
|
||||
|
||||
class NODE_MT_category_shader_vector(Menu):
|
||||
bl_idname = "NODE_MT_category_shader_vector"
|
||||
bl_label = "Vector"
|
||||
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeBump")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeDisplacement")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeMapping")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeNormal")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeNormalMap")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeVectorCurve")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeVectorDisplacement")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeVectorRotate")
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeVectorTransform")
|
||||
|
||||
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
|
||||
|
||||
|
||||
class NODE_MT_category_shader_script(Menu):
|
||||
bl_idname = "NODE_MT_category_shader_script"
|
||||
bl_label = "Script"
|
||||
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
|
||||
node_add_menu.add_node_type(layout, "ShaderNodeScript")
|
||||
|
||||
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
|
||||
|
||||
|
||||
class NODE_MT_category_shader_group(Menu):
|
||||
bl_idname = "NODE_MT_category_shader_group"
|
||||
bl_label = "Group"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
node_add_menu.draw_node_group_add_menu(context, layout)
|
||||
node_add_menu.draw_assets_for_catalog(layout, self.bl_label)
|
||||
|
||||
|
||||
class NODE_MT_shader_node_add_all(Menu):
|
||||
bl_idname = "NODE_MT_shader_node_add_all"
|
||||
bl_label = "Add"
|
||||
|
||||
def draw(self, _context):
|
||||
layout = self.layout
|
||||
layout.menu("NODE_MT_category_shader_input")
|
||||
layout.menu("NODE_MT_category_shader_output")
|
||||
layout.separator()
|
||||
layout.menu("NODE_MT_category_shader_color")
|
||||
layout.menu("NODE_MT_category_shader_converter")
|
||||
layout.menu("NODE_MT_category_shader_shader")
|
||||
layout.menu("NODE_MT_category_shader_texture")
|
||||
layout.menu("NODE_MT_category_shader_vector")
|
||||
layout.separator()
|
||||
layout.menu("NODE_MT_category_shader_script")
|
||||
layout.separator()
|
||||
layout.menu("NODE_MT_category_shader_group")
|
||||
layout.menu("NODE_MT_category_layout")
|
||||
|
||||
node_add_menu.draw_root_assets(layout)
|
||||
|
||||
|
||||
classes = (
|
||||
NODE_MT_shader_node_add_all,
|
||||
NODE_MT_category_shader_input,
|
||||
NODE_MT_category_shader_output,
|
||||
NODE_MT_category_shader_color,
|
||||
NODE_MT_category_shader_converter,
|
||||
NODE_MT_category_shader_shader,
|
||||
NODE_MT_category_shader_texture,
|
||||
NODE_MT_category_shader_vector,
|
||||
NODE_MT_category_shader_script,
|
||||
NODE_MT_category_shader_group,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__": # only for live edit.
|
||||
from bpy.utils import register_class
|
||||
for cls in classes:
|
||||
register_class(cls)
|
|
@ -957,7 +957,7 @@ class ConstraintButtonsPanel:
|
|||
self.draw_influence(layout, con)
|
||||
|
||||
|
||||
# Parent class for constraint subpanels
|
||||
# Parent class for constraint sub-panels.
|
||||
class ConstraintButtonsSubPanel:
|
||||
bl_space_type = 'PROPERTIES'
|
||||
bl_region_type = 'WINDOW'
|
||||
|
@ -1443,7 +1443,7 @@ class BONE_PT_bTransformConstraint_to(BoneConstraintPanel, ConstraintButtonsSubP
|
|||
self.draw_transform_to(context)
|
||||
|
||||
|
||||
# Shrinkwrap Constraint
|
||||
# Shrink-wrap Constraint.
|
||||
|
||||
class OBJECT_PT_bShrinkwrapConstraint(ObjectConstraintPanel, ConstraintButtonsPanel, Panel):
|
||||
def draw(self, context):
|
||||
|
|
|
@ -235,7 +235,7 @@ class SCENE_PT_keying_set_paths(SceneButtonsPanel, SceneKeyingSetsPanel, Panel):
|
|||
# TODO: 1) the template_any_ID needs to be fixed for the text alignment.
|
||||
# 2) use_property_decorate has to properly skip the non animatable properties.
|
||||
# Properties affected with needless draw:
|
||||
# group_method, template_any_ID dropdown, use_entire_array
|
||||
# group_method, template_any_ID drop-down, use_entire_array.
|
||||
|
||||
layout.use_property_split = True
|
||||
layout.use_property_decorate = False # No animation (remove this later on).
|
||||
|
|
|
@ -49,7 +49,7 @@ class DopesheetFilterPopoverBase:
|
|||
bl_region_type = 'HEADER'
|
||||
bl_label = "Filters"
|
||||
|
||||
# Generic = Affects all datatypes
|
||||
# Generic = Affects all data-types.
|
||||
# XXX: Perhaps we want these to stay in the header instead, for easy/fast access
|
||||
@classmethod
|
||||
def draw_generic_filters(cls, context, layout):
|
||||
|
@ -160,7 +160,7 @@ class DopesheetFilterPopoverBase:
|
|||
col.prop(dopesheet, "use_datablock_sort", icon='NONE')
|
||||
|
||||
|
||||
# Popover for Dopesheet Editor(s) - Dopesheet, Action, Shapekey, GPencil, Mask, etc.
|
||||
# Popover for Dope-sheet Editor(s) - Dope-sheet, Action, Shape-key, GPencil, Mask, etc.
|
||||
class DOPESHEET_PT_filters(DopesheetFilterPopoverBase, Panel):
|
||||
bl_space_type = 'DOPESHEET_EDITOR'
|
||||
bl_region_type = 'HEADER'
|
||||
|
|
|
@ -238,14 +238,18 @@ class NODE_MT_add(bpy.types.Menu):
|
|||
elif snode.tree_type == 'CompositorNodeTree':
|
||||
props = layout.operator("node.add_search", text="Search...", icon='VIEWZOOM')
|
||||
layout.separator()
|
||||
layout.menu_contents("NODE_MT_compositing_node_add_all")
|
||||
layout.menu_contents("NODE_MT_compositor_node_add_all")
|
||||
elif snode.tree_type == 'ShaderNodeTree':
|
||||
props = layout.operator("node.add_search", text="Search...", icon='VIEWZOOM')
|
||||
layout.separator()
|
||||
layout.menu_contents("NODE_MT_shader_node_add_all")
|
||||
elif nodeitems_utils.has_node_categories(context):
|
||||
props = layout.operator("node.add_search", text="Search...", icon='VIEWZOOM')
|
||||
props.use_transform = True
|
||||
|
||||
layout.separator()
|
||||
|
||||
# actual node submenus are defined by draw functions from node categories
|
||||
# Actual node sub-menus are defined by draw functions from node categories.
|
||||
nodeitems_utils.draw_node_categories_menu(self, context)
|
||||
|
||||
|
||||
|
|
|
@ -603,22 +603,16 @@ class TOPBAR_MT_edit(Menu):
|
|||
|
||||
layout.operator("ed.undo")
|
||||
layout.operator("ed.redo")
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.menu("TOPBAR_MT_undo_history")
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("screen.redo_last", text="Adjust Last Operation...")
|
||||
layout.operator("screen.repeat_last")
|
||||
layout.operator("screen.repeat_history", text="Repeat History...")
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("screen.redo_last", text="Adjust Last Operation...")
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("wm.search_menu", text="Menu Search...", icon='VIEWZOOM')
|
||||
if show_developer:
|
||||
layout.operator("wm.search_operator", text="Operator Search...", icon='VIEWZOOM')
|
||||
|
@ -699,45 +693,27 @@ class TOPBAR_MT_help(Menu):
|
|||
|
||||
show_developer = context.preferences.view.show_developer_ui
|
||||
|
||||
layout.operator("wm.url_open_preset", text="Manual",
|
||||
icon='HELP').type = 'MANUAL'
|
||||
|
||||
layout.operator(
|
||||
"wm.url_open", text="Tutorials", icon='URL',
|
||||
).url = "https://www.blender.org/tutorials"
|
||||
layout.operator(
|
||||
"wm.url_open", text="Support", icon='URL',
|
||||
).url = "https://www.blender.org/support"
|
||||
layout.operator("wm.url_open_preset", text="Manual", icon='URL').type = 'MANUAL'
|
||||
layout.operator("wm.url_open_preset", text="Release Notes").type = 'RELEASE_NOTES'
|
||||
layout.operator("wm.url_open", text="Tutorials").url = "https://www.blender.org/tutorials"
|
||||
layout.operator("wm.url_open", text="Support").url = "https://www.blender.org/support"
|
||||
layout.operator("wm.url_open", text="User Communities").url = "https://www.blender.org/community/"
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator(
|
||||
"wm.url_open", text="User Communities", icon='URL',
|
||||
).url = "https://www.blender.org/community/"
|
||||
layout.operator(
|
||||
"wm.url_open", text="Developer Community", icon='URL',
|
||||
).url = "https://devtalk.blender.org"
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator(
|
||||
"wm.url_open_preset", text="Python API Reference", icon='URL',
|
||||
).type = 'API'
|
||||
|
||||
if show_developer:
|
||||
layout.operator(
|
||||
"wm.url_open", text="Developer Documentation", icon='URL',
|
||||
"wm.url_open",
|
||||
text="Developer Documentation",
|
||||
icon='URL',
|
||||
).url = "https://wiki.blender.org/wiki/Main_Page"
|
||||
|
||||
layout.operator("wm.url_open", text="Developer Community").url = "https://devtalk.blender.org"
|
||||
layout.operator("wm.url_open_preset", text="Python API Reference").type = 'API'
|
||||
layout.operator("wm.operator_cheat_sheet", icon='TEXT')
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("wm.url_open_preset",
|
||||
text="Report a Bug", icon='URL').type = 'BUG'
|
||||
|
||||
layout.separator()
|
||||
|
||||
layout.operator("wm.url_open_preset", text="Report a Bug", icon='URL').type = 'BUG'
|
||||
layout.operator("wm.sysinfo")
|
||||
|
||||
|
||||
|
|
|
@ -1245,8 +1245,6 @@ class ThemeGenericClassGenerator:
|
|||
("Toolbar Item", "wcol_toolbar_item"),
|
||||
("Tooltip", "wcol_tooltip"),
|
||||
("Value Slider", "wcol_numslider"),
|
||||
# Not used yet, so hide this from the UI.
|
||||
# ("Data-View Item", "wcol_view_item"),
|
||||
]
|
||||
|
||||
for (name, wcol) in wcols:
|
||||
|
|
|
@ -7641,7 +7641,7 @@ class VIEW3D_PT_context_properties(Panel):
|
|||
rna_prop_ui.draw(self.layout, context, member, object, use_edit=False)
|
||||
|
||||
|
||||
# Grease Pencil Object - Multiframe falloff tools
|
||||
# Grease Pencil Object - Multi-frame falloff tools.
|
||||
class VIEW3D_PT_gpencil_multi_frame(Panel):
|
||||
bl_space_type = 'VIEW_3D'
|
||||
bl_region_type = 'HEADER'
|
||||
|
|
|
@ -738,9 +738,9 @@ class VIEW3D_PT_tools_brush_stroke_smooth_stroke(Panel, View3DPaintPanel, Smooth
|
|||
|
||||
|
||||
class VIEW3D_PT_tools_weight_gradient(Panel, View3DPaintPanel):
|
||||
# dont give context on purpose to not show this in the generic header toolsettings
|
||||
# Don't give context on purpose to not show this in the generic header tool-settings
|
||||
# this is added only in the gradient tool's ToolDef
|
||||
# bl_context = ".weightpaint" # dot on purpose (access from topbar)
|
||||
# `bl_context = ".weightpaint"` # dot on purpose (access from top-bar)
|
||||
bl_label = "Falloff"
|
||||
bl_options = {'DEFAULT_CLOSED'}
|
||||
# also dont draw as an extra panel in the sidebar (already included in the Brush settings)
|
||||
|
|
|
@ -82,10 +82,10 @@ def node_group_items(context):
|
|||
for group in context.blend_data.node_groups:
|
||||
if group.bl_idname != ntree.bl_idname:
|
||||
continue
|
||||
# filter out recursive groups
|
||||
# Filter out recursive groups.
|
||||
if group.contains_tree(ntree):
|
||||
continue
|
||||
# filter out hidden nodetrees
|
||||
# Filter out hidden node-trees.
|
||||
if group.name.startswith('.'):
|
||||
continue
|
||||
yield NodeItem(node_tree_group_type[group.bl_idname],
|
||||
|
@ -101,291 +101,6 @@ def group_input_output_item_poll(context):
|
|||
return False
|
||||
|
||||
|
||||
# only show input/output nodes when editing line style node trees
|
||||
def line_style_shader_nodes_poll(context):
|
||||
snode = context.space_data
|
||||
return (snode.tree_type == 'ShaderNodeTree' and
|
||||
snode.shader_type == 'LINESTYLE')
|
||||
|
||||
|
||||
# only show nodes working in world node trees
|
||||
def world_shader_nodes_poll(context):
|
||||
snode = context.space_data
|
||||
return (snode.tree_type == 'ShaderNodeTree' and
|
||||
snode.shader_type == 'WORLD')
|
||||
|
||||
|
||||
# only show nodes working in object node trees
|
||||
def object_shader_nodes_poll(context):
|
||||
snode = context.space_data
|
||||
return (snode.tree_type == 'ShaderNodeTree' and
|
||||
snode.shader_type == 'OBJECT')
|
||||
|
||||
|
||||
def cycles_shader_nodes_poll(context):
|
||||
return context.engine == 'CYCLES'
|
||||
|
||||
|
||||
def eevee_shader_nodes_poll(context):
|
||||
return context.engine == 'BLENDER_EEVEE'
|
||||
|
||||
|
||||
def eevee_cycles_shader_nodes_poll(context):
|
||||
return (cycles_shader_nodes_poll(context) or
|
||||
eevee_shader_nodes_poll(context))
|
||||
|
||||
|
||||
def object_cycles_shader_nodes_poll(context):
|
||||
return (object_shader_nodes_poll(context) and
|
||||
cycles_shader_nodes_poll(context))
|
||||
|
||||
|
||||
def object_eevee_shader_nodes_poll(context):
|
||||
return (object_shader_nodes_poll(context) and
|
||||
eevee_shader_nodes_poll(context))
|
||||
|
||||
|
||||
def object_eevee_cycles_shader_nodes_poll(context):
|
||||
return (object_shader_nodes_poll(context) and
|
||||
eevee_cycles_shader_nodes_poll(context))
|
||||
|
||||
|
||||
# All standard node categories currently used in nodes.
|
||||
|
||||
shader_node_categories = [
|
||||
# Shader Nodes (Cycles and Eevee)
|
||||
ShaderNodeCategory("SH_NEW_INPUT", "Input", items=[
|
||||
NodeItem("ShaderNodeTexCoord"),
|
||||
NodeItem("ShaderNodeAttribute"),
|
||||
NodeItem("ShaderNodeLightPath"),
|
||||
NodeItem("ShaderNodeFresnel"),
|
||||
NodeItem("ShaderNodeLayerWeight"),
|
||||
NodeItem("ShaderNodeRGB"),
|
||||
NodeItem("ShaderNodeValue"),
|
||||
NodeItem("ShaderNodeTangent"),
|
||||
NodeItem("ShaderNodeNewGeometry"),
|
||||
NodeItem("ShaderNodeWireframe"),
|
||||
NodeItem("ShaderNodeBevel"),
|
||||
NodeItem("ShaderNodeAmbientOcclusion"),
|
||||
NodeItem("ShaderNodeObjectInfo"),
|
||||
NodeItem("ShaderNodeHairInfo"),
|
||||
NodeItem("ShaderNodePointInfo"),
|
||||
NodeItem("ShaderNodeVolumeInfo"),
|
||||
NodeItem("ShaderNodeParticleInfo"),
|
||||
NodeItem("ShaderNodeCameraData"),
|
||||
NodeItem("ShaderNodeUVMap"),
|
||||
NodeItem("ShaderNodeVertexColor"),
|
||||
NodeItem("ShaderNodeUVAlongStroke", poll=line_style_shader_nodes_poll),
|
||||
]),
|
||||
ShaderNodeCategory("SH_NEW_OUTPUT", "Output", items=[
|
||||
NodeItem("ShaderNodeOutputMaterial", poll=object_eevee_cycles_shader_nodes_poll),
|
||||
NodeItem("ShaderNodeOutputLight", poll=object_cycles_shader_nodes_poll),
|
||||
NodeItem("ShaderNodeOutputAOV"),
|
||||
NodeItem("ShaderNodeOutputWorld", poll=world_shader_nodes_poll),
|
||||
NodeItem("ShaderNodeOutputLineStyle", poll=line_style_shader_nodes_poll),
|
||||
]),
|
||||
ShaderNodeCategory("SH_NEW_SHADER", "Shader", items=[
|
||||
NodeItem("ShaderNodeMixShader", poll=eevee_cycles_shader_nodes_poll),
|
||||
NodeItem("ShaderNodeAddShader", poll=eevee_cycles_shader_nodes_poll),
|
||||
NodeItem("ShaderNodeBsdfDiffuse", poll=object_eevee_cycles_shader_nodes_poll),
|
||||
NodeItem("ShaderNodeBsdfPrincipled", poll=object_eevee_cycles_shader_nodes_poll),
|
||||
NodeItem("ShaderNodeBsdfGlossy", poll=object_eevee_cycles_shader_nodes_poll),
|
||||
NodeItem("ShaderNodeBsdfTransparent", poll=object_eevee_cycles_shader_nodes_poll),
|
||||
NodeItem("ShaderNodeBsdfRefraction", poll=object_eevee_cycles_shader_nodes_poll),
|
||||
NodeItem("ShaderNodeBsdfGlass", poll=object_eevee_cycles_shader_nodes_poll),
|
||||
NodeItem("ShaderNodeBsdfTranslucent", poll=object_eevee_cycles_shader_nodes_poll),
|
||||
NodeItem("ShaderNodeBsdfSheen", poll=object_cycles_shader_nodes_poll),
|
||||
NodeItem("ShaderNodeBsdfToon", poll=object_cycles_shader_nodes_poll),
|
||||
NodeItem("ShaderNodeSubsurfaceScattering", poll=object_eevee_cycles_shader_nodes_poll),
|
||||
NodeItem("ShaderNodeEmission", poll=eevee_cycles_shader_nodes_poll),
|
||||
NodeItem("ShaderNodeBsdfHair", poll=object_cycles_shader_nodes_poll),
|
||||
NodeItem("ShaderNodeBackground", poll=world_shader_nodes_poll),
|
||||
NodeItem("ShaderNodeHoldout", poll=object_eevee_cycles_shader_nodes_poll),
|
||||
NodeItem("ShaderNodeVolumeAbsorption", poll=eevee_cycles_shader_nodes_poll),
|
||||
NodeItem("ShaderNodeVolumeScatter", poll=eevee_cycles_shader_nodes_poll),
|
||||
NodeItem("ShaderNodeVolumePrincipled"),
|
||||
NodeItem("ShaderNodeEeveeSpecular", poll=object_eevee_shader_nodes_poll),
|
||||
NodeItem("ShaderNodeBsdfHairPrincipled", poll=object_cycles_shader_nodes_poll),
|
||||
]),
|
||||
ShaderNodeCategory("SH_NEW_TEXTURE", "Texture", items=[
|
||||
NodeItem("ShaderNodeTexImage"),
|
||||
NodeItem("ShaderNodeTexEnvironment"),
|
||||
NodeItem("ShaderNodeTexSky"),
|
||||
NodeItem("ShaderNodeTexNoise"),
|
||||
NodeItem("ShaderNodeTexWave"),
|
||||
NodeItem("ShaderNodeTexVoronoi"),
|
||||
NodeItem("ShaderNodeTexMusgrave"),
|
||||
NodeItem("ShaderNodeTexGradient"),
|
||||
NodeItem("ShaderNodeTexMagic"),
|
||||
NodeItem("ShaderNodeTexChecker"),
|
||||
NodeItem("ShaderNodeTexBrick"),
|
||||
NodeItem("ShaderNodeTexPointDensity"),
|
||||
NodeItem("ShaderNodeTexIES"),
|
||||
NodeItem("ShaderNodeTexWhiteNoise"),
|
||||
]),
|
||||
ShaderNodeCategory("SH_NEW_OP_COLOR", "Color", items=[
|
||||
NodeItem("ShaderNodeMix", label="Mix Color", settings={"data_type": "'RGBA'"}),
|
||||
NodeItem("ShaderNodeRGBCurve"),
|
||||
NodeItem("ShaderNodeInvert"),
|
||||
NodeItem("ShaderNodeLightFalloff"),
|
||||
NodeItem("ShaderNodeHueSaturation"),
|
||||
NodeItem("ShaderNodeGamma"),
|
||||
NodeItem("ShaderNodeBrightContrast"),
|
||||
]),
|
||||
ShaderNodeCategory("SH_NEW_OP_VECTOR", "Vector", items=[
|
||||
NodeItem("ShaderNodeMapping"),
|
||||
NodeItem("ShaderNodeBump"),
|
||||
NodeItem("ShaderNodeDisplacement"),
|
||||
NodeItem("ShaderNodeVectorDisplacement"),
|
||||
NodeItem("ShaderNodeNormalMap"),
|
||||
NodeItem("ShaderNodeNormal"),
|
||||
NodeItem("ShaderNodeVectorCurve"),
|
||||
NodeItem("ShaderNodeVectorRotate"),
|
||||
NodeItem("ShaderNodeVectorTransform"),
|
||||
]),
|
||||
ShaderNodeCategory("SH_NEW_CONVERTOR", "Converter", items=[
|
||||
NodeItem("ShaderNodeMapRange"),
|
||||
NodeItem("ShaderNodeFloatCurve"),
|
||||
NodeItem("ShaderNodeClamp"),
|
||||
NodeItem("ShaderNodeMath"),
|
||||
NodeItem("ShaderNodeMix"),
|
||||
NodeItem("ShaderNodeValToRGB"),
|
||||
NodeItem("ShaderNodeRGBToBW"),
|
||||
NodeItem("ShaderNodeShaderToRGB", poll=object_eevee_shader_nodes_poll),
|
||||
NodeItem("ShaderNodeVectorMath"),
|
||||
NodeItem("ShaderNodeSeparateColor"),
|
||||
NodeItem("ShaderNodeCombineColor"),
|
||||
NodeItem("ShaderNodeSeparateXYZ"),
|
||||
NodeItem("ShaderNodeCombineXYZ"),
|
||||
NodeItem("ShaderNodeWavelength"),
|
||||
NodeItem("ShaderNodeBlackbody"),
|
||||
]),
|
||||
ShaderNodeCategory("SH_NEW_SCRIPT", "Script", items=[
|
||||
NodeItem("ShaderNodeScript"),
|
||||
]),
|
||||
ShaderNodeCategory("SH_NEW_GROUP", "Group", items=node_group_items),
|
||||
ShaderNodeCategory("SH_NEW_LAYOUT", "Layout", items=[
|
||||
NodeItem("NodeFrame"),
|
||||
NodeItem("NodeReroute"),
|
||||
]),
|
||||
]
|
||||
|
||||
compositor_node_categories = [
|
||||
# Compositor Nodes
|
||||
CompositorNodeCategory("CMP_INPUT", "Input", items=[
|
||||
NodeItem("CompositorNodeRLayers"),
|
||||
NodeItem("CompositorNodeImage"),
|
||||
NodeItem("CompositorNodeMovieClip"),
|
||||
NodeItem("CompositorNodeMask"),
|
||||
NodeItem("CompositorNodeRGB"),
|
||||
NodeItem("CompositorNodeValue"),
|
||||
NodeItem("CompositorNodeTexture"),
|
||||
NodeItem("CompositorNodeBokehImage"),
|
||||
NodeItem("CompositorNodeTime"),
|
||||
NodeItem("CompositorNodeSceneTime"),
|
||||
NodeItem("CompositorNodeTrackPos"),
|
||||
]),
|
||||
CompositorNodeCategory("CMP_OUTPUT", "Output", items=[
|
||||
NodeItem("CompositorNodeComposite"),
|
||||
NodeItem("CompositorNodeViewer"),
|
||||
NodeItem("CompositorNodeSplitViewer"),
|
||||
NodeItem("CompositorNodeOutputFile"),
|
||||
NodeItem("CompositorNodeLevels"),
|
||||
]),
|
||||
CompositorNodeCategory("CMP_OP_COLOR", "Color", items=[
|
||||
NodeItem("CompositorNodeMixRGB"),
|
||||
NodeItem("CompositorNodeAlphaOver"),
|
||||
NodeItem("CompositorNodeInvert"),
|
||||
NodeItem("CompositorNodeCurveRGB"),
|
||||
NodeItem("CompositorNodeHueSat"),
|
||||
NodeItem("CompositorNodeColorBalance"),
|
||||
NodeItem("CompositorNodeHueCorrect"),
|
||||
NodeItem("CompositorNodeBrightContrast"),
|
||||
NodeItem("CompositorNodeGamma"),
|
||||
NodeItem("CompositorNodeExposure"),
|
||||
NodeItem("CompositorNodeColorCorrection"),
|
||||
NodeItem("CompositorNodePosterize"),
|
||||
NodeItem("CompositorNodeTonemap"),
|
||||
NodeItem("CompositorNodeZcombine"),
|
||||
]),
|
||||
CompositorNodeCategory("CMP_CONVERTOR", "Converter", items=[
|
||||
NodeItem("CompositorNodeMath"),
|
||||
NodeItem("CompositorNodeValToRGB"),
|
||||
NodeItem("CompositorNodeSetAlpha"),
|
||||
NodeItem("CompositorNodePremulKey"),
|
||||
NodeItem("CompositorNodeIDMask"),
|
||||
NodeItem("CompositorNodeRGBToBW"),
|
||||
NodeItem("CompositorNodeSeparateColor"),
|
||||
NodeItem("CompositorNodeCombineColor"),
|
||||
NodeItem("CompositorNodeSeparateXYZ"),
|
||||
NodeItem("CompositorNodeCombineXYZ"),
|
||||
NodeItem("CompositorNodeSwitchView"),
|
||||
NodeItem("CompositorNodeConvertColorSpace"),
|
||||
]),
|
||||
CompositorNodeCategory("CMP_OP_FILTER", "Filter", items=[
|
||||
NodeItem("CompositorNodeBlur"),
|
||||
NodeItem("CompositorNodeBilateralblur"),
|
||||
NodeItem("CompositorNodeDilateErode"),
|
||||
NodeItem("CompositorNodeDespeckle"),
|
||||
NodeItem("CompositorNodeFilter"),
|
||||
NodeItem("CompositorNodeBokehBlur"),
|
||||
NodeItem("CompositorNodeVecBlur"),
|
||||
NodeItem("CompositorNodeDefocus"),
|
||||
NodeItem("CompositorNodeGlare"),
|
||||
NodeItem("CompositorNodeInpaint"),
|
||||
NodeItem("CompositorNodeDBlur"),
|
||||
NodeItem("CompositorNodePixelate"),
|
||||
NodeItem("CompositorNodeSunBeams"),
|
||||
NodeItem("CompositorNodeDenoise"),
|
||||
NodeItem("CompositorNodeAntiAliasing"),
|
||||
NodeItem("CompositorNodeKuwahara"),
|
||||
]),
|
||||
CompositorNodeCategory("CMP_OP_VECTOR", "Vector", items=[
|
||||
NodeItem("CompositorNodeNormal"),
|
||||
NodeItem("CompositorNodeMapValue"),
|
||||
NodeItem("CompositorNodeMapRange"),
|
||||
NodeItem("CompositorNodeNormalize"),
|
||||
NodeItem("CompositorNodeCurveVec"),
|
||||
]),
|
||||
CompositorNodeCategory("CMP_MATTE", "Matte", items=[
|
||||
NodeItem("CompositorNodeKeying"),
|
||||
NodeItem("CompositorNodeKeyingScreen"),
|
||||
NodeItem("CompositorNodeChannelMatte"),
|
||||
NodeItem("CompositorNodeColorSpill"),
|
||||
NodeItem("CompositorNodeBoxMask"),
|
||||
NodeItem("CompositorNodeEllipseMask"),
|
||||
NodeItem("CompositorNodeLumaMatte"),
|
||||
NodeItem("CompositorNodeDiffMatte"),
|
||||
NodeItem("CompositorNodeDistanceMatte"),
|
||||
NodeItem("CompositorNodeChromaMatte"),
|
||||
NodeItem("CompositorNodeColorMatte"),
|
||||
NodeItem("CompositorNodeDoubleEdgeMask"),
|
||||
NodeItem("CompositorNodeCryptomatte"),
|
||||
NodeItem("CompositorNodeCryptomatteV2"),
|
||||
]),
|
||||
CompositorNodeCategory("CMP_DISTORT", "Distort", items=[
|
||||
NodeItem("CompositorNodeScale"),
|
||||
NodeItem("CompositorNodeLensdist"),
|
||||
NodeItem("CompositorNodeMovieDistortion"),
|
||||
NodeItem("CompositorNodeTranslate"),
|
||||
NodeItem("CompositorNodeRotate"),
|
||||
NodeItem("CompositorNodeFlip"),
|
||||
NodeItem("CompositorNodeCrop"),
|
||||
NodeItem("CompositorNodeDisplace"),
|
||||
NodeItem("CompositorNodeMapUV"),
|
||||
NodeItem("CompositorNodeTransform"),
|
||||
NodeItem("CompositorNodeStabilize"),
|
||||
NodeItem("CompositorNodePlaneTrackDeform"),
|
||||
NodeItem("CompositorNodeCornerPin"),
|
||||
]),
|
||||
CompositorNodeCategory("CMP_GROUP", "Group", items=node_group_items),
|
||||
CompositorNodeCategory("CMP_LAYOUT", "Layout", items=[
|
||||
NodeItem("NodeFrame"),
|
||||
NodeItem("NodeReroute"),
|
||||
NodeItem("CompositorNodeSwitch"),
|
||||
]),
|
||||
]
|
||||
|
||||
texture_node_categories = [
|
||||
# Texture Nodes
|
||||
TextureNodeCategory("TEX_INPUT", "Input", items=[
|
||||
|
@ -444,14 +159,10 @@ texture_node_categories = [
|
|||
|
||||
|
||||
def register():
|
||||
nodeitems_utils.register_node_categories('SHADER', shader_node_categories)
|
||||
nodeitems_utils.register_node_categories('COMPOSITING', compositor_node_categories)
|
||||
nodeitems_utils.register_node_categories('TEXTURE', texture_node_categories)
|
||||
|
||||
|
||||
def unregister():
|
||||
nodeitems_utils.unregister_node_categories('SHADER')
|
||||
nodeitems_utils.unregister_node_categories('COMPOSITING')
|
||||
nodeitems_utils.unregister_node_categories('TEXTURE')
|
||||
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ def main(context, event):
|
|||
class ViewOperatorRayCast(bpy.types.Operator):
|
||||
"""Modal object selection with a ray cast"""
|
||||
bl_idname = "view3d.modal_operator_raycast"
|
||||
bl_label = "RayCast View Operator"
|
||||
bl_label = "Ray-cast View Operator"
|
||||
|
||||
def modal(self, context, event):
|
||||
if event.type in {'MIDDLEMOUSE', 'WHEELUPMOUSE', 'WHEELDOWNMOUSE'}:
|
||||
|
@ -100,7 +100,7 @@ def menu_func(self, context):
|
|||
self.layout.operator(ViewOperatorRayCast.bl_idname, text="Raycast View Modal Operator")
|
||||
|
||||
|
||||
# Register and add to the "view" menu (required to also use F3 search "Raycast View Modal Operator" for quick access).
|
||||
# Register and add to the "view" menu (required to also use F3 search "Ray-cast View Modal Operator" for quick access).
|
||||
def register():
|
||||
bpy.utils.register_class(ViewOperatorRayCast)
|
||||
bpy.types.VIEW3D_MT_view.append(menu_func)
|
||||
|
|
|
@ -42,7 +42,7 @@ def enum_previews_from_directory_items(self, context):
|
|||
print("Scanning directory: %s" % directory)
|
||||
|
||||
if directory and os.path.exists(directory):
|
||||
# Scan the directory for png files
|
||||
# Scan the directory for `*.png` files
|
||||
image_paths = []
|
||||
for fn in os.listdir(directory):
|
||||
if fn.lower().endswith(".png"):
|
||||
|
|
|
@ -18,7 +18,9 @@
|
|||
#include "BKE_preferences.h"
|
||||
|
||||
#include "BLI_fileops.h"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_path_util.h"
|
||||
#include "BLI_string.h"
|
||||
|
||||
#include "DNA_userdef_types.h"
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include "BLI_fileops.h" /* For PATH_MAX (at least on Windows). */
|
||||
#include "BLI_path_util.h"
|
||||
#include "BLI_string.h"
|
||||
|
||||
#include "BKE_appdir.h"
|
||||
#include "BKE_callbacks.h"
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "BLI_string.h"
|
||||
|
||||
#include "asset_library_service.hh"
|
||||
#include "asset_library_test_common.hh"
|
||||
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BLI_sub_frame.hh"
|
||||
|
||||
#include "BKE_bake_items.hh"
|
||||
#include "BKE_bake_items_paths.hh"
|
||||
#include "BKE_bake_items_serialize.hh"
|
||||
|
||||
struct NodesModifierData;
|
||||
struct Main;
|
||||
struct Object;
|
||||
struct Scene;
|
||||
|
||||
namespace blender::bke::bake {
|
||||
|
||||
enum class CacheStatus {
|
||||
/** The cache is up-to-date with the inputs. */
|
||||
Valid,
|
||||
/**
|
||||
* Nodes or input values have changed since the cache was created, i.e. the output would be
|
||||
* different if the simulation was run again.
|
||||
*/
|
||||
Invalid,
|
||||
/** The cache has been baked and will not be invalidated by changing inputs. */
|
||||
Baked,
|
||||
};
|
||||
|
||||
/**
|
||||
* Stores the state for a specific frame.
|
||||
*/
|
||||
struct FrameCache {
|
||||
SubFrame frame;
|
||||
BakeState state;
|
||||
/** Used when the baked data is loaded lazily. */
|
||||
std::optional<std::string> meta_path;
|
||||
};
|
||||
|
||||
/**
|
||||
* Stores the state after the previous simulation step. This is only used, when the frame-cache is
|
||||
* not used.
|
||||
*/
|
||||
struct PrevCache {
|
||||
BakeState state;
|
||||
SubFrame frame;
|
||||
};
|
||||
|
||||
/**
|
||||
* Stores the cached/baked data for simulation nodes in geometry nodes.
|
||||
*/
|
||||
struct NodeCache {
|
||||
CacheStatus cache_status = CacheStatus::Valid;
|
||||
|
||||
/** All cached frames. */
|
||||
Vector<std::unique_ptr<FrameCache>> frame_caches;
|
||||
/** Previous simulation state when only that is stored (instead of the state for every frame). */
|
||||
std::optional<PrevCache> prev_cache;
|
||||
|
||||
/** Where to load blobs from disk when loading the baked data lazily. */
|
||||
std::optional<std::string> blobs_dir;
|
||||
/** Used to avoid reading blobs multiple times for different frames. */
|
||||
std::unique_ptr<BlobSharing> blob_sharing;
|
||||
/** Used to avoid checking if a bake exists many times. */
|
||||
bool failed_finding_bake = false;
|
||||
|
||||
void reset();
|
||||
};
|
||||
|
||||
struct ModifierCache {
|
||||
mutable std::mutex mutex;
|
||||
Map<int, std::unique_ptr<NodeCache>> cache_by_id;
|
||||
};
|
||||
|
||||
/**
|
||||
* Reset all simulation caches in the scene, for use when some fundamental change made them
|
||||
* impossible to reuse.
|
||||
*/
|
||||
void scene_simulation_states_reset(Scene &scene);
|
||||
|
||||
std::optional<BakePath> get_node_bake_path(const Main &bmain,
|
||||
const Object &object,
|
||||
const NodesModifierData &nmd,
|
||||
int node_id);
|
||||
std::optional<std::string> get_modifier_bake_path(const Main &bmain,
|
||||
const Object &object,
|
||||
const NodesModifierData &nmd);
|
||||
|
||||
/**
|
||||
* Get the directory that contains all baked data for the given modifier by default.
|
||||
*/
|
||||
std::string get_default_modifier_bake_directory(const Main &bmain,
|
||||
const Object &object,
|
||||
const NodesModifierData &nmd);
|
||||
|
||||
} // namespace blender::bke::bake
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
#include "BKE_geometry_set.hh"
|
||||
|
||||
namespace blender::bke {
|
||||
namespace blender::bke::bake {
|
||||
|
||||
/**
|
||||
* A "bake item" contains the baked data of e.g. one node socket at one frame. Typically, multiple
|
||||
|
@ -103,4 +103,4 @@ class StringBakeItem : public BakeItem {
|
|||
}
|
||||
};
|
||||
|
||||
} // namespace blender::bke
|
||||
} // namespace blender::bke::bake
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include "BLI_sub_frame.hh"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
namespace blender::bke::bake_paths {
|
||||
namespace blender::bke::bake {
|
||||
|
||||
struct MetaFile {
|
||||
SubFrame frame;
|
||||
|
@ -25,10 +25,10 @@ struct BakePath {
|
|||
* Path to the directory that contains the binary data. Could be shared between multiple bakes
|
||||
* to reduce memory consumption.
|
||||
*/
|
||||
std::string bdata_dir;
|
||||
std::string blobs_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.
|
||||
* else. Typically, this contains the meta and blob directories.
|
||||
*/
|
||||
std::optional<std::string> bake_dir;
|
||||
|
||||
|
@ -40,4 +40,4 @@ 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
|
||||
} // namespace blender::bke::bake
|
||||
|
|
|
@ -9,48 +9,49 @@
|
|||
|
||||
#include "BKE_bake_items.hh"
|
||||
|
||||
namespace blender::bke {
|
||||
namespace blender::bke::bake {
|
||||
|
||||
/**
|
||||
* Reference to a slice of memory typically stored on disk.
|
||||
* A blob is a "binary large object".
|
||||
*/
|
||||
struct BDataSlice {
|
||||
struct BlobSlice {
|
||||
std::string name;
|
||||
IndexRange range;
|
||||
|
||||
std::shared_ptr<io::serialize::DictionaryValue> serialize() const;
|
||||
static std::optional<BDataSlice> deserialize(const io::serialize::DictionaryValue &io_slice);
|
||||
static std::optional<BlobSlice> deserialize(const io::serialize::DictionaryValue &io_slice);
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract base class for loading binary data.
|
||||
*/
|
||||
class BDataReader {
|
||||
class BlobReader {
|
||||
public:
|
||||
/**
|
||||
* Read the data from the given slice into the provided memory buffer.
|
||||
* \return True on success, otherwise false.
|
||||
*/
|
||||
[[nodiscard]] virtual bool read(const BDataSlice &slice, void *r_data) const = 0;
|
||||
[[nodiscard]] virtual bool read(const BlobSlice &slice, void *r_data) const = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Abstract base class for writing binary data.
|
||||
*/
|
||||
class BDataWriter {
|
||||
class BlobWriter {
|
||||
public:
|
||||
/**
|
||||
* Write the provided binary data.
|
||||
* \return Slice where the data has been written to.
|
||||
*/
|
||||
virtual BDataSlice write(const void *data, int64_t size) = 0;
|
||||
virtual BlobSlice write(const void *data, int64_t size) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Allows for simple data deduplication when writing or reading data by making use of implicit
|
||||
* sharing.
|
||||
*/
|
||||
class BDataSharing {
|
||||
class BlobSharing {
|
||||
private:
|
||||
struct StoredByRuntimeValue {
|
||||
/**
|
||||
|
@ -60,7 +61,7 @@ class BDataSharing {
|
|||
int64_t sharing_info_version;
|
||||
/**
|
||||
* Identifier of the stored data. This includes information for where the data is stored (a
|
||||
* #BDataSlice) and optionally information for how it is loaded (e.g. endian information).
|
||||
* #BlobSlice) and optionally information for how it is loaded (e.g. endian information).
|
||||
*/
|
||||
std::shared_ptr<io::serialize::DictionaryValue> io_data;
|
||||
};
|
||||
|
@ -83,7 +84,7 @@ class BDataSharing {
|
|||
mutable Map<std::string, ImplicitSharingInfoAndData> runtime_by_stored_;
|
||||
|
||||
public:
|
||||
~BDataSharing();
|
||||
~BlobSharing();
|
||||
|
||||
/**
|
||||
* Check if the data referenced by `sharing_info` has been written before. If yes, return the
|
||||
|
@ -105,44 +106,44 @@ class BDataSharing {
|
|||
};
|
||||
|
||||
/**
|
||||
* A specific #BDataReader that reads from disk.
|
||||
* A specific #BlobReader that reads from disk.
|
||||
*/
|
||||
class DiskBDataReader : public BDataReader {
|
||||
class DiskBlobReader : public BlobReader {
|
||||
private:
|
||||
const std::string bdata_dir_;
|
||||
const std::string blobs_dir_;
|
||||
mutable std::mutex mutex_;
|
||||
mutable Map<std::string, std::unique_ptr<fstream>> open_input_streams_;
|
||||
|
||||
public:
|
||||
DiskBDataReader(std::string bdata_dir);
|
||||
[[nodiscard]] bool read(const BDataSlice &slice, void *r_data) const override;
|
||||
DiskBlobReader(std::string blobs_dir);
|
||||
[[nodiscard]] bool read(const BlobSlice &slice, void *r_data) const override;
|
||||
};
|
||||
|
||||
/**
|
||||
* A specific #BDataWriter that writes to a file on disk.
|
||||
* A specific #BlobWriter that writes to a file on disk.
|
||||
*/
|
||||
class DiskBDataWriter : public BDataWriter {
|
||||
class DiskBlobWriter : public BlobWriter {
|
||||
private:
|
||||
/** Name of the file that data is written to. */
|
||||
std::string bdata_name_;
|
||||
std::string blob_name_;
|
||||
/** File handle. */
|
||||
std::ostream &bdata_file_;
|
||||
std::ostream &blob_file_;
|
||||
/** Current position in the file. */
|
||||
int64_t current_offset_;
|
||||
|
||||
public:
|
||||
DiskBDataWriter(std::string bdata_name, std::ostream &bdata_file, int64_t current_offset);
|
||||
DiskBlobWriter(std::string blob_name, std::ostream &blob_file, int64_t current_offset);
|
||||
|
||||
BDataSlice write(const void *data, int64_t size) override;
|
||||
BlobSlice write(const void *data, int64_t size) override;
|
||||
};
|
||||
|
||||
void serialize_bake(const BakeState &bake_state,
|
||||
BDataWriter &bdata_writer,
|
||||
BDataSharing &bdata_sharing,
|
||||
BlobWriter &blob_writer,
|
||||
BlobSharing &blob_sharing,
|
||||
std::ostream &r_stream);
|
||||
|
||||
std::optional<BakeState> deserialize_bake(std::istream &stream,
|
||||
const BDataReader &bdata_reader,
|
||||
const BDataSharing &bdata_sharing);
|
||||
const BlobReader &blob_reader,
|
||||
const BlobSharing &blob_sharing);
|
||||
|
||||
} // namespace blender::bke
|
||||
} // namespace blender::bke::bake
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#include "BKE_bake_items.hh"
|
||||
#include "BKE_geometry_fields.hh"
|
||||
|
||||
namespace blender::bke {
|
||||
namespace blender::bke::bake {
|
||||
|
||||
/**
|
||||
* Describes how bake items should be mapped to sockets.
|
||||
|
@ -67,4 +67,4 @@ void copy_bake_items_to_socket_values(
|
|||
make_attribute_field,
|
||||
Span<void *> r_socket_values);
|
||||
|
||||
} // namespace blender::bke
|
||||
} // namespace blender::bke::bake
|
||||
|
|
|
@ -29,7 +29,7 @@ extern "C" {
|
|||
|
||||
/* Blender file format version. */
|
||||
#define BLENDER_FILE_VERSION BLENDER_VERSION
|
||||
#define BLENDER_FILE_SUBVERSION 20
|
||||
#define BLENDER_FILE_SUBVERSION 22
|
||||
|
||||
/* Minimum Blender version that supports reading file written with the current
|
||||
* version. Older Blender versions will test this and cancel loading the file, showing a warning to
|
||||
|
@ -37,7 +37,7 @@ extern "C" {
|
|||
*
|
||||
* See https://wiki.blender.org/wiki/Process/Compatibility_Handling for details. */
|
||||
#define BLENDER_FILE_MIN_VERSION 306
|
||||
#define BLENDER_FILE_MIN_SUBVERSION 11
|
||||
#define BLENDER_FILE_MIN_SUBVERSION 12
|
||||
|
||||
/** User readable version string. */
|
||||
const char *BKE_blender_version_string(void);
|
||||
|
|
|
@ -1,84 +0,0 @@
|
|||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BKE_bake_items_paths.hh"
|
||||
#include "BKE_bake_items_serialize.hh"
|
||||
#include "BKE_geometry_set.hh"
|
||||
|
||||
#include "BLI_map.hh"
|
||||
#include "BLI_sub_frame.hh"
|
||||
|
||||
struct bNodeTree;
|
||||
struct ModifierData;
|
||||
struct NodesModifierData;
|
||||
struct Main;
|
||||
|
||||
namespace blender::bke::sim {
|
||||
|
||||
enum class CacheState {
|
||||
/** The cache is up-to-date with the inputs. */
|
||||
Valid,
|
||||
/**
|
||||
* Nodes or input values have changed since the cache was created, i.e. the output would be
|
||||
* different if the simulation was run again.
|
||||
*/
|
||||
Invalid,
|
||||
/** The cache has been baked and will not be invalidated by changing inputs. */
|
||||
Baked,
|
||||
};
|
||||
|
||||
struct SimulationZoneFrameCache {
|
||||
SubFrame frame;
|
||||
BakeState state;
|
||||
/** Used when the baked data is loaded lazily. */
|
||||
std::optional<std::string> meta_path;
|
||||
};
|
||||
|
||||
struct SimulationZonePrevState {
|
||||
BakeState state;
|
||||
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 {
|
||||
public:
|
||||
mutable std::mutex mutex;
|
||||
Map<int, std::unique_ptr<SimulationZoneCache>> cache_by_zone_id;
|
||||
};
|
||||
|
||||
/**
|
||||
* Reset all simulation caches in the scene, for use when some fundamental change made them
|
||||
* impossible to reuse.
|
||||
*/
|
||||
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);
|
||||
|
||||
/**
|
||||
* Get the directory that contains all baked simulation data for the given modifier.
|
||||
*/
|
||||
std::string get_default_modifier_bake_directory(const Main &bmain,
|
||||
const Object &object,
|
||||
const ModifierData &md);
|
||||
|
||||
} // namespace blender::bke::sim
|
|
@ -72,6 +72,7 @@ set(SRC
|
|||
intern/attribute_access.cc
|
||||
intern/attribute_math.cc
|
||||
intern/autoexec.cc
|
||||
intern/bake_geometry_nodes_modifier.cc
|
||||
intern/bake_items.cc
|
||||
intern/bake_items_paths.cc
|
||||
intern/bake_items_serialize.cc
|
||||
|
@ -270,7 +271,6 @@ set(SRC
|
|||
intern/screen.cc
|
||||
intern/shader_fx.cc
|
||||
intern/shrinkwrap.cc
|
||||
intern/simulation_state.cc
|
||||
intern/softbody.c
|
||||
intern/sound.cc
|
||||
intern/speaker.cc
|
||||
|
@ -332,6 +332,7 @@ set(SRC
|
|||
BKE_attribute.hh
|
||||
BKE_attribute_math.hh
|
||||
BKE_autoexec.h
|
||||
BKE_bake_geometry_nodes_modifier.hh
|
||||
BKE_bake_items.hh
|
||||
BKE_bake_items_paths.hh
|
||||
BKE_bake_items_serialize.hh
|
||||
|
@ -480,7 +481,6 @@ set(SRC
|
|||
BKE_sequencer_offscreen.h
|
||||
BKE_shader_fx.h
|
||||
BKE_shrinkwrap.h
|
||||
BKE_simulation_state.hh
|
||||
BKE_softbody.h
|
||||
BKE_sound.h
|
||||
BKE_speaker.h
|
||||
|
|
|
@ -1527,7 +1527,7 @@ static void object_get_datamask(const Depsgraph *depsgraph,
|
|||
r_mask->fmask |= CD_MASK_MTFACE;
|
||||
}
|
||||
|
||||
/* check if we need mcols due to vertex paint or weightpaint */
|
||||
/* Check if we need mcols due to vertex paint or weight-paint. */
|
||||
if (ob->mode & OB_MODE_VERTEX_PAINT) {
|
||||
r_mask->lmask |= CD_MASK_PROP_BYTE_COLOR;
|
||||
}
|
||||
|
|
|
@ -1665,12 +1665,13 @@ static bool nla_combine_get_inverted_lower_value(const int mix_mode,
|
|||
* up interpolation for the animator, requiring further cleanup on their part.
|
||||
*/
|
||||
if (IS_EQF(blended_value, 0.0f)) {
|
||||
/* For blending, nla_combine_value(), when strip_value==0:
|
||||
*
|
||||
* blended_value = lower_value * powf(strip_value / base_value, infl);
|
||||
* blended_value = lower_value * powf(0, infl);
|
||||
* blended_value = lower_value * 0;
|
||||
* blended_value = 0;
|
||||
/* For blending, nla_combine_value(), when `strip_value == 0`:
|
||||
* \code{.cc}
|
||||
* blended_value = lower_value * powf(strip_value / base_value, infl);
|
||||
* blended_value = lower_value * powf(0, infl);
|
||||
* blended_value = lower_value * 0;
|
||||
* blended_value = 0;
|
||||
* \endcode
|
||||
*
|
||||
* Effectively, blended_value will equal 0 no matter what lower_value is. Put another
|
||||
* way, when (blended_value==0 and strip_value==0), then lower_value can be any value and
|
||||
|
|
|
@ -54,10 +54,11 @@ static CLG_LogRef LOG = {"bke.armature_deform"};
|
|||
static void pchan_deform_accumulate(const DualQuat *deform_dq,
|
||||
const float deform_mat[4][4],
|
||||
const float co_in[3],
|
||||
float weight,
|
||||
const float weight,
|
||||
float co_accum[3],
|
||||
DualQuat *dq_accum,
|
||||
float mat_accum[3][3])
|
||||
float mat_accum[3][3],
|
||||
const bool full_deform)
|
||||
{
|
||||
if (weight == 0.0f) {
|
||||
return;
|
||||
|
@ -66,22 +67,7 @@ static void pchan_deform_accumulate(const DualQuat *deform_dq,
|
|||
if (dq_accum) {
|
||||
BLI_assert(!co_accum);
|
||||
|
||||
if (deform_dq->scale_weight) {
|
||||
/* FIX #32022. */
|
||||
DualQuat mdq = *deform_dq;
|
||||
float dst[3];
|
||||
mul_v3_m4v3(dst, mdq.scale, co_in);
|
||||
sub_v3_v3(dst, co_in);
|
||||
mdq.trans[0] -= .5f * (mdq.quat[1] * dst[0] + mdq.quat[2] * dst[1] + mdq.quat[3] * dst[2]);
|
||||
mdq.trans[1] += .5f * (mdq.quat[0] * dst[0] + mdq.quat[2] * dst[2] - mdq.quat[3] * dst[1]);
|
||||
mdq.trans[2] += .5f * (mdq.quat[0] * dst[1] + mdq.quat[3] * dst[0] - mdq.quat[1] * dst[2]);
|
||||
mdq.trans[3] += .5f * (mdq.quat[0] * dst[2] + mdq.quat[1] * dst[1] - mdq.quat[2] * dst[0]);
|
||||
mdq.scale_weight = 0.0f;
|
||||
add_weighted_dq_dq(dq_accum, &mdq, weight);
|
||||
}
|
||||
else {
|
||||
add_weighted_dq_dq(dq_accum, deform_dq, weight);
|
||||
}
|
||||
add_weighted_dq_dq_pivot(dq_accum, deform_dq, co_in, weight, full_deform);
|
||||
}
|
||||
else {
|
||||
float tmp[3];
|
||||
|
@ -90,7 +76,7 @@ static void pchan_deform_accumulate(const DualQuat *deform_dq,
|
|||
sub_v3_v3(tmp, co_in);
|
||||
madd_v3_v3fl(co_accum, tmp, weight);
|
||||
|
||||
if (mat_accum) {
|
||||
if (full_deform) {
|
||||
float tmpmat[3][3];
|
||||
copy_m3_m4(tmpmat, deform_mat);
|
||||
|
||||
|
@ -101,10 +87,11 @@ static void pchan_deform_accumulate(const DualQuat *deform_dq,
|
|||
|
||||
static void b_bone_deform(const bPoseChannel *pchan,
|
||||
const float co[3],
|
||||
float weight,
|
||||
const float weight,
|
||||
float vec[3],
|
||||
DualQuat *dq,
|
||||
float defmat[3][3])
|
||||
float defmat[3][3],
|
||||
const bool full_deform)
|
||||
{
|
||||
const DualQuat *quats = pchan->runtime.bbone_dual_quats;
|
||||
const Mat4 *mats = pchan->runtime.bbone_deform_mats;
|
||||
|
@ -114,10 +101,16 @@ static void b_bone_deform(const bPoseChannel *pchan,
|
|||
/* Calculate the indices of the 2 affecting b_bone segments. */
|
||||
BKE_pchan_bbone_deform_segment_index(pchan, co, &index, &blend);
|
||||
|
||||
pchan_deform_accumulate(&quats[index],
|
||||
mats[index + 1].mat,
|
||||
co,
|
||||
weight * (1.0f - blend),
|
||||
vec,
|
||||
dq,
|
||||
defmat,
|
||||
full_deform);
|
||||
pchan_deform_accumulate(
|
||||
&quats[index], mats[index + 1].mat, co, weight * (1.0f - blend), vec, dq, defmat);
|
||||
pchan_deform_accumulate(
|
||||
&quats[index + 1], mats[index + 2].mat, co, weight * blend, vec, dq, defmat);
|
||||
&quats[index + 1], mats[index + 2].mat, co, weight * blend, vec, dq, defmat, full_deform);
|
||||
}
|
||||
|
||||
float distfactor_to_bone(
|
||||
|
@ -173,8 +166,12 @@ float distfactor_to_bone(
|
|||
return 1.0f - (a * a) / (rdist * rdist);
|
||||
}
|
||||
|
||||
static float dist_bone_deform(
|
||||
const bPoseChannel *pchan, float vec[3], DualQuat *dq, float mat[3][3], const float co[3])
|
||||
static float dist_bone_deform(const bPoseChannel *pchan,
|
||||
float vec[3],
|
||||
DualQuat *dq,
|
||||
float mat[3][3],
|
||||
const float co[3],
|
||||
const bool full_deform)
|
||||
{
|
||||
const Bone *bone = pchan->bone;
|
||||
float fac, contrib = 0.0;
|
||||
|
@ -191,11 +188,11 @@ static float dist_bone_deform(
|
|||
contrib = fac;
|
||||
if (contrib > 0.0f) {
|
||||
if (bone->segments > 1 && pchan->runtime.bbone_segments == bone->segments) {
|
||||
b_bone_deform(pchan, co, fac, vec, dq, mat);
|
||||
b_bone_deform(pchan, co, fac, vec, dq, mat, full_deform);
|
||||
}
|
||||
else {
|
||||
pchan_deform_accumulate(
|
||||
&pchan->runtime.deform_dual_quat, pchan->chan_mat, co, fac, vec, dq, mat);
|
||||
&pchan->runtime.deform_dual_quat, pchan->chan_mat, co, fac, vec, dq, mat, full_deform);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -204,11 +201,12 @@ static float dist_bone_deform(
|
|||
}
|
||||
|
||||
static void pchan_bone_deform(const bPoseChannel *pchan,
|
||||
float weight,
|
||||
const float weight,
|
||||
float vec[3],
|
||||
DualQuat *dq,
|
||||
float mat[3][3],
|
||||
const float co[3],
|
||||
const bool full_deform,
|
||||
float *contrib)
|
||||
{
|
||||
const Bone *bone = pchan->bone;
|
||||
|
@ -218,11 +216,11 @@ static void pchan_bone_deform(const bPoseChannel *pchan,
|
|||
}
|
||||
|
||||
if (bone->segments > 1 && pchan->runtime.bbone_segments == bone->segments) {
|
||||
b_bone_deform(pchan, co, weight, vec, dq, mat);
|
||||
b_bone_deform(pchan, co, weight, vec, dq, mat, full_deform);
|
||||
}
|
||||
else {
|
||||
pchan_deform_accumulate(
|
||||
&pchan->runtime.deform_dual_quat, pchan->chan_mat, co, weight, vec, dq, mat);
|
||||
&pchan->runtime.deform_dual_quat, pchan->chan_mat, co, weight, vec, dq, mat, full_deform);
|
||||
}
|
||||
|
||||
(*contrib) += weight;
|
||||
|
@ -286,6 +284,8 @@ static void armature_vert_task_with_dvert(const ArmatureUserdata *data,
|
|||
float armature_weight = 1.0f; /* default to 1 if no overall def group */
|
||||
float prevco_weight = 0.0f; /* weight for optional cached vertexcos */
|
||||
|
||||
const bool full_deform = vert_deform_mats != nullptr;
|
||||
|
||||
if (use_quaternion) {
|
||||
memset(&sumdq, 0, sizeof(DualQuat));
|
||||
dq = &sumdq;
|
||||
|
@ -294,7 +294,7 @@ static void armature_vert_task_with_dvert(const ArmatureUserdata *data,
|
|||
zero_v3(sumvec);
|
||||
vec = sumvec;
|
||||
|
||||
if (vert_deform_mats) {
|
||||
if (full_deform) {
|
||||
zero_m3(summat);
|
||||
smat = summat;
|
||||
}
|
||||
|
@ -354,7 +354,7 @@ static void armature_vert_task_with_dvert(const ArmatureUserdata *data,
|
|||
co, bone->arm_head, bone->arm_tail, bone->rad_head, bone->rad_tail, bone->dist);
|
||||
}
|
||||
|
||||
pchan_bone_deform(pchan, weight, vec, dq, smat, co, &contrib);
|
||||
pchan_bone_deform(pchan, weight, vec, dq, smat, co, full_deform, &contrib);
|
||||
}
|
||||
}
|
||||
/* If there are vertex-groups but not groups with bones (like for soft-body groups). */
|
||||
|
@ -363,7 +363,7 @@ static void armature_vert_task_with_dvert(const ArmatureUserdata *data,
|
|||
pchan = pchan->next)
|
||||
{
|
||||
if (!(pchan->bone->flag & BONE_NO_DEFORM)) {
|
||||
contrib += dist_bone_deform(pchan, vec, dq, smat, co);
|
||||
contrib += dist_bone_deform(pchan, vec, dq, smat, co, full_deform);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -373,7 +373,7 @@ static void armature_vert_task_with_dvert(const ArmatureUserdata *data,
|
|||
pchan = pchan->next)
|
||||
{
|
||||
if (!(pchan->bone->flag & BONE_NO_DEFORM)) {
|
||||
contrib += dist_bone_deform(pchan, vec, dq, smat, co);
|
||||
contrib += dist_bone_deform(pchan, vec, dq, smat, co, full_deform);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -385,13 +385,13 @@ static void armature_vert_task_with_dvert(const ArmatureUserdata *data,
|
|||
|
||||
if (armature_weight != 1.0f) {
|
||||
copy_v3_v3(dco, co);
|
||||
mul_v3m3_dq(dco, (vert_deform_mats) ? summat : nullptr, dq);
|
||||
mul_v3m3_dq(dco, full_deform ? summat : nullptr, dq);
|
||||
sub_v3_v3(dco, co);
|
||||
mul_v3_fl(dco, armature_weight);
|
||||
add_v3_v3(co, dco);
|
||||
}
|
||||
else {
|
||||
mul_v3m3_dq(co, (vert_deform_mats) ? summat : nullptr, dq);
|
||||
mul_v3m3_dq(co, full_deform ? summat : nullptr, dq);
|
||||
}
|
||||
|
||||
smat = summat;
|
||||
|
@ -401,7 +401,7 @@ static void armature_vert_task_with_dvert(const ArmatureUserdata *data,
|
|||
add_v3_v3v3(co, vec, co);
|
||||
}
|
||||
|
||||
if (vert_deform_mats) {
|
||||
if (full_deform) {
|
||||
float pre[3][3], post[3][3], tmpmat[3][3];
|
||||
|
||||
copy_m3_m4(pre, data->premat);
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "BLI_math_matrix.h"
|
||||
#include "BLI_math_rotation.h"
|
||||
#include "BLI_math_vector.h"
|
||||
#include "BLI_string.h"
|
||||
|
||||
#include "DNA_armature_types.h"
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
|
||||
#include <memory>
|
||||
|
||||
#include "BLI_string.h"
|
||||
|
||||
#include "AS_asset_identifier.hh"
|
||||
#include "AS_asset_library.hh"
|
||||
|
||||
|
|
|
@ -4,10 +4,10 @@
|
|||
|
||||
#include <sstream>
|
||||
|
||||
#include "BKE_bake_geometry_nodes_modifier.hh"
|
||||
#include "BKE_collection.h"
|
||||
#include "BKE_curves.hh"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_simulation_state.hh"
|
||||
|
||||
#include "DNA_modifier_types.h"
|
||||
#include "DNA_node_types.h"
|
||||
|
@ -17,22 +17,18 @@
|
|||
#include "BLI_fileops.hh"
|
||||
#include "BLI_hash_md5.h"
|
||||
#include "BLI_path_util.h"
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_string_utils.h"
|
||||
|
||||
#include "MOD_nodes.hh"
|
||||
|
||||
namespace blender::bke::sim {
|
||||
namespace blender::bke::bake {
|
||||
|
||||
void SimulationZoneCache::reset()
|
||||
void NodeCache::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;
|
||||
std::destroy_at(this);
|
||||
new (this) NodeCache();
|
||||
}
|
||||
|
||||
void scene_simulation_states_reset(Scene &scene)
|
||||
{
|
||||
FOREACH_SCENE_OBJECT_BEGIN (&scene, ob) {
|
||||
|
@ -41,10 +37,10 @@ void scene_simulation_states_reset(Scene &scene)
|
|||
continue;
|
||||
}
|
||||
NodesModifierData *nmd = reinterpret_cast<NodesModifierData *>(md);
|
||||
if (!nmd->runtime->simulation_cache) {
|
||||
if (!nmd->runtime->cache) {
|
||||
continue;
|
||||
}
|
||||
for (auto item : nmd->runtime->simulation_cache->cache_by_zone_id.items()) {
|
||||
for (auto item : nmd->runtime->cache->cache_by_id.items()) {
|
||||
item.value->reset();
|
||||
}
|
||||
}
|
||||
|
@ -52,9 +48,9 @@ void scene_simulation_states_reset(Scene &scene)
|
|||
FOREACH_SCENE_OBJECT_END;
|
||||
}
|
||||
|
||||
std::optional<std::string> get_modifier_simulation_bake_path(const Main &bmain,
|
||||
const Object &object,
|
||||
const NodesModifierData &nmd)
|
||||
std::optional<std::string> get_modifier_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()) {
|
||||
|
@ -70,13 +66,12 @@ std::optional<std::string> get_modifier_simulation_bake_path(const Main &bmain,
|
|||
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)
|
||||
std::optional<bake::BakePath> get_node_bake_path(const Main &bmain,
|
||||
const Object &object,
|
||||
const NodesModifierData &nmd,
|
||||
int node_id)
|
||||
{
|
||||
const std::optional<std::string> modifier_bake_path = get_modifier_simulation_bake_path(
|
||||
bmain, object, nmd);
|
||||
const std::optional<std::string> modifier_bake_path = get_modifier_bake_path(bmain, object, nmd);
|
||||
if (!modifier_bake_path) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
@ -85,8 +80,8 @@ std::optional<bake_paths::BakePath> get_simulation_zone_bake_path(const Main &bm
|
|||
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);
|
||||
std::to_string(node_id).c_str());
|
||||
return bake::BakePath::from_single_root(zone_bake_dir);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -122,16 +117,16 @@ static std::string get_blend_file_name(const Main &bmain)
|
|||
return "blendcache_" + StringRef(blend_name);
|
||||
}
|
||||
|
||||
static std::string get_modifier_sim_name(const Object &object, const ModifierData &md)
|
||||
static std::string get_modifier_directory_name(const Object &object, const ModifierData &md)
|
||||
{
|
||||
const std::string object_name_escaped = escape_name(object.id.name + 2);
|
||||
const std::string modifier_name_escaped = escape_name(md.name);
|
||||
return "sim_" + object_name_escaped + "_" + modifier_name_escaped;
|
||||
return object_name_escaped + "_" + modifier_name_escaped;
|
||||
}
|
||||
|
||||
std::string get_default_modifier_bake_directory(const Main &bmain,
|
||||
const Object &object,
|
||||
const ModifierData &md)
|
||||
const NodesModifierData &nmd)
|
||||
{
|
||||
char dir[FILE_MAX];
|
||||
/* Make path that's relative to the .blend file. */
|
||||
|
@ -139,8 +134,8 @@ std::string get_default_modifier_bake_directory(const Main &bmain,
|
|||
sizeof(dir),
|
||||
"//",
|
||||
get_blend_file_name(bmain).c_str(),
|
||||
get_modifier_sim_name(object, md).c_str());
|
||||
get_modifier_directory_name(object, nmd.modifier).c_str());
|
||||
return dir;
|
||||
}
|
||||
|
||||
} // namespace blender::bke::sim
|
||||
} // namespace blender::bke::bake
|
|
@ -20,7 +20,7 @@
|
|||
#include "RNA_access.hh"
|
||||
#include "RNA_enum_types.hh"
|
||||
|
||||
namespace blender::bke {
|
||||
namespace blender::bke::bake {
|
||||
|
||||
using namespace io::serialize;
|
||||
using DictionaryValuePtr = std::shared_ptr<DictionaryValue>;
|
||||
|
@ -81,4 +81,4 @@ BakeStateRef::BakeStateRef(const BakeState &bake_state)
|
|||
}
|
||||
}
|
||||
|
||||
} // namespace blender::bke
|
||||
} // namespace blender::bke::bake
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include "BLI_string.h"
|
||||
#include "BLI_string_utils.h"
|
||||
|
||||
namespace blender::bke::bake_paths {
|
||||
namespace blender::bke::bake {
|
||||
|
||||
std::string frame_to_file_name(const SubFrame &frame)
|
||||
{
|
||||
|
@ -63,14 +63,14 @@ 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");
|
||||
char blobs_dir[FILE_MAX];
|
||||
BLI_path_join(blobs_dir, sizeof(blobs_dir), root_dir.c_str(), "blobs");
|
||||
|
||||
BakePath bake_path;
|
||||
bake_path.meta_dir = meta_dir;
|
||||
bake_path.bdata_dir = bdata_dir;
|
||||
bake_path.blobs_dir = blobs_dir;
|
||||
bake_path.bake_dir = root_dir;
|
||||
return bake_path;
|
||||
}
|
||||
|
||||
} // namespace blender::bke::bake_paths
|
||||
} // namespace blender::bke::bake
|
||||
|
|
|
@ -22,12 +22,12 @@
|
|||
|
||||
#include <sstream>
|
||||
|
||||
namespace blender::bke {
|
||||
namespace blender::bke::bake {
|
||||
|
||||
using namespace io::serialize;
|
||||
using DictionaryValuePtr = std::shared_ptr<DictionaryValue>;
|
||||
|
||||
std::shared_ptr<DictionaryValue> BDataSlice::serialize() const
|
||||
std::shared_ptr<DictionaryValue> BlobSlice::serialize() const
|
||||
{
|
||||
auto io_slice = std::make_shared<DictionaryValue>();
|
||||
io_slice->append_str("name", this->name);
|
||||
|
@ -36,7 +36,7 @@ std::shared_ptr<DictionaryValue> BDataSlice::serialize() const
|
|||
return io_slice;
|
||||
}
|
||||
|
||||
std::optional<BDataSlice> BDataSlice::deserialize(const DictionaryValue &io_slice)
|
||||
std::optional<BlobSlice> BlobSlice::deserialize(const DictionaryValue &io_slice)
|
||||
{
|
||||
const std::optional<StringRefNull> name = io_slice.lookup_str("name");
|
||||
const std::optional<int64_t> start = io_slice.lookup_int("start");
|
||||
|
@ -45,48 +45,48 @@ std::optional<BDataSlice> BDataSlice::deserialize(const DictionaryValue &io_slic
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
return BDataSlice{*name, {*start, *size}};
|
||||
return BlobSlice{*name, {*start, *size}};
|
||||
}
|
||||
|
||||
DiskBDataReader::DiskBDataReader(std::string bdata_dir) : bdata_dir_(std::move(bdata_dir)) {}
|
||||
DiskBlobReader::DiskBlobReader(std::string blobs_dir) : blobs_dir_(std::move(blobs_dir)) {}
|
||||
|
||||
[[nodiscard]] bool DiskBDataReader::read(const BDataSlice &slice, void *r_data) const
|
||||
[[nodiscard]] bool DiskBlobReader::read(const BlobSlice &slice, void *r_data) const
|
||||
{
|
||||
if (slice.range.is_empty()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
char bdata_path[FILE_MAX];
|
||||
BLI_path_join(bdata_path, sizeof(bdata_path), bdata_dir_.c_str(), slice.name.c_str());
|
||||
char blob_path[FILE_MAX];
|
||||
BLI_path_join(blob_path, sizeof(blob_path), blobs_dir_.c_str(), slice.name.c_str());
|
||||
|
||||
std::lock_guard lock{mutex_};
|
||||
std::unique_ptr<fstream> &bdata_file = open_input_streams_.lookup_or_add_cb_as(
|
||||
bdata_path,
|
||||
[&]() { return std::make_unique<fstream>(bdata_path, std::ios::in | std::ios::binary); });
|
||||
bdata_file->seekg(slice.range.start());
|
||||
bdata_file->read(static_cast<char *>(r_data), slice.range.size());
|
||||
if (bdata_file->gcount() != slice.range.size()) {
|
||||
std::unique_ptr<fstream> &blob_file = open_input_streams_.lookup_or_add_cb_as(blob_path, [&]() {
|
||||
return std::make_unique<fstream>(blob_path, std::ios::in | std::ios::binary);
|
||||
});
|
||||
blob_file->seekg(slice.range.start());
|
||||
blob_file->read(static_cast<char *>(r_data), slice.range.size());
|
||||
if (blob_file->gcount() != slice.range.size()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
DiskBDataWriter::DiskBDataWriter(std::string bdata_name,
|
||||
std::ostream &bdata_file,
|
||||
const int64_t current_offset)
|
||||
: bdata_name_(std::move(bdata_name)), bdata_file_(bdata_file), current_offset_(current_offset)
|
||||
DiskBlobWriter::DiskBlobWriter(std::string blob_name,
|
||||
std::ostream &blob_file,
|
||||
const int64_t current_offset)
|
||||
: blob_name_(std::move(blob_name)), blob_file_(blob_file), current_offset_(current_offset)
|
||||
{
|
||||
}
|
||||
|
||||
BDataSlice DiskBDataWriter::write(const void *data, const int64_t size)
|
||||
BlobSlice DiskBlobWriter::write(const void *data, const int64_t size)
|
||||
{
|
||||
const int64_t old_offset = current_offset_;
|
||||
bdata_file_.write(static_cast<const char *>(data), size);
|
||||
blob_file_.write(static_cast<const char *>(data), size);
|
||||
current_offset_ += size;
|
||||
return {bdata_name_, {old_offset, size}};
|
||||
return {blob_name_, {old_offset, size}};
|
||||
}
|
||||
|
||||
BDataSharing::~BDataSharing()
|
||||
BlobSharing::~BlobSharing()
|
||||
{
|
||||
for (const ImplicitSharingInfo *sharing_info : stored_by_runtime_.keys()) {
|
||||
sharing_info->remove_weak_user_and_delete_if_last();
|
||||
|
@ -98,8 +98,8 @@ BDataSharing::~BDataSharing()
|
|||
}
|
||||
}
|
||||
|
||||
DictionaryValuePtr BDataSharing::write_shared(const ImplicitSharingInfo *sharing_info,
|
||||
FunctionRef<DictionaryValuePtr()> write_fn)
|
||||
DictionaryValuePtr BlobSharing::write_shared(const ImplicitSharingInfo *sharing_info,
|
||||
FunctionRef<DictionaryValuePtr()> write_fn)
|
||||
{
|
||||
if (sharing_info == nullptr) {
|
||||
return write_fn();
|
||||
|
@ -126,7 +126,7 @@ DictionaryValuePtr BDataSharing::write_shared(const ImplicitSharingInfo *sharing
|
|||
});
|
||||
}
|
||||
|
||||
std::optional<ImplicitSharingInfoAndData> BDataSharing::read_shared(
|
||||
std::optional<ImplicitSharingInfoAndData> BlobSharing::read_shared(
|
||||
const DictionaryValue &io_data,
|
||||
FunctionRef<std::optional<ImplicitSharingInfoAndData>()> read_fn) const
|
||||
{
|
||||
|
@ -196,10 +196,10 @@ static std::optional<eCustomDataType> get_data_type_from_io_name(const StringRef
|
|||
/**
|
||||
* Write the data and remember which endianness the data had.
|
||||
*/
|
||||
static std::shared_ptr<DictionaryValue> write_bdata_raw_data_with_endian(
|
||||
BDataWriter &bdata_writer, const void *data, const int64_t size_in_bytes)
|
||||
static std::shared_ptr<DictionaryValue> write_blob_raw_data_with_endian(
|
||||
BlobWriter &blob_writer, const void *data, const int64_t size_in_bytes)
|
||||
{
|
||||
auto io_data = bdata_writer.write(data, size_in_bytes).serialize();
|
||||
auto io_data = blob_writer.write(data, size_in_bytes).serialize();
|
||||
if (ENDIAN_ORDER == B_ENDIAN) {
|
||||
io_data->append_str("endian", get_endian_io_name(ENDIAN_ORDER));
|
||||
}
|
||||
|
@ -209,20 +209,20 @@ static std::shared_ptr<DictionaryValue> write_bdata_raw_data_with_endian(
|
|||
/**
|
||||
* Read data of an into an array and optionally perform an endian switch if necessary.
|
||||
*/
|
||||
[[nodiscard]] static bool read_bdata_raw_data_with_endian(const BDataReader &bdata_reader,
|
||||
const DictionaryValue &io_data,
|
||||
const int64_t element_size,
|
||||
const int64_t elements_num,
|
||||
void *r_data)
|
||||
[[nodiscard]] static bool read_blob_raw_data_with_endian(const BlobReader &blob_reader,
|
||||
const DictionaryValue &io_data,
|
||||
const int64_t element_size,
|
||||
const int64_t elements_num,
|
||||
void *r_data)
|
||||
{
|
||||
const std::optional<BDataSlice> slice = BDataSlice::deserialize(io_data);
|
||||
const std::optional<BlobSlice> slice = BlobSlice::deserialize(io_data);
|
||||
if (!slice) {
|
||||
return false;
|
||||
}
|
||||
if (slice->range.size() != element_size * elements_num) {
|
||||
return false;
|
||||
}
|
||||
if (!bdata_reader.read(*slice, r_data)) {
|
||||
if (!blob_reader.read(*slice, r_data)) {
|
||||
return false;
|
||||
}
|
||||
const StringRefNull stored_endian = io_data.lookup_str("endian").value_or("little");
|
||||
|
@ -249,95 +249,95 @@ static std::shared_ptr<DictionaryValue> write_bdata_raw_data_with_endian(
|
|||
}
|
||||
|
||||
/** Write bytes ignoring endianness. */
|
||||
static std::shared_ptr<DictionaryValue> write_bdata_raw_bytes(BDataWriter &bdata_writer,
|
||||
const void *data,
|
||||
const int64_t size_in_bytes)
|
||||
static std::shared_ptr<DictionaryValue> write_blob_raw_bytes(BlobWriter &blob_writer,
|
||||
const void *data,
|
||||
const int64_t size_in_bytes)
|
||||
{
|
||||
return bdata_writer.write(data, size_in_bytes).serialize();
|
||||
return blob_writer.write(data, size_in_bytes).serialize();
|
||||
}
|
||||
|
||||
/** Read bytes ignoring endianness. */
|
||||
[[nodiscard]] static bool read_bdata_raw_bytes(const BDataReader &bdata_reader,
|
||||
const DictionaryValue &io_data,
|
||||
const int64_t bytes_num,
|
||||
void *r_data)
|
||||
[[nodiscard]] static bool read_blob_raw_bytes(const BlobReader &blob_reader,
|
||||
const DictionaryValue &io_data,
|
||||
const int64_t bytes_num,
|
||||
void *r_data)
|
||||
{
|
||||
const std::optional<BDataSlice> slice = BDataSlice::deserialize(io_data);
|
||||
const std::optional<BlobSlice> slice = BlobSlice::deserialize(io_data);
|
||||
if (!slice) {
|
||||
return false;
|
||||
}
|
||||
if (slice->range.size() != bytes_num) {
|
||||
return false;
|
||||
}
|
||||
return bdata_reader.read(*slice, r_data);
|
||||
return blob_reader.read(*slice, r_data);
|
||||
}
|
||||
|
||||
static std::shared_ptr<DictionaryValue> write_bdata_simple_gspan(BDataWriter &bdata_writer,
|
||||
const GSpan data)
|
||||
static std::shared_ptr<DictionaryValue> write_blob_simple_gspan(BlobWriter &blob_writer,
|
||||
const GSpan data)
|
||||
{
|
||||
const CPPType &type = data.type();
|
||||
BLI_assert(type.is_trivial());
|
||||
if (type.size() == 1 || type.is<ColorGeometry4b>()) {
|
||||
return write_bdata_raw_bytes(bdata_writer, data.data(), data.size_in_bytes());
|
||||
return write_blob_raw_bytes(blob_writer, data.data(), data.size_in_bytes());
|
||||
}
|
||||
return write_bdata_raw_data_with_endian(bdata_writer, data.data(), data.size_in_bytes());
|
||||
return write_blob_raw_data_with_endian(blob_writer, data.data(), data.size_in_bytes());
|
||||
}
|
||||
|
||||
[[nodiscard]] static bool read_bdata_simple_gspan(const BDataReader &bdata_reader,
|
||||
const DictionaryValue &io_data,
|
||||
GMutableSpan r_data)
|
||||
[[nodiscard]] static bool read_blob_simple_gspan(const BlobReader &blob_reader,
|
||||
const DictionaryValue &io_data,
|
||||
GMutableSpan r_data)
|
||||
{
|
||||
const CPPType &type = r_data.type();
|
||||
BLI_assert(type.is_trivial());
|
||||
if (type.size() == 1 || type.is<ColorGeometry4b>()) {
|
||||
return read_bdata_raw_bytes(bdata_reader, io_data, r_data.size_in_bytes(), r_data.data());
|
||||
return read_blob_raw_bytes(blob_reader, io_data, r_data.size_in_bytes(), r_data.data());
|
||||
}
|
||||
if (type.is_any<int16_t, uint16_t, int32_t, uint32_t, int64_t, uint64_t, float>()) {
|
||||
return read_bdata_raw_data_with_endian(
|
||||
bdata_reader, io_data, type.size(), r_data.size(), r_data.data());
|
||||
return read_blob_raw_data_with_endian(
|
||||
blob_reader, io_data, type.size(), r_data.size(), r_data.data());
|
||||
}
|
||||
if (type.is_any<float2, int2>()) {
|
||||
return read_bdata_raw_data_with_endian(
|
||||
bdata_reader, io_data, sizeof(int32_t), r_data.size() * 2, r_data.data());
|
||||
return read_blob_raw_data_with_endian(
|
||||
blob_reader, io_data, sizeof(int32_t), r_data.size() * 2, r_data.data());
|
||||
}
|
||||
if (type.is<float3>()) {
|
||||
return read_bdata_raw_data_with_endian(
|
||||
bdata_reader, io_data, sizeof(float), r_data.size() * 3, r_data.data());
|
||||
return read_blob_raw_data_with_endian(
|
||||
blob_reader, io_data, sizeof(float), r_data.size() * 3, r_data.data());
|
||||
}
|
||||
if (type.is<float4x4>()) {
|
||||
return read_bdata_raw_data_with_endian(
|
||||
bdata_reader, io_data, sizeof(float), r_data.size() * 16, r_data.data());
|
||||
return read_blob_raw_data_with_endian(
|
||||
blob_reader, io_data, sizeof(float), r_data.size() * 16, r_data.data());
|
||||
}
|
||||
if (type.is<ColorGeometry4f>()) {
|
||||
return read_bdata_raw_data_with_endian(
|
||||
bdata_reader, io_data, sizeof(float), r_data.size() * 4, r_data.data());
|
||||
return read_blob_raw_data_with_endian(
|
||||
blob_reader, io_data, sizeof(float), r_data.size() * 4, r_data.data());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static std::shared_ptr<DictionaryValue> write_bdata_shared_simple_gspan(
|
||||
BDataWriter &bdata_writer,
|
||||
BDataSharing &bdata_sharing,
|
||||
static std::shared_ptr<DictionaryValue> write_blob_shared_simple_gspan(
|
||||
BlobWriter &blob_writer,
|
||||
BlobSharing &blob_sharing,
|
||||
const GSpan data,
|
||||
const ImplicitSharingInfo *sharing_info)
|
||||
{
|
||||
return bdata_sharing.write_shared(
|
||||
sharing_info, [&]() { return write_bdata_simple_gspan(bdata_writer, data); });
|
||||
return blob_sharing.write_shared(sharing_info,
|
||||
[&]() { return write_blob_simple_gspan(blob_writer, data); });
|
||||
}
|
||||
|
||||
[[nodiscard]] static const void *read_bdata_shared_simple_gspan(
|
||||
[[nodiscard]] static const void *read_blob_shared_simple_gspan(
|
||||
const DictionaryValue &io_data,
|
||||
const BDataReader &bdata_reader,
|
||||
const BDataSharing &bdata_sharing,
|
||||
const BlobReader &blob_reader,
|
||||
const BlobSharing &blob_sharing,
|
||||
const CPPType &cpp_type,
|
||||
const int size,
|
||||
const ImplicitSharingInfo **r_sharing_info)
|
||||
{
|
||||
const std::optional<ImplicitSharingInfoAndData> sharing_info_and_data =
|
||||
bdata_sharing.read_shared(io_data, [&]() -> std::optional<ImplicitSharingInfoAndData> {
|
||||
const std::optional<ImplicitSharingInfoAndData> sharing_info_and_data = blob_sharing.read_shared(
|
||||
io_data, [&]() -> std::optional<ImplicitSharingInfoAndData> {
|
||||
void *data_mem = MEM_mallocN_aligned(
|
||||
size * cpp_type.size(), cpp_type.alignment(), __func__);
|
||||
if (!read_bdata_simple_gspan(bdata_reader, io_data, {cpp_type, data_mem, size})) {
|
||||
if (!read_blob_simple_gspan(blob_reader, io_data, {cpp_type, data_mem, size})) {
|
||||
MEM_freeN(data_mem);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
@ -352,22 +352,22 @@ static std::shared_ptr<DictionaryValue> write_bdata_shared_simple_gspan(
|
|||
}
|
||||
|
||||
template<typename T>
|
||||
[[nodiscard]] static bool read_bdata_shared_simple_span(const DictionaryValue &io_data,
|
||||
const BDataReader &bdata_reader,
|
||||
const BDataSharing &bdata_sharing,
|
||||
const int size,
|
||||
T **r_data,
|
||||
const ImplicitSharingInfo **r_sharing_info)
|
||||
[[nodiscard]] static bool read_blob_shared_simple_span(const DictionaryValue &io_data,
|
||||
const BlobReader &blob_reader,
|
||||
const BlobSharing &blob_sharing,
|
||||
const int size,
|
||||
T **r_data,
|
||||
const ImplicitSharingInfo **r_sharing_info)
|
||||
{
|
||||
*r_data = const_cast<T *>(static_cast<const T *>(read_bdata_shared_simple_gspan(
|
||||
io_data, bdata_reader, bdata_sharing, CPPType::get<T>(), size, r_sharing_info)));
|
||||
*r_data = const_cast<T *>(static_cast<const T *>(read_blob_shared_simple_gspan(
|
||||
io_data, blob_reader, blob_sharing, CPPType::get<T>(), size, r_sharing_info)));
|
||||
return *r_data != nullptr;
|
||||
}
|
||||
|
||||
[[nodiscard]] static bool load_attributes(const io::serialize::ArrayValue &io_attributes,
|
||||
bke::MutableAttributeAccessor &attributes,
|
||||
const BDataReader &bdata_reader,
|
||||
const BDataSharing &bdata_sharing)
|
||||
const BlobReader &blob_reader,
|
||||
const BlobSharing &blob_sharing)
|
||||
{
|
||||
for (const auto &io_attribute_value : io_attributes.elements()) {
|
||||
const auto *io_attribute = io_attribute_value->as_dictionary_value();
|
||||
|
@ -393,8 +393,8 @@ template<typename T>
|
|||
}
|
||||
const int domain_size = attributes.domain_size(*domain);
|
||||
const ImplicitSharingInfo *attribute_sharing_info;
|
||||
const void *attribute_data = read_bdata_shared_simple_gspan(
|
||||
*io_data, bdata_reader, bdata_sharing, *cpp_type, domain_size, &attribute_sharing_info);
|
||||
const void *attribute_data = read_blob_shared_simple_gspan(
|
||||
*io_data, blob_reader, blob_sharing, *cpp_type, domain_size, &attribute_sharing_info);
|
||||
if (!attribute_data) {
|
||||
return false;
|
||||
}
|
||||
|
@ -425,8 +425,8 @@ template<typename T>
|
|||
}
|
||||
|
||||
static PointCloud *try_load_pointcloud(const DictionaryValue &io_geometry,
|
||||
const BDataReader &bdata_reader,
|
||||
const BDataSharing &bdata_sharing)
|
||||
const BlobReader &blob_reader,
|
||||
const BlobSharing &blob_sharing)
|
||||
{
|
||||
const DictionaryValue *io_pointcloud = io_geometry.lookup_dict("pointcloud");
|
||||
if (!io_pointcloud) {
|
||||
|
@ -446,15 +446,15 @@ static PointCloud *try_load_pointcloud(const DictionaryValue &io_geometry,
|
|||
};
|
||||
|
||||
bke::MutableAttributeAccessor attributes = pointcloud->attributes_for_write();
|
||||
if (!load_attributes(*io_attributes, attributes, bdata_reader, bdata_sharing)) {
|
||||
if (!load_attributes(*io_attributes, attributes, blob_reader, blob_sharing)) {
|
||||
return cancel();
|
||||
}
|
||||
return pointcloud;
|
||||
}
|
||||
|
||||
static Curves *try_load_curves(const DictionaryValue &io_geometry,
|
||||
const BDataReader &bdata_reader,
|
||||
const BDataSharing &bdata_sharing)
|
||||
const BlobReader &blob_reader,
|
||||
const BlobSharing &blob_sharing)
|
||||
{
|
||||
const DictionaryValue *io_curves = io_geometry.lookup_dict("curves");
|
||||
if (!io_curves) {
|
||||
|
@ -482,19 +482,19 @@ static Curves *try_load_curves(const DictionaryValue &io_geometry,
|
|||
if (!io_curve_offsets) {
|
||||
return cancel();
|
||||
}
|
||||
if (!read_bdata_shared_simple_span(*io_curve_offsets,
|
||||
bdata_reader,
|
||||
bdata_sharing,
|
||||
curves.curves_num() + 1,
|
||||
&curves.curve_offsets,
|
||||
&curves.runtime->curve_offsets_sharing_info))
|
||||
if (!read_blob_shared_simple_span(*io_curve_offsets,
|
||||
blob_reader,
|
||||
blob_sharing,
|
||||
curves.curves_num() + 1,
|
||||
&curves.curve_offsets,
|
||||
&curves.runtime->curve_offsets_sharing_info))
|
||||
{
|
||||
return cancel();
|
||||
}
|
||||
}
|
||||
|
||||
bke::MutableAttributeAccessor attributes = curves.attributes_for_write();
|
||||
if (!load_attributes(*io_attributes, attributes, bdata_reader, bdata_sharing)) {
|
||||
if (!load_attributes(*io_attributes, attributes, blob_reader, blob_sharing)) {
|
||||
return cancel();
|
||||
}
|
||||
|
||||
|
@ -504,8 +504,8 @@ static Curves *try_load_curves(const DictionaryValue &io_geometry,
|
|||
}
|
||||
|
||||
static Mesh *try_load_mesh(const DictionaryValue &io_geometry,
|
||||
const BDataReader &bdata_reader,
|
||||
const BDataSharing &bdata_sharing)
|
||||
const BlobReader &blob_reader,
|
||||
const BlobSharing &blob_sharing)
|
||||
{
|
||||
const DictionaryValue *io_mesh = io_geometry.lookup_dict("mesh");
|
||||
if (!io_mesh) {
|
||||
|
@ -537,19 +537,19 @@ static Mesh *try_load_mesh(const DictionaryValue &io_geometry,
|
|||
if (!io_poly_offsets) {
|
||||
return cancel();
|
||||
}
|
||||
if (!read_bdata_shared_simple_span(*io_poly_offsets,
|
||||
bdata_reader,
|
||||
bdata_sharing,
|
||||
mesh->faces_num + 1,
|
||||
&mesh->face_offset_indices,
|
||||
&mesh->runtime->face_offsets_sharing_info))
|
||||
if (!read_blob_shared_simple_span(*io_poly_offsets,
|
||||
blob_reader,
|
||||
blob_sharing,
|
||||
mesh->faces_num + 1,
|
||||
&mesh->face_offset_indices,
|
||||
&mesh->runtime->face_offsets_sharing_info))
|
||||
{
|
||||
return cancel();
|
||||
}
|
||||
}
|
||||
|
||||
bke::MutableAttributeAccessor attributes = mesh->attributes_for_write();
|
||||
if (!load_attributes(*io_attributes, attributes, bdata_reader, bdata_sharing)) {
|
||||
if (!load_attributes(*io_attributes, attributes, blob_reader, blob_sharing)) {
|
||||
return cancel();
|
||||
}
|
||||
|
||||
|
@ -557,12 +557,12 @@ static Mesh *try_load_mesh(const DictionaryValue &io_geometry,
|
|||
}
|
||||
|
||||
static GeometrySet load_geometry(const DictionaryValue &io_geometry,
|
||||
const BDataReader &bdata_reader,
|
||||
const BDataSharing &bdata_sharing);
|
||||
const BlobReader &blob_reader,
|
||||
const BlobSharing &blob_sharing);
|
||||
|
||||
static std::unique_ptr<bke::Instances> try_load_instances(const DictionaryValue &io_geometry,
|
||||
const BDataReader &bdata_reader,
|
||||
const BDataSharing &bdata_sharing)
|
||||
const BlobReader &blob_reader,
|
||||
const BlobSharing &blob_sharing)
|
||||
{
|
||||
const DictionaryValue *io_instances = io_geometry.lookup_dict("instances");
|
||||
if (!io_instances) {
|
||||
|
@ -588,7 +588,7 @@ static std::unique_ptr<bke::Instances> try_load_instances(const DictionaryValue
|
|||
const DictionaryValue *io_reference = io_reference_value->as_dictionary_value();
|
||||
GeometrySet reference_geometry;
|
||||
if (io_reference) {
|
||||
reference_geometry = load_geometry(*io_reference, bdata_reader, bdata_sharing);
|
||||
reference_geometry = load_geometry(*io_reference, blob_reader, blob_sharing);
|
||||
}
|
||||
instances->add_reference(std::move(reference_geometry));
|
||||
}
|
||||
|
@ -597,7 +597,7 @@ static std::unique_ptr<bke::Instances> try_load_instances(const DictionaryValue
|
|||
if (!io_transforms) {
|
||||
return {};
|
||||
}
|
||||
if (!read_bdata_simple_gspan(bdata_reader, *io_transforms, instances->transforms())) {
|
||||
if (!read_blob_simple_gspan(blob_reader, *io_transforms, instances->transforms())) {
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -605,12 +605,12 @@ static std::unique_ptr<bke::Instances> try_load_instances(const DictionaryValue
|
|||
if (!io_handles) {
|
||||
return {};
|
||||
}
|
||||
if (!read_bdata_simple_gspan(bdata_reader, *io_handles, instances->reference_handles())) {
|
||||
if (!read_blob_simple_gspan(blob_reader, *io_handles, instances->reference_handles())) {
|
||||
return {};
|
||||
}
|
||||
|
||||
bke::MutableAttributeAccessor attributes = instances->attributes_for_write();
|
||||
if (!load_attributes(*io_attributes, attributes, bdata_reader, bdata_sharing)) {
|
||||
if (!load_attributes(*io_attributes, attributes, blob_reader, blob_sharing)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
|
@ -618,15 +618,14 @@ static std::unique_ptr<bke::Instances> try_load_instances(const DictionaryValue
|
|||
}
|
||||
|
||||
static GeometrySet load_geometry(const DictionaryValue &io_geometry,
|
||||
const BDataReader &bdata_reader,
|
||||
const BDataSharing &bdata_sharing)
|
||||
const BlobReader &blob_reader,
|
||||
const BlobSharing &blob_sharing)
|
||||
{
|
||||
GeometrySet geometry;
|
||||
geometry.replace_mesh(try_load_mesh(io_geometry, bdata_reader, bdata_sharing));
|
||||
geometry.replace_pointcloud(try_load_pointcloud(io_geometry, bdata_reader, bdata_sharing));
|
||||
geometry.replace_curves(try_load_curves(io_geometry, bdata_reader, bdata_sharing));
|
||||
geometry.replace_instances(
|
||||
try_load_instances(io_geometry, bdata_reader, bdata_sharing).release());
|
||||
geometry.replace_mesh(try_load_mesh(io_geometry, blob_reader, blob_sharing));
|
||||
geometry.replace_pointcloud(try_load_pointcloud(io_geometry, blob_reader, blob_sharing));
|
||||
geometry.replace_curves(try_load_curves(io_geometry, blob_reader, blob_sharing));
|
||||
geometry.replace_instances(try_load_instances(io_geometry, blob_reader, blob_sharing).release());
|
||||
return geometry;
|
||||
}
|
||||
|
||||
|
@ -651,8 +650,8 @@ static std::shared_ptr<io::serialize::ArrayValue> serialize_material_slots(
|
|||
|
||||
static std::shared_ptr<io::serialize::ArrayValue> serialize_attributes(
|
||||
const bke::AttributeAccessor &attributes,
|
||||
BDataWriter &bdata_writer,
|
||||
BDataSharing &bdata_sharing,
|
||||
BlobWriter &blob_writer,
|
||||
BlobSharing &blob_sharing,
|
||||
const Set<std::string> &attributes_to_ignore)
|
||||
{
|
||||
auto io_attributes = std::make_shared<io::serialize::ArrayValue>();
|
||||
|
@ -676,9 +675,9 @@ static std::shared_ptr<io::serialize::ArrayValue> serialize_attributes(
|
|||
const bke::GAttributeReader attribute = attributes.lookup(attribute_id);
|
||||
const GVArraySpan attribute_span(attribute.varray);
|
||||
io_attribute->append("data",
|
||||
write_bdata_shared_simple_gspan(
|
||||
bdata_writer,
|
||||
bdata_sharing,
|
||||
write_blob_shared_simple_gspan(
|
||||
blob_writer,
|
||||
blob_sharing,
|
||||
attribute_span,
|
||||
attribute.varray.is_span() ? attribute.sharing_info : nullptr));
|
||||
return true;
|
||||
|
@ -687,8 +686,8 @@ static std::shared_ptr<io::serialize::ArrayValue> serialize_attributes(
|
|||
}
|
||||
|
||||
static std::shared_ptr<DictionaryValue> serialize_geometry_set(const GeometrySet &geometry,
|
||||
BDataWriter &bdata_writer,
|
||||
BDataSharing &bdata_sharing)
|
||||
BlobWriter &blob_writer,
|
||||
BlobSharing &blob_sharing)
|
||||
{
|
||||
auto io_geometry = std::make_shared<DictionaryValue>();
|
||||
if (geometry.has_mesh()) {
|
||||
|
@ -702,16 +701,16 @@ static std::shared_ptr<DictionaryValue> serialize_geometry_set(const GeometrySet
|
|||
|
||||
if (mesh.faces_num > 0) {
|
||||
io_mesh->append("poly_offsets",
|
||||
write_bdata_shared_simple_gspan(bdata_writer,
|
||||
bdata_sharing,
|
||||
mesh.face_offsets(),
|
||||
mesh.runtime->face_offsets_sharing_info));
|
||||
write_blob_shared_simple_gspan(blob_writer,
|
||||
blob_sharing,
|
||||
mesh.face_offsets(),
|
||||
mesh.runtime->face_offsets_sharing_info));
|
||||
}
|
||||
|
||||
auto io_materials = serialize_material_slots({mesh.mat, mesh.totcol});
|
||||
io_mesh->append("materials", io_materials);
|
||||
|
||||
auto io_attributes = serialize_attributes(mesh.attributes(), bdata_writer, bdata_sharing, {});
|
||||
auto io_attributes = serialize_attributes(mesh.attributes(), blob_writer, blob_sharing, {});
|
||||
io_mesh->append("attributes", io_attributes);
|
||||
}
|
||||
if (geometry.has_pointcloud()) {
|
||||
|
@ -724,7 +723,7 @@ static std::shared_ptr<DictionaryValue> serialize_geometry_set(const GeometrySet
|
|||
io_pointcloud->append("materials", io_materials);
|
||||
|
||||
auto io_attributes = serialize_attributes(
|
||||
pointcloud.attributes(), bdata_writer, bdata_sharing, {});
|
||||
pointcloud.attributes(), blob_writer, blob_sharing, {});
|
||||
io_pointcloud->append("attributes", io_attributes);
|
||||
}
|
||||
if (geometry.has_curves()) {
|
||||
|
@ -739,17 +738,16 @@ static std::shared_ptr<DictionaryValue> serialize_geometry_set(const GeometrySet
|
|||
if (curves.curve_num > 0) {
|
||||
io_curves->append(
|
||||
"curve_offsets",
|
||||
write_bdata_shared_simple_gspan(bdata_writer,
|
||||
bdata_sharing,
|
||||
curves.offsets(),
|
||||
curves.runtime->curve_offsets_sharing_info));
|
||||
write_blob_shared_simple_gspan(blob_writer,
|
||||
blob_sharing,
|
||||
curves.offsets(),
|
||||
curves.runtime->curve_offsets_sharing_info));
|
||||
}
|
||||
|
||||
auto io_materials = serialize_material_slots({curves_id.mat, curves_id.totcol});
|
||||
io_curves->append("materials", io_materials);
|
||||
|
||||
auto io_attributes = serialize_attributes(
|
||||
curves.attributes(), bdata_writer, bdata_sharing, {});
|
||||
auto io_attributes = serialize_attributes(curves.attributes(), blob_writer, blob_sharing, {});
|
||||
io_curves->append("attributes", io_attributes);
|
||||
}
|
||||
if (geometry.has_instances()) {
|
||||
|
@ -762,16 +760,16 @@ static std::shared_ptr<DictionaryValue> serialize_geometry_set(const GeometrySet
|
|||
for (const bke::InstanceReference &reference : instances.references()) {
|
||||
BLI_assert(reference.type() == bke::InstanceReference::Type::GeometrySet);
|
||||
io_references->append(
|
||||
serialize_geometry_set(reference.geometry_set(), bdata_writer, bdata_sharing));
|
||||
serialize_geometry_set(reference.geometry_set(), blob_writer, blob_sharing));
|
||||
}
|
||||
|
||||
io_instances->append("transforms",
|
||||
write_bdata_simple_gspan(bdata_writer, instances.transforms()));
|
||||
write_blob_simple_gspan(blob_writer, instances.transforms()));
|
||||
io_instances->append("handles",
|
||||
write_bdata_simple_gspan(bdata_writer, instances.reference_handles()));
|
||||
write_blob_simple_gspan(blob_writer, instances.reference_handles()));
|
||||
|
||||
auto io_attributes = serialize_attributes(
|
||||
instances.attributes(), bdata_writer, bdata_sharing, {"position"});
|
||||
instances.attributes(), blob_writer, blob_sharing, {"position"});
|
||||
io_instances->append("attributes", io_attributes);
|
||||
}
|
||||
return io_geometry;
|
||||
|
@ -961,15 +959,15 @@ template<typename T>
|
|||
}
|
||||
|
||||
static void serialize_bake_item(const BakeItem &item,
|
||||
BDataWriter &bdata_writer,
|
||||
BDataSharing &bdata_sharing,
|
||||
BlobWriter &blob_writer,
|
||||
BlobSharing &blob_sharing,
|
||||
DictionaryValue &r_io_item)
|
||||
{
|
||||
if (const auto *geometry_state_item = dynamic_cast<const GeometryBakeItem *>(&item)) {
|
||||
r_io_item.append_str("type", "GEOMETRY");
|
||||
|
||||
const GeometrySet &geometry = geometry_state_item->geometry;
|
||||
auto io_geometry = serialize_geometry_set(geometry, bdata_writer, bdata_sharing);
|
||||
auto io_geometry = serialize_geometry_set(geometry, blob_writer, blob_sharing);
|
||||
r_io_item.append("data", io_geometry);
|
||||
}
|
||||
else if (const auto *attribute_state_item = dynamic_cast<const AttributeBakeItem *>(&item)) {
|
||||
|
@ -980,12 +978,12 @@ static void serialize_bake_item(const BakeItem &item,
|
|||
r_io_item.append_str("type", "STRING");
|
||||
const StringRefNull str = string_state_item->value();
|
||||
/* Small strings are inlined, larger strings are stored separately. */
|
||||
const int64_t bdata_threshold = 100;
|
||||
if (str.size() < bdata_threshold) {
|
||||
const int64_t blob_threshold = 100;
|
||||
if (str.size() < blob_threshold) {
|
||||
r_io_item.append_str("data", string_state_item->value());
|
||||
}
|
||||
else {
|
||||
r_io_item.append("data", write_bdata_raw_bytes(bdata_writer, str.data(), str.size()));
|
||||
r_io_item.append("data", write_blob_raw_bytes(blob_writer, str.data(), str.size()));
|
||||
}
|
||||
}
|
||||
else if (const auto *primitive_state_item = dynamic_cast<const PrimitiveBakeItem *>(&item)) {
|
||||
|
@ -997,8 +995,8 @@ static void serialize_bake_item(const BakeItem &item,
|
|||
}
|
||||
|
||||
static std::unique_ptr<BakeItem> deserialize_bake_item(const DictionaryValue &io_item,
|
||||
const BDataReader &bdata_reader,
|
||||
const BDataSharing &bdata_sharing)
|
||||
const BlobReader &blob_reader,
|
||||
const BlobSharing &blob_sharing)
|
||||
{
|
||||
|
||||
const std::optional<StringRefNull> state_item_type = io_item.lookup_str("type");
|
||||
|
@ -1010,7 +1008,7 @@ static std::unique_ptr<BakeItem> deserialize_bake_item(const DictionaryValue &io
|
|||
if (!io_geometry) {
|
||||
return {};
|
||||
}
|
||||
GeometrySet geometry = load_geometry(*io_geometry, bdata_reader, bdata_sharing);
|
||||
GeometrySet geometry = load_geometry(*io_geometry, blob_reader, blob_sharing);
|
||||
return std::make_unique<GeometryBakeItem>(std::move(geometry));
|
||||
}
|
||||
if (*state_item_type == StringRef("ATTRIBUTE")) {
|
||||
|
@ -1041,7 +1039,7 @@ static std::unique_ptr<BakeItem> deserialize_bake_item(const DictionaryValue &io
|
|||
}
|
||||
std::string str;
|
||||
str.resize(*size);
|
||||
if (!read_bdata_raw_bytes(bdata_reader, *io_string, *size, str.data())) {
|
||||
if (!read_blob_raw_bytes(blob_reader, *io_string, *size, str.data())) {
|
||||
return {};
|
||||
}
|
||||
return std::make_unique<StringBakeItem>(std::move(str));
|
||||
|
@ -1067,8 +1065,8 @@ static std::unique_ptr<BakeItem> deserialize_bake_item(const DictionaryValue &io
|
|||
static constexpr int bake_file_version = 3;
|
||||
|
||||
void serialize_bake(const BakeState &bake_state,
|
||||
BDataWriter &bdata_writer,
|
||||
BDataSharing &bdata_sharing,
|
||||
BlobWriter &blob_writer,
|
||||
BlobSharing &blob_sharing,
|
||||
std::ostream &r_stream)
|
||||
{
|
||||
io::serialize::DictionaryValue io_root;
|
||||
|
@ -1076,7 +1074,7 @@ void serialize_bake(const BakeState &bake_state,
|
|||
io::serialize::DictionaryValue &io_items = *io_root.append_dict("items");
|
||||
for (auto item : bake_state.items_by_id.items()) {
|
||||
io::serialize::DictionaryValue &io_item = *io_items.append_dict(std::to_string(item.key));
|
||||
bke::serialize_bake_item(*item.value, bdata_writer, bdata_sharing, io_item);
|
||||
serialize_bake_item(*item.value, blob_writer, blob_sharing, io_item);
|
||||
}
|
||||
|
||||
io::serialize::JsonFormatter formatter;
|
||||
|
@ -1084,8 +1082,8 @@ void serialize_bake(const BakeState &bake_state,
|
|||
}
|
||||
|
||||
std::optional<BakeState> deserialize_bake(std::istream &stream,
|
||||
const BDataReader &bdata_reader,
|
||||
const BDataSharing &bdata_sharing)
|
||||
const BlobReader &blob_reader,
|
||||
const BlobSharing &blob_sharing)
|
||||
{
|
||||
JsonFormatter formatter;
|
||||
std::unique_ptr<io::serialize::Value> io_root_value = formatter.deserialize(stream);
|
||||
|
@ -1121,7 +1119,7 @@ std::optional<BakeState> deserialize_bake(std::istream &stream,
|
|||
return std::nullopt;
|
||||
}
|
||||
std::unique_ptr<BakeItem> bake_item = deserialize_bake_item(
|
||||
*io_item, bdata_reader, bdata_sharing);
|
||||
*io_item, blob_reader, blob_sharing);
|
||||
if (!bake_item) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
@ -1130,4 +1128,4 @@ std::optional<BakeState> deserialize_bake(std::istream &stream,
|
|||
return bake_state;
|
||||
}
|
||||
|
||||
} // namespace blender::bke
|
||||
} // namespace blender::bke::bake
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
#include "FN_field_cpp_type.hh"
|
||||
|
||||
namespace blender::bke {
|
||||
namespace blender::bke::bake {
|
||||
|
||||
static const CPPType &get_socket_cpp_type(const eNodeSocketDatatype socket_type)
|
||||
{
|
||||
|
@ -288,4 +288,4 @@ void copy_bake_items_to_socket_values(
|
|||
rename_attributes(geometries, attribute_map);
|
||||
}
|
||||
|
||||
} // namespace blender::bke
|
||||
} // namespace blender::bke::bake
|
||||
|
|
|
@ -2578,7 +2578,8 @@ static void armdef_accumulate_matrix(const float obmat[4][4],
|
|||
const float iobmat[4][4],
|
||||
const float basemat[4][4],
|
||||
const float bonemat[4][4],
|
||||
float weight,
|
||||
const float pivot[3],
|
||||
const float weight,
|
||||
float r_sum_mat[4][4],
|
||||
DualQuat *r_sum_dq)
|
||||
{
|
||||
|
@ -2600,7 +2601,7 @@ static void armdef_accumulate_matrix(const float obmat[4][4],
|
|||
orthogonalize_m4_stable(basemat_world, 1, true);
|
||||
|
||||
mat4_to_dquat(&tmpdq, basemat_world, mat);
|
||||
add_weighted_dq_dq(r_sum_dq, &tmpdq, weight);
|
||||
add_weighted_dq_dq_pivot(r_sum_dq, &tmpdq, pivot, weight, true);
|
||||
}
|
||||
else {
|
||||
madd_m4_m4m4fl(r_sum_mat, r_sum_mat, mat, weight);
|
||||
|
@ -2608,16 +2609,16 @@ static void armdef_accumulate_matrix(const float obmat[4][4],
|
|||
}
|
||||
|
||||
/* Compute and accumulate transformation for a single target bone. */
|
||||
static void armdef_accumulate_bone(bConstraintTarget *ct,
|
||||
bPoseChannel *pchan,
|
||||
static void armdef_accumulate_bone(const bConstraintTarget *ct,
|
||||
const bPoseChannel *pchan,
|
||||
const float wco[3],
|
||||
bool force_envelope,
|
||||
const bool force_envelope,
|
||||
float *r_totweight,
|
||||
float r_sum_mat[4][4],
|
||||
DualQuat *r_sum_dq)
|
||||
{
|
||||
float iobmat[4][4], co[3];
|
||||
Bone *bone = pchan->bone;
|
||||
const Bone *bone = pchan->bone;
|
||||
float weight = ct->weight;
|
||||
|
||||
/* Our object's location in target pose space. */
|
||||
|
@ -2632,8 +2633,8 @@ static void armdef_accumulate_bone(bConstraintTarget *ct,
|
|||
|
||||
/* Find the correct bone transform matrix in world space. */
|
||||
if (bone->segments > 1 && bone->segments == pchan->runtime.bbone_segments) {
|
||||
Mat4 *b_bone_mats = pchan->runtime.bbone_deform_mats;
|
||||
Mat4 *b_bone_rest_mats = pchan->runtime.bbone_rest_mats;
|
||||
const Mat4 *b_bone_mats = pchan->runtime.bbone_deform_mats;
|
||||
const Mat4 *b_bone_rest_mats = pchan->runtime.bbone_rest_mats;
|
||||
float basemat[4][4];
|
||||
|
||||
/* Blend the matrix. */
|
||||
|
@ -2650,6 +2651,7 @@ static void armdef_accumulate_bone(bConstraintTarget *ct,
|
|||
iobmat,
|
||||
basemat,
|
||||
b_bone_mats[index + 1].mat,
|
||||
wco,
|
||||
weight * (1.0f - blend),
|
||||
r_sum_mat,
|
||||
r_sum_dq);
|
||||
|
@ -2663,6 +2665,7 @@ static void armdef_accumulate_bone(bConstraintTarget *ct,
|
|||
iobmat,
|
||||
basemat,
|
||||
b_bone_mats[index + 2].mat,
|
||||
wco,
|
||||
weight * blend,
|
||||
r_sum_mat,
|
||||
r_sum_dq);
|
||||
|
@ -2673,6 +2676,7 @@ static void armdef_accumulate_bone(bConstraintTarget *ct,
|
|||
iobmat,
|
||||
bone->arm_mat,
|
||||
pchan->chan_mat,
|
||||
wco,
|
||||
weight,
|
||||
r_sum_mat,
|
||||
r_sum_dq);
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
/* SPDX-FileCopyrightText: 2021 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "testing/testing.h"
|
||||
|
||||
#include "BLI_string.h"
|
||||
|
||||
#include "BKE_cryptomatte.h"
|
||||
#include "BKE_cryptomatte.hh"
|
||||
#include "BKE_image.h"
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_task.hh"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
|
@ -81,7 +82,10 @@ static KnotsMode knots_mode_from_legacy(const short flag)
|
|||
|
||||
Curves *curve_legacy_to_curves(const Curve &curve_legacy, const ListBase &nurbs_list)
|
||||
{
|
||||
const Vector<const Nurb *> src_curves(nurbs_list);
|
||||
Vector<const Nurb *> src_curves;
|
||||
LISTBASE_FOREACH (const Nurb *, item, &nurbs_list) {
|
||||
src_curves.append(item);
|
||||
}
|
||||
if (src_curves.is_empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -839,7 +839,7 @@ static void get_effector_tot(
|
|||
if (eff->pd->forcefield == PFIELD_CHARGE) {
|
||||
/* Only the charge of the effected particle is used for
|
||||
* interaction, not fall-offs. If the fall-offs aren't the
|
||||
* same this will be unphysical, but for animation this
|
||||
* same this will be nonphysical, but for animation this
|
||||
* could be the wanted behavior. If you want physical
|
||||
* correctness the fall-off should be spherical 2.0 anyways.
|
||||
*/
|
||||
|
|
|
@ -3266,7 +3266,7 @@ static Mesh *create_liquid_geometry(FluidDomainSettings *fds,
|
|||
madd_v3fl_v3fl_v3fl_v3i(max, fds->p0, cell_size_scaled, fds->res_max);
|
||||
sub_v3_v3v3(size, max, min);
|
||||
|
||||
/* Biggest dimension will be used for upscaling. */
|
||||
/* Biggest dimension will be used for up-scaling. */
|
||||
float max_size = MAX3(size[0], size[1], size[2]);
|
||||
|
||||
float co_scale[3];
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "BLI_color.hh"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_math_vector_types.hh"
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
#include "DNA_gpencil_legacy_types.h"
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
#include "testing/testing.h"
|
||||
|
||||
#include "BLI_string.h"
|
||||
|
||||
#include "BKE_curves.hh"
|
||||
#include "BKE_grease_pencil.hh"
|
||||
#include "BKE_idtype.h"
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
#include "testing/testing.h"
|
||||
|
||||
#include "BLI_listbase.h"
|
||||
|
||||
#include "DNA_ID.h"
|
||||
|
||||
#include "BKE_idprop.hh"
|
||||
|
|
|
@ -57,6 +57,7 @@
|
|||
#include "IMB_imbuf.h"
|
||||
#include "IMB_imbuf_types.h"
|
||||
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
namespace blender::bke::image::partial_update {
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "BLI_map.hh"
|
||||
#include "BLI_math_base.hh"
|
||||
#include "BLI_set.hh"
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_string_utf8.h"
|
||||
#include "BLI_string_utils.h"
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "BLI_listbase.h"
|
||||
#include "BLI_math_color.h"
|
||||
#include "BLI_math_vector.h"
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BLT_translation.h"
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "BLI_mesh_boolean.hh"
|
||||
#include "BLI_mesh_intersect.hh"
|
||||
#include "BLI_span.hh"
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_task.hh"
|
||||
#include "BLI_virtual_array.hh"
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
#include "BLI_memarena.h"
|
||||
#include "BLI_polyfill_2d.h"
|
||||
#include "BLI_resource_scope.hh"
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_task.hh"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
|
|
|
@ -323,7 +323,9 @@ static void sort_small_groups(const OffsetIndices<int> groups,
|
|||
static Array<int> reverse_indices_in_groups(const Span<int> group_indices,
|
||||
const OffsetIndices<int> offsets)
|
||||
{
|
||||
BLI_assert(!group_indices.is_empty());
|
||||
if (group_indices.is_empty()) {
|
||||
return {};
|
||||
}
|
||||
BLI_assert(*std::max_element(group_indices.begin(), group_indices.end()) < offsets.size());
|
||||
BLI_assert(*std::min_element(group_indices.begin(), group_indices.end()) >= 0);
|
||||
Array<int> counts(offsets.size(), -1);
|
||||
|
@ -344,11 +346,6 @@ static GroupedSpan<int> gather_groups(const Span<int> group_indices,
|
|||
Array<int> &r_offsets,
|
||||
Array<int> &r_indices)
|
||||
{
|
||||
if (group_indices.is_empty()) {
|
||||
r_offsets.reinitialize(groups_num + 1);
|
||||
r_offsets.as_mutable_span().fill(0);
|
||||
return {OffsetIndices<int>(r_offsets), {}};
|
||||
}
|
||||
r_offsets = create_reverse_offsets(group_indices, groups_num);
|
||||
r_indices = reverse_indices_in_groups(group_indices, r_offsets.as_span());
|
||||
return {OffsetIndices<int>(r_offsets), r_indices};
|
||||
|
|
|
@ -452,12 +452,10 @@ void BKE_remesh_reproject_vertex_paint(Mesh *target, const Mesh *source)
|
|||
|
||||
/* Make sure active/default color attribute (names) are brought over. */
|
||||
if (source->active_color_attribute) {
|
||||
MEM_SAFE_FREE(target->active_color_attribute);
|
||||
target->active_color_attribute = BLI_strdup(source->active_color_attribute);
|
||||
BKE_id_attributes_active_color_set(&target->id, source->active_color_attribute);
|
||||
}
|
||||
if (source->default_color_attribute) {
|
||||
MEM_SAFE_FREE(target->default_color_attribute);
|
||||
target->default_color_attribute = BLI_strdup(source->default_color_attribute);
|
||||
BKE_id_attributes_default_color_set(&target->id, source->default_color_attribute);
|
||||
}
|
||||
|
||||
free_bvhtree_from_mesh(&bvhtree);
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include "BLI_math_geom.h"
|
||||
#include "BLI_math_vector.h"
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_task.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
|
|
|
@ -2304,7 +2304,7 @@ void BKE_nla_tweakmode_exit(AnimData *adt)
|
|||
BKE_nlastrip_recalculate_bounds_sync_action(strip);
|
||||
}
|
||||
|
||||
/* clear tweakuser flag */
|
||||
/* Clear tweak-user flag. */
|
||||
strip->flag &= ~NLASTRIP_FLAG_TWEAKUSER;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -531,11 +531,7 @@ static void construct_interface_as_legacy_sockets(bNodeTree *ntree)
|
|||
SET_FLAG_FROM_TEST(
|
||||
iosock->flag, socket.flag & NODE_INTERFACE_SOCKET_HIDE_IN_MODIFIER, SOCK_HIDE_IN_MODIFIER);
|
||||
iosock->attribute_domain = socket.attribute_domain;
|
||||
if (socket.default_attribute_name) {
|
||||
BLI_strncpy(iosock->default_attribute_name,
|
||||
socket.default_attribute_name,
|
||||
sizeof(iosock->default_attribute_name));
|
||||
}
|
||||
iosock->default_attribute_name = BLI_strdup_null(socket.default_attribute_name);
|
||||
return iosock;
|
||||
};
|
||||
|
||||
|
|
|
@ -991,8 +991,6 @@ void bNodeTreeInterfacePanel::copy_from(
|
|||
/* Copy buffers. */
|
||||
for (const int i : items_src.index_range()) {
|
||||
const bNodeTreeInterfaceItem *item_src = items_src[i];
|
||||
BLI_assert(item_src->item_type != NODE_INTERFACE_PANEL ||
|
||||
(flag & NODE_INTERFACE_PANEL_ALLOW_CHILD_PANELS));
|
||||
items_array[i] = static_cast<bNodeTreeInterfaceItem *>(MEM_dupallocN(item_src));
|
||||
item_types::item_copy(*items_array[i], *item_src, flag);
|
||||
}
|
||||
|
@ -1205,7 +1203,7 @@ bNodeTreeInterfaceItem *bNodeTreeInterface::insert_item_copy(const bNodeTreeInte
|
|||
|
||||
bool bNodeTreeInterface::remove_item(bNodeTreeInterfaceItem &item, bool move_content_to_parent)
|
||||
{
|
||||
bNodeTreeInterfacePanel *parent = this->find_item_parent(item);
|
||||
bNodeTreeInterfacePanel *parent = this->find_item_parent(item, true);
|
||||
if (parent == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
@ -1230,7 +1228,7 @@ void bNodeTreeInterface::clear_items()
|
|||
|
||||
bool bNodeTreeInterface::move_item(bNodeTreeInterfaceItem &item, const int new_position)
|
||||
{
|
||||
bNodeTreeInterfacePanel *parent = this->find_item_parent(item);
|
||||
bNodeTreeInterfacePanel *parent = this->find_item_parent(item, true);
|
||||
if (parent == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
@ -1241,11 +1239,11 @@ bool bNodeTreeInterface::move_item_to_parent(bNodeTreeInterfaceItem &item,
|
|||
bNodeTreeInterfacePanel *new_parent,
|
||||
int new_position)
|
||||
{
|
||||
bNodeTreeInterfacePanel *parent = this->find_item_parent(item);
|
||||
bNodeTreeInterfacePanel *parent = this->find_item_parent(item, true);
|
||||
if (parent == nullptr) {
|
||||
return false;
|
||||
}
|
||||
if (item.item_type == NODE_INTERFACE_PANEL &&
|
||||
if (item.item_type == NODE_INTERFACE_PANEL && new_parent &&
|
||||
!(new_parent->flag & NODE_INTERFACE_PANEL_ALLOW_CHILD_PANELS))
|
||||
{
|
||||
/* Parent does not allow adding child panels. */
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
/* SPDX-FileCopyrightText: 2023 Blender Authors
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include "BLI_compiler_compat.h"
|
||||
#include "BLI_string.h"
|
||||
|
||||
#include "DNA_material_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
|
|
|
@ -3011,7 +3011,7 @@ static int collision_response(ParticleSimulationData *sim,
|
|||
interp_v3_v3v3(v0_tan, v0_tan, v1_tan, frict);
|
||||
}
|
||||
else {
|
||||
/* just basic friction (unphysical due to the friction model used in Blender) */
|
||||
/* Just basic friction (nonphysical due to the friction model used in Blender). */
|
||||
interp_v3_v3v3(v0_tan, v0_tan, vc_tan, frict);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1351,6 +1351,10 @@ static void pbvh_faces_update_normals(PBVH *pbvh, Span<PBVHNode *> nodes, Mesh &
|
|||
}
|
||||
});
|
||||
});
|
||||
|
||||
/* #SharedCache::update() reallocates the cached vectors if they were shared initially. */
|
||||
pbvh->face_normals = mesh.runtime->face_normals_cache.data();
|
||||
pbvh->vert_normals = mesh.runtime->vert_normals_cache.data();
|
||||
}
|
||||
|
||||
static void node_update_mask_redraw(PBVH &pbvh, PBVHNode &node)
|
||||
|
|
|
@ -14,16 +14,16 @@
|
|||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_math_geom.h"
|
||||
#include "BLI_math_vector.h"
|
||||
#include "BLI_task.h"
|
||||
|
||||
#include "PIL_time.h"
|
||||
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_image_wrappers.hh"
|
||||
|
||||
#include "bmesh.h"
|
||||
|
||||
#include "pbvh_intern.hh"
|
||||
#include "pbvh_pixels_copy.hh"
|
||||
#include "pbvh_uv_islands.hh"
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
|
||||
#include "BLI_array.hh"
|
||||
#include "BLI_bit_vector.hh"
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_math_geom.h"
|
||||
#include "BLI_math_vector.hh"
|
||||
#include "BLI_task.hh"
|
||||
|
|
|
@ -66,7 +66,6 @@
|
|||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "BLI_math_base.h"
|
||||
#include "BLI_string_ref.hh"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
|
|
|
@ -14,11 +14,7 @@
|
|||
#include <cmath>
|
||||
|
||||
#include "BLI_allocator.hh"
|
||||
#include "BLI_array.hh"
|
||||
#include "BLI_math_base.h"
|
||||
#include "BLI_memory_utils.hh"
|
||||
#include "BLI_string.h"
|
||||
#include "BLI_string_ref.hh"
|
||||
#include "BLI_utildefines.h"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
|
@ -303,7 +299,7 @@ class HashTableStats {
|
|||
removed_load_factor_ = (float)removed_amount_ / (float)capacity_;
|
||||
}
|
||||
|
||||
void print(StringRef name = "") const;
|
||||
void print(const char *name) const;
|
||||
};
|
||||
|
||||
/** \} */
|
||||
|
|
|
@ -915,7 +915,7 @@ class Map {
|
|||
/**
|
||||
* Print common statistics like size and collision count. This is useful for debugging purposes.
|
||||
*/
|
||||
void print_stats(StringRef name = "") const
|
||||
void print_stats(const char *name) const
|
||||
{
|
||||
HashTableStats stats(*this, this->keys());
|
||||
stats.print(name);
|
||||
|
|
|
@ -411,6 +411,11 @@ void rotate_eulO(float beul[3], short order, char axis, float angle);
|
|||
void copy_dq_dq(DualQuat *r, const DualQuat *dq);
|
||||
void normalize_dq(DualQuat *dq, float totweight);
|
||||
void add_weighted_dq_dq(DualQuat *dq_sum, const DualQuat *dq, float weight);
|
||||
void add_weighted_dq_dq_pivot(DualQuat *dq_sum,
|
||||
const DualQuat *dq,
|
||||
const float pivot[3],
|
||||
float weight,
|
||||
bool compute_scale_matrix);
|
||||
void mul_v3m3_dq(float r[3], float R[3][3], DualQuat *dq);
|
||||
|
||||
void mat4_to_dquat(DualQuat *dq, const float basemat[4][4], const float mat[4][4]);
|
||||
|
|
|
@ -83,6 +83,9 @@ template<typename T, int Size> struct VecBase : public vec_struct_base<T, Size>
|
|||
BLI_STATIC_ASSERT(alignof(T) <= sizeof(T),
|
||||
"VecBase is not compatible with aligned type for now.");
|
||||
|
||||
/* Workaround issue with template BLI_ENABLE_IF((Size == 2)) not working. */
|
||||
#define BLI_ENABLE_IF_VEC(_size, _test) int S = _size, BLI_ENABLE_IF((S _test))
|
||||
|
||||
static constexpr int type_length = Size;
|
||||
|
||||
using base_type = T;
|
||||
|
@ -90,7 +93,7 @@ template<typename T, int Size> struct VecBase : public vec_struct_base<T, Size>
|
|||
|
||||
VecBase() = default;
|
||||
|
||||
explicit VecBase(T value)
|
||||
template<BLI_ENABLE_IF_VEC(Size, > 1)> explicit VecBase(T value)
|
||||
{
|
||||
for (int i = 0; i < Size; i++) {
|
||||
(*this)[i] = value;
|
||||
|
@ -102,8 +105,10 @@ template<typename T, int Size> struct VecBase : public vec_struct_base<T, Size>
|
|||
{
|
||||
}
|
||||
|
||||
/* Workaround issue with template BLI_ENABLE_IF((Size == 2)) not working. */
|
||||
#define BLI_ENABLE_IF_VEC(_size, _test) int S = _size, BLI_ENABLE_IF((S _test))
|
||||
template<BLI_ENABLE_IF_VEC(Size, == 1)> VecBase(T _x)
|
||||
{
|
||||
(*this)[0] = _x;
|
||||
}
|
||||
|
||||
template<BLI_ENABLE_IF_VEC(Size, == 2)> VecBase(T _x, T _y)
|
||||
{
|
||||
|
@ -667,6 +672,7 @@ using ushort2 = VecBase<uint16_t, 2>;
|
|||
using ushort3 = blender::VecBase<uint16_t, 3>;
|
||||
using ushort4 = blender::VecBase<uint16_t, 4>;
|
||||
|
||||
using float1 = VecBase<float, 1>;
|
||||
using float2 = VecBase<float, 2>;
|
||||
using float3 = VecBase<float, 3>;
|
||||
using float4 = VecBase<float, 4>;
|
||||
|
|
|
@ -511,7 +511,7 @@ class Set {
|
|||
/**
|
||||
* Print common statistics like size and collision count. This is useful for debugging purposes.
|
||||
*/
|
||||
void print_stats(StringRef name = "") const
|
||||
void print_stats(const char *name) const
|
||||
{
|
||||
HashTableStats stats(*this, *this);
|
||||
stats.print(name);
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "BLI_assert.h"
|
||||
#include "BLI_math_base.h"
|
||||
|
||||
|
|
|
@ -31,11 +31,8 @@
|
|||
|
||||
#include "BLI_allocator.hh"
|
||||
#include "BLI_index_range.hh"
|
||||
#include "BLI_listbase_wrapper.hh"
|
||||
#include "BLI_math_base.h"
|
||||
#include "BLI_memory_utils.hh"
|
||||
#include "BLI_span.hh"
|
||||
#include "BLI_string_ref.hh"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
@ -43,7 +40,7 @@
|
|||
namespace blender {
|
||||
|
||||
namespace internal {
|
||||
void vector_print_stats(StringRef name,
|
||||
void vector_print_stats(const char *name,
|
||||
void *address,
|
||||
int64_t size,
|
||||
int64_t capacity,
|
||||
|
@ -211,21 +208,6 @@ class Vector {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a vector from a ListBase. The caller has to make sure that the values in the linked
|
||||
* list have the correct type.
|
||||
*
|
||||
* Example Usage:
|
||||
* Vector<ModifierData *> modifiers(ob->modifiers);
|
||||
*/
|
||||
Vector(const ListBase &values, Allocator allocator = {})
|
||||
: Vector(NoExceptConstructor(), allocator)
|
||||
{
|
||||
LISTBASE_FOREACH (T, value, &values) {
|
||||
this->append(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a copy of another vector. The other vector will not be changed. If the other vector has
|
||||
* less than InlineBufferCapacity elements, no allocation will be made.
|
||||
|
@ -983,7 +965,7 @@ class Vector {
|
|||
/**
|
||||
* Print some debug information about the vector.
|
||||
*/
|
||||
void print_stats(StringRef name = "") const
|
||||
void print_stats(const char *name) const
|
||||
{
|
||||
internal::vector_print_stats(
|
||||
name, this, this->size(), capacity_end_ - begin_, InlineBufferCapacity, sizeof(*this));
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue